changeset 446:bb9dadc169ef

Add function to dump/display network interface and routing tables.
author gthomas
date Tue, 03 Dec 2002 17:22:45 +0000
parents 4bfb0d444b05
children 44f818173f96
files packages/net/bsd_tcpip/current/ChangeLog packages/net/bsd_tcpip/current/src/ecos/support.c packages/net/tcpip/current/ChangeLog packages/net/tcpip/current/src/ecos/support.c
diffstat 4 files changed, 259 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/packages/net/bsd_tcpip/current/ChangeLog
+++ b/packages/net/bsd_tcpip/current/ChangeLog
@@ -1,3 +1,8 @@
+2002-12-03  Gary Thomas  <gthomas@ecoscentric.com>
+
+	* src/ecos/support.c (show_network_tables): New function to
+	print information about network tables (interfaces, routing).
+
 2002-11-12  Gary Thomas  <gary@mlbassoc.com>
 
 	* src/ecos/timeout.c (callout_reset): Check for finding the
--- a/packages/net/bsd_tcpip/current/src/ecos/support.c
+++ b/packages/net/bsd_tcpip/current/src/ecos/support.c
@@ -14,6 +14,7 @@
 // Portions created by Red Hat are
 // Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
 //
+// Copyright (C) 2002 Gary Thomas
 // -------------------------------------------
 //
 //####BSDCOPYRIGHTEND####
@@ -817,6 +818,130 @@ cyg_net_init(void)
     _init = true;
 }
 
+
+#include <net/if.h>
+#include <net/netdb.h>
+#include <net/route.h>
+externC void if_indextoname(int indx, char *buf, int len);
+
+typedef void pr_fun(char *fmt, ...);
+
+static void
+_mask(struct sockaddr *sa, char *buf, int _len)
+{
+    char *cp = ((char *)sa) + 4;
+    int len = sa->sa_len - 4;
+    int tot = 0;
+
+    while (len-- > 0) {
+        if (tot) *buf++ = '.';
+        buf += diag_sprintf(buf, "%d", *cp++);
+        tot++;
+    }
+
+    while (tot < 4) {
+        if (tot) *buf++ = '.';
+        buf += diag_sprintf(buf, "%d", 0);
+        tot++;
+    }
+}
+
+static void
+_show_ifp(struct ifnet *ifp, pr_fun *pr)
+{
+    struct ifaddr *ifa;
+    char name[64], addr[64], netmask[64], broadcast[64];
+
+    if_indextoname(ifp->if_index, name, 64);
+    (*pr)("%-8s", name);
+    TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
+        if (ifa->ifa_addr->sa_family != AF_LINK) {
+            getnameinfo (ifa->ifa_addr, ifa->ifa_addr->sa_len, addr, sizeof(addr), 0, 0, 0);
+            getnameinfo (ifa->ifa_dstaddr, ifa->ifa_dstaddr->sa_len, broadcast, sizeof(broadcast), 0, 0, 0);
+            _mask(ifa->ifa_netmask, netmask, 64);
+            (*pr)("IP: %s, Broadcast: %s, Netmask: %s\n", addr, broadcast, netmask);
+            (*pr)("        ");
+            if ((ifp->if_flags & IFF_UP)) (*pr)("UP ");
+            if ((ifp->if_flags & IFF_BROADCAST)) (*pr)("BROADCAST ");
+            if ((ifp->if_flags & IFF_LOOPBACK)) (*pr)("LOOPBACK ");
+            if ((ifp->if_flags & IFF_RUNNING)) (*pr)("RUNNING ");
+            if ((ifp->if_flags & IFF_PROMISC)) (*pr)("PROMISC ");
+            if ((ifp->if_flags & IFF_MULTICAST)) (*pr)("MULTICAST ");
+            if ((ifp->if_flags & IFF_ALLMULTI)) (*pr)("ALLMULTI ");
+            (*pr)("MTU: %d, Metric: %d\n", ifp->if_mtu, ifp->if_metric);
+            (*pr)("        Rx - Packets: %d, Bytes: %d", ifa->if_data.ifi_ipackets, ifa->if_data.ifi_ibytes);
+            (*pr)(", Tx - Packets: %d, Bytes: %d\n", ifa->if_data.ifi_opackets, ifa->if_data.ifi_obytes);
+        }
+    }
+}
+
+static int
+_dumpentry(struct radix_node *rn, void *vw)
+{
+    struct rtentry *rt = (struct rtentry *)rn;
+    struct sockaddr *dst, *gate, *netmask, *genmask;
+    char addr[32], *cp;
+    pr_fun *pr = (pr_fun *)vw;
+
+    dst = rt_key(rt);
+    gate = rt->rt_gateway;
+    netmask = rt_mask(rt);
+    genmask = rt->rt_genmask;
+    if ((rt->rt_flags & (RTF_UP | RTF_WASCLONED)) == RTF_UP) {
+        if (netmask == NULL) {
+            return 0;
+        }
+        _inet_ntop(dst, addr, sizeof(addr));
+        (*pr)("%-15s ", addr);
+        if (gate != NULL) {
+            _inet_ntop(gate, addr, sizeof(addr));
+            (*pr)("%-15s ", addr);
+        } else {
+            (*pr)("%-15s ", " ");
+        }
+        if (netmask != NULL) {
+            _mask(netmask, addr, sizeof(addr));
+            (*pr)("%-15s ", addr);
+        } else {
+            (*pr)("%-15s ", " ");
+        }
+        cp = addr;
+        if ((rt->rt_flags & RTF_UP)) *cp++ = 'U';
+        if ((rt->rt_flags & RTF_GATEWAY)) *cp++ = 'G';
+        if ((rt->rt_flags & RTF_STATIC)) *cp++ = 'S';
+        if ((rt->rt_flags & RTF_DYNAMIC)) *cp++ = 'D';
+        *cp = '\0';
+        (*pr)("%-8s ", addr);  // Flags
+        if_indextoname(rt->rt_ifp->if_index, addr, 64);
+        (*pr)("%-8s ", addr);
+        (*pr)("\n");
+    }
+    return 0;
+}
+
+void
+show_network_tables(pr_fun *pr)
+{
+    int i, error;
+    struct radix_node_head *rnh;
+    struct ifnet *ifp;
+
+    cyg_scheduler_lock();
+    (*pr)("Routing tables\n");
+    (*pr)("Destination     Gateway         Mask            Flags    Interface\n");
+    for (i = 1; i <= AF_MAX; i++) {
+        if ((rnh = rt_tables[i]) != NULL) {
+            error = rnh->rnh_walktree(rnh, _dumpentry, pr);
+        }
+    }
+
+    (*pr)("Interface statistics\n");
+    for (ifp = ifnet.tqh_first; ifp; ifp = ifp->if_link.tqe_next) {
+        _show_ifp(ifp, pr);
+    }
+    cyg_scheduler_unlock();
+}
+
 #endif // CYGPKG_NET_DRIVER_FRAMEWORK
 
 // EOF support.c
