|
|
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.