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