summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libnetworking/rtems/rtems_showroute.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libnetworking/rtems/rtems_showroute.c')
-rw-r--r--c/src/lib/libnetworking/rtems/rtems_showroute.c159
1 files changed, 159 insertions, 0 deletions
diff --git a/c/src/lib/libnetworking/rtems/rtems_showroute.c b/c/src/lib/libnetworking/rtems/rtems_showroute.c
new file mode 100644
index 0000000000..8695680d5e
--- /dev/null
+++ b/c/src/lib/libnetworking/rtems/rtems_showroute.c
@@ -0,0 +1,159 @@
+#include <sys/param.h>
+#include <sys/queue.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/sysctl.h>
+#include <sys/proc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/domain.h>
+
+#include <net/if.h>
+#include <net/route.h>
+
+#include <netinet/in.h>
+
+/*
+ * We'll use the application versions of malloc and free.
+ */
+#undef malloc
+#undef free
+/*
+ * Information per route
+ */
+struct rinfo {
+ struct in_addr dst;
+ struct in_addr gw_mask;
+ unsigned long pksent;
+ unsigned long expire;
+ int flags;
+ char ifname[16];
+ short ifunit;
+ short refcnt;
+};
+
+/*
+ * Information per display
+ */
+struct dinfo {
+ int capacity;
+ int count;
+ struct rinfo *routes;
+};
+
+/*
+ * Package everything up before printing it.
+ * We don't want to block all network operations till
+ * the printing completes!
+ */
+static int
+show_inet_route (rn, vw)
+ struct radix_node *rn;
+ void *vw;
+{
+ struct rtentry *rt = (struct rtentry *)rn;
+ struct ifnet *ifp;
+ struct dinfo *dp = (struct dinfo *)vw;
+ struct rinfo *r;
+
+ /*
+ * Get a pointer to a new route info structure
+ */
+ if (dp->count >= dp->capacity) {
+ r = realloc (dp->routes, (sizeof *r) * (dp->capacity + 20));
+ if (r == 0)
+ return ENOMEM;
+ dp->capacity += 20;
+ dp->routes = r;
+ }
+ r = dp->routes + dp->count++;
+
+ /*
+ * Fill in the route info structure
+ */
+ r->dst = ((struct sockaddr_in *)rt_key(rt))->sin_addr;
+ if (rt->rt_flags & RTF_GATEWAY)
+ r->gw_mask = ((struct sockaddr_in *)rt->rt_gateway)->sin_addr;
+ else if (!(rt->rt_flags & RTF_HOST))
+ r->gw_mask = ((struct sockaddr_in *)rt_mask(rt))->sin_addr;
+ r->flags = rt->rt_flags;
+ r->refcnt = rt->rt_refcnt;
+ r->pksent = rt->rt_rmx.rmx_pksent;
+ r->expire = rt->rt_rmx.rmx_expire;
+ ifp = rt->rt_ifp;
+ strncpy (r->ifname, ifp->if_name, sizeof r->ifname);
+ r->ifunit = ifp->if_unit;
+ return 0;
+}
+
+/*
+ * Reentrant version of inet_ntoa
+ */
+char *
+inet_ntoa_r (struct in_addr ina, char *buf)
+{
+ unsigned char *ucp = (unsigned char *)&ina;
+
+ sprintf (buf, "%d.%d.%d.%d",
+ ucp[0] & 0xff,
+ ucp[1] & 0xff,
+ ucp[2] & 0xff,
+ ucp[3] & 0xff);
+ return buf;
+}
+
+void
+rtems_bsdnet_show_inet_routes (void)
+{
+ struct radix_node_head *rnh;
+ struct dinfo d;
+ struct rinfo *r;
+ int i, error;
+
+ rnh = rt_tables[AF_INET];
+ if (!rnh)
+ return;
+ d.count = d.capacity = 0;
+ d.routes = NULL;
+ rtems_bsdnet_semaphore_obtain ();
+ error = rnh->rnh_walktree(rnh, show_inet_route, &d);
+ rtems_bsdnet_semaphore_release ();
+ if (error) {
+ printf ("Can't get route info: %s\n", strerror (error));
+ return;
+ }
+ if (d.count == 0) {
+ printf ("No routes!\n");
+ return;
+ }
+ printf ("Destination Gateway/Mask Flags Refs Use Expire Interface\n");
+ for (i = 0, r = d.routes ; i < d.count ; i++, r++) {
+ char buf[30];
+ char *cp, *fc, flagbuf[10];
+ unsigned long flagbit;
+
+ if (r->dst.s_addr == INADDR_ANY)
+ cp = "default";
+ else
+ cp = inet_ntoa_r (r->dst, buf);
+ printf ("%-16s", cp);
+ if (!(r->flags & RTF_HOST))
+ cp = inet_ntoa_r (r->gw_mask, buf);
+ else
+ cp = "";
+ printf ("%-16s", cp);
+ fc = "UGHRDM XLS";
+ for (flagbit = 0x1, cp = flagbuf ; *fc ; flagbit <<= 1, fc++) {
+ if ((r->flags & flagbit) && (*fc != ' '))
+ *cp++ = *fc;
+ }
+ *cp = '\0';
+ printf ("%-10s%3d%9ld%7ld %.*s%d\n", flagbuf,
+ r->refcnt, r->pksent,
+ r->expire,
+ (int)sizeof r->ifname, r->ifname,
+ r->ifunit);
+ }
+ free (d.routes);
+}