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: }

Defined functions

Perror defined in line 397; used 9 times
in_getaddr defined in line 421; used 4 times
in_status defined in line 306; used 2 times
main defined in line 103; never used
printb defined in line 455; used 1 times
setifaddr defined in line 205; used 2 times
setifbroadaddr defined in line 225; used 2 times
setifdstaddr defined in line 240; used 2 times
setifflags defined in line 250; used 11 times
setifipdst defined in line 232; used 2 times
setifmetric defined in line 271; used 2 times
setifnetmask defined in line 218; used 2 times
status defined in line 282; used 1 times
xns_getaddr defined in line 485; used 2 times
xns_status defined in line 359; used 2 times

Defined variables

afp defined in line 101; used 8 times
afs defined in line 95; used 2 times
broadaddr defined in line 36; used 2 times
cmds defined in line 58; used 1 times
copyright defined in line 8; never used
flags defined in line 40; used 9 times
ifr defined in line 34; used 65 times
ipdst defined in line 38; used 2 times
metric defined in line 41; used 3 times
name defined in line 39; used 13 times
netmask defined in line 37; used 4 times
s defined in line 46; used 31 times
sccsid defined in line 14; never used
setaddr defined in line 42; used 5 times
setbroadaddr defined in line 44; used 2 times
setipdst defined in line 45; used 2 times
setmask defined in line 43; used 2 times
sin defined in line 35; used 18 times

Defined struct's

afswtch defined in line 90; used 6 times
cmd defined in line 54; used 2 times
  • in line 152(2)

Defined macros

EN_SWABIPS defined in line 68; used 2 times
IFFBITS defined in line 280; used 1 times
NEXTARG defined in line 52; used 5 times
NSIP defined in line 24; never used
Last modified: 1986-05-23
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2943
Valid CSS Valid XHTML 1.0 Strict