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