aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--networking/ifconfig.c162
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