This exposes network routing table on /proc/route --- procfs/Makefile | 2 +- procfs/rootdir.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-)
diff --git a/procfs/Makefile b/procfs/Makefile index 13ee026c4..d32328d28 100644 --- a/procfs/Makefile +++ b/procfs/Makefile @@ -21,7 +21,7 @@ makemode := server target = procfs -SRCS = procfs.c netfs.c procfs_dir.c process.c proclist.c rootdir.c dircat.c main.c mach_debugUser.c default_pagerUser.c +SRCS = procfs.c netfs.c procfs_dir.c process.c proclist.c rootdir.c dircat.c main.c mach_debugUser.c default_pagerUser.c pfinetUser.c LCLHDRS = dircat.h main.h process.h procfs.h procfs_dir.h proclist.h rootdir.h OBJS = $(SRCS:.c=.o) diff --git a/procfs/rootdir.c b/procfs/rootdir.c index 0e7c05c00..deddaa43f 100644 --- a/procfs/rootdir.c +++ b/procfs/rootdir.c @@ -25,6 +25,7 @@ #include <mach/default_pager.h> #include <mach_debug/mach_debug_types.h> #include <hurd/paths.h> +#include <arpa/inet.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> @@ -37,8 +38,10 @@ #include "procfs.h" #include "procfs_dir.h" #include "main.h" +#include <net/route.h> #include "mach_debug_U.h" +#include "pfinet_U.h" /* This implements a directory node with the static files in /proc. NB: the libps functions for host information return static storage; @@ -408,6 +411,70 @@ out: return err; } +static error_t +rootdir_gc_route (void *hook, char **contents, ssize_t *contents_len) +{ + error_t err; + mach_port_t pfinet; + unsigned int i, len, buflen = 0; + char *src, *dst; + ifrtreq_t *r; + char dest[16], gw[16], mask[16]; + + char *inet_to_str(in_addr_t addr) + { + struct in_addr sin; + + sin.s_addr = addr; + return inet_ntoa(sin); + } + + pfinet = file_name_lookup (_SERVERS_SOCKET "/2", O_RDONLY, 0); + if (pfinet == MACH_PORT_NULL) + { + *contents_len = 0; + err = errno; + goto out; + } + + err = pfinet_getroutes (pfinet, -1, &src, &buflen); + if (err) + { + *contents_len = 0; + goto out; + } + + r = (ifrtreq_t *)src; + *contents_len = buflen / sizeof(ifrtreq_t) * 200 + 128; + *contents = calloc (1, *contents_len); + if (! *contents) + { + err = ENOMEM; + goto out; + } + + dst = *contents; + sprintf(dst, "%-127s\n", "Iface\tDestination\tGateway\t Flags\tRefCnt\tUse\tMetric\tMask\t\tMTU\tWindow\tIRTT"); + dst += 128; + + for (i = 0; i < buflen / sizeof(ifrtreq_t); i++) + { + sprintf(dest, "%-15s", inet_to_str(r->rt_dest)); + sprintf(gw, "%-15s", inet_to_str(r->rt_gateway)); + sprintf(mask, "%-15s", inet_to_str(r->rt_mask)); + + len = sprintf(dst, "%s\t%s\t%s\t%04X\t%d\t%u\t%d\t%s\t%d\t%u\t%u\n", + r->ifname, dest, gw, r->rt_flags, 0, 0, + r->rt_metric, mask, r->rt_mtu, r->rt_window, r->rt_irtt); + dst += len; + r++; + } + +out: + mach_port_deallocate (mach_task_self (), pfinet); + return err; +} + static struct node *rootdir_self_node; static struct node *rootdir_mounts_node; @@ -780,6 +847,13 @@ static const struct procfs_dir_entry rootdir_entries[] = { .cleanup_contents = procfs_cleanup_contents_with_free, }, }, + { + .name = "route", + .hook = & (struct procfs_node_ops) { + .get_contents = rootdir_gc_route, + .cleanup_contents = procfs_cleanup_contents_with_free, + }, + }, { .name = "mounts", .hook = ROOTDIR_DEFINE_TRANSLATED_NODE (&rootdir_mounts_node, -- 2.34.1