114869Ssam #ifndef lint 2*16822Slepreau static char sccsid[] = "@(#)ifconfig.c 4.8 (Berkeley) 08/02/84"; 314869Ssam #endif 414869Ssam 514869Ssam #include <sys/types.h> 614869Ssam #include <sys/socket.h> 714869Ssam #include <sys/ioctl.h> 814869Ssam 914869Ssam #include <netinet/in.h> 1014869Ssam #include <net/if.h> 1114869Ssam 1214869Ssam #include <stdio.h> 1314869Ssam #include <errno.h> 1414869Ssam #include <ctype.h> 1514869Ssam #include <netdb.h> 1614869Ssam 1714869Ssam struct ifreq ifr; 1814869Ssam struct sockaddr_in sin = { AF_INET }; 1914869Ssam char name[30]; 2016329Skarels int setaddr; 2114869Ssam int s; 2214869Ssam 2314869Ssam int setifflags(), setifaddr(); 2414869Ssam 2514869Ssam struct cmd { 2614869Ssam char *c_name; 2714869Ssam int c_parameter; 2814869Ssam int (*c_func)(); 2914869Ssam } cmds[] = { 3014869Ssam { "up", IFF_UP, setifflags } , 3114869Ssam { "down", -IFF_UP, setifflags }, 3214869Ssam { "trailers", -IFF_NOTRAILERS,setifflags }, 3314869Ssam { "-trailers", IFF_NOTRAILERS, setifflags }, 3415359Skarels { "arp", -IFF_NOARP, setifflags }, 3515359Skarels { "-arp", IFF_NOARP, setifflags }, 3616329Skarels { "local", IFF_LOCAL, setifflags }, 3716329Skarels { "-local", -IFF_LOCAL, setifflags }, 3815286Sleres { "debug", IFF_DEBUG, setifflags }, 3915286Sleres { "-debug", -IFF_DEBUG, setifflags }, 4015004Ssam #ifdef notdef 4115004Ssam #define EN_SWABIPS 0x100 4215004Ssam { "swabips", EN_SWABIPS, setifflags }, 4315004Ssam { "-swabips", -EN_SWABIPS, setifflags }, 4415004Ssam #endif 4514869Ssam { 0, 0, setifaddr }, 4614869Ssam }; 4714869Ssam 4814869Ssam main(argc, argv) 4914869Ssam int argc; 5014869Ssam char *argv[]; 5114869Ssam { 5214869Ssam 5314869Ssam if (argc < 2) { 5414869Ssam fprintf(stderr, "usage: ifconfig interface %s %s %s\n", 5514869Ssam "[ address ] [ up ] [ down ]", 5614869Ssam "[ trailers | -trailers ]", 5714869Ssam "[ arp | -arp ]"); 5814869Ssam exit(1); 5914869Ssam } 6014869Ssam s = socket(AF_INET, SOCK_DGRAM, 0); 6114869Ssam if (s < 0) { 6214869Ssam perror("ifconfig: socket"); 6314869Ssam exit(1); 6414869Ssam } 6514869Ssam argc--, argv++; 6614869Ssam strcpy(name, *argv); 6714869Ssam strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 6814869Ssam if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { 6914869Ssam Perror("ioctl (SIOCGIFFLAGS)"); 7014869Ssam exit(1); 7114869Ssam } 7214869Ssam argc--, argv++; 7314869Ssam if (argc == 0) { 7414869Ssam status(); 7514869Ssam exit(0); 7614869Ssam } 7714869Ssam while (argc > 0) { 7814869Ssam register struct cmd *p; 7914869Ssam 8014869Ssam for (p = cmds; p->c_name; p++) 8114869Ssam if (strcmp(*argv, p->c_name) == 0) 8214869Ssam break; 8314869Ssam if (p->c_func) 8414869Ssam (*p->c_func)(*argv, p->c_parameter); 8514869Ssam argc--, argv++; 8614869Ssam } 8716329Skarels if (setaddr) { 8816329Skarels strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 8916329Skarels ifr.ifr_addr = *(struct sockaddr *) &sin; 9016329Skarels if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0) 9116329Skarels Perror("ioctl (SIOCSIFADDR)"); 9216329Skarels } 9314869Ssam exit(0); 9414869Ssam } 9514869Ssam 9614869Ssam /*ARGSUSED*/ 9714869Ssam setifaddr(addr, param) 9814869Ssam char *addr; 9914869Ssam int param; 10014869Ssam { 10114869Ssam 10216329Skarels getaddr(addr, &sin); 10316329Skarels /* 10416329Skarels * Delay the ioctl to set the interface addr until flags are all set. 10516329Skarels * The address interpretation may depend on the flags, 10616329Skarels * and the flags may change when the address is set. 10715390Skarels */ 10816329Skarels setaddr++; 10914869Ssam } 11014869Ssam 11114870Ssam setifflags(vname, value) 11214870Ssam char *vname; 11314869Ssam int value; 11414869Ssam { 11514869Ssam 11614869Ssam if (value < 0) { 11714869Ssam value = -value; 11816329Skarels ifr.ifr_flags &= ~value; 11914869Ssam } else 12016329Skarels ifr.ifr_flags |= value; 12114869Ssam strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 12214869Ssam if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) 12314870Ssam Perror(vname); 12414869Ssam } 12514869Ssam 12614869Ssam status() 12714869Ssam { 12814869Ssam struct sockaddr_in *sin; 12916329Skarels int flags = ifr.ifr_flags; 13014869Ssam 13114869Ssam strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); 13214869Ssam if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) 13314869Ssam Perror("ioctl (SIOCGIFADDR)"); 13414869Ssam sin = (struct sockaddr_in *)&ifr.ifr_addr; 13514869Ssam printf("%s: %s ", name, inet_ntoa(sin->sin_addr)); 13614869Ssam #define IFFBITS \ 13716329Skarels "\020\1UP\2BROADCAST\3DEBUG\4ROUTE\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\ 13816329Skarels \11LOCAL" 13914869Ssam printb("flags", flags, IFFBITS); putchar('\n'); 14014869Ssam } 14114869Ssam 14214869Ssam Perror(cmd) 14314869Ssam char *cmd; 14414869Ssam { 14514869Ssam extern int errno; 14614869Ssam 14714869Ssam fprintf(stderr, "ifconfig: "); 14814869Ssam switch (errno) { 14914869Ssam 15014869Ssam case ENXIO: 15114869Ssam fprintf(stderr, "%s: ", cmd); 15214869Ssam fprintf(stderr, "no such interface\n"); 15314869Ssam break; 15414869Ssam 15514869Ssam case EPERM: 156*16822Slepreau fprintf(stderr, "%s: permission denied\n", cmd); 15714869Ssam break; 15814869Ssam 15914869Ssam default: 16014869Ssam perror(cmd); 16114869Ssam } 16214869Ssam exit(1); 16314869Ssam } 16414869Ssam 16514869Ssam struct in_addr inet_makeaddr(); 16614869Ssam 16714869Ssam getaddr(s, sin) 16814869Ssam char *s; 16914869Ssam struct sockaddr_in *sin; 17014869Ssam { 17114869Ssam struct hostent *hp; 17214869Ssam struct netent *np; 17314869Ssam int val; 17414869Ssam 17514869Ssam hp = gethostbyname(s); 17614869Ssam if (hp) { 17714869Ssam sin->sin_family = hp->h_addrtype; 17814869Ssam bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length); 17914869Ssam return; 18014869Ssam } 18114869Ssam np = getnetbyname(s); 18214869Ssam if (np) { 18314869Ssam sin->sin_family = np->n_addrtype; 18414869Ssam sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY); 18514869Ssam return; 18614869Ssam } 18714869Ssam sin->sin_family = AF_INET; 18814869Ssam val = inet_addr(s); 18914869Ssam if (val != -1) { 19014869Ssam sin->sin_addr.s_addr = val; 19114869Ssam return; 19214869Ssam } 19314869Ssam val = inet_network(s); 19414869Ssam if (val != -1) { 19514869Ssam sin->sin_addr = inet_makeaddr(val, INADDR_ANY); 19614869Ssam return; 19714869Ssam } 19814869Ssam fprintf(stderr, "%s: bad value\n", s); 19914869Ssam exit(1); 20014869Ssam } 20114869Ssam 20214869Ssam /* 20314869Ssam * Print a value a la the %b format of the kernel's printf 20414869Ssam */ 20514869Ssam printb(s, v, bits) 20614869Ssam char *s; 20714869Ssam register char *bits; 20814869Ssam register unsigned short v; 20914869Ssam { 21014869Ssam register int i, any = 0; 21114869Ssam register char c; 21214869Ssam 21314869Ssam if (bits && *bits == 8) 21414869Ssam printf("%s=%o", s, v); 21514869Ssam else 21614869Ssam printf("%s=%x", s, v); 21714869Ssam bits++; 21814869Ssam if (bits) { 21914869Ssam putchar('<'); 22014869Ssam while (i = *bits++) { 22114869Ssam if (v & (1 << (i-1))) { 22214869Ssam if (any) 22314869Ssam putchar(','); 22414869Ssam any = 1; 22514869Ssam for (; (c = *bits) > 32; bits++) 22614869Ssam putchar(c); 22714869Ssam } else 22814869Ssam for (; *bits > 32; bits++) 22914869Ssam ; 23014869Ssam } 23114869Ssam putchar('>'); 23214869Ssam } 23314869Ssam } 234