xref: /csrg-svn/sbin/ifconfig/ifconfig.c (revision 14870)
114869Ssam #ifndef lint
2*14870Ssam static char sccsid[] = "@(#)ifconfig.c	4.2 (Berkeley) 08/28/83";
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];
2014869Ssam int	flags;
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 },
3414869Ssam 	{ "arp",	IFF_NOARP,	setifflags },
3514869Ssam 	{ "-arp",	-IFF_NOARP,	setifflags },
3614869Ssam 	{ 0,		0,		setifaddr },
3714869Ssam };
3814869Ssam 
3914869Ssam main(argc, argv)
4014869Ssam 	int argc;
4114869Ssam 	char *argv[];
4214869Ssam {
4314869Ssam 
4414869Ssam 	if (argc < 2) {
4514869Ssam 		fprintf(stderr, "usage: ifconfig interface %s %s %s\n",
4614869Ssam 		    "[ address ] [ up ] [ down ]",
4714869Ssam 		    "[ trailers | -trailers ]",
4814869Ssam 		    "[ arp | -arp ]");
4914869Ssam 		exit(1);
5014869Ssam 	}
5114869Ssam 	s = socket(AF_INET, SOCK_DGRAM, 0);
5214869Ssam 	if (s < 0) {
5314869Ssam 		perror("ifconfig: socket");
5414869Ssam 		exit(1);
5514869Ssam 	}
5614869Ssam 	argc--, argv++;
5714869Ssam 	strcpy(name, *argv);
5814869Ssam 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
5914869Ssam 	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
6014869Ssam 		Perror("ioctl (SIOCGIFFLAGS)");
6114869Ssam 		exit(1);
6214869Ssam 	}
6314869Ssam 	flags = ifr.ifr_flags;
6414869Ssam 	argc--, argv++;
6514869Ssam 	if (argc == 0) {
6614869Ssam 		status();
6714869Ssam 		exit(0);
6814869Ssam 	}
6914869Ssam 	while (argc > 0) {
7014869Ssam 		register struct cmd *p;
7114869Ssam 
7214869Ssam 		for (p = cmds; p->c_name; p++)
7314869Ssam 			if (strcmp(*argv, p->c_name) == 0)
7414869Ssam 				break;
7514869Ssam 		if (p->c_func)
7614869Ssam 			(*p->c_func)(*argv, p->c_parameter);
7714869Ssam 		argc--, argv++;
7814869Ssam 	}
7914869Ssam 	exit(0);
8014869Ssam }
8114869Ssam 
8214869Ssam /*ARGSUSED*/
8314869Ssam setifaddr(addr, param)
8414869Ssam 	char *addr;
8514869Ssam 	int param;
8614869Ssam {
8714869Ssam 
8814869Ssam 	getaddr(addr, (struct sockaddr_in *)&ifr.ifr_addr);
8914869Ssam 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
9014869Ssam 	if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0)
9114869Ssam 		Perror("ioctl (SIOCSIFADDR)");
9214869Ssam }
9314869Ssam 
94*14870Ssam setifflags(vname, value)
95*14870Ssam 	char *vname;
9614869Ssam 	int value;
9714869Ssam {
9814869Ssam 
9914869Ssam 	if (value < 0) {
10014869Ssam 		value = -value;
10114869Ssam 		ifr.ifr_flags = (flags &~ value);
10214869Ssam 	} else
10314869Ssam 		ifr.ifr_flags |= value;
10414869Ssam 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
10514869Ssam 	if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
106*14870Ssam 		Perror(vname);
10714869Ssam }
10814869Ssam 
10914869Ssam status()
11014869Ssam {
11114869Ssam 	struct sockaddr_in *sin;
11214869Ssam 
11314869Ssam 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
11414869Ssam 	if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0)
11514869Ssam 		Perror("ioctl (SIOCGIFADDR)");
11614869Ssam 	sin = (struct sockaddr_in *)&ifr.ifr_addr;
11714869Ssam 	printf("%s: %s ", name, inet_ntoa(sin->sin_addr));
11814869Ssam #define	IFFBITS \
11914869Ssam "\020\1UP\2BROADCAST\3DEBUG\4ROUTE\5POINTOPOINT\6NOTRAILERS\7RUNNING"
12014869Ssam 	printb("flags", flags, IFFBITS); putchar('\n');
12114869Ssam }
12214869Ssam 
12314869Ssam Perror(cmd)
12414869Ssam 	char *cmd;
12514869Ssam {
12614869Ssam 	extern int errno;
12714869Ssam 
12814869Ssam 	fprintf(stderr, "ifconfig: ");
12914869Ssam 	switch (errno) {
13014869Ssam 
13114869Ssam 	case ENXIO:
13214869Ssam 		fprintf(stderr, "%s: ", cmd);
13314869Ssam 		fprintf(stderr, "no such interface\n");
13414869Ssam 		break;
13514869Ssam 
13614869Ssam 	case EPERM:
13714869Ssam 		fprintf(stderr, "%s: permission denied\n");
13814869Ssam 		break;
13914869Ssam 
14014869Ssam 	default:
14114869Ssam 		perror(cmd);
14214869Ssam 	}
14314869Ssam 	exit(1);
14414869Ssam }
14514869Ssam 
14614869Ssam struct	in_addr inet_makeaddr();
14714869Ssam 
14814869Ssam getaddr(s, sin)
14914869Ssam 	char *s;
15014869Ssam 	struct sockaddr_in *sin;
15114869Ssam {
15214869Ssam 	struct hostent *hp;
15314869Ssam 	struct netent *np;
15414869Ssam 	int val;
15514869Ssam 
15614869Ssam 	hp = gethostbyname(s);
15714869Ssam 	if (hp) {
15814869Ssam 		sin->sin_family = hp->h_addrtype;
15914869Ssam 		bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
16014869Ssam 		return;
16114869Ssam 	}
16214869Ssam 	np = getnetbyname(s);
16314869Ssam 	if (np) {
16414869Ssam 		sin->sin_family = np->n_addrtype;
16514869Ssam 		sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
16614869Ssam 		return;
16714869Ssam 	}
16814869Ssam 	sin->sin_family = AF_INET;
16914869Ssam 	val = inet_addr(s);
17014869Ssam 	if (val != -1) {
17114869Ssam 		sin->sin_addr.s_addr = val;
17214869Ssam 		return;
17314869Ssam 	}
17414869Ssam 	val = inet_network(s);
17514869Ssam 	if (val != -1) {
17614869Ssam 		sin->sin_addr = inet_makeaddr(val, INADDR_ANY);
17714869Ssam 		return;
17814869Ssam 	}
17914869Ssam 	fprintf(stderr, "%s: bad value\n", s);
18014869Ssam 	exit(1);
18114869Ssam }
18214869Ssam 
18314869Ssam /*
18414869Ssam  * Print a value a la the %b format of the kernel's printf
18514869Ssam  */
18614869Ssam printb(s, v, bits)
18714869Ssam 	char *s;
18814869Ssam 	register char *bits;
18914869Ssam 	register unsigned short v;
19014869Ssam {
19114869Ssam 	register int i, any = 0;
19214869Ssam 	register char c;
19314869Ssam 
19414869Ssam 	if (bits && *bits == 8)
19514869Ssam 		printf("%s=%o", s, v);
19614869Ssam 	else
19714869Ssam 		printf("%s=%x", s, v);
19814869Ssam 	bits++;
19914869Ssam 	if (bits) {
20014869Ssam 		putchar('<');
20114869Ssam 		while (i = *bits++) {
20214869Ssam 			if (v & (1 << (i-1))) {
20314869Ssam 				if (any)
20414869Ssam 					putchar(',');
20514869Ssam 				any = 1;
20614869Ssam 				for (; (c = *bits) > 32; bits++)
20714869Ssam 					putchar(c);
20814869Ssam 			} else
20914869Ssam 				for (; *bits > 32; bits++)
21014869Ssam 					;
21114869Ssam 		}
21214869Ssam 		putchar('>');
21314869Ssam 	}
21414869Ssam }
215