X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=networking%2Flibiproute%2Fipaddress.c;h=1be03a6c3b17b9b70fc63d9e83f88259e07171b3;hb=b276e418351612341e31da6385edbc3c91d2f6e8;hp=f2e340a42b1253d5aff063ec1b85291bd04c3c0b;hpb=ffc4bced958e5746e736c9939c4d1de665e1cffa;p=oweals%2Fbusybox.git diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index f2e340a42..1be03a6c3 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c @@ -2,7 +2,7 @@ /* * ipaddress.c "ip address". * - * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + * Licensed under GPLv2 or later, see file LICENSE in this source tree. * * Authors: Alexey Kuznetsov, * @@ -23,7 +23,7 @@ #define IFF_LOWER_UP 0x10000 /* driver signals L1 up*/ #endif -typedef struct filter_t { +struct filter_t { char *label; char *flushb; struct rtnl_handle *rth; @@ -38,7 +38,8 @@ typedef struct filter_t { smallint up; smallint flushed; inet_prefix pfx; -} filter_t; +} FIX_ALIASING; +typedef struct filter_t filter_t; #define G_filter (*(filter_t*)&bb_common_bufsiz1) @@ -53,6 +54,8 @@ static void print_link_flags(unsigned flags, unsigned mdown) "MULTICAST\0""NOARP\0""UP\0""LOWER_UP\0"; bb_putchar('<'); + if (flags & IFF_UP && !(flags & IFF_RUNNING)) + printf("NO-CARRIER,"); flags &= ~IFF_RUNNING; #if 0 _PF(ALLMULTI); @@ -161,6 +164,13 @@ static NOINLINE int print_linkinfo(const struct nlmsghdr *n) printf("master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1)); } #endif + if (tb[IFLA_OPERSTATE]) { + static const char operstate_labels[] ALIGN1 = + "UNKNOWN\0""NOTPRESENT\0""DOWN\0""LOWERLAYERDOWN\0" + "TESTING\0""DORMANT\0""UP\0"; + printf("state %s ", nth_string(operstate_labels, + *(uint8_t *)RTA_DATA(tb[IFLA_OPERSTATE]))); + } if (G_filter.showqueue) print_queuelen((char*)RTA_DATA(tb[IFLA_IFNAME])); @@ -193,7 +203,7 @@ static NOINLINE int print_linkinfo(const struct nlmsghdr *n) static int flush_update(void) { if (rtnl_send(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) { - bb_perror_msg("failed to send flush request"); + bb_perror_msg("can't send flush request"); return -1; } G_filter.flushp = 0; @@ -405,7 +415,7 @@ static void ipaddr_reset_filter(int _oneline) } /* Return value becomes exitcode. It's okay to not return at all */ -int ipaddr_list_or_flush(char **argv, int flush) +int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush) { static const char option[] ALIGN1 = "to\0""scope\0""up\0""label\0""dev\0"; @@ -432,43 +442,36 @@ int ipaddr_list_or_flush(char **argv, int flush) } while (*argv) { - const int option_num = index_in_strings(option, *argv); - switch (option_num) { - case 0: /* to */ - NEXT_ARG(); - get_prefix(&G_filter.pfx, *argv, G_filter.family); - if (G_filter.family == AF_UNSPEC) { - G_filter.family = G_filter.pfx.family; - } - break; - case 1: { /* scope */ - uint32_t scope = 0; - NEXT_ARG(); - G_filter.scopemask = -1; - if (rtnl_rtscope_a2n(&scope, *argv)) { - if (strcmp(*argv, "all") != 0) { - invarg(*argv, "scope"); - } - scope = RT_SCOPE_NOWHERE; - G_filter.scopemask = 0; + const smalluint key = index_in_strings(option, *argv); + if (key == 0) { /* to */ + NEXT_ARG(); + get_prefix(&G_filter.pfx, *argv, G_filter.family); + if (G_filter.family == AF_UNSPEC) { + G_filter.family = G_filter.pfx.family; + } + } else if (key == 1) { /* scope */ + uint32_t scope = 0; + NEXT_ARG(); + G_filter.scopemask = -1; + if (rtnl_rtscope_a2n(&scope, *argv)) { + if (strcmp(*argv, "all") != 0) { + invarg(*argv, "scope"); } - G_filter.scope = scope; - break; + scope = RT_SCOPE_NOWHERE; + G_filter.scopemask = 0; } - case 2: /* up */ - G_filter.up = 1; - break; - case 3: /* label */ - NEXT_ARG(); - G_filter.label = *argv; - break; - case 4: /* dev */ + G_filter.scope = scope; + } else if (key == 2) { /* up */ + G_filter.up = 1; + } else if (key == 3) { /* label */ + NEXT_ARG(); + G_filter.label = *argv; + } else { + if (key == 4) /* dev */ NEXT_ARG(); - default: - if (filter_dev) { - duparg2("dev", *argv); - } - filter_dev = *argv; + if (filter_dev) + duparg2("dev", *argv); + filter_dev = *argv; } argv++; } @@ -621,98 +624,83 @@ static int ipaddr_modify(int cmd, char **argv) req.ifa.ifa_family = preferred_family; while (*argv) { - const int option_num = index_in_strings(option, *argv); - switch (option_num) { - case 0: /* peer */ - case 1: /* remote */ - NEXT_ARG(); + const smalluint arg = index_in_strings(option, *argv); + if (arg <= 1) { /* peer, remote */ + NEXT_ARG(); - if (peer_len) { - duparg("peer", *argv); - } - get_prefix(&peer, *argv, req.ifa.ifa_family); - peer_len = peer.bytelen; - if (req.ifa.ifa_family == AF_UNSPEC) { - req.ifa.ifa_family = peer.family; - } - addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen); - req.ifa.ifa_prefixlen = peer.bitlen; - break; - case 2: /* broadcast */ - case 3: /* brd */ - { - inet_prefix addr; - NEXT_ARG(); - if (brd_len) { - duparg("broadcast", *argv); - } - if (LONE_CHAR(*argv, '+')) { - brd_len = -1; - } else if (LONE_DASH(*argv)) { - brd_len = -2; - } else { - get_addr(&addr, *argv, req.ifa.ifa_family); - if (req.ifa.ifa_family == AF_UNSPEC) - req.ifa.ifa_family = addr.family; - addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen); - brd_len = addr.bytelen; - } - break; + if (peer_len) { + duparg("peer", *argv); } - case 4: /* anycast */ - { - inet_prefix addr; - NEXT_ARG(); - if (any_len) { - duparg("anycast", *argv); - } + get_prefix(&peer, *argv, req.ifa.ifa_family); + peer_len = peer.bytelen; + if (req.ifa.ifa_family == AF_UNSPEC) { + req.ifa.ifa_family = peer.family; + } + addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen); + req.ifa.ifa_prefixlen = peer.bitlen; + } else if (arg <= 3) { /* broadcast, brd */ + inet_prefix addr; + NEXT_ARG(); + if (brd_len) { + duparg("broadcast", *argv); + } + if (LONE_CHAR(*argv, '+')) { + brd_len = -1; + } else if (LONE_DASH(*argv)) { + brd_len = -2; + } else { get_addr(&addr, *argv, req.ifa.ifa_family); - if (req.ifa.ifa_family == AF_UNSPEC) { + if (req.ifa.ifa_family == AF_UNSPEC) req.ifa.ifa_family = addr.family; - } - addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen); - any_len = addr.bytelen; - break; + addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen); + brd_len = addr.bytelen; } - case 5: /* scope */ - { - uint32_t scope = 0; - NEXT_ARG(); - if (rtnl_rtscope_a2n(&scope, *argv)) { - invarg(*argv, "scope"); - } - req.ifa.ifa_scope = scope; - scoped = 1; - break; + } else if (arg == 4) { /* anycast */ + inet_prefix addr; + NEXT_ARG(); + if (any_len) { + duparg("anycast", *argv); } - case 6: /* dev */ - NEXT_ARG(); - d = *argv; - break; - case 7: /* label */ - NEXT_ARG(); - l = *argv; - addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l)+1); - break; - case 8: /* local */ + get_addr(&addr, *argv, req.ifa.ifa_family); + if (req.ifa.ifa_family == AF_UNSPEC) { + req.ifa.ifa_family = addr.family; + } + addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen); + any_len = addr.bytelen; + } else if (arg == 5) { /* scope */ + uint32_t scope = 0; + NEXT_ARG(); + if (rtnl_rtscope_a2n(&scope, *argv)) { + invarg(*argv, "scope"); + } + req.ifa.ifa_scope = scope; + scoped = 1; + } else if (arg == 6) { /* dev */ + NEXT_ARG(); + d = *argv; + } else if (arg == 7) { /* label */ + NEXT_ARG(); + l = *argv; + addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1); + } else { + if (arg == 8) /* local */ NEXT_ARG(); - default: - if (local_len) { - duparg2("local", *argv); - } - get_prefix(&lcl, *argv, req.ifa.ifa_family); - if (req.ifa.ifa_family == AF_UNSPEC) { - req.ifa.ifa_family = lcl.family; - } - addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen); - local_len = lcl.bytelen; + if (local_len) { + duparg2("local", *argv); + } + get_prefix(&lcl, *argv, req.ifa.ifa_family); + if (req.ifa.ifa_family == AF_UNSPEC) { + req.ifa.ifa_family = lcl.family; + } + addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen); + local_len = lcl.bytelen; } argv++; } - if (d == NULL) { - bb_error_msg(bb_msg_requires_arg, "\"dev\""); - return -1; + if (!d) { + /* There was no "dev IFACE", but we need that */ + bb_error_msg_and_die("need \"dev IFACE\""); } if (l && strncmp(d, l, strlen(d)) != 0) { bb_error_msg_and_die("\"dev\" (%s) must match \"label\" (%s)", d, l); @@ -759,25 +747,19 @@ static int ipaddr_modify(int cmd, char **argv) } /* Return value becomes exitcode. It's okay to not return at all */ -int do_ipaddr(char **argv) +int FAST_FUNC do_ipaddr(char **argv) { static const char commands[] ALIGN1 = "add\0""delete\0""list\0""show\0""lst\0""flush\0"; - - int command_num = 2; /* default command is list */ - + smalluint cmd = 2; if (*argv) { - command_num = index_in_substrings(commands, *argv); - if (command_num < 0 || command_num > 5) - bb_error_msg_and_die("unknown command %s", *argv); + cmd = index_in_substrings(commands, *argv); + if (cmd > 5) + bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); argv++; + if (cmd <= 1) + return ipaddr_modify((cmd == 0) ? RTM_NEWADDR : RTM_DELADDR, argv); } - if (command_num == 0) /* add */ - return ipaddr_modify(RTM_NEWADDR, argv); - if (command_num == 1) /* delete */ - return ipaddr_modify(RTM_DELADDR, argv); - if (command_num == 5) /* flush */ - return ipaddr_list_or_flush(argv, 1); /* 2 == list, 3 == show, 4 == lst */ - return ipaddr_list_or_flush(argv, 0); + return ipaddr_list_or_flush(argv, cmd == 5); }