|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)ifconfig.c 4.5 (Berkeley) 11/2/83"; ! 3: #endif ! 4: ! 5: #include <sys/types.h> ! 6: #include <sys/socket.h> ! 7: #include <sys/ioctl.h> ! 8: ! 9: #include <netinet/in.h> ! 10: #include <net/if.h> ! 11: ! 12: #include <stdio.h> ! 13: #include <errno.h> ! 14: #include <ctype.h> ! 15: #include <netdb.h> ! 16: #include <strings.h> ! 17: ! 18: struct ifreq ifr; ! 19: struct sockaddr_in sin = { AF_INET }; ! 20: char name[30]; ! 21: int flags; ! 22: int s; ! 23: ! 24: int setifflags(), setifaddr(); ! 25: ! 26: struct cmd { ! 27: char *c_name; ! 28: int c_parameter; ! 29: int (*c_func)(); ! 30: } cmds[] = { ! 31: { "up", IFF_UP, setifflags } , ! 32: { "down", -IFF_UP, setifflags }, ! 33: { "trailers", -IFF_NOTRAILERS,setifflags }, ! 34: { "-trailers", IFF_NOTRAILERS, setifflags }, ! 35: { "arp", -IFF_NOARP, setifflags }, ! 36: { "-arp", IFF_NOARP, setifflags }, ! 37: { "debug", IFF_DEBUG, setifflags }, ! 38: { "-debug", -IFF_DEBUG, setifflags }, ! 39: #ifdef notdef ! 40: #define EN_SWABIPS 0x100 ! 41: { "swabips", EN_SWABIPS, setifflags }, ! 42: { "-swabips", -EN_SWABIPS, setifflags }, ! 43: #endif ! 44: { 0, 0, setifaddr }, ! 45: }; ! 46: ! 47: char *malloc(); ! 48: /*-------------------------------------------------------- ! 49: Changes: ! 50: ! 51: . reget the interface flag before setting it (in case ! 52: ioctl(SIOCSIFADDR) has already changed the flag. ! 53: ! 54: . add the interface to set the Ethernet station address. ! 55: If the interface address is not recognized symbolically ! 56: and it is not Internet numeric address and its ! 57: syntax is "Ex.x.x.x.x.x", then the address is Ethernet ! 58: station address. Also enhance the parsing of Ethernet address. ! 59: ! 60: . fix the format error in Perror(). ! 61: ! 62: --------------------------------------------------------*/ ! 63: main(argc, argv) ! 64: int argc; ! 65: char *argv[]; ! 66: { ! 67: ! 68: if (argc < 2) { ! 69: fprintf(stderr, "usage: ifconfig interface %s %s %s\n", ! 70: "[ address ] [ up ] [ down ]", ! 71: "[ trailers | -trailers ]", ! 72: "[ arp | -arp ]"); ! 73: exit(1); ! 74: } ! 75: s = socket(AF_INET, SOCK_DGRAM, 0); ! 76: if (s < 0) { ! 77: perror("ifconfig: socket"); ! 78: exit(1); ! 79: } ! 80: argc--, argv++; ! 81: strcpy(name, *argv); ! 82: strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); ! 83: if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { ! 84: Perror("ioctl (SIOCGIFFLAGS)"); ! 85: exit(1); ! 86: } ! 87: flags = ifr.ifr_flags; ! 88: argc--, argv++; ! 89: if (argc == 0) { ! 90: status(); ! 91: exit(0); ! 92: } ! 93: while (argc > 0) { ! 94: register struct cmd *p; ! 95: ! 96: for (p = cmds; p->c_name; p++) ! 97: if (strcmp(*argv, p->c_name) == 0) ! 98: break; ! 99: if (p->c_func) ! 100: (*p->c_func)(*argv, p->c_parameter); ! 101: argc--, argv++; ! 102: } ! 103: exit(0); ! 104: } ! 105: ! 106: /*ARGSUSED*/ ! 107: setifaddr(addr, param) ! 108: char *addr; ! 109: int param; ! 110: { ! 111: register long val; ! 112: ! 113: val = getaddr(addr, (struct sockaddr_in *)&ifr.ifr_addr); ! 114: strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); ! 115: if (val != 2) { ! 116: if (ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0) ! 117: Perror("ioctl (SIOCSIFADDR)"); ! 118: } ! 119: else { /* Set Ethernet station address */ ! 120: if (ioctl(s, SIOCSETETADDR, (caddr_t)&ifr) < 0) ! 121: Perror("ioctl (SIOCSETADDR)"); ! 122: } ! 123: } ! 124: ! 125: setifflags(vname, value) ! 126: char *vname; ! 127: int value; ! 128: { ! 129: if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { ! 130: Perror("ioctl (SIOCGIFFLAGS)"); ! 131: exit(1); ! 132: } ! 133: flags = ifr.ifr_flags; ! 134: ! 135: if (value < 0) { ! 136: value = -value; ! 137: flags &= ~value; ! 138: } else ! 139: flags |= value; ! 140: ifr.ifr_flags = flags; ! 141: strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); ! 142: if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) ! 143: Perror(vname); ! 144: } ! 145: ! 146: status() ! 147: { ! 148: struct sockaddr_in *sin; ! 149: ! 150: strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name)); ! 151: if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) ! 152: Perror("ioctl (SIOCGIFADDR)"); ! 153: sin = (struct sockaddr_in *)&ifr.ifr_addr; ! 154: printf("%s: %s ", name, inet_ntoa(sin->sin_addr)); ! 155: #define IFFBITS \ ! 156: "\020\1UP\2BROADCAST\3DEBUG\4ROUTE\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP" ! 157: printb("flags", flags, IFFBITS); putchar('\n'); ! 158: } ! 159: ! 160: Perror(cmd) ! 161: char *cmd; ! 162: { ! 163: extern int errno; ! 164: ! 165: fprintf(stderr, "ifconfig: "); ! 166: switch (errno) { ! 167: ! 168: case ENXIO: ! 169: fprintf(stderr, "%s: ", cmd); ! 170: fprintf(stderr, "no such interface\n"); ! 171: break; ! 172: ! 173: case EPERM: ! 174: fprintf(stderr, "%s: permission denied\n", cmd); ! 175: break; ! 176: ! 177: default: ! 178: perror(cmd); ! 179: } ! 180: exit(1); ! 181: } ! 182: ! 183: struct in_addr inet_makeaddr(); ! 184: ! 185: getaddr(s, sin) ! 186: char *s; ! 187: struct sockaddr_in *sin; ! 188: { ! 189: struct hostent *hp; ! 190: struct netent *np; ! 191: char *s1; ! 192: int val; ! 193: ! 194: hp = gethostbyname(s); ! 195: if (hp) { ! 196: sin->sin_family = hp->h_addrtype; ! 197: bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length); ! 198: return(1); ! 199: } ! 200: np = getnetbyname(s); ! 201: if (np) { ! 202: sin->sin_family = np->n_addrtype; ! 203: sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY); ! 204: return(1); ! 205: } ! 206: sin->sin_family = AF_INET; ! 207: val = inet_addr(s); ! 208: if (val != -1) { ! 209: sin->sin_addr.s_addr = val; ! 210: return(1); ! 211: } ! 212: val = inet_network(s); ! 213: if (val != -1) { ! 214: sin->sin_addr = inet_makeaddr(val, INADDR_ANY); ! 215: return(1); ! 216: } ! 217: if ((s[0] == 'E') && (index(s,'.'))) { ! 218: char *nxtc; ! 219: long lno, ix; ! 220: ! 221: /* Get Ethernet station address */ ! 222: s1 = malloc((unsigned)(strlen(s)+1)); ! 223: if (!s1) { ! 224: fprintf(stderr,"%s: Ethernet address too long\n",s); ! 225: exit(1); ! 226: } ! 227: strcpy(s1,s); /* save original address for error message */ ! 228: ! 229: /* Transform Ea.b.c.d.e.f to a.b.c.d.e.f. for ease of ! 230: parsing ! 231: */ ! 232: strncpy(s,s+1,strlen(s)-1); ! 233: s[strlen(s)-1]='.'; ! 234: for (ix=2; ix<8; ix++) { ! 235: char *t; ! 236: ! 237: nxtc = index(s,'.'); ! 238: if (!nxtc || nxtc==s) { ! 239: fprintf(stderr,"%s: bad Ethernet address\n",s1); ! 240: exit(1); ! 241: } ! 242: ! 243: *nxtc++ = NULL; ! 244: for (t=s;*t && t<nxtc; t++) { ! 245: if ( !(*t>='0' && *t<='9') && ! 246: !(*t>='a' && *t<='f') && ! 247: !(*t>='A' && *t<='F')) { ! 248: fprintf(stderr, ! 249: "%s: bad1 Ethernet address\n",s1); ! 250: exit(1); ! 251: } ! 252: } ! 253: sscanf(s,"%x",&lno); ! 254: sin->sin_zero[ix]=(char)(~(lno & 0xff)); ! 255: s = nxtc; ! 256: } ! 257: if (*s) { ! 258: fprintf(stderr,"%s: Ethernet address too long\n",s1); ! 259: exit(1); ! 260: } ! 261: #ifdef DEBUG ! 262: printf("\nEthernet station address : "); ! 263: printf("%x.%x.%x.%x.%x.%x\n",sin->sin_zero[2]&0xff, ! 264: sin->sin_zero[3]&0xff,sin->sin_zero[4]&0xff, ! 265: sin->sin_zero[5]&0xff, ! 266: sin->sin_zero[6]&0xff,sin->sin_zero[7]&0xff); ! 267: #endif DEBUG ! 268: return(2); ! 269: } ! 270: fprintf(stderr, "%s: bad value\n", s); ! 271: exit(1); ! 272: } ! 273: ! 274: /* ! 275: * Print a value a la the %b format of the kernel's printf ! 276: */ ! 277: printb(s, v, bits) ! 278: char *s; ! 279: register char *bits; ! 280: register unsigned short v; ! 281: { ! 282: register int i, any = 0; ! 283: register char c; ! 284: ! 285: if (bits && *bits == 8) ! 286: printf("%s=%o", s, v); ! 287: else ! 288: printf("%s=%x", s, v); ! 289: bits++; ! 290: if (bits) { ! 291: putchar('<'); ! 292: while (i = *bits++) { ! 293: if (v & (1 << (i-1))) { ! 294: if (any) ! 295: putchar(','); ! 296: any = 1; ! 297: for (; (c = *bits) > 32; bits++) ! 298: putchar(c); ! 299: } else ! 300: for (; *bits > 32; bits++) ! 301: ; ! 302: } ! 303: putchar('>'); ! 304: } ! 305: } ! 306:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.