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