|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)ifconfig.c 4.5 (Berkeley) 11/2/83";
3: #endif
4:
5: #include <sys/types.h>
6: #include <sys/socket.h>
7: #include <sys/ioctl.h>
8:
9: #include <netinet/in.h>
10: #include <net/if.h>
11:
12: #include <stdio.h>
13: #include <errno.h>
14: #include <ctype.h>
15: #include <netdb.h>
16: #include <strings.h>
17:
18: struct ifreq ifr;
19: struct sockaddr_in sin = { AF_INET };
20: char name[30];
21: int flags;
22: int s;
23:
24: int setifflags(), setifaddr();
25:
26: struct cmd {
27: char *c_name;
28: int c_parameter;
29: int (*c_func)();
30: } cmds[] = {
31: { "up", IFF_UP, setifflags } ,
32: { "down", -IFF_UP, setifflags },
33: { "trailers", -IFF_NOTRAILERS,setifflags },
34: { "-trailers", IFF_NOTRAILERS, setifflags },
35: { "arp", -IFF_NOARP, setifflags },
36: { "-arp", IFF_NOARP, setifflags },
37: { "debug", IFF_DEBUG, setifflags },
38: { "-debug", -IFF_DEBUG, setifflags },
39: #ifdef notdef
40: #define EN_SWABIPS 0x100
41: { "swabips", EN_SWABIPS, setifflags },
42: { "-swabips", -EN_SWABIPS, setifflags },
43: #endif
44: { 0, 0, setifaddr },
45: };
46:
47: char *malloc();
48: /*--------------------------------------------------------
49: Changes:
50:
51: . reget the interface flag before setting it (in case
52: ioctl(SIOCSIFADDR) has already changed the flag.
53:
54: . add the interface to set the Ethernet station address.
55: If the interface address is not recognized symbolically
56: and it is not Internet numeric address and its
57: syntax is "Ex.x.x.x.x.x", then the address is Ethernet
58: station address. Also enhance the parsing of Ethernet address.
59:
60: . fix the format error in Perror().
61:
62: --------------------------------------------------------*/
63: main(argc, argv)
64: int argc;
65: char *argv[];
66: {
67:
68: if (argc < 2) {
69: fprintf(stderr, "usage: ifconfig interface %s %s %s\n",
70: "[ address ] [ up ] [ down ]",
71: "[ trailers | -trailers ]",
72: "[ arp | -arp ]");
73: exit(1);
74: }
75: s = socket(AF_INET, SOCK_DGRAM, 0);
76: if (s < 0) {
77: perror("ifconfig: socket");
78: exit(1);
79: }
80: argc--, argv++;
81: strcpy(name, *argv);
82: strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
83: if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
84: Perror("ioctl (SIOCGIFFLAGS)");
85: exit(1);
86: }
87: flags = ifr.ifr_flags;
88: argc--, argv++;
89: if (argc == 0) {
90: status();
91: exit(0);
92: }
93: while (argc > 0) {
94: register struct cmd *p;
95:
96: for (p = cmds; p->c_name; p++)
97: if (strcmp(*argv, p->c_name) == 0)
98: break;
99: if (p->c_func)
100: (*p->c_func)(*argv, p->c_parameter);
101: argc--, argv++;
102: }
103: exit(0);
104: }
105:
106: /*ARGSUSED*/
107: setifaddr(addr, param)
108: char *addr;
109: int param;
110: {
111: register long val;
112:
113: val = getaddr(addr, (struct sockaddr_in *)&ifr.ifr_addr);
114: strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
115: if (val != 2) {
116: if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0)
117: Perror("ioctl (SIOCSIFADDR)");
118: }
119: else { /* Set Ethernet station address */
120: if (ioctl(s, SIOCSETETADDR, (caddr_t)&ifr) < 0)
121: Perror("ioctl (SIOCSETADDR)");
122: }
123: }
124:
125: setifflags(vname, value)
126: char *vname;
127: int value;
128: {
129: if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
130: Perror("ioctl (SIOCGIFFLAGS)");
131: exit(1);
132: }
133: flags = ifr.ifr_flags;
134:
135: if (value < 0) {
136: value = -value;
137: flags &= ~value;
138: } else
139: flags |= value;
140: ifr.ifr_flags = flags;
141: strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
142: if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
143: Perror(vname);
144: }
145:
146: status()
147: {
148: struct sockaddr_in *sin;
149:
150: strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
151: if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0)
152: Perror("ioctl (SIOCGIFADDR)");
153: sin = (struct sockaddr_in *)&ifr.ifr_addr;
154: printf("%s: %s ", name, inet_ntoa(sin->sin_addr));
155: #define IFFBITS \
156: "\020\1UP\2BROADCAST\3DEBUG\4ROUTE\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP"
157: printb("flags", flags, IFFBITS); putchar('\n');
158: }
159:
160: Perror(cmd)
161: char *cmd;
162: {
163: extern int errno;
164:
165: fprintf(stderr, "ifconfig: ");
166: switch (errno) {
167:
168: case ENXIO:
169: fprintf(stderr, "%s: ", cmd);
170: fprintf(stderr, "no such interface\n");
171: break;
172:
173: case EPERM:
174: fprintf(stderr, "%s: permission denied\n", cmd);
175: break;
176:
177: default:
178: perror(cmd);
179: }
180: exit(1);
181: }
182:
183: struct in_addr inet_makeaddr();
184:
185: getaddr(s, sin)
186: char *s;
187: struct sockaddr_in *sin;
188: {
189: struct hostent *hp;
190: struct netent *np;
191: char *s1;
192: int val;
193:
194: hp = gethostbyname(s);
195: if (hp) {
196: sin->sin_family = hp->h_addrtype;
197: bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
198: return(1);
199: }
200: np = getnetbyname(s);
201: if (np) {
202: sin->sin_family = np->n_addrtype;
203: sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
204: return(1);
205: }
206: sin->sin_family = AF_INET;
207: val = inet_addr(s);
208: if (val != -1) {
209: sin->sin_addr.s_addr = val;
210: return(1);
211: }
212: val = inet_network(s);
213: if (val != -1) {
214: sin->sin_addr = inet_makeaddr(val, INADDR_ANY);
215: return(1);
216: }
217: if ((s[0] == 'E') && (index(s,'.'))) {
218: char *nxtc;
219: long lno, ix;
220:
221: /* Get Ethernet station address */
222: s1 = malloc((unsigned)(strlen(s)+1));
223: if (!s1) {
224: fprintf(stderr,"%s: Ethernet address too long\n",s);
225: exit(1);
226: }
227: strcpy(s1,s); /* save original address for error message */
228:
229: /* Transform Ea.b.c.d.e.f to a.b.c.d.e.f. for ease of
230: parsing
231: */
232: strncpy(s,s+1,strlen(s)-1);
233: s[strlen(s)-1]='.';
234: for (ix=2; ix<8; ix++) {
235: char *t;
236:
237: nxtc = index(s,'.');
238: if (!nxtc || nxtc==s) {
239: fprintf(stderr,"%s: bad Ethernet address\n",s1);
240: exit(1);
241: }
242:
243: *nxtc++ = NULL;
244: for (t=s;*t && t<nxtc; t++) {
245: if ( !(*t>='0' && *t<='9') &&
246: !(*t>='a' && *t<='f') &&
247: !(*t>='A' && *t<='F')) {
248: fprintf(stderr,
249: "%s: bad1 Ethernet address\n",s1);
250: exit(1);
251: }
252: }
253: sscanf(s,"%x",&lno);
254: sin->sin_zero[ix]=(char)(~(lno & 0xff));
255: s = nxtc;
256: }
257: if (*s) {
258: fprintf(stderr,"%s: Ethernet address too long\n",s1);
259: exit(1);
260: }
261: #ifdef DEBUG
262: printf("\nEthernet station address : ");
263: printf("%x.%x.%x.%x.%x.%x\n",sin->sin_zero[2]&0xff,
264: sin->sin_zero[3]&0xff,sin->sin_zero[4]&0xff,
265: sin->sin_zero[5]&0xff,
266: sin->sin_zero[6]&0xff,sin->sin_zero[7]&0xff);
267: #endif DEBUG
268: return(2);
269: }
270: fprintf(stderr, "%s: bad value\n", s);
271: exit(1);
272: }
273:
274: /*
275: * Print a value a la the %b format of the kernel's printf
276: */
277: printb(s, v, bits)
278: char *s;
279: register char *bits;
280: register unsigned short v;
281: {
282: register int i, any = 0;
283: register char c;
284:
285: if (bits && *bits == 8)
286: printf("%s=%o", s, v);
287: else
288: printf("%s=%x", s, v);
289: bits++;
290: if (bits) {
291: putchar('<');
292: while (i = *bits++) {
293: if (v & (1 << (i-1))) {
294: if (any)
295: putchar(',');
296: any = 1;
297: for (; (c = *bits) > 32; bits++)
298: putchar(c);
299: } else
300: for (; *bits > 32; bits++)
301: ;
302: }
303: putchar('>');
304: }
305: }
306:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.