source: rtems-libbsd/freebsd-userspace/commands/usr.bin/netstat/main.c @ af0a8ea

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since af0a8ea was af0a8ea, checked in by Joel Sherrill <joel.sherrill@…>, on 10/25/12 at 14:03:28

netstat/kvm: Disable debug prints

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