From b43d6d6f4617cf045ef1a5443568360df6cef328 Mon Sep 17 00:00:00 2001 From: Damien Zammit Date: Fri, 9 Sep 2022 09:42:48 +0000 Subject: Add new RPC for pfinet network routes Message-Id: <20220909094234.517165-1-damien@zamaudio.com> --- pfinet/pfinet-ops.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 87 insertions(+), 1 deletion(-) (limited to 'pfinet/pfinet-ops.c') diff --git a/pfinet/pfinet-ops.c b/pfinet/pfinet-ops.c index 5db66978..9722e0e3 100644 --- a/pfinet/pfinet-ops.c +++ b/pfinet/pfinet-ops.c @@ -22,6 +22,13 @@ #include #include +#include +#include +#include +#include +#include +#include +#include #include "pfinet_S.h" #include @@ -32,7 +39,8 @@ #include #include -#include + +#define MAX_ROUTES 255 extern int dev_ifconf(char *arg); @@ -91,3 +99,81 @@ S_pfinet_siocgifconf (io_t port, pthread_mutex_unlock (&global_lock); return err; } + +int +get_routing_table(int start, int count, ifrtreq_t *routes) +{ + struct fib_table *tb; + + if (!routes) + return 0; + + if ((tb = fib_get_table(RT_TABLE_MAIN)) == NULL) + return 0; + + return fn_hash_get_routes(tb, routes, start, count); +} + + +/* Return the routing table as a series of ifrtreq_t structs + in routes, but don't return more then AMOUNT number of them. + If AMOUNT is -1, we get the full table. */ +error_t +S_pfinet_getroutes (io_t port, + vm_size_t amount, + data_t *routes, + mach_msg_type_number_t *len, + boolean_t *dealloc_data) +{ + error_t err = 0; + ifrtreq_t rs[MAX_ROUTES]; + int n; + ifrtreq_t *rtable; + + pthread_mutex_lock (&global_lock); + + if (dealloc_data) + *dealloc_data = FALSE; + + if (amount == (vm_size_t) -1) + { + /* Get all of them, and return the number we got. */ + n = get_routing_table (0, MAX_ROUTES, rs); + amount = n; + } + else + n = amount; + + if (amount > 0) + { + /* Possibly allocate a new buffer. */ + if (*len < amount * sizeof(ifrtreq_t)) + { + rtable = (ifrtreq_t *) mmap (0, amount * sizeof(ifrtreq_t), PROT_READ|PROT_WRITE, + MAP_ANON, 0, 0); + if (dealloc_data) + *dealloc_data = TRUE; + } + else + rtable = (ifrtreq_t *)*routes; + + n = get_routing_table (0, n, rtable); + if (amount > n) + memset(&rtable[n], 0, (amount - n) * sizeof(ifrtreq_t)); + } + + if (rtable == MAP_FAILED) + { + /* Should use errno here, but glue headers #undef errno */ + err = ENOMEM; + *len = 0; + } + else + { + *len = n * sizeof(ifrtreq_t); + *routes = (char *)rtable; + } + + pthread_mutex_unlock (&global_lock); + return err; +} -- cgit v1.2.3