source: rtems/c/src/lib/libnetworking/rtems/rtems_showroute.c @ 718dc95

4.104.114.84.95
Last change on this file since 718dc95 was 718dc95, checked in by Joel Sherrill <joel.sherrill@…>, on 09/21/98 at 00:46:00

Patch from Eric Norum <eric@…>:

Here's a patch to make the rtems_showroute routine a little more
useful. For `host' route table entries the link-level address is now
displayed. This is equivalent to the old `show arp table'
information displayed by the KA9Q code.

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/*
2 *  $Id$
3 */
4
5#include <stdlib.h>
6
7#include <sys/param.h>
8#include <sys/queue.h>
9#include <sys/systm.h>
10#include <sys/kernel.h>
11#include <sys/sysctl.h>
12#include <sys/proc.h>
13#include <sys/mbuf.h>
14#include <sys/socket.h>
15#include <sys/socketvar.h>
16#include <sys/domain.h>
17
18#include <net/if.h>
19#include <net/if_dl.h>
20#include <net/route.h>
21
22#include <netinet/in.h>
23
24#include <arpa/inet.h>
25
26/*
27 * We'll use the application versions of malloc and free.
28 */
29#undef malloc
30#undef free
31
32/*
33 * Information per route
34 */
35struct rinfo {
36        struct sockaddr dst;
37        union {
38                struct sockaddr         sa;
39                struct sockaddr_in      sin;
40                struct sockaddr_dl      sdl;
41        } un;
42        unsigned long   pksent;
43        unsigned long   expire;
44        int             flags;
45        char            ifname[16];
46        short           ifunit;
47        short           refcnt;
48};
49
50/*
51 * Information per display
52 */
53struct dinfo {
54        int             capacity;
55        int             count;
56        struct rinfo    *routes;
57};
58
59/*
60 * Copy address
61 */
62static void
63copyAddress (void *to, void *from, int tolen)
64{
65        int ncopy;
66        struct sockaddr dummy;
67
68        if (from == NULL) {
69                /*
70                 * Create a fake address of unspecified type
71                 */
72                from = &dummy;
73                dummy.sa_len = 4;
74                dummy.sa_family = AF_UNSPEC;
75        }
76        ncopy = ((struct sockaddr *)from)->sa_len;
77        if (ncopy > tolen)
78                ncopy = tolen;
79        memcpy (to, from, ncopy);
80}
81
82/*
83 * Package everything up before printing it.
84 * We don't want to block all network operations till
85 * the printing completes!
86 */
87static int
88show_inet_route (rn, vw)
89        struct radix_node *rn;
90        void *vw;
91{
92        struct rtentry *rt = (struct rtentry *)rn;
93        struct ifnet *ifp;
94        struct dinfo *dp = (struct dinfo *)vw;
95        struct rinfo *r;
96
97        /*
98         * Get a pointer to a new route info structure
99         */
100        if (dp->count >= dp->capacity) {
101                r = realloc (dp->routes, (sizeof *r) * (dp->capacity + 20));
102                if (r == 0)
103                        return ENOMEM;
104                dp->capacity += 20;
105                dp->routes = r;
106        }
107        r = dp->routes + dp->count++;
108
109        /*
110         * Fill in the route info structure
111         */
112        copyAddress (&r->dst, rt_key(rt), sizeof r->dst);
113        if (rt->rt_flags & (RTF_GATEWAY | RTF_HOST)) {
114                copyAddress (&r->un, rt->rt_gateway, sizeof r->un);
115        }
116        else {
117                /*
118                 * Create a fake address to hold the mask
119                 */
120                struct sockaddr_in dummy;
121
122                dummy.sin_family = AF_INET;
123                dummy.sin_len = sizeof dummy;
124                dummy.sin_addr = ((struct sockaddr_in *)rt_mask(rt))->sin_addr;
125                copyAddress (&r->un, &dummy, sizeof r->un);
126        }
127        r->flags = rt->rt_flags;
128        r->refcnt = rt->rt_refcnt;
129        r->pksent = rt->rt_rmx.rmx_pksent;
130        r->expire = rt->rt_rmx.rmx_expire;
131        ifp = rt->rt_ifp;
132        strncpy (r->ifname, ifp->if_name, sizeof r->ifname);
133        r->ifunit = ifp->if_unit;
134        return 0;
135}
136
137/*
138 * Convert link address to ASCII
139 */
140static char *
141link_ascii (struct sockaddr_dl *sdl, char *buf, int bufsize)
142{
143        char *cp;
144        int i;
145        int first = 1;
146        int nleft = sdl->sdl_alen;
147        unsigned char *ap = LLADDR (sdl);
148        static const char hextab[16] = "0123456789ABCDEF";
149
150        cp = buf;
151        while (nleft && (bufsize > 4)) {
152                if (first) {
153                        first = 0;
154                }
155                else {
156                        *cp++ = ':';
157                        bufsize--;
158                }
159                i = *ap++;
160                *cp++ = hextab[(i >> 4) & 0xf];
161                *cp++ = hextab[i & 0xf];
162                nleft--;
163                bufsize -= 2;
164        }
165        *cp = '\0';
166        return buf;
167}
168               
169void
170rtems_bsdnet_show_inet_routes (void)
171{
172        struct radix_node_head *rnh;
173        struct dinfo d;
174        struct rinfo *r;
175        int i, error;
176
177        /*
178         * For now we'll handle only AF_INET
179         */
180        rnh = rt_tables[AF_INET];
181        if (!rnh)
182                return;
183        d.count = d.capacity = 0;
184        d.routes = NULL;
185        rtems_bsdnet_semaphore_obtain ();
186        error = rnh->rnh_walktree(rnh, show_inet_route, &d);
187        rtems_bsdnet_semaphore_release ();
188        if (error) {
189                printf ("Can't get route info: %s\n", strerror (error));
190                return;
191        }
192        if (d.count == 0) {
193                printf ("No routes!\n");
194                return;
195        }
196        printf ("Destination     Gateway/Mask/Hw    Flags     Refs     Use Expire Interface\n");
197        for (i = 0, r = d.routes ; i < d.count ; i++, r++) {
198                char buf[30];
199                char *cp, *fc, flagbuf[10];
200                const char *addr;
201                unsigned long flagbit;
202                struct sockaddr_in *sin;
203
204                sin = (struct sockaddr_in *)&r->dst;
205                if (sin->sin_addr.s_addr == INADDR_ANY)
206                        addr = "default";
207                else
208                        addr = inet_ntop (AF_INET, &sin->sin_addr, buf, sizeof buf);
209                printf ("%-16s", addr);
210                switch (r->un.sa.sa_family) {
211                case AF_INET:
212                        addr = inet_ntop (AF_INET, &r->un.sin.sin_addr, buf, sizeof buf);
213                        break;
214
215                case AF_LINK:
216                        addr = link_ascii (&r->un.sdl, buf, sizeof buf);
217                        break;
218
219                default:
220                        addr = "";
221                        break;
222                }
223                printf ("%-19s", addr);
224                fc = "UGHRDM   XLS";
225                for (flagbit = 0x1, cp = flagbuf ; *fc ; flagbit <<= 1, fc++) {
226                        if ((r->flags & flagbit) && (*fc != ' '))
227                                *cp++ = *fc;
228                }
229                *cp = '\0';
230                printf ("%-10s%3d%9ld%7ld %.*s%d\n", flagbuf,
231                                        r->refcnt, r->pksent,
232                                        r->expire,
233                                        (int)sizeof r->ifname, r->ifname,
234                                        r->ifunit);
235        }
236        free (d.routes);
237}
Note: See TracBrowser for help on using the repository browser.