X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=networking%2Flibiproute%2Fiproute.c;h=f8a67d9eedc43f3ede19c506773ce20933b39f61;hb=04f296b28a4927efffced38170d92134982566a6;hp=c4b3450dd35a9c32d4063f4f7fa36a4166fe17c9;hpb=ffc4bced958e5746e736c9939c4d1de665e1cffa;p=oweals%2Fbusybox.git diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index c4b3450dd..f8a67d9ee 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c @@ -1,19 +1,16 @@ /* vi: set sw=4 ts=4: */ /* - * iproute.c "ip route". - * - * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. - * - * Authors: Alexey Kuznetsov, + * Licensed under GPLv2 or later, see file LICENSE in this source tree. * + * Authors: Alexey Kuznetsov, * * Changes: * - * Rani Assaf 980929: resolve addresses + * Rani Assaf 980929: resolve addresses * Kunihiro Ishiguro 001102: rtnh_ifindex was not initialized */ -#include "ip_common.h" /* #include "libbb.h" is inside */ +#include "ip_common.h" /* #include "libbb.h" is inside */ #include "rt_names.h" #include "utils.h" @@ -22,7 +19,7 @@ #endif -typedef struct filter_t { +struct filter_t { int tb; smallint flushed; char *flushb; @@ -34,8 +31,8 @@ typedef struct filter_t { //int type; - read-only //int typemask; - unused //int tos, tosmask; - unused - int iif, iifmask; - int oif, oifmask; + int iif; + int oif; //int realm, realmmask; - unused //inet_prefix rprefsrc; - read-only inet_prefix rvia; @@ -43,14 +40,15 @@ typedef struct filter_t { inet_prefix mdst; inet_prefix rsrc; inet_prefix msrc; -} filter_t; +} FIX_ALIASING; +typedef struct filter_t filter_t; #define G_filter (*(filter_t*)&bb_common_bufsiz1) 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; @@ -84,7 +82,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, { struct rtmsg *r = NLMSG_DATA(n); int len = n->nlmsg_len; - struct rtattr * tb[RTA_MAX+1]; + struct rtattr *tb[RTA_MAX+1]; char abuf[256]; inet_prefix dst; inet_prefix src; @@ -161,39 +159,68 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, } memset(tb, 0, sizeof(tb)); + memset(&src, 0, sizeof(src)); + memset(&dst, 0, sizeof(dst)); parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len); - if (G_filter.rdst.family && inet_addr_match(&dst, &G_filter.rdst, G_filter.rdst.bitlen)) + if (tb[RTA_SRC]) { + src.bitlen = r->rtm_src_len; + src.bytelen = (r->rtm_family == AF_INET6 ? 16 : 4); + memcpy(src.data, RTA_DATA(tb[RTA_SRC]), src.bytelen); + } + if (tb[RTA_DST]) { + dst.bitlen = r->rtm_dst_len; + dst.bytelen = (r->rtm_family == AF_INET6 ? 16 : 4); + memcpy(dst.data, RTA_DATA(tb[RTA_DST]), dst.bytelen); + } + + if (G_filter.rdst.family + && inet_addr_match(&dst, &G_filter.rdst, G_filter.rdst.bitlen) + ) { return 0; - if (G_filter.mdst.family && G_filter.mdst.bitlen >= 0 && - inet_addr_match(&dst, &G_filter.mdst, r->rtm_dst_len)) + } + if (G_filter.mdst.family + && G_filter.mdst.bitlen >= 0 + && inet_addr_match(&dst, &G_filter.mdst, r->rtm_dst_len) + ) { return 0; - - if (G_filter.rsrc.family && inet_addr_match(&src, &G_filter.rsrc, G_filter.rsrc.bitlen)) + } + if (G_filter.rsrc.family + && inet_addr_match(&src, &G_filter.rsrc, G_filter.rsrc.bitlen) + ) { return 0; + } if (G_filter.msrc.family && G_filter.msrc.bitlen >= 0 && inet_addr_match(&src, &G_filter.msrc, r->rtm_src_len) ) { return 0; } - - if (G_filter.flushb - && r->rtm_family == AF_INET6 - && r->rtm_dst_len == 0 - && r->rtm_type == RTN_UNREACHABLE - && tb[RTA_PRIORITY] - && *(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1 - ) { - return 0; + if (G_filter.oif != 0) { + if (!tb[RTA_OIF]) + return 0; + if (G_filter.oif != *(int*)RTA_DATA(tb[RTA_OIF])) + return 0; } if (G_filter.flushb) { struct nlmsghdr *fn; + + /* We are creating route flush commands */ + + if (r->rtm_family == AF_INET6 + && r->rtm_dst_len == 0 + && r->rtm_type == RTN_UNREACHABLE + && tb[RTA_PRIORITY] + && *(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1 + ) { + return 0; + } + if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > G_filter.flushe) { if (flush_update()) bb_error_msg_and_die("flush"); } - fn = (struct nlmsghdr*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp)); + fn = (void*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp)); memcpy(fn, n, n->nlmsg_len); fn->nlmsg_type = RTM_DELROUTE; fn->nlmsg_flags = NLM_F_REQUEST; @@ -203,6 +230,8 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, return 0; } + /* We are printing routes */ + if (n->nlmsg_type == RTM_DELROUTE) { printf("Deleted "); } @@ -252,10 +281,12 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, RTA_DATA(tb[RTA_GATEWAY]), abuf, sizeof(abuf))); } - if (tb[RTA_OIF] && G_filter.oifmask != -1) { + if (tb[RTA_OIF]) { printf("dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF]))); } + /* Todo: parse & show "proto kernel", "scope link" here */ + if (tb[RTA_PREFSRC] && /*G_filter.rprefsrc.bitlen - always 0*/ 0 != host_len) { /* Do not use format_host(). It is our local addr and symbolic name will not be useful. @@ -287,7 +318,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, printf(" error %d", ci->rta_error); } } - if (tb[RTA_IIF] && G_filter.iifmask != -1) { + if (tb[RTA_IIF] && G_filter.iif == 0) { printf(" iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF]))); } bb_putchar('\n'); @@ -319,9 +350,9 @@ IF_FEATURE_IP_RULE(ARG_table,) }; struct rtnl_handle rth; struct { - struct nlmsghdr n; - struct rtmsg r; - char buf[1024]; + struct nlmsghdr n; + struct rtmsg r; + char buf[1024]; } req; char mxbuf[256]; struct rtattr * mxrta = (void*)mxbuf; @@ -408,7 +439,8 @@ IF_FEATURE_IP_RULE(ARG_table,) NEXT_ARG(); } if ((**argv < '0' || **argv > '9') - && rtnl_rtntype_a2n(&type, *argv) == 0) { + && rtnl_rtntype_a2n(&type, *argv) == 0 + ) { NEXT_ARG(); req.r.rtm_type = type; ok |= type_ok; @@ -657,12 +689,10 @@ static int iproute_list_or_flush(char **argv, int flush) if (id) { idx = xll_name_to_index(id); G_filter.iif = idx; - G_filter.iifmask = -1; } if (od) { idx = xll_name_to_index(od); G_filter.oif = idx; - G_filter.oifmask = -1; } } @@ -783,8 +813,8 @@ static int iproute_get(char **argv) } req.r.rtm_dst_len = addr.bitlen; } - argv++; } + argv++; } if (req.r.rtm_dst_len == 0) { @@ -838,7 +868,7 @@ static int iproute_get(char **argv) tb[RTA_PREFSRC]->rta_type = RTA_SRC; r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]); } else if (!tb[RTA_SRC]) { - bb_error_msg_and_die("failed to connect the route"); + bb_error_msg_and_die("can't connect the route"); } if (!odev && tb[RTA_OIF]) { tb[RTA_OIF]->rta_type = 0; @@ -861,7 +891,7 @@ static int iproute_get(char **argv) } /* Return value becomes exitcode. It's okay to not return at all */ -int do_iproute(char **argv) +int FAST_FUNC do_iproute(char **argv) { static const char ip_route_commands[] ALIGN1 = /*0-3*/ "add\0""append\0""change\0""chg\0"