xref: /csrg-svn/sbin/ifconfig/ifconfig.c (revision 16822)
114869Ssam #ifndef lint
2*16822Slepreau static char sccsid[] = "@(#)ifconfig.c	4.8 (Berkeley) 08/02/84";
314869Ssam #endif
414869Ssam 
514869Ssam #include <sys/types.h>
614869Ssam #include <sys/socket.h>
714869Ssam #include <sys/ioctl.h>
814869Ssam 
914869Ssam #include <netinet/in.h>
1014869Ssam #include <net/if.h>
1114869Ssam 
1214869Ssam #include <stdio.h>
1314869Ssam #include <errno.h>
1414869Ssam #include <ctype.h>
1514869Ssam #include <netdb.h>
1614869Ssam 
1714869Ssam struct	ifreq ifr;
1814869Ssam struct	sockaddr_in sin = { AF_INET };
1914869Ssam char	name[30];
2016329Skarels int	setaddr;
2114869Ssam int	s;
2214869Ssam 
2314869Ssam int	setifflags(), setifaddr();
2414869Ssam 
2514869Ssam struct	cmd {
2614869Ssam 	char	*c_name;
2714869Ssam 	int	c_parameter;
2814869Ssam 	int	(*c_func)();
2914869Ssam } cmds[] = {
3014869Ssam 	{ "up",		IFF_UP,		setifflags } ,
3114869Ssam 	{ "down",	-IFF_UP,	setifflags },
3214869Ssam 	{ "trailers",	-IFF_NOTRAILERS,setifflags },
3314869Ssam 	{ "-trailers",	IFF_NOTRAILERS,	setifflags },
3415359Skarels 	{ "arp",	-IFF_NOARP,	setifflags },
3515359Skarels 	{ "-arp",	IFF_NOARP,	setifflags },
3616329Skarels 	{ "local",	IFF_LOCAL,	setifflags },
3716329Skarels 	{ "-local",	-IFF_LOCAL,	setifflags },
3815286Sleres 	{ "debug",	IFF_DEBUG,	setifflags },
3915286Sleres 	{ "-debug",	-IFF_DEBUG,	setifflags },
4015004Ssam #ifdef notdef
4115004Ssam #define	EN_SWABIPS	0x100
4215004Ssam 	{ "swabips",	EN_SWABIPS,	setifflags },
4315004Ssam 	{ "-swabips",	-EN_SWABIPS,	setifflags },
4415004Ssam #endif
4514869Ssam 	{ 0,		0,		setifaddr },
4614869Ssam };
4714869Ssam 
4814869Ssam main(argc, argv)
4914869Ssam 	int argc;
5014869Ssam 	char *argv[];
5114869Ssam {
5214869Ssam 
5314869Ssam 	if (argc < 2) {
5414869Ssam 		fprintf(stderr, "usage: ifconfig interface %s %s %s\n",
5514869Ssam 		    "[ address ] [ up ] [ down ]",
5614869Ssam 		    "[ trailers | -trailers ]",
5714869Ssam 		    "[ arp | -arp ]");
5814869Ssam 		exit(1);
5914869Ssam 	}
6014869Ssam 	s = socket(AF_INET, SOCK_DGRAM, 0);
6114869Ssam 	if (s < 0) {
6214869Ssam 		perror("ifconfig: socket");
6314869Ssam 		exit(1);
6414869Ssam 	}
6514869Ssam 	argc--, argv++;
6614869Ssam 	strcpy(name, *argv);
6714869Ssam 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
6814869Ssam 	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
6914869Ssam 		Perror("ioctl (SIOCGIFFLAGS)");
7014869Ssam 		exit(1);
7114869Ssam 	}
7214869Ssam 	argc--, argv++;
7314869Ssam 	if (argc == 0) {
7414869Ssam 		status();
7514869Ssam 		exit(0);
7614869Ssam 	}
7714869Ssam 	while (argc > 0) {
7814869Ssam 		register struct cmd *p;
7914869Ssam 
8014869Ssam 		for (p = cmds; p->c_name; p++)
8114869Ssam 			if (strcmp(*argv, p->c_name) == 0)
8214869Ssam 				break;
8314869Ssam 		if (p->c_func)
8414869Ssam 			(*p->c_func)(*argv, p->c_parameter);
8514869Ssam 		argc--, argv++;
8614869Ssam 	}
8716329Skarels 	if (setaddr) {
8816329Skarels 		strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
8916329Skarels 		ifr.ifr_addr = *(struct sockaddr *) &sin;
9016329Skarels 		if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0)
9116329Skarels 			Perror("ioctl (SIOCSIFADDR)");
9216329Skarels 	}
9314869Ssam 	exit(0);
9414869Ssam }
9514869Ssam 
9614869Ssam /*ARGSUSED*/
9714869Ssam setifaddr(addr, param)
9814869Ssam 	char *addr;
9914869Ssam 	int param;
10014869Ssam {
10114869Ssam 
10216329Skarels 	getaddr(addr, &sin);
10316329Skarels 	/*
10416329Skarels 	 * Delay the ioctl to set the interface addr until flags are all set.
10516329Skarels 	 * The address interpretation may depend on the flags,
10616329Skarels 	 * and the flags may change when the address is set.
10715390Skarels 	 */
10816329Skarels 	setaddr++;
10914869Ssam }
11014869Ssam 
11114870Ssam setifflags(vname, value)
11214870Ssam 	char *vname;
11314869Ssam 	int value;
11414869Ssam {
11514869Ssam 
11614869Ssam 	if (value < 0) {
11714869Ssam 		value = -value;
11816329Skarels 		ifr.ifr_flags &= ~value;
11914869Ssam 	} else
12016329Skarels 		ifr.ifr_flags |= value;
12114869Ssam 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
12214869Ssam 	if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
12314870Ssam 		Perror(vname);
12414869Ssam }
12514869Ssam 
12614869Ssam status()
12714869Ssam {
12814869Ssam 	struct sockaddr_in *sin;
12916329Skarels 	int flags = ifr.ifr_flags;
13014869Ssam 
13114869Ssam 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
13214869Ssam 	if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0)
13314869Ssam 		Perror("ioctl (SIOCGIFADDR)");
13414869Ssam 	sin = (struct sockaddr_in *)&ifr.ifr_addr;
13514869Ssam 	printf("%s: %s ", name, inet_ntoa(sin->sin_addr));
13614869Ssam #define	IFFBITS \
13716329Skarels "\020\1UP\2BROADCAST\3DEBUG\4ROUTE\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
13816329Skarels \11LOCAL"
13914869Ssam 	printb("flags", flags, IFFBITS); putchar('\n');
14014869Ssam }
14114869Ssam 
14214869Ssam Perror(cmd)
14314869Ssam 	char *cmd;
14414869Ssam {
14514869Ssam 	extern int errno;
14614869Ssam 
14714869Ssam 	fprintf(stderr, "ifconfig: ");
14814869Ssam 	switch (errno) {
14914869Ssam 
15014869Ssam 	case ENXIO:
15114869Ssam 		fprintf(stderr, "%s: ", cmd);
15214869Ssam 		fprintf(stderr, "no such interface\n");
15314869Ssam 		break;
15414869Ssam 
15514869Ssam 	case EPERM:
156*16822Slepreau 		fprintf(stderr, "%s: permission denied\n", cmd);
15714869Ssam 		break;
15814869Ssam 
15914869Ssam 	default:
16014869Ssam 		perror(cmd);
16114869Ssam 	}
16214869Ssam 	exit(1);
16314869Ssam }
16414869Ssam 
16514869Ssam struct	in_addr inet_makeaddr();
16614869Ssam 
16714869Ssam getaddr(s, sin)
16814869Ssam 	char *s;
16914869Ssam 	struct sockaddr_in *sin;
17014869Ssam {
17114869Ssam 	struct hostent *hp;
17214869Ssam 	struct netent *np;
17314869Ssam 	int val;
17414869Ssam 
17514869Ssam 	hp = gethostbyname(s);
17614869Ssam 	if (hp) {
17714869Ssam 		sin->sin_family = hp->h_addrtype;
17814869Ssam 		bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
17914869Ssam 		return;
18014869Ssam 	}
18114869Ssam 	np = getnetbyname(s);
18214869Ssam 	if (np) {
18314869Ssam 		sin->sin_family = np->n_addrtype;
18414869Ssam 		sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
18514869Ssam 		return;
18614869Ssam 	}
18714869Ssam 	sin->sin_family = AF_INET;
18814869Ssam 	val = inet_addr(s);
18914869Ssam 	if (val != -1) {
19014869Ssam 		sin->sin_addr.s_addr = val;
19114869Ssam 		return;
19214869Ssam 	}
19314869Ssam 	val = inet_network(s);
19414869Ssam 	if (val != -1) {
19514869Ssam 		sin->sin_addr = inet_makeaddr(val, INADDR_ANY);
19614869Ssam 		return;
19714869Ssam 	}
19814869Ssam 	fprintf(stderr, "%s: bad value\n", s);
19914869Ssam 	exit(1);
20014869Ssam }
20114869Ssam 
20214869Ssam /*
20314869Ssam  * Print a value a la the %b format of the kernel's printf
20414869Ssam  */
20514869Ssam printb(s, v, bits)
20614869Ssam 	char *s;
20714869Ssam 	register char *bits;
20814869Ssam 	register unsigned short v;
20914869Ssam {
21014869Ssam 	register int i, any = 0;
21114869Ssam 	register char c;
21214869Ssam 
21314869Ssam 	if (bits && *bits == 8)
21414869Ssam 		printf("%s=%o", s, v);
21514869Ssam 	else
21614869Ssam 		printf("%s=%x", s, v);
21714869Ssam 	bits++;
21814869Ssam 	if (bits) {
21914869Ssam 		putchar('<');
22014869Ssam 		while (i = *bits++) {
22114869Ssam 			if (v & (1 << (i-1))) {
22214869Ssam 				if (any)
22314869Ssam 					putchar(',');
22414869Ssam 				any = 1;
22514869Ssam 				for (; (c = *bits) > 32; bits++)
22614869Ssam 					putchar(c);
22714869Ssam 			} else
22814869Ssam 				for (; *bits > 32; bits++)
22914869Ssam 					;
23014869Ssam 		}
23114869Ssam 		putchar('>');
23214869Ssam 	}
23314869Ssam }
234