xref: /csrg-svn/sbin/ifconfig/ifconfig.c (revision 30692)
121811Skarels /*
221811Skarels  * Copyright (c) 1983 Regents of the University of California.
321811Skarels  * All rights reserved.  The Berkeley software License Agreement
421811Skarels  * specifies the terms and conditions for redistribution.
521811Skarels  */
621811Skarels 
714869Ssam #ifndef lint
821811Skarels char copyright[] =
921811Skarels "@(#) Copyright (c) 1983 Regents of the University of California.\n\
1021811Skarels  All rights reserved.\n";
1121811Skarels #endif not lint
1214869Ssam 
1321811Skarels #ifndef lint
14*30692Smckusick static char sccsid[] = "@(#)ifconfig.c	4.19 (Berkeley) 03/29/87";
1521811Skarels #endif not lint
1621811Skarels 
1714869Ssam #include <sys/types.h>
1814869Ssam #include <sys/socket.h>
1914869Ssam #include <sys/ioctl.h>
2014869Ssam 
2122485Ssklower #include <net/if.h>
2214869Ssam #include <netinet/in.h>
2314869Ssam 
2422485Ssklower #define	NSIP
2522485Ssklower #include <netns/ns.h>
2622485Ssklower #include <netns/ns_if.h>
2722485Ssklower 
2814869Ssam #include <stdio.h>
2914869Ssam #include <errno.h>
3014869Ssam #include <ctype.h>
3114869Ssam #include <netdb.h>
3214869Ssam 
3322485Ssklower extern int errno;
3414869Ssam struct	ifreq ifr;
3514869Ssam struct	sockaddr_in sin = { AF_INET };
3621811Skarels struct	sockaddr_in broadaddr;
3721811Skarels struct	sockaddr_in netmask = { AF_INET };
3822485Ssklower struct	sockaddr_in ipdst = { AF_INET };
3914869Ssam char	name[30];
4021811Skarels int	flags;
4126185Skarels int	metric;
4216329Skarels int	setaddr;
4321811Skarels int	setmask;
4421811Skarels int	setbroadaddr;
4522485Ssklower int	setipdst;
4614869Ssam int	s;
4721811Skarels extern	int errno;
4814869Ssam 
4921811Skarels int	setifflags(), setifaddr(), setifdstaddr(), setifnetmask();
5026185Skarels int	setifmetric(), setifbroadaddr(), setifipdst();
5114869Ssam 
5221811Skarels #define	NEXTARG		0xffffff
5321811Skarels 
5414869Ssam struct	cmd {
5514869Ssam 	char	*c_name;
5621811Skarels 	int	c_parameter;		/* NEXTARG means next argv */
5714869Ssam 	int	(*c_func)();
5814869Ssam } cmds[] = {
5914869Ssam 	{ "up",		IFF_UP,		setifflags } ,
6014869Ssam 	{ "down",	-IFF_UP,	setifflags },
6114869Ssam 	{ "trailers",	-IFF_NOTRAILERS,setifflags },
6214869Ssam 	{ "-trailers",	IFF_NOTRAILERS,	setifflags },
6315359Skarels 	{ "arp",	-IFF_NOARP,	setifflags },
6415359Skarels 	{ "-arp",	IFF_NOARP,	setifflags },
6515286Sleres 	{ "debug",	IFF_DEBUG,	setifflags },
6615286Sleres 	{ "-debug",	-IFF_DEBUG,	setifflags },
6715004Ssam #ifdef notdef
6821811Skarels #define	EN_SWABIPS	0x1000
6915004Ssam 	{ "swabips",	EN_SWABIPS,	setifflags },
7015004Ssam 	{ "-swabips",	-EN_SWABIPS,	setifflags },
7115004Ssam #endif
7221811Skarels 	{ "netmask",	NEXTARG,	setifnetmask },
7326185Skarels 	{ "metric",	NEXTARG,	setifmetric },
7421811Skarels 	{ "broadcast",	NEXTARG,	setifbroadaddr },
7522485Ssklower 	{ "ipdst",	NEXTARG,	setifipdst },
7614869Ssam 	{ 0,		0,		setifaddr },
7717218Stef 	{ 0,		0,		setifdstaddr },
7814869Ssam };
7914869Ssam 
8022485Ssklower /*
8122485Ssklower  * XNS support liberally adapted from
8222485Ssklower  * code written at the University of Maryland
8322485Ssklower  * principally by James O'Toole and Chris Torek.
8422485Ssklower  */
8522485Ssklower 
8622485Ssklower int	in_status(), in_getaddr();
8722485Ssklower int	xns_status(), xns_getaddr();
8822485Ssklower 
8922485Ssklower /* Known address families */
9022485Ssklower struct afswtch {
9122485Ssklower 	char *af_name;
9222485Ssklower 	short af_af;
9322485Ssklower 	int (*af_status)();
9422485Ssklower 	int (*af_getaddr)();
9522485Ssklower } afs[] = {
9622485Ssklower 	{ "inet",	AF_INET,	in_status,	in_getaddr },
9722485Ssklower 	{ "ns",		AF_NS,		xns_status,	xns_getaddr },
9822485Ssklower 	{ 0,		0,		0,		0 }
9922485Ssklower };
10022485Ssklower 
10122485Ssklower struct afswtch *afp;	/*the address family being set or asked about*/
10222485Ssklower 
10314869Ssam main(argc, argv)
10414869Ssam 	int argc;
10514869Ssam 	char *argv[];
10614869Ssam {
10722485Ssklower 	int af = AF_INET;
10827061Skarels 
10914869Ssam 	if (argc < 2) {
11026185Skarels 		fprintf(stderr, "usage: ifconfig interface\n%s%s%s%s",
11126185Skarels 		    "\t[ af [ address [ dest_addr ] ] [ up ] [ down ]",
11226185Skarels 			    "[ netmask mask ] ]\n",
11326185Skarels 		    "\t[ metric n ]\n",
11426185Skarels 		    "\t[ trailers | -trailers ]\n",
11526185Skarels 		    "\t[ arp | -arp ]\n");
11614869Ssam 		exit(1);
11714869Ssam 	}
11822485Ssklower 	argc--, argv++;
11924248Ssklower 	strncpy(name, *argv, sizeof(name));
12022485Ssklower 	strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
12122485Ssklower 	argc--, argv++;
12222485Ssklower 	if (argc > 0) {
12322485Ssklower 		struct afswtch *myafp;
12422485Ssklower 
12522485Ssklower 		for (myafp = afp = afs; myafp->af_name; myafp++)
12622485Ssklower 			if (strcmp(myafp->af_name, *argv) == 0) {
12722485Ssklower 				afp = myafp; argc--; argv++;
12822485Ssklower 				break;
12922485Ssklower 			}
13022485Ssklower 		af = ifr.ifr_addr.sa_family = afp->af_af;
13122485Ssklower 	}
13222485Ssklower 	s = socket(af, SOCK_DGRAM, 0);
13314869Ssam 	if (s < 0) {
13414869Ssam 		perror("ifconfig: socket");
13514869Ssam 		exit(1);
13614869Ssam 	}
13714869Ssam 	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
13814869Ssam 		Perror("ioctl (SIOCGIFFLAGS)");
13914869Ssam 		exit(1);
14014869Ssam 	}
14122485Ssklower 	strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
14221811Skarels 	flags = ifr.ifr_flags;
14326185Skarels 	if (ioctl(s, SIOCGIFMETRIC, (caddr_t)&ifr) < 0)
14426185Skarels 		perror("ioctl (SIOCGIFMETRIC)");
14526185Skarels 	else
14626185Skarels 		metric = ifr.ifr_metric;
14714869Ssam 	if (argc == 0) {
14814869Ssam 		status();
14914869Ssam 		exit(0);
15014869Ssam 	}
15114869Ssam 	while (argc > 0) {
15214869Ssam 		register struct cmd *p;
15314869Ssam 
15414869Ssam 		for (p = cmds; p->c_name; p++)
15514869Ssam 			if (strcmp(*argv, p->c_name) == 0)
15614869Ssam 				break;
15717218Stef 		if (p->c_name == 0 && setaddr)
15817218Stef 			p++;	/* got src, do dst */
15921811Skarels 		if (p->c_func) {
16021811Skarels 			if (p->c_parameter == NEXTARG) {
16121811Skarels 				(*p->c_func)(argv[1]);
16221811Skarels 				argc--, argv++;
16321811Skarels 			} else
16421811Skarels 				(*p->c_func)(*argv, p->c_parameter);
16521811Skarels 		}
16614869Ssam 		argc--, argv++;
16714869Ssam 	}
16827061Skarels 	if ((setmask || setaddr) && (af == AF_INET)) {
16921811Skarels 		/*
17021811Skarels 		 * If setting the address and not the mask,
17121811Skarels 		 * clear any existing mask and the kernel will then
17221811Skarels 		 * assign the default.  If setting both,
17321811Skarels 		 * set the mask first, so the address will be
17421811Skarels 		 * interpreted correctly.
17521811Skarels 		 */
17621811Skarels 		ifr.ifr_addr = *(struct sockaddr *)&netmask;
17721811Skarels 		if (ioctl(s, SIOCSIFNETMASK, (caddr_t)&ifr) < 0)
17821811Skarels 			Perror("ioctl (SIOCSIFNETMASK)");
17921811Skarels 	}
18022485Ssklower 	if (setipdst && af==AF_NS) {
18122485Ssklower 		struct nsip_req rq;
18222485Ssklower 		int size = sizeof(rq);
18322485Ssklower 
18422485Ssklower 		rq.rq_ns = *(struct sockaddr *) &sin;
18522485Ssklower 		rq.rq_ip = *(struct sockaddr *) &ipdst;
18622485Ssklower 
18722485Ssklower 		if (setsockopt(s, 0, SO_NSIP_ROUTE, &rq, size) < 0)
18822485Ssklower 			Perror("Encapsulation Routing");
18922485Ssklower 		setaddr = 0;
19022485Ssklower 	}
19116329Skarels 	if (setaddr) {
19216329Skarels 		ifr.ifr_addr = *(struct sockaddr *) &sin;
19316329Skarels 		if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0)
19416329Skarels 			Perror("ioctl (SIOCSIFADDR)");
19516329Skarels 	}
19621811Skarels 	if (setbroadaddr) {
19721811Skarels 		ifr.ifr_addr = *(struct sockaddr *)&broadaddr;
19821811Skarels 		if (ioctl(s, SIOCSIFBRDADDR, (caddr_t)&ifr) < 0)
19921811Skarels 			Perror("ioctl (SIOCSIFBRDADDR)");
20021811Skarels 	}
20114869Ssam 	exit(0);
20214869Ssam }
20314869Ssam 
20414869Ssam /*ARGSUSED*/
20514869Ssam setifaddr(addr, param)
20614869Ssam 	char *addr;
20722485Ssklower 	short param;
20814869Ssam {
20916329Skarels 	/*
21016329Skarels 	 * Delay the ioctl to set the interface addr until flags are all set.
21116329Skarels 	 * The address interpretation may depend on the flags,
21216329Skarels 	 * and the flags may change when the address is set.
21315390Skarels 	 */
21416329Skarels 	setaddr++;
21522485Ssklower 	(*afp->af_getaddr)(addr, &sin);
21614869Ssam }
21714869Ssam 
21821811Skarels setifnetmask(addr)
21921811Skarels 	char *addr;
22021811Skarels {
22122485Ssklower 	in_getaddr(addr, &netmask);
22221811Skarels 	setmask++;
22321811Skarels }
22421811Skarels 
22521811Skarels setifbroadaddr(addr)
22621811Skarels 	char *addr;
22721811Skarels {
22822485Ssklower 	(*afp->af_getaddr)(addr, &broadaddr);
22921811Skarels 	setbroadaddr++;
23021811Skarels }
23121811Skarels 
23222485Ssklower setifipdst(addr)
23322485Ssklower 	char *addr;
23422485Ssklower {
23522485Ssklower 	in_getaddr(addr, &ipdst);
23622485Ssklower 	setipdst++;
23722485Ssklower }
23822485Ssklower 
23917218Stef /*ARGSUSED*/
24017218Stef setifdstaddr(addr, param)
24117218Stef 	char *addr;
24217218Stef 	int param;
24317218Stef {
24417218Stef 
24522485Ssklower 	(*afp->af_getaddr)(addr, &ifr.ifr_addr);
24617218Stef 	if (ioctl(s, SIOCSIFDSTADDR, (caddr_t)&ifr) < 0)
24717218Stef 		Perror("ioctl (SIOCSIFDSTADDR)");
24817218Stef }
24917218Stef 
25014870Ssam setifflags(vname, value)
25114870Ssam 	char *vname;
25222485Ssklower 	short value;
25314869Ssam {
25422485Ssklower  	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
25522485Ssklower  		Perror("ioctl (SIOCGIFFLAGS)");
25622485Ssklower  		exit(1);
25722485Ssklower  	}
25822485Ssklower 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
25922485Ssklower  	flags = ifr.ifr_flags;
26014869Ssam 
26114869Ssam 	if (value < 0) {
26214869Ssam 		value = -value;
26321811Skarels 		flags &= ~value;
26414869Ssam 	} else
26521811Skarels 		flags |= value;
26621811Skarels 	ifr.ifr_flags = flags;
26714869Ssam 	if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
26814870Ssam 		Perror(vname);
26914869Ssam }
27014869Ssam 
27126185Skarels setifmetric(val)
27226185Skarels 	char *val;
27326185Skarels {
27426185Skarels 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
27526185Skarels 	ifr.ifr_metric = atoi(val);
27626185Skarels 	if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0)
27726185Skarels 		perror("ioctl (set metric)");
27826185Skarels }
27926185Skarels 
28026185Skarels #define	IFFBITS \
28126185Skarels "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
28226185Skarels "
28326185Skarels 
28422485Ssklower /*
28522485Ssklower  * Print the status of the interface.  If an address family was
28622485Ssklower  * specified, show it and it only; otherwise, show them all.
28722485Ssklower  */
28814869Ssam status()
28914869Ssam {
29022485Ssklower 	register struct afswtch *p = afp;
29122485Ssklower 	short af = ifr.ifr_addr.sa_family;
29222485Ssklower 
29326185Skarels 	printf("%s: ", name);
29426185Skarels 	printb("flags", flags, IFFBITS);
29526185Skarels 	if (metric)
29626185Skarels 		printf(" metric %d", metric);
29726185Skarels 	putchar('\n');
29822485Ssklower 	if ((p = afp) != NULL) {
29928468Skarels 		(*p->af_status)(1);
30028468Skarels 	} else for (p = afs; p->af_name; p++) {
30122485Ssklower 		ifr.ifr_addr.sa_family = p->af_af;
30228468Skarels 		(*p->af_status)(0);
30322485Ssklower 	}
30422485Ssklower }
30522485Ssklower 
30628468Skarels in_status(force)
30728468Skarels 	int force;
30822485Ssklower {
30914869Ssam 	struct sockaddr_in *sin;
31022485Ssklower 	char *inet_ntoa();
31114869Ssam 
31227061Skarels 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
31321811Skarels 	if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
31428468Skarels 		if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
31528468Skarels 			if (!force)
31628468Skarels 				return;
31721811Skarels 			bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
31828468Skarels 		} else
31928468Skarels 			perror("ioctl (SIOCGIFADDR)");
32021811Skarels 	}
32114869Ssam 	sin = (struct sockaddr_in *)&ifr.ifr_addr;
32226429Skarels 	printf("\tinet %s ", inet_ntoa(sin->sin_addr));
32328468Skarels 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
32428468Skarels 	if (ioctl(s, SIOCGIFNETMASK, (caddr_t)&ifr) < 0) {
32528468Skarels 		if (errno != EADDRNOTAVAIL)
32628468Skarels 			perror("ioctl (SIOCGIFNETMASK)");
32728468Skarels 		bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
32828468Skarels 	} else
32928468Skarels 		netmask.sin_addr =
33028468Skarels 		    ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
33117218Stef 	if (flags & IFF_POINTOPOINT) {
33221811Skarels 		if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
33321811Skarels 			if (errno == EADDRNOTAVAIL)
33421811Skarels 			    bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
33521811Skarels 			else
33628468Skarels 			    perror("ioctl (SIOCGIFDSTADDR)");
33721811Skarels 		}
33822485Ssklower 		strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
33917218Stef 		sin = (struct sockaddr_in *)&ifr.ifr_dstaddr;
34017218Stef 		printf("--> %s ", inet_ntoa(sin->sin_addr));
34117218Stef 	}
34221811Skarels 	printf("netmask %x ", ntohl(netmask.sin_addr.s_addr));
34321811Skarels 	if (flags & IFF_BROADCAST) {
34421811Skarels 		if (ioctl(s, SIOCGIFBRDADDR, (caddr_t)&ifr) < 0) {
34521811Skarels 			if (errno == EADDRNOTAVAIL)
34628468Skarels 			    bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
34728468Skarels 			else
34828468Skarels 			    perror("ioctl (SIOCGIFADDR)");
34921811Skarels 		}
35022485Ssklower 		strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
35121811Skarels 		sin = (struct sockaddr_in *)&ifr.ifr_addr;
35228468Skarels 		if (sin->sin_addr.s_addr != 0)
35328468Skarels 			printf("broadcast %s", inet_ntoa(sin->sin_addr));
35421811Skarels 	}
35526185Skarels 	putchar('\n');
35614869Ssam }
35714869Ssam 
35822485Ssklower 
35928468Skarels xns_status(force)
36028468Skarels 	int force;
36122485Ssklower {
36222485Ssklower 	struct sockaddr_ns *sns;
36322485Ssklower 
36422485Ssklower 	close(s);
36522485Ssklower 	s = socket(AF_NS, SOCK_DGRAM, 0);
36622485Ssklower 	if (s < 0) {
367*30692Smckusick 		if (errno == EPROTONOSUPPORT)
36824248Ssklower 			return;
36922485Ssklower 		perror("ifconfig: socket");
37022485Ssklower 		exit(1);
37122485Ssklower 	}
37222485Ssklower 	if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
37328468Skarels 		if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
37428468Skarels 			if (!force)
37528468Skarels 				return;
37628468Skarels 			bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
37728468Skarels 		} else
37828468Skarels 			perror("ioctl (SIOCGIFADDR)");
37922485Ssklower 	}
38022485Ssklower 	strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
38122485Ssklower 	sns = (struct sockaddr_ns *)&ifr.ifr_addr;
38226185Skarels 	printf("\tns %s ", ns_ntoa(sns->sns_addr));
38326101Ssklower 	if (flags & IFF_POINTOPOINT) { /* by W. Nesheim@Cornell */
38426101Ssklower 		if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
38526101Ssklower 			if (errno == EADDRNOTAVAIL)
38626101Ssklower 			    bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
38726101Ssklower 			else
38826101Ssklower 			    Perror("ioctl (SIOCGIFDSTADDR)");
38926101Ssklower 		}
39026101Ssklower 		strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
39126101Ssklower 		sns = (struct sockaddr_ns *)&ifr.ifr_dstaddr;
39226101Ssklower 		printf("--> %s ", ns_ntoa(sns->sns_addr));
39326101Ssklower 	}
39422485Ssklower 	putchar('\n');
39522485Ssklower }
39622485Ssklower 
39714869Ssam Perror(cmd)
39814869Ssam 	char *cmd;
39914869Ssam {
40014869Ssam 	extern int errno;
40114869Ssam 
40214869Ssam 	fprintf(stderr, "ifconfig: ");
40314869Ssam 	switch (errno) {
40414869Ssam 
40514869Ssam 	case ENXIO:
40622485Ssklower 		fprintf(stderr, "%s: no such interface\n", cmd);
40714869Ssam 		break;
40814869Ssam 
40914869Ssam 	case EPERM:
41016822Slepreau 		fprintf(stderr, "%s: permission denied\n", cmd);
41114869Ssam 		break;
41214869Ssam 
41314869Ssam 	default:
41414869Ssam 		perror(cmd);
41514869Ssam 	}
41614869Ssam 	exit(1);
41714869Ssam }
41814869Ssam 
41914869Ssam struct	in_addr inet_makeaddr();
42014869Ssam 
42122485Ssklower in_getaddr(s, saddr)
42214869Ssam 	char *s;
42322485Ssklower 	struct sockaddr *saddr;
42414869Ssam {
42522485Ssklower 	register struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
42614869Ssam 	struct hostent *hp;
42714869Ssam 	struct netent *np;
42814869Ssam 	int val;
42914869Ssam 
43021811Skarels 	sin->sin_family = AF_INET;
43121811Skarels 	val = inet_addr(s);
43221811Skarels 	if (val != -1) {
43321811Skarels 		sin->sin_addr.s_addr = val;
43421811Skarels 		return;
43521811Skarels 	}
43614869Ssam 	hp = gethostbyname(s);
43714869Ssam 	if (hp) {
43814869Ssam 		sin->sin_family = hp->h_addrtype;
43914869Ssam 		bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
44014869Ssam 		return;
44114869Ssam 	}
44214869Ssam 	np = getnetbyname(s);
44314869Ssam 	if (np) {
44414869Ssam 		sin->sin_family = np->n_addrtype;
44514869Ssam 		sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
44614869Ssam 		return;
44714869Ssam 	}
44814869Ssam 	fprintf(stderr, "%s: bad value\n", s);
44914869Ssam 	exit(1);
45014869Ssam }
45114869Ssam 
45214869Ssam /*
45314869Ssam  * Print a value a la the %b format of the kernel's printf
45414869Ssam  */
45514869Ssam printb(s, v, bits)
45614869Ssam 	char *s;
45714869Ssam 	register char *bits;
45814869Ssam 	register unsigned short v;
45914869Ssam {
46014869Ssam 	register int i, any = 0;
46114869Ssam 	register char c;
46214869Ssam 
46314869Ssam 	if (bits && *bits == 8)
46414869Ssam 		printf("%s=%o", s, v);
46514869Ssam 	else
46614869Ssam 		printf("%s=%x", s, v);
46714869Ssam 	bits++;
46814869Ssam 	if (bits) {
46914869Ssam 		putchar('<');
47014869Ssam 		while (i = *bits++) {
47114869Ssam 			if (v & (1 << (i-1))) {
47214869Ssam 				if (any)
47314869Ssam 					putchar(',');
47414869Ssam 				any = 1;
47514869Ssam 				for (; (c = *bits) > 32; bits++)
47614869Ssam 					putchar(c);
47714869Ssam 			} else
47814869Ssam 				for (; *bits > 32; bits++)
47914869Ssam 					;
48014869Ssam 		}
48114869Ssam 		putchar('>');
48214869Ssam 	}
48314869Ssam }
48422485Ssklower 
48522485Ssklower xns_getaddr(addr, saddr)
48622485Ssklower char *addr;
48722485Ssklower struct sockaddr *saddr;
48822485Ssklower {
48926101Ssklower 	struct sockaddr_ns *sns = (struct sockaddr_ns *)saddr;
49026101Ssklower 	struct ns_addr ns_addr();
49122485Ssklower 	sns->sns_family = AF_NS;
49226101Ssklower 	sns->sns_addr = ns_addr(addr);
49322485Ssklower }
494