source: rtems-libbsd/freebsd/usr.bin/netstat/main.c @ c333bab

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since c333bab was c333bab, checked in by Sebastian Huber <sebastian.huber@…>, on 10/17/13 at 08:46:42

Simplify getopt() to getopt_r() translation

  • Property mode set to 100644
File size: 31.8 KB
Line 
1/*-
2 * Copyright (c) 1983, 1988, 1993
3 *      Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *      This product includes software developed by the University of
16 *      California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35char const copyright[] =
36"@(#) Copyright (c) 1983, 1988, 1993\n\
37        Regents of the University of California.  All rights reserved.\n";
38#endif /* not lint */
39
40#if 0
41#ifndef lint
42static char sccsid[] = "@(#)main.c      8.4 (Berkeley) 3/1/94";
43#endif /* not lint */
44#endif
45
46#ifdef __rtems__
47#define __need_getopt_newlib
48#include <getopt.h>
49#endif /* __rtems__ */
50#include <sys/cdefs.h>
51__FBSDID("$FreeBSD$");
52
53#include <rtems/bsd/sys/param.h>
54#include <sys/file.h>
55#include <sys/protosw.h>
56#include <sys/socket.h>
57#include <sys/socketvar.h>
58
59#include <netinet/in.h>
60
61#ifdef NETGRAPH
62#include <netgraph/ng_socket.h>
63#endif
64
65#include <ctype.h>
66#include <err.h>
67#include <errno.h>
68#include <kvm.h>
69#include <limits.h>
70#include <netdb.h>
71#include <nlist.h>
72#include <paths.h>
73#include <stdint.h>
74#include <stdio.h>
75#include <stdlib.h>
76#include <string.h>
77#include <unistd.h>
78#include "netstat.h"
79
80static struct nlist nl[] = {
81#define N_IFNET         0
82        { .n_name = "_ifnet" },
83#define N_RTSTAT        1
84        { .n_name = "_rtstat" },
85#define N_RTREE         2
86        { .n_name = "_rt_tables"},
87#define N_MRTSTAT       3
88        { .n_name = "_mrtstat" },
89#define N_MFCHASHTBL    4
90        { .n_name = "_mfchashtbl" },
91#define N_VIFTABLE      5
92        { .n_name = "_viftable" },
93#define N_IPX           6
94        { .n_name = "_ipxpcb_list"},
95#define N_IPXSTAT       7
96        { .n_name = "_ipxstat"},
97#define N_SPXSTAT       8
98        { .n_name = "_spx_istat"},
99#define N_DDPSTAT       9
100        { .n_name = "_ddpstat"},
101#define N_DDPCB         10
102        { .n_name = "_ddpcb"},
103#define N_NGSOCKS       11
104        { .n_name = "_ngsocklist"},
105#define N_IP6STAT       12
106        { .n_name = "_ip6stat" },
107#define N_ICMP6STAT     13
108        { .n_name = "_icmp6stat" },
109#define N_IPSECSTAT     14
110        { .n_name = "_ipsec4stat" },
111#define N_IPSEC6STAT    15
112        { .n_name = "_ipsec6stat" },
113#define N_PIM6STAT      16
114        { .n_name = "_pim6stat" },
115#define N_MRT6STAT      17
116        { .n_name = "_mrt6stat" },
117#define N_MF6CTABLE     18
118        { .n_name = "_mf6ctable" },
119#define N_MIF6TABLE     19
120        { .n_name = "_mif6table" },
121#define N_PFKEYSTAT     20
122        { .n_name = "_pfkeystat" },
123#define N_MBSTAT        21
124        { .n_name = "_mbstat" },
125#define N_MBTYPES       22
126        { .n_name = "_mbtypes" },
127#define N_NMBCLUSTERS   23
128        { .n_name = "_nmbclusters" },
129#define N_NMBUFS        24
130        { .n_name = "_nmbufs" },
131#define N_MBHI          25
132        { .n_name = "_mbuf_hiwm" },
133#define N_CLHI          26
134        { .n_name = "_clust_hiwm" },
135#define N_NCPUS         27
136        { .n_name = "_smp_cpus" },
137#define N_PAGESZ        28
138        { .n_name = "_pagesize" },
139#define N_MBPSTAT       29
140        { .n_name = "_mb_statpcpu" },
141#define N_RTTRASH       30
142        { .n_name = "_rttrash" },
143#define N_MBLO          31
144        { .n_name = "_mbuf_lowm" },
145#define N_CLLO          32
146        { .n_name = "_clust_lowm" },
147#define N_CARPSTAT      33
148        { .n_name = "_carpstats" },
149#define N_PFSYNCSTAT    34
150        { .n_name = "_pfsyncstats" },
151#define N_AHSTAT        35
152        { .n_name = "_ahstat" },
153#define N_ESPSTAT       36
154        { .n_name = "_espstat" },
155#define N_IPCOMPSTAT    37
156        { .n_name = "_ipcompstat" },
157#define N_TCPSTAT       38
158        { .n_name = "_tcpstat" },
159#define N_UDPSTAT       39
160        { .n_name = "_udpstat" },
161#define N_IPSTAT        40
162        { .n_name = "_ipstat" },
163#define N_ICMPSTAT      41
164        { .n_name = "_icmpstat" },
165#define N_IGMPSTAT      42
166        { .n_name = "_igmpstat" },
167#define N_PIMSTAT       43
168        { .n_name = "_pimstat" },
169#define N_TCBINFO       44
170        { .n_name = "_tcbinfo" },
171#define N_UDBINFO       45
172        { .n_name = "_udbinfo" },
173#define N_DIVCBINFO     46
174        { .n_name = "_divcbinfo" },
175#define N_RIPCBINFO     47
176        { .n_name = "_ripcbinfo" },
177#define N_UNP_COUNT     48
178        { .n_name = "_unp_count" },
179#define N_UNP_GENCNT    49
180        { .n_name = "_unp_gencnt" },
181#define N_UNP_DHEAD     50
182        { .n_name = "_unp_dhead" },
183#define N_UNP_SHEAD     51
184        { .n_name = "_unp_shead" },
185#define N_RIP6STAT      52
186        { .n_name = "_rip6stat" },
187#define N_SCTPSTAT      53
188        { .n_name = "_sctpstat" },
189#define N_MFCTABLESIZE  54
190        { .n_name = "_mfctablesize" },
191#define N_ARPSTAT       55
192        { .n_name = "_arpstat" },
193        { .n_name = NULL },
194};
195
196struct protox {
197        int     pr_index;               /* index into nlist of cb head */
198        int     pr_sindex;              /* index into nlist of stat block */
199        u_char  pr_wanted;              /* 1 if wanted, 0 otherwise */
200        void    (*pr_cblocks)(u_long, const char *, int, int);
201                                        /* control blocks printing routine */
202        void    (*pr_stats)(u_long, const char *, int, int);
203                                        /* statistics printing routine */
204        void    (*pr_istats)(char *);   /* per/if statistics printing routine */
205        const char      *pr_name;               /* well-known name */
206        int     pr_usesysctl;           /* non-zero if we use sysctl, not kvm */
207        int     pr_protocol;
208} protox[] = {
209        { N_TCBINFO,    N_TCPSTAT,      1,      protopr,
210          tcp_stats,    NULL,           "tcp",  1,      IPPROTO_TCP },
211        { N_UDBINFO,    N_UDPSTAT,      1,      protopr,
212          udp_stats,    NULL,           "udp",  1,      IPPROTO_UDP },
213#ifdef SCTP
214        { -1,           N_SCTPSTAT,     1,      sctp_protopr,
215          sctp_stats,   NULL,           "sctp", 1,      IPPROTO_SCTP },
216#endif
217        { N_DIVCBINFO,  -1,             1,      protopr,
218          NULL,         NULL,           "divert", 1,    IPPROTO_DIVERT },
219        { N_RIPCBINFO,  N_IPSTAT,       1,      protopr,
220          ip_stats,     NULL,           "ip",   1,      IPPROTO_RAW },
221        { N_RIPCBINFO,  N_ICMPSTAT,     1,      protopr,
222          icmp_stats,   NULL,           "icmp", 1,      IPPROTO_ICMP },
223        { N_RIPCBINFO,  N_IGMPSTAT,     1,      protopr,
224          igmp_stats,   NULL,           "igmp", 1,      IPPROTO_IGMP },
225#ifdef IPSEC
226        { -1,           N_IPSECSTAT,    1,      NULL,   /* keep as compat */
227          ipsec_stats,  NULL,           "ipsec", 0,     0},
228        { -1,           N_AHSTAT,       1,      NULL,
229          ah_stats,     NULL,           "ah",   0,      0},
230        { -1,           N_ESPSTAT,      1,      NULL,
231          esp_stats,    NULL,           "esp",  0,      0},
232        { -1,           N_IPCOMPSTAT,   1,      NULL,
233          ipcomp_stats, NULL,           "ipcomp", 0,    0},
234#endif
235        { N_RIPCBINFO,  N_PIMSTAT,      1,      protopr,
236          pim_stats,    NULL,           "pim",  1,      IPPROTO_PIM },
237        { -1,           N_CARPSTAT,     1,      NULL,
238          carp_stats,   NULL,           "carp", 1,      0 },
239        { -1,           N_PFSYNCSTAT,   1,      NULL,
240          pfsync_stats, NULL,           "pfsync", 1,    0 },
241        { -1,           N_ARPSTAT,      1,      NULL,
242          arp_stats,    NULL,           "arp", 1,       0 },
243        { -1,           -1,             0,      NULL,
244          NULL,         NULL,           NULL,   0,      0 }
245};
246
247#ifdef INET6
248struct protox ip6protox[] = {
249        { N_TCBINFO,    N_TCPSTAT,      1,      protopr,
250          tcp_stats,    NULL,           "tcp",  1,      IPPROTO_TCP },
251        { N_UDBINFO,    N_UDPSTAT,      1,      protopr,
252          udp_stats,    NULL,           "udp",  1,      IPPROTO_UDP },
253        { N_RIPCBINFO,  N_IP6STAT,      1,      protopr,
254          ip6_stats,    ip6_ifstats,    "ip6",  1,      IPPROTO_RAW },
255        { N_RIPCBINFO,  N_ICMP6STAT,    1,      protopr,
256          icmp6_stats,  icmp6_ifstats,  "icmp6", 1,     IPPROTO_ICMPV6 },
257#ifdef IPSEC
258        { -1,           N_IPSEC6STAT,   1,      NULL,
259          ipsec_stats,  NULL,           "ipsec6", 0,    0 },
260#endif
261#ifdef notyet
262        { -1,           N_PIM6STAT,     1,      NULL,
263          pim6_stats,   NULL,           "pim6", 1,      0 },
264#endif
265        { -1,           N_RIP6STAT,     1,      NULL,
266          rip6_stats,   NULL,           "rip6", 1,      0 },
267        { -1,           -1,             0,      NULL,
268          NULL,         NULL,           NULL,   0,      0 }
269};
270#endif /*INET6*/
271
272#ifdef IPSEC
273struct protox pfkeyprotox[] = {
274        { -1,           N_PFKEYSTAT,    1,      NULL,
275          pfkey_stats,  NULL,           "pfkey", 0,     0 },
276        { -1,           -1,             0,      NULL,
277          NULL,         NULL,           NULL,   0,      0 }
278};
279#endif
280
281#ifndef __rtems__
282struct protox atalkprotox[] = {
283        { N_DDPCB,      N_DDPSTAT,      1,      atalkprotopr,
284          ddp_stats,    NULL,           "ddp",  0,      0 },
285        { -1,           -1,             0,      NULL,
286          NULL,         NULL,           NULL,   0,      0 }
287};
288#endif
289#ifdef NETGRAPH
290struct protox netgraphprotox[] = {
291        { N_NGSOCKS,    -1,             1,      netgraphprotopr,
292          NULL,         NULL,           "ctrl", 0,      0 },
293        { N_NGSOCKS,    -1,             1,      netgraphprotopr,
294          NULL,         NULL,           "data", 0,      0 },
295        { -1,           -1,             0,      NULL,
296          NULL,         NULL,           NULL,   0,      0 }
297};
298#endif
299#ifdef IPX
300struct protox ipxprotox[] = {
301        { N_IPX,        N_IPXSTAT,      1,      ipxprotopr,
302          ipx_stats,    NULL,           "ipx",  0,      0 },
303        { N_IPX,        N_SPXSTAT,      1,      ipxprotopr,
304          spx_stats,    NULL,           "spx",  0,      0 },
305        { -1,           -1,             0,      NULL,
306          NULL,         NULL,           0,      0,      0 }
307};
308#endif
309
310struct protox *protoprotox[] = {
311                                         protox,
312#ifdef INET6
313                                         ip6protox,
314#endif
315#ifdef IPSEC
316                                         pfkeyprotox,
317#endif
318#ifdef IPX
319                                         ipxprotox,
320#endif
321#ifndef __rtems__
322                                         atalkprotox, NULL };
323#else
324                                NULL };
325#endif
326
327static void printproto(struct protox *, const char *);
328static void usage(void);
329static struct protox *name2protox(const char *);
330static struct protox *knownname(const char *);
331
332static kvm_t *kvmd;
333static char *nlistf = NULL, *memf = NULL;
334
335int     Aflag;          /* show addresses of protocol control block */
336int     aflag;          /* show all sockets (including servers) */
337int     Bflag;          /* show information about bpf consumers */
338int     bflag;          /* show i/f total bytes in/out */
339int     dflag;          /* show i/f dropped packets */
340int     gflag;          /* show group (multicast) routing or stats */
341int     hflag;          /* show counters in human readable format */
342int     iflag;          /* show interfaces */
343int     Lflag;          /* show size of listen queues */
344int     mflag;          /* show memory stats */
345int     noutputs = 0;   /* how much outputs before we exit */
346int     numeric_addr;   /* show addresses numerically */
347int     numeric_port;   /* show ports numerically */
348static int pflag;       /* show given protocol */
349int     rflag;          /* show routing tables (or routing stats) */
350int     sflag;          /* show protocol statistics */
351int     tflag;          /* show i/f watchdog timers */
352int     Wflag;          /* wide display */
353int     xflag;          /* extra information, includes all socket buffer info */
354int     zflag;          /* zero stats */
355
356int     interval;       /* repeat interval for i/f stats */
357
358char    *interface;     /* desired i/f for stats, or NULL for all i/fs */
359int     unit;           /* unit number for above */
360
361int     af;             /* address family */
362int     live;           /* true if we are examining a live system */
363
364
365#ifdef __rtems__
366static int main_netstat(int argc, char *argv[]);
367static int rtems_shell_main_netstat(int argc, char *argv[])
368{
369  int i;
370  rtems_shell_globals_t  netstat_globals;
371  rtems_shell_globals = &netstat_globals;
372  memset (rtems_shell_globals, 0, sizeof (netstat_globals));
373
374  i = 0;
375  protox[i].pr_index     = N_TCBINFO;
376  protox[i].pr_sindex    = N_TCPSTAT;
377  protox[i].pr_wanted    = 1;
378  protox[i].pr_cblocks   = protopr;
379  protox[i].pr_stats     = tcp_stats;
380  protox[i].pr_istats    = NULL;
381  protox[i].pr_name      = "tcp";
382  protox[i].pr_usesysctl = 1;
383  protox[i].pr_protocol  = IPPROTO_TCP;
384  i++;
385  protox[i].pr_index     = N_UDBINFO;
386  protox[i].pr_sindex    = N_UDPSTAT;
387  protox[i].pr_wanted    = 1;
388  protox[i].pr_cblocks   = protopr;
389  protox[i].pr_stats     = udp_stats;
390  protox[i].pr_istats    = NULL;
391  protox[i].pr_name      = "udp";
392  protox[i].pr_usesysctl = 1;
393  protox[i].pr_protocol  = IPPROTO_UDP;
394  i++;
395#ifdef SCTP
396  protox[i].pr_index     = -1;
397  protox[i].pr_sindex    = N_SCTPSTAT;
398  protox[i].pr_wanted    = 1;
399  protox[i].pr_cblocks   = sctp_protopr;
400  protox[i].pr_stats     = sctp_stats;
401  protox[i].pr_istats    = NULL;
402  protox[i].pr_name      = "sctp";
403  protox[i].pr_usesysctl = 1;
404  protox[i].pr_protocol  = IPPROTO_SCTP;
405  i++;
406#endif
407  protox[i].pr_index     = N_DIVCBINFO;
408  protox[i].pr_sindex    = -1;
409  protox[i].pr_wanted    = 1;
410  protox[i].pr_cblocks   = protopr;
411  protox[i].pr_stats     = NULL;
412  protox[i].pr_istats    = NULL;
413  protox[i].pr_name      = "divert";
414  protox[i].pr_usesysctl = 1;
415  protox[i].pr_protocol  = IPPROTO_DIVERT;
416  i++;
417  protox[i].pr_index     = N_RIPCBINFO;
418  protox[i].pr_sindex    = N_IPSTAT;
419  protox[i].pr_wanted    = 1;
420  protox[i].pr_cblocks   = protopr;
421  protox[i].pr_stats     = ip_stats;
422  protox[i].pr_istats    = NULL;
423  protox[i].pr_name      = "ip";
424  protox[i].pr_usesysctl = 1;
425  protox[i].pr_protocol  = IPPROTO_RAW;
426  i++;
427  protox[i].pr_index     = N_RIPCBINFO;
428  protox[i].pr_sindex    = N_ICMPSTAT;
429  protox[i].pr_wanted    = 1;
430  protox[i].pr_cblocks   = protopr;
431  protox[i].pr_stats     = icmp_stats;
432  protox[i].pr_istats    = NULL;
433  protox[i].pr_name      = "icmp";
434  protox[i].pr_usesysctl = 1;
435  protox[i].pr_protocol  = IPPROTO_ICMP;
436  i++;
437  protox[i].pr_index     = N_RIPCBINFO;
438  protox[i].pr_sindex    = N_IGMPSTAT;
439  protox[i].pr_wanted    = 1;
440  protox[i].pr_cblocks   = protopr;
441  protox[i].pr_stats     = igmp_stats;
442  protox[i].pr_istats    = NULL;
443  protox[i].pr_name      = "igmp";
444  protox[i].pr_usesysctl = 1;
445  protox[i].pr_protocol  = IPPROTO_IGMP;
446  i++;
447#ifdef IPSEC
448  protox[i].pr_index     = -1;
449  protox[i].pr_sindex    = N_IPSECSTAT;
450  protox[i].pr_wanted    = 1;
451  protox[i].pr_cblocks   = NULL;
452  protox[i].pr_stats     = ipsec_stats;
453  protox[i].pr_istats    = NULL;
454  protox[i].pr_name      = "ipsec";
455  protox[i].pr_usesysctl = 0;
456  protox[i].pr_protocol  = 0;
457  i++;
458  protox[i].pr_index     = -1;
459  protox[i].pr_sindex    = N_AHSTAT;
460  protox[i].pr_wanted    = 1;
461  protox[i].pr_cblocks   = NULL;
462  protox[i].pr_stats     = ah_stats;
463  protox[i].pr_istats    = NULL;
464  protox[i].pr_name      = "ah";
465  protox[i].pr_usesysctl = 0;
466  protox[i].pr_protocol  = 0;
467  i++;
468  protox[i].pr_index     = -1;
469  protox[i].pr_sindex    = N_ESPSTAT;
470  protox[i].pr_wanted    = 1;
471  protox[i].pr_cblocks   = NULL;
472  protox[i].pr_stats     = esp_stats;
473  protox[i].pr_istats    = NULL;
474  protox[i].pr_name      = "esp";
475  protox[i].pr_usesysctl = 0;
476  protox[i].pr_protocol  = 0;
477  i++;
478  protox[i].pr_index     = -1;
479  protox[i].pr_sindex    = N_IPCOMPSTAT;
480  protox[i].pr_wanted    = 1;
481  protox[i].pr_cblocks   = NULL;
482  protox[i].pr_stats     = ipcomp_stats;
483  protox[i].pr_istats    = NULL;
484  protox[i].pr_name      = "ipcomp";
485  protox[i].pr_usesysctl = 0;
486  protox[i].pr_protocol  = 0;
487  i++;
488#endif
489  protox[i].pr_index     = N_RIPCBINFO;
490  protox[i].pr_sindex    = N_PIMSTAT;
491  protox[i].pr_wanted    = 1;
492  protox[i].pr_cblocks   = protopr;
493  protox[i].pr_stats     = pim_stats;
494  protox[i].pr_istats    = NULL;
495  protox[i].pr_name      = "pim";
496  protox[i].pr_usesysctl = 1;
497  protox[i].pr_protocol  = IPPROTO_PIM;
498  i++;
499  protox[i].pr_index     =  -1;
500  protox[i].pr_sindex    = N_CARPSTAT;
501  protox[i].pr_wanted    = 1;
502  protox[i].pr_cblocks   = NULL;
503  protox[i].pr_stats     = carp_stats;
504  protox[i].pr_istats    = NULL;
505  protox[i].pr_name      = "carp";
506  protox[i].pr_usesysctl = 1;
507  protox[i].pr_protocol  = 0;
508  i++;
509  protox[i].pr_index     =  -1;
510  protox[i].pr_sindex    = N_PFSYNCSTAT;
511  protox[i].pr_wanted    = 1;
512  protox[i].pr_cblocks   = NULL;
513  protox[i].pr_stats     = pfsync_stats;
514  protox[i].pr_istats    = NULL;
515  protox[i].pr_name      = "pfsync";
516  protox[i].pr_usesysctl = 1;
517  protox[i].pr_protocol  = 0;
518  i++;
519  protox[i].pr_index     = -1;
520  protox[i].pr_sindex    = N_ARPSTAT;
521  protox[i].pr_wanted    = 1;
522  protox[i].pr_cblocks   = NULL;
523  protox[i].pr_stats     = arp_stats;
524  protox[i].pr_istats    = NULL;
525  protox[i].pr_name      = "arp";
526  protox[i].pr_usesysctl = 1;
527  protox[i].pr_protocol  = 0;
528  i++;
529  protox[i].pr_index     = -1;
530  protox[i].pr_sindex    = -1;
531  protox[i].pr_wanted    = 0;
532  protox[i].pr_cblocks   = NULL;
533  protox[i].pr_stats     = NULL;
534  protox[i].pr_istats    = NULL;
535  protox[i].pr_name      = NULL;
536  protox[i].pr_usesysctl = 0;
537  protox[i].pr_protocol  = 0;
538
539#ifdef INET6
540  i=0;
541  ip6protox[i].pr_index     = N_TCBINFO;
542  ip6protox[i].pr_sindex    = N_TCPSTAT;
543  ip6protox[i].pr_wanted    = 1;
544  ip6protox[i].pr_cblocks   = protopr;
545  ip6protox[i].pr_stats     = tcp_stats;
546  ip6protox[i].pr_istats    = NULL;
547  ip6protox[i].pr_name      = "tcp";
548  ip6protox[i].pr_usesysctl = 1;
549  ip6protox[i].pr_protocol  = IPPROTO_TCP;
550  i++;
551  ip6protox[i].pr_index     = N_UDBINFO;
552  ip6protox[i].pr_sindex    = N_UDPSTAT;
553  ip6protox[i].pr_wanted    = 1;
554  ip6protox[i].pr_cblocks   = protopr;
555  ip6protox[i].pr_stats     = udp_stats;
556  ip6protox[i].pr_istats    = NULL;
557  ip6protox[i].pr_name      = "udp";
558  ip6protox[i].pr_usesysctl = 1;
559  ip6protox[i].pr_protocol  = IPPROTO_UDP;
560  i++;
561  ip6protox[i].pr_index     = N_RIPCBINFO;
562  ip6protox[i].pr_sindex    = N_IP6STAT;
563  ip6protox[i].pr_wanted    = 1;
564  ip6protox[i].pr_cblocks   = protopr;
565  ip6protox[i].pr_stats     = ip6_stats;
566  ip6protox[i].pr_istats    = ip6_ifstats;
567  ip6protox[i].pr_name      = "ip6";
568  ip6protox[i].pr_usesysctl = 1;
569  ip6protox[i].pr_protocol  = IPPROTO_RAW;
570  i++;
571  ip6protox[i].pr_index     = N_RIPCBINFO;
572  ip6protox[i].pr_sindex    = N_ICMP6STAT;
573  ip6protox[i].pr_wanted    = 1;
574  ip6protox[i].pr_cblocks   = protopr;
575  ip6protox[i].pr_stats     = icmp6_stats;
576  ip6protox[i].pr_istats    = icmp6_ifstats;
577  ip6protox[i].pr_name      = "icmp6";
578  ip6protox[i].pr_usesysctl = 1;
579  ip6protox[i].pr_protocol  = IPPROTO_ICMPV6;
580  i++;
581#ifdef IPSEC
582  ip6protox[i].pr_index     = -1;
583  ip6protox[i].pr_sindex    = N_IPSEC6STAT;
584  ip6protox[i].pr_wanted    = 1;
585  ip6protox[i].pr_cblocks   = NULL;
586  ip6protox[i].pr_stats     = ipsec_stats;
587  ip6protox[i].pr_istats    = NULL;
588  ip6protox[i].pr_name      = "ipsec6";
589  ip6protox[i].pr_usesysctl = 0;
590  ip6protox[i].pr_protocol  = 0;
591  i++;
592#endif
593#ifdef notyet
594  ip6protox[i].pr_index     = -1;
595  ip6protox[i].pr_sindex    = N_PIM6STAT;
596  ip6protox[i].pr_wanted    = 1;
597  ip6protox[i].pr_cblocks   = NULL;
598  ip6protox[i].pr_stats     = pim6_stats;
599  ip6protox[i].pr_istats    = NULL;
600  ip6protox[i].pr_name      = "pim6";
601  ip6protox[i].pr_usesysctl = 1;
602  ip6protox[i].pr_protocol  = 0;
603  i++;
604#endif
605  ip6protox[i].pr_index     = -1;
606  ip6protox[i].pr_sindex    = N_RIP6STAT;
607  ip6protox[i].pr_wanted    = 1;
608  ip6protox[i].pr_cblocks   = NULL;
609  ip6protox[i].pr_stats     = rip6_stats;
610  ip6protox[i].pr_istats    = NULL;
611  ip6protox[i].pr_name      = "rip6";
612  ip6protox[i].pr_usesysctl = 1;
613  ip6protox[i].pr_protocol  = 0;
614  i++;
615  ip6protox[i].pr_index     = -1;
616  ip6protox[i].pr_sindex    = -1;
617  ip6protox[i].pr_wanted    = 0;
618  ip6protox[i].pr_cblocks   = NULL;
619  ip6protox[i].pr_stats     = NULL;
620  ip6protox[i].pr_istats    = NULL;
621  ip6protox[i].pr_name      = NULL;
622  ip6protox[i].pr_usesysctl = 0;
623  ip6protox[i].pr_protocol  = 0;
624  i++;
625#endif /*INET6*/
626
627#ifdef IPSEC
628  i=0;
629  pfkeyprotox[i].pr_index     = -1;
630  pfkeyprotox[i].pr_sindex    = N_PFKEYSTAT;
631  pfkeyprotox[i].pr_wanted    = 1;
632  pfkeyprotox[i].pr_cblocks   = NULL;
633  pfkeyprotox[i].pr_stats     = pfkey_stats;
634  pfkeyprotox[i].pr_istats    = NULL;
635  pfkeyprotox[i].pr_name      = "pfkey";
636  pfkeyprotox[i].pr_usesysctl = 0;
637  pfkeyprotox[i].pr_protocol  = 0;
638  i++;
639  pfkeyprotox[i].pr_index     = -1;
640  pfkeyprotox[i].pr_sindex    = -1;
641  pfkeyprotox[i].pr_wanted    = 0;
642  pfkeyprotox[i].pr_cblocks   = NULL;
643  pfkeyprotox[i].pr_stats     = NULL;
644  pfkeyprotox[i].pr_istats    = NULL;
645  pfkeyprotox[i].pr_name      = NULL;
646  pfkeyprotox[i].pr_usesysctl = 0;
647  pfkeyprotox[i].pr_protocol  = 0;
648#endif
649
650#ifdef NETGRAPH
651  netgraphprotox[i].pr_index     = N_NGSOCKS;
652  netgraphprotox[i].pr_sindex    = -1;
653  netgraphprotox[i].pr_wanted    = 1;
654  netgraphprotox[i].pr_cblocks   = netgraphprotopr;
655  netgraphprotox[i].pr_stats     = NULL;
656  netgraphprotox[i].pr_istats    = NULL;
657  netgraphprotox[i].pr_name      = "ctrl";
658  netgraphprotox[i].pr_usesysctl = 0;
659  netgraphprotox[i].pr_protocol  = 0;
660  i++;
661  netgraphprotox[i].pr_index     = N_NGSOCKS;
662  netgraphprotox[i].pr_sindex    = -1;
663  netgraphprotox[i].pr_wanted    = 1;
664  netgraphprotox[i].pr_cblocks   = netgraphprotopr;
665  netgraphprotox[i].pr_stats     = NULL;
666  netgraphprotox[i].pr_istats    = NULL;
667  netgraphprotox[i].pr_name      = "data";
668  netgraphprotox[i].pr_usesysctl = 0;
669  netgraphprotox[i].pr_protocol  = 0;
670  i++;
671  netgraphprotox[i].pr_index     = -1;
672  netgraphprotox[i].pr_sindex    = -1;
673  netgraphprotox[i].pr_wanted    = 0;
674  netgraphprotox[i].pr_cblocks   = NULL;
675  netgraphprotox[i].pr_stats     = NULL;
676  netgraphprotox[i].pr_istats    = NULL;
677  netgraphprotox[i].pr_name      = NULL;
678  netgraphprotox[i].pr_usesysctl = 0;
679  netgraphprotox[i].pr_protocol  = 0;
680#endif
681#ifdef IPX
682  i=0;
683  ipxprotox[i].pr_index     = N_IPX;
684  ipxprotox[i].pr_sindex    = N_IPXSTAT;
685  ipxprotox[i].pr_wanted    = 1;
686  ipxprotox[i].pr_cblocks   = ipxprotopr;
687  ipxprotox[i].pr_stats     = ipx_stats;
688  ipxprotox[i].pr_istats    = NULL;
689  ipxprotox[i].pr_name      = "ipx";
690  ipxprotox[i].pr_usesysctl = 0;
691  ipxprotox[i].pr_protocol  = 0;
692  i++;
693  ipxprotox[i].pr_index     = N_IPX;
694  ipxprotox[i].pr_sindex    = N_SPXSTAT;
695  ipxprotox[i].pr_wanted    = 1;
696  ipxprotox[i].pr_cblocks   = ipxprotopr;
697  ipxprotox[i].pr_stats     = spx_stats;
698  ipxprotox[i].pr_istats    = NULL;
699  ipxprotox[i].pr_name      = "spx";
700  ipxprotox[i].pr_usesysctl = 0;
701  ipxprotox[i].pr_protocol  = 0;
702  i++;
703  ipxprotox[i].pr_index     = -1;
704  ipxprotox[i].pr_sindex    = -1;
705  ipxprotox[i].pr_wanted    = 0;
706  ipxprotox[i].pr_cblocks   = NULL;
707  ipxprotox[i].pr_stats     = NULL;
708  ipxprotox[i].pr_istats    = NULL;
709  ipxprotox[i].pr_name      = 0;
710  ipxprotox[i].pr_usesysctl = 0;
711  ipxprotox[i].pr_protocol  = 0;
712  i++;
713#endif
714
715  i=0;
716  protoprotox[i] = protox;
717  i++;
718#ifdef INET6
719  protoprotox[i] = ip6protox,
720  i++;
721#endif
722#ifdef IPSEC
723  protoprotox[i] = pfkeyprotox,
724  i++;
725#endif
726#ifdef IPX
727  protoprotox[i] = ipxprotox,
728#endif
729  noutputs = 0;
730
731  netstat_globals.exit_code = 1;
732  if (setjmp (netstat_globals.exit_jmp) == 0)
733    return main_netstat (argc, argv);
734  return netstat_globals.exit_code;
735}
736#endif
737
738int
739#ifdef __rtems__
740main_netstat(int argc, char *argv[])
741#else
742main(int argc, char *argv[])
743#endif
744{
745        struct protox *tp = NULL;  /* for printing cblocks & stats */
746        int ch;
747#ifdef __rtems__
748        struct getopt_data getopt_data;
749        memset(&getopt_data, 0, sizeof(getopt_data));
750#define optind getopt_data.optind
751#define optarg getopt_data.optarg
752#define opterr getopt_data.opterr
753#define optopt getopt_data.optopt
754#define getopt(argc, argv, opt) getopt_r(argc, argv, opt, &getopt_data)
755#endif /* __rtems__ */
756
757        af = AF_UNSPEC;
758
759        while ((ch = getopt(argc, argv, "AaBbdf:ghI:iLlM:mN:np:q:rSstuWw:xz")) != -1)
760                switch(ch) {
761                case 'A':
762                        Aflag = 1;
763                        break;
764                case 'a':
765                        aflag = 1;
766                        break;
767                case 'B':
768                        Bflag = 1;
769                        break;
770                case 'b':
771                        bflag = 1;
772                        break;
773                case 'd':
774                        dflag = 1;
775                        break;
776                case 'f':
777                        if (strcmp(optarg, "ipx") == 0)
778                                af = AF_IPX;
779                        else if (strcmp(optarg, "inet") == 0)
780                                af = AF_INET;
781#ifdef INET6
782                        else if (strcmp(optarg, "inet6") == 0)
783                                af = AF_INET6;
784#endif
785#ifdef IPSEC
786                        else if (strcmp(optarg, "pfkey") == 0)
787                                af = PF_KEY;
788#endif
789                        else if (strcmp(optarg, "unix") == 0)
790                                af = AF_UNIX;
791                        else if (strcmp(optarg, "atalk") == 0)
792                                af = AF_APPLETALK;
793#ifdef NETGRAPH
794                        else if (strcmp(optarg, "ng") == 0
795                            || strcmp(optarg, "netgraph") == 0)
796                                af = AF_NETGRAPH;
797#endif
798                        else if (strcmp(optarg, "link") == 0)
799                                af = AF_LINK;
800                        else {
801                                errx(1, "%s: unknown address family", optarg);
802                        }
803                        break;
804                case 'g':
805                        gflag = 1;
806                        break;
807                case 'h':
808                        hflag = 1;
809                        break;
810                case 'I': {
811                        char *cp;
812
813                        iflag = 1;
814                        for (cp = interface = optarg; isalpha(*cp); cp++)
815                                continue;
816                        unit = atoi(cp);
817                        break;
818                }
819                case 'i':
820                        iflag = 1;
821                        break;
822                case 'L':
823                        Lflag = 1;
824                        break;
825                case 'M':
826                        memf = optarg;
827                        break;
828                case 'm':
829                        mflag = 1;
830                        break;
831                case 'N':
832                        nlistf = optarg;
833                        break;
834                case 'n':
835                        numeric_addr = numeric_port = 1;
836                        break;
837                case 'p':
838                        if ((tp = name2protox(optarg)) == NULL) {
839                                errx(1,
840                                     "%s: unknown or uninstrumented protocol",
841                                     optarg);
842                        }
843                        pflag = 1;
844                        break;
845                case 'q':
846                        noutputs = atoi(optarg);
847                        if (noutputs != 0)
848                                noutputs++;
849                        break;
850                case 'r':
851                        rflag = 1;
852                        break;
853                case 's':
854                        ++sflag;
855                        break;
856                case 'S':
857                        numeric_addr = 1;
858                        break;
859                case 't':
860                        tflag = 1;
861                        break;
862                case 'u':
863                        af = AF_UNIX;
864                        break;
865                case 'W':
866                case 'l':
867                        Wflag = 1;
868                        break;
869                case 'w':
870                        interval = atoi(optarg);
871                        iflag = 1;
872                        break;
873                case 'x':
874                        xflag = 1;
875                        break;
876                case 'z':
877                        zflag = 1;
878                        break;
879                case '?':
880                default:
881                        usage();
882                }
883        argv += optind;
884        argc -= optind;
885
886#define BACKWARD_COMPATIBILITY
887#ifdef  BACKWARD_COMPATIBILITY
888        if (*argv) {
889                if (isdigit(**argv)) {
890                        interval = atoi(*argv);
891                        if (interval <= 0)
892                                usage();
893                        ++argv;
894                        iflag = 1;
895                }
896                if (*argv) {
897                        nlistf = *argv;
898                        if (*++argv)
899                                memf = *argv;
900                }
901        }
902#endif
903
904        /*
905         * Discard setgid privileges if not the running kernel so that bad
906         * guys can't print interesting stuff from kernel memory.
907         */
908        live = (nlistf == NULL && memf == NULL);
909        if (!live)
910                setgid(getgid());
911
912        if (Bflag) {
913                if (!live)
914                        usage();
915                bpf_stats(interface);
916                exit(0);
917        }
918        if (mflag) {
919                if (!live) {
920                        if (kread(0, NULL, 0) == 0)
921                                mbpr(kvmd, nl[N_MBSTAT].n_value);
922                } else
923                        mbpr(NULL, 0);
924                exit(0);
925        }
926#if 0
927        /*
928         * Keep file descriptors open to avoid overhead
929         * of open/close on each call to get* routines.
930         */
931        sethostent(1);
932        setnetent(1);
933#else
934        /*
935         * This does not make sense any more with DNS being default over
936         * the files.  Doing a setXXXXent(1) causes a tcp connection to be
937         * used for the queries, which is slower.
938         */
939#endif
940        kread(0, NULL, 0);
941        if (iflag && !sflag) {
942                intpr(interval, nl[N_IFNET].n_value, NULL);
943                exit(0);
944        }
945        if (rflag) {
946                if (sflag)
947                        rt_stats(nl[N_RTSTAT].n_value, nl[N_RTTRASH].n_value);
948                else
949                        routepr(nl[N_RTREE].n_value);
950                exit(0);
951        }
952        if (gflag) {
953                if (sflag) {
954                        if (af == AF_INET || af == AF_UNSPEC)
955                                mrt_stats(nl[N_MRTSTAT].n_value);
956#ifdef INET6
957                        if (af == AF_INET6 || af == AF_UNSPEC)
958                                mrt6_stats(nl[N_MRT6STAT].n_value);
959#endif
960                } else {
961                        if (af == AF_INET || af == AF_UNSPEC)
962                                mroutepr(nl[N_MFCHASHTBL].n_value,
963                                         nl[N_MFCTABLESIZE].n_value,
964                                         nl[N_VIFTABLE].n_value);
965#ifdef INET6
966                        if (af == AF_INET6 || af == AF_UNSPEC)
967                                mroute6pr(nl[N_MF6CTABLE].n_value,
968                                          nl[N_MIF6TABLE].n_value);
969#endif
970                }
971                exit(0);
972        }
973
974        if (tp) {
975                printproto(tp, tp->pr_name);
976                exit(0);
977        }
978        if (af == AF_INET || af == AF_UNSPEC)
979                for (tp = protox; tp->pr_name; tp++)
980                        printproto(tp, tp->pr_name);
981#ifdef INET6
982        if (af == AF_INET6 || af == AF_UNSPEC)
983                for (tp = ip6protox; tp->pr_name; tp++)
984                        printproto(tp, tp->pr_name);
985#endif /*INET6*/
986#ifdef IPSEC
987        if (af == PF_KEY || af == AF_UNSPEC)
988                for (tp = pfkeyprotox; tp->pr_name; tp++)
989                        printproto(tp, tp->pr_name);
990#endif /*IPSEC*/
991#ifdef IPX
992        if (af == AF_IPX || af == AF_UNSPEC) {
993                for (tp = ipxprotox; tp->pr_name; tp++)
994                        printproto(tp, tp->pr_name);
995        }
996#endif /* IPX */
997#ifndef __rtems__
998        if (af == AF_APPLETALK || af == AF_UNSPEC)
999                for (tp = atalkprotox; tp->pr_name; tp++)
1000                        printproto(tp, tp->pr_name);
1001#endif
1002#ifdef NETGRAPH
1003        if (af == AF_NETGRAPH || af == AF_UNSPEC)
1004                for (tp = netgraphprotox; tp->pr_name; tp++)
1005                        printproto(tp, tp->pr_name);
1006#endif /* NETGRAPH */
1007#ifndef __rtems__
1008        if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)
1009                unixpr(nl[N_UNP_COUNT].n_value, nl[N_UNP_GENCNT].n_value,
1010                    nl[N_UNP_DHEAD].n_value, nl[N_UNP_SHEAD].n_value);
1011#endif
1012        exit(0);
1013}
1014
1015/*
1016 * Print out protocol statistics or control blocks (per sflag).
1017 * If the interface was not specifically requested, and the symbol
1018 * is not in the namelist, ignore this one.
1019 */
1020static void
1021printproto(tp, name)
1022        struct protox *tp;
1023        const char *name;
1024{
1025        void (*pr)(u_long, const char *, int, int);
1026        u_long off;
1027
1028        if (sflag) {
1029                if (iflag) {
1030                        if (tp->pr_istats)
1031                                intpr(interval, nl[N_IFNET].n_value,
1032                                      tp->pr_istats);
1033                        else if (pflag)
1034                                printf("%s: no per-interface stats routine\n",
1035                                    tp->pr_name);
1036                        return;
1037                } else {
1038                        pr = tp->pr_stats;
1039                        if (!pr) {
1040                                if (pflag)
1041                                        printf("%s: no stats routine\n",
1042                                            tp->pr_name);
1043                                return;
1044                        }
1045                        if (tp->pr_usesysctl && live)
1046                                off = 0;
1047                        else if (tp->pr_sindex < 0) {
1048                                if (pflag)
1049                                        printf(
1050                                    "%s: stats routine doesn't work on cores\n",
1051                                            tp->pr_name);
1052                                return;
1053                        } else
1054                                off = nl[tp->pr_sindex].n_value;
1055                }
1056        } else {
1057                pr = tp->pr_cblocks;
1058                if (!pr) {
1059                        if (pflag)
1060                                printf("%s: no PCB routine\n", tp->pr_name);
1061                        return;
1062                }
1063                if (tp->pr_usesysctl && live)
1064                        off = 0;
1065                else if (tp->pr_index < 0) {
1066                        if (pflag)
1067                                printf(
1068                                    "%s: PCB routine doesn't work on cores\n",
1069                                    tp->pr_name);
1070                        return;
1071                } else
1072                        off = nl[tp->pr_index].n_value;
1073        }
1074        if (pr != NULL && (off || (live && tp->pr_usesysctl) ||
1075            af != AF_UNSPEC))
1076                (*pr)(off, name, af, tp->pr_protocol);
1077}
1078
1079#ifdef __rtems__
1080#define _POSIX2_LINE_MAX 128
1081#endif
1082
1083/*
1084 * Read kernel memory, return 0 on success.
1085 */
1086int
1087kread(u_long addr, void *buf, size_t size)
1088{
1089        char errbuf[_POSIX2_LINE_MAX];
1090#ifdef __rtems__
1091        /* printf( "kread( %p to %p for %d)\n", (void *)addr, buf, size ); */
1092#endif
1093
1094        if (kvmd == NULL) {
1095                kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);
1096                setgid(getgid());
1097                if (kvmd != NULL) {
1098                        if (kvm_nlist(kvmd, nl) < 0) {
1099                                if (nlistf)
1100                                        errx(1, "%s: kvm_nlist: %s", nlistf,
1101                                             kvm_geterr(kvmd));
1102                                else
1103                                        errx(1, "kvm_nlist: %s", kvm_geterr(kvmd));
1104                        }
1105
1106                        if (nl[0].n_type == 0) {
1107                                if (nlistf)
1108                                        errx(1, "%s: no namelist", nlistf);
1109                                else
1110                                        errx(1, "no namelist");
1111                        }
1112                } else {
1113                        warnx("kvm not available: %s", errbuf);
1114                        return(-1);
1115                }
1116        }
1117        if (!buf)
1118                return (0);
1119        if (kvm_read(kvmd, addr, buf, size) != (ssize_t)size) {
1120                warnx("%s", kvm_geterr(kvmd));
1121                return (-1);
1122        }
1123        return (0);
1124}
1125
1126const char *
1127plural(uintmax_t n)
1128{
1129        return (n != 1 ? "s" : "");
1130}
1131
1132const char *
1133plurales(uintmax_t n)
1134{
1135        return (n != 1 ? "es" : "");
1136}
1137
1138const char *
1139pluralies(uintmax_t n)
1140{
1141        return (n != 1 ? "ies" : "y");
1142}
1143
1144/*
1145 * Find the protox for the given "well-known" name.
1146 */
1147static struct protox *
1148knownname(const char *name)
1149{
1150        struct protox **tpp, *tp;
1151
1152        for (tpp = protoprotox; *tpp; tpp++)
1153                for (tp = *tpp; tp->pr_name; tp++)
1154                        if (strcmp(tp->pr_name, name) == 0)
1155                                return (tp);
1156        return (NULL);
1157}
1158
1159/*
1160 * Find the protox corresponding to name.
1161 */
1162static struct protox *
1163name2protox(const char *name)
1164{
1165        struct protox *tp;
1166        char **alias;                   /* alias from p->aliases */
1167        struct protoent *p;
1168
1169        /*
1170         * Try to find the name in the list of "well-known" names. If that
1171         * fails, check if name is an alias for an Internet protocol.
1172         */
1173        if ((tp = knownname(name)) != NULL)
1174                return (tp);
1175
1176        setprotoent(1);                 /* make protocol lookup cheaper */
1177        while ((p = getprotoent()) != NULL) {
1178                /* assert: name not same as p->name */
1179                for (alias = p->p_aliases; *alias; alias++)
1180                        if (strcmp(name, *alias) == 0) {
1181                                endprotoent();
1182                                return (knownname(p->p_name));
1183                        }
1184        }
1185        endprotoent();
1186        return (NULL);
1187}
1188
1189static void
1190usage(void)
1191{
1192        (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
1193"usage: netstat [-AaLnSWx] [-f protocol_family | -p protocol]\n"
1194"               [-M core] [-N system]",
1195"       netstat -i | -I interface [-abdhntW] [-f address_family]\n"
1196"               [-M core] [-N system]",
1197"       netstat -w wait [-I interface] [-d] [-M core] [-N system] [-q howmany]",
1198"       netstat -s [-s] [-z] [-f protocol_family | -p protocol]\n"
1199"               [-M core] [-N system]",
1200"       netstat -i | -I interface -s [-f protocol_family | -p protocol]\n"
1201"               [-M core] [-N system]",
1202"       netstat -m [-M core] [-N system]",
1203"       netstat -B [-I interface]",
1204"       netstat -r [-AanW] [-f address_family] [-M core] [-N system]",
1205"       netstat -rs [-s] [-M core] [-N system]",
1206"       netstat -g [-W] [-f address_family] [-M core] [-N system]",
1207"       netstat -gs [-s] [-f address_family] [-M core] [-N system]");
1208        exit(1);
1209}
1210
1211#ifdef __rtems__
1212  #include <rtems/shell.h>
1213
1214  rtems_shell_cmd_t rtems_shell_NETSTAT_Command = {
1215    "netstat",                     /* name */
1216    "netstat [args]",              /* usage */
1217    "net",                         /* topic */
1218    rtems_shell_main_netstat,      /* command */
1219    NULL,                          /* alias */
1220    NULL                           /* next */
1221  };
1222#endif
Note: See TracBrowser for help on using the repository browser.