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