ifconfig.c revision 1.12
1/*
2 * Copyright (c) 1983 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35char copyright[] =
36"@(#) Copyright (c) 1983 Regents of the University of California.\n\
37 All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41/*static char sccsid[] = "from: @(#)ifconfig.c	5.1 (Berkeley) 2/28/91";*/
42static char rcsid[] = "$Id: ifconfig.c,v 1.12 1994/01/22 02:04:35 cgd Exp $";
43#endif /* not lint */
44
45#include <sys/param.h>
46#include <sys/socket.h>
47#include <sys/ioctl.h>
48
49#include <net/if.h>
50#include <netinet/in.h>
51#include <arpa/inet.h>
52
53#define	NSIP
54#include <netns/ns.h>
55#include <netns/ns_if.h>
56
57#define EON
58#include <netiso/iso.h>
59#include <netiso/iso_var.h>
60
61#include <netdb.h>
62#include <sys/protosw.h>
63
64#include <unistd.h>
65#include <stdio.h>
66#include <errno.h>
67#include <ctype.h>
68#include <stdlib.h>
69#include <string.h>
70#include <err.h>
71
72struct	ifreq		ifr, ridreq;
73struct	ifaliasreq	addreq;
74#ifdef	EON
75struct	iso_ifreq	iso_ridreq;
76struct	iso_aliasreq	iso_addreq;
77#endif
78struct	sockaddr_in	netmask;
79
80char	name[30];
81int	flags;
82int	metric;
83int	nsellength = 1;
84int	setaddr;
85int	setipdst;
86int	doalias;
87int	clearaddr;
88int	newaddr = 1;
89int	s;
90extern	int errno;
91
92int	setifflags(), setifaddr(), setifdstaddr(), setifnetmask();
93int	setifmetric(), setifbroadaddr(), setifipdst();
94int	notealias(), setsnpaoffset(), setnsellength();
95
96#define	NEXTARG		0xffffff
97
98struct	cmd {
99	char	*c_name;
100	int	c_parameter;		/* NEXTARG means next argv */
101	int	(*c_func)();
102} cmds[] = {
103	{ "up",		IFF_UP,		setifflags } ,
104	{ "down",	-IFF_UP,	setifflags },
105	{ "trailers",	-IFF_NOTRAILERS,setifflags },
106	{ "-trailers",	IFF_NOTRAILERS,	setifflags },
107	{ "arp",	-IFF_NOARP,	setifflags },
108	{ "-arp",	IFF_NOARP,	setifflags },
109	{ "debug",	IFF_DEBUG,	setifflags },
110	{ "-debug",	-IFF_DEBUG,	setifflags },
111	{ "link0",	IFF_LINK0,	setifflags },
112	{ "-link0",	-IFF_LINK0,	setifflags },
113	{ "link1",	IFF_LINK1,	setifflags },
114	{ "-link1",	-IFF_LINK1,	setifflags },
115	{ "link2",	IFF_LINK2,	setifflags },
116	{ "-link2",	-IFF_LINK2,	setifflags },
117	{ "alias",	IFF_UP,		notealias },
118	{ "-alias",	-IFF_UP,	notealias },
119	{ "delete",	-IFF_UP,	notealias },
120#ifdef notdef
121#define	EN_SWABIPS	0x1000
122	{ "swabips",	EN_SWABIPS,	setifflags },
123	{ "-swabips",	-EN_SWABIPS,	setifflags },
124#endif
125	{ "netmask",	NEXTARG,	setifnetmask },
126	{ "metric",	NEXTARG,	setifmetric },
127	{ "broadcast",	NEXTARG,	setifbroadaddr },
128	{ "ipdst",	NEXTARG,	setifipdst },
129	{ "snpaoffset",	NEXTARG,	setsnpaoffset },
130	{ "nsellength",	NEXTARG,	setnsellength },
131	{ 0,		0,		setifaddr },
132	{ 0,		0,		setifdstaddr },
133};
134
135/*
136 * XNS support liberally adapted from
137 * code written at the University of Maryland
138 * principally by James O'Toole and Chris Torek.
139 */
140int	in_status(), in_getaddr();
141int	in_s = -1;
142
143#ifdef NSIP
144int	xns_status(), xns_getaddr();
145int	xns_s = -1;
146#endif
147#ifdef EON
148int	iso_status(), iso_getaddr();
149int	iso_s = -1;
150#endif
151
152/* Known address families */
153struct afswtch {
154	char *af_name;
155	short af_af;
156	int (*af_status)();
157	int (*af_getaddr)();
158	int af_difaddr;
159	int af_aifaddr;
160	caddr_t af_ridreq;
161	caddr_t af_addreq;
162} afs[] = {
163#define C(x) ((caddr_t) &x)
164	{ "inet", AF_INET, in_status, in_getaddr,
165	     SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) },
166#ifdef	NSIP
167	{ "ns", AF_NS, xns_status, xns_getaddr,
168	     SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) },
169#endif
170#ifdef	EON
171	{ "iso", AF_ISO, iso_status, iso_getaddr,
172	     SIOCDIFADDR_ISO, SIOCAIFADDR_ISO, C(iso_ridreq), C(iso_addreq) },
173#endif
174	{ 0,	0,	    0,		0 }
175};
176
177struct afswtch *afp;	/*the address family being set or asked about*/
178
179main(argc, argv)
180	int argc;
181	char *argv[];
182{
183	int af = AF_INET;
184	register struct afswtch *rafp;
185	int all = 0;
186
187	if (argc < 2) {
188		fprintf(stderr, "usage: ifconfig interface\n%s%s%s%s%s%s",
189		    "\t[ af [ address [ dest_addr ] ] [ up ] [ down ] ",
190			    "[ netmask mask ] ]\n",
191		    "\t[ metric n ]\n",
192		    "\t[ arp | -arp ]\n",
193		    "\t[ link0 | -link0 ] [ link1 | -link1 ] ",
194			    "[ link2 | -link2 ]\n");
195		exit(1);
196	}
197	argc--, argv++;
198	if(strcmp(*argv, "-a")==0)
199		all = 1;
200	else {
201		strncpy(name, *argv, sizeof(name));
202		strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
203	}
204	argc--, argv++;
205	if (argc > 0) {
206		for (afp = rafp = afs; rafp->af_name; rafp++)
207			if (strcmp(rafp->af_name, *argv) == 0) {
208				afp = rafp; argc--; argv++;
209				break;
210			}
211		rafp = afp;
212		af = ifr.ifr_addr.sa_family = rafp->af_af;
213	}
214	in_s = s = socket(af, SOCK_DGRAM, 0);
215	if (s < 0) {
216		perror("ifconfig: socket");
217		exit(1);
218	}
219#ifdef NSIP
220	xns_s = socket(AF_NS, SOCK_DGRAM, 0);
221	if(xns_s < 0) {
222		if (errno != EPROTONOSUPPORT) {
223			perror("ifconfig: xns: socket");
224		}
225	}
226#endif
227#ifdef EON
228	iso_s = socket(AF_ISO, SOCK_DGRAM, 0);
229	if (iso_s < 0) {
230		if (errno != EPROTONOSUPPORT) {
231			perror("ifconfig: iso: socket");
232		}
233	}
234#endif
235
236	if(all) {
237		printall(af);
238		exit(0);
239	}
240	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
241		Perror("ioctl (SIOCGIFFLAGS)");
242		exit(1);
243	}
244	if(argc==0) {
245		handle_ifreq(&ifr);
246		exit(0);
247	}
248
249	strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
250	flags = ifr.ifr_flags;
251	if (ioctl(s, SIOCGIFMETRIC, (caddr_t)&ifr) < 0)
252		perror("ioctl (SIOCGIFMETRIC)");
253	else
254		metric = ifr.ifr_metric;
255
256	while (argc > 0) {
257		register struct cmd *p;
258
259		for (p = cmds; p->c_name; p++)
260			if (strcmp(*argv, p->c_name) == 0)
261				break;
262		if (p->c_name == 0 && setaddr)
263			p++;	/* got src, do dst */
264		if (p->c_func) {
265			if (p->c_parameter == NEXTARG) {
266				if (argv[1] == NULL)
267					errx(1, "'%s' requires argument",
268					    p->c_name);
269				(*p->c_func)(argv[1]);
270				argc--, argv++;
271			} else
272				(*p->c_func)(*argv, p->c_parameter);
273		}
274		argc--, argv++;
275	}
276	if (af == AF_ISO)
277		adjust_nsellength();
278#ifdef	NSIP
279	if (setipdst && af==AF_NS) {
280		struct nsip_req rq;
281		int size = sizeof(rq);
282
283		rq.rq_ns = addreq.ifra_addr;
284		rq.rq_ip = addreq.ifra_dstaddr;
285
286		if (setsockopt(s, 0, SO_NSIP_ROUTE, &rq, size) < 0)
287			Perror("Encapsulation Routing");
288	}
289#endif
290	if (clearaddr) {
291		int ret;
292		strncpy(rafp->af_ridreq, name, sizeof ifr.ifr_name);
293		if ((ret = ioctl(s, rafp->af_difaddr, rafp->af_ridreq)) < 0) {
294			if (errno == EADDRNOTAVAIL && (doalias >= 0)) {
295				/* means no previous address for interface */
296			} else
297				Perror("ioctl (SIOCDIFADDR)");
298		}
299	}
300	if (newaddr) {
301		strncpy(rafp->af_addreq, name, sizeof ifr.ifr_name);
302		if (ioctl(s, rafp->af_aifaddr, rafp->af_addreq) < 0)
303			Perror("ioctl (SIOCAIFADDR)");
304	}
305
306	exit(0);
307}
308
309printall()
310{
311	char inbuf[8192];
312	struct ifconf ifc;
313	struct ifreq ifreq, *ifr;
314	struct in_addr in;
315	int i, len;
316
317	ifc.ifc_len = sizeof inbuf;
318	ifc.ifc_buf = inbuf;
319	if( ioctl(s, SIOCGIFCONF, &ifc) < 0) {
320		perror("ioctl(SIOCGIFCONF)");
321		return -1;
322	}
323	ifr = ifc.ifc_req;
324	ifreq.ifr_name[0] = '\0';
325	for(i=0; i<ifc.ifc_len; i+=len, ifr=(struct ifreq *)((caddr_t)ifr+len)) {
326		len = sizeof ifr->ifr_name + ifr->ifr_addr.sa_len;
327		ifreq = *ifr;
328		if( ioctl(s, SIOCGIFFLAGS, &ifreq) < 0) {
329			perror("ioctl(SIOCGIFFLAGS)");
330			continue;
331		}
332		handle_ifreq(&ifreq);
333	}
334}
335
336struct ifseen {
337	struct ifseen *next;
338	char *name;
339} *ifshead;
340
341handle_ifreq(ifr)
342struct ifreq *ifr;
343{
344	struct ifseen *ifs;
345
346	for(ifs=ifshead; ifs; ifs=ifs->next)
347		if(strcmp(ifs->name, ifr->ifr_name)==0)
348			return;
349
350	strncpy(name, ifr->ifr_name, sizeof ifr->ifr_name);
351	flags = ifr->ifr_flags;
352
353	if (ioctl(s, SIOCGIFMETRIC, (caddr_t)ifr) < 0) {
354		perror("ioctl (SIOCGIFMETRIC)");
355		metric = 0;
356	} else
357		metric = ifr->ifr_metric;
358	status();
359
360	ifs = (struct ifseen *)malloc(sizeof *ifs);
361	ifs->name = strdup(ifr->ifr_name);
362	ifs->next = ifshead;
363	ifshead = ifs;
364}
365
366#define RIDADDR 0
367#define ADDR	1
368#define MASK	2
369#define DSTADDR	3
370
371/*ARGSUSED*/
372setifaddr(addr, param)
373	char *addr;
374	short param;
375{
376	/*
377	 * Delay the ioctl to set the interface addr until flags are all set.
378	 * The address interpretation may depend on the flags,
379	 * and the flags may change when the address is set.
380	 */
381	setaddr++;
382	if (doalias == 0)
383		clearaddr = 1;
384	(*afp->af_getaddr)(addr, (doalias >= 0 ? ADDR : RIDADDR));
385}
386
387setifnetmask(addr)
388	char *addr;
389{
390	(*afp->af_getaddr)(addr, MASK);
391}
392
393setifbroadaddr(addr)
394	char *addr;
395{
396	(*afp->af_getaddr)(addr, DSTADDR);
397}
398
399setifipdst(addr)
400	char *addr;
401{
402	in_getaddr(addr, DSTADDR);
403	setipdst++;
404	clearaddr = 0;
405	newaddr = 0;
406}
407#define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr))
408/*ARGSUSED*/
409notealias(addr, param)
410	char *addr;
411{
412	if (setaddr && doalias == 0 && param < 0)
413		bcopy((caddr_t)rqtosa(af_addreq),
414		      (caddr_t)rqtosa(af_ridreq),
415		      rqtosa(af_addreq)->sa_len);
416	doalias = param;
417	if (param < 0) {
418		clearaddr = 1;
419		newaddr = 0;
420	} else
421		clearaddr = 0;
422}
423
424/*ARGSUSED*/
425setifdstaddr(addr, param)
426	char *addr;
427	int param;
428{
429	(*afp->af_getaddr)(addr, DSTADDR);
430}
431
432setifflags(vname, value)
433	char *vname;
434	short value;
435{
436 	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
437 		Perror("ioctl (SIOCGIFFLAGS)");
438 		exit(1);
439 	}
440	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
441 	flags = ifr.ifr_flags;
442
443	if (value < 0) {
444		value = -value;
445		flags &= ~value;
446	} else
447		flags |= value;
448	ifr.ifr_flags = flags;
449	if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
450		Perror(vname);
451}
452
453setifmetric(val)
454	char *val;
455{
456	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
457	ifr.ifr_metric = atoi(val);
458	if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0)
459		perror("ioctl (set metric)");
460}
461
462setsnpaoffset(val)
463	char *val;
464{
465#ifdef	EON
466	iso_addreq.ifra_snpaoffset = atoi(val);
467#endif
468}
469
470#define	IFFBITS \
471"\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST"
472
473/*
474 * Print the status of the interface.  If an address family was
475 * specified, show it and it only; otherwise, show them all.
476 */
477status()
478{
479	register struct afswtch *p = afp;
480	short af = ifr.ifr_addr.sa_family;
481
482	printf("%s: ", name);
483	printb("flags", flags, IFFBITS);
484	if (metric)
485		printf(" metric %d", metric);
486	putchar('\n');
487	if ((p = afp) != NULL) {
488		(*p->af_status)(1);
489	} else for (p = afs; p->af_name; p++) {
490		ifr.ifr_addr.sa_family = p->af_af;
491		(*p->af_status)(0);
492	}
493}
494
495in_status(force)
496	int force;
497{
498	struct sockaddr_in *sin;
499	char *inet_ntoa();
500
501	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
502	if (ioctl(in_s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
503		if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
504			if (!force)
505				return;
506			bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
507		} else
508			perror("ioctl (SIOCGIFADDR)");
509	}
510	sin = (struct sockaddr_in *)&ifr.ifr_addr;
511	printf("\tinet %s ", inet_ntoa(sin->sin_addr));
512	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
513	if (ioctl(in_s, SIOCGIFNETMASK, (caddr_t)&ifr) < 0) {
514		if (errno != EADDRNOTAVAIL)
515			perror("ioctl (SIOCGIFNETMASK)");
516		bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
517	} else
518		netmask.sin_addr =
519		    ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
520	if (flags & IFF_POINTOPOINT) {
521		if (ioctl(in_s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
522			if (errno == EADDRNOTAVAIL)
523			    bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
524			else
525			    perror("ioctl (SIOCGIFDSTADDR)");
526		}
527		strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
528		sin = (struct sockaddr_in *)&ifr.ifr_dstaddr;
529		printf("--> %s ", inet_ntoa(sin->sin_addr));
530	}
531	printf("netmask 0x%x ", ntohl(netmask.sin_addr.s_addr));
532	if (flags & IFF_BROADCAST) {
533		if (ioctl(in_s, SIOCGIFBRDADDR, (caddr_t)&ifr) < 0) {
534			if (errno == EADDRNOTAVAIL)
535			    bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
536			else
537			    perror("ioctl (SIOCGIFADDR)");
538		}
539		strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
540		sin = (struct sockaddr_in *)&ifr.ifr_addr;
541		if (sin->sin_addr.s_addr != 0)
542			printf("broadcast %s", inet_ntoa(sin->sin_addr));
543	}
544	putchar('\n');
545}
546
547#ifdef	NSIP
548
549xns_status(force)
550	int force;
551{
552	struct sockaddr_ns *sns;
553
554	if (xns_s < 0)
555			return;
556
557	if (ioctl(xns_s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
558		if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
559			if (!force)
560				return;
561			bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
562		} else
563			perror("ioctl (SIOCGIFADDR)");
564	}
565	strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
566	sns = (struct sockaddr_ns *)&ifr.ifr_addr;
567	printf("\tns %s ", ns_ntoa(sns->sns_addr));
568	if (flags & IFF_POINTOPOINT) { /* by W. Nesheim@Cornell */
569		if (ioctl(xns_s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
570			if (errno == EADDRNOTAVAIL)
571			    bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
572			else
573			    Perror("ioctl (SIOCGIFDSTADDR)");
574		}
575		strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
576		sns = (struct sockaddr_ns *)&ifr.ifr_dstaddr;
577		printf("--> %s ", ns_ntoa(sns->sns_addr));
578	}
579	putchar('\n');
580}
581
582#endif
583#ifdef	EON
584iso_status(force)
585	int force;
586{
587	struct sockaddr_iso *siso;
588	struct iso_ifreq ifr;
589
590	if (iso_s < 0)
591			return;
592	bzero((caddr_t)&ifr, sizeof(ifr));
593	strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
594	if (ioctl(iso_s, SIOCGIFADDR_ISO, (caddr_t)&ifr) < 0) {
595		if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
596			if (!force)
597				return;
598			bzero((char *)&ifr.ifr_Addr, sizeof(ifr.ifr_Addr));
599		} else {
600			perror("ioctl (SIOCGIFADDR_ISO)");
601			exit(1);
602		}
603	}
604	strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
605	siso = &ifr.ifr_Addr;
606	printf("\tiso %s ", iso_ntoa(&siso->siso_addr));
607	if (ioctl(iso_s, SIOCGIFNETMASK_ISO, (caddr_t)&ifr) < 0) {
608		if (errno != EADDRNOTAVAIL)
609			perror("ioctl (SIOCGIFNETMASK_ISO)");
610	} else {
611		printf(" netmask %s ", iso_ntoa(&siso->siso_addr));
612	}
613	if (flags & IFF_POINTOPOINT) {
614		if (ioctl(iso_s, SIOCGIFDSTADDR_ISO, (caddr_t)&ifr) < 0) {
615			if (errno == EADDRNOTAVAIL)
616			    bzero((char *)&ifr.ifr_Addr, sizeof(ifr.ifr_Addr));
617			else
618			    Perror("ioctl (SIOCGIFDSTADDR_ISO)");
619		}
620		strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
621		siso = &ifr.ifr_Addr;
622		printf("--> %s ", iso_ntoa(&siso->siso_addr));
623	}
624	putchar('\n');
625}
626#endif
627
628Perror(cmd)
629	char *cmd;
630{
631	extern int errno;
632
633	switch (errno) {
634
635	case ENXIO:
636		errx(1, "%s: no such interface", cmd);
637		break;
638
639	case EPERM:
640		errx(1, "%s: permission denied", cmd);
641		break;
642
643	default:
644		err(1, "%s", cmd);
645	}
646}
647
648struct	in_addr inet_makeaddr();
649
650#define SIN(x) ((struct sockaddr_in *) &(x))
651struct sockaddr_in *sintab[] = {
652SIN(ridreq.ifr_addr), SIN(addreq.ifra_addr),
653SIN(addreq.ifra_mask), SIN(addreq.ifra_broadaddr)};
654
655in_getaddr(s, which)
656	char *s;
657{
658	register struct sockaddr_in *sin = sintab[which];
659	struct hostent *hp;
660	struct netent *np;
661	int val;
662
663	sin->sin_len = sizeof(*sin);
664	if (which != MASK)
665		sin->sin_family = AF_INET;
666
667	if ((val = inet_addr(s)) != -1)
668		sin->sin_addr.s_addr = val;
669	else if (hp = gethostbyname(s))
670		bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
671	else if (np = getnetbyname(s))
672		sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
673	else
674		errx(1, "%s: bad value", s);
675}
676
677/*
678 * Print a value a la the %b format of the kernel's printf
679 */
680printb(s, v, bits)
681	char *s;
682	register char *bits;
683	register unsigned short v;
684{
685	register int i, any = 0;
686	register char c;
687
688	if (bits && *bits == 8)
689		printf("%s=%o", s, v);
690	else
691		printf("%s=%x", s, v);
692	bits++;
693	if (bits) {
694		putchar('<');
695		while (i = *bits++) {
696			if (v & (1 << (i-1))) {
697				if (any)
698					putchar(',');
699				any = 1;
700				for (; (c = *bits) > 32; bits++)
701					putchar(c);
702			} else
703				for (; *bits > 32; bits++)
704					;
705		}
706		putchar('>');
707	}
708}
709#ifdef	NSIP
710
711#define SNS(x) ((struct sockaddr_ns *) &(x))
712struct sockaddr_ns *snstab[] = {
713SNS(ridreq.ifr_addr), SNS(addreq.ifra_addr),
714SNS(addreq.ifra_mask), SNS(addreq.ifra_broadaddr)};
715
716xns_getaddr(addr, which)
717char *addr;
718{
719	struct sockaddr_ns *sns = snstab[which];
720	struct ns_addr ns_addr();
721
722	sns->sns_family = AF_NS;
723	sns->sns_len = sizeof(*sns);
724	sns->sns_addr = ns_addr(addr);
725	if (which == MASK)
726		printf("Attempt to set XNS netmask will be ineffectual\n");
727}
728
729#endif
730#ifdef	EON
731#define SISO(x) ((struct sockaddr_iso *) &(x))
732struct sockaddr_iso *sisotab[] = {
733SISO(iso_ridreq.ifr_Addr), SISO(iso_addreq.ifra_addr),
734SISO(iso_addreq.ifra_mask), SISO(iso_addreq.ifra_dstaddr)};
735
736iso_getaddr(addr, which)
737char *addr;
738{
739	register struct sockaddr_iso *siso = sisotab[which];
740	struct iso_addr *iso_addr();
741	siso->siso_addr = *iso_addr(addr);
742
743	if (which == MASK) {
744		siso->siso_len = TSEL(siso) - (caddr_t)(siso);
745		siso->siso_nlen = 0;
746	} else {
747		siso->siso_len = sizeof(*siso);
748		siso->siso_family = AF_ISO;
749	}
750}
751#endif
752
753setnsellength(val)
754	char *val;
755{
756	nsellength = atoi(val);
757	if (nsellength < 0)
758		errx(1, "Negative NSEL length is absurd");
759	if (afp == 0 || afp->af_af != AF_ISO)
760		errx(1, "Setting NSEL length valid only for iso");
761}
762
763#ifdef EON
764fixnsel(s)
765register struct sockaddr_iso *s;
766{
767	if (s->siso_family == 0)
768		return;
769	s->siso_tlen = nsellength;
770}
771#endif
772
773adjust_nsellength()
774{
775#ifdef EON
776	fixnsel(sisotab[RIDADDR]);
777	fixnsel(sisotab[ADDR]);
778	fixnsel(sisotab[DSTADDR]);
779#endif
780}
781