xref: /csrg-svn/sbin/ifconfig/ifconfig.c (revision 22485)
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*22485Ssklower static char sccsid[] = "@(#)ifconfig.c	4.12 (Berkeley) 06/06/85";
1521811Skarels #endif not lint
1621811Skarels 
1721811Skarels 
1814869Ssam #include <sys/types.h>
1914869Ssam #include <sys/socket.h>
2014869Ssam #include <sys/ioctl.h>
2114869Ssam 
22*22485Ssklower #include <net/if.h>
2314869Ssam #include <netinet/in.h>
2414869Ssam 
25*22485Ssklower #define	NSIP
26*22485Ssklower #include <netns/ns.h>
27*22485Ssklower #include <netns/ns_if.h>
28*22485Ssklower 
2914869Ssam #include <stdio.h>
3014869Ssam #include <errno.h>
3114869Ssam #include <ctype.h>
3214869Ssam #include <netdb.h>
3314869Ssam 
34*22485Ssklower extern int errno;
3514869Ssam struct	ifreq ifr;
3614869Ssam struct	sockaddr_in sin = { AF_INET };
3721811Skarels struct	sockaddr_in broadaddr;
3821811Skarels struct	sockaddr_in netmask = { AF_INET };
39*22485Ssklower struct	sockaddr_in ipdst = { AF_INET };
4014869Ssam char	name[30];
4121811Skarels int	flags;
4216329Skarels int	setaddr;
4321811Skarels int	setmask;
4421811Skarels int	setbroadaddr;
45*22485Ssklower int	setipdst;
4614869Ssam int	s;
4721811Skarels extern	int errno;
4814869Ssam 
4921811Skarels int	setifflags(), setifaddr(), setifdstaddr(), setifnetmask();
50*22485Ssklower int	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 },
6521811Skarels #ifdef IFF_LOCAL
6616329Skarels 	{ "local",	IFF_LOCAL,	setifflags },
6716329Skarels 	{ "-local",	-IFF_LOCAL,	setifflags },
6821811Skarels #endif
6915286Sleres 	{ "debug",	IFF_DEBUG,	setifflags },
7015286Sleres 	{ "-debug",	-IFF_DEBUG,	setifflags },
7115004Ssam #ifdef notdef
7221811Skarels #define	EN_SWABIPS	0x1000
7315004Ssam 	{ "swabips",	EN_SWABIPS,	setifflags },
7415004Ssam 	{ "-swabips",	-EN_SWABIPS,	setifflags },
7515004Ssam #endif
7621811Skarels 	{ "netmask",	NEXTARG,	setifnetmask },
7721811Skarels 	{ "broadcast",	NEXTARG,	setifbroadaddr },
78*22485Ssklower 	{ "ipdst",	NEXTARG,	setifipdst },
7914869Ssam 	{ 0,		0,		setifaddr },
8017218Stef 	{ 0,		0,		setifdstaddr },
8114869Ssam };
8214869Ssam 
83*22485Ssklower /*
84*22485Ssklower  * XNS support liberally adapted from
85*22485Ssklower  * code written at the University of Maryland
86*22485Ssklower  * principally by James O'Toole and Chris Torek.
87*22485Ssklower  */
88*22485Ssklower 
89*22485Ssklower int	in_status(), in_getaddr();
90*22485Ssklower int	xns_status(), xns_getaddr();
91*22485Ssklower 
92*22485Ssklower /* Known address families */
93*22485Ssklower struct afswtch {
94*22485Ssklower 	char *af_name;
95*22485Ssklower 	short af_af;
96*22485Ssklower 	int (*af_status)();
97*22485Ssklower 	int (*af_getaddr)();
98*22485Ssklower } afs[] = {
99*22485Ssklower 	{ "inet",	AF_INET,	in_status,	in_getaddr },
100*22485Ssklower 	{ "ns",		AF_NS,		xns_status,	xns_getaddr },
101*22485Ssklower 	{ 0,		0,		0,		0 }
102*22485Ssklower };
103*22485Ssklower 
104*22485Ssklower struct afswtch *afp;	/*the address family being set or asked about*/
105*22485Ssklower 
10614869Ssam main(argc, argv)
10714869Ssam 	int argc;
10814869Ssam 	char *argv[];
10914869Ssam {
110*22485Ssklower 	int af = AF_INET;
11114869Ssam 	if (argc < 2) {
112*22485Ssklower 		fprintf(stderr, "usage: ifconfig interface [ af %s %s %s %s\n",
11317218Stef 		    "[ address [ dest_addr ] ] [ up ] [ down ]",
114*22485Ssklower 		    "[ netmask mask ] ]",
11514869Ssam 		    "[ trailers | -trailers ]",
116*22485Ssklower 		    "[ arp | -arp ] ]");
11714869Ssam 		exit(1);
11814869Ssam 	}
119*22485Ssklower 	argc--, argv++;
120*22485Ssklower 	strncpy(name, *argv, sizeof(name - 1));
121*22485Ssklower 	name[sizeof name - 1] = 0;
122*22485Ssklower 	strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
123*22485Ssklower 	argc--, argv++;
124*22485Ssklower 	if (argc > 0) {
125*22485Ssklower 		struct afswtch *myafp;
126*22485Ssklower 
127*22485Ssklower 		for (myafp = afp = afs; myafp->af_name; myafp++)
128*22485Ssklower 			if (strcmp(myafp->af_name, *argv) == 0) {
129*22485Ssklower 				afp = myafp; argc--; argv++;
130*22485Ssklower 				break;
131*22485Ssklower 			}
132*22485Ssklower 		af = ifr.ifr_addr.sa_family = afp->af_af;
133*22485Ssklower 	}
134*22485Ssklower 	s = socket(af, SOCK_DGRAM, 0);
13514869Ssam 	if (s < 0) {
13614869Ssam 		perror("ifconfig: socket");
13714869Ssam 		exit(1);
13814869Ssam 	}
13914869Ssam 	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
14014869Ssam 		Perror("ioctl (SIOCGIFFLAGS)");
14114869Ssam 		exit(1);
14214869Ssam 	}
143*22485Ssklower 	strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
14421811Skarels 	flags = ifr.ifr_flags;
145*22485Ssklower 	if (af == AF_INET) {
146*22485Ssklower 		if (ioctl(s, SIOCGIFNETMASK, (caddr_t)&ifr) < 0) {
147*22485Ssklower 			if (errno != EADDRNOTAVAIL)
148*22485Ssklower 				Perror("ioctl (SIOCGIFNETMASK)");
149*22485Ssklower 		} else
150*22485Ssklower 			netmask.sin_addr =
151*22485Ssklower 			      ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
152*22485Ssklower 		strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
153*22485Ssklower 	}
15414869Ssam 	if (argc == 0) {
15514869Ssam 		status();
15614869Ssam 		exit(0);
15714869Ssam 	}
15814869Ssam 	while (argc > 0) {
15914869Ssam 		register struct cmd *p;
16014869Ssam 
16114869Ssam 		for (p = cmds; p->c_name; p++)
16214869Ssam 			if (strcmp(*argv, p->c_name) == 0)
16314869Ssam 				break;
16417218Stef 		if (p->c_name == 0 && setaddr)
16517218Stef 			p++;	/* got src, do dst */
16621811Skarels 		if (p->c_func) {
16721811Skarels 			if (p->c_parameter == NEXTARG) {
16821811Skarels 				(*p->c_func)(argv[1]);
16921811Skarels 				argc--, argv++;
17021811Skarels 			} else
17121811Skarels 				(*p->c_func)(*argv, p->c_parameter);
17221811Skarels 		}
17314869Ssam 		argc--, argv++;
17414869Ssam 	}
175*22485Ssklower 	if ((setmask || setaddr) && (af == AF_INET)){
17621811Skarels 		/*
17721811Skarels 		 * If setting the address and not the mask,
17821811Skarels 		 * clear any existing mask and the kernel will then
17921811Skarels 		 * assign the default.  If setting both,
18021811Skarels 		 * set the mask first, so the address will be
18121811Skarels 		 * interpreted correctly.
18221811Skarels 		 */
18321811Skarels 		ifr.ifr_addr = *(struct sockaddr *)&netmask;
18421811Skarels 		if (ioctl(s, SIOCSIFNETMASK, (caddr_t)&ifr) < 0)
18521811Skarels 			Perror("ioctl (SIOCSIFNETMASK)");
18621811Skarels 	}
187*22485Ssklower 	if (setipdst && af==AF_NS) {
188*22485Ssklower 		struct nsip_req rq;
189*22485Ssklower 		int size = sizeof(rq);
190*22485Ssklower 
191*22485Ssklower 		rq.rq_ns = *(struct sockaddr *) &sin;
192*22485Ssklower 		rq.rq_ip = *(struct sockaddr *) &ipdst;
193*22485Ssklower 
194*22485Ssklower 		if (setsockopt(s, 0, SO_NSIP_ROUTE, &rq, size) < 0)
195*22485Ssklower 			Perror("Encapsulation Routing");
196*22485Ssklower 		setaddr = 0;
197*22485Ssklower 	}
19816329Skarels 	if (setaddr) {
19916329Skarels 		ifr.ifr_addr = *(struct sockaddr *) &sin;
20016329Skarels 		if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0)
20116329Skarels 			Perror("ioctl (SIOCSIFADDR)");
20216329Skarels 	}
20321811Skarels 	if (setbroadaddr) {
20421811Skarels 		ifr.ifr_addr = *(struct sockaddr *)&broadaddr;
20521811Skarels 		if (ioctl(s, SIOCSIFBRDADDR, (caddr_t)&ifr) < 0)
20621811Skarels 			Perror("ioctl (SIOCSIFBRDADDR)");
20721811Skarels 	}
20814869Ssam 	exit(0);
20914869Ssam }
21014869Ssam 
21114869Ssam /*ARGSUSED*/
21214869Ssam setifaddr(addr, param)
21314869Ssam 	char *addr;
214*22485Ssklower 	short param;
21514869Ssam {
21616329Skarels 	/*
21716329Skarels 	 * Delay the ioctl to set the interface addr until flags are all set.
21816329Skarels 	 * The address interpretation may depend on the flags,
21916329Skarels 	 * and the flags may change when the address is set.
22015390Skarels 	 */
22116329Skarels 	setaddr++;
222*22485Ssklower 	(*afp->af_getaddr)(addr, &sin);
22314869Ssam }
22414869Ssam 
22521811Skarels setifnetmask(addr)
22621811Skarels 	char *addr;
22721811Skarels {
228*22485Ssklower 	in_getaddr(addr, &netmask);
22921811Skarels 	setmask++;
23021811Skarels }
23121811Skarels 
23221811Skarels setifbroadaddr(addr)
23321811Skarels 	char *addr;
23421811Skarels {
235*22485Ssklower 	(*afp->af_getaddr)(addr, &broadaddr);
23621811Skarels 	setbroadaddr++;
23721811Skarels }
23821811Skarels 
239*22485Ssklower setifipdst(addr)
240*22485Ssklower 	char *addr;
241*22485Ssklower {
242*22485Ssklower 	in_getaddr(addr, &ipdst);
243*22485Ssklower 	setipdst++;
244*22485Ssklower }
245*22485Ssklower 
24617218Stef /*ARGSUSED*/
24717218Stef setifdstaddr(addr, param)
24817218Stef 	char *addr;
24917218Stef 	int param;
25017218Stef {
25117218Stef 
252*22485Ssklower 	(*afp->af_getaddr)(addr, &ifr.ifr_addr);
25317218Stef 	if (ioctl(s, SIOCSIFDSTADDR, (caddr_t)&ifr) < 0)
25417218Stef 		Perror("ioctl (SIOCSIFDSTADDR)");
25517218Stef }
25617218Stef 
25714870Ssam setifflags(vname, value)
25814870Ssam 	char *vname;
259*22485Ssklower 	short value;
26014869Ssam {
261*22485Ssklower  	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
262*22485Ssklower  		Perror("ioctl (SIOCGIFFLAGS)");
263*22485Ssklower  		exit(1);
264*22485Ssklower  	}
265*22485Ssklower 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
266*22485Ssklower  	flags = ifr.ifr_flags;
26714869Ssam 
26814869Ssam 	if (value < 0) {
26914869Ssam 		value = -value;
27021811Skarels 		flags &= ~value;
27114869Ssam 	} else
27221811Skarels 		flags |= value;
27321811Skarels 	ifr.ifr_flags = flags;
27414869Ssam 	if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
27514870Ssam 		Perror(vname);
27614869Ssam }
27714869Ssam 
278*22485Ssklower /*
279*22485Ssklower  * Print the status of the interface.  If an address family was
280*22485Ssklower  * specified, show it and it only; otherwise, show them all.
281*22485Ssklower  */
28214869Ssam status()
28314869Ssam {
284*22485Ssklower 	register struct afswtch *p = afp;
285*22485Ssklower 	short af = ifr.ifr_addr.sa_family;
286*22485Ssklower 
287*22485Ssklower 	if ((p = afp) != NULL) {
288*22485Ssklower 		(*p->af_status)();
289*22485Ssklower 		return;
290*22485Ssklower 	}
291*22485Ssklower 	for (p = afs; p->af_name; p++) {
292*22485Ssklower 		ifr.ifr_addr.sa_family = p->af_af;
293*22485Ssklower 		(*p->af_status)();
294*22485Ssklower 	}
295*22485Ssklower }
296*22485Ssklower 
297*22485Ssklower #define	IFFBITS \
298*22485Ssklower "\020\1UP\2BROADCAST\3DEBUG\4ROUTE\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
299*22485Ssklower \11LOCAL"
300*22485Ssklower 
301*22485Ssklower in_status()
302*22485Ssklower {
30314869Ssam 	struct sockaddr_in *sin;
304*22485Ssklower 	char *inet_ntoa();
30514869Ssam 
30621811Skarels 	if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
30721811Skarels 		if (errno == EADDRNOTAVAIL)
30821811Skarels 			bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
30921811Skarels 		else
31021811Skarels 			Perror("ioctl (SIOCGIFADDR)");
31121811Skarels 	}
312*22485Ssklower 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
31314869Ssam 	sin = (struct sockaddr_in *)&ifr.ifr_addr;
31414869Ssam 	printf("%s: %s ", name, inet_ntoa(sin->sin_addr));
31517218Stef 	if (flags & IFF_POINTOPOINT) {
31621811Skarels 		if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
31721811Skarels 			if (errno == EADDRNOTAVAIL)
31821811Skarels 			    bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
31921811Skarels 			else
32021811Skarels 			    Perror("ioctl (SIOCGIFDSTADDR)");
32121811Skarels 		}
322*22485Ssklower 		strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
32317218Stef 		sin = (struct sockaddr_in *)&ifr.ifr_dstaddr;
32417218Stef 		printf("--> %s ", inet_ntoa(sin->sin_addr));
32517218Stef 	}
32621811Skarels 	printf("netmask %x ", ntohl(netmask.sin_addr.s_addr));
32714869Ssam 	printb("flags", flags, IFFBITS); putchar('\n');
32821811Skarels 	if (flags & IFF_BROADCAST) {
32921811Skarels 		if (ioctl(s, SIOCGIFBRDADDR, (caddr_t)&ifr) < 0) {
33021811Skarels 			if (errno == EADDRNOTAVAIL)
33121811Skarels 				return;
33221811Skarels 			Perror("ioctl (SIOCGIFADDR)");
33321811Skarels 		}
334*22485Ssklower 		strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
33521811Skarels 		sin = (struct sockaddr_in *)&ifr.ifr_addr;
33621811Skarels 		printf("broadcast: %s\n", inet_ntoa(sin->sin_addr));
33721811Skarels 	}
33814869Ssam }
33914869Ssam 
340*22485Ssklower 
341*22485Ssklower xns_status()
342*22485Ssklower {
343*22485Ssklower 	struct sockaddr_ns *sns;
344*22485Ssklower 	char *xns_ntoa();
345*22485Ssklower 
346*22485Ssklower 	close(s);
347*22485Ssklower 	s = socket(AF_NS, SOCK_DGRAM, 0);
348*22485Ssklower 	if (s < 0) {
349*22485Ssklower 		perror("ifconfig: socket");
350*22485Ssklower 		exit(1);
351*22485Ssklower 	}
352*22485Ssklower 	if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
353*22485Ssklower 		if (errno == EAFNOSUPPORT)
354*22485Ssklower 			return;
355*22485Ssklower 		Perror("ioctl (SIOCGIFADDR)");
356*22485Ssklower 	}
357*22485Ssklower 	strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
358*22485Ssklower 	sns = (struct sockaddr_ns *)&ifr.ifr_addr;
359*22485Ssklower 	printf("%s: xns %s ", name, xns_ntoa(sns));
360*22485Ssklower 	printb("flags", flags, IFFBITS);
361*22485Ssklower 	putchar('\n');
362*22485Ssklower }
363*22485Ssklower 
36414869Ssam Perror(cmd)
36514869Ssam 	char *cmd;
36614869Ssam {
36714869Ssam 	extern int errno;
36814869Ssam 
36914869Ssam 	fprintf(stderr, "ifconfig: ");
37014869Ssam 	switch (errno) {
37114869Ssam 
37214869Ssam 	case ENXIO:
373*22485Ssklower 		fprintf(stderr, "%s: no such interface\n", cmd);
37414869Ssam 		break;
37514869Ssam 
37614869Ssam 	case EPERM:
37716822Slepreau 		fprintf(stderr, "%s: permission denied\n", cmd);
37814869Ssam 		break;
37914869Ssam 
38014869Ssam 	default:
38114869Ssam 		perror(cmd);
38214869Ssam 	}
38314869Ssam 	exit(1);
38414869Ssam }
38514869Ssam 
38614869Ssam struct	in_addr inet_makeaddr();
38714869Ssam 
388*22485Ssklower in_getaddr(s, saddr)
38914869Ssam 	char *s;
390*22485Ssklower 	struct sockaddr *saddr;
39114869Ssam {
392*22485Ssklower 	register struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
39314869Ssam 	struct hostent *hp;
39414869Ssam 	struct netent *np;
39514869Ssam 	int val;
39614869Ssam 
39721811Skarels 	sin->sin_family = AF_INET;
39821811Skarels 	val = inet_addr(s);
39921811Skarels 	if (val != -1) {
40021811Skarels 		sin->sin_addr.s_addr = val;
40121811Skarels 		return;
40221811Skarels 	}
40314869Ssam 	hp = gethostbyname(s);
40414869Ssam 	if (hp) {
40514869Ssam 		sin->sin_family = hp->h_addrtype;
40614869Ssam 		bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
40714869Ssam 		return;
40814869Ssam 	}
40914869Ssam 	np = getnetbyname(s);
41014869Ssam 	if (np) {
41114869Ssam 		sin->sin_family = np->n_addrtype;
41214869Ssam 		sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
41314869Ssam 		return;
41414869Ssam 	}
41514869Ssam 	fprintf(stderr, "%s: bad value\n", s);
41614869Ssam 	exit(1);
41714869Ssam }
41814869Ssam 
41914869Ssam /*
42014869Ssam  * Print a value a la the %b format of the kernel's printf
42114869Ssam  */
42214869Ssam printb(s, v, bits)
42314869Ssam 	char *s;
42414869Ssam 	register char *bits;
42514869Ssam 	register unsigned short v;
42614869Ssam {
42714869Ssam 	register int i, any = 0;
42814869Ssam 	register char c;
42914869Ssam 
43014869Ssam 	if (bits && *bits == 8)
43114869Ssam 		printf("%s=%o", s, v);
43214869Ssam 	else
43314869Ssam 		printf("%s=%x", s, v);
43414869Ssam 	bits++;
43514869Ssam 	if (bits) {
43614869Ssam 		putchar('<');
43714869Ssam 		while (i = *bits++) {
43814869Ssam 			if (v & (1 << (i-1))) {
43914869Ssam 				if (any)
44014869Ssam 					putchar(',');
44114869Ssam 				any = 1;
44214869Ssam 				for (; (c = *bits) > 32; bits++)
44314869Ssam 					putchar(c);
44414869Ssam 			} else
44514869Ssam 				for (; *bits > 32; bits++)
44614869Ssam 					;
44714869Ssam 		}
44814869Ssam 		putchar('>');
44914869Ssam 	}
45014869Ssam }
451*22485Ssklower 
452*22485Ssklower #define setxnnet(a,b) {a = * (union ns_net *) &(b);}
453*22485Ssklower 
454*22485Ssklower xns_getaddr(addr, saddr)
455*22485Ssklower char *addr;
456*22485Ssklower struct sockaddr *saddr;
457*22485Ssklower {
458*22485Ssklower 	register struct sockaddr_ns *sns = (struct sockaddr_ns *)saddr;
459*22485Ssklower 	u_long netnum;
460*22485Ssklower 	char *index();
461*22485Ssklower 	register char *s = index(addr, ':');
462*22485Ssklower 	register int i;
463*22485Ssklower 
464*22485Ssklower 	if (s!=NULL) *s = 0;
465*22485Ssklower 	netnum = atoi(addr);
466*22485Ssklower 	netnum = htonl(netnum);
467*22485Ssklower 	setxnnet(sns->sns_addr.x_net, netnum);
468*22485Ssklower 	sns->sns_family = AF_NS;
469*22485Ssklower 
470*22485Ssklower 	for (i = 0; i < 6; i++) {
471*22485Ssklower 		if (s == NULL || *++s == 0)
472*22485Ssklower 			break;
473*22485Ssklower 		sns->sns_addr.x_host.c_host[i] = xtoi(s);
474*22485Ssklower 		s = index(s, '.');
475*22485Ssklower 	}
476*22485Ssklower 
477*22485Ssklower }
478*22485Ssklower 
479*22485Ssklower char *
480*22485Ssklower xns_ntoa(sns)
481*22485Ssklower register struct sockaddr_ns *sns;
482*22485Ssklower {
483*22485Ssklower 	static char buf[30];
484*22485Ssklower 
485*22485Ssklower 	sprintf (buf, "%d:%x.%x.%x.%x.%x.%x",
486*22485Ssklower 	    ntohl(ns_netof(sns->sns_addr)),
487*22485Ssklower 	    sns->sns_addr.x_host.c_host[0], sns->sns_addr.x_host.c_host[1],
488*22485Ssklower 	    sns->sns_addr.x_host.c_host[2], sns->sns_addr.x_host.c_host[3],
489*22485Ssklower 	    sns->sns_addr.x_host.c_host[4], sns->sns_addr.x_host.c_host[5]);
490*22485Ssklower 	return (buf);
491*22485Ssklower }
492*22485Ssklower 
493*22485Ssklower int xtoi(s)
494*22485Ssklower register char *s;
495*22485Ssklower {
496*22485Ssklower 	register int res = 0, delta;
497*22485Ssklower 	register char *cp;
498*22485Ssklower 	static char base[] = "0123456789ABCDEFabcdef";
499*22485Ssklower 
500*22485Ssklower 	for(; *s; s++) {
501*22485Ssklower 		cp = index(base, *s);
502*22485Ssklower 		if (cp==NULL)
503*22485Ssklower 			break;
504*22485Ssklower 		if ((delta = cp - base) > 15)
505*22485Ssklower 			delta -= 6;
506*22485Ssklower 		res = (res << 4) + delta;
507*22485Ssklower 	}
508*22485Ssklower 	return(res);
509*22485Ssklower }
510