Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/networking/ifconfig.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/networking/ifconfig.c
r821 r1770 27 27 */ 28 28 29 #include <stdio.h>30 #include <stdlib.h>31 #include <string.h> /* strcmp and friends */32 #include <ctype.h> /* isdigit and friends */33 #include <stddef.h> /* offsetof */34 #include <unistd.h>35 #include <netdb.h>36 #include <sys/ioctl.h>37 29 #include <net/if.h> 38 30 #include <net/if_arp.h> 39 31 #include <netinet/in.h> 40 #if __GLIBC__ >=2 && __GLIBC_MINOR>= 132 #if defined(__GLIBC__) && __GLIBC__ >=2 && __GLIBC_MINOR__ >= 1 41 33 #include <netpacket/packet.h> 42 34 #include <net/ethernet.h> … … 46 38 #endif 47 39 #include "inet_common.h" 48 #include " busybox.h"49 50 #if def CONFIG_FEATURE_IFCONFIG_SLIP40 #include "libbb.h" 41 42 #if ENABLE_FEATURE_IFCONFIG_SLIP 51 43 # include <net/if_slip.h> 52 44 #endif … … 71 63 #endif 72 64 73 #if def CONFIG_FEATURE_IPV665 #if ENABLE_FEATURE_IPV6 74 66 struct in6_ifreq { 75 67 struct in6_addr ifr6_addr; … … 122 114 #define A_SET_AFTER 0x40 /* Set a flag at the end. */ 123 115 #define A_COLON_CHK 0x80 /* Is this needed? See below. */ 124 #if def CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS116 #if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS 125 117 #define A_HOSTNAME 0x100 /* Set if it is ip addr. */ 126 118 #define A_BROADCAST 0x200 /* Set if it is broadcast addr. */ … … 179 171 struct options { 180 172 const char *name; 181 #if def CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS173 #if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS 182 174 const unsigned int flags:6; 183 175 const unsigned int arg_flags:10; … … 198 190 {"SIOCSIFNETMASK", SIOCSIFNETMASK, ifreq_offsetof(ifr_netmask)}, 199 191 {"SIOCSIFBRDADDR", SIOCSIFBRDADDR, ifreq_offsetof(ifr_broadaddr)}, 200 #if def CONFIG_FEATURE_IFCONFIG_HW192 #if ENABLE_FEATURE_IFCONFIG_HW 201 193 {"SIOCSIFHWADDR", SIOCSIFHWADDR, ifreq_offsetof(ifr_hwaddr)}, 202 194 #endif … … 208 200 {"SIOCSOUTFILL", SIOCSOUTFILL, ifreq_offsetof(ifr_data)}, 209 201 #endif 210 #if def CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ202 #if ENABLE_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ 211 203 {"SIOCSIFMAP", SIOCSIFMAP, ifreq_offsetof(ifr_map.mem_start)}, 212 204 {"SIOCSIFMAP", SIOCSIFMAP, ifreq_offsetof(ifr_map.base_addr)}, … … 214 206 #endif 215 207 /* Last entry if for unmatched (possibly hostname) arg. */ 216 #if def CONFIG_FEATURE_IPV6208 #if ENABLE_FEATURE_IPV6 217 209 {"SIOCSIFADDR", SIOCSIFADDR, ifreq_offsetof(ifr_addr)}, /* IPv6 version ignores the offset */ 218 210 {"SIOCDIFADDR", SIOCDIFADDR, ifreq_offsetof(ifr_addr)}, /* IPv6 version ignores the offset */ … … 228 220 {"netmask", N_ARG, ARG_NETMASK, 0}, 229 221 {"broadcast", N_ARG | M_CLR, ARG_BROADCAST, IFF_BROADCAST}, 230 #if def CONFIG_FEATURE_IFCONFIG_HW222 #if ENABLE_FEATURE_IFCONFIG_HW 231 223 {"hw", N_ARG, ARG_HW, 0}, 232 224 #endif … … 238 230 {"outfill", N_ARG, ARG_OUTFILL, 0}, 239 231 #endif 240 #if def CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ232 #if ENABLE_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ 241 233 {"mem_start", N_ARG, ARG_MEM_START, 0}, 242 234 {"io_addr", N_ARG, ARG_IO_ADDR, 0}, 243 235 {"irq", N_ARG, ARG_IRQ, 0}, 244 236 #endif 245 #if def CONFIG_FEATURE_IPV6237 #if ENABLE_FEATURE_IPV6 246 238 {"add", N_ARG, ARG_ADD_DEL, 0}, 247 239 {"del", N_ARG, ARG_ADD_DEL, 0}, … … 262 254 */ 263 255 264 #ifdef CONFIG_FEATURE_IFCONFIG_HW 265 static int in_ether(char *bufp, struct sockaddr *sap); 266 #endif 267 268 #ifdef CONFIG_FEATURE_IFCONFIG_STATUS 269 extern int interface_opt_a; 270 extern int display_interfaces(char *ifname); 256 #if ENABLE_FEATURE_IFCONFIG_HW 257 static int in_ether(const char *bufp, struct sockaddr *sap); 271 258 #endif 272 259 … … 275 262 */ 276 263 264 int ifconfig_main(int argc, char **argv); 277 265 int ifconfig_main(int argc, char **argv) 278 266 { 279 267 struct ifreq ifr; 280 268 struct sockaddr_in sai; 281 #ifdef CONFIG_FEATURE_IPV6 282 struct sockaddr_in6 sai6; 283 #endif 284 #ifdef CONFIG_FEATURE_IFCONFIG_HW 269 #if ENABLE_FEATURE_IFCONFIG_HW 285 270 struct sockaddr sa; 286 271 #endif … … 288 273 const struct options *op; 289 274 int sockfd; /* socket fd we use to manipulate stuff with */ 290 int goterr;291 275 int selector; 292 #if def CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS276 #if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS 293 277 unsigned int mask; 294 278 unsigned int did_flags; … … 299 283 #endif 300 284 char *p; 301 char host[128];302 303 goterr = 0; 285 /*char host[128];*/ 286 const char *host = NULL; /* make gcc happy */ 287 304 288 did_flags = 0; 305 #if def CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS289 #if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS 306 290 sai_hostname = 0; 307 291 sai_netmask = 0; … … 312 296 --argc; 313 297 314 #if def CONFIG_FEATURE_IFCONFIG_STATUS315 if ( (argc > 0) && (((*argv)[0] == '-') && ((*argv)[1] == 'a') && !(*argv)[2])) {298 #if ENABLE_FEATURE_IFCONFIG_STATUS 299 if (argc > 0 && (argv[0][0] == '-' && argv[0][1] == 'a' && !argv[0][2])) { 316 300 interface_opt_a = 1; 317 301 --argc; … … 321 305 322 306 if (argc <= 1) { 323 #if def CONFIG_FEATURE_IFCONFIG_STATUS307 #if ENABLE_FEATURE_IFCONFIG_STATUS 324 308 return display_interfaces(argc ? *argv : NULL); 325 309 #else 326 bb_error_msg_and_die 327 ("ifconfig was not compiled with interface status display support."); 310 bb_error_msg_and_die("no support for status display"); 328 311 #endif 329 312 } 330 313 331 314 /* Create a channel to the NET kernel. */ 332 sockfd = bb_xsocket(AF_INET, SOCK_DGRAM, 0);315 sockfd = xsocket(AF_INET, SOCK_DGRAM, 0); 333 316 334 317 /* get interface name */ … … 345 328 for (op = OptArray; op->name; op++) { /* Find table entry. */ 346 329 if (strcmp(p, op->name) == 0) { /* If name matches... */ 347 if ((mask &= op->flags)) { /* set the mask and go. */ 330 mask &= op->flags; 331 if (mask) /* set the mask and go. */ 348 332 goto FOUND_ARG; 349 }350 333 /* If we get here, there was a valid arg with an */ 351 334 /* invalid '-' prefix. */ 352 ++goterr; 353 goto LOOP; 335 bb_error_msg_and_die("bad: '%s'", p-1); 354 336 } 355 337 } 356 338 357 339 /* We fell through, so treat as possible hostname. */ 358 a1op = Arg1Opt + (sizeof(Arg1Opt) / sizeof(Arg1Opt[0])) - 1;340 a1op = Arg1Opt + ARRAY_SIZE(Arg1Opt) - 1; 359 341 mask = op->arg_flags; 360 342 goto HOSTNAME; 361 343 362 344 FOUND_ARG: 363 345 if (mask & ARG_MASK) { 364 346 mask = op->arg_flags; 365 347 a1op = Arg1Opt + (op - OptArray); 366 if (mask & A_NETMASK & did_flags) {348 if (mask & A_NETMASK & did_flags) 367 349 bb_show_usage(); 368 }369 350 if (*++argv == NULL) { 370 if (mask & A_ARG_REQ) {351 if (mask & A_ARG_REQ) 371 352 bb_show_usage(); 372 } else { 373 --argv; 374 mask &= A_SET_AFTER; /* just for broadcast */ 375 } 353 --argv; 354 mask &= A_SET_AFTER; /* just for broadcast */ 376 355 } else { /* got an arg so process it */ 377 356 HOSTNAME: 378 357 did_flags |= (mask & (A_NETMASK|A_HOSTNAME)); 379 358 if (mask & A_CAST_HOST_COPY) { 380 #if def CONFIG_FEATURE_IFCONFIG_HW359 #if ENABLE_FEATURE_IFCONFIG_HW 381 360 if (mask & A_CAST_RESOLVE) { 382 361 #endif 383 #if def CONFIG_FEATURE_IPV6362 #if ENABLE_FEATURE_IPV6 384 363 char *prefix; 385 364 int prefix_len = 0; 386 365 #endif 387 388 safe_strncpy(host, *argv, (sizeof host)); 389 #ifdef CONFIG_FEATURE_IPV6 390 if ((prefix = strchr(host, '/'))) { 391 if (safe_strtoi(prefix + 1, &prefix_len) || 392 (prefix_len < 0) || (prefix_len > 128)) 393 { 394 ++goterr; 395 goto LOOP; 396 } 397 *prefix = 0; 366 /*safe_strncpy(host, *argv, (sizeof host));*/ 367 host = *argv; 368 #if ENABLE_FEATURE_IPV6 369 prefix = strchr(host, '/'); 370 if (prefix) { 371 prefix_len = xatou_range(prefix + 1, 0, 128); 372 *prefix = '\0'; 398 373 } 399 374 #endif 400 401 375 sai.sin_family = AF_INET; 402 376 sai.sin_port = 0; 403 if (!strcmp(host, bb_ INET_default)) {377 if (!strcmp(host, bb_str_default)) { 404 378 /* Default is special, meaning 0.0.0.0. */ 405 379 sai.sin_addr.s_addr = INADDR_ANY; 406 #ifdef CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS 407 } else if (((host[0] == '+') && !host[1]) && (mask & A_BROADCAST) && 408 (did_flags & (A_NETMASK|A_HOSTNAME)) == (A_NETMASK|A_HOSTNAME)) { 380 } 381 #if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS 382 else if ((host[0] == '+' && !host[1]) && (mask & A_BROADCAST) 383 && (did_flags & (A_NETMASK|A_HOSTNAME)) == (A_NETMASK|A_HOSTNAME) 384 ) { 409 385 /* + is special, meaning broadcast is derived. */ 410 386 sai.sin_addr.s_addr = (~sai_netmask) | (sai_hostname & sai_netmask); 411 #endif 412 #ifdef CONFIG_FEATURE_IPV6 413 } else if (inet_pton(AF_INET6, host, &sai6.sin6_addr) > 0) { 414 int sockfd6; 415 struct in6_ifreq ifr6; 416 417 memcpy((char *) &ifr6.ifr6_addr, 418 (char *) &sai6.sin6_addr, 419 sizeof(struct in6_addr)); 420 421 /* Create a channel to the NET kernel. */ 422 if ((sockfd6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { 423 bb_perror_msg_and_die("socket6"); 424 } 425 if (ioctl(sockfd6, SIOGIFINDEX, &ifr) < 0) { 426 perror("SIOGIFINDEX"); 427 ++goterr; 387 } 388 #endif 389 else { 390 len_and_sockaddr *lsa; 391 if (strcmp(host, "inet") == 0) 392 continue; /* compat stuff */ 393 lsa = xhost2sockaddr(host, 0); 394 #if ENABLE_FEATURE_IPV6 395 if (lsa->sa.sa_family == AF_INET6) { 396 int sockfd6; 397 struct in6_ifreq ifr6; 398 399 memcpy((char *) &ifr6.ifr6_addr, 400 (char *) &(lsa->sin6.sin6_addr), 401 sizeof(struct in6_addr)); 402 403 /* Create a channel to the NET kernel. */ 404 sockfd6 = xsocket(AF_INET6, SOCK_DGRAM, 0); 405 xioctl(sockfd6, SIOGIFINDEX, &ifr); 406 ifr6.ifr6_ifindex = ifr.ifr_ifindex; 407 ifr6.ifr6_prefixlen = prefix_len; 408 ioctl_or_perror_and_die(sockfd6, a1op->selector, &ifr6, "%s", a1op->name); 409 if (ENABLE_FEATURE_CLEAN_UP) 410 free(lsa); 428 411 continue; 429 412 } 430 ifr6.ifr6_ifindex = ifr.ifr_ifindex; 431 ifr6.ifr6_prefixlen = prefix_len; 432 if (ioctl(sockfd6, a1op->selector, &ifr6) < 0) { 433 perror(a1op->name); 434 ++goterr; 435 } 436 continue; 437 #endif 438 } else if (inet_aton(host, &sai.sin_addr) == 0) { 439 /* It's not a dotted quad. */ 440 struct hostent *hp; 441 if ((hp = gethostbyname(host)) == (struct hostent *)NULL) { 442 ++goterr; 443 continue; 444 } 445 memcpy((char *) &sai.sin_addr, (char *) hp->h_addr_list[0], 446 sizeof(struct in_addr)); 413 #endif 414 sai.sin_addr = lsa->sin.sin_addr; 415 if (ENABLE_FEATURE_CLEAN_UP) 416 free(lsa); 447 417 } 448 #if def CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS449 if (mask & A_HOSTNAME) {418 #if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS 419 if (mask & A_HOSTNAME) 450 420 sai_hostname = sai.sin_addr.s_addr; 451 } 452 if (mask & A_NETMASK) { 421 if (mask & A_NETMASK) 453 422 sai_netmask = sai.sin_addr.s_addr; 454 }455 423 #endif 456 424 p = (char *) &sai; 457 #if def CONFIG_FEATURE_IFCONFIG_HW425 #if ENABLE_FEATURE_IFCONFIG_HW 458 426 } else { /* A_CAST_HOST_COPY_IN_ETHER */ 459 427 /* This is the "hw" arg case. */ 460 if (strcmp("ether", *argv) || (*++argv == NULL)) {428 if (strcmp("ether", *argv) || !*++argv) 461 429 bb_show_usage(); 462 } 463 safe_strncpy(host, *argv, (sizeof host)); 464 if (in_ether(host, &sa)) { 465 bb_error_msg("invalid hw-addr %s", host); 466 ++goterr; 467 continue; 468 } 430 /*safe_strncpy(host, *argv, sizeof(host));*/ 431 host = *argv; 432 if (in_ether(host, &sa)) 433 bb_error_msg_and_die("invalid hw-addr %s", host); 469 434 p = (char *) &sa; 470 435 } 471 436 #endif 472 memcpy( (((char *) (&ifr)) + a1op->ifr_offset),437 memcpy( (((char *)&ifr) + a1op->ifr_offset), 473 438 p, sizeof(struct sockaddr)); 474 439 } else { 440 /* FIXME: error check?? */ 475 441 unsigned long i = strtoul(*argv, NULL, 0); 476 477 p = ((char *) (&ifr)) + a1op->ifr_offset; 478 #ifdef CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ 442 p = ((char *)&ifr) + a1op->ifr_offset; 443 #if ENABLE_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ 479 444 if (mask & A_MAP_TYPE) { 480 if (ioctl(sockfd, SIOCGIFMAP, &ifr) < 0) { 481 ++goterr; 482 continue; 483 } 484 if ((mask & A_MAP_UCHAR) == A_MAP_UCHAR) { 445 xioctl(sockfd, SIOCGIFMAP, &ifr); 446 if ((mask & A_MAP_UCHAR) == A_MAP_UCHAR) 485 447 *((unsigned char *) p) = i; 486 } else if (mask & A_MAP_USHORT) {448 else if (mask & A_MAP_USHORT) 487 449 *((unsigned short *) p) = i; 488 } else {450 else 489 451 *((unsigned long *) p) = i; 490 }491 452 } else 492 453 #endif 493 if (mask & A_CAST_CHAR_PTR) {454 if (mask & A_CAST_CHAR_PTR) 494 455 *((caddr_t *) p) = (caddr_t) i; 495 } else {/* A_CAST_INT */456 else /* A_CAST_INT */ 496 457 *((int *) p) = i; 497 }498 458 } 499 459 500 if (ioctl(sockfd, a1op->selector, &ifr) < 0) { 501 perror(a1op->name); 502 ++goterr; 503 continue; 504 } 460 ioctl_or_perror_and_die(sockfd, a1op->selector, &ifr, "%s", a1op->name); 505 461 #ifdef QUESTIONABLE_ALIAS_CASE 506 462 if (mask & A_COLON_CHK) { 507 463 /* 508 464 * Don't do the set_flag() if the address is an alias with 509 * a -at the end, since it's deleted already! - Roman465 * a '-' at the end, since it's deleted already! - Roman 510 466 * 511 467 * Should really use regex.h here, not sure though how well … … 514 470 char *ptr; 515 471 short int found_colon = 0; 516 517 for (ptr = ifr.ifr_name; *ptr; ptr++) { 518 if (*ptr == ':') { 472 for (ptr = ifr.ifr_name; *ptr; ptr++) 473 if (*ptr == ':') 519 474 found_colon++; 520 } 521 } 522 523 if (found_colon && *(ptr - 1) == '-') { 475 if (found_colon && ptr[-1] == '-') 524 476 continue; 525 }526 477 } 527 478 #endif 528 479 } 529 if (!(mask & A_SET_AFTER)) {480 if (!(mask & A_SET_AFTER)) 530 481 continue; 531 }532 482 mask = N_SET; 533 483 } 534 484 535 if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { 536 perror("SIOCGIFFLAGS"); 537 ++goterr; 538 } else { 539 selector = op->selector; 540 if (mask & SET_MASK) { 541 ifr.ifr_flags |= selector; 542 } else { 543 ifr.ifr_flags &= ~selector; 544 } 545 if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) { 546 perror("SIOCSIFFLAGS"); 547 ++goterr; 548 } 549 } 550 LOOP: 551 continue; 552 } /* end of while-loop */ 553 554 if (ENABLE_FEATURE_CLEAN_UP) close(sockfd); 555 return goterr; 485 xioctl(sockfd, SIOCGIFFLAGS, &ifr); 486 selector = op->selector; 487 if (mask & SET_MASK) 488 ifr.ifr_flags |= selector; 489 else 490 ifr.ifr_flags &= ~selector; 491 xioctl(sockfd, SIOCSIFFLAGS, &ifr); 492 } /* while () */ 493 494 if (ENABLE_FEATURE_CLEAN_UP) 495 close(sockfd); 496 return 0; 556 497 } 557 498 558 #if def CONFIG_FEATURE_IFCONFIG_HW499 #if ENABLE_FEATURE_IFCONFIG_HW 559 500 /* Input an Ethernet address and convert to binary. */ 560 static int in_ether(c har *bufp, struct sockaddr *sap)501 static int in_ether(const char *bufp, struct sockaddr *sap) 561 502 { 562 503 char *ptr; … … 595 536 } while (++i < ETH_ALEN); 596 537 597 return (int) (*bufp);/* Error if we don't end at end of string. */538 return *bufp; /* Error if we don't end at end of string. */ 598 539 } 599 540 #endif
Note:
See TracChangeset
for help on using the changeset viewer.