|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that the above copyright notice and this paragraph are
7: * duplicated in all such forms and that any documentation,
8: * advertising materials, and other materials related to such
9: * distribution and use acknowledge that the software was developed
10: * by the University of California, Berkeley. The name of the
11: * University may not be used to endorse or promote products derived
12: * from this software without specific prior written permission.
13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16: */
17:
18: #ifndef lint
19: char copyright[] =
20: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
21: All rights reserved.\n";
22: #endif /* not lint */
23:
24: #ifndef lint
25: static char sccsid[] = "@(#)ifconfig.c 4.21 (Berkeley) 7/1/88";
26: #endif /* not lint */
27:
28: #include <sys/types.h>
29: #include <sys/socket.h>
30: #include <sys/ioctl.h>
31:
32: #include <net/if.h>
33: #include <netinet/in.h>
34:
35: #define NSIP
36: #include <netns/ns.h>
37: #include <netns/ns_if.h>
38:
39: #include <stdio.h>
40: #include <errno.h>
41: #include <ctype.h>
42: #include <netdb.h>
43:
44: extern int errno;
45: struct ifreq ifr;
46: struct sockaddr_in sin = { AF_INET };
47: struct sockaddr_in broadaddr;
48: struct sockaddr_in netmask = { AF_INET };
49: struct sockaddr_in ipdst = { AF_INET };
50: char name[30];
51: int flags;
52: int metric;
53: int setaddr;
54: int setmask;
55: int setbroadaddr;
56: int setipdst;
57: int s;
58: extern int errno;
59:
60: int setifflags(), setifaddr(), setifdstaddr(), setifnetmask();
61: int setifmetric(), setifbroadaddr(), setifipdst();
62:
63: #define NEXTARG 0xffffff
64:
65: struct cmd {
66: char *c_name;
67: int c_parameter; /* NEXTARG means next argv */
68: int (*c_func)();
69: } cmds[] = {
70: { "up", IFF_UP, setifflags } ,
71: { "down", -IFF_UP, setifflags },
72: { "trailers", -IFF_NOTRAILERS,setifflags },
73: { "-trailers", IFF_NOTRAILERS, setifflags },
74: { "arp", -IFF_NOARP, setifflags },
75: { "-arp", IFF_NOARP, setifflags },
76: { "debug", IFF_DEBUG, setifflags },
77: { "-debug", -IFF_DEBUG, setifflags },
78: #ifdef notdef
79: #define EN_SWABIPS 0x1000
80: { "swabips", EN_SWABIPS, setifflags },
81: { "-swabips", -EN_SWABIPS, setifflags },
82: #endif
83: { "netmask", NEXTARG, setifnetmask },
84: { "metric", NEXTARG, setifmetric },
85: { "broadcast", NEXTARG, setifbroadaddr },
86: { "ipdst", NEXTARG, setifipdst },
87: { 0, 0, setifaddr },
88: { 0, 0, setifdstaddr },
89: };
90:
91: /*
92: * XNS support liberally adapted from
93: * code written at the University of Maryland
94: * principally by James O'Toole and Chris Torek.
95: */
96:
97: int in_status(), in_getaddr();
98: int xns_status(), xns_getaddr();
99:
100: /* Known address families */
101: struct afswtch {
102: char *af_name;
103: short af_af;
104: int (*af_status)();
105: int (*af_getaddr)();
106: } afs[] = {
107: { "inet", AF_INET, in_status, in_getaddr },
108: { "ns", AF_NS, xns_status, xns_getaddr },
109: { 0, 0, 0, 0 }
110: };
111:
112: struct afswtch *afp; /*the address family being set or asked about*/
113:
114: main(argc, argv)
115: int argc;
116: char *argv[];
117: {
118: int af = AF_INET;
119:
120: if (argc < 2) {
121: fprintf(stderr, "usage: ifconfig interface\n%s%s%s%s%s",
122: "\t[ af [ address [ dest_addr ] ] [ up ] [ down ]",
123: "[ netmask mask ] ]\n",
124: "\t[ metric n ]\n",
125: "\t[ trailers | -trailers ]\n",
126: "\t[ arp | -arp ]\n");
127: exit(1);
128: }
129: argc--, argv++;
130: strncpy(name, *argv, sizeof(name));
131: strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
132: argc--, argv++;
133: if (argc > 0) {
134: struct afswtch *myafp;
135:
136: for (myafp = afp = afs; myafp->af_name; myafp++)
137: if (strcmp(myafp->af_name, *argv) == 0) {
138: afp = myafp; argc--; argv++;
139: break;
140: }
141: af = ifr.ifr_addr.sa_family = afp->af_af;
142: }
143: s = socket(af, SOCK_DGRAM, 0);
144: if (s < 0) {
145: perror("ifconfig: socket");
146: exit(1);
147: }
148: if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
149: Perror("ioctl (SIOCGIFFLAGS)");
150: exit(1);
151: }
152: strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
153: flags = ifr.ifr_flags;
154: if (ioctl(s, SIOCGIFMETRIC, (caddr_t)&ifr) < 0)
155: perror("ioctl (SIOCGIFMETRIC)");
156: else
157: metric = ifr.ifr_metric;
158: if (argc == 0) {
159: status();
160: exit(0);
161: }
162: while (argc > 0) {
163: register struct cmd *p;
164:
165: for (p = cmds; p->c_name; p++)
166: if (strcmp(*argv, p->c_name) == 0)
167: break;
168: if (p->c_name == 0 && setaddr)
169: p++; /* got src, do dst */
170: if (p->c_func) {
171: if (p->c_parameter == NEXTARG) {
172: (*p->c_func)(argv[1]);
173: argc--, argv++;
174: } else
175: (*p->c_func)(*argv, p->c_parameter);
176: }
177: argc--, argv++;
178: }
179: if ((setmask || setaddr) && (af == AF_INET)) {
180: /*
181: * If setting the address and not the mask,
182: * clear any existing mask and the kernel will then
183: * assign the default. If setting both,
184: * set the mask first, so the address will be
185: * interpreted correctly.
186: */
187: ifr.ifr_addr = *(struct sockaddr *)&netmask;
188: if (ioctl(s, SIOCSIFNETMASK, (caddr_t)&ifr) < 0)
189: Perror("ioctl (SIOCSIFNETMASK)");
190: }
191: if (setipdst && af==AF_NS) {
192: struct nsip_req rq;
193: int size = sizeof(rq);
194:
195: rq.rq_ns = *(struct sockaddr *) &sin;
196: rq.rq_ip = *(struct sockaddr *) &ipdst;
197:
198: if (setsockopt(s, 0, SO_NSIP_ROUTE, &rq, size) < 0)
199: Perror("Encapsulation Routing");
200: setaddr = 0;
201: }
202: if (setaddr) {
203: ifr.ifr_addr = *(struct sockaddr *) &sin;
204: if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0)
205: Perror("ioctl (SIOCSIFADDR)");
206: }
207: if (setbroadaddr) {
208: ifr.ifr_addr = *(struct sockaddr *)&broadaddr;
209: if (ioctl(s, SIOCSIFBRDADDR, (caddr_t)&ifr) < 0)
210: Perror("ioctl (SIOCSIFBRDADDR)");
211: }
212: exit(0);
213: }
214:
215: /*ARGSUSED*/
216: setifaddr(addr, param)
217: char *addr;
218: short param;
219: {
220: /*
221: * Delay the ioctl to set the interface addr until flags are all set.
222: * The address interpretation may depend on the flags,
223: * and the flags may change when the address is set.
224: */
225: setaddr++;
226: (*afp->af_getaddr)(addr, &sin);
227: }
228:
229: setifnetmask(addr)
230: char *addr;
231: {
232: in_getaddr(addr, &netmask);
233: setmask++;
234: }
235:
236: setifbroadaddr(addr)
237: char *addr;
238: {
239: (*afp->af_getaddr)(addr, &broadaddr);
240: setbroadaddr++;
241: }
242:
243: setifipdst(addr)
244: char *addr;
245: {
246: in_getaddr(addr, &ipdst);
247: setipdst++;
248: }
249:
250: /*ARGSUSED*/
251: setifdstaddr(addr, param)
252: char *addr;
253: int param;
254: {
255:
256: (*afp->af_getaddr)(addr, &ifr.ifr_addr);
257: if (ioctl(s, SIOCSIFDSTADDR, (caddr_t)&ifr) < 0)
258: Perror("ioctl (SIOCSIFDSTADDR)");
259: }
260:
261: setifflags(vname, value)
262: char *vname;
263: short value;
264: {
265: if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
266: Perror("ioctl (SIOCGIFFLAGS)");
267: exit(1);
268: }
269: strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
270: flags = ifr.ifr_flags;
271:
272: if (value < 0) {
273: value = -value;
274: flags &= ~value;
275: } else
276: flags |= value;
277: ifr.ifr_flags = flags;
278: if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
279: Perror(vname);
280: }
281:
282: setifmetric(val)
283: char *val;
284: {
285: strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
286: ifr.ifr_metric = atoi(val);
287: if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0)
288: perror("ioctl (set metric)");
289: }
290:
291: #define IFFBITS \
292: "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
293: "
294:
295: /*
296: * Print the status of the interface. If an address family was
297: * specified, show it and it only; otherwise, show them all.
298: */
299: status()
300: {
301: register struct afswtch *p = afp;
302: short af = ifr.ifr_addr.sa_family;
303:
304: printf("%s: ", name);
305: printb("flags", flags, IFFBITS);
306: if (metric)
307: printf(" metric %d", metric);
308: putchar('\n');
309: if ((p = afp) != NULL) {
310: (*p->af_status)(1);
311: } else for (p = afs; p->af_name; p++) {
312: ifr.ifr_addr.sa_family = p->af_af;
313: (*p->af_status)(0);
314: }
315: }
316:
317: in_status(force)
318: int force;
319: {
320: struct sockaddr_in *sin;
321: char *inet_ntoa();
322:
323: strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
324: if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
325: if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
326: if (!force)
327: return;
328: bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
329: } else
330: perror("ioctl (SIOCGIFADDR)");
331: }
332: sin = (struct sockaddr_in *)&ifr.ifr_addr;
333: printf("\tinet %s ", inet_ntoa(sin->sin_addr));
334: strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
335: if (ioctl(s, SIOCGIFNETMASK, (caddr_t)&ifr) < 0) {
336: if (errno != EADDRNOTAVAIL)
337: perror("ioctl (SIOCGIFNETMASK)");
338: bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
339: } else
340: netmask.sin_addr =
341: ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
342: if (flags & IFF_POINTOPOINT) {
343: if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
344: if (errno == EADDRNOTAVAIL)
345: bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
346: else
347: perror("ioctl (SIOCGIFDSTADDR)");
348: }
349: strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
350: sin = (struct sockaddr_in *)&ifr.ifr_dstaddr;
351: printf("--> %s ", inet_ntoa(sin->sin_addr));
352: }
353: printf("netmask %x ", ntohl(netmask.sin_addr.s_addr));
354: if (flags & IFF_BROADCAST) {
355: if (ioctl(s, SIOCGIFBRDADDR, (caddr_t)&ifr) < 0) {
356: if (errno == EADDRNOTAVAIL)
357: bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
358: else
359: perror("ioctl (SIOCGIFADDR)");
360: }
361: strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
362: sin = (struct sockaddr_in *)&ifr.ifr_addr;
363: if (sin->sin_addr.s_addr != 0)
364: printf("broadcast %s", inet_ntoa(sin->sin_addr));
365: }
366: putchar('\n');
367: }
368:
369:
370: xns_status(force)
371: int force;
372: {
373: struct sockaddr_ns *sns;
374:
375: close(s);
376: s = socket(AF_NS, SOCK_DGRAM, 0);
377: if (s < 0) {
378: if (errno == EPROTONOSUPPORT)
379: return;
380: perror("ifconfig: socket");
381: exit(1);
382: }
383: if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
384: if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
385: if (!force)
386: return;
387: bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
388: } else
389: perror("ioctl (SIOCGIFADDR)");
390: }
391: strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
392: sns = (struct sockaddr_ns *)&ifr.ifr_addr;
393: printf("\tns %s ", ns_ntoa(sns->sns_addr));
394: if (flags & IFF_POINTOPOINT) { /* by W. Nesheim@Cornell */
395: if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
396: if (errno == EADDRNOTAVAIL)
397: bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
398: else
399: Perror("ioctl (SIOCGIFDSTADDR)");
400: }
401: strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
402: sns = (struct sockaddr_ns *)&ifr.ifr_dstaddr;
403: printf("--> %s ", ns_ntoa(sns->sns_addr));
404: }
405: putchar('\n');
406: }
407:
408: Perror(cmd)
409: char *cmd;
410: {
411: extern int errno;
412:
413: fprintf(stderr, "ifconfig: ");
414: switch (errno) {
415:
416: case ENXIO:
417: fprintf(stderr, "%s: no such interface\n", cmd);
418: break;
419:
420: case EPERM:
421: fprintf(stderr, "%s: permission denied\n", cmd);
422: break;
423:
424: default:
425: perror(cmd);
426: }
427: exit(1);
428: }
429:
430: struct in_addr inet_makeaddr();
431:
432: in_getaddr(s, saddr)
433: char *s;
434: struct sockaddr *saddr;
435: {
436: register struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
437: struct hostent *hp;
438: struct netent *np;
439: int val;
440:
441: sin->sin_family = AF_INET;
442: val = inet_addr(s);
443: if (val != -1) {
444: sin->sin_addr.s_addr = val;
445: return;
446: }
447: hp = gethostbyname(s);
448: if (hp) {
449: sin->sin_family = hp->h_addrtype;
450: bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
451: return;
452: }
453: np = getnetbyname(s);
454: if (np) {
455: sin->sin_family = np->n_addrtype;
456: sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
457: return;
458: }
459: fprintf(stderr, "%s: bad value\n", s);
460: exit(1);
461: }
462:
463: /*
464: * Print a value a la the %b format of the kernel's printf
465: */
466: printb(s, v, bits)
467: char *s;
468: register char *bits;
469: register unsigned short v;
470: {
471: register int i, any = 0;
472: register char c;
473:
474: if (bits && *bits == 8)
475: printf("%s=%o", s, v);
476: else
477: printf("%s=%x", s, v);
478: bits++;
479: if (bits) {
480: putchar('<');
481: while (i = *bits++) {
482: if (v & (1 << (i-1))) {
483: if (any)
484: putchar(',');
485: any = 1;
486: for (; (c = *bits) > 32; bits++)
487: putchar(c);
488: } else
489: for (; *bits > 32; bits++)
490: ;
491: }
492: putchar('>');
493: }
494: }
495:
496: xns_getaddr(addr, saddr)
497: char *addr;
498: struct sockaddr *saddr;
499: {
500: struct sockaddr_ns *sns = (struct sockaddr_ns *)saddr;
501: struct ns_addr ns_addr();
502: sns->sns_family = AF_NS;
503: sns->sns_addr = ns_addr(addr);
504: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.