diff options
-rw-r--r-- | networking/libiproute/ip_common.h | 4 | ||||
-rw-r--r-- | networking/libiproute/ipaddress.c | 279 | ||||
-rw-r--r-- | networking/libiproute/iplink.c | 9 |
3 files changed, 166 insertions, 126 deletions
diff --git a/networking/libiproute/ip_common.h b/networking/libiproute/ip_common.h index 0686136c7..e96f92981 100644 --- a/networking/libiproute/ip_common.h +++ b/networking/libiproute/ip_common.h | |||
@@ -2,14 +2,10 @@ extern int preferred_family; | |||
2 | extern char * _SL_; | 2 | extern char * _SL_; |
3 | 3 | ||
4 | extern void ip_parse_common_args(int *argcp, char ***argvp); | 4 | extern void ip_parse_common_args(int *argcp, char ***argvp); |
5 | extern int print_linkinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); | ||
6 | extern int print_addrinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); | ||
7 | extern int print_neigh(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); | 5 | extern int print_neigh(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); |
8 | extern int ipaddr_list(int argc, char **argv); | 6 | extern int ipaddr_list(int argc, char **argv); |
9 | extern int ipaddr_list_link(int argc, char **argv); | ||
10 | extern int iproute_monitor(int argc, char **argv); | 7 | extern int iproute_monitor(int argc, char **argv); |
11 | extern void iplink_usage(void) __attribute__((noreturn)); | 8 | extern void iplink_usage(void) __attribute__((noreturn)); |
12 | extern void ipaddr_reset_filter(int); | ||
13 | extern void ipneigh_reset_filter(void); | 9 | extern void ipneigh_reset_filter(void); |
14 | extern int do_ipaddr(int argc, char **argv); | 10 | extern int do_ipaddr(int argc, char **argv); |
15 | extern int do_iproute(int argc, char **argv); | 11 | extern int do_iproute(int argc, char **argv); |
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index 055aadfee..57956852b 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c | |||
@@ -50,8 +50,6 @@ static struct | |||
50 | struct rtnl_handle *rth; | 50 | struct rtnl_handle *rth; |
51 | } filter; | 51 | } filter; |
52 | 52 | ||
53 | static int do_link; | ||
54 | |||
55 | void print_link_flags(FILE *fp, unsigned flags, unsigned mdown) | 53 | void print_link_flags(FILE *fp, unsigned flags, unsigned mdown) |
56 | { | 54 | { |
57 | fprintf(fp, "<"); | 55 | fprintf(fp, "<"); |
@@ -84,7 +82,7 @@ void print_link_flags(FILE *fp, unsigned flags, unsigned mdown) | |||
84 | fprintf(fp, "> "); | 82 | fprintf(fp, "> "); |
85 | } | 83 | } |
86 | 84 | ||
87 | void print_queuelen(char *name) | 85 | static void print_queuelen(char *name) |
88 | { | 86 | { |
89 | struct ifreq ifr; | 87 | struct ifreq ifr; |
90 | int s; | 88 | int s; |
@@ -106,7 +104,7 @@ void print_queuelen(char *name) | |||
106 | printf("qlen %d", ifr.ifr_qlen); | 104 | printf("qlen %d", ifr.ifr_qlen); |
107 | } | 105 | } |
108 | 106 | ||
109 | int print_linkinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) | 107 | static int print_linkinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) |
110 | { | 108 | { |
111 | FILE *fp = (FILE*)arg; | 109 | FILE *fp = (FILE*)arg; |
112 | struct ifinfomsg *ifi = NLMSG_DATA(n); | 110 | struct ifinfomsg *ifi = NLMSG_DATA(n); |
@@ -198,7 +196,7 @@ int print_linkinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) | |||
198 | return 0; | 196 | return 0; |
199 | } | 197 | } |
200 | 198 | ||
201 | int print_addrinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) | 199 | static int print_addrinfo(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) |
202 | { | 200 | { |
203 | FILE *fp = (FILE*)arg; | 201 | FILE *fp = (FILE*)arg; |
204 | struct ifaddrmsg *ifa = NLMSG_DATA(n); | 202 | struct ifaddrmsg *ifa = NLMSG_DATA(n); |
@@ -341,7 +339,7 @@ struct nlmsg_list | |||
341 | struct nlmsghdr h; | 339 | struct nlmsghdr h; |
342 | }; | 340 | }; |
343 | 341 | ||
344 | int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *fp) | 342 | static int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *fp) |
345 | { | 343 | { |
346 | for ( ;ainfo ; ainfo = ainfo->next) { | 344 | for ( ;ainfo ; ainfo = ainfo->next) { |
347 | struct nlmsghdr *n = &ainfo->h; | 345 | struct nlmsghdr *n = &ainfo->h; |
@@ -363,7 +361,7 @@ int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *fp) | |||
363 | } | 361 | } |
364 | 362 | ||
365 | 363 | ||
366 | int store_nlmsg(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) | 364 | static int store_nlmsg(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) |
367 | { | 365 | { |
368 | struct nlmsg_list **linfo = (struct nlmsg_list**)arg; | 366 | struct nlmsg_list **linfo = (struct nlmsg_list**)arg; |
369 | struct nlmsg_list *h; | 367 | struct nlmsg_list *h; |
@@ -383,8 +381,15 @@ int store_nlmsg(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) | |||
383 | return 0; | 381 | return 0; |
384 | } | 382 | } |
385 | 383 | ||
386 | int ipaddr_list(int argc, char **argv) | 384 | static void ipaddr_reset_filter(int _oneline) |
387 | { | 385 | { |
386 | memset(&filter, 0, sizeof(filter)); | ||
387 | filter.oneline = _oneline; | ||
388 | } | ||
389 | |||
390 | extern int ipaddr_list(int argc, char **argv) | ||
391 | { | ||
392 | const char *option[] = { "to", "scope", "up", "label", "dev", 0 }; | ||
388 | struct nlmsg_list *linfo = NULL; | 393 | struct nlmsg_list *linfo = NULL; |
389 | struct nlmsg_list *ainfo = NULL; | 394 | struct nlmsg_list *ainfo = NULL; |
390 | struct nlmsg_list *l; | 395 | struct nlmsg_list *l; |
@@ -399,36 +404,47 @@ int ipaddr_list(int argc, char **argv) | |||
399 | filter.family = preferred_family; | 404 | filter.family = preferred_family; |
400 | 405 | ||
401 | while (argc > 0) { | 406 | while (argc > 0) { |
402 | if (strcmp(*argv, "to") == 0) { | 407 | const unsigned short option_num = compare_string_array(option, *argv); |
403 | NEXT_ARG(); | 408 | switch (option_num) { |
404 | get_prefix(&filter.pfx, *argv, filter.family); | 409 | case 0: /* to */ |
405 | if (filter.family == AF_UNSPEC) | 410 | NEXT_ARG(); |
406 | filter.family = filter.pfx.family; | 411 | get_prefix(&filter.pfx, *argv, filter.family); |
407 | } else if (strcmp(*argv, "scope") == 0) { | 412 | if (filter.family == AF_UNSPEC) { |
408 | int scope = 0; | 413 | filter.family = filter.pfx.family; |
409 | NEXT_ARG(); | 414 | } |
410 | filter.scopemask = -1; | 415 | break; |
411 | if (rtnl_rtscope_a2n(&scope, *argv)) { | 416 | case 1: /* scope */ |
412 | if (strcmp(*argv, "all") != 0) | 417 | { |
413 | invarg("invalid \"scope\"\n", *argv); | 418 | int scope = 0; |
414 | scope = RT_SCOPE_NOWHERE; | ||
415 | filter.scopemask = 0; | ||
416 | } | ||
417 | filter.scope = scope; | ||
418 | } else if (strcmp(*argv, "up") == 0) { | ||
419 | filter.up = 1; | ||
420 | } else if (strcmp(*argv, "label") == 0) { | ||
421 | NEXT_ARG(); | ||
422 | filter.label = *argv; | ||
423 | } else { | ||
424 | if (strcmp(*argv, "dev") == 0) { | ||
425 | NEXT_ARG(); | 419 | NEXT_ARG(); |
420 | filter.scopemask = -1; | ||
421 | if (rtnl_rtscope_a2n(&scope, *argv)) { | ||
422 | if (strcmp(*argv, "all") != 0) { | ||
423 | invarg("invalid \"scope\"\n", *argv); | ||
424 | } | ||
425 | scope = RT_SCOPE_NOWHERE; | ||
426 | filter.scopemask = 0; | ||
427 | } | ||
428 | filter.scope = scope; | ||
429 | break; | ||
426 | } | 430 | } |
427 | if (filter_dev) | 431 | case 2: /* up */ |
428 | duparg2("dev", *argv); | 432 | filter.up = 1; |
429 | filter_dev = *argv; | 433 | break; |
434 | case 3: /* label */ | ||
435 | NEXT_ARG(); | ||
436 | filter.label = *argv; | ||
437 | break; | ||
438 | case 4: /* dev */ | ||
439 | NEXT_ARG(); | ||
440 | default: | ||
441 | if (filter_dev) { | ||
442 | duparg2("dev", *argv); | ||
443 | } | ||
444 | filter_dev = *argv; | ||
430 | } | 445 | } |
431 | argv++; argc--; | 446 | argv++; |
447 | argc--; | ||
432 | } | 448 | } |
433 | 449 | ||
434 | if (rtnl_open(&rth, 0) < 0) | 450 | if (rtnl_open(&rth, 0) < 0) |
@@ -533,20 +549,7 @@ int ipaddr_list(int argc, char **argv) | |||
533 | exit(0); | 549 | exit(0); |
534 | } | 550 | } |
535 | 551 | ||
536 | int ipaddr_list_link(int argc, char **argv) | 552 | static int default_scope(inet_prefix *lcl) |
537 | { | ||
538 | preferred_family = AF_PACKET; | ||
539 | do_link = 1; | ||
540 | return ipaddr_list(argc, argv); | ||
541 | } | ||
542 | |||
543 | void ipaddr_reset_filter(int _oneline) | ||
544 | { | ||
545 | memset(&filter, 0, sizeof(filter)); | ||
546 | filter.oneline = _oneline; | ||
547 | } | ||
548 | |||
549 | int default_scope(inet_prefix *lcl) | ||
550 | { | 553 | { |
551 | if (lcl->family == AF_INET) { | 554 | if (lcl->family == AF_INET) { |
552 | if (lcl->bytelen >= 1 && *(__u8*)&lcl->data == 127) | 555 | if (lcl->bytelen >= 1 && *(__u8*)&lcl->data == 127) |
@@ -555,8 +558,10 @@ int default_scope(inet_prefix *lcl) | |||
555 | return 0; | 558 | return 0; |
556 | } | 559 | } |
557 | 560 | ||
558 | int ipaddr_modify(int cmd, int argc, char **argv) | 561 | static int ipaddr_modify(int cmd, int argc, char **argv) |
559 | { | 562 | { |
563 | const char *option[] = { "peer", "remote", "broadcast", "brd", | ||
564 | "anycast", "scope", "dev", "label", "local", 0 }; | ||
560 | struct rtnl_handle rth; | 565 | struct rtnl_handle rth; |
561 | struct { | 566 | struct { |
562 | struct nlmsghdr n; | 567 | struct nlmsghdr n; |
@@ -581,73 +586,97 @@ int ipaddr_modify(int cmd, int argc, char **argv) | |||
581 | req.ifa.ifa_family = preferred_family; | 586 | req.ifa.ifa_family = preferred_family; |
582 | 587 | ||
583 | while (argc > 0) { | 588 | while (argc > 0) { |
584 | if (strcmp(*argv, "peer") == 0 || | 589 | const unsigned short option_num = compare_string_array(option, *argv); |
585 | strcmp(*argv, "remote") == 0) { | 590 | switch (option_num) { |
586 | NEXT_ARG(); | 591 | case 0: /* peer */ |
587 | 592 | case 1: /* remote */ | |
588 | if (peer_len) | 593 | NEXT_ARG(); |
589 | duparg("peer", *argv); | 594 | |
590 | get_prefix(&peer, *argv, req.ifa.ifa_family); | 595 | if (peer_len) { |
591 | peer_len = peer.bytelen; | 596 | duparg("peer", *argv); |
592 | if (req.ifa.ifa_family == AF_UNSPEC) | 597 | } |
593 | req.ifa.ifa_family = peer.family; | 598 | get_prefix(&peer, *argv, req.ifa.ifa_family); |
594 | addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen); | 599 | peer_len = peer.bytelen; |
595 | req.ifa.ifa_prefixlen = peer.bitlen; | 600 | if (req.ifa.ifa_family == AF_UNSPEC) { |
596 | } else if (matches(*argv, "broadcast") == 0 || | 601 | req.ifa.ifa_family = peer.family; |
597 | strcmp(*argv, "brd") == 0) { | 602 | } |
598 | inet_prefix addr; | 603 | addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen); |
599 | NEXT_ARG(); | 604 | req.ifa.ifa_prefixlen = peer.bitlen; |
600 | if (brd_len) | 605 | break; |
601 | duparg("broadcast", *argv); | 606 | case 2: /* broadcast */ |
602 | if (strcmp(*argv, "+") == 0) | 607 | case 3: /* brd */ |
603 | brd_len = -1; | 608 | { |
604 | else if (strcmp(*argv, "-") == 0) | 609 | inet_prefix addr; |
605 | brd_len = -2; | 610 | NEXT_ARG(); |
606 | else { | 611 | if (brd_len) { |
612 | duparg("broadcast", *argv); | ||
613 | } | ||
614 | if (strcmp(*argv, "+") == 0) { | ||
615 | brd_len = -1; | ||
616 | } | ||
617 | else if (strcmp(*argv, "-") == 0) { | ||
618 | brd_len = -2; | ||
619 | } else { | ||
620 | get_addr(&addr, *argv, req.ifa.ifa_family); | ||
621 | if (req.ifa.ifa_family == AF_UNSPEC) | ||
622 | req.ifa.ifa_family = addr.family; | ||
623 | addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen); | ||
624 | brd_len = addr.bytelen; | ||
625 | } | ||
626 | break; | ||
627 | } | ||
628 | case 4: /* anycast */ | ||
629 | { | ||
630 | inet_prefix addr; | ||
631 | NEXT_ARG(); | ||
632 | if (any_len) { | ||
633 | duparg("anycast", *argv); | ||
634 | } | ||
607 | get_addr(&addr, *argv, req.ifa.ifa_family); | 635 | get_addr(&addr, *argv, req.ifa.ifa_family); |
608 | if (req.ifa.ifa_family == AF_UNSPEC) | 636 | if (req.ifa.ifa_family == AF_UNSPEC) { |
609 | req.ifa.ifa_family = addr.family; | 637 | req.ifa.ifa_family = addr.family; |
610 | addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen); | 638 | } |
611 | brd_len = addr.bytelen; | 639 | addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen); |
640 | any_len = addr.bytelen; | ||
641 | break; | ||
612 | } | 642 | } |
613 | } else if (strcmp(*argv, "anycast") == 0) { | 643 | case 5: /* scope */ |
614 | inet_prefix addr; | 644 | { |
615 | NEXT_ARG(); | 645 | int scope = 0; |
616 | if (any_len) | ||
617 | duparg("anycast", *argv); | ||
618 | get_addr(&addr, *argv, req.ifa.ifa_family); | ||
619 | if (req.ifa.ifa_family == AF_UNSPEC) | ||
620 | req.ifa.ifa_family = addr.family; | ||
621 | addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen); | ||
622 | any_len = addr.bytelen; | ||
623 | } else if (strcmp(*argv, "scope") == 0) { | ||
624 | int scope = 0; | ||
625 | NEXT_ARG(); | ||
626 | if (rtnl_rtscope_a2n(&scope, *argv)) | ||
627 | invarg(*argv, "invalid scope value."); | ||
628 | req.ifa.ifa_scope = scope; | ||
629 | scoped = 1; | ||
630 | } else if (strcmp(*argv, "dev") == 0) { | ||
631 | NEXT_ARG(); | ||
632 | d = *argv; | ||
633 | } else if (strcmp(*argv, "label") == 0) { | ||
634 | NEXT_ARG(); | ||
635 | l = *argv; | ||
636 | addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l)+1); | ||
637 | } else { | ||
638 | if (strcmp(*argv, "local") == 0) { | ||
639 | NEXT_ARG(); | 646 | NEXT_ARG(); |
647 | if (rtnl_rtscope_a2n(&scope, *argv)) { | ||
648 | invarg(*argv, "invalid scope value."); | ||
649 | } | ||
650 | req.ifa.ifa_scope = scope; | ||
651 | scoped = 1; | ||
652 | break; | ||
640 | } | 653 | } |
641 | if (local_len) | 654 | case 6: /* dev */ |
642 | duparg2("local", *argv); | 655 | NEXT_ARG(); |
643 | get_prefix(&lcl, *argv, req.ifa.ifa_family); | 656 | d = *argv; |
644 | if (req.ifa.ifa_family == AF_UNSPEC) | 657 | break; |
645 | req.ifa.ifa_family = lcl.family; | 658 | case 7: /* label */ |
646 | addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen); | 659 | NEXT_ARG(); |
647 | local_len = lcl.bytelen; | 660 | l = *argv; |
661 | addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l)+1); | ||
662 | break; | ||
663 | case 8: /* local */ | ||
664 | NEXT_ARG(); | ||
665 | default: | ||
666 | if (local_len) { | ||
667 | duparg2("local", *argv); | ||
668 | } | ||
669 | get_prefix(&lcl, *argv, req.ifa.ifa_family); | ||
670 | if (req.ifa.ifa_family == AF_UNSPEC) { | ||
671 | req.ifa.ifa_family = lcl.family; | ||
672 | } | ||
673 | addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen); | ||
674 | local_len = lcl.bytelen; | ||
648 | } | 675 | } |
649 | argc--; argv++; | 676 | argc--; |
677 | argv++; | ||
650 | } | 678 | } |
679 | |||
651 | if (d == NULL) { | 680 | if (d == NULL) { |
652 | error_msg("Not enough information: \"dev\" argument is required."); | 681 | error_msg("Not enough information: \"dev\" argument is required."); |
653 | return -1; | 682 | return -1; |
@@ -701,17 +730,23 @@ int ipaddr_modify(int cmd, int argc, char **argv) | |||
701 | exit(0); | 730 | exit(0); |
702 | } | 731 | } |
703 | 732 | ||
704 | int do_ipaddr(int argc, char **argv) | 733 | extern int do_ipaddr(int argc, char **argv) |
705 | { | 734 | { |
706 | if (argc < 1) | 735 | const char *commands[] = { "add", "delete", "list", "show", "lst", 0 }; |
707 | return ipaddr_list(0, NULL); | 736 | unsigned short command_num = 2; |
708 | if (matches(*argv, "add") == 0) | 737 | |
709 | return ipaddr_modify(RTM_NEWADDR, argc-1, argv+1); | 738 | if (*argv) { |
710 | if (matches(*argv, "delete") == 0) | 739 | command_num = compare_string_array(commands, *argv); |
711 | return ipaddr_modify(RTM_DELADDR, argc-1, argv+1); | 740 | } |
712 | if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0 | 741 | switch (command_num) { |
713 | || matches(*argv, "lst") == 0) | 742 | case 0: /* add */ |
714 | return ipaddr_list(argc-1, argv+1); | 743 | return ipaddr_modify(RTM_NEWADDR, argc-1, argv+1); |
715 | error_msg("Command \"%s\" is unknown, try \"ip address help\".", *argv); | 744 | case 1: /* delete */ |
716 | exit(-1); | 745 | return ipaddr_modify(RTM_DELADDR, argc-1, argv+1); |
746 | case 2: /* list */ | ||
747 | case 3: /* show */ | ||
748 | case 4: /* lst */ | ||
749 | return ipaddr_list(argc-1, argv+1); | ||
750 | } | ||
751 | error_msg_and_die("Unknown command %s", *argv); | ||
717 | } | 752 | } |
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c index c9d218a11..33f38918a 100644 --- a/networking/libiproute/iplink.c +++ b/networking/libiproute/iplink.c | |||
@@ -33,6 +33,8 @@ | |||
33 | 33 | ||
34 | #include "busybox.h" | 34 | #include "busybox.h" |
35 | 35 | ||
36 | static int do_link; | ||
37 | |||
36 | static int on_off(char *msg) | 38 | static int on_off(char *msg) |
37 | { | 39 | { |
38 | error_msg("Error: argument of \"%s\" must be \"on\" or \"off\"", msg); | 40 | error_msg("Error: argument of \"%s\" must be \"on\" or \"off\"", msg); |
@@ -332,6 +334,13 @@ static int do_set(int argc, char **argv) | |||
332 | return 0; | 334 | return 0; |
333 | } | 335 | } |
334 | 336 | ||
337 | static int ipaddr_list_link(int argc, char **argv) | ||
338 | { | ||
339 | preferred_family = AF_PACKET; | ||
340 | do_link = 1; | ||
341 | return ipaddr_list(argc, argv); | ||
342 | } | ||
343 | |||
335 | int do_iplink(int argc, char **argv) | 344 | int do_iplink(int argc, char **argv) |
336 | { | 345 | { |
337 | if (argc > 0) { | 346 | if (argc > 0) { |