1 /*
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 *
7 * @(#)x25config.c 5.3 (Berkeley) 04/25/93
8 */
9 /*
10 * Configure X.25 interface
11 *
12 * Copyright (c) 1986 University of British Columbia
13 *
14 * Frank Pronk
15 * February 1986
16 */
17
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <sys/ioctl.h>
21
22 #include <net/if.h>
23 #include <netccitt/x25.h>
24
25 #include <stdio.h>
26 #include <netdb.h>
27
28 #define IFFBITS \
29 "\020\1UP\2BROADCAST\3DEBUG\4ROUTE\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP"
30
31 int setifflags (), setdefault (), setnet (), setntn ();
32 int setlproto (), sethdlc (), setlwsize (), setlkeepalive (), setltrace ();
33 int setyear (), setpwsize (), setpacketsize (), setmaxlcn (), setptrace ();
34
35 struct cmd {
36 char *c_name;
37 int c_arg;
38 int (*c_func) ();
39 } cmds[] = {
40 "up", IFF_UP, setifflags,
41 "-up", -IFF_UP, setifflags,
42 "down", -IFF_UP, setifflags,
43 "debug", IFF_DEBUG, setifflags,
44 "-debug", -IFF_DEBUG, setifflags,
45 "default", 0, setdefault,
46 "hdlc", CCITTPROTO_HDLC, setlproto,
47 "ieee802llc", IEEEPROTO_802LLC, setlproto,
48 "llc2", IEEEPROTO_802LLC, setlproto,
49 "lap", HDLCPROTO_LAP, sethdlc,
50 "lapb", HDLCPROTO_LAPB, sethdlc,
51 "lapd", HDLCPROTO_LAPD, sethdlc,
52 "unset", HDLCPROTO_UNSET, sethdlc,
53 "-ltrace", 0, setltrace,
54 "ltrace", 1, setltrace,
55 "keepalive", 1, setlkeepalive,
56 "-keepalive", 0, setlkeepalive,
57
58 "1976", X25_1976, setyear,
59 "1980", X25_1980, setyear,
60 "1984", X25_1984, setyear,
61 "-ptrace", 0, setptrace,
62 "ptrace", 1, setptrace,
63
64 "-net", 0, setnet,
65 "-ntn", 0, setntn,
66 "-lwsize", 0, setlwsize,
67 "-pwsize", 0, setpwsize,
68 "-psize", 0, setpacketsize,
69 "-maxlcn", 0, setmaxlcn,
70 0, 0, 0
71 };
72
73 struct ifreq ifr;
74 struct ifreq_x25 ifrx25;
75 #define x25conf ifrx25.ifr_xc
76
77 char *myname;
78 char *ifname; /* interface name */
79 short ifflags; /* local copy of interface flags */
80
main(argc,argv)81 main (argc, argv)
82 register char **argv;
83 int argc;
84 {
85 register int s;
86
87 myname = *argv;
88 if (argc < 2)
89 abort ("usage: x25ifconfig interface [default] [-net net] [-ntn ntn] [-maxlcn maxlcn] [up] [down] [zillions of other options]");
90
91 if ((s = socket (AF_CCITT, SOCK_STREAM, 0)) < 0)
92 syserr ("socket");
93 argv[argc] = 0;
94 argv++;
95
96 ifname = *argv;
97 strcpy (ifr.ifr_name, ifname);
98 if (ioctl (s, SIOCGIFFLAGS, (char *)&ifr) < 0)
99 syserr ("ioctl (SIOCGIFFLAGS)");
100 ifflags = ifr.ifr_flags;
101 strcpy (ifrx25.ifr_name, ifname);
102 if (ioctl (s, SIOCGIFCONF_X25, (char *)&ifrx25) < 0) {
103 x25conf.xc_addr.x25_len = sizeof(x25conf);
104 x25conf.xc_addr.x25_family = AF_CCITT;
105 }
106 if (argc == 2) {
107 status ();
108 exit (0);
109 }
110 argv++;
111 while (*argv) {
112 register struct cmd *cp;
113 register int argneeded;
114
115 argneeded = 0;
116 for (cp = cmds; ; cp++) {
117 if (cp->c_name == 0)
118 abort ("invalid argument: %s", *argv);
119 if (cp->c_func == setnet)
120 argneeded++;
121 if (strcmp (cp->c_name, *argv) == 0) {
122 if (argneeded) {
123 if (argv[1]) {
124 argv++;
125 (*cp->c_func) (*argv);
126 } else
127 abort ("argument expect after %s", *argv);
128 } else
129 (*cp->c_func) (cp->c_arg);
130 break;
131 }
132 }
133 argv++;
134 }
135 ifr.ifr_flags = ifflags;
136 strcpy (ifr.ifr_name, ifname);
137 if (ioctl (s, SIOCSIFFLAGS, (char *)&ifr) < 0)
138 syserr ("ioctl (SIOCSIFFLAGS)");
139
140 strcpy (ifrx25.ifr_name, ifname);
141 if (ioctl (s, SIOCSIFCONF_X25, (char *)&ifrx25) < 0)
142 syserr ("ioctl (SIOCSIFCONF_X25)");
143 exit (0);
144 }
145
146 /* VARARGS */
abort(fmt,a1,a2,a3,a4,a5)147 abort (fmt, a1, a2, a3, a4, a5)
148 char *fmt;
149 {
150 char buf[128];
151
152 sprintf (buf, "%s: %s\n", myname, fmt);
153 fprintf (stderr, buf, a1, a2, a3, a4, a5);
154 exit (1);
155 }
156
157 /* VARARGS */
syserr(fmt,a1,a2,a3,a4,a5)158 syserr (fmt, a1, a2, a3, a4, a5)
159 char *fmt;
160 {
161 char buf[128];
162 extern int errno;
163 extern char *sys_errlist[];
164
165 sprintf (buf, "%s: %s: %s\n", myname, fmt, sys_errlist[errno]);
166 fprintf (stderr, buf, a1, a2, a3, a4, a5);
167 exit (1);
168 }
169
status()170 status ()
171 {
172 char *addr = x25conf.xc_addr.x25_addr;
173
174 printf ("%s: ", ifname);
175 printb ("interface flags", ifflags, IFFBITS);
176 printf ("link level:\n");
177 printf ("\twindow size: %d\n", x25conf.xc_lwsize);
178 if (x25conf.xc_ltrace)
179 printf ("\ttracing: on\n");
180 printf ("\npacket level:\n");
181 printf ("\taddress: %04d %s\n", x25conf.xc_addr.x25_net, addr);
182 printf ("\twindow size: %d\n", x25conf.xc_pwsize);
183 printf ("\tpacket size: %d\n", 1 << x25conf.xc_psize);
184 printf ("\tmax lcn: %d\n", x25conf.xc_maxlcn);
185 if (x25conf.xc_ptrace)
186 printf ("\ttracing: on\n");
187 }
188
setifflags(value)189 setifflags (value)
190 {
191
192 if (value < 0) {
193 value = -value;
194 ifflags &= ~value;
195 } else
196 ifflags |= value;
197 }
198
199 /* VARARGS */
setdefault(arg)200 setdefault (arg)
201 {
202
203 x25conf.xc_addr.x25_family = AF_CCITT;
204 x25conf.xc_lproto = CCITTPROTO_HDLC;
205 x25conf.xc_lptype = HDLCPROTO_LAPB;
206 x25conf.xc_lwsize = 7;
207
208 x25conf.xc_pwsize = 2;
209 x25conf.xc_psize = X25_PS128;
210 x25conf.xc_type = X25_1976;
211 }
212
setnet(arg)213 setnet (arg)
214 char *arg;
215 {
216 register int net;
217 register struct netent *np;
218
219 if (*arg < '0' || *arg > '9') { /* lookup name in /etc/networks */
220 if ((np = getnetbyname (arg)) == 0)
221 abort ("unknown network (%s)", arg);
222 net = np->n_net;
223 } else
224 net = atoi (arg);
225 x25conf.xc_addr.x25_net = net;
226 }
227
setntn(arg)228 setntn (arg)
229 register char *arg;
230 {
231 register int l;
232 register char *p;
233 register struct hostent *hp;
234 struct hostent *getx25hostbyname ();
235
236 if (*arg < '0' || *arg > '9') { /* lookup in /etc/x25hosts */
237 if ((hp = getx25hostbyname (arg)) == 0)
238 abort ("can't find '%s' in /etc/x25hosts", arg);
239 arg = ((struct sockaddr_x25 *)hp->h_addr)->x25_addr;
240 l = strlen (arg) + 1;
241 } else
242 for (l = 1, p = arg; *p; p++) {
243 l++;
244 if (*p < '0' || *p > '9')
245 abort ("invalid character in ntn address");
246 }
247 if (l > sizeof (x25conf.xc_addr.x25_addr))
248 abort ("invalid ntn address");
249 bcopy(arg, x25conf.xc_addr.x25_addr, l);
250 }
251
to_bcd(src,dest)252 to_bcd (src, dest)
253 register char *src, *dest;
254 {
255 register int i;
256
257 for(i = 0; *src; i++)
258 if (i & 0x01 )
259 *dest++ |= *src++ & 0x0F;
260 else
261 *dest = *src++ << 4;
262 }
263
from_bcd(src,dest,len)264 from_bcd (src, dest, len)
265 char *src, *dest;
266 {
267 register int i;
268
269 for (i = 0; i < len/2; i++) {
270 *dest++ = ((*src & 0xf0) >> 4) + '0';
271 *dest++ = (*src++ & 0xf) + '0';
272 }
273 *dest = 0;
274 }
275
setlproto(arg)276 setlproto (arg)
277 {
278 x25conf.xc_lproto = arg;
279 }
280
sethdlc(arg)281 sethdlc (arg)
282 {
283 x25conf.xc_lptype = arg;
284 }
285
setlwsize(arg)286 setlwsize (arg)
287 char *arg;
288 {
289 register int ws;
290
291 if ((ws = atoi (arg)) <= 0 ||
292 ( ws > 31 && x25conf.xc_lproto != IEEEPROTO_802LLC )
293 || ws > 127)
294 abort ("invalid link level window size");
295 x25conf.xc_lwsize = ws;
296 }
297
setlkeepalive(arg)298 setlkeepalive (arg)
299 int arg;
300 {
301 /* x25conf.xc_lkeepalive = arg; */
302 }
303
setltrace(arg)304 setltrace (arg)
305 {
306 x25conf.xc_ltrace = arg;
307 }
308
setyear(arg)309 setyear (arg)
310 {
311 x25conf.xc_type = arg;
312 switch (arg) {
313 case X25_1976:
314 return;
315
316 case X25_1980:
317 case X25_1984:
318 x25conf.xc_pwsize = 7;
319 x25conf.xc_psize = 12; /* 4096 bytes */
320 }
321 }
322
setpwsize(arg)323 setpwsize (arg)
324 char *arg;
325 {
326 register int ws;
327
328 if ((ws = atoi (arg)) <= 0 || ws > 7)
329 abort ("invalid packet level window size");
330 x25conf.xc_pwsize = ws;
331 }
332
setpacketsize(arg)333 setpacketsize (arg)
334 char *arg;
335 {
336 register int psize, logpsize = 0;
337
338 if ((psize = atoi (arg)) < 64 || psize > 4096)
339 abort ("invalid packet size");
340 while (psize > 1) {
341 psize >>= 1;
342 logpsize++;
343 }
344 x25conf.xc_psize = logpsize;
345 }
346
setmaxlcn(arg)347 setmaxlcn (arg)
348 char *arg;
349 {
350 register int lcn;
351
352 if ((lcn = atoi (arg)) <= 0)
353 abort ("invalid maximum lcn");
354 x25conf.xc_maxlcn = lcn;
355 }
356
setptrace(arg)357 setptrace (arg)
358 {
359 x25conf.xc_ptrace = arg;
360 }
361
362 /*
363 * Print a value a la the %b format of the kernel's printf
364 */
365
printb(s,v,bits)366 printb(s, v, bits)
367 char *s;
368 register char *bits;
369 register unsigned short v;
370 {
371 register int i, any = 0;
372 register char c;
373
374 if (bits && *bits == 8)
375 printf("%s=%o", s, v);
376 else
377 printf("%s=%x", s, v);
378 bits++;
379 if (bits) {
380 putchar('<');
381 while (i = *bits++) {
382 if (v & (1 << (i-1))) {
383 if (any)
384 putchar(',');
385 any = 1;
386 for (; (c = *bits) > 32; bits++)
387 putchar(c);
388 } else
389 for (; *bits > 32; bits++)
390 ;
391 }
392 putchar('>');
393 putchar('\n');
394 }
395 }
396