--- a/packages/net/tcpip/current/ChangeLog
+++ b/packages/net/tcpip/current/ChangeLog
@@ -1,3 +1,8 @@
+2002-12-03  Gary Thomas  <gthomas@ecoscentric.com>
+
+	* src/ecos/support.c (show_network_tables): New function used
+	to print network information (interface, routing).
+
 2002-05-21  Jesper Skov  <jskov@redhat.com>
 
 	* src/lib/recv.c: Fix warning. socket.h declarations are not
--- a/packages/net/tcpip/current/src/ecos/support.c
+++ b/packages/net/tcpip/current/src/ecos/support.c
@@ -602,6 +602,130 @@ cyg_net_init(void)
     _init = true;
 }
 
+// Copyright (C) 2002 Gary Thomas
+
+#include <net/if.h>
+#include <net/route.h>
+#include <net/netdb.h>
+externC void if_indextoname(int indx, char *buf, int len);
+
+typedef void pr_fun(char *fmt, ...);
+
+static void
+_mask(struct sockaddr *sa, char *buf, int _len)
+{
+    char *cp = ((char *)sa) + 4;
+    int len = sa->sa_len - 4;
+    int tot = 0;
+
+    while (len-- > 0) {
+        if (tot) *buf++ = '.';
+        buf += diag_sprintf(buf, "%d", *cp++);
+        tot++;
+    }
+
+    while (tot < 4) {
+        if (tot) *buf++ = '.';
+        buf += diag_sprintf(buf, "%d", 0);
+        tot++;
+    }
+}
+
+static void
+_show_ifp(struct ifnet *ifp, pr_fun *pr)
+{
+    struct ifaddr *ifa;
+    char addr[64], netmask[64], broadcast[64];
+
+    (*pr)("%-8s", ifp->if_xname);
+    TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
+        if (ifa->ifa_addr->sa_family != AF_LINK) {
+            getnameinfo (ifa->ifa_addr, ifa->ifa_addr->sa_len, addr, sizeof(addr), 0, 0, 0);
+            getnameinfo (ifa->ifa_dstaddr, ifa->ifa_dstaddr->sa_len, broadcast, sizeof(broadcast), 0, 0, 0);
+            _mask(ifa->ifa_netmask, netmask, 64);
+            (*pr)("IP: %s, Broadcast: %s, Netmask: %s\n", addr, broadcast, netmask);
+            (*pr)("        ");
+            if ((ifp->if_flags & IFF_UP)) (*pr)("UP ");
+            if ((ifp->if_flags & IFF_BROADCAST)) (*pr)("BROADCAST ");
+            if ((ifp->if_flags & IFF_LOOPBACK)) (*pr)("LOOPBACK ");
+            if ((ifp->if_flags & IFF_RUNNING)) (*pr)("RUNNING ");
+            if ((ifp->if_flags & IFF_PROMISC)) (*pr)("PROMISC ");
+            if ((ifp->if_flags & IFF_MULTICAST)) (*pr)("MULTICAST ");
+            if ((ifp->if_flags & IFF_ALLMULTI)) (*pr)("ALLMULTI ");
+            (*pr)("MTU: %d, Metric: %d\n", ifp->if_mtu, ifp->if_metric);
+            (*pr)("        Rx - Packets: %d, Bytes: %d", ifp->if_data.ifi_ipackets, ifp->if_data.ifi_ibytes);
+            (*pr)(", Tx - Packets: %d, Bytes: %d\n", ifp->if_data.ifi_opackets, ifp->if_data.ifi_obytes);
+        }
+    }
+}
+
+static int
+_dumpentry(struct radix_node *rn, void *vw)
+{
+    struct rtentry *rt = (struct rtentry *)rn;
+    struct sockaddr *dst, *gate, *netmask, *genmask;
+    char addr[32], *cp;
+    pr_fun *pr = (pr_fun *)vw;
+
+    dst = rt_key(rt);
+    gate = rt->rt_gateway;
+    netmask = rt_mask(rt);
+    genmask = rt->rt_genmask;
+    if ((rt->rt_flags & (RTF_UP | RTF_LLINFO)) == RTF_UP) {
+        if (netmask == NULL) {
+            return 0;
+        }
+        _inet_ntop(dst, addr, sizeof(addr));
+        (*pr)("%-15s ", addr);
+        if (gate != NULL) {
+            _inet_ntop(gate, addr, sizeof(addr));
+            (*pr)("%-15s ", addr);
+        } else {
+            (*pr)("%-15s ", " ");
+        }
+        if (netmask != NULL) {
+            _mask(netmask, addr, sizeof(addr));
+            (*pr)("%-15s ", addr);
+        } else {
+            (*pr)("%-15s ", " ");
+        }
+        cp = addr;
+        if ((rt->rt_flags & RTF_UP)) *cp++ = 'U';
+        if ((rt->rt_flags & RTF_GATEWAY)) *cp++ = 'G';
+        if ((rt->rt_flags & RTF_STATIC)) *cp++ = 'S';
+        if ((rt->rt_flags & RTF_DYNAMIC)) *cp++ = 'D';
+        *cp = '\0';
+        (*pr)("%-8s ", addr);  // Flags
+        if_indextoname(rt->rt_ifp->if_index, addr, 64);
+        (*pr)("%-8s ", addr);
+        (*pr)("\n");
+    }
+    return 0;
+}
+
+void
+show_network_tables(pr_fun *pr)
+{
+    int i, error;
+    struct radix_node_head *rnh;
+    struct ifnet *ifp;
+
+    cyg_scheduler_lock();
+    (*pr)("Routing tables\n");
+    (*pr)("Destination     Gateway         Mask            Flags    Interface\n");
+    for (i = 1; i <= AF_MAX; i++) {
+        if ((rnh = rt_tables[i]) != NULL) {
+            error = rnh->rnh_walktree(rnh, _dumpentry, pr);
+        }
+    }
+
+    (*pr)("Interface statistics\n");
+    for (ifp = ifnet.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next) {
+        _show_ifp(ifp, pr);
+    }
+    cyg_scheduler_unlock();
+}
+
 #endif // CYGPKG_NET_DRIVER_FRAMEWORK
 
 // EOF support.c