source: rtems/cpukit/libnetworking/rtems/rtems_showroute.c @ 429ba3b

4.104.114.84.95
Last change on this file since 429ba3b was 429ba3b, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/18/04 at 06:19:33

Remove stray white spaces.

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