xref: /original-bsd/contrib/usr.x25/x25config.c (revision 9e86b9c3)
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 
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 */
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 */
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 
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 
189 setifflags (value)
190 {
191 
192 	if (value < 0) {
193 		value = -value;
194 		ifflags &= ~value;
195 	} else
196 		ifflags |= value;
197 }
198 
199 /* VARARGS */
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 
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 
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 
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 
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 
276 setlproto (arg)
277 {
278 	x25conf.xc_lproto = arg;
279 }
280 
281 sethdlc (arg)
282 {
283 	x25conf.xc_lptype = arg;
284 }
285 
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 
298 setlkeepalive (arg)
299 int arg;
300 {
301 	/* x25conf.xc_lkeepalive = arg; */
302 }
303 
304 setltrace (arg)
305 {
306 	x25conf.xc_ltrace = arg;
307 }
308 
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 
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 
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 
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 
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 
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