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