xref: /csrg-svn/sbin/ifconfig/ifconfig.c (revision 14869)
1*14869Ssam #ifndef lint
2*14869Ssam static char sccsid[] = "@(#)ifconfig.c	4.1 (Berkeley) 08/28/83";
3*14869Ssam #endif
4*14869Ssam 
5*14869Ssam #include <sys/types.h>
6*14869Ssam #include <sys/socket.h>
7*14869Ssam #include <sys/ioctl.h>
8*14869Ssam 
9*14869Ssam #include <netinet/in.h>
10*14869Ssam #include <net/if.h>
11*14869Ssam 
12*14869Ssam #include <stdio.h>
13*14869Ssam #include <errno.h>
14*14869Ssam #include <ctype.h>
15*14869Ssam #include <netdb.h>
16*14869Ssam 
17*14869Ssam struct	ifreq ifr;
18*14869Ssam struct	sockaddr_in sin = { AF_INET };
19*14869Ssam char	name[30];
20*14869Ssam int	flags;
21*14869Ssam int	s;
22*14869Ssam 
23*14869Ssam int	setifflags(), setifaddr();
24*14869Ssam 
25*14869Ssam struct	cmd {
26*14869Ssam 	char	*c_name;
27*14869Ssam 	int	c_parameter;
28*14869Ssam 	int	(*c_func)();
29*14869Ssam } cmds[] = {
30*14869Ssam 	{ "up",		IFF_UP,		setifflags } ,
31*14869Ssam 	{ "down",	-IFF_UP,	setifflags },
32*14869Ssam 	{ "trailers",	-IFF_NOTRAILERS,setifflags },
33*14869Ssam 	{ "-trailers",	IFF_NOTRAILERS,	setifflags },
34*14869Ssam 	{ "arp",	IFF_NOARP,	setifflags },
35*14869Ssam 	{ "-arp",	-IFF_NOARP,	setifflags },
36*14869Ssam 	{ 0,		0,		setifaddr },
37*14869Ssam };
38*14869Ssam 
39*14869Ssam main(argc, argv)
40*14869Ssam 	int argc;
41*14869Ssam 	char *argv[];
42*14869Ssam {
43*14869Ssam 
44*14869Ssam 	if (argc < 2) {
45*14869Ssam 		fprintf(stderr, "usage: ifconfig interface %s %s %s\n",
46*14869Ssam 		    "[ address ] [ up ] [ down ]",
47*14869Ssam 		    "[ trailers | -trailers ]",
48*14869Ssam 		    "[ arp | -arp ]");
49*14869Ssam 		exit(1);
50*14869Ssam 	}
51*14869Ssam 	s = socket(AF_INET, SOCK_DGRAM, 0);
52*14869Ssam 	if (s < 0) {
53*14869Ssam 		perror("ifconfig: socket");
54*14869Ssam 		exit(1);
55*14869Ssam 	}
56*14869Ssam 	argc--, argv++;
57*14869Ssam 	strcpy(name, *argv);
58*14869Ssam 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
59*14869Ssam 	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
60*14869Ssam 		Perror("ioctl (SIOCGIFFLAGS)");
61*14869Ssam 		exit(1);
62*14869Ssam 	}
63*14869Ssam 	flags = ifr.ifr_flags;
64*14869Ssam 	argc--, argv++;
65*14869Ssam 	if (argc == 0) {
66*14869Ssam 		status();
67*14869Ssam 		exit(0);
68*14869Ssam 	}
69*14869Ssam 	while (argc > 0) {
70*14869Ssam 		register struct cmd *p;
71*14869Ssam 
72*14869Ssam 		for (p = cmds; p->c_name; p++)
73*14869Ssam 			if (strcmp(*argv, p->c_name) == 0)
74*14869Ssam 				break;
75*14869Ssam 		if (p->c_func)
76*14869Ssam 			(*p->c_func)(*argv, p->c_parameter);
77*14869Ssam 		argc--, argv++;
78*14869Ssam 	}
79*14869Ssam 	exit(0);
80*14869Ssam }
81*14869Ssam 
82*14869Ssam /*ARGSUSED*/
83*14869Ssam setifaddr(addr, param)
84*14869Ssam 	char *addr;
85*14869Ssam 	int param;
86*14869Ssam {
87*14869Ssam 
88*14869Ssam 	getaddr(addr, (struct sockaddr_in *)&ifr.ifr_addr);
89*14869Ssam 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
90*14869Ssam 	if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0)
91*14869Ssam 		Perror("ioctl (SIOCSIFADDR)");
92*14869Ssam }
93*14869Ssam 
94*14869Ssam setifflags(name, value)
95*14869Ssam 	char *name;
96*14869Ssam 	int value;
97*14869Ssam {
98*14869Ssam 
99*14869Ssam 	if (value < 0) {
100*14869Ssam 		value = -value;
101*14869Ssam 		ifr.ifr_flags = (flags &~ value);
102*14869Ssam 	} else
103*14869Ssam 		ifr.ifr_flags |= value;
104*14869Ssam 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
105*14869Ssam 	if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
106*14869Ssam 		Perror(name);
107*14869Ssam }
108*14869Ssam 
109*14869Ssam status()
110*14869Ssam {
111*14869Ssam 	struct sockaddr_in *sin;
112*14869Ssam 
113*14869Ssam 	strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
114*14869Ssam 	if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0)
115*14869Ssam 		Perror("ioctl (SIOCGIFADDR)");
116*14869Ssam 	sin = (struct sockaddr_in *)&ifr.ifr_addr;
117*14869Ssam 	printf("%s: %s ", name, inet_ntoa(sin->sin_addr));
118*14869Ssam #define	IFFBITS \
119*14869Ssam "\020\1UP\2BROADCAST\3DEBUG\4ROUTE\5POINTOPOINT\6NOTRAILERS\7RUNNING"
120*14869Ssam 	printb("flags", flags, IFFBITS); putchar('\n');
121*14869Ssam }
122*14869Ssam 
123*14869Ssam Perror(cmd)
124*14869Ssam 	char *cmd;
125*14869Ssam {
126*14869Ssam 	extern int errno;
127*14869Ssam 
128*14869Ssam 	fprintf(stderr, "ifconfig: ");
129*14869Ssam 	switch (errno) {
130*14869Ssam 
131*14869Ssam 	case ENXIO:
132*14869Ssam 		fprintf(stderr, "%s: ", cmd);
133*14869Ssam 		fprintf(stderr, "no such interface\n");
134*14869Ssam 		break;
135*14869Ssam 
136*14869Ssam 	case EPERM:
137*14869Ssam 		fprintf(stderr, "%s: permission denied\n");
138*14869Ssam 		break;
139*14869Ssam 
140*14869Ssam 	default:
141*14869Ssam 		perror(cmd);
142*14869Ssam 	}
143*14869Ssam 	exit(1);
144*14869Ssam }
145*14869Ssam 
146*14869Ssam struct	in_addr inet_makeaddr();
147*14869Ssam 
148*14869Ssam getaddr(s, sin)
149*14869Ssam 	char *s;
150*14869Ssam 	struct sockaddr_in *sin;
151*14869Ssam {
152*14869Ssam 	struct hostent *hp;
153*14869Ssam 	struct netent *np;
154*14869Ssam 	int val;
155*14869Ssam 
156*14869Ssam 	hp = gethostbyname(s);
157*14869Ssam 	if (hp) {
158*14869Ssam 		sin->sin_family = hp->h_addrtype;
159*14869Ssam 		bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
160*14869Ssam 		return;
161*14869Ssam 	}
162*14869Ssam 	np = getnetbyname(s);
163*14869Ssam 	if (np) {
164*14869Ssam 		sin->sin_family = np->n_addrtype;
165*14869Ssam 		sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
166*14869Ssam 		return;
167*14869Ssam 	}
168*14869Ssam 	sin->sin_family = AF_INET;
169*14869Ssam 	val = inet_addr(s);
170*14869Ssam 	if (val != -1) {
171*14869Ssam 		sin->sin_addr.s_addr = val;
172*14869Ssam 		return;
173*14869Ssam 	}
174*14869Ssam 	val = inet_network(s);
175*14869Ssam 	if (val != -1) {
176*14869Ssam 		sin->sin_addr = inet_makeaddr(val, INADDR_ANY);
177*14869Ssam 		return;
178*14869Ssam 	}
179*14869Ssam 	fprintf(stderr, "%s: bad value\n", s);
180*14869Ssam 	exit(1);
181*14869Ssam }
182*14869Ssam 
183*14869Ssam /*
184*14869Ssam  * Print a value a la the %b format of the kernel's printf
185*14869Ssam  */
186*14869Ssam printb(s, v, bits)
187*14869Ssam 	char *s;
188*14869Ssam 	register char *bits;
189*14869Ssam 	register unsigned short v;
190*14869Ssam {
191*14869Ssam 	register int i, any = 0;
192*14869Ssam 	register char c;
193*14869Ssam 
194*14869Ssam 	if (bits && *bits == 8)
195*14869Ssam 		printf("%s=%o", s, v);
196*14869Ssam 	else
197*14869Ssam 		printf("%s=%x", s, v);
198*14869Ssam 	bits++;
199*14869Ssam 	if (bits) {
200*14869Ssam 		putchar('<');
201*14869Ssam 		while (i = *bits++) {
202*14869Ssam 			if (v & (1 << (i-1))) {
203*14869Ssam 				if (any)
204*14869Ssam 					putchar(',');
205*14869Ssam 				any = 1;
206*14869Ssam 				for (; (c = *bits) > 32; bits++)
207*14869Ssam 					putchar(c);
208*14869Ssam 			} else
209*14869Ssam 				for (; *bits > 32; bits++)
210*14869Ssam 					;
211*14869Ssam 		}
212*14869Ssam 		putchar('>');
213*14869Ssam 	}
214*14869Ssam }
215