summaryrefslogtreecommitdiff
path: root/procfs
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2022-09-20 03:01:59 +0000
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2022-09-20 22:36:37 +0000
commita64baf761265b4a09b058e146485c102b52a3449 (patch)
tree6b93777e0756fbb5e5bc1f6f6536ae8e5345d430 /procfs
parent9c7a1bc253ba4a264e8e3d6ae7983f2fc645f2b3 (diff)
procfs: Populate /proc/route with network routes
Diffstat (limited to 'procfs')
-rw-r--r--procfs/Makefile2
-rw-r--r--procfs/rootdir.c77
2 files changed, 78 insertions, 1 deletions
diff --git a/procfs/Makefile b/procfs/Makefile
index 13ee026c..d32328d2 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 0e7c05c0..bb49ce5f 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,12 @@
#include "procfs.h"
#include "procfs_dir.h"
#include "main.h"
+#include <net/route.h>
#include "mach_debug_U.h"
+#include "pfinet_U.h"
+
+#define ROUTE_STRLEN 180
/* This implements a directory node with the static files in /proc.
NB: the libps functions for host information return static storage;
@@ -408,6 +413,71 @@ 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[INET_ADDRSTRLEN], gw[INET_ADDRSTRLEN], mask[INET_ADDRSTRLEN];
+ char socket_inet[20];
+
+ char *inet_to_str(in_addr_t addr)
+ {
+ struct in_addr sin;
+
+ sin.s_addr = addr;
+ return inet_ntoa(sin);
+ }
+
+ snprintf(socket_inet, sizeof(socket_inet), _SERVERS_SOCKET "/%d", AF_INET);
+ pfinet = file_name_lookup (socket_inet, O_RDONLY, 0);
+ if (pfinet == MACH_PORT_NULL)
+ {
+ *contents_len = 0;
+ return errno;
+ }
+
+ err = pfinet_getroutes (pfinet, -1, &src, &buflen);
+ if (err)
+ {
+ *contents_len = 0;
+ goto out;
+ }
+
+ r = (ifrtreq_t *)src;
+ *contents_len = (buflen / sizeof(ifrtreq_t) + 1) * ROUTE_STRLEN;
+ *contents = calloc (1, *contents_len);
+ if (! *contents)
+ {
+ err = ENOMEM;
+ goto out;
+ }
+
+ dst = *contents;
+ snprintf(dst, ROUTE_STRLEN, "%-*s\n", ROUTE_STRLEN - 2, "Iface\tDestination\tGateway\t Flags\tRefCnt\tUse\tMetric\tMask\t\tMTU\tWindow\tIRTT");
+ dst += ROUTE_STRLEN;
+
+ for (i = 0; i < buflen / sizeof(ifrtreq_t); i++)
+ {
+ snprintf(dest, INET_ADDRSTRLEN, "%-*s", INET_ADDRSTRLEN - 1, inet_to_str(r->rt_dest));
+ snprintf(gw, INET_ADDRSTRLEN, "%-*s", INET_ADDRSTRLEN - 1, inet_to_str(r->rt_gateway));
+ snprintf(mask, INET_ADDRSTRLEN, "%-*s", INET_ADDRSTRLEN - 1, inet_to_str(r->rt_mask));
+
+ len = snprintf(dst, ROUTE_STRLEN, "%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;
@@ -781,6 +851,13 @@ static const struct procfs_dir_entry rootdir_entries[] = {
},
},
{
+ .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,
_HURD_MTAB "\0/"),