source: rtems/cpukit/libnetworking/rtems/rtems_showroute.c @ 48e7abe6

4.104.114.84.95
Last change on this file since 48e7abe6 was 4aa8a23, checked in by Ralf Corsepius <ralf.corsepius@…>, on 02/02/05 at 03:06:41

Include config.h.

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