Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/networking/libiproute
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- Location:
- branches/stable/mindi-busybox/networking/libiproute
- Files:
-
- 3 deleted
- 19 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/networking/libiproute/ip_common.h
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 #ifndef _IP_COMMON_H 2 3 #define _IP_COMMON_H 1 3 4 4 #include " busybox.h"5 #include "libbb.h" 5 6 #include <asm/types.h> 6 7 #include <linux/netlink.h> 7 8 #include <linux/rtnetlink.h> 8 9 10 extern int preferred_family; 11 extern char * _SL_; 9 #if !defined IFA_RTA 10 #include <linux/if_addr.h> 11 #endif 12 #if !defined IFLA_RTA 13 #include <linux/if_link.h> 14 #endif 12 15 13 16 extern void ip_parse_common_args(int *argcp, char ***argvp); … … 17 20 extern void iplink_usage(void) ATTRIBUTE_NORETURN; 18 21 extern void ipneigh_reset_filter(void); 22 19 23 extern int do_ipaddr(int argc, char **argv); 20 24 extern int do_iproute(int argc, char **argv); -
branches/stable/mindi-busybox/networking/libiproute/ip_parse_common_args.c
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * ip.c "ip" utility frontend. … … 15 16 */ 16 17 17 #include <string.h> 18 19 #include "libbb.h" 18 #include "ip_common.h" /* #include "libbb.h" is inside */ 20 19 #include "utils.h" 21 #include "ip_common.h"22 23 20 24 21 int preferred_family = AF_UNSPEC; 25 int oneline = 0;26 char * _SL_ = NULL;22 smallint oneline; 23 char _SL_; 27 24 28 25 void ip_parse_common_args(int *argcp, char ***argvp) … … 30 27 int argc = *argcp; 31 28 char **argv = *argvp; 29 static const char ip_common_commands[] ALIGN1 = 30 "-family\0""inet\0""inet6\0""link\0" 31 "-4\0""-6\0""-0\0""-oneline\0"; 32 enum { 33 ARG_family = 1, 34 ARG_inet, 35 ARG_inet6, 36 ARG_link, 37 ARG_IPv4, 38 ARG_IPv6, 39 ARG_packet, 40 ARG_oneline 41 }; 42 smalluint arg; 32 43 33 44 while (argc > 1) { … … 35 46 36 47 if (strcmp(opt,"--") == 0) { 37 argc--; argv++; 48 argc--; 49 argv++; 38 50 break; 39 51 } 40 41 52 if (opt[0] != '-') 42 53 break; 43 44 54 if (opt[1] == '-') 45 55 opt++; 46 47 if ( matches(opt, "-family") == 0) {56 arg = index_in_strings(ip_common_commands, opt) + 1; 57 if (arg == ARG_family) { 48 58 argc--; 49 59 argv++; 50 if (! argv[1]) 51 bb_show_usage(); 52 if (strcmp(argv[1], "inet") == 0) 60 if (!argv[1]) 61 bb_show_usage(); 62 arg = index_in_strings(ip_common_commands, argv[1]) + 1; 63 if (arg == ARG_inet) 53 64 preferred_family = AF_INET; 54 else if ( strcmp(argv[1], "inet6") == 0)65 else if (arg == ARG_inet6) 55 66 preferred_family = AF_INET6; 56 else if ( strcmp(argv[1], "link") == 0)67 else if (arg == ARG_link) 57 68 preferred_family = AF_PACKET; 58 69 else 59 70 invarg(argv[1], "protocol family"); 60 } else if ( strcmp(opt, "-4") == 0) {71 } else if (arg == ARG_IPv4) { 61 72 preferred_family = AF_INET; 62 } else if ( strcmp(opt, "-6") == 0) {73 } else if (arg == ARG_IPv6) { 63 74 preferred_family = AF_INET6; 64 } else if ( strcmp(opt, "-0") == 0) {75 } else if (arg == ARG_packet) { 65 76 preferred_family = AF_PACKET; 66 } else if ( matches(opt, "-oneline") == 0) {77 } else if (arg == ARG_oneline) { 67 78 ++oneline; 68 79 } else { 69 80 bb_show_usage(); 70 81 } 71 argc--; argv++; 82 argc--; 83 argv++; 72 84 } 73 _SL_ = oneline ? "\\" : "\n";85 _SL_ = oneline ? '\\' : '\n'; 74 86 *argcp = argc; 75 87 *argvp = argv; -
branches/stable/mindi-busybox/networking/libiproute/ipaddress.c
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * ipaddress.c "ip address". … … 10 11 */ 11 12 12 #include "libbb.h" 13 #include <sys/socket.h> 14 #include <sys/ioctl.h> 15 13 //#include <sys/socket.h> 14 //#include <sys/ioctl.h> 16 15 #include <fnmatch.h> 17 #include <string.h>18 #include <unistd.h>19 20 16 #include <net/if.h> 21 17 #include <net/if_arp.h> 22 18 19 #include "ip_common.h" /* #include "libbb.h" is inside */ 23 20 #include "rt_names.h" 24 21 #include "utils.h" 25 #include "ip_common.h" 26 27 28 static struct 29 { 22 23 24 typedef struct filter_t { 30 25 int ifindex; 31 26 int family; … … 42 37 int flushe; 43 38 struct rtnl_handle *rth; 44 } filter; 39 } filter_t; 40 41 #define filter (*(filter_t*)&bb_common_bufsiz1) 42 45 43 46 44 static void print_link_flags(FILE *fp, unsigned flags, unsigned mdown) … … 49 47 flags &= ~IFF_RUNNING; 50 48 #define _PF(f) if (flags&IFF_##f) { \ 51 flags &= ~IFF_##f 49 flags &= ~IFF_##f; \ 52 50 fprintf(fp, #f "%s", flags ? "," : ""); } 53 51 _PF(LOOPBACK); … … 86 84 87 85 memset(&ifr, 0, sizeof(ifr)); 88 strcpy(ifr.ifr_name, name); 89 if (ioctl(s, SIOCGIFTXQLEN, &ifr) < 0) { 90 perror("SIOCGIFXQLEN"); 86 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); 87 if (ioctl_or_warn(s, SIOCGIFTXQLEN, &ifr) < 0) { 91 88 close(s); 92 89 return; … … 99 96 100 97 static int print_linkinfo(struct sockaddr_nl ATTRIBUTE_UNUSED *who, 101 struct nlmsghdr *n, void ATTRIBUTE_UNUSED *arg)98 const struct nlmsghdr *n, void ATTRIBUTE_UNUSED *arg) 102 99 { 103 100 FILE *fp = (FILE*)arg; … … 125 122 return -1; 126 123 } 127 if (filter.label && 128 (!filter.family || filter.family == AF_PACKET) && 129 fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0)) 130 return 0; 124 if (filter.label 125 && (!filter.family || filter.family == AF_PACKET) 126 && fnmatch(filter.label, RTA_DATA(tb[IFLA_IFNAME]), 0) 127 ) { 128 return 0; 129 } 131 130 132 131 if (n->nlmsg_type == RTM_DELLINK) … … 166 165 if (!filter.family || filter.family == AF_PACKET) { 167 166 SPRINT_BUF(b1); 168 fprintf(fp, "%s", _SL_); 169 fprintf(fp, " link/%s ", ll_type_n2a(ifi->ifi_type, b1, sizeof(b1))); 167 fprintf(fp, "%c link/%s ", _SL_, ll_type_n2a(ifi->ifi_type, b1, sizeof(b1))); 170 168 171 169 if (tb[IFLA_ADDRESS]) { … … 186 184 } 187 185 } 188 fp rintf(fp, "\n");186 fputc('\n', fp); 189 187 fflush(fp); 190 188 return 0; … … 194 192 { 195 193 if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) { 196 perror("Failed to send flush request\n");194 bb_perror_msg("failed to send flush request"); 197 195 return -1; 198 196 } … … 341 339 struct ifa_cacheinfo *ci = RTA_DATA(rta_tb[IFA_CACHEINFO]); 342 340 char buf[128]; 343 fp rintf(fp, "%s", _SL_);341 fputc(_SL_, fp); 344 342 if (ci->ifa_valid == 0xFFFFFFFFU) 345 343 sprintf(buf, "valid_lft forever"); … … 352 350 fprintf(fp, " %s", buf); 353 351 } 354 fp rintf(fp, "\n");352 fputc('\n', fp); 355 353 fflush(fp); 356 354 return 0; … … 366 364 static int print_selected_addrinfo(int ifindex, struct nlmsg_list *ainfo, FILE *fp) 367 365 { 368 for ( ;ainfo ;ainfo = ainfo->next) {366 for (; ainfo; ainfo = ainfo->next) { 369 367 struct nlmsghdr *n = &ainfo->h; 370 368 struct ifaddrmsg *ifa = NLMSG_DATA(n); … … 412 410 } 413 411 412 /* Return value becomes exitcode. It's okay to not return at all */ 414 413 int ipaddr_list_or_flush(int argc, char **argv, int flush) 415 414 { 416 static const char *const option[] = { "to", "scope", "up", "label", "dev", 0 };415 static const char option[] ALIGN1 = "to\0""scope\0""up\0""label\0""dev\0"; 417 416 418 417 struct nlmsg_list *linfo = NULL; … … 431 430 if (flush) { 432 431 if (argc <= 0) { 433 bb_error_msg(bb_msg_requires_arg, "flush"); 434 return -1; 432 bb_error_msg_and_die(bb_msg_requires_arg, "flush"); 435 433 } 436 434 if (filter.family == AF_PACKET) { 437 bb_error_msg("Cannot flush link addresses."); 438 return -1; 435 bb_error_msg_and_die("cannot flush link addresses"); 439 436 } 440 437 } 441 438 442 439 while (argc > 0) { 443 const int option_num = compare_string_array(option, *argv);440 const int option_num = index_in_strings(option, *argv); 444 441 switch (option_num) { 445 442 case 0: /* to */ … … 484 481 } 485 482 486 if (rtnl_open(&rth, 0) < 0) 487 exit(1); 488 489 if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK) < 0) { 490 bb_perror_msg_and_die("Cannot send dump request"); 491 } 492 493 if (rtnl_dump_filter(&rth, store_nlmsg, &linfo, NULL, NULL) < 0) { 494 bb_error_msg_and_die("Dump terminated"); 495 } 483 xrtnl_open(&rth); 484 485 xrtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK); 486 xrtnl_dump_filter(&rth, store_nlmsg, &linfo); 496 487 497 488 if (filter_dev) { 498 filter.ifindex = ll_name_to_index(filter_dev); 499 if (filter.ifindex <= 0) { 500 bb_error_msg("Device \"%s\" does not exist", filter_dev); 501 return -1; 502 } 489 filter.ifindex = xll_name_to_index(filter_dev); 503 490 } 504 491 … … 512 499 513 500 for (;;) { 514 if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { 515 perror("Cannot send dump request"); 516 exit(1); 517 } 501 xrtnl_wilddump_request(&rth, filter.family, RTM_GETADDR); 518 502 filter.flushed = 0; 519 if (rtnl_dump_filter(&rth, print_addrinfo, stdout, NULL, NULL) < 0) { 520 fprintf(stderr, "Flush terminated\n"); 521 exit(1); 522 } 503 xrtnl_dump_filter(&rth, print_addrinfo, stdout); 523 504 if (filter.flushed == 0) { 524 fflush(stdout);525 505 return 0; 526 506 } 527 507 if (flush_update() < 0) 528 exit(1);508 return 1; 529 509 } 530 510 } 531 511 532 512 if (filter.family != AF_PACKET) { 533 if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) { 534 bb_perror_msg_and_die("Cannot send dump request"); 535 } 536 537 if (rtnl_dump_filter(&rth, store_nlmsg, &ainfo, NULL, NULL) < 0) { 538 bb_error_msg_and_die("Dump terminated"); 539 } 513 xrtnl_wilddump_request(&rth, filter.family, RTM_GETADDR); 514 xrtnl_dump_filter(&rth, store_nlmsg, &ainfo); 540 515 } 541 516 … … 601 576 } 602 577 603 for (l =linfo; l; l = l->next) {578 for (l = linfo; l; l = l->next) { 604 579 if (no_link || print_linkinfo(NULL, &l->h, stdout) == 0) { 605 580 struct ifinfomsg *ifi = NLMSG_DATA(&l->h); … … 607 582 print_selected_addrinfo(ifi->ifi_index, ainfo, stdout); 608 583 } 609 fflush(stdout); 610 } 611 612 exit(0);584 fflush(stdout); /* why? */ 585 } 586 587 return 0; 613 588 } 614 589 … … 616 591 { 617 592 if (lcl->family == AF_INET) { 618 if (lcl->bytelen >= 1 && *( __u8*)&lcl->data == 127)593 if (lcl->bytelen >= 1 && *(uint8_t*)&lcl->data == 127) 619 594 return RT_SCOPE_HOST; 620 595 } … … 622 597 } 623 598 599 /* Return value becomes exitcode. It's okay to not return at all */ 624 600 static int ipaddr_modify(int cmd, int argc, char **argv) 625 601 { 626 static const char *const option[] = { 627 "peer", "remote", "broadcast", "brd", 628 "anycast", "scope", "dev", "label", "local", 0 629 }; 630 602 static const char option[] ALIGN1 = 603 "peer\0""remote\0""broadcast\0""brd\0" 604 "anycast\0""scope\0""dev\0""label\0""local\0"; 631 605 struct rtnl_handle rth; 632 606 struct { 633 struct nlmsghdr 634 struct ifaddrmsg 635 char 607 struct nlmsghdr n; 608 struct ifaddrmsg ifa; 609 char buf[256]; 636 610 } req; 637 char 638 char 611 char *d = NULL; 612 char *l = NULL; 639 613 inet_prefix lcl; 640 614 inet_prefix peer; … … 643 617 int brd_len = 0; 644 618 int any_len = 0; 645 intscoped = 0;619 bool scoped = 0; 646 620 647 621 memset(&req, 0, sizeof(req)); … … 653 627 654 628 while (argc > 0) { 655 const int option_num = compare_string_array(option, *argv);629 const int option_num = index_in_strings(option, *argv); 656 630 switch (option_num) { 657 631 case 0: /* peer */ … … 678 652 duparg("broadcast", *argv); 679 653 } 680 if ( strcmp(*argv, "+") == 0) {654 if (LONE_CHAR(*argv, '+')) { 681 655 brd_len = -1; 682 656 } 683 else if ( strcmp(*argv, "-") == 0) {657 else if (LONE_DASH(*argv)) { 684 658 brd_len = -2; 685 659 } else { … … 748 722 return -1; 749 723 } 750 if (l && matches(d, l) != 0) {724 if (l && strncmp(d, l, strlen(d)) != 0) { 751 725 bb_error_msg_and_die("\"dev\" (%s) must match \"label\" (%s)", d, l); 752 726 } … … 763 737 int i; 764 738 if (req.ifa.ifa_family != AF_INET) { 765 bb_error_msg("Broadcast can be set only for IPv4 addresses"); 766 return -1; 739 bb_error_msg_and_die("broadcast can be set only for IPv4 addresses"); 767 740 } 768 741 brd = peer; … … 781 754 req.ifa.ifa_scope = default_scope(&lcl); 782 755 783 if (rtnl_open(&rth, 0) < 0) 784 exit(1); 756 xrtnl_open(&rth); 785 757 786 758 ll_init_map(&rth); 787 759 788 if ((req.ifa.ifa_index = ll_name_to_index(d)) == 0) { 789 bb_error_msg("Cannot find device \"%s\"", d); 790 return -1; 791 } 760 req.ifa.ifa_index = xll_name_to_index(d); 792 761 793 762 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) 794 exit(2); 795 796 exit(0); 797 } 798 763 return 2; 764 765 return 0; 766 } 767 768 /* Return value becomes exitcode. It's okay to not return at all */ 799 769 int do_ipaddr(int argc, char **argv) 800 770 { 801 static const char *const commands[] = { 802 "add", "delete", "list", "show", "lst", "flush", 0 803 }; 804 805 int command_num = 2; 771 static const char commands[] ALIGN1 = 772 "add\0""delete\0""list\0""show\0""lst\0""flush\0"; 773 774 int command_num = 2; /* default command is list */ 806 775 807 776 if (*argv) { 808 command_num = compare_string_array(commands, *argv); 809 } 810 switch (command_num) { 811 case 0: /* add */ 812 return ipaddr_modify(RTM_NEWADDR, argc-1, argv+1); 813 case 1: /* delete */ 814 return ipaddr_modify(RTM_DELADDR, argc-1, argv+1); 815 case 2: /* list */ 816 case 3: /* show */ 817 case 4: /* lst */ 818 return ipaddr_list_or_flush(argc-1, argv+1, 0); 819 case 5: /* flush */ 820 return ipaddr_list_or_flush(argc-1, argv+1, 1); 821 } 822 bb_error_msg_and_die("Unknown command %s", *argv); 823 } 777 command_num = index_in_substrings(commands, *argv); 778 } 779 if (command_num < 0 || command_num > 5) 780 bb_error_msg_and_die("unknown command %s", *argv); 781 --argc; 782 ++argv; 783 if (command_num == 0) /* add */ 784 return ipaddr_modify(RTM_NEWADDR, argc, argv); 785 else if (command_num == 1) /* delete */ 786 return ipaddr_modify(RTM_DELADDR, argc, argv); 787 else if (command_num == 5) /* flush */ 788 return ipaddr_list_or_flush(argc, argv, 1); 789 else /* 2 == list, 3 == show, 4 == lst */ 790 return ipaddr_list_or_flush(argc, argv, 0); 791 } -
branches/stable/mindi-busybox/networking/libiproute/iplink.c
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 * iplink.c 3 * iplink.c "ip link". 3 4 * 4 * Authors: 5 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 5 6 * 6 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 7 8 */ 8 9 9 #include "libbb.h" 10 11 #include <sys/ioctl.h> 12 #include <sys/socket.h> 13 14 #include <errno.h> 15 #include <string.h> 16 #include <unistd.h> 17 10 //#include <sys/ioctl.h> 11 //#include <sys/socket.h> 18 12 #include <net/if.h> 19 13 #include <net/if_packet.h> 20 14 #include <netpacket/packet.h> 21 22 15 #include <net/ethernet.h> 23 16 17 #include "ip_common.h" /* #include "libbb.h" is inside */ 24 18 #include "rt_names.h" 25 19 #include "utils.h" 26 #include "ip_common.h" 27 28 /* take from linux/sockios.h */ 20 21 /* taken from linux/sockios.h */ 29 22 #define SIOCSIFNAME 0x8923 /* set interface name */ 30 23 31 static int do_link; 32 33 static int on_off(char *msg) 34 { 35 bb_error_msg("Error: argument of \"%s\" must be \"on\" or \"off\"", msg); 36 return -1; 37 } 38 24 static void on_off(const char *msg) ATTRIBUTE_NORETURN; 25 static void on_off(const char *msg) 26 { 27 bb_error_msg_and_die("error: argument of \"%s\" must be \"on\" or \"off\"", msg); 28 } 29 30 /* Exits on error */ 39 31 static int get_ctl_fd(void) 40 32 { 41 int s_errno;42 33 int fd; 43 34 … … 45 36 if (fd >= 0) 46 37 return fd; 47 s_errno = errno;48 38 fd = socket(PF_PACKET, SOCK_DGRAM, 0); 49 39 if (fd >= 0) 50 40 return fd; 51 fd = socket(PF_INET6, SOCK_DGRAM, 0); 52 if (fd >= 0) 53 return fd; 54 errno = s_errno; 55 perror("Cannot create control socket"); 56 return -1; 57 } 58 59 static int do_chflags(char *dev, __u32 flags, __u32 mask) 41 return xsocket(PF_INET6, SOCK_DGRAM, 0); 42 } 43 44 /* Exits on error */ 45 static void do_chflags(char *dev, uint32_t flags, uint32_t mask) 60 46 { 61 47 struct ifreq ifr; 62 48 int fd; 63 int err; 64 65 strcpy(ifr.ifr_name, dev); 49 50 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 66 51 fd = get_ctl_fd(); 67 if (fd < 0) 68 return -1; 69 err = ioctl(fd, SIOCGIFFLAGS, &ifr); 70 if (err) { 71 perror("SIOCGIFFLAGS"); 72 close(fd); 73 return -1; 74 } 75 if ((ifr.ifr_flags^flags)&mask) { 52 xioctl(fd, SIOCGIFFLAGS, &ifr); 53 if ((ifr.ifr_flags ^ flags) & mask) { 76 54 ifr.ifr_flags &= ~mask; 77 ifr.ifr_flags |= mask&flags; 78 err = ioctl(fd, SIOCSIFFLAGS, &ifr); 79 if (err) 80 perror("SIOCSIFFLAGS"); 55 ifr.ifr_flags |= mask & flags; 56 xioctl(fd, SIOCSIFFLAGS, &ifr); 81 57 } 82 58 close(fd); 83 return err; 84 } 85 86 static intdo_changename(char *dev, char *newdev)59 } 60 61 /* Exits on error */ 62 static void do_changename(char *dev, char *newdev) 87 63 { 88 64 struct ifreq ifr; 89 65 int fd; 90 int err; 91 92 strcpy(ifr.ifr_name, dev); 93 strcpy(ifr.ifr_newname, newdev); 66 67 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 68 strncpy(ifr.ifr_newname, newdev, sizeof(ifr.ifr_newname)); 94 69 fd = get_ctl_fd(); 95 if (fd < 0) 96 return -1; 97 err = ioctl(fd, SIOCSIFNAME, &ifr); 98 if (err) { 99 perror("SIOCSIFNAME"); 100 close(fd); 101 return -1; 102 } 70 xioctl(fd, SIOCSIFNAME, &ifr); 103 71 close(fd); 104 return err; 105 } 106 107 static intset_qlen(char *dev, int qlen)72 } 73 74 /* Exits on error */ 75 static void set_qlen(char *dev, int qlen) 108 76 { 109 77 struct ifreq ifr; … … 111 79 112 80 s = get_ctl_fd(); 113 if (s < 0)114 return -1;115 116 81 memset(&ifr, 0, sizeof(ifr)); 117 str cpy(ifr.ifr_name, dev);82 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 118 83 ifr.ifr_qlen = qlen; 119 if (ioctl(s, SIOCSIFTXQLEN, &ifr) < 0) { 120 perror("SIOCSIFXQLEN"); 121 close(s); 122 return -1; 123 } 124 close(s); 125 126 return 0; 127 } 128 129 static int set_mtu(char *dev, int mtu) 84 xioctl(s, SIOCSIFTXQLEN, &ifr); 85 close(s); 86 } 87 88 /* Exits on error */ 89 static void set_mtu(char *dev, int mtu) 130 90 { 131 91 struct ifreq ifr; … … 133 93 134 94 s = get_ctl_fd(); 135 if (s < 0)136 return -1;137 138 95 memset(&ifr, 0, sizeof(ifr)); 139 str cpy(ifr.ifr_name, dev);96 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 140 97 ifr.ifr_mtu = mtu; 141 if (ioctl(s, SIOCSIFMTU, &ifr) < 0) { 142 perror("SIOCSIFMTU"); 143 close(s); 144 return -1; 145 } 146 close(s); 147 148 return 0; 149 } 150 98 xioctl(s, SIOCSIFMTU, &ifr); 99 close(s); 100 } 101 102 /* Exits on error */ 151 103 static int get_address(char *dev, int *htype) 152 104 { … … 156 108 int s; 157 109 158 s = socket(PF_PACKET, SOCK_DGRAM, 0); 159 if (s < 0) { 160 perror("socket(PF_PACKET)"); 161 return -1; 162 } 110 s = xsocket(PF_PACKET, SOCK_DGRAM, 0); 163 111 164 112 memset(&ifr, 0, sizeof(ifr)); 165 strcpy(ifr.ifr_name, dev); 166 if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { 167 perror("SIOCGIFINDEX"); 168 close(s); 169 return -1; 170 } 113 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 114 xioctl(s, SIOCGIFINDEX, &ifr); 171 115 172 116 memset(&me, 0, sizeof(me)); … … 174 118 me.sll_ifindex = ifr.ifr_ifindex; 175 119 me.sll_protocol = htons(ETH_P_LOOP); 176 if (bind(s, (struct sockaddr*)&me, sizeof(me)) == -1) { 177 perror("bind"); 178 close(s); 179 return -1; 180 } 120 xbind(s, (struct sockaddr*)&me, sizeof(me)); 181 121 182 122 alen = sizeof(me); 183 123 if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) { 184 perror("getsockname"); 185 close(s); 186 return -1; 124 bb_perror_msg_and_die("getsockname"); 187 125 } 188 126 close(s); … … 191 129 } 192 130 193 static int parse_address(char *dev, int hatype, int halen, char *lla, struct ifreq *ifr) 131 /* Exits on error */ 132 static void parse_address(char *dev, int hatype, int halen, char *lla, struct ifreq *ifr) 194 133 { 195 134 int alen; 196 135 197 136 memset(ifr, 0, sizeof(*ifr)); 198 str cpy(ifr->ifr_name, dev);137 strncpy(ifr->ifr_name, dev, sizeof(ifr->ifr_name)); 199 138 ifr->ifr_hwaddr.sa_family = hatype; 200 139 alen = ll_addr_a2n((unsigned char *)(ifr->ifr_hwaddr.sa_data), 14, lla); 201 140 if (alen < 0) 202 return -1;141 exit(1); 203 142 if (alen != halen) { 204 bb_error_msg("Wrong address (%s) length: expected %d bytes", lla, halen); 205 return -1; 206 } 207 return 0; 208 } 209 210 static int set_address(struct ifreq *ifr, int brd) 143 bb_error_msg_and_die("wrong address (%s) length: expected %d bytes", lla, halen); 144 } 145 } 146 147 /* Exits on error */ 148 static void set_address(struct ifreq *ifr, int brd) 211 149 { 212 150 int s; 213 151 214 152 s = get_ctl_fd(); 215 if (s < 0) 216 return -1; 217 if (ioctl(s, brd?SIOCSIFHWBROADCAST:SIOCSIFHWADDR, ifr) < 0) { 218 perror(brd?"SIOCSIFHWBROADCAST":"SIOCSIFHWADDR"); 219 close(s); 220 return -1; 221 } 222 close(s); 223 return 0; 224 } 225 226 153 if (brd) 154 xioctl(s, SIOCSIFHWBROADCAST, ifr); 155 else 156 xioctl(s, SIOCSIFHWADDR, ifr); 157 close(s); 158 } 159 160 161 /* Return value becomes exitcode. It's okay to not return at all */ 227 162 static int do_set(int argc, char **argv) 228 163 { 229 164 char *dev = NULL; 230 __u32mask = 0;231 __u32flags = 0;165 uint32_t mask = 0; 166 uint32_t flags = 0; 232 167 int qlen = -1; 233 168 int mtu = -1; … … 237 172 char *newname = NULL; 238 173 int htype, halen; 174 static const char keywords[] ALIGN1 = 175 "up\0""down\0""name\0""mtu\0""multicast\0""arp\0""addr\0""dev\0" 176 "on\0""off\0"; 177 enum { ARG_up = 1, ARG_down, ARG_name, ARG_mtu, ARG_multicast, ARG_arp, 178 ARG_addr, ARG_dev, PARM_on, PARM_off }; 179 smalluint key; 239 180 240 181 while (argc > 0) { 241 if (strcmp(*argv, "up") == 0) { 182 key = index_in_strings(keywords, *argv) + 1; 183 if (key == ARG_up) { 242 184 mask |= IFF_UP; 243 185 flags |= IFF_UP; 244 } else if ( strcmp(*argv, "down") == 0) {186 } else if (key == ARG_down) { 245 187 mask |= IFF_UP; 246 188 flags &= ~IFF_UP; 247 } else if ( strcmp(*argv, "name") == 0) {189 } else if (key == ARG_name) { 248 190 NEXT_ARG(); 249 191 newname = *argv; 250 } else if ( strcmp(*argv, "mtu") == 0) {192 } else if (key == ARG_mtu) { 251 193 NEXT_ARG(); 252 194 if (mtu != -1) … … 254 196 if (get_integer(&mtu, *argv, 0)) 255 197 invarg(*argv, "mtu"); 256 } else if ( strcmp(*argv, "multicast") == 0) {198 } else if (key == ARG_multicast) { 257 199 NEXT_ARG(); 258 200 mask |= IFF_MULTICAST; 259 if (strcmp(*argv, "on") == 0) { 201 key = index_in_strings(keywords, *argv) + 1; 202 if (key == PARM_on) { 260 203 flags |= IFF_MULTICAST; 261 } else if ( strcmp(*argv, "off") == 0) {204 } else if (key == PARM_off) { 262 205 flags &= ~IFF_MULTICAST; 263 206 } else 264 returnon_off("multicast");265 } else if ( strcmp(*argv, "arp") == 0) {207 on_off("multicast"); 208 } else if (key == ARG_arp) { 266 209 NEXT_ARG(); 267 210 mask |= IFF_NOARP; 268 if (strcmp(*argv, "on") == 0) { 211 key = index_in_strings(keywords, *argv) + 1; 212 if (key == PARM_on) { 269 213 flags &= ~IFF_NOARP; 270 } else if ( strcmp(*argv, "off") == 0) {214 } else if (key == PARM_off) { 271 215 flags |= IFF_NOARP; 272 216 } else 273 return on_off("noarp");274 } else if ( strcmp(*argv, "addr") == 0) {217 on_off("arp"); 218 } else if (key == ARG_addr) { 275 219 NEXT_ARG(); 276 220 newaddr = *argv; 277 221 } else { 278 if ( strcmp(*argv, "dev") == 0) {222 if (key == ARG_dev) { 279 223 NEXT_ARG(); 280 224 } … … 287 231 288 232 if (!dev) { 289 bb_error_msg(bb_msg_requires_arg, "\"dev\""); 290 exit(-1); 233 bb_error_msg_and_die(bb_msg_requires_arg, "\"dev\""); 291 234 } 292 235 293 236 if (newaddr || newbrd) { 294 237 halen = get_address(dev, &htype); 295 if (halen < 0)296 return -1;297 238 if (newaddr) { 298 if (parse_address(dev, htype, halen, newaddr, &ifr0) < 0) 299 return -1; 239 parse_address(dev, htype, halen, newaddr, &ifr0); 300 240 } 301 241 if (newbrd) { 302 if (parse_address(dev, htype, halen, newbrd, &ifr1) < 0) 303 return -1; 242 parse_address(dev, htype, halen, newbrd, &ifr1); 304 243 } 305 244 } 306 245 307 246 if (newname && strcmp(dev, newname)) { 308 if (do_changename(dev, newname) < 0) 309 return -1; 247 do_changename(dev, newname); 310 248 dev = newname; 311 249 } 312 250 if (qlen != -1) { 313 if (set_qlen(dev, qlen) < 0) 314 return -1; 251 set_qlen(dev, qlen); 315 252 } 316 253 if (mtu != -1) { 317 if (set_mtu(dev, mtu) < 0) 318 return -1; 254 set_mtu(dev, mtu); 319 255 } 320 256 if (newaddr || newbrd) { 321 257 if (newbrd) { 322 if (set_address(&ifr1, 1) < 0) 323 return -1; 258 set_address(&ifr1, 1); 324 259 } 325 260 if (newaddr) { 326 if (set_address(&ifr0, 0) < 0) 327 return -1; 261 set_address(&ifr0, 0); 328 262 } 329 263 } 330 264 if (mask) 331 returndo_chflags(dev, flags, mask);265 do_chflags(dev, flags, mask); 332 266 return 0; 333 267 } … … 336 270 { 337 271 preferred_family = AF_PACKET; 338 do_link = 1;339 272 return ipaddr_list_or_flush(argc, argv, 0); 340 273 } 341 274 275 /* Return value becomes exitcode. It's okay to not return at all */ 342 276 int do_iplink(int argc, char **argv) 343 277 { 344 if (argc > 0) { 345 if (matches(*argv, "set") == 0) 346 return do_set(argc-1, argv+1); 347 if (matches(*argv, "show") == 0 || 348 matches(*argv, "lst") == 0 || 349 matches(*argv, "list") == 0) 350 return ipaddr_list_link(argc-1, argv+1); 351 } else 278 static const char keywords[] ALIGN1 = 279 "set\0""show\0""lst\0""list\0"; 280 smalluint key; 281 if (argc <= 0) 352 282 return ipaddr_list_link(0, NULL); 353 354 bb_error_msg("Command \"%s\" is unknown.", *argv); 355 exit(-1); 356 } 283 key = index_in_substrings(keywords, *argv) + 1; 284 if (key == 0) 285 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); 286 argc--; argv++; 287 if (key == 1) /* set */ 288 return do_set(argc, argv); 289 else /* show, lst, list */ 290 return ipaddr_list_link(argc, argv); 291 } -
branches/stable/mindi-busybox/networking/libiproute/iproute.c
r821 r1770 14 14 */ 15 15 16 #include "libbb.h" 17 18 #include <sys/socket.h> 19 20 #include <string.h> 21 #include <fcntl.h> 22 #include <unistd.h> 23 16 #include "ip_common.h" /* #include "libbb.h" is inside */ 24 17 #include "rt_names.h" 25 18 #include "utils.h" 26 #include "ip_common.h"27 19 28 20 #ifndef RTAX_RTTVAR … … 31 23 32 24 33 static struct 34 { 25 typedef struct filter_t { 35 26 int tb; 36 27 int flushed; … … 52 43 inet_prefix rsrc; 53 44 inet_prefix msrc; 54 } filter; 45 } filter_t; 46 47 #define filter (*(filter_t*)&bb_common_bufsiz1) 55 48 56 49 static int flush_update(void) 57 50 { 58 51 if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) { 59 perror("Failed to send flush request\n");52 bb_perror_msg("failed to send flush request"); 60 53 return -1; 61 54 } 62 55 filter.flushp = 0; 63 56 return 0; 57 } 58 59 static unsigned get_hz(void) 60 { 61 static unsigned hz_internal; 62 FILE *fp; 63 64 if (hz_internal) 65 return hz_internal; 66 67 fp = fopen("/proc/net/psched", "r"); 68 if (fp) { 69 unsigned nom, denom; 70 71 if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2) 72 if (nom == 1000000) 73 hz_internal = denom; 74 fclose(fp); 75 } 76 if (!hz_internal) 77 hz_internal = sysconf(_SC_CLK_TCK); 78 return hz_internal; 64 79 } 65 80 … … 86 101 return 0; 87 102 len -= NLMSG_LENGTH(sizeof(*r)); 88 if (len < 0) { 89 bb_error_msg("wrong nlmsg len %d", len); 90 return -1; 91 } 103 if (len < 0) 104 bb_error_msg_and_die("wrong nlmsg len %d", len); 92 105 93 106 if (r->rtm_family == AF_INET6) … … 170 183 if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { 171 184 if (flush_update()) 172 return -1;185 bb_error_msg_and_die("flush"); 173 186 } 174 187 fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp)); … … 249 262 } 250 263 if (tb[RTA_PRIORITY]) { 251 fprintf(fp, " metric %d ", *( __u32*)RTA_DATA(tb[RTA_PRIORITY]));264 fprintf(fp, " metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY])); 252 265 } 253 266 if (r->rtm_family == AF_INET6) { … … 257 270 } 258 271 if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) { 259 static int hz;260 if (!hz) {261 hz = get_hz();262 }263 272 if (r->rtm_flags & RTM_F_CLONED) { 264 fprintf(fp, "% scache ", _SL_);273 fprintf(fp, "%c cache ", _SL_); 265 274 } 266 275 if (ci->rta_expires) { 267 fprintf(fp, " expires %dsec", ci->rta_expires /hz);276 fprintf(fp, " expires %dsec", ci->rta_expires / get_hz()); 268 277 } 269 278 if (ci->rta_error != 0) { … … 278 287 fprintf(fp, " iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF]))); 279 288 } 280 fp rintf(fp, "\n");289 fputc('\n', fp); 281 290 fflush(fp); 282 291 return 0; 283 292 } 284 293 294 /* Return value becomes exitcode. It's okay to not return at all */ 285 295 static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) 286 296 { 297 static const char keywords[] ALIGN1 = 298 "src\0""via\0""mtu\0""lock\0""protocol\0"USE_FEATURE_IP_RULE("table\0") 299 "dev\0""oif\0""to\0"; 300 enum { 301 ARG_src, 302 ARG_via, 303 ARG_mtu, PARM_lock, 304 ARG_protocol, 305 USE_FEATURE_IP_RULE(ARG_table,) 306 ARG_dev, 307 ARG_oif, 308 ARG_to 309 }; 310 enum { 311 gw_ok = 1 << 0, 312 dst_ok = 1 << 1, 313 proto_ok = 1 << 2, 314 type_ok = 1 << 3 315 }; 287 316 struct rtnl_handle rth; 288 317 struct { … … 291 320 char buf[1024]; 292 321 } req; 293 char 322 char mxbuf[256]; 294 323 struct rtattr * mxrta = (void*)mxbuf; 295 324 unsigned mxlock = 0; 296 char *d = NULL; 297 int gw_ok = 0; 298 int dst_ok = 0; 299 int proto_ok = 0; 300 int type_ok = 0; 325 char *d = NULL; 326 smalluint ok = 0; 327 int arg; 301 328 302 329 memset(&req, 0, sizeof(req)); … … 319 346 320 347 while (argc > 0) { 321 if (strcmp(*argv, "src") == 0) { 348 arg = index_in_substrings(keywords, *argv); 349 if (arg == ARG_src) { 322 350 inet_prefix addr; 351 NEXT_ARG(); 352 get_addr(&addr, *argv, req.r.rtm_family); 353 if (req.r.rtm_family == AF_UNSPEC) 354 req.r.rtm_family = addr.family; 355 addattr_l(&req.n, sizeof(req), RTA_PREFSRC, &addr.data, addr.bytelen); 356 } else if (arg == ARG_via) { 357 inet_prefix addr; 358 ok |= gw_ok; 323 359 NEXT_ARG(); 324 360 get_addr(&addr, *argv, req.r.rtm_family); … … 326 362 req.r.rtm_family = addr.family; 327 363 } 328 addattr_l(&req.n, sizeof(req), RTA_PREFSRC, &addr.data, addr.bytelen);329 } else if (strcmp(*argv, "via") == 0) {330 inet_prefix addr;331 gw_ok = 1;332 NEXT_ARG();333 get_addr(&addr, *argv, req.r.rtm_family);334 if (req.r.rtm_family == AF_UNSPEC) {335 req.r.rtm_family = addr.family;336 }337 364 addattr_l(&req.n, sizeof(req), RTA_GATEWAY, &addr.data, addr.bytelen); 338 } else if ( strcmp(*argv, "mtu") == 0) {365 } else if (arg == ARG_mtu) { 339 366 unsigned mtu; 340 367 NEXT_ARG(); 341 if ( strcmp(*argv, "lock") == 0) {368 if (index_in_strings(keywords, *argv) == PARM_lock) { 342 369 mxlock |= (1<<RTAX_MTU); 343 370 NEXT_ARG(); 344 371 } 345 if (get_unsigned(&mtu, *argv, 0)) {372 if (get_unsigned(&mtu, *argv, 0)) 346 373 invarg(*argv, "mtu"); 347 }348 374 rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu); 349 } else if ( matches(*argv, "protocol") == 0) {375 } else if (arg == ARG_protocol) { 350 376 uint32_t prot; 351 377 NEXT_ARG(); … … 353 379 invarg(*argv, "protocol"); 354 380 req.r.rtm_protocol = prot; 355 proto_ok =1; 356 } else if (strcmp(*argv, "dev") == 0 || 357 strcmp(*argv, "oif") == 0) { 381 ok |= proto_ok; 382 #if ENABLE_FEATURE_IP_RULE 383 } else if (arg == ARG_table) { 384 uint32_t tid; 385 NEXT_ARG(); 386 if (rtnl_rttable_a2n(&tid, *argv)) 387 invarg(*argv, "table"); 388 req.r.rtm_table = tid; 389 #endif 390 } else if (arg == ARG_dev || arg == ARG_oif) { 358 391 NEXT_ARG(); 359 392 d = *argv; … … 362 395 inet_prefix dst; 363 396 364 if ( strcmp(*argv, "to") == 0) {365 NEXT_ARG(); 366 } 367 if ((**argv < '0' || **argv > '9') &&368 397 if (arg == ARG_to) { 398 NEXT_ARG(); 399 } 400 if ((**argv < '0' || **argv > '9') 401 && rtnl_rtntype_a2n(&type, *argv) == 0) { 369 402 NEXT_ARG(); 370 403 req.r.rtm_type = type; 371 type_ok = 1;372 } 373 374 if ( dst_ok) {404 ok |= type_ok; 405 } 406 407 if (ok & dst_ok) { 375 408 duparg2("to", *argv); 376 409 } … … 380 413 } 381 414 req.r.rtm_dst_len = dst.bitlen; 382 dst_ok = 1;415 ok |= dst_ok; 383 416 if (dst.bytelen) { 384 417 addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen); … … 388 421 } 389 422 390 if (rtnl_open(&rth, 0) < 0) { 391 exit(1); 392 } 423 xrtnl_open(&rth); 393 424 394 425 if (d) { … … 398 429 399 430 if (d) { 400 if ((idx = ll_name_to_index(d)) == 0) { 401 bb_error_msg("Cannot find device \"%s\"", d); 402 return -1; 403 } 431 idx = xll_name_to_index(d); 404 432 addattr32(&req.n, sizeof(req), RTA_OIF, idx); 405 433 } … … 413 441 } 414 442 443 if (req.r.rtm_type == RTN_LOCAL || req.r.rtm_type == RTN_NAT) 444 req.r.rtm_scope = RT_SCOPE_HOST; 445 else if (req.r.rtm_type == RTN_BROADCAST || 446 req.r.rtm_type == RTN_MULTICAST || 447 req.r.rtm_type == RTN_ANYCAST) 448 req.r.rtm_scope = RT_SCOPE_LINK; 449 else if (req.r.rtm_type == RTN_UNICAST || req.r.rtm_type == RTN_UNSPEC) { 450 if (cmd == RTM_DELROUTE) 451 req.r.rtm_scope = RT_SCOPE_NOWHERE; 452 else if (!(ok & gw_ok)) 453 req.r.rtm_scope = RT_SCOPE_LINK; 454 } 455 415 456 if (req.r.rtm_family == AF_UNSPEC) { 416 457 req.r.rtm_family = AF_INET; … … 418 459 419 460 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) { 420 exit(2);461 return 2; 421 462 } 422 463 … … 444 485 req.rtm.rtm_flags |= RTM_F_CLONED; 445 486 446 return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); 447 } 448 449 static int iproute_flush_cache(void) 450 { 451 #define ROUTE_FLUSH_PATH "/proc/sys/net/ipv4/route/flush" 452 453 int len; 454 int flush_fd = open (ROUTE_FLUSH_PATH, O_WRONLY); 455 char *buffer = "-1"; 487 return xsendto(rth->fd, (void*)&req, sizeof(req), (struct sockaddr*)&nladdr, sizeof(nladdr)); 488 } 489 490 static void iproute_flush_cache(void) 491 { 492 static const char fn[] ALIGN1 = "/proc/sys/net/ipv4/route/flush"; 493 int flush_fd = open_or_warn(fn, O_WRONLY); 456 494 457 495 if (flush_fd < 0) { 458 fprintf (stderr, "Cannot open \"%s\"\n", ROUTE_FLUSH_PATH); 459 return -1; 460 } 461 462 len = strlen (buffer); 463 464 if ((write (flush_fd, (void *)buffer, len)) < len) { 465 fprintf (stderr, "Cannot flush routing cache\n"); 466 return -1; 496 return; 497 } 498 499 if (write(flush_fd, "-1", 2) < 2) { 500 bb_perror_msg("cannot flush routing cache"); 501 return; 467 502 } 468 503 close(flush_fd); 469 return 0;470 504 } 471 505 … … 477 511 } 478 512 513 /* Return value becomes exitcode. It's okay to not return at all */ 479 514 static int iproute_list_or_flush(int argc, char **argv, int flush) 480 515 { … … 483 518 char *id = NULL; 484 519 char *od = NULL; 485 520 static const char keywords[] ALIGN1 = 521 "protocol\0""all\0""dev\0""oif\0""iif\0""via\0""table\0""cache\0" /*all*/ 522 "from\0""root\0""match\0""exact\0""to\0"/*root match exact*/; 523 enum { 524 ARG_proto, PARM_all, 525 ARG_dev, 526 ARG_oif, 527 ARG_iif, 528 ARG_via, 529 ARG_table, PARM_cache, /*PARM_all,*/ 530 ARG_from, PARM_root, PARM_match, PARM_exact, 531 ARG_to /*PARM_root, PARM_match, PARM_exact*/ 532 }; 533 int arg, parm; 486 534 iproute_reset_filter(); 487 535 filter.tb = RT_TABLE_MAIN; 488 536 489 if (flush && argc <= 0) { 490 bb_error_msg(bb_msg_requires_arg, "\"ip route flush\""); 491 return -1; 492 } 537 if (flush && argc <= 0) 538 bb_error_msg_and_die(bb_msg_requires_arg, "\"ip route flush\""); 493 539 494 540 while (argc > 0) { 495 if (matches(*argv, "protocol") == 0) { 541 arg = index_in_substrings(keywords, *argv); 542 if (arg == ARG_proto) { 496 543 uint32_t prot = 0; 497 544 NEXT_ARG(); 498 545 filter.protocolmask = -1; 499 546 if (rtnl_rtprot_a2n(&prot, *argv)) { 500 if ( strcmp(*argv, "all") != 0) {547 if (index_in_strings(keywords, *argv) != PARM_all) 501 548 invarg(*argv, "protocol"); 502 }503 549 prot = 0; 504 550 filter.protocolmask = 0; 505 551 } 506 552 filter.protocol = prot; 507 } else if (strcmp(*argv, "dev") == 0 || 508 strcmp(*argv, "oif") == 0) { 553 } else if (arg == ARG_dev || arg == ARG_oif) { 509 554 NEXT_ARG(); 510 555 od = *argv; 511 } else if ( strcmp(*argv, "iif") == 0) {556 } else if (arg == ARG_iif) { 512 557 NEXT_ARG(); 513 558 id = *argv; 514 } else if (matches(*argv, "from") == 0) { 515 NEXT_ARG(); 516 if (matches(*argv, "root") == 0) { 559 } else if (arg == ARG_via) { 560 NEXT_ARG(); 561 get_prefix(&filter.rvia, *argv, do_ipv6); 562 } else if (arg == ARG_table) { 563 NEXT_ARG(); 564 parm = index_in_substrings(keywords, *argv); 565 if (parm == PARM_cache) 566 filter.tb = -1; 567 else if (parm == PARM_all) 568 filter.tb = 0; 569 else 570 invarg(*argv, "table"); 571 } else if (arg == ARG_from) { 572 NEXT_ARG(); 573 parm = index_in_substrings(keywords, *argv); 574 if (parm == PARM_root) { 517 575 NEXT_ARG(); 518 576 get_prefix(&filter.rsrc, *argv, do_ipv6); 519 } else if ( matches(*argv, "match") == 0) {577 } else if (parm == PARM_match) { 520 578 NEXT_ARG(); 521 579 get_prefix(&filter.msrc, *argv, do_ipv6); 522 580 } else { 523 if ( matches(*argv, "exact") == 0) {581 if (parm == PARM_exact) 524 582 NEXT_ARG(); 525 }526 583 get_prefix(&filter.msrc, *argv, do_ipv6); 527 584 filter.rsrc = filter.msrc; 528 585 } 529 586 } else { 530 if (matches(*argv, "to") == 0) { 531 NEXT_ARG(); 532 } 533 if (matches(*argv, "root") == 0) { 587 /* parm = arg; // would be more plausible, we reuse arg here */ 588 if (arg == ARG_to) { 589 NEXT_ARG(); 590 arg = index_in_substrings(keywords, *argv); 591 } 592 if (arg == PARM_root) { 534 593 NEXT_ARG(); 535 594 get_prefix(&filter.rdst, *argv, do_ipv6); 536 } else if ( matches(*argv, "match") == 0) {595 } else if (arg == PARM_match) { 537 596 NEXT_ARG(); 538 597 get_prefix(&filter.mdst, *argv, do_ipv6); 539 } else if (matches(*argv, "table") == 0) {540 NEXT_ARG();541 if (matches(*argv, "cache") == 0) {542 filter.tb = -1;543 } else if (matches(*argv, "main") != 0) {544 invarg(*argv, "table");545 }546 } else if (matches(*argv, "cache") == 0) {547 filter.tb = -1;548 598 } else { 549 if ( matches(*argv, "exact") == 0) {599 if (arg == PARM_exact) 550 600 NEXT_ARG(); 551 }552 601 get_prefix(&filter.mdst, *argv, do_ipv6); 553 602 filter.rdst = filter.mdst; 554 603 } 555 604 } 556 argc--; argv++; 605 argc--; 606 argv++; 557 607 } 558 608 … … 561 611 } 562 612 563 if (rtnl_open(&rth, 0) < 0) { 564 exit(1); 565 } 613 xrtnl_open(&rth); 566 614 567 615 ll_init_map(&rth); … … 571 619 572 620 if (id) { 573 if ((idx = ll_name_to_index(id)) == 0) { 574 bb_error_msg("Cannot find device \"%s\"", id); 575 return -1; 576 } 621 idx = xll_name_to_index(id); 577 622 filter.iif = idx; 578 623 filter.iifmask = -1; 579 624 } 580 625 if (od) { 581 if ((idx = ll_name_to_index(od)) == 0) { 582 bb_error_msg("Cannot find device \"%s\"", od); 583 } 626 idx = xll_name_to_index(od); 584 627 filter.oif = idx; 585 628 filter.oifmask = -1; … … 603 646 604 647 for (;;) { 605 if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) { 606 perror("Cannot send dump request"); 607 return -1; 608 } 648 xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE); 609 649 filter.flushed = 0; 610 if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) { 611 bb_error_msg("Flush terminated\n"); 612 return -1; 613 } 614 if (filter.flushed == 0) { 615 fflush(stdout); 650 xrtnl_dump_filter(&rth, print_route, stdout); 651 if (filter.flushed == 0) 616 652 return 0; 617 } 618 if (flush_update() < 0) 619 exit(1); 653 if (flush_update()) 654 return 1; 620 655 } 621 656 } 622 657 623 658 if (filter.tb != -1) { 624 if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) { 625 bb_perror_msg_and_die("Cannot send dump request"); 626 } 627 } else { 628 if (rtnl_rtcache_request(&rth, do_ipv6) < 0) { 629 bb_perror_msg_and_die("Cannot send dump request"); 630 } 631 } 632 633 if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) { 634 bb_error_msg_and_die("Dump terminated"); 635 } 636 637 exit(0); 638 } 639 640 659 xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE); 660 } else if (rtnl_rtcache_request(&rth, do_ipv6) < 0) { 661 bb_perror_msg_and_die("cannot send dump request"); 662 } 663 xrtnl_dump_filter(&rth, print_route, stdout); 664 665 return 0; 666 } 667 668 669 /* Return value becomes exitcode. It's okay to not return at all */ 641 670 static int iproute_get(int argc, char **argv) 642 671 { 643 672 struct rtnl_handle rth; 644 673 struct { 645 struct nlmsghdr 646 struct rtmsg 647 char 674 struct nlmsghdr n; 675 struct rtmsg r; 676 char buf[1024]; 648 677 } req; 649 char 650 char 651 intconnected = 0;652 intfrom_ok = 0;653 static const char * const options[]=654 { "from", "iif", "oif", "dev", "notify", "connected", "to", 0 };678 char *idev = NULL; 679 char *odev = NULL; 680 bool connected = 0; 681 bool from_ok = 0; 682 static const char options[] ALIGN1 = 683 "from\0""iif\0""oif\0""dev\0""notify\0""connected\0""to\0"; 655 684 656 685 memset(&req, 0, sizeof(req)); … … 671 700 672 701 while (argc > 0) { 673 switch ( compare_string_array(options, *argv)) {702 switch (index_in_strings(options, *argv)) { 674 703 case 0: /* from */ 675 704 { … … 724 753 } 725 754 726 if (rtnl_open(&rth, 0) < 0) 727 exit(1); 755 xrtnl_open(&rth); 728 756 729 757 ll_init_map(&rth); … … 733 761 734 762 if (idev) { 735 if ((idx = ll_name_to_index(idev)) == 0) { 736 bb_error_msg("Cannot find device \"%s\"", idev); 737 return -1; 738 } 763 idx = xll_name_to_index(idev); 739 764 addattr32(&req.n, sizeof(req), RTA_IIF, idx); 740 765 } 741 766 if (odev) { 742 if ((idx = ll_name_to_index(odev)) == 0) { 743 bb_error_msg("Cannot find device \"%s\"", odev); 744 return -1; 745 } 767 idx = xll_name_to_index(odev); 746 768 addattr32(&req.n, sizeof(req), RTA_OIF, idx); 747 769 } … … 753 775 754 776 if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) { 755 exit(2);777 return 2; 756 778 } 757 779 … … 761 783 struct rtattr * tb[RTA_MAX+1]; 762 784 763 if (print_route(NULL, &req.n, (void*)stdout) < 0) { 764 bb_error_msg_and_die("An error :-)"); 765 } 785 print_route(NULL, &req.n, (void*)stdout); 766 786 767 787 if (req.n.nlmsg_type != RTM_NEWROUTE) { 768 bb_error_msg("Not a route?"); 769 return -1; 788 bb_error_msg_and_die("not a route?"); 770 789 } 771 790 len -= NLMSG_LENGTH(sizeof(*r)); 772 791 if (len < 0) { 773 bb_error_msg("Wrong len %d", len); 774 return -1; 792 bb_error_msg_and_die("wrong len %d", len); 775 793 } 776 794 … … 782 800 r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]); 783 801 } else if (!tb[RTA_SRC]) { 784 bb_error_msg("Failed to connect the route"); 785 return -1; 802 bb_error_msg_and_die("failed to connect the route"); 786 803 } 787 804 if (!odev && tb[RTA_OIF]) { … … 798 815 799 816 if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) { 800 exit(2); 801 } 802 } 803 804 if (print_route(NULL, &req.n, (void*)stdout) < 0) { 805 bb_error_msg_and_die("An error :-)"); 806 } 807 808 exit(0); 809 } 810 817 return 2; 818 } 819 } 820 print_route(NULL, &req.n, (void*)stdout); 821 return 0; 822 } 823 824 /* Return value becomes exitcode. It's okay to not return at all */ 811 825 int do_iproute(int argc, char **argv) 812 826 { 813 static const char * const ip_route_commands[] = 814 { "add", "append", "change", "chg", "delete", "del", "get", 815 "list", "show", "prepend", "replace", "test", "flush", 0 }; 816 int command_num = 7; 817 unsigned int flags = 0; 827 static const char ip_route_commands[] ALIGN1 = 828 /*0-3*/ "add\0""append\0""change\0""chg\0" 829 /*4-7*/ "delete\0""get\0""list\0""show\0" 830 /*8..*/ "prepend\0""replace\0""test\0""flush\0"; 831 int command_num = 6; 832 unsigned flags = 0; 818 833 int cmd = RTM_NEWROUTE; 819 834 835 /* "Standard" 'ip r a' treats 'a' as 'add', not 'append' */ 836 /* It probably means that it is using "first match" rule */ 820 837 if (*argv) { 821 command_num = compare_string_array(ip_route_commands, *argv);822 } 823 switch (command_num) {824 case 0: /* add */838 command_num = index_in_substrings(ip_route_commands, *argv); 839 } 840 switch (command_num) { 841 case 0: /* add */ 825 842 flags = NLM_F_CREATE|NLM_F_EXCL; 826 843 break; … … 833 850 break; 834 851 case 4: /* delete */ 835 case 5: /* del */836 852 cmd = RTM_DELROUTE; 837 853 break; 838 case 6: /* get */854 case 5: /* get */ 839 855 return iproute_get(argc-1, argv+1); 840 case 7: /* list */841 case 8: /* show */856 case 6: /* list */ 857 case 7: /* show */ 842 858 return iproute_list_or_flush(argc-1, argv+1, 0); 843 case 9: /* prepend */859 case 8: /* prepend */ 844 860 flags = NLM_F_CREATE; 845 case 10: /* replace */861 case 9: /* replace */ 846 862 flags = NLM_F_CREATE|NLM_F_REPLACE; 847 case 1 1: /* test */863 case 10: /* test */ 848 864 flags = NLM_F_EXCL; 849 case 1 2: /* flush */865 case 11: /* flush */ 850 866 return iproute_list_or_flush(argc-1, argv+1, 1); 851 867 default: 852 bb_error_msg_and_die(" Unknown command %s", *argv);868 bb_error_msg_and_die("unknown command %s", *argv); 853 869 } 854 870 -
branches/stable/mindi-busybox/networking/libiproute/iptunnel.c
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * iptunnel.c "ip tunnel" … … 14 15 */ 15 16 16 #include "libbb.h"17 #include <sys/socket.h>18 #include <sys/ioctl.h>19 20 #include <string.h>21 #include <unistd.h>22 23 17 #include <netinet/ip.h> 24 25 18 #include <net/if.h> 26 19 #include <net/if_arp.h> 27 28 20 #include <asm/types.h> 29 21 #ifndef __constant_htons … … 32 24 #include <linux/if_tunnel.h> 33 25 26 #include "ip_common.h" /* #include "libbb.h" is inside */ 34 27 #include "rt_names.h" 35 28 #include "utils.h" 36 #include "ip_common.h" 37 38 29 30 31 /* Dies on error */ 39 32 static int do_ioctl_get_ifindex(char *dev) 40 33 { … … 42 35 int fd; 43 36 44 strcpy(ifr.ifr_name, dev); 45 fd = socket(AF_INET, SOCK_DGRAM, 0); 46 if (ioctl(fd, SIOCGIFINDEX, &ifr)) { 47 bb_perror_msg("ioctl"); 48 return 0; 49 } 37 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 38 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 39 xioctl(fd, SIOCGIFINDEX, &ifr); 50 40 close(fd); 51 41 return ifr.ifr_ifindex; … … 53 43 54 44 static int do_ioctl_get_iftype(char *dev) 55 {56 struct ifreq ifr;57 int fd;58 59 strcpy(ifr.ifr_name, dev);60 fd = socket(AF_INET, SOCK_DGRAM, 0);61 if (ioctl(fd, SIOCGIFHWADDR, &ifr)) {62 bb_perror_msg("ioctl");63 return -1;64 }65 close(fd);66 return ifr.ifr_addr.sa_family;67 }68 69 70 static char *do_ioctl_get_ifname(int idx)71 {72 static struct ifreq ifr;73 int fd;74 75 ifr.ifr_ifindex = idx;76 fd = socket(AF_INET, SOCK_DGRAM, 0);77 if (ioctl(fd, SIOCGIFNAME, &ifr)) {78 bb_perror_msg("ioctl");79 return NULL;80 }81 close(fd);82 return ifr.ifr_name;83 }84 85 86 87 static int do_get_ioctl(char *basedev, struct ip_tunnel_parm *p)88 45 { 89 46 struct ifreq ifr; … … 91 48 int err; 92 49 93 strcpy(ifr.ifr_name, basedev); 94 ifr.ifr_ifru.ifru_data = (void*)p; 95 fd = socket(AF_INET, SOCK_DGRAM, 0); 96 err = ioctl(fd, SIOCGETTUNNEL, &ifr); 97 if (err) { 98 bb_perror_msg("ioctl"); 99 } 50 strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); 51 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 52 err = ioctl_or_warn(fd, SIOCGIFHWADDR, &ifr); 100 53 close(fd); 101 return err ;102 } 103 104 static int do_add_ioctl(int cmd, char *basedev, struct ip_tunnel_parm *p)54 return err ? -1 : ifr.ifr_addr.sa_family; 55 } 56 57 static char *do_ioctl_get_ifname(int idx) 105 58 { 106 59 struct ifreq ifr; … … 108 61 int err; 109 62 110 if (cmd == SIOCCHGTUNNEL && p->name[0]) { 111 strcpy(ifr.ifr_name, p->name); 112 } else { 113 strcpy(ifr.ifr_name, basedev); 114 } 115 ifr.ifr_ifru.ifru_data = (void*)p; 116 fd = socket(AF_INET, SOCK_DGRAM, 0); 117 err = ioctl(fd, cmd, &ifr); 118 if (err) { 119 bb_perror_msg("ioctl"); 120 } 63 ifr.ifr_ifindex = idx; 64 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 65 err = ioctl_or_warn(fd, SIOCGIFNAME, &ifr); 121 66 close(fd); 122 return err ;123 } 124 125 static int do_ del_ioctl(char *basedev, struct ip_tunnel_parm *p)67 return err ? NULL : xstrndup(ifr.ifr_name, sizeof(ifr.ifr_name)); 68 } 69 70 static int do_get_ioctl(const char *basedev, struct ip_tunnel_parm *p) 126 71 { 127 72 struct ifreq ifr; … … 129 74 int err; 130 75 131 if (p->name[0]) { 132 strcpy(ifr.ifr_name, p->name); 133 } else { 134 strcpy(ifr.ifr_name, basedev); 135 } 76 strncpy(ifr.ifr_name, basedev, sizeof(ifr.ifr_name)); 136 77 ifr.ifr_ifru.ifru_data = (void*)p; 137 fd = socket(AF_INET, SOCK_DGRAM, 0); 138 err = ioctl(fd, SIOCDELTUNNEL, &ifr); 139 if (err) { 140 bb_perror_msg("ioctl"); 141 } 78 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 79 err = ioctl_or_warn(fd, SIOCGETTUNNEL, &ifr); 142 80 close(fd); 143 81 return err; 144 82 } 145 83 146 static int parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) 147 { 84 /* Dies on error, otherwise returns 0 */ 85 static int do_add_ioctl(int cmd, const char *basedev, struct ip_tunnel_parm *p) 86 { 87 struct ifreq ifr; 88 int fd; 89 90 if (cmd == SIOCCHGTUNNEL && p->name[0]) { 91 strncpy(ifr.ifr_name, p->name, sizeof(ifr.ifr_name)); 92 } else { 93 strncpy(ifr.ifr_name, basedev, sizeof(ifr.ifr_name)); 94 } 95 ifr.ifr_ifru.ifru_data = (void*)p; 96 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 97 #if ENABLE_IOCTL_HEX2STR_ERROR 98 /* #define magic will turn ioctl# into string */ 99 if (cmd == SIOCCHGTUNNEL) 100 xioctl(fd, SIOCCHGTUNNEL, &ifr); 101 else 102 xioctl(fd, SIOCADDTUNNEL, &ifr); 103 #else 104 xioctl(fd, cmd, &ifr); 105 #endif 106 close(fd); 107 return 0; 108 } 109 110 /* Dies on error, otherwise returns 0 */ 111 static int do_del_ioctl(const char *basedev, struct ip_tunnel_parm *p) 112 { 113 struct ifreq ifr; 114 int fd; 115 116 if (p->name[0]) { 117 strncpy(ifr.ifr_name, p->name, sizeof(ifr.ifr_name)); 118 } else { 119 strncpy(ifr.ifr_name, basedev, sizeof(ifr.ifr_name)); 120 } 121 ifr.ifr_ifru.ifru_data = (void*)p; 122 fd = xsocket(AF_INET, SOCK_DGRAM, 0); 123 xioctl(fd, SIOCDELTUNNEL, &ifr); 124 close(fd); 125 return 0; 126 } 127 128 /* Dies on error */ 129 static void parse_args(int argc, char **argv, int cmd, struct ip_tunnel_parm *p) 130 { 131 static const char keywords[] ALIGN1 = 132 "mode\0""ipip\0""ip/ip\0""gre\0""gre/ip\0""sit\0""ipv6/ip\0" 133 "key\0""ikey\0""okey\0""seq\0""iseq\0""oseq\0" 134 "csum\0""icsum\0""ocsum\0""nopmtudisc\0""pmtudisc\0" 135 "remote\0""any\0""local\0""dev\0" 136 "ttl\0""inherit\0""tos\0""dsfield\0" 137 "name\0"; 138 enum { 139 ARG_mode, ARG_ipip, ARG_ip_ip, ARG_gre, ARG_gre_ip, ARG_sit, ARG_ip6_ip, 140 ARG_key, ARG_ikey, ARG_okey, ARG_seq, ARG_iseq, ARG_oseq, 141 ARG_csum, ARG_icsum, ARG_ocsum, ARG_nopmtudisc, ARG_pmtudisc, 142 ARG_remote, ARG_any, ARG_local, ARG_dev, 143 ARG_ttl, ARG_inherit, ARG_tos, ARG_dsfield, 144 ARG_name 145 }; 148 146 int count = 0; 149 147 char medium[IFNAMSIZ]; 148 int key; 149 150 150 memset(p, 0, sizeof(*p)); 151 151 memset(&medium, 0, sizeof(medium)); … … 154 154 p->iph.ihl = 5; 155 155 #ifndef IP_DF 156 #define IP_DF 0x4000 /* Flag: "Don't Fragment"*/156 #define IP_DF 0x4000 /* Flag: "Don't Fragment" */ 157 157 #endif 158 158 p->iph.frag_off = htons(IP_DF); 159 159 160 160 while (argc > 0) { 161 if (strcmp(*argv, "mode") == 0) { 162 NEXT_ARG(); 163 if (strcmp(*argv, "ipip") == 0 || 164 strcmp(*argv, "ip/ip") == 0) { 161 key = index_in_strings(keywords, *argv); 162 if (key == ARG_mode) { 163 NEXT_ARG(); 164 key = index_in_strings(keywords, *argv); 165 if (key == ARG_ipip || 166 key == ARG_ip_ip) { 165 167 if (p->iph.protocol && p->iph.protocol != IPPROTO_IPIP) { 166 bb_error_msg("You managed to ask for more than one tunnel mode."); 167 exit(-1); 168 bb_error_msg_and_die("you managed to ask for more than one tunnel mode"); 168 169 } 169 170 p->iph.protocol = IPPROTO_IPIP; 170 } else if ( strcmp(*argv, "gre") == 0||171 strcmp(*argv, "gre/ip") == 0) {171 } else if (key == ARG_gre || 172 key == ARG_gre_ip) { 172 173 if (p->iph.protocol && p->iph.protocol != IPPROTO_GRE) { 173 bb_error_msg("You managed to ask for more than one tunnel mode."); 174 exit(-1); 174 bb_error_msg_and_die("you managed to ask for more than one tunnel mode"); 175 175 } 176 176 p->iph.protocol = IPPROTO_GRE; 177 } else if ( strcmp(*argv, "sit") == 0||178 strcmp(*argv, "ipv6/ip") == 0) {177 } else if (key == ARG_sit || 178 key == ARG_ip6_ip) { 179 179 if (p->iph.protocol && p->iph.protocol != IPPROTO_IPV6) { 180 bb_error_msg("You managed to ask for more than one tunnel mode."); 181 exit(-1); 180 bb_error_msg_and_die("you managed to ask for more than one tunnel mode"); 182 181 } 183 182 p->iph.protocol = IPPROTO_IPV6; 184 183 } else { 185 bb_error_msg("Cannot guess tunnel mode."); 186 exit(-1); 187 } 188 } else if (strcmp(*argv, "key") == 0) { 184 bb_error_msg_and_die("cannot guess tunnel mode"); 185 } 186 } else if (key == ARG_key) { 189 187 unsigned uval; 190 188 NEXT_ARG(); … … 195 193 else { 196 194 if (get_unsigned(&uval, *argv, 0)<0) { 197 bb_error_msg("invalid value of \"key\""); 198 exit(-1); 195 bb_error_msg_and_die("invalid value of \"key\""); 199 196 } 200 197 p->i_key = p->o_key = htonl(uval); 201 198 } 202 } else if ( strcmp(*argv, "ikey") == 0) {199 } else if (key == ARG_ikey) { 203 200 unsigned uval; 204 201 NEXT_ARG(); … … 208 205 else { 209 206 if (get_unsigned(&uval, *argv, 0)<0) { 210 bb_error_msg("invalid value of \"ikey\""); 211 exit(-1); 207 bb_error_msg_and_die("invalid value of \"ikey\""); 212 208 } 213 209 p->i_key = htonl(uval); 214 210 } 215 } else if ( strcmp(*argv, "okey") == 0) {211 } else if (key == ARG_okey) { 216 212 unsigned uval; 217 213 NEXT_ARG(); … … 221 217 else { 222 218 if (get_unsigned(&uval, *argv, 0)<0) { 223 bb_error_msg("invalid value of \"okey\""); 224 exit(-1); 219 bb_error_msg_and_die("invalid value of \"okey\""); 225 220 } 226 221 p->o_key = htonl(uval); 227 222 } 228 } else if ( strcmp(*argv, "seq") == 0) {223 } else if (key == ARG_seq) { 229 224 p->i_flags |= GRE_SEQ; 230 225 p->o_flags |= GRE_SEQ; 231 } else if ( strcmp(*argv, "iseq") == 0) {226 } else if (key == ARG_iseq) { 232 227 p->i_flags |= GRE_SEQ; 233 } else if ( strcmp(*argv, "oseq") == 0) {228 } else if (key == ARG_oseq) { 234 229 p->o_flags |= GRE_SEQ; 235 } else if ( strcmp(*argv, "csum") == 0) {230 } else if (key == ARG_csum) { 236 231 p->i_flags |= GRE_CSUM; 237 232 p->o_flags |= GRE_CSUM; 238 } else if ( strcmp(*argv, "icsum") == 0) {233 } else if (key == ARG_icsum) { 239 234 p->i_flags |= GRE_CSUM; 240 } else if ( strcmp(*argv, "ocsum") == 0) {235 } else if (key == ARG_ocsum) { 241 236 p->o_flags |= GRE_CSUM; 242 } else if ( strcmp(*argv, "nopmtudisc") == 0) {237 } else if (key == ARG_nopmtudisc) { 243 238 p->iph.frag_off = 0; 244 } else if ( strcmp(*argv, "pmtudisc") == 0) {239 } else if (key == ARG_pmtudisc) { 245 240 p->iph.frag_off = htons(IP_DF); 246 } else if (strcmp(*argv, "remote") == 0) { 247 NEXT_ARG(); 248 if (strcmp(*argv, "any")) 241 } else if (key == ARG_remote) { 242 NEXT_ARG(); 243 key = index_in_strings(keywords, *argv); 244 if (key == ARG_any) 249 245 p->iph.daddr = get_addr32(*argv); 250 } else if (strcmp(*argv, "local") == 0) { 251 NEXT_ARG(); 252 if (strcmp(*argv, "any")) 246 } else if (key == ARG_local) { 247 NEXT_ARG(); 248 key = index_in_strings(keywords, *argv); 249 if (key == ARG_any) 253 250 p->iph.saddr = get_addr32(*argv); 254 } else if ( strcmp(*argv, "dev") == 0) {251 } else if (key == ARG_dev) { 255 252 NEXT_ARG(); 256 253 strncpy(medium, *argv, IFNAMSIZ-1); 257 } else if ( strcmp(*argv, "ttl") == 0) {254 } else if (key == ARG_ttl) { 258 255 unsigned uval; 259 256 NEXT_ARG(); 260 if (strcmp(*argv, "inherit") != 0) { 257 key = index_in_strings(keywords, *argv); 258 if (key != ARG_inherit) { 261 259 if (get_unsigned(&uval, *argv, 0)) 262 260 invarg(*argv, "TTL"); … … 265 263 p->iph.ttl = uval; 266 264 } 267 } else if (strcmp(*argv, "tos") == 0 || 268 matches(*argv, "dsfield") == 0) { 269 __u32 uval; 270 NEXT_ARG(); 271 if (strcmp(*argv, "inherit") != 0) { 265 } else if (key == ARG_tos || 266 key == ARG_dsfield) { 267 uint32_t uval; 268 NEXT_ARG(); 269 key = index_in_strings(keywords, *argv); 270 if (key != ARG_inherit) { 272 271 if (rtnl_dsfield_a2n(&uval, *argv)) 273 272 invarg(*argv, "TOS"); … … 276 275 p->iph.tos = 1; 277 276 } else { 278 if ( strcmp(*argv, "name") == 0) {277 if (key == ARG_name) { 279 278 NEXT_ARG(); 280 279 } … … 286 285 memset(&old_p, 0, sizeof(old_p)); 287 286 if (do_get_ioctl(*argv, &old_p)) 288 return -1;287 exit(1); 289 288 *p = old_p; 290 289 } 291 290 } 292 291 count++; 293 argc--; argv++;294 }295 292 argc--; 293 argv++; 294 } 296 295 297 296 if (p->iph.protocol == 0) { … … 306 305 if (p->iph.protocol == IPPROTO_IPIP || p->iph.protocol == IPPROTO_IPV6) { 307 306 if ((p->i_flags & GRE_KEY) || (p->o_flags & GRE_KEY)) { 308 bb_error_msg("Keys are not allowed with ipip and sit."); 309 return -1; 307 bb_error_msg_and_die("keys are not allowed with ipip and sit"); 310 308 } 311 309 } … … 313 311 if (medium[0]) { 314 312 p->link = do_ioctl_get_ifindex(medium); 315 if (p->link == 0)316 return -1;317 313 } 318 314 … … 326 322 } 327 323 if (IN_MULTICAST(ntohl(p->iph.daddr)) && !p->iph.saddr) { 328 bb_error_msg("Broadcast tunnel requires a source address."); 329 return -1; 330 } 331 return 0; 332 } 333 334 324 bb_error_msg_and_die("broadcast tunnel requires a source address"); 325 } 326 } 327 328 329 /* Return value becomes exitcode. It's okay to not return at all */ 335 330 static int do_add(int cmd, int argc, char **argv) 336 331 { 337 332 struct ip_tunnel_parm p; 338 333 339 if (parse_args(argc, argv, cmd, &p) < 0) 340 return -1; 334 parse_args(argc, argv, cmd, &p); 341 335 342 336 if (p.iph.ttl && p.iph.frag_off == 0) { 343 bb_error_msg("ttl != 0 and noptmudisc are incompatible"); 344 return -1; 337 bb_error_msg_and_die("ttl != 0 and noptmudisc are incompatible"); 345 338 } 346 339 … … 353 346 return do_add_ioctl(cmd, "sit0", &p); 354 347 default: 355 bb_error_msg("cannot determine tunnel mode (ipip, gre or sit)"); 356 return -1; 357 } 358 return -1; 359 } 360 348 bb_error_msg_and_die("cannot determine tunnel mode (ipip, gre or sit)"); 349 } 350 } 351 352 /* Return value becomes exitcode. It's okay to not return at all */ 361 353 static int do_del(int argc, char **argv) 362 354 { 363 355 struct ip_tunnel_parm p; 364 356 365 if (parse_args(argc, argv, SIOCDELTUNNEL, &p) < 0) 366 return -1; 357 parse_args(argc, argv, SIOCDELTUNNEL, &p); 367 358 368 359 switch (p.iph.protocol) { … … 376 367 return do_del_ioctl(p.name, &p); 377 368 } 378 return -1;379 369 } 380 370 … … 399 389 if (p->link) { 400 390 char *n = do_ioctl_get_ifname(p->link); 401 if (n) 391 if (n) { 402 392 printf(" dev %s ", n); 393 free(n); 394 } 403 395 } 404 396 if (p->iph.ttl) … … 409 401 SPRINT_BUF(b1); 410 402 printf(" tos"); 411 if (p->iph.tos &1)403 if (p->iph.tos & 1) 412 404 printf(" inherit"); 413 if (p->iph.tos &~1)414 printf("%c%s ", p->iph.tos &1 ? '/' : ' ',415 rtnl_dsfield_n2a(p->iph.tos &~1, b1, sizeof(b1)));416 } 417 if (!(p->iph.frag_off &htons(IP_DF)))405 if (p->iph.tos & ~1) 406 printf("%c%s ", p->iph.tos & 1 ? '/' : ' ', 407 rtnl_dsfield_n2a(p->iph.tos & ~1, b1, sizeof(b1))); 408 } 409 if (!(p->iph.frag_off & htons(IP_DF))) 418 410 printf(" nopmtudisc"); 419 411 420 if ((p->i_flags &GRE_KEY) && (p->o_flags&GRE_KEY) && p->o_key == p->i_key)412 if ((p->i_flags & GRE_KEY) && (p->o_flags & GRE_KEY) && p->o_key == p->i_key) 421 413 printf(" key %s", s3); 422 else if ((p->i_flags |p->o_flags)&GRE_KEY) {423 if (p->i_flags &GRE_KEY)414 else if ((p->i_flags | p->o_flags) & GRE_KEY) { 415 if (p->i_flags & GRE_KEY) 424 416 printf(" ikey %s ", s3); 425 if (p->o_flags &GRE_KEY)417 if (p->o_flags & GRE_KEY) 426 418 printf(" okey %s ", s4); 427 419 } 428 420 429 if (p->i_flags &GRE_SEQ)430 printf("% sDrop packets out of sequence.\n", _SL_);431 if (p->i_flags &GRE_CSUM)432 printf("% sChecksum in received packet is required.", _SL_);433 if (p->o_flags &GRE_SEQ)434 printf("% sSequence packets on output.", _SL_);435 if (p->o_flags &GRE_CSUM)436 printf("% sChecksum output packets.", _SL_);437 } 438 439 static intdo_tunnels_list(struct ip_tunnel_parm *p)421 if (p->i_flags & GRE_SEQ) 422 printf("%c Drop packets out of sequence.\n", _SL_); 423 if (p->i_flags & GRE_CSUM) 424 printf("%c Checksum in received packet is required.", _SL_); 425 if (p->o_flags & GRE_SEQ) 426 printf("%c Sequence packets on output.", _SL_); 427 if (p->o_flags & GRE_CSUM) 428 printf("%c Checksum output packets.", _SL_); 429 } 430 431 static void do_tunnels_list(struct ip_tunnel_parm *p) 440 432 { 441 433 char name[IFNAMSIZ]; 442 unsigned long 443 rx_fifo, rx_frame,444 tx_bytes, tx_packets, tx_errs, tx_drops,445 tx_fifo, tx_colls, tx_carrier, rx_multi;434 unsigned long rx_bytes, rx_packets, rx_errs, rx_drops, 435 rx_fifo, rx_frame, 436 tx_bytes, tx_packets, tx_errs, tx_drops, 437 tx_fifo, tx_colls, tx_carrier, rx_multi; 446 438 int type; 447 439 struct ip_tunnel_parm p1; 448 449 440 char buf[512]; 450 FILE *fp = fopen("/proc/net/dev", "r"); 441 FILE *fp = fopen_or_warn("/proc/net/dev", "r"); 442 451 443 if (fp == NULL) { 452 perror("fopen"); 453 return -1; 444 return; 454 445 } 455 446 … … 459 450 while (fgets(buf, sizeof(buf), fp) != NULL) { 460 451 char *ptr; 461 buf[sizeof(buf) - 1] = 0; 462 if ((ptr = strchr(buf, ':')) == NULL || 452 453 /*buf[sizeof(buf) - 1] = 0; - fgets is safe anyway */ 454 ptr = strchr(buf, ':'); 455 if (ptr == NULL || 463 456 (*ptr++ = 0, sscanf(buf, "%s", name) != 1)) { 464 bb_error_msg(" Wrong format of /proc/net/dev. Sorry.");465 return -1;457 bb_error_msg("wrong format of /proc/net/dev"); 458 return; 466 459 } 467 460 if (sscanf(ptr, "%lu%lu%lu%lu%lu%lu%lu%*d%lu%lu%lu%lu%lu%lu%lu", … … 475 468 type = do_ioctl_get_iftype(name); 476 469 if (type == -1) { 477 bb_error_msg(" Failed toget type of [%s]", name);470 bb_error_msg("cannot get type of [%s]", name); 478 471 continue; 479 472 } … … 490 483 continue; 491 484 print_tunnel(&p1); 492 p rintf("\n");493 } 494 return 0; 495 } 496 485 puts(""); 486 } 487 } 488 489 /* Return value becomes exitcode. It's okay to not return at all */ 497 490 static int do_show(int argc, char **argv) 498 491 { … … 500 493 struct ip_tunnel_parm p; 501 494 502 if (parse_args(argc, argv, SIOCGETTUNNEL, &p) < 0) 503 return -1; 495 parse_args(argc, argv, SIOCGETTUNNEL, &p); 504 496 505 497 switch (p.iph.protocol) { … … 521 513 522 514 print_tunnel(&p); 523 p rintf("\n");515 puts(""); 524 516 return 0; 525 517 } 526 518 519 /* Return value becomes exitcode. It's okay to not return at all */ 527 520 int do_iptunnel(int argc, char **argv) 528 521 { 529 if (argc > 0) { 530 if (matches(*argv, "add") == 0) 531 return do_add(SIOCADDTUNNEL, argc-1, argv+1); 532 if (matches(*argv, "change") == 0) 533 return do_add(SIOCCHGTUNNEL, argc-1, argv+1); 534 if (matches(*argv, "del") == 0) 535 return do_del(argc-1, argv+1); 536 if (matches(*argv, "show") == 0 || 537 matches(*argv, "lst") == 0 || 538 matches(*argv, "list") == 0) 539 return do_show(argc-1, argv+1); 540 } else 541 return do_show(0, NULL); 542 543 bb_error_msg("Command \"%s\" is unknown.", *argv); 544 exit(-1); 545 } 522 static const char keywords[] ALIGN1 = 523 "add\0""change\0""delete\0""show\0""list\0""lst\0"; 524 enum { ARG_add = 0, ARG_change, ARG_del, ARG_show, ARG_list, ARG_lst }; 525 int key; 526 527 if (argc) { 528 key = index_in_substrings(keywords, *argv); 529 if (key < 0) 530 bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); 531 --argc; 532 ++argv; 533 if (key == ARG_add) 534 return do_add(SIOCADDTUNNEL, argc, argv); 535 if (key == ARG_change) 536 return do_add(SIOCCHGTUNNEL, argc, argv); 537 if (key == ARG_del) 538 return do_del(argc, argv); 539 } 540 return do_show(argc, argv); 541 } -
branches/stable/mindi-busybox/networking/libiproute/libnetlink.c
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * libnetlink.c RTnetlink service routines. … … 11 12 */ 12 13 14 #include <sys/socket.h> 15 #include <sys/uio.h> 16 13 17 #include "libbb.h" 14 #include <sys/socket.h>15 16 #include <errno.h>17 #include <string.h>18 #include <time.h>19 #include <unistd.h>20 21 #include <sys/uio.h>22 23 18 #include "libnetlink.h" 24 19 … … 28 23 } 29 24 30 int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions)25 int xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/) 31 26 { 32 27 socklen_t addr_len; … … 34 29 memset(rth, 0, sizeof(rth)); 35 30 36 rth->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 37 if (rth->fd < 0) { 38 bb_perror_msg("Cannot open netlink socket"); 39 return -1; 40 } 31 rth->fd = xsocket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); 41 32 42 33 memset(&rth->local, 0, sizeof(rth->local)); 43 34 rth->local.nl_family = AF_NETLINK; 44 rth->local.nl_groups = subscriptions; 45 46 if (bind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)) < 0) { 47 bb_perror_msg("Cannot bind netlink socket"); 48 return -1; 49 } 35 /*rth->local.nl_groups = subscriptions;*/ 36 37 xbind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)); 50 38 addr_len = sizeof(rth->local); 51 if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) { 52 bb_perror_msg("Cannot getsockname"); 53 return -1; 54 } 55 if (addr_len != sizeof(rth->local)) { 56 bb_error_msg("Wrong address length %d", addr_len); 57 return -1; 58 } 59 if (rth->local.nl_family != AF_NETLINK) { 60 bb_error_msg("Wrong address family %d", rth->local.nl_family); 61 return -1; 62 } 39 if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) 40 bb_perror_msg_and_die("cannot getsockname"); 41 if (addr_len != sizeof(rth->local)) 42 bb_error_msg_and_die("wrong address length %d", addr_len); 43 if (rth->local.nl_family != AF_NETLINK) 44 bb_error_msg_and_die("wrong address family %d", rth->local.nl_family); 63 45 rth->seq = time(NULL); 64 46 return 0; 65 47 } 66 48 67 int rtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)49 int xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) 68 50 { 69 51 struct { … … 83 65 req.g.rtgen_family = family; 84 66 85 return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); 67 return xsendto(rth->fd, (void*)&req, sizeof(req), 68 (struct sockaddr*)&nladdr, sizeof(nladdr)); 86 69 } 87 70 … … 93 76 nladdr.nl_family = AF_NETLINK; 94 77 95 return sendto(rth->fd, buf, len, 0, (struct sockaddr*)&nladdr, sizeof(nladdr));78 return xsendto(rth->fd, buf, len, (struct sockaddr*)&nladdr, sizeof(nladdr)); 96 79 } 97 80 … … 120 103 } 121 104 122 int rtnl_dump_filter(struct rtnl_handle *rth,123 124 void *arg1,125 int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *),126 void *arg2)127 { 128 char 105 static int rtnl_dump_filter(struct rtnl_handle *rth, 106 int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *), 107 void *arg1/*, 108 int (*junk)(struct sockaddr_nl *, struct nlmsghdr *n, void *), 109 void *arg2*/) 110 { 111 char buf[8192]; 129 112 struct sockaddr_nl nladdr; 130 113 struct iovec iov = { buf, sizeof(buf) }; … … 164 147 h->nlmsg_pid != rth->local.nl_pid || 165 148 h->nlmsg_seq != rth->dump) { 166 if (junk) {149 /* if (junk) { 167 150 err = junk(&nladdr, h, arg2); 168 if (err < 0) {151 if (err < 0) 169 152 return err; 170 } 171 } 153 } */ 172 154 goto skip_it; 173 155 } … … 187 169 } 188 170 err = filter(&nladdr, h, arg1); 189 if (err < 0) {171 if (err < 0) 190 172 return err; 191 }192 173 193 174 skip_it: … … 195 176 } 196 177 if (msg.msg_flags & MSG_TRUNC) { 197 bb_error_msg(" Message truncated");178 bb_error_msg("message truncated"); 198 179 continue; 199 180 } 200 181 if (status) { 201 bb_error_msg_and_die("!!!Remnant of size %d", status); 202 } 203 } 182 bb_error_msg_and_die("remnant of size %d!", status); 183 } 184 } 185 } 186 187 int xrtnl_dump_filter(struct rtnl_handle *rth, 188 int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *), 189 void *arg1) 190 { 191 int ret = rtnl_dump_filter(rth, filter, arg1/*, NULL, NULL*/); 192 if (ret < 0) 193 bb_error_msg_and_die("dump terminated"); 194 return ret; 204 195 } 205 196 … … 234 225 235 226 if (status < 0) { 236 bb_perror_msg(" Cannot talk to rtnetlink");227 bb_perror_msg("cannot talk to rtnetlink"); 237 228 return -1; 238 229 } … … 265 256 if (l<0 || len>status) { 266 257 if (msg.msg_flags & MSG_TRUNC) { 267 bb_error_msg(" Truncated message");258 bb_error_msg("truncated message"); 268 259 return -1; 269 260 } 270 bb_error_msg_and_die(" !!!malformed message: len=%d", len);261 bb_error_msg_and_die("malformed message: len=%d!", len); 271 262 } 272 263 … … 304 295 } 305 296 306 bb_error_msg(" Unexpected reply!!!");297 bb_error_msg("unexpected reply!"); 307 298 308 299 status -= NLMSG_ALIGN(len); … … 310 301 } 311 302 if (msg.msg_flags & MSG_TRUNC) { 312 bb_error_msg(" Message truncated");303 bb_error_msg("message truncated"); 313 304 continue; 314 305 } 315 306 if (status) { 316 bb_error_msg_and_die(" !!!Remnant of size %d", status);317 } 318 } 319 } 320 321 int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32data)307 bb_error_msg_and_die("remnant of size %d!", status); 308 } 309 } 310 } 311 312 int addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data) 322 313 { 323 314 int len = RTA_LENGTH(4); … … 348 339 } 349 340 350 int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32data)341 int rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data) 351 342 { 352 343 int len = RTA_LENGTH(4); … … 390 381 } 391 382 if (len) { 392 bb_error_msg(" !!!Deficit %d, rta_len=%d", len, rta->rta_len);393 } 394 return 0; 395 } 383 bb_error_msg("deficit %d, rta_len=%d!", len, rta->rta_len); 384 } 385 return 0; 386 } -
branches/stable/mindi-busybox/networking/libiproute/libnetlink.h
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 #ifndef __LIBNETLINK_H__ 2 3 #define __LIBNETLINK_H__ 1 3 4 4 #include <asm/types.h> 5 #include <linux/types.h> 6 /* We need linux/types.h because older kernels use __u32 etc 7 * in linux/[rt]netlink.h. 2.6.19 seems to be ok, though */ 5 8 #include <linux/netlink.h> 6 9 #include <linux/rtnetlink.h> … … 11 14 struct sockaddr_nl local; 12 15 struct sockaddr_nl peer; 13 __u32seq;14 __u32dump;16 uint32_t seq; 17 uint32_t dump; 15 18 }; 16 19 17 extern int rtnl_open(struct rtnl_handle *rth, unsigned subscriptions);20 extern int xrtnl_open(struct rtnl_handle *rth); 18 21 extern void rtnl_close(struct rtnl_handle *rth); 19 extern int rtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type);22 extern int xrtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type); 20 23 extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len); 21 extern int rtnl_dump_filter(struct rtnl_handle *rth, 22 int (*filter)(struct sockaddr_nl *, struct nlmsghdr *n, void *), 23 void *arg1, 24 int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *), 25 void *arg2); 24 extern int xrtnl_dump_filter(struct rtnl_handle *rth, 25 int (*filter)(struct sockaddr_nl*, struct nlmsghdr *n, void*), 26 void *arg1); 26 27 extern int rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, pid_t peer, 27 28 29 28 unsigned groups, struct nlmsghdr *answer, 29 int (*junk)(struct sockaddr_nl *,struct nlmsghdr *n, void *), 30 void *jarg); 30 31 extern int rtnl_send(struct rtnl_handle *rth, char *buf, int); 31 32 32 33 33 extern int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32data);34 extern int addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data); 34 35 extern int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int alen); 35 extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, __u32data);36 extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data); 36 37 extern int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen); 37 38 38 39 extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len); 39 40 40 41 41 #endif /* __LIBNETLINK_H__ */ 42 -
branches/stable/mindi-busybox/networking/libiproute/ll_addr.c
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * ll_addr.c … … 10 11 */ 11 12 12 #include "libbb.h"13 14 #include <string.h>15 13 #include <net/if_arp.h> 16 14 15 #include "libbb.h" 17 16 #include "rt_names.h" 18 17 #include "utils.h" … … 31 30 for (i=0; i<alen; i++) { 32 31 if (i==0) { 33 snprintf(buf+l, blen, " %02x", addr[i]);32 snprintf(buf+l, blen, ":%02x"+1, addr[i]); 34 33 blen -= 2; 35 34 l += 2; … … 48 47 inet_prefix pfx; 49 48 if (get_addr_1(&pfx, arg, AF_INET)) { 50 bb_error_msg("\"%s\" is invalid lladdr .", arg);49 bb_error_msg("\"%s\" is invalid lladdr", arg); 51 50 return -1; 52 51 } … … 67 66 } 68 67 if (sscanf(arg, "%x", &temp) != 1) { 69 bb_error_msg("\"%s\" is invalid lladdr .", arg);68 bb_error_msg("\"%s\" is invalid lladdr", arg); 70 69 return -1; 71 70 } 72 71 if (temp < 0 || temp > 255) { 73 bb_error_msg("\"%s\" is invalid lladdr .", arg);72 bb_error_msg("\"%s\" is invalid lladdr", arg); 74 73 return -1; 75 74 } -
branches/stable/mindi-busybox/networking/libiproute/ll_map.c
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * ll_map.c … … 11 12 */ 12 13 14 #include <net/if.h> /* struct ifreq and co. */ 15 13 16 #include "libbb.h" 14 #include <string.h>15 16 17 #include "libnetlink.h" 17 18 #include "ll_map.h" 18 19 19 struct idxmap 20 { 21 struct idxmap * next; 22 int index; 23 int type; 24 int alen; 25 unsigned flags; 26 unsigned char addr[8]; 27 char name[16]; 20 struct idxmap { 21 struct idxmap *next; 22 int index; 23 int type; 24 int alen; 25 unsigned flags; 26 unsigned char addr[8]; 27 char name[16]; 28 28 }; 29 29 30 30 static struct idxmap *idxmap[16]; 31 32 static struct idxmap *find_by_index(int idx) 33 { 34 struct idxmap *im; 35 36 for (im = idxmap[idx & 0xF]; im; im = im->next) 37 if (im->index == idx) 38 return im; 39 return NULL; 40 } 31 41 32 42 int ll_remember_index(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) … … 43 53 return -1; 44 54 45 46 55 memset(tb, 0, sizeof(tb)); 47 56 parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), IFLA_PAYLOAD(n)); … … 49 58 return 0; 50 59 51 h = ifi->ifi_index &0xF;60 h = ifi->ifi_index & 0xF; 52 61 53 for (imp =&idxmap[h]; (im=*imp)!=NULL; imp = &im->next)62 for (imp = &idxmap[h]; (im = *imp) != NULL; imp = &im->next) 54 63 if (im->index == ifi->ifi_index) 55 break;64 goto found; 56 65 57 if (im == NULL) { 58 im = xmalloc(sizeof(*im)); 59 im->next = *imp; 60 im->index = ifi->ifi_index; 61 *imp = im; 62 } 63 66 im = xmalloc(sizeof(*im)); 67 im->next = *imp; 68 im->index = ifi->ifi_index; 69 *imp = im; 70 found: 64 71 im->type = ifi->ifi_type; 65 72 im->flags = ifi->ifi_flags; … … 84 91 if (idx == 0) 85 92 return "*"; 86 for (im = idxmap[idx&0xF]; im; im = im->next)87 if (im->index == idx)88 93 im = find_by_index(idx); 94 if (im) 95 return im->name; 89 96 snprintf(buf, 16, "if%d", idx); 90 97 return buf; … … 99 106 } 100 107 108 #ifdef UNUSED 101 109 int ll_index_to_type(int idx) 102 110 { … … 105 113 if (idx == 0) 106 114 return -1; 107 for (im = idxmap[idx&0xF]; im; im = im->next)108 if (im->index == idx)109 115 im = find_by_index(idx); 116 if (im) 117 return im->type; 110 118 return -1; 111 119 } 120 #endif 112 121 113 122 unsigned ll_index_to_flags(int idx) … … 117 126 if (idx == 0) 118 127 return 0; 119 120 for (im = idxmap[idx&0xF]; im; im = im->next) 121 if (im->index == idx) 122 return im->flags; 128 im = find_by_index(idx); 129 if (im) 130 return im->flags; 123 131 return 0; 124 132 } 125 133 126 int ll_name_to_index(char *name)134 int xll_name_to_index(const char *const name) 127 135 { 136 int ret = 0; 137 int sock_fd; 138 139 /* caching is not warranted - no users which repeatedly call it */ 140 #ifdef UNUSED 128 141 static char ncache[16]; 129 142 static int icache; 143 130 144 struct idxmap *im; 131 145 int i; 132 146 133 147 if (name == NULL) 134 return 0; 135 if (icache && strcmp(name, ncache) == 0) 136 return icache; 137 for (i=0; i<16; i++) { 148 goto out; 149 if (icache && strcmp(name, ncache) == 0) { 150 ret = icache; 151 goto out; 152 } 153 for (i = 0; i < 16; i++) { 138 154 for (im = idxmap[i]; im; im = im->next) { 139 155 if (strcmp(im->name, name) == 0) { 140 156 icache = im->index; 141 157 strcpy(ncache, name); 142 return im->index; 158 ret = im->index; 159 goto out; 143 160 } 144 161 } 145 162 } 146 return 0; 163 /* We have not found the interface in our cache, but the kernel 164 * may still know about it. One reason is that we may be using 165 * module on-demand loading, which means that the kernel will 166 * load the module and make the interface exist only when 167 * we explicitely request it (check for dev_load() in net/core/dev.c). 168 * I can think of other similar scenario, but they are less common... 169 * Jean II */ 170 #endif 171 172 sock_fd = socket(AF_INET, SOCK_DGRAM, 0); 173 if (sock_fd) { 174 struct ifreq ifr; 175 int tmp; 176 177 strncpy(ifr.ifr_name, name, IFNAMSIZ); 178 ifr.ifr_ifindex = -1; 179 tmp = ioctl(sock_fd, SIOCGIFINDEX, &ifr); 180 close(sock_fd); 181 if (tmp >= 0) 182 /* In theory, we should redump the interface list 183 * to update our cache, this is left as an exercise 184 * to the reader... Jean II */ 185 ret = ifr.ifr_ifindex; 186 } 187 /* out:*/ 188 if (ret <= 0) 189 bb_error_msg_and_die("cannot find device \"%s\"", name); 190 return ret; 147 191 } 148 192 149 193 int ll_init_map(struct rtnl_handle *rth) 150 194 { 151 if (rtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK) < 0) { 152 perror("Cannot send dump request"); 153 exit(1); 154 } 155 156 if (rtnl_dump_filter(rth, ll_remember_index, &idxmap, NULL, NULL) < 0) { 157 fprintf(stderr, "Dump terminated\n"); 158 exit(1); 159 } 195 xrtnl_wilddump_request(rth, AF_UNSPEC, RTM_GETLINK); 196 xrtnl_dump_filter(rth, ll_remember_index, &idxmap); 160 197 return 0; 161 198 } -
branches/stable/mindi-busybox/networking/libiproute/ll_map.h
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 #ifndef __LL_MAP_H__ 2 3 #define __LL_MAP_H__ 1 3 4 4 externint ll_remember_index(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);5 externint ll_init_map(struct rtnl_handle *rth);6 extern int ll_name_to_index(char *name);7 externconst char *ll_index_to_name(int idx);8 externconst char *ll_idx_n2a(int idx, char *buf);9 extern int ll_index_to_type(int idx); 10 externunsigned ll_index_to_flags(int idx);5 int ll_remember_index(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); 6 int ll_init_map(struct rtnl_handle *rth); 7 int xll_name_to_index(const char *const name); 8 const char *ll_index_to_name(int idx); 9 const char *ll_idx_n2a(int idx, char *buf); 10 /* int ll_index_to_type(int idx); */ 11 unsigned ll_index_to_flags(int idx); 11 12 12 13 #endif /* __LL_MAP_H__ */ -
branches/stable/mindi-busybox/networking/libiproute/ll_proto.c
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * ll_proto.c … … 11 12 12 13 #include "libbb.h" 13 #include <string.h>14 15 14 #include "rt_names.h" 16 15 #include "utils.h" 17 16 18 #if __GLIBC__ >=2 && __GLIBC_MINOR>= 117 #if defined(__GLIBC__) && __GLIBC__ >=2 && __GLIBC_MINOR__ >= 1 19 18 #include <net/ethernet.h> 20 19 #else … … 25 24 static struct { 26 25 int id; 27 c har *name;26 const char *name; 28 27 } llproto_names[] = { 29 28 __PF(LOOP,loop) … … 98 97 id = ntohs(id); 99 98 100 for (i=0; i <sizeof(llproto_names)/sizeof(llproto_names[0]); i++) {99 for (i=0; i < ARRAY_SIZE(llproto_names); i++) { 101 100 if (llproto_names[i].id == id) 102 101 return llproto_names[i].name; … … 109 108 { 110 109 int i; 111 for (i=0; i <sizeof(llproto_names)/sizeof(llproto_names[0]); i++) {110 for (i=0; i < ARRAY_SIZE(llproto_names); i++) { 112 111 if (strcasecmp(llproto_names[i].name, buf) == 0) { 113 112 *id = htons(llproto_names[i].id); -
branches/stable/mindi-busybox/networking/libiproute/ll_types.c
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * ll_types.c … … 9 10 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10 11 */ 11 #include <stdio.h>12 12 #include <arpa/inet.h> 13 14 13 #include <linux/if_arp.h> 15 14 15 #include "libbb.h" 16 16 #include "rt_names.h" 17 17 18 const char 18 const char* ll_type_n2a(int type, char *buf, int len) 19 19 { 20 20 #define __PF(f,n) { ARPHRD_##f, #n }, 21 static struct {21 static const struct { 22 22 int type; 23 c har *name;23 const char *name; 24 24 } arphrd_names[] = { 25 25 { 0, "generic" }, … … 109 109 110 110 int i; 111 for (i =0; i<sizeof(arphrd_names)/sizeof(arphrd_names[0]); i++) {111 for (i = 0; i < ARRAY_SIZE(arphrd_names); i++) { 112 112 if (arphrd_names[i].type == type) 113 113 return arphrd_names[i].name; -
branches/stable/mindi-busybox/networking/libiproute/rt_names.c
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * rt_names.c rtnetlink names DB. … … 9 10 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 10 11 */ 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <string.h> 14 15 #include <stdint.h> 12 13 #include "libbb.h" 16 14 #include "rt_names.h" 17 15 18 static void rtnl_tab_initialize(c har *file,char **tab, int size)16 static void rtnl_tab_initialize(const char *file, const char **tab, int size) 19 17 { 20 18 char buf[512]; … … 33 31 if (*p == '#' || *p == '\n' || *p == 0) 34 32 continue; 35 if (sscanf(p, "0x%x %s\n", &id, namebuf) != 2 && 36 sscanf(p, "0x%x %s #", &id, namebuf) != 2 && 37 sscanf(p, "%d %s\n", &id, namebuf) != 2 && 38 sscanf(p, "%d %s #", &id, namebuf) != 2) { 39 fprintf(stderr, "Database %s is corrupted at %s\n", 33 if (sscanf(p, "0x%x %s\n", &id, namebuf) != 2 34 && sscanf(p, "0x%x %s #", &id, namebuf) != 2 35 && sscanf(p, "%d %s\n", &id, namebuf) != 2 36 && sscanf(p, "%d %s #", &id, namebuf) != 2 37 ) { 38 bb_error_msg("database %s is corrupted at %s", 40 39 file, p); 41 40 return; 42 41 } 43 42 44 if (id <0 || id>size)43 if (id < 0 || id > size) 45 44 continue; 46 45 47 tab[id] = strdup(namebuf);46 tab[id] = xstrdup(namebuf); 48 47 } 49 48 fclose(fp); … … 51 50 52 51 53 static char * rtnl_rtprot_tab[256] = { 54 "none", 55 "redirect", 56 "kernel", 57 "boot", 58 "static", 59 NULL, 60 NULL, 61 NULL, 62 "gated", 63 "ra", 64 "mrt", 65 "zebra", 66 "bird", 67 }; 68 69 70 71 static int rtnl_rtprot_init; 52 static const char **rtnl_rtprot_tab; /* [256] */ 72 53 73 54 static void rtnl_rtprot_initialize(void) 74 55 { 75 rtnl_rtprot_init = 1; 56 static const char *const init_tab[] = { 57 "none", 58 "redirect", 59 "kernel", 60 "boot", 61 "static", 62 NULL, 63 NULL, 64 NULL, 65 "gated", 66 "ra", 67 "mrt", 68 "zebra", 69 "bird", 70 }; 71 if (rtnl_rtprot_tab) return; 72 rtnl_rtprot_tab = xzalloc(256 * sizeof(rtnl_rtprot_tab[0])); 73 memcpy(rtnl_rtprot_tab, init_tab, sizeof(init_tab)); 76 74 rtnl_tab_initialize("/etc/iproute2/rt_protos", 77 75 rtnl_rtprot_tab, 256); 78 76 } 79 77 80 const char * rtnl_rtprot_n2a(int id, char *buf, int len) 81 { 82 if (id<0 || id>=256){83 snprintf(buf, len, "%d", id);84 return buf;85 }86 if (!rtnl_rtprot_tab[id]) {87 if (!rtnl_rtprot_init) 88 89 } 78 79 const char* rtnl_rtprot_n2a(int id, char *buf, int len) 80 { 81 if (id < 0 || id >= 256) { 82 snprintf(buf, len, "%d", id); 83 return buf; 84 } 85 86 rtnl_rtprot_initialize(); 87 90 88 if (rtnl_rtprot_tab[id]) 91 89 return rtnl_rtprot_tab[id]; … … 96 94 int rtnl_rtprot_a2n(uint32_t *id, char *arg) 97 95 { 98 static char *cache = NULL; 99 static unsigned long res; 100 char *end; 101 int i; 102 103 if (cache && strcmp(cache, arg) == 0) { 104 *id = res; 105 return 0; 106 } 107 108 if (!rtnl_rtprot_init) 109 rtnl_rtprot_initialize(); 110 111 for (i=0; i<256; i++) { 96 static const char *cache = NULL; 97 static unsigned long res; 98 int i; 99 100 if (cache && strcmp(cache, arg) == 0) { 101 *id = res; 102 return 0; 103 } 104 105 rtnl_rtprot_initialize(); 106 107 for (i = 0; i < 256; i++) { 112 108 if (rtnl_rtprot_tab[i] && 113 109 strcmp(rtnl_rtprot_tab[i], arg) == 0) { … … 119 115 } 120 116 121 res = strtoul(arg, &end, 0);122 if ( !end || end == arg || *end|| res > 255)117 res = bb_strtoul(arg, NULL, 0); 118 if (errno || res > 255) 123 119 return -1; 124 120 *id = res; … … 127 123 128 124 129 130 static char * rtnl_rtscope_tab[256] = { 131 "global", 132 }; 133 134 static int rtnl_rtscope_init; 125 static const char **rtnl_rtscope_tab; /* [256] */ 135 126 136 127 static void rtnl_rtscope_initialize(void) 137 128 { 138 rtnl_rtscope_init = 1; 129 if (rtnl_rtscope_tab) return; 130 rtnl_rtscope_tab = xzalloc(256 * sizeof(rtnl_rtscope_tab[0])); 131 rtnl_rtscope_tab[0] = "global"; 139 132 rtnl_rtscope_tab[255] = "nowhere"; 140 133 rtnl_rtscope_tab[254] = "host"; … … 145 138 } 146 139 147 const char * rtnl_rtscope_n2a(int id, char *buf, int len) 148 { 149 if (id<0 || id>=256){150 snprintf(buf, len, "%d", id);151 return buf;152 }153 if (!rtnl_rtscope_tab[id]) {154 if (!rtnl_rtscope_init) 155 156 } 140 141 const char* rtnl_rtscope_n2a(int id, char *buf, int len) 142 { 143 if (id < 0 || id >= 256) { 144 snprintf(buf, len, "%d", id); 145 return buf; 146 } 147 148 rtnl_rtscope_initialize(); 149 157 150 if (rtnl_rtscope_tab[id]) 158 151 return rtnl_rtscope_tab[id]; … … 163 156 int rtnl_rtscope_a2n(uint32_t *id, char *arg) 164 157 { 165 static char *cache = NULL; 166 static unsigned long res; 167 char *end; 168 int i; 169 170 if (cache && strcmp(cache, arg) == 0) { 171 *id = res; 172 return 0; 173 } 174 175 if (!rtnl_rtscope_init) 176 rtnl_rtscope_initialize(); 177 178 for (i=0; i<256; i++) { 158 static const char *cache = NULL; 159 static unsigned long res; 160 int i; 161 162 if (cache && strcmp(cache, arg) == 0) { 163 *id = res; 164 return 0; 165 } 166 167 rtnl_rtscope_initialize(); 168 169 for (i = 0; i < 256; i++) { 179 170 if (rtnl_rtscope_tab[i] && 180 171 strcmp(rtnl_rtscope_tab[i], arg) == 0) { … … 186 177 } 187 178 188 res = strtoul(arg, &end, 0);189 if ( !end || end == arg || *end|| res > 255)179 res = bb_strtoul(arg, NULL, 0); 180 if (errno || res > 255) 190 181 return -1; 191 182 *id = res; … … 194 185 195 186 196 197 static char * rtnl_rtrealm_tab[256] = { 198 "unknown", 199 }; 200 201 static int rtnl_rtrealm_init; 187 static const char **rtnl_rtrealm_tab; /* [256] */ 202 188 203 189 static void rtnl_rtrealm_initialize(void) 204 190 { 205 rtnl_rtrealm_init = 1; 191 if (rtnl_rtrealm_tab) return; 192 rtnl_rtrealm_tab = xzalloc(256 * sizeof(rtnl_rtrealm_tab[0])); 193 rtnl_rtrealm_tab[0] = "unknown"; 206 194 rtnl_tab_initialize("/etc/iproute2/rt_realms", 207 195 rtnl_rtrealm_tab, 256); 208 196 } 209 197 198 210 199 int rtnl_rtrealm_a2n(uint32_t *id, char *arg) 211 200 { 212 static char *cache = NULL; 213 static unsigned long res; 214 char *end; 215 int i; 216 217 if (cache && strcmp(cache, arg) == 0) { 218 *id = res; 219 return 0; 220 } 221 222 if (!rtnl_rtrealm_init) 223 rtnl_rtrealm_initialize(); 224 225 for (i=0; i<256; i++) { 201 static const char *cache = NULL; 202 static unsigned long res; 203 int i; 204 205 if (cache && strcmp(cache, arg) == 0) { 206 *id = res; 207 return 0; 208 } 209 210 rtnl_rtrealm_initialize(); 211 212 for (i = 0; i < 256; i++) { 226 213 if (rtnl_rtrealm_tab[i] && 227 214 strcmp(rtnl_rtrealm_tab[i], arg) == 0) { … … 233 220 } 234 221 235 res = strtoul(arg, &end, 0);236 if ( !end || end == arg || *end|| res > 255)222 res = bb_strtoul(arg, NULL, 0); 223 if (errno || res > 255) 237 224 return -1; 238 225 *id = res; … … 240 227 } 241 228 242 243 244 static char * rtnl_rtdsfield_tab[256] = { 245 "0", 246 }; 247 248 static int rtnl_rtdsfield_init; 229 #if ENABLE_FEATURE_IP_RULE 230 const char* rtnl_rtrealm_n2a(int id, char *buf, int len) 231 { 232 if (id < 0 || id >= 256) { 233 snprintf(buf, len, "%d", id); 234 return buf; 235 } 236 237 rtnl_rtrealm_initialize(); 238 239 if (rtnl_rtrealm_tab[id]) 240 return rtnl_rtrealm_tab[id]; 241 snprintf(buf, len, "%d", id); 242 return buf; 243 } 244 #endif 245 246 247 static const char **rtnl_rtdsfield_tab; /* [256] */ 249 248 250 249 static void rtnl_rtdsfield_initialize(void) 251 250 { 252 rtnl_rtdsfield_init = 1; 251 if (rtnl_rtdsfield_tab) return; 252 rtnl_rtdsfield_tab = xzalloc(256 * sizeof(rtnl_rtdsfield_tab[0])); 253 rtnl_rtdsfield_tab[0] = "0"; 253 254 rtnl_tab_initialize("/etc/iproute2/rt_dsfield", 254 255 rtnl_rtdsfield_tab, 256); 255 256 } 256 257 258 257 259 const char * rtnl_dsfield_n2a(int id, char *buf, int len) 258 260 { 259 if (id<0 || id>=256) { 260 snprintf(buf, len, "%d", id); 261 return buf; 262 } 263 if (!rtnl_rtdsfield_tab[id]) { 264 if (!rtnl_rtdsfield_init) 265 rtnl_rtdsfield_initialize(); 266 } 261 if (id < 0 || id >= 256) { 262 snprintf(buf, len, "%d", id); 263 return buf; 264 } 265 266 rtnl_rtdsfield_initialize(); 267 267 268 if (rtnl_rtdsfield_tab[id]) 268 269 return rtnl_rtdsfield_tab[id]; … … 274 275 int rtnl_dsfield_a2n(uint32_t *id, char *arg) 275 276 { 276 static char *cache = NULL; 277 static unsigned long res; 278 char *end; 279 int i; 280 281 if (cache && strcmp(cache, arg) == 0) { 282 *id = res; 283 return 0; 284 } 285 286 if (!rtnl_rtdsfield_init) 287 rtnl_rtdsfield_initialize(); 288 289 for (i=0; i<256; i++) { 277 static const char *cache = NULL; 278 static unsigned long res; 279 int i; 280 281 if (cache && strcmp(cache, arg) == 0) { 282 *id = res; 283 return 0; 284 } 285 286 rtnl_rtdsfield_initialize(); 287 288 for (i = 0; i < 256; i++) { 290 289 if (rtnl_rtdsfield_tab[i] && 291 290 strcmp(rtnl_rtdsfield_tab[i], arg) == 0) { … … 297 296 } 298 297 299 res = strtoul(arg, &end, 16);300 if ( !end || end == arg || *end|| res > 255)298 res = bb_strtoul(arg, NULL, 16); 299 if (errno || res > 255) 301 300 return -1; 302 301 *id = res; … … 304 303 } 305 304 305 306 #if ENABLE_FEATURE_IP_RULE 307 static const char **rtnl_rttable_tab; /* [256] */ 308 309 static void rtnl_rttable_initialize(void) 310 { 311 if (rtnl_rtdsfield_tab) return; 312 rtnl_rttable_tab = xzalloc(256 * sizeof(rtnl_rttable_tab[0])); 313 rtnl_rttable_tab[0] = "unspec"; 314 rtnl_rttable_tab[255] = "local"; 315 rtnl_rttable_tab[254] = "main"; 316 rtnl_rttable_tab[253] = "default"; 317 rtnl_tab_initialize("/etc/iproute2/rt_tables", rtnl_rttable_tab, 256); 318 } 319 320 321 const char *rtnl_rttable_n2a(int id, char *buf, int len) 322 { 323 if (id < 0 || id >= 256) { 324 snprintf(buf, len, "%d", id); 325 return buf; 326 } 327 328 rtnl_rttable_initialize(); 329 330 if (rtnl_rttable_tab[id]) 331 return rtnl_rttable_tab[id]; 332 snprintf(buf, len, "%d", id); 333 return buf; 334 } 335 336 int rtnl_rttable_a2n(uint32_t * id, char *arg) 337 { 338 static char *cache = NULL; 339 static unsigned long res; 340 int i; 341 342 if (cache && strcmp(cache, arg) == 0) { 343 *id = res; 344 return 0; 345 } 346 347 rtnl_rttable_initialize(); 348 349 for (i = 0; i < 256; i++) { 350 if (rtnl_rttable_tab[i] && strcmp(rtnl_rttable_tab[i], arg) == 0) { 351 cache = (char*)rtnl_rttable_tab[i]; 352 res = i; 353 *id = res; 354 return 0; 355 } 356 } 357 358 i = bb_strtoul(arg, NULL, 0); 359 if (errno || i > 255) 360 return -1; 361 *id = i; 362 return 0; 363 } 364 365 #endif -
branches/stable/mindi-busybox/networking/libiproute/rt_names.h
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 #ifndef RT_NAMES_H_ 2 3 #define RT_NAMES_H_ 1 … … 6 7 extern const char* rtnl_rtprot_n2a(int id, char *buf, int len); 7 8 extern const char* rtnl_rtscope_n2a(int id, char *buf, int len); 9 extern const char* rtnl_rtrealm_n2a(int id, char *buf, int len); 8 10 extern const char* rtnl_dsfield_n2a(int id, char *buf, int len); 11 extern const char* rtnl_rttable_n2a(int id, char *buf, int len); 9 12 extern int rtnl_rtprot_a2n(uint32_t *id, char *arg); 10 13 extern int rtnl_rtscope_a2n(uint32_t *id, char *arg); 11 14 extern int rtnl_rtrealm_a2n(uint32_t *id, char *arg); 12 15 extern int rtnl_dsfield_a2n(uint32_t *id, char *arg); 16 extern int rtnl_rttable_a2n(uint32_t *id, char *arg); 13 17 14 18 15 extern const char 19 extern const char* ll_type_n2a(int type, char *buf, int len); 16 20 17 extern const char *ll_addr_n2a(unsigned char *addr, int alen, int type,21 extern const char* ll_addr_n2a(unsigned char *addr, int alen, int type, 18 22 char *buf, int blen); 19 23 extern int ll_addr_a2n(unsigned char *lladdr, int len, char *arg); 20 24 21 extern const char 25 extern const char* ll_proto_n2a(unsigned short id, char *buf, int len); 22 26 extern int ll_proto_a2n(unsigned short *id, char *buf); 23 27 24 25 28 #endif -
branches/stable/mindi-busybox/networking/libiproute/rtm_map.c
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * rtm_map.c … … 11 12 */ 12 13 13 #include <stdlib.h> 14 #include <string.h> 15 14 #include "libbb.h" 16 15 #include "rt_names.h" 17 16 #include "utils.h" 18 17 19 c har *rtnl_rtntype_n2a(int id, char *buf, int len)18 const char *rtnl_rtntype_n2a(int id, char *buf, int len) 20 19 { 21 20 switch (id) { … … 53 52 int rtnl_rtntype_a2n(int *id, char *arg) 54 53 { 54 static const char keywords[] ALIGN1 = 55 "local\0""nat\0""broadcast\0""brd\0""anycast\0" 56 "multicast\0""prohibit\0""unreachable\0""blackhole\0" 57 "xresolve\0""unicast\0""throw\0"; 58 enum { 59 ARG_local = 1, ARG_nat, ARG_broadcast, ARG_brd, ARG_anycast, 60 ARG_multicast, ARG_prohibit, ARG_unreachable, ARG_blackhole, 61 ARG_xresolve, ARG_unicast, ARG_throw 62 }; 63 const smalluint key = index_in_substrings(keywords, arg) + 1; 55 64 char *end; 56 65 unsigned long res; 57 66 58 if ( strcmp(arg, "local") == 0)67 if (key == ARG_local) 59 68 res = RTN_LOCAL; 60 else if ( strcmp(arg, "nat") == 0)69 else if (key == ARG_nat) 61 70 res = RTN_NAT; 62 else if (matches(arg, "broadcast") == 0 || 63 strcmp(arg, "brd") == 0) 71 else if (key == ARG_broadcast || key == ARG_brd) 64 72 res = RTN_BROADCAST; 65 else if ( matches(arg, "anycast") == 0)73 else if (key == ARG_anycast) 66 74 res = RTN_ANYCAST; 67 else if ( matches(arg, "multicast") == 0)75 else if (key == ARG_multicast) 68 76 res = RTN_MULTICAST; 69 else if ( matches(arg, "prohibit") == 0)77 else if (key == ARG_prohibit) 70 78 res = RTN_PROHIBIT; 71 else if ( matches(arg, "unreachable") == 0)79 else if (key == ARG_unreachable) 72 80 res = RTN_UNREACHABLE; 73 else if ( matches(arg, "blackhole") == 0)81 else if (key == ARG_blackhole) 74 82 res = RTN_BLACKHOLE; 75 else if ( matches(arg, "xresolve") == 0)83 else if (key == ARG_xresolve) 76 84 res = RTN_XRESOLVE; 77 else if ( matches(arg, "unicast") == 0)85 else if (key == ARG_unicast) 78 86 res = RTN_UNICAST; 79 else if ( strcmp(arg, "throw") == 0)87 else if (key == ARG_throw) 80 88 res = RTN_THROW; 81 89 else { … … 88 96 } 89 97 90 int get_rt_realms( __u32*realms, char *arg)98 int get_rt_realms(uint32_t *realms, char *arg) 91 99 { 92 __u32realm = 0;100 uint32_t realm = 0; 93 101 char *p = strchr(arg, '/'); 94 102 -
branches/stable/mindi-busybox/networking/libiproute/rtm_map.h
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 #ifndef __RTM_MAP_H__ 2 3 #define __RTM_MAP_H__ 1 3 4 4 c har *rtnl_rtntype_n2a(int id, char *buf, int len);5 const char *rtnl_rtntype_n2a(int id, char *buf, int len); 5 6 int rtnl_rtntype_a2n(int *id, char *arg); 6 7 7 int get_rt_realms( __u32*realms, char *arg);8 int get_rt_realms(uint32_t *realms, char *arg); 8 9 9 10 -
branches/stable/mindi-busybox/networking/libiproute/utils.c
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 /* 2 3 * utils.c … … 12 13 13 14 #include "libbb.h" 14 15 #include <string.h>16 #include <unistd.h>17 18 15 #include "utils.h" 19 16 #include "inet_common.h" … … 32 29 return 0; 33 30 } 34 31 //XXX: FIXME: use some libbb function instead 35 32 int get_unsigned(unsigned *val, char *arg, int base) 36 33 { … … 47 44 } 48 45 49 int get_u32( __u32* val, char *arg, int base)46 int get_u32(uint32_t * val, char *arg, int base) 50 47 { 51 48 unsigned long res; … … 61 58 } 62 59 63 int get_u16( __u16* val, char *arg, int base)60 int get_u16(uint16_t * val, char *arg, int base) 64 61 { 65 62 unsigned long res; … … 75 72 } 76 73 77 int get_u8( __u8* val, char *arg, int base)74 int get_u8(uint8_t * val, char *arg, int base) 78 75 { 79 76 unsigned long res; … … 89 86 } 90 87 91 int get_s16( __s16* val, char *arg, int base)88 int get_s16(int16_t * val, char *arg, int base) 92 89 { 93 90 long res; … … 103 100 } 104 101 105 int get_s8( __s8* val, char *arg, int base)102 int get_s8(int8_t * val, char *arg, int base) 106 103 { 107 104 long res; … … 125 122 memset(addr, 0, sizeof(*addr)); 126 123 127 if (strcmp(name, bb_ INET_default) == 0 ||124 if (strcmp(name, bb_str_default) == 0 || 128 125 strcmp(name, "all") == 0 || strcmp(name, "any") == 0) { 129 126 addr->family = family; … … 169 166 memset(dst, 0, sizeof(*dst)); 170 167 171 if (strcmp(arg, bb_ INET_default) == 0 || strcmp(arg, "any") == 0) {168 if (strcmp(arg, bb_str_default) == 0 || strcmp(arg, "any") == 0) { 172 169 dst->family = family; 173 170 dst->bytelen = 0; … … 178 175 slash = strchr(arg, '/'); 179 176 if (slash) 180 *slash = 0;177 *slash = '\0'; 181 178 err = get_addr_1(dst, arg, family); 182 179 if (err == 0) { … … 197 194 } 198 195 } 199 196 done: 200 197 if (slash) 201 198 *slash = '/'; … … 206 203 { 207 204 if (family == AF_PACKET) { 208 bb_error_msg_and_die("\"%s\" may be inet address, but it is not allowed in this context .", arg);205 bb_error_msg_and_die("\"%s\" may be inet address, but it is not allowed in this context", arg); 209 206 } 210 207 if (get_addr_1(dst, arg, family)) { 211 bb_error_msg_and_die("an inet address is expected rather than \"%s\" .", arg);208 bb_error_msg_and_die("an inet address is expected rather than \"%s\"", arg); 212 209 } 213 210 return 0; … … 217 214 { 218 215 if (family == AF_PACKET) { 219 bb_error_msg_and_die("\"%s\" may be inet address, but it is not allowed in this context .", arg);216 bb_error_msg_and_die("\"%s\" may be inet address, but it is not allowed in this context", arg); 220 217 } 221 218 if (get_prefix_1(dst, arg, family)) { 222 bb_error_msg_and_die("an inet address is expected rather than \"%s\" .", arg);223 } 224 return 0; 225 } 226 227 __u32get_addr32(char *name)219 bb_error_msg_and_die("an inet address is expected rather than \"%s\"", arg); 220 } 221 return 0; 222 } 223 224 uint32_t get_addr32(char *name) 228 225 { 229 226 inet_prefix addr; … … 237 234 void incomplete_command(void) 238 235 { 239 bb_error_msg("Command line is not complete. Try option \"help\""); 240 exit(-1); 241 } 242 243 void invarg(const char * const arg, const char * const opt) 244 { 245 bb_error_msg(bb_msg_invalid_arg, arg, opt); 246 exit(-1); 247 } 248 249 void duparg(char *key, char *arg) 250 { 251 bb_error_msg("duplicate \"%s\": \"%s\" is the second value.", key, arg); 252 exit(-1); 253 } 254 255 void duparg2(char *key, char *arg) 256 { 257 bb_error_msg("either \"%s\" is duplicate, or \"%s\" is a garbage.", key, arg); 258 exit(-1); 259 } 260 261 int matches(char *cmd, char *pattern) 262 { 263 int len = strlen(cmd); 264 265 if (len > strlen(pattern)) { 266 return -1; 267 } 268 return memcmp(pattern, cmd, len); 236 bb_error_msg_and_die("command line is not complete, try option \"help\""); 237 } 238 239 void invarg(const char *arg, const char *opt) 240 { 241 bb_error_msg_and_die(bb_msg_invalid_arg, arg, opt); 242 } 243 244 void duparg(const char *key, const char *arg) 245 { 246 bb_error_msg_and_die("duplicate \"%s\": \"%s\" is the second value", key, arg); 247 } 248 249 void duparg2(const char *key, const char *arg) 250 { 251 bb_error_msg_and_die("either \"%s\" is duplicate, or \"%s\" is garbage", key, arg); 269 252 } 270 253 271 254 int inet_addr_match(inet_prefix * a, inet_prefix * b, int bits) 272 255 { 273 __u32*a1 = a->data;274 __u32*a2 = b->data;256 uint32_t *a1 = a->data; 257 uint32_t *a2 = b->data; 275 258 int words = bits >> 0x05; 276 259 … … 282 265 283 266 if (bits) { 284 __u32w1, w2;285 __u32mask;267 uint32_t w1, w2; 268 uint32_t mask; 286 269 287 270 w1 = a1[words]; … … 295 278 296 279 return 0; 297 }298 299 int __iproute2_hz_internal;300 301 int __get_hz(void)302 {303 int hz = 0;304 FILE *fp = fopen("/proc/net/psched", "r");305 306 if (fp) {307 unsigned nom, denom;308 309 if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2)310 if (nom == 1000000)311 hz = denom;312 fclose(fp);313 }314 if (hz)315 return hz;316 return sysconf(_SC_CLK_TCK);317 280 } 318 281 … … 347 310 } 348 311 } 349 if (len > 0 && (h_ent = gethostbyaddr(addr, len, af)) != NULL) { 350 snprintf(buf, buflen - 1, "%s", h_ent->h_name); 351 return buf; 312 if (len > 0) { 313 h_ent = gethostbyaddr(addr, len, af); 314 if (h_ent != NULL) { 315 safe_strncpy(buf, h_ent->h_name, buflen); 316 return buf; 317 } 352 318 } 353 319 } -
branches/stable/mindi-busybox/networking/libiproute/utils.h
r821 r1770 1 /* vi: set sw=4 ts=4: */ 1 2 #ifndef __UTILS_H__ 2 3 #define __UTILS_H__ 1 3 4 #include "libbb.h"5 #include <asm/types.h>6 #include <resolv.h>7 4 8 5 #include "libnetlink.h" … … 11 8 12 9 extern int preferred_family; 13 extern int show_stats;14 extern int show_details;15 extern int show_raw;16 extern int resolve_hosts;17 extern int oneline;18 extern char *_SL_;10 extern smallint show_stats; /* UNUSED */ 11 extern smallint show_details; /* UNUSED */ 12 extern smallint show_raw; /* UNUSED */ 13 extern smallint resolve_hosts; /* UNUSED */ 14 extern smallint oneline; 15 extern char _SL_; 19 16 20 17 #ifndef IPPROTO_ESP … … 30 27 extern void incomplete_command(void) ATTRIBUTE_NORETURN; 31 28 32 #define NEXT_ARG() do { argv++; if (--argc <= 0) incomplete_command(); } while (0)29 #define NEXT_ARG() do { argv++; if (--argc <= 0) incomplete_command(); } while (0) 33 30 34 31 typedef struct 35 32 { 36 __u8family;37 __u8bytelen;38 __s16bitlen;39 __u32data[4];33 uint8_t family; 34 uint8_t bytelen; 35 int16_t bitlen; 36 uint32_t data[4]; 40 37 } inet_prefix; 41 38 … … 45 42 #endif 46 43 47 struct dn_naddr 48 { 44 struct dn_naddr { 49 45 unsigned short a_len; 50 46 unsigned char a_addr[DN_MAXADDL]; … … 58 54 }; 59 55 60 extern __u32get_addr32(char *name);56 extern uint32_t get_addr32(char *name); 61 57 extern int get_addr_1(inet_prefix *dst, char *arg, int family); 62 58 extern int get_prefix_1(inet_prefix *dst, char *arg, int family); … … 69 65 #define get_ushort get_u16 70 66 #define get_short get_s16 71 extern int get_u32( __u32*val, char *arg, int base);72 extern int get_u16( __u16*val, char *arg, int base);73 extern int get_s16( __s16*val, char *arg, int base);74 extern int get_u8( __u8*val, char *arg, int base);75 extern int get_s8( __s8*val, char *arg, int base);67 extern int get_u32(uint32_t *val, char *arg, int base); 68 extern int get_u16(uint16_t *val, char *arg, int base); 69 extern int get_s16(int16_t *val, char *arg, int base); 70 extern int get_u8(uint8_t *val, char *arg, int base); 71 extern int get_s8(int8_t *val, char *arg, int base); 76 72 77 73 extern const char *format_host(int af, int len, void *addr, char *buf, int buflen); 78 74 extern const char *rt_addr_n2a(int af, int len, void *addr, char *buf, int buflen); 79 75 80 void invarg(const char * const, const char * const) ATTRIBUTE_NORETURN; 81 void duparg(char *, char *) ATTRIBUTE_NORETURN; 82 void duparg2(char *, char *) ATTRIBUTE_NORETURN; 83 int matches(char *arg, char *pattern); 84 extern int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits); 76 void invarg(const char *, const char *) ATTRIBUTE_NORETURN; 77 void duparg(const char *, const char *) ATTRIBUTE_NORETURN; 78 void duparg2(const char *, const char *) ATTRIBUTE_NORETURN; 79 int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits); 85 80 86 81 const char *dnet_ntop(int af, const void *addr, char *str, size_t len); … … 90 85 int ipx_pton(int af, const char *src, void *addr); 91 86 92 extern int __iproute2_hz_internal;93 extern int __get_hz(void);94 95 static __inline__ int get_hz(void)96 {97 if (__iproute2_hz_internal == 0)98 __iproute2_hz_internal = __get_hz();99 return __iproute2_hz_internal;100 }101 102 87 #endif /* __UTILS_H__ */
Note:
See TracChangeset
for help on using the changeset viewer.