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