diff options
Diffstat (limited to 'networking/libiproute/iproute.c')
-rw-r--r-- | networking/libiproute/iproute.c | 107 |
1 files changed, 54 insertions, 53 deletions
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index 27d37ac79..bb0bfaed1 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c | |||
@@ -24,8 +24,7 @@ | |||
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | 26 | ||
27 | static struct | 27 | typedef struct filter_t { |
28 | { | ||
29 | int tb; | 28 | int tb; |
30 | int flushed; | 29 | int flushed; |
31 | char *flushb; | 30 | char *flushb; |
@@ -45,12 +44,14 @@ static struct | |||
45 | inet_prefix mdst; | 44 | inet_prefix mdst; |
46 | inet_prefix rsrc; | 45 | inet_prefix rsrc; |
47 | inet_prefix msrc; | 46 | inet_prefix msrc; |
48 | } filter; | 47 | } filter_t; |
48 | |||
49 | #define filter (*(filter_t*)&bb_common_bufsiz1) | ||
49 | 50 | ||
50 | static int flush_update(void) | 51 | static int flush_update(void) |
51 | { | 52 | { |
52 | if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) { | 53 | if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) { |
53 | perror("Failed to send flush request\n"); | 54 | bb_perror_msg("failed to send flush request"); |
54 | return -1; | 55 | return -1; |
55 | } | 56 | } |
56 | filter.flushp = 0; | 57 | filter.flushp = 0; |
@@ -273,7 +274,7 @@ static int print_route(struct sockaddr_nl *who ATTRIBUTE_UNUSED, | |||
273 | } | 274 | } |
274 | if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) { | 275 | if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) { |
275 | if (r->rtm_flags & RTM_F_CLONED) { | 276 | if (r->rtm_flags & RTM_F_CLONED) { |
276 | fprintf(fp, "%s cache ", _SL_); | 277 | fprintf(fp, "%c cache ", _SL_); |
277 | } | 278 | } |
278 | if (ci->rta_expires) { | 279 | if (ci->rta_expires) { |
279 | fprintf(fp, " expires %dsec", ci->rta_expires / get_hz()); | 280 | fprintf(fp, " expires %dsec", ci->rta_expires / get_hz()); |
@@ -289,11 +290,12 @@ static int print_route(struct sockaddr_nl *who ATTRIBUTE_UNUSED, | |||
289 | if (tb[RTA_IIF] && filter.iifmask != -1) { | 290 | if (tb[RTA_IIF] && filter.iifmask != -1) { |
290 | fprintf(fp, " iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF]))); | 291 | fprintf(fp, " iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF]))); |
291 | } | 292 | } |
292 | fprintf(fp, "\n"); | 293 | fputc('\n', fp); |
293 | fflush(fp); | 294 | fflush(fp); |
294 | return 0; | 295 | return 0; |
295 | } | 296 | } |
296 | 297 | ||
298 | /* Return value becomes exitcode. It's okay to not return at all */ | ||
297 | static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) | 299 | static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) |
298 | { | 300 | { |
299 | struct rtnl_handle rth; | 301 | struct rtnl_handle rth; |
@@ -302,10 +304,10 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) | |||
302 | struct rtmsg r; | 304 | struct rtmsg r; |
303 | char buf[1024]; | 305 | char buf[1024]; |
304 | } req; | 306 | } req; |
305 | char mxbuf[256]; | 307 | char mxbuf[256]; |
306 | struct rtattr * mxrta = (void*)mxbuf; | 308 | struct rtattr * mxrta = (void*)mxbuf; |
307 | unsigned mxlock = 0; | 309 | unsigned mxlock = 0; |
308 | char *d = NULL; | 310 | char *d = NULL; |
309 | int gw_ok = 0; | 311 | int gw_ok = 0; |
310 | int dst_ok = 0; | 312 | int dst_ok = 0; |
311 | int proto_ok = 0; | 313 | int proto_ok = 0; |
@@ -384,8 +386,9 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) | |||
384 | if (strcmp(*argv, "to") == 0) { | 386 | if (strcmp(*argv, "to") == 0) { |
385 | NEXT_ARG(); | 387 | NEXT_ARG(); |
386 | } | 388 | } |
387 | if ((**argv < '0' || **argv > '9') && | 389 | if ((**argv < '0' || **argv > '9') |
388 | rtnl_rtntype_a2n(&type, *argv) == 0) { | 390 | && rtnl_rtntype_a2n(&type, *argv) == 0 |
391 | ) { | ||
389 | NEXT_ARG(); | 392 | NEXT_ARG(); |
390 | req.r.rtm_type = type; | 393 | req.r.rtm_type = type; |
391 | type_ok = 1; | 394 | type_ok = 1; |
@@ -408,7 +411,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) | |||
408 | } | 411 | } |
409 | 412 | ||
410 | if (rtnl_open(&rth, 0) < 0) { | 413 | if (rtnl_open(&rth, 0) < 0) { |
411 | exit(1); | 414 | return 1; |
412 | } | 415 | } |
413 | 416 | ||
414 | if (d) { | 417 | if (d) { |
@@ -419,8 +422,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) | |||
419 | if (d) { | 422 | if (d) { |
420 | idx = ll_name_to_index(d); | 423 | idx = ll_name_to_index(d); |
421 | if (idx == 0) { | 424 | if (idx == 0) { |
422 | bb_error_msg("cannot find device \"%s\"", d); | 425 | bb_error_msg_and_die("cannot find device \"%s\"", d); |
423 | return -1; | ||
424 | } | 426 | } |
425 | addattr32(&req.n, sizeof(req), RTA_OIF, idx); | 427 | addattr32(&req.n, sizeof(req), RTA_OIF, idx); |
426 | } | 428 | } |
@@ -438,7 +440,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) | |||
438 | } | 440 | } |
439 | 441 | ||
440 | if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) { | 442 | if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) { |
441 | exit(2); | 443 | return 2; |
442 | } | 444 | } |
443 | 445 | ||
444 | return 0; | 446 | return 0; |
@@ -467,21 +469,21 @@ static int rtnl_rtcache_request(struct rtnl_handle *rth, int family) | |||
467 | return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); | 469 | return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); |
468 | } | 470 | } |
469 | 471 | ||
470 | static int iproute_flush_cache(void) | 472 | static void iproute_flush_cache(void) |
471 | { | 473 | { |
472 | static const char fn[] = "/proc/sys/net/ipv4/route/flush"; | 474 | static const char fn[] = "/proc/sys/net/ipv4/route/flush"; |
473 | int flush_fd = open(fn, O_WRONLY); | 475 | int flush_fd = open(fn, O_WRONLY); |
476 | |||
474 | if (flush_fd < 0) { | 477 | if (flush_fd < 0) { |
475 | bb_perror_msg("cannot open '%s'", fn); | 478 | bb_perror_msg("cannot open '%s'", fn); |
476 | return -1; | 479 | return; |
477 | } | 480 | } |
478 | 481 | ||
479 | if (write(flush_fd, "-1", 2) < 2) { | 482 | if (write(flush_fd, "-1", 2) < 2) { |
480 | bb_perror_msg("cannot flush routing cache"); | 483 | bb_perror_msg("cannot flush routing cache"); |
481 | return -1; | 484 | return; |
482 | } | 485 | } |
483 | close(flush_fd); | 486 | close(flush_fd); |
484 | return 0; | ||
485 | } | 487 | } |
486 | 488 | ||
487 | static void iproute_reset_filter(void) | 489 | static void iproute_reset_filter(void) |
@@ -491,6 +493,7 @@ static void iproute_reset_filter(void) | |||
491 | filter.msrc.bitlen = -1; | 493 | filter.msrc.bitlen = -1; |
492 | } | 494 | } |
493 | 495 | ||
496 | /* Return value becomes exitcode. It's okay to not return at all */ | ||
494 | static int iproute_list_or_flush(int argc, char **argv, int flush) | 497 | static int iproute_list_or_flush(int argc, char **argv, int flush) |
495 | { | 498 | { |
496 | int do_ipv6 = preferred_family; | 499 | int do_ipv6 = preferred_family; |
@@ -501,10 +504,8 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) | |||
501 | iproute_reset_filter(); | 504 | iproute_reset_filter(); |
502 | filter.tb = RT_TABLE_MAIN; | 505 | filter.tb = RT_TABLE_MAIN; |
503 | 506 | ||
504 | if (flush && argc <= 0) { | 507 | if (flush && argc <= 0) |
505 | bb_error_msg(bb_msg_requires_arg, "\"ip route flush\""); | 508 | bb_error_msg_and_die(bb_msg_requires_arg, "\"ip route flush\""); |
506 | return -1; | ||
507 | } | ||
508 | 509 | ||
509 | while (argc > 0) { | 510 | while (argc > 0) { |
510 | if (matches(*argv, "protocol") == 0) { | 511 | if (matches(*argv, "protocol") == 0) { |
@@ -572,7 +573,8 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) | |||
572 | filter.rdst = filter.mdst; | 573 | filter.rdst = filter.mdst; |
573 | } | 574 | } |
574 | } | 575 | } |
575 | argc--; argv++; | 576 | argc--; |
577 | argv++; | ||
576 | } | 578 | } |
577 | 579 | ||
578 | if (do_ipv6 == AF_UNSPEC && filter.tb) { | 580 | if (do_ipv6 == AF_UNSPEC && filter.tb) { |
@@ -580,7 +582,7 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) | |||
580 | } | 582 | } |
581 | 583 | ||
582 | if (rtnl_open(&rth, 0) < 0) { | 584 | if (rtnl_open(&rth, 0) < 0) { |
583 | exit(1); | 585 | return 1; |
584 | } | 586 | } |
585 | 587 | ||
586 | ll_init_map(&rth); | 588 | ll_init_map(&rth); |
@@ -589,15 +591,16 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) | |||
589 | int idx; | 591 | int idx; |
590 | 592 | ||
591 | if (id) { | 593 | if (id) { |
592 | if ((idx = ll_name_to_index(id)) == 0) { | 594 | idx = ll_name_to_index(id); |
593 | bb_error_msg("cannot find device \"%s\"", id); | 595 | if (idx == 0) { |
594 | return -1; | 596 | bb_error_msg_and_die("cannot find device \"%s\"", id); |
595 | } | 597 | } |
596 | filter.iif = idx; | 598 | filter.iif = idx; |
597 | filter.iifmask = -1; | 599 | filter.iifmask = -1; |
598 | } | 600 | } |
599 | if (od) { | 601 | if (od) { |
600 | if ((idx = ll_name_to_index(od)) == 0) { | 602 | idx = ll_name_to_index(od); |
603 | if (idx == 0) { | ||
601 | bb_error_msg("cannot find device \"%s\"", od); | 604 | bb_error_msg("cannot find device \"%s\"", od); |
602 | } | 605 | } |
603 | filter.oif = idx; | 606 | filter.oif = idx; |
@@ -622,20 +625,17 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) | |||
622 | 625 | ||
623 | for (;;) { | 626 | for (;;) { |
624 | if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) { | 627 | if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) { |
625 | perror("Cannot send dump request"); | 628 | bb_perror_msg_and_die("cannot send dump request"); |
626 | return -1; | ||
627 | } | 629 | } |
628 | filter.flushed = 0; | 630 | filter.flushed = 0; |
629 | if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) { | 631 | if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) { |
630 | bb_error_msg("flush terminated"); | 632 | bb_error_msg_and_die("flush terminated"); |
631 | return -1; | ||
632 | } | 633 | } |
633 | if (filter.flushed == 0) { | 634 | if (filter.flushed == 0) { |
634 | fflush(stdout); | ||
635 | return 0; | 635 | return 0; |
636 | } | 636 | } |
637 | if (flush_update() < 0) | 637 | if (flush_update()) |
638 | exit(1); | 638 | return 1; |
639 | } | 639 | } |
640 | } | 640 | } |
641 | 641 | ||
@@ -653,10 +653,11 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) | |||
653 | bb_error_msg_and_die("dump terminated"); | 653 | bb_error_msg_and_die("dump terminated"); |
654 | } | 654 | } |
655 | 655 | ||
656 | exit(0); | 656 | return 0; |
657 | } | 657 | } |
658 | 658 | ||
659 | 659 | ||
660 | /* Return value becomes exitcode. It's okay to not return at all */ | ||
660 | static int iproute_get(int argc, char **argv) | 661 | static int iproute_get(int argc, char **argv) |
661 | { | 662 | { |
662 | struct rtnl_handle rth; | 663 | struct rtnl_handle rth; |
@@ -734,7 +735,8 @@ static int iproute_get(int argc, char **argv) | |||
734 | } | 735 | } |
735 | req.r.rtm_dst_len = addr.bitlen; | 736 | req.r.rtm_dst_len = addr.bitlen; |
736 | } | 737 | } |
737 | argc--; argv++; | 738 | argc--; |
739 | argv++; | ||
738 | } | 740 | } |
739 | } | 741 | } |
740 | 742 | ||
@@ -743,7 +745,7 @@ static int iproute_get(int argc, char **argv) | |||
743 | } | 745 | } |
744 | 746 | ||
745 | if (rtnl_open(&rth, 0) < 0) | 747 | if (rtnl_open(&rth, 0) < 0) |
746 | exit(1); | 748 | return 1; |
747 | 749 | ||
748 | ll_init_map(&rth); | 750 | ll_init_map(&rth); |
749 | 751 | ||
@@ -751,16 +753,16 @@ static int iproute_get(int argc, char **argv) | |||
751 | int idx; | 753 | int idx; |
752 | 754 | ||
753 | if (idev) { | 755 | if (idev) { |
754 | if ((idx = ll_name_to_index(idev)) == 0) { | 756 | idx = ll_name_to_index(idev); |
755 | bb_error_msg("cannot find device \"%s\"", idev); | 757 | if (idx == 0) { |
756 | return -1; | 758 | bb_error_msg_and_die("cannot find device \"%s\"", idev); |
757 | } | 759 | } |
758 | addattr32(&req.n, sizeof(req), RTA_IIF, idx); | 760 | addattr32(&req.n, sizeof(req), RTA_IIF, idx); |
759 | } | 761 | } |
760 | if (odev) { | 762 | if (odev) { |
761 | if ((idx = ll_name_to_index(odev)) == 0) { | 763 | idx = ll_name_to_index(odev); |
762 | bb_error_msg("cannot find device \"%s\"", odev); | 764 | if (idx == 0) { |
763 | return -1; | 765 | bb_error_msg_and_die("cannot find device \"%s\"", odev); |
764 | } | 766 | } |
765 | addattr32(&req.n, sizeof(req), RTA_OIF, idx); | 767 | addattr32(&req.n, sizeof(req), RTA_OIF, idx); |
766 | } | 768 | } |
@@ -771,7 +773,7 @@ static int iproute_get(int argc, char **argv) | |||
771 | } | 773 | } |
772 | 774 | ||
773 | if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) { | 775 | if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) { |
774 | exit(2); | 776 | return 2; |
775 | } | 777 | } |
776 | 778 | ||
777 | if (connected && !from_ok) { | 779 | if (connected && !from_ok) { |
@@ -784,13 +786,11 @@ static int iproute_get(int argc, char **argv) | |||
784 | } | 786 | } |
785 | 787 | ||
786 | if (req.n.nlmsg_type != RTM_NEWROUTE) { | 788 | if (req.n.nlmsg_type != RTM_NEWROUTE) { |
787 | bb_error_msg("not a route?"); | 789 | bb_error_msg_and_die("not a route?"); |
788 | return -1; | ||
789 | } | 790 | } |
790 | len -= NLMSG_LENGTH(sizeof(*r)); | 791 | len -= NLMSG_LENGTH(sizeof(*r)); |
791 | if (len < 0) { | 792 | if (len < 0) { |
792 | bb_error_msg("wrong len %d", len); | 793 | bb_error_msg_and_die("wrong len %d", len); |
793 | return -1; | ||
794 | } | 794 | } |
795 | 795 | ||
796 | memset(tb, 0, sizeof(tb)); | 796 | memset(tb, 0, sizeof(tb)); |
@@ -800,8 +800,7 @@ static int iproute_get(int argc, char **argv) | |||
800 | tb[RTA_PREFSRC]->rta_type = RTA_SRC; | 800 | tb[RTA_PREFSRC]->rta_type = RTA_SRC; |
801 | r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]); | 801 | r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]); |
802 | } else if (!tb[RTA_SRC]) { | 802 | } else if (!tb[RTA_SRC]) { |
803 | bb_error_msg("failed to connect the route"); | 803 | bb_error_msg_and_die("failed to connect the route"); |
804 | return -1; | ||
805 | } | 804 | } |
806 | if (!odev && tb[RTA_OIF]) { | 805 | if (!odev && tb[RTA_OIF]) { |
807 | tb[RTA_OIF]->rta_type = 0; | 806 | tb[RTA_OIF]->rta_type = 0; |
@@ -816,17 +815,19 @@ static int iproute_get(int argc, char **argv) | |||
816 | req.n.nlmsg_type = RTM_GETROUTE; | 815 | req.n.nlmsg_type = RTM_GETROUTE; |
817 | 816 | ||
818 | if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) { | 817 | if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) { |
819 | exit(2); | 818 | return 2; |
820 | } | 819 | } |
821 | } | 820 | } |
822 | 821 | ||
823 | if (print_route(NULL, &req.n, (void*)stdout) < 0) { | 822 | if (print_route(NULL, &req.n, (void*)stdout) < 0) { |
823 | // how is this useful? | ||
824 | bb_error_msg_and_die("an error :-)"); | 824 | bb_error_msg_and_die("an error :-)"); |
825 | } | 825 | } |
826 | 826 | ||
827 | exit(0); | 827 | return 0; |
828 | } | 828 | } |
829 | 829 | ||
830 | /* Return value becomes exitcode. It's okay to not return at all */ | ||
830 | int do_iproute(int argc, char **argv) | 831 | int do_iproute(int argc, char **argv) |
831 | { | 832 | { |
832 | static const char * const ip_route_commands[] = { | 833 | static const char * const ip_route_commands[] = { |