aboutsummaryrefslogtreecommitdiff
path: root/toys
diff options
context:
space:
mode:
Diffstat (limited to 'toys')
-rw-r--r--toys/pending/route.c167
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);
}
}