1 /*
2  * parse CCITT addresses
3  *
4  * Addresses must have the format: [hpr],x121address[,userdata][,protocol]
5  * items enclosed with square brackets are optional
6  * 'h' or 'p' means hi priority (packet size = 128; specific to Datapac
7  * and necessary only for X.25(76) and non-negotiating X.25(80) DTE's)
8  * 'r' means reverse charge (remote DTE pays for call).
9  * The x121address consists of an optional netid and dot, followed
10  * by a dte address.
11  *
12  * Frank Pronk
13  * The University of British Columbia
14  * Laboratory for Computational Vision
15  * Copyright (c) 1984
16  */
17 
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <netccitt/x25.h>
21 
22 static char *copychar ();
23 
24 ccitt_addr (addr, xp)
25 char *addr;
26 register struct sockaddr_x25 *xp;
27 {
28 	register char *p, *ap, *limit;
29 	register int havenet = 0;
30 
31 	bzero ((char *)xp, sizeof (*xp));
32 	xp->x25_family = AF_CCITT;
33 	xp->x25_udlen = 4;
34 	p = addr;
35 
36 	/*
37 	 * process optional priority and reverse charging flags
38 	 */
39 
40 	if (*p == 'p' || *p == 'r' || *p == 'h') {
41 		while (*p == 'p' || *p == 'r' || *p == 'h') {
42 			if (*p == 'p' || *p == 'h')
43 				xp->x25_opts.op_psize = X25_PS128;
44 			else if (*p == 'r')
45 				xp->x25_opts.op_flags |= X25_REVERSE_CHARGE;
46 			p++;
47 		}
48 		if (*p != ',')
49 			return (0);
50 		p++;
51 	}
52 	if (*p == '\0')
53 		return (0);
54 
55 	/*
56 	 * [network id:]X.121 address
57 	 */
58 
59 	ap = xp->x25_addr;
60 	limit = ap + sizeof (xp->x25_addr) - 1;
61 	while (*p) {
62 		if (*p == ',')
63 			break;
64 		if (*p == '.' || *p == ':') {
65 			if (havenet)
66 				return (0);
67 			havenet++;
68 			xp->x25_net = atoi (xp->x25_addr);
69 			p++;
70 			ap = xp->x25_addr;
71 			*ap = '\0';
72 		}
73 		if (*p < '0' || *p > '9')
74 			return (0);
75 		if (ap >= limit)
76 			return (0);
77 		*ap++ = *p++;
78 	}
79 	if (*p == '\0')
80 		return (1);
81 
82 	/*
83 	 * optional user data, bytes 4 to 16
84 	 */
85 
86 	p++;
87 	ap = xp->x25_udata + 4;		/* first four bytes are protocol id */
88 	limit = ap + sizeof (xp->x25_udata) - 4;
89 	while (*p) {
90 		if (*p == ',')
91 			break;
92 		if (ap >= limit)
93 			return (0);
94 		p = copychar (p, ap++);
95 		xp->x25_udlen++;
96 	}
97 	if (*p == '\0')
98 		return (1);
99 
100 	p++;
101 	ap = xp->x25_udata;		/* protocol id */
102 	limit = ap + 4;
103 	while (*p) {
104 		if (*p == ',')
105 			return (0);
106 		if (ap >= limit)
107 			return (0);
108 		p = copychar (p, ap++);
109 	}
110 	return (1);
111 }
112 
113 static char *
114 copychar (from, to)
115 register char *from, *to;
116 {
117 	register int n;
118 
119 	if (*from != '\\' || from[1] < '0' || from[1] > '7') {
120 		*to = *from++;
121 		return (from);
122 	}
123 	n = *++from - '0';
124 	from++;
125 	if (*from >= '0' && *from <= '7') {
126 		register int n1;
127 
128 		n = n*8 + *from++ - '0';
129 		if (*from >= '0' && *from <= '7' && (n1 = n*8 + *from-'0') < 256) {
130 			n = n1;
131 			from++;
132 		}
133 	}
134 	*to = n;
135 	return (from);
136 }
137