diff options
-rw-r--r-- | networking/ifconfig.c | 162 |
1 files changed, 58 insertions, 104 deletions
diff --git a/networking/ifconfig.c b/networking/ifconfig.c index 05be7dc1f..d28ca22c5 100644 --- a/networking/ifconfig.c +++ b/networking/ifconfig.c | |||
@@ -279,7 +279,6 @@ int ifconfig_main(int argc, char **argv) | |||
279 | const struct arg1opt *a1op; | 279 | const struct arg1opt *a1op; |
280 | const struct options *op; | 280 | const struct options *op; |
281 | int sockfd; /* socket fd we use to manipulate stuff with */ | 281 | int sockfd; /* socket fd we use to manipulate stuff with */ |
282 | int goterr; | ||
283 | int selector; | 282 | int selector; |
284 | #if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS | 283 | #if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS |
285 | unsigned int mask; | 284 | unsigned int mask; |
@@ -293,7 +292,6 @@ int ifconfig_main(int argc, char **argv) | |||
293 | /*char host[128];*/ | 292 | /*char host[128];*/ |
294 | const char *host = NULL; /* make gcc happy */ | 293 | const char *host = NULL; /* make gcc happy */ |
295 | 294 | ||
296 | goterr = 0; | ||
297 | did_flags = 0; | 295 | did_flags = 0; |
298 | #if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS | 296 | #if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS |
299 | sai_hostname = 0; | 297 | sai_hostname = 0; |
@@ -305,7 +303,7 @@ int ifconfig_main(int argc, char **argv) | |||
305 | --argc; | 303 | --argc; |
306 | 304 | ||
307 | #if ENABLE_FEATURE_IFCONFIG_STATUS | 305 | #if ENABLE_FEATURE_IFCONFIG_STATUS |
308 | if ((argc > 0) && (((*argv)[0] == '-') && ((*argv)[1] == 'a') && !(*argv)[2])) { | 306 | if (argc > 0 && (argv[0][0] == '-' && argv[0][1] == 'a' && !argv[0][2])) { |
309 | interface_opt_a = 1; | 307 | interface_opt_a = 1; |
310 | --argc; | 308 | --argc; |
311 | ++argv; | 309 | ++argv; |
@@ -337,13 +335,11 @@ int ifconfig_main(int argc, char **argv) | |||
337 | for (op = OptArray; op->name; op++) { /* Find table entry. */ | 335 | for (op = OptArray; op->name; op++) { /* Find table entry. */ |
338 | if (strcmp(p, op->name) == 0) { /* If name matches... */ | 336 | if (strcmp(p, op->name) == 0) { /* If name matches... */ |
339 | mask &= op->flags; | 337 | mask &= op->flags; |
340 | if (mask) { /* set the mask and go. */ | 338 | if (mask) /* set the mask and go. */ |
341 | goto FOUND_ARG; | 339 | goto FOUND_ARG; |
342 | } | ||
343 | /* If we get here, there was a valid arg with an */ | 340 | /* If we get here, there was a valid arg with an */ |
344 | /* invalid '-' prefix. */ | 341 | /* invalid '-' prefix. */ |
345 | ++goterr; | 342 | bb_error_msg_and_die("bad: '%s'", p-1); |
346 | goto LOOP; | ||
347 | } | 343 | } |
348 | } | 344 | } |
349 | 345 | ||
@@ -356,16 +352,13 @@ int ifconfig_main(int argc, char **argv) | |||
356 | if (mask & ARG_MASK) { | 352 | if (mask & ARG_MASK) { |
357 | mask = op->arg_flags; | 353 | mask = op->arg_flags; |
358 | a1op = Arg1Opt + (op - OptArray); | 354 | a1op = Arg1Opt + (op - OptArray); |
359 | if (mask & A_NETMASK & did_flags) { | 355 | if (mask & A_NETMASK & did_flags) |
360 | bb_show_usage(); | 356 | bb_show_usage(); |
361 | } | ||
362 | if (*++argv == NULL) { | 357 | if (*++argv == NULL) { |
363 | if (mask & A_ARG_REQ) { | 358 | if (mask & A_ARG_REQ) |
364 | bb_show_usage(); | 359 | bb_show_usage(); |
365 | } else { | 360 | --argv; |
366 | --argv; | 361 | mask &= A_SET_AFTER; /* just for broadcast */ |
367 | mask &= A_SET_AFTER; /* just for broadcast */ | ||
368 | } | ||
369 | } else { /* got an arg so process it */ | 362 | } else { /* got an arg so process it */ |
370 | HOSTNAME: | 363 | HOSTNAME: |
371 | did_flags |= (mask & (A_NETMASK|A_HOSTNAME)); | 364 | did_flags |= (mask & (A_NETMASK|A_HOSTNAME)); |
@@ -382,121 +375,95 @@ int ifconfig_main(int argc, char **argv) | |||
382 | #if ENABLE_FEATURE_IPV6 | 375 | #if ENABLE_FEATURE_IPV6 |
383 | prefix = strchr(host, '/'); | 376 | prefix = strchr(host, '/'); |
384 | if (prefix) { | 377 | if (prefix) { |
385 | if (safe_strtoi(prefix + 1, &prefix_len) || | 378 | prefix_len = xatou_range(prefix + 1, 0, 128); |
386 | (prefix_len < 0) || (prefix_len > 128)) | 379 | *prefix = '\0'; |
387 | { | ||
388 | ++goterr; | ||
389 | goto LOOP; | ||
390 | } | ||
391 | *prefix = 0; | ||
392 | } | 380 | } |
393 | #endif | 381 | #endif |
394 | |||
395 | sai.sin_family = AF_INET; | 382 | sai.sin_family = AF_INET; |
396 | sai.sin_port = 0; | 383 | sai.sin_port = 0; |
397 | if (!strcmp(host, bb_str_default)) { | 384 | if (!strcmp(host, bb_str_default)) { |
398 | /* Default is special, meaning 0.0.0.0. */ | 385 | /* Default is special, meaning 0.0.0.0. */ |
399 | sai.sin_addr.s_addr = INADDR_ANY; | 386 | sai.sin_addr.s_addr = INADDR_ANY; |
387 | } | ||
400 | #if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS | 388 | #if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS |
401 | } else if (((host[0] == '+') && !host[1]) && (mask & A_BROADCAST) && | 389 | else if ((host[0] == '+' && !host[1]) && (mask & A_BROADCAST) |
402 | (did_flags & (A_NETMASK|A_HOSTNAME)) == (A_NETMASK|A_HOSTNAME)) { | 390 | && (did_flags & (A_NETMASK|A_HOSTNAME)) == (A_NETMASK|A_HOSTNAME) |
391 | ) { | ||
403 | /* + is special, meaning broadcast is derived. */ | 392 | /* + is special, meaning broadcast is derived. */ |
404 | sai.sin_addr.s_addr = (~sai_netmask) | (sai_hostname & sai_netmask); | 393 | sai.sin_addr.s_addr = (~sai_netmask) | (sai_hostname & sai_netmask); |
394 | } | ||
405 | #endif | 395 | #endif |
406 | #if ENABLE_FEATURE_IPV6 | 396 | #if ENABLE_FEATURE_IPV6 |
407 | } else if (inet_pton(AF_INET6, host, &sai6.sin6_addr) > 0) { | 397 | else if (inet_pton(AF_INET6, host, &sai6.sin6_addr) > 0) { |
408 | int sockfd6; | 398 | int sockfd6; |
409 | struct in6_ifreq ifr6; | 399 | struct in6_ifreq ifr6; |
410 | 400 | ||
411 | memcpy((char *) &ifr6.ifr6_addr, | 401 | memcpy((char *) &ifr6.ifr6_addr, |
412 | (char *) &sai6.sin6_addr, | 402 | (char *) &sai6.sin6_addr, |
413 | sizeof(struct in6_addr)); | 403 | sizeof(struct in6_addr)); |
414 | 404 | ||
415 | /* Create a channel to the NET kernel. */ | 405 | /* Create a channel to the NET kernel. */ |
416 | if ((sockfd6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { | 406 | sockfd6 = xsocket(AF_INET6, SOCK_DGRAM, 0); |
417 | bb_perror_msg_and_die("socket6"); | 407 | if (ioctl(sockfd6, SIOGIFINDEX, &ifr) < 0) |
418 | } | 408 | bb_perror_msg_and_die("SIOGIFINDEX"); |
419 | if (ioctl(sockfd6, SIOGIFINDEX, &ifr) < 0) { | ||
420 | perror("SIOGIFINDEX"); | ||
421 | ++goterr; | ||
422 | continue; | ||
423 | } | ||
424 | ifr6.ifr6_ifindex = ifr.ifr_ifindex; | 409 | ifr6.ifr6_ifindex = ifr.ifr_ifindex; |
425 | ifr6.ifr6_prefixlen = prefix_len; | 410 | ifr6.ifr6_prefixlen = prefix_len; |
426 | if (ioctl(sockfd6, a1op->selector, &ifr6) < 0) { | 411 | if (ioctl(sockfd6, a1op->selector, &ifr6) < 0) |
427 | perror(a1op->name); | 412 | bb_perror_msg_and_die(a1op->name); |
428 | ++goterr; | ||
429 | } | ||
430 | continue; | 413 | continue; |
414 | } | ||
431 | #endif | 415 | #endif |
432 | } else if (inet_aton(host, &sai.sin_addr) == 0) { | 416 | else if (inet_aton(host, &sai.sin_addr) == 0) { |
433 | /* It's not a dotted quad. */ | 417 | /* It's not a dotted quad. */ |
434 | struct hostent *hp = gethostbyname(host); | 418 | struct hostent *hp = xgethostbyname(host); |
435 | if (!hp) { | ||
436 | ++goterr; | ||
437 | continue; | ||
438 | } | ||
439 | memcpy((char *) &sai.sin_addr, (char *) hp->h_addr_list[0], | 419 | memcpy((char *) &sai.sin_addr, (char *) hp->h_addr_list[0], |
440 | sizeof(struct in_addr)); | 420 | sizeof(struct in_addr)); |
441 | } | 421 | } |
442 | #if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS | 422 | #if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS |
443 | if (mask & A_HOSTNAME) { | 423 | if (mask & A_HOSTNAME) |
444 | sai_hostname = sai.sin_addr.s_addr; | 424 | sai_hostname = sai.sin_addr.s_addr; |
445 | } | 425 | if (mask & A_NETMASK) |
446 | if (mask & A_NETMASK) { | ||
447 | sai_netmask = sai.sin_addr.s_addr; | 426 | sai_netmask = sai.sin_addr.s_addr; |
448 | } | ||
449 | #endif | 427 | #endif |
450 | p = (char *) &sai; | 428 | p = (char *) &sai; |
451 | #if ENABLE_FEATURE_IFCONFIG_HW | 429 | #if ENABLE_FEATURE_IFCONFIG_HW |
452 | } else { /* A_CAST_HOST_COPY_IN_ETHER */ | 430 | } else { /* A_CAST_HOST_COPY_IN_ETHER */ |
453 | /* This is the "hw" arg case. */ | 431 | /* This is the "hw" arg case. */ |
454 | if (strcmp("ether", *argv) || (*++argv == NULL)) { | 432 | if (strcmp("ether", *argv) || !*++argv) |
455 | bb_show_usage(); | 433 | bb_show_usage(); |
456 | } | ||
457 | /*safe_strncpy(host, *argv, sizeof(host));*/ | 434 | /*safe_strncpy(host, *argv, sizeof(host));*/ |
458 | host = *argv; | 435 | host = *argv; |
459 | if (in_ether(host, &sa)) { | 436 | if (in_ether(host, &sa)) |
460 | bb_error_msg("invalid hw-addr %s", host); | 437 | bb_error_msg_and_die("invalid hw-addr %s", host); |
461 | ++goterr; | ||
462 | continue; | ||
463 | } | ||
464 | p = (char *) &sa; | 438 | p = (char *) &sa; |
465 | } | 439 | } |
466 | #endif | 440 | #endif |
467 | memcpy( (((char *)&ifr) + a1op->ifr_offset), | 441 | memcpy( (((char *)&ifr) + a1op->ifr_offset), |
468 | p, sizeof(struct sockaddr)); | 442 | p, sizeof(struct sockaddr)); |
469 | } else { | 443 | } else { |
444 | /* FIXME: error check?? */ | ||
470 | unsigned long i = strtoul(*argv, NULL, 0); | 445 | unsigned long i = strtoul(*argv, NULL, 0); |
471 | |||
472 | p = ((char *)&ifr) + a1op->ifr_offset; | 446 | p = ((char *)&ifr) + a1op->ifr_offset; |
473 | #if ENABLE_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ | 447 | #if ENABLE_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ |
474 | if (mask & A_MAP_TYPE) { | 448 | if (mask & A_MAP_TYPE) { |
475 | if (ioctl(sockfd, SIOCGIFMAP, &ifr) < 0) { | 449 | if (ioctl(sockfd, SIOCGIFMAP, &ifr) < 0) |
476 | ++goterr; | 450 | bb_perror_msg_and_die("SIOCGIFMAP"); |
477 | continue; | 451 | if ((mask & A_MAP_UCHAR) == A_MAP_UCHAR) |
478 | } | ||
479 | if ((mask & A_MAP_UCHAR) == A_MAP_UCHAR) { | ||
480 | *((unsigned char *) p) = i; | 452 | *((unsigned char *) p) = i; |
481 | } else if (mask & A_MAP_USHORT) { | 453 | else if (mask & A_MAP_USHORT) |
482 | *((unsigned short *) p) = i; | 454 | *((unsigned short *) p) = i; |
483 | } else { | 455 | else |
484 | *((unsigned long *) p) = i; | 456 | *((unsigned long *) p) = i; |
485 | } | ||
486 | } else | 457 | } else |
487 | #endif | 458 | #endif |
488 | if (mask & A_CAST_CHAR_PTR) { | 459 | if (mask & A_CAST_CHAR_PTR) |
489 | *((caddr_t *) p) = (caddr_t) i; | 460 | *((caddr_t *) p) = (caddr_t) i; |
490 | } else { /* A_CAST_INT */ | 461 | else /* A_CAST_INT */ |
491 | *((int *) p) = i; | 462 | *((int *) p) = i; |
492 | } | ||
493 | } | 463 | } |
494 | 464 | ||
495 | if (ioctl(sockfd, a1op->selector, &ifr) < 0) { | 465 | if (ioctl(sockfd, a1op->selector, &ifr) < 0) |
496 | perror(a1op->name); | 466 | bb_perror_msg_and_die(a1op->name); |
497 | ++goterr; | ||
498 | continue; | ||
499 | } | ||
500 | #ifdef QUESTIONABLE_ALIAS_CASE | 467 | #ifdef QUESTIONABLE_ALIAS_CASE |
501 | if (mask & A_COLON_CHK) { | 468 | if (mask & A_COLON_CHK) { |
502 | /* | 469 | /* |
@@ -508,46 +475,33 @@ int ifconfig_main(int argc, char **argv) | |||
508 | */ | 475 | */ |
509 | char *ptr; | 476 | char *ptr; |
510 | short int found_colon = 0; | 477 | short int found_colon = 0; |
511 | 478 | for (ptr = ifr.ifr_name; *ptr; ptr++) | |
512 | for (ptr = ifr.ifr_name; *ptr; ptr++) { | 479 | if (*ptr == ':') |
513 | if (*ptr == ':') { | ||
514 | found_colon++; | 480 | found_colon++; |
515 | } | 481 | if (found_colon && ptr[-1] == '-') |
516 | } | ||
517 | |||
518 | if (found_colon && *(ptr - 1) == '-') { | ||
519 | continue; | 482 | continue; |
520 | } | ||
521 | } | 483 | } |
522 | #endif | 484 | #endif |
523 | } | 485 | } |
524 | if (!(mask & A_SET_AFTER)) { | 486 | if (!(mask & A_SET_AFTER)) |
525 | continue; | 487 | continue; |
526 | } | ||
527 | mask = N_SET; | 488 | mask = N_SET; |
528 | } | 489 | } |
529 | 490 | ||
530 | if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { | 491 | if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) |
531 | perror("SIOCGIFFLAGS"); | 492 | bb_perror_msg_and_die("SIOCGIFFLAGS"); |
532 | ++goterr; | 493 | selector = op->selector; |
533 | } else { | 494 | if (mask & SET_MASK) |
534 | selector = op->selector; | 495 | ifr.ifr_flags |= selector; |
535 | if (mask & SET_MASK) { | 496 | else |
536 | ifr.ifr_flags |= selector; | 497 | ifr.ifr_flags &= ~selector; |
537 | } else { | 498 | if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) |
538 | ifr.ifr_flags &= ~selector; | 499 | bb_perror_msg_and_die("SIOCSIFFLAGS"); |
539 | } | 500 | } /* while() */ |
540 | if (ioctl(sockfd, SIOCSIFFLAGS, &ifr) < 0) { | 501 | |
541 | perror("SIOCSIFFLAGS"); | 502 | if (ENABLE_FEATURE_CLEAN_UP) |
542 | ++goterr; | 503 | close(sockfd); |
543 | } | 504 | return 0; |
544 | } | ||
545 | LOOP: | ||
546 | continue; | ||
547 | } /* end of while-loop */ | ||
548 | |||
549 | if (ENABLE_FEATURE_CLEAN_UP) close(sockfd); | ||
550 | return goterr; | ||
551 | } | 505 | } |
552 | 506 | ||
553 | #if ENABLE_FEATURE_IFCONFIG_HW | 507 | #if ENABLE_FEATURE_IFCONFIG_HW |