aboutsummaryrefslogtreecommitdiff
path: root/toys
diff options
context:
space:
mode:
Diffstat (limited to 'toys')
-rw-r--r--toys/pending/route.c141
1 files changed, 51 insertions, 90 deletions
diff --git a/toys/pending/route.c b/toys/pending/route.c
index 4c673172..e7de50bd 100644
--- a/toys/pending/route.c
+++ b/toys/pending/route.c
@@ -145,20 +145,7 @@ static int get_addrinfo(char *ip, struct sockaddr_in6 *sock_in6)
return 0;
}
-static void get_flag_value(char *str, int flags)
-{
- // RTF_* bits in order:
- // UP, GATEWAY, HOST, REINSTATE, DYNAMIC, MODIFIED, DEFAULT, ADDRCONF, CACHE
- int i = 0, mask = 0x105003f;
-
- for (; mask; mask>>=1) if (mask&1) {
- if (flags&(1<<i)) *str++ = "UGHRDMDAC"[i];
- i++;
- }
- *str = 0;
-}
-
-static void display_routes(void)
+static void display_routes(sa_family_t family)
{
int fd, msg_hdr_len, route_protocol;
struct nlmsghdr buf[8192 / sizeof(struct nlmsghdr)];
@@ -171,14 +158,19 @@ static void display_routes(void)
fd = xsocket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
memset(&req, 0, sizeof(req));
- req.rtm_family = AF_INET;
+ req.rtm_family = family;
req.rtm_table = RT_TABLE_MAIN;
send_nlrtmsg(fd, RTM_GETROUTE, NLM_F_REQUEST | NLM_F_DUMP, &req);
- xprintf("Kernel IP routing table\n"
- "Destination Gateway Genmask Flags %s Iface\n",
- (toys.optflags & FLAG_e)? " MSS Window irtt" : "Metric Ref Use");
+ if (family == 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");
+ } else {
+ xprintf("Kernel IPv6 routing table\n"
+ "%-31s%-26s Flag Met Ref Use If\n", "Destination", "Next Hop");
+ }
msg_hdr_len = xrecv(fd, buf, sizeof(buf));
msg_hdr_ptr = (struct nlmsghdr *) buf;
@@ -192,21 +184,30 @@ static void display_routes(void)
// have to filter here.
if (route_entry->rtm_table == RT_TABLE_MAIN) {
struct in_addr netmask_addr;
- char destip[32] = "0.0.0.0";
- char gateip[32] = "0.0.0.0";
- char netmask[32] = "0.0.0.0";
+ char destip[INET6_ADDRSTRLEN];
+ char gateip[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 refcount = 0; //todo(emolitor): implement
char if_name[IF_NAMESIZE] = "-";
uint32_t route_netmask;
struct rtattr *metric;
uint32_t metric_len;
- if (!(toys.optflags & FLAG_n)) strcpy(destip, "default");
- if (!(toys.optflags & FLAG_n)) strcpy(gateip, "*");
+ if (family == AF_INET) {
+ if (!(toys.optflags & FLAG_n)) strcpy(destip, "default");
+ else strcpy(destip, "0.0.0.0");
+ if (!(toys.optflags & FLAG_n)) strcpy(gateip, "*");
+ else strcpy(gateip, "0.0.0.0");
+ strcpy(netmask, "0.0.0.0");
+ } else {
+ strcpy(destip, "::");
+ strcpy(gateip, "::");
+ }
route_netmask = route_entry->rtm_dst_len;
if (route_netmask == 0) {
@@ -221,11 +222,11 @@ static void display_routes(void)
while (RTA_OK(route_attribute, route_attribute_len)) {
switch (route_attribute->rta_type) {
case RTA_DST:
- inet_ntop(AF_INET, RTA_DATA(route_attribute), destip, 24);
+ inet_ntop(family, RTA_DATA(route_attribute), destip, INET6_ADDRSTRLEN);
break;
case RTA_GATEWAY:
- inet_ntop(AF_INET, RTA_DATA(route_attribute), gateip, 24);
+ inet_ntop(family, RTA_DATA(route_attribute), gateip, INET6_ADDRSTRLEN);
strcat(flags, "G");
break;
@@ -248,9 +249,19 @@ static void display_routes(void)
win = *(uint32_t *) RTA_DATA(metric);
} else if (metric->rta_type == RTAX_RTT) {
irtt = (*(uint32_t *) RTA_DATA(metric)) / 8;
+ } else {
+ printf("Unknown metric->rta_type %u\n", metric->rta_type);
}
}
break;
+
+ case RTA_CACHEINFO:
+ // todo(emolitor): implement for AF_INET6
+ break;
+
+ case RTA_PREF:
+ // todo(emolitor): implement for AF_INET6
+ break;
}
route_attribute = RTA_NEXT(route_attribute, route_attribute_len);
@@ -261,12 +272,19 @@ static void display_routes(void)
if (route_netmask == 32) strcat(flags, "H");
if (route_protocol == RTPROT_REDIRECT) strcat(flags, "D");
- // Ref is not used by the kernel so hard coding to 0
- // IPv4 caching is disabled so hard coding Use to 0
- xprintf("%-15.15s %-15.15s %-16s%-6s", destip, gateip, 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, 0, 0, if_name);
+ if (family == AF_INET) {
+ // Ref is not used by the kernel so hard coding to 0
+ // IPv4 caching is disabled so hard coding Use to 0
+ xprintf("%-15.15s %-15.15s %-16s%-6s", destip, gateip, 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, refcount, 0, if_name);
+ } else {;
+ char dest_with_mask[INET6_ADDRSTRLEN + 4];
+ snprintf(dest_with_mask, INET6_ADDRSTRLEN + 4, "%s/%u", destip, route_netmask);
+ xprintf("%-30s %-26s %-4s %-3d %-4d %2d %-8s\n",
+ dest_with_mask, gateip, flags, priority, refcount, 0, if_name);
+ }
}
msg_hdr_ptr = NLMSG_NEXT(msg_hdr_ptr, msg_hdr_len);
}
@@ -495,69 +513,12 @@ static void setroute_inet6(char **argv)
xclose(sockfd);
}
-/*
- * format the dest and src address in ipv6 format.
- * e.g. 2002:6b6d:26c8:d:ea03:9aff:fe65:9d62
- */
-static void ipv6_addr_formating(char *ptr, char *addr)
-{
- int i = 0;
- while (i <= IPV6_ADDR_LEN) {
- if (!*ptr) {
- if (i == IPV6_ADDR_LEN) {
- addr[IPV6_ADDR_LEN - 1] = 0; //NULL terminating the ':' separated address.
- break;
- }
- error_exit("IPv6 ip format error");
- }
- addr[i++] = *ptr++;
- if (!((i+1) % 5)) addr[i++] = ':'; //put ':' after 4th bit
- }
-}
-
-static void display_routes6(void)
-{
- char iface[16] = {0,}, ipv6_dest_addr[41];
- char ipv6_src_addr[41], flag_val[10], buf2[INET6_ADDRSTRLEN];
- int prefixlen, metric, use, refcount, flag, items = 0;
- unsigned char buf[sizeof(struct in6_addr)];
-
- FILE *fp = xfopen("/proc/net/ipv6_route", "r");
-
- xprintf("Kernel IPv6 routing table\n"
- "%-43s%-40s Flags Metric Ref Use Iface\n", "Destination", "Next Hop");
-
- while ((items = fscanf(fp, "%32s%x%*s%*x%32s%x%x%x%x%15s\n", ipv6_dest_addr+8,
- &prefixlen, ipv6_src_addr+8, &metric, &use, &refcount, &flag,
- iface)) == 8)
- {
- if (!(flag & RTF_UP)) continue; //skip down interfaces.
-
- //ipv6_dest_addr+8: as the values are filled from the 8th location of the array.
- ipv6_addr_formating(ipv6_dest_addr+8, ipv6_dest_addr);
- ipv6_addr_formating(ipv6_src_addr+8, ipv6_src_addr);
-
- get_flag_value(flag_val, flag);
- if (inet_pton(AF_INET6, ipv6_dest_addr, buf) <= 0) perror_exit("inet");
- if (inet_ntop(AF_INET6, buf, buf2, INET6_ADDRSTRLEN))
- sprintf(toybuf, "%s/%d", buf2, prefixlen);
-
- if (inet_pton(AF_INET6, ipv6_src_addr, buf) <= 0) perror_exit("inet");
- if (inet_ntop(AF_INET6, buf, buf2, INET6_ADDRSTRLEN))
- xprintf("%-43s %-39s %-5s %-6d %-4d %5d %-8s\n",
- toybuf, buf2, flag_val, metric, refcount, use, iface);
- }
- if ((items > 0) && feof(fp)) perror_exit("fscanf");
-
- fclose(fp);
-}
-
void route_main(void)
{
if (!TT.family) TT.family = "inet";
if (!*toys.optargs) {
- if (!strcmp(TT.family, "inet")) display_routes();
- else if (!strcmp(TT.family, "inet6")) display_routes6();
+ if (!strcmp(TT.family, "inet")) display_routes(AF_INET);
+ else if (!strcmp(TT.family, "inet6")) display_routes(AF_INET6);
else help_exit(0);
} else {
if (!strcmp(TT.family, "inet6")) setroute_inet6(toys.optargs);