diff options
Diffstat (limited to 'toys')
-rw-r--r-- | toys/pending/route.c | 167 |
1 files changed, 60 insertions, 107 deletions
diff --git a/toys/pending/route.c b/toys/pending/route.c index a7e88246..36089ae3 100644 --- a/toys/pending/route.c +++ b/toys/pending/route.c @@ -19,16 +19,12 @@ config ROUTE help usage: route [-ne] [-A [inet|inet6]] [add|del TARGET [OPTIONS]] - Display, add or delete network routes in the "Forwarding Information Base". + Display, add or delete network routes in the "Forwarding Information Base", + which send packets out a network interface to an address. -n Show numerical addresses (no DNS lookups) -e display netstat fields - Routing means sending packets out a network interface to an address. - The kernel can tell where to send packets one hop away by examining each - interface's address and netmask, so the most common use of this command - is to identify a "gateway" that forwards other traffic. - Assigning an address to an interface automatically creates an appropriate network route ("ifconfig eth0 10.0.2.15/8" does "route add 10.0.0.0/8 eth0" for you), although some devices (such as loopback) won't show it in the @@ -40,10 +36,9 @@ config ROUTE Available OPTIONS include: reject - blocking route (force match failure) - dev NAME - force packets out this interface (ala "eth0") + dev NAME - force matching packets out this interface (ala "eth0") netmask - old way of saying things like ADDR/24 gw ADDR - forward packets to gateway ADDR - */ #define FOR_route @@ -52,7 +47,7 @@ config ROUTE #include <linux/rtnetlink.h> GLOBALS( - char *family; + char *A; ) struct _arglist { @@ -112,7 +107,7 @@ static void display_routes(sa_family_t f) struct nlmsghdr buf[8192 / sizeof(struct nlmsghdr)]; struct nlmsghdr *msg_hdr_ptr; struct rtmsg *route_entry; - struct rtattr *route_attribute; + struct rtattr *rteattr; fd = xsocket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); @@ -129,7 +124,7 @@ static void display_routes(sa_family_t f) if (f == AF_INET) { xprintf("Kernel IP routing table\n" "Destination Gateway Genmask Flags %s Iface\n", - (toys.optflags & FLAG_e) ? " MSS Window irtt" : "Metric Ref Use"); + FLAG(e) ? " MSS Window irtt" : "Metric Ref Use"); } else { xprintf("Kernel IPv6 routing table\n" "%-31s%-26s Flag Metric Ref Use If\n", "Destination", "Next Hop"); @@ -146,28 +141,18 @@ static void display_routes(sa_family_t f) // RT_TABLE_MAIN with RTM_GETROUTE it still returns everything so we // have to filter here. if (route_entry->rtm_table == RT_TABLE_MAIN) { + int route_attribute_len; + char dest[INET6_ADDRSTRLEN], gate[INET6_ADDRSTRLEN], netmask[32], + flags[10] = "U", if_name[IF_NAMESIZE] = "-"; + unsigned priority = 0, mss = 0, win = 0, irtt = 0, ref = 0, use = 0, + route_netmask, metric_len; struct in_addr netmask_addr; - char dest[INET6_ADDRSTRLEN]; - char gate[INET6_ADDRSTRLEN]; - char netmask[32]; - char flags[10] = "U"; - uint32_t priority = 0; - uint32_t mss = 0; - uint32_t win = 0; - uint32_t irtt = 0; - uint32_t ref = 0; - uint32_t use = 0; - char if_name[IF_NAMESIZE] = "-"; - uint32_t route_netmask; struct rtattr *metric; - uint32_t metric_len; struct rta_cacheinfo *cache_info; if (f == AF_INET) { - if (!(toys.optflags & FLAG_n)) strcpy(dest, "default"); - else strcpy(dest, "0.0.0.0"); - if (!(toys.optflags & FLAG_n)) strcpy(gate, "*"); - else strcpy(gate, "0.0.0.0"); + strcpy(dest, FLAG(n) ? "0.0.0.0" : "default"); + strcpy(gate, FLAG(n) ? "*" : "0.0.0.0"); strcpy(netmask, "0.0.0.0"); } else { strcpy(dest, "::"); @@ -175,65 +160,53 @@ static void display_routes(sa_family_t f) } route_netmask = route_entry->rtm_dst_len; - if (route_netmask == 0) { - netmask_addr.s_addr = ~((in_addr_t) -1); - } else { - netmask_addr.s_addr = htonl(~((1 << (32 - route_netmask)) - 1)); - } + if (route_netmask == 0) netmask_addr.s_addr = ~((in_addr_t) -1); + else netmask_addr.s_addr = htonl(~((1 << (32 - route_netmask)) - 1)); inet_ntop(AF_INET, &netmask_addr, netmask, sizeof(netmask)); - route_attribute = RTM_RTA(route_entry); - int route_attribute_len = RTM_PAYLOAD(msg_hdr_ptr); - while (RTA_OK(route_attribute, route_attribute_len)) { - switch (route_attribute->rta_type) { + rteattr = RTM_RTA(route_entry); + route_attribute_len = RTM_PAYLOAD(msg_hdr_ptr); + while (RTA_OK(rteattr, route_attribute_len)) { + switch (rteattr->rta_type) { case RTA_DST: - if (toys.optflags & FLAG_n) { - inet_ntop(f, RTA_DATA(route_attribute), dest, sizeof(dest)); - } else { - get_hostname(f, RTA_DATA(route_attribute), dest, sizeof(dest)); - } + if (FLAG(n)) inet_ntop(f, RTA_DATA(rteattr), dest, sizeof(dest)); + else get_hostname(f, RTA_DATA(rteattr), dest, sizeof(dest)); break; case RTA_GATEWAY: - if (toys.optflags & FLAG_n) { - inet_ntop(f, RTA_DATA(route_attribute), gate, sizeof(dest)); - } else { - get_hostname(f, RTA_DATA(route_attribute), gate, sizeof(dest)); - } + if (FLAG(n)) inet_ntop(f, RTA_DATA(rteattr), gate, sizeof(dest)); + else get_hostname(f, RTA_DATA(rteattr), gate, sizeof(dest)); strcat(flags, "G"); break; case RTA_PRIORITY: - priority = *(uint32_t *) RTA_DATA(route_attribute); + priority = *(unsigned *)RTA_DATA(rteattr); break; case RTA_OIF: - if_indextoname(*((int *) RTA_DATA(route_attribute)), if_name); + if_indextoname(*(int *)RTA_DATA(rteattr), if_name); break; case RTA_METRICS: - metric_len = RTA_PAYLOAD(route_attribute); - for (metric = RTA_DATA(route_attribute); - RTA_OK(metric, metric_len); - metric=RTA_NEXT(metric, metric_len)) { - if (metric->rta_type == RTAX_ADVMSS) { - mss = *(uint32_t *) RTA_DATA(metric); - } else if (metric->rta_type == RTAX_WINDOW) { - win = *(uint32_t *) RTA_DATA(metric); - } else if (metric->rta_type == RTAX_RTT) { - irtt = (*(uint32_t *) RTA_DATA(metric)) / 8; - } - } + metric_len = RTA_PAYLOAD(rteattr); + for (metric = RTA_DATA(rteattr); RTA_OK(metric, metric_len); + metric = RTA_NEXT(metric, metric_len)) + if (metric->rta_type == RTAX_ADVMSS) + mss = *(unsigned *)RTA_DATA(metric); + else if (metric->rta_type == RTAX_WINDOW) + win = *(unsigned *)RTA_DATA(metric); + else if (metric->rta_type == RTAX_RTT) + irtt = (*(unsigned *)RTA_DATA(metric))/8; break; case RTA_CACHEINFO: - cache_info = RTA_DATA(route_attribute); + cache_info = RTA_DATA(rteattr); ref = cache_info->rta_clntref; use = cache_info->rta_used; break; } - route_attribute = RTA_NEXT(route_attribute, route_attribute_len); + rteattr = RTA_NEXT(rteattr, route_attribute_len); } if (route_entry->rtm_type == RTN_UNREACHABLE) flags[0] = '!'; @@ -242,9 +215,8 @@ static void display_routes(sa_family_t f) if (f == AF_INET) { xprintf("%-15.15s %-15.15s %-16s%-6s", dest, gate, netmask, flags); - if (toys.optflags & FLAG_e) { - xprintf("%5d %-5d %6d %s\n", mss, win, irtt, if_name); - } else xprintf("%-6d %-2d %7d %s\n", priority, ref, use, if_name); + if (FLAG(e)) xprintf("%5d %-5d %6d %s\n", mss, win, irtt, if_name); + else xprintf("%-6d %-2d %7d %s\n", priority, ref, use, if_name); } else { char *dest_with_mask = xmprintf("%s/%u", dest, route_netmask); xprintf("%-30s %-26s %-4s %-6d %-4d %2d %-8s\n", @@ -262,10 +234,7 @@ static void display_routes(sa_family_t f) xclose(fd); } -/* - * find the given parameter in list like add/del/net/host. - * and if match found return the appropriate action. - */ +// find parameter (add/del/net/host) in list, return appropriate action or 0. static int get_action(char ***argv, struct _arglist *list) { struct _arglist *alist; @@ -283,7 +252,7 @@ static int get_action(char ***argv, struct _arglist *list) // add/del a route. static void setroute(sa_family_t f, char **argv) { - char *targetip; + char *tgtip; int sockfd, arg2_action; int action = get_action(&argv, arglist1); //verify the arg for add/del. struct nlmsghdr buf[8192 / sizeof(struct nlmsghdr)]; @@ -293,7 +262,7 @@ static void setroute(sa_family_t f, char **argv) if (!action || !*argv) help_exit("setroute"); arg2_action = get_action(&argv, arglist2); //verify the arg for -net or -host if (!*argv) help_exit("setroute"); - targetip = *argv++; + tgtip = *argv++; sockfd = xsocket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); memset(buf, 0, sizeof(buf)); nlMsg = (struct nlmsghdr *) buf; @@ -317,32 +286,20 @@ static void setroute(sa_family_t f, char **argv) rtMsg->rtm_type = RTN_UNICAST; rtMsg->rtm_protocol = RTPROT_UNSPEC; rtMsg->rtm_flags = RTM_F_NOTIFY; - if (f == AF_INET) { - rtMsg->rtm_dst_len = 32; - rtMsg->rtm_src_len = 32; - } else { - rtMsg->rtm_dst_len = 128; - rtMsg->rtm_src_len = 128; - } + rtMsg->rtm_dst_len = rtMsg->rtm_src_len = (f == AF_INET) ? 32 : 128; - if (arg2_action == 2) { - rtMsg->rtm_scope = RT_SCOPE_HOST; - } + if (arg2_action == 2) rtMsg->rtm_scope = RT_SCOPE_HOST; size_t addr_len = sizeof(struct in_addr); if (f == AF_INET6) addr_len = sizeof(struct in6_addr); unsigned char addr[sizeof(struct in6_addr)] = {0,}; for (; *argv; argv++) { - if (!strcmp(*argv, "mod")) { - continue; - } else if (!strcmp(*argv, "dyn")) { - continue; - } else if (!strcmp(*argv, "reinstate")) { - continue; - } else if (!strcmp(*argv, "reject")) { - rtMsg->rtm_type = RTN_UNREACHABLE; - } else { + if (!strcmp(*argv, "mod")) continue; + else if (!strcmp(*argv, "dyn")) continue; + else if (!strcmp(*argv, "reinstate")) continue; + else if (!strcmp(*argv, "reject")) rtMsg->rtm_type = RTN_UNREACHABLE; + else { if (!argv[1]) show_help(stdout, 1); if (!strcmp(*argv, "metric")) { @@ -394,17 +351,13 @@ static void setroute(sa_family_t f, char **argv) } } - if (strcmp(targetip, "default") != 0) { - char *ptr; - char *dst = strtok(targetip, "/"); - char *prefix = strtok(NULL, "/"); + if (strcmp(tgtip, "default") != 0) { + char *prefix = strtok(0, "/"); - if (prefix) rtMsg->rtm_dst_len = strtoul(prefix, &ptr, 0); - if (!inet_pton(f, dst, &addr)) error_exit("invalid target"); + if (prefix) rtMsg->rtm_dst_len = strtoul(prefix, &prefix, 0); + if (!inet_pton(f, strtok(tgtip, "/"), &addr)) error_exit("invalid target"); addAttr(nlMsg, sizeof(toybuf), &addr, RTA_DST, addr_len); - } else { - rtMsg->rtm_dst_len = 0; - } + } else rtMsg->rtm_dst_len = 0; xsend(sockfd, nlMsg, nlMsg->nlmsg_len); xclose(sockfd); @@ -413,18 +366,18 @@ static void setroute(sa_family_t f, char **argv) void route_main(void) { if (!*toys.optargs) { - if ( (!TT.family) || (!strcmp(TT.family, "inet")) ) display_routes(AF_INET); - else if (!strcmp(TT.family, "inet6")) display_routes(AF_INET6); + if (!TT.A || !strcmp(TT.A, "inet")) display_routes(AF_INET); + else if (!strcmp(TT.A, "inet6")) display_routes(AF_INET6); else show_help(stdout, 1); } else { - if (!TT.family) { - if ( (toys.optc > 1) && (strchr(toys.optargs[1], ':')) ) { + if (!TT.A) { + if (toys.optc>1 && strchr(toys.optargs[1], ':')) { xprintf("WARNING: Implicit IPV6 address using -Ainet6\n"); - TT.family = "inet6"; - } else TT.family = "inet"; + TT.A = "inet6"; + } else TT.A = "inet"; } - if (!strcmp(TT.family, "inet")) setroute(AF_INET, toys.optargs); + if (!strcmp(TT.A, "inet")) setroute(AF_INET, toys.optargs); else setroute(AF_INET6, toys.optargs); } } |