1 /*
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 *
7 * @(#)ccitt_addr.c 5.3 (Berkeley) 07/01/91
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
ccitt_addr(addr,xp)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 bzero ((char *)xp, 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 *
copychar(from,to)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