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

4.115-freebsd-12freebsd-9.3
Last change on this file since 6da9b23 was 6da9b23, checked in by Sebastian Huber <sebastian.huber@…>, on Oct 30, 2013 at 2:42:53 PM

NETSTAT(1): Initialize global variables

Use BSD program lock.

  • Property mode set to 100644
File size: 21.2 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#include <machine/rtems-bsd-program.h>
50#include <machine/rtems-bsd-commands.h>
51#endif /* __rtems__ */
52#include <sys/cdefs.h>
53__FBSDID("$FreeBSD$");
54
55#include <rtems/bsd/sys/param.h>
56#include <sys/file.h>
57#include <sys/protosw.h>
58#include <sys/socket.h>
59#include <sys/socketvar.h>
60
61#include <netinet/in.h>
62
63#ifdef NETGRAPH
64#include <netgraph/ng_socket.h>
65#endif
66
67#include <ctype.h>
68#include <err.h>
69#include <errno.h>
70#include <kvm.h>
71#include <limits.h>
72#include <netdb.h>
73#include <nlist.h>
74#include <paths.h>
75#include <stdint.h>
76#include <stdio.h>
77#include <stdlib.h>
78#include <string.h>
79#include <unistd.h>
80#include "netstat.h"
81
82static struct nlist nl[] = {
83#define N_IFNET         0
84        { .n_name = "_ifnet" },
85#define N_RTSTAT        1
86        { .n_name = "_rtstat" },
87#define N_RTREE         2
88        { .n_name = "_rt_tables"},
89#define N_MRTSTAT       3
90        { .n_name = "_mrtstat" },
91#define N_MFCHASHTBL    4
92        { .n_name = "_mfchashtbl" },
93#define N_VIFTABLE      5
94        { .n_name = "_viftable" },
95#define N_IPX           6
96        { .n_name = "_ipxpcb_list"},
97#define N_IPXSTAT       7
98        { .n_name = "_ipxstat"},
99#define N_SPXSTAT       8
100        { .n_name = "_spx_istat"},
101#define N_DDPSTAT       9
102        { .n_name = "_ddpstat"},
103#define N_DDPCB         10
104        { .n_name = "_ddpcb"},
105#define N_NGSOCKS       11
106        { .n_name = "_ngsocklist"},
107#define N_IP6STAT       12
108        { .n_name = "_ip6stat" },
109#define N_ICMP6STAT     13
110        { .n_name = "_icmp6stat" },
111#define N_IPSECSTAT     14
112        { .n_name = "_ipsec4stat" },
113#define N_IPSEC6STAT    15
114        { .n_name = "_ipsec6stat" },
115#define N_PIM6STAT      16
116        { .n_name = "_pim6stat" },
117#define N_MRT6STAT      17
118        { .n_name = "_mrt6stat" },
119#define N_MF6CTABLE     18
120        { .n_name = "_mf6ctable" },
121#define N_MIF6TABLE     19
122        { .n_name = "_mif6table" },
123#define N_PFKEYSTAT     20
124        { .n_name = "_pfkeystat" },
125#define N_MBSTAT        21
126        { .n_name = "_mbstat" },
127#define N_MBTYPES       22
128        { .n_name = "_mbtypes" },
129#define N_NMBCLUSTERS   23
130        { .n_name = "_nmbclusters" },
131#define N_NMBUFS        24
132        { .n_name = "_nmbufs" },
133#define N_MBHI          25
134        { .n_name = "_mbuf_hiwm" },
135#define N_CLHI          26
136        { .n_name = "_clust_hiwm" },
137#define N_NCPUS         27
138        { .n_name = "_smp_cpus" },
139#define N_PAGESZ        28
140        { .n_name = "_pagesize" },
141#define N_MBPSTAT       29
142        { .n_name = "_mb_statpcpu" },
143#define N_RTTRASH       30
144        { .n_name = "_rttrash" },
145#define N_MBLO          31
146        { .n_name = "_mbuf_lowm" },
147#define N_CLLO          32
148        { .n_name = "_clust_lowm" },
149#define N_CARPSTAT      33
150        { .n_name = "_carpstats" },
151#define N_PFSYNCSTAT    34
152        { .n_name = "_pfsyncstats" },
153#define N_AHSTAT        35
154        { .n_name = "_ahstat" },
155#define N_ESPSTAT       36
156        { .n_name = "_espstat" },
157#define N_IPCOMPSTAT    37
158        { .n_name = "_ipcompstat" },
159#define N_TCPSTAT       38
160        { .n_name = "_tcpstat" },
161#define N_UDPSTAT       39
162        { .n_name = "_udpstat" },
163#define N_IPSTAT        40
164        { .n_name = "_ipstat" },
165#define N_ICMPSTAT      41
166        { .n_name = "_icmpstat" },
167#define N_IGMPSTAT      42
168        { .n_name = "_igmpstat" },
169#define N_PIMSTAT       43
170        { .n_name = "_pimstat" },
171#define N_TCBINFO       44
172        { .n_name = "_tcbinfo" },
173#define N_UDBINFO       45
174        { .n_name = "_udbinfo" },
175#define N_DIVCBINFO     46
176        { .n_name = "_divcbinfo" },
177#define N_RIPCBINFO     47
178        { .n_name = "_ripcbinfo" },
179#define N_UNP_COUNT     48
180        { .n_name = "_unp_count" },
181#define N_UNP_GENCNT    49
182        { .n_name = "_unp_gencnt" },
183#define N_UNP_DHEAD     50
184        { .n_name = "_unp_dhead" },
185#define N_UNP_SHEAD     51
186        { .n_name = "_unp_shead" },
187#define N_RIP6STAT      52
188        { .n_name = "_rip6stat" },
189#define N_SCTPSTAT      53
190        { .n_name = "_sctpstat" },
191#define N_MFCTABLESIZE  54
192        { .n_name = "_mfctablesize" },
193#define N_ARPSTAT       55
194        { .n_name = "_arpstat" },
195        { .n_name = NULL },
196};
197
198struct protox {
199        int     pr_index;               /* index into nlist of cb head */
200        int     pr_sindex;              /* index into nlist of stat block */
201        u_char  pr_wanted;              /* 1 if wanted, 0 otherwise */
202        void    (*pr_cblocks)(u_long, const char *, int, int);
203                                        /* control blocks printing routine */
204        void    (*pr_stats)(u_long, const char *, int, int);
205                                        /* statistics printing routine */
206        void    (*pr_istats)(char *);   /* per/if statistics printing routine */
207        const char      *pr_name;               /* well-known name */
208        int     pr_usesysctl;           /* non-zero if we use sysctl, not kvm */
209        int     pr_protocol;
210} static const protox[] = {
211        { N_TCBINFO,    N_TCPSTAT,      1,      protopr,
212          tcp_stats,    NULL,           "tcp",  1,      IPPROTO_TCP },
213        { N_UDBINFO,    N_UDPSTAT,      1,      protopr,
214          udp_stats,    NULL,           "udp",  1,      IPPROTO_UDP },
215#ifdef SCTP
216        { -1,           N_SCTPSTAT,     1,      sctp_protopr,
217          sctp_stats,   NULL,           "sctp", 1,      IPPROTO_SCTP },
218#endif
219        { N_DIVCBINFO,  -1,             1,      protopr,
220          NULL,         NULL,           "divert", 1,    IPPROTO_DIVERT },
221        { N_RIPCBINFO,  N_IPSTAT,       1,      protopr,
222          ip_stats,     NULL,           "ip",   1,      IPPROTO_RAW },
223        { N_RIPCBINFO,  N_ICMPSTAT,     1,      protopr,
224          icmp_stats,   NULL,           "icmp", 1,      IPPROTO_ICMP },
225        { N_RIPCBINFO,  N_IGMPSTAT,     1,      protopr,
226          igmp_stats,   NULL,           "igmp", 1,      IPPROTO_IGMP },
227#ifdef IPSEC
228        { -1,           N_IPSECSTAT,    1,      NULL,   /* keep as compat */
229          ipsec_stats,  NULL,           "ipsec", 0,     0},
230        { -1,           N_AHSTAT,       1,      NULL,
231          ah_stats,     NULL,           "ah",   0,      0},
232        { -1,           N_ESPSTAT,      1,      NULL,
233          esp_stats,    NULL,           "esp",  0,      0},
234        { -1,           N_IPCOMPSTAT,   1,      NULL,
235          ipcomp_stats, NULL,           "ipcomp", 0,    0},
236#endif
237        { N_RIPCBINFO,  N_PIMSTAT,      1,      protopr,
238          pim_stats,    NULL,           "pim",  1,      IPPROTO_PIM },
239        { -1,           N_CARPSTAT,     1,      NULL,
240          carp_stats,   NULL,           "carp", 1,      0 },
241        { -1,           N_PFSYNCSTAT,   1,      NULL,
242          pfsync_stats, NULL,           "pfsync", 1,    0 },
243        { -1,           N_ARPSTAT,      1,      NULL,
244          arp_stats,    NULL,           "arp", 1,       0 },
245        { -1,           -1,             0,      NULL,
246          NULL,         NULL,           NULL,   0,      0 }
247};
248
249#ifdef INET6
250static const struct protox ip6protox[] = {
251        { N_TCBINFO,    N_TCPSTAT,      1,      protopr,
252          tcp_stats,    NULL,           "tcp",  1,      IPPROTO_TCP },
253        { N_UDBINFO,    N_UDPSTAT,      1,      protopr,
254          udp_stats,    NULL,           "udp",  1,      IPPROTO_UDP },
255        { N_RIPCBINFO,  N_IP6STAT,      1,      protopr,
256          ip6_stats,    ip6_ifstats,    "ip6",  1,      IPPROTO_RAW },
257        { N_RIPCBINFO,  N_ICMP6STAT,    1,      protopr,
258          icmp6_stats,  icmp6_ifstats,  "icmp6", 1,     IPPROTO_ICMPV6 },
259#ifdef IPSEC
260        { -1,           N_IPSEC6STAT,   1,      NULL,
261          ipsec_stats,  NULL,           "ipsec6", 0,    0 },
262#endif
263#ifdef notyet
264        { -1,           N_PIM6STAT,     1,      NULL,
265          pim6_stats,   NULL,           "pim6", 1,      0 },
266#endif
267        { -1,           N_RIP6STAT,     1,      NULL,
268          rip6_stats,   NULL,           "rip6", 1,      0 },
269        { -1,           -1,             0,      NULL,
270          NULL,         NULL,           NULL,   0,      0 }
271};
272#endif /*INET6*/
273
274#ifdef IPSEC
275static const struct protox pfkeyprotox[] = {
276        { -1,           N_PFKEYSTAT,    1,      NULL,
277          pfkey_stats,  NULL,           "pfkey", 0,     0 },
278        { -1,           -1,             0,      NULL,
279          NULL,         NULL,           NULL,   0,      0 }
280};
281#endif
282
283#ifndef __rtems__
284static const struct protox atalkprotox[] = {
285        { N_DDPCB,      N_DDPSTAT,      1,      atalkprotopr,
286          ddp_stats,    NULL,           "ddp",  0,      0 },
287        { -1,           -1,             0,      NULL,
288          NULL,         NULL,           NULL,   0,      0 }
289};
290#endif
291#ifdef NETGRAPH
292static const struct protox netgraphprotox[] = {
293        { N_NGSOCKS,    -1,             1,      netgraphprotopr,
294          NULL,         NULL,           "ctrl", 0,      0 },
295        { N_NGSOCKS,    -1,             1,      netgraphprotopr,
296          NULL,         NULL,           "data", 0,      0 },
297        { -1,           -1,             0,      NULL,
298          NULL,         NULL,           NULL,   0,      0 }
299};
300#endif
301#ifdef IPX
302static const struct protox ipxprotox[] = {
303        { N_IPX,        N_IPXSTAT,      1,      ipxprotopr,
304          ipx_stats,    NULL,           "ipx",  0,      0 },
305        { N_IPX,        N_SPXSTAT,      1,      ipxprotopr,
306          spx_stats,    NULL,           "spx",  0,      0 },
307        { -1,           -1,             0,      NULL,
308          NULL,         NULL,           0,      0,      0 }
309};
310#endif
311
312static const struct protox *protoprotox[] = {
313                                         protox,
314#ifdef INET6
315                                         ip6protox,
316#endif
317#ifdef IPSEC
318                                         pfkeyprotox,
319#endif
320#ifdef IPX
321                                         ipxprotox,
322#endif
323#ifndef __rtems__
324                                         atalkprotox, NULL };
325#else
326                                NULL };
327#endif
328
329static void printproto(const struct protox *, const char *);
330static void usage(void);
331static const struct protox *name2protox(const char *);
332static const struct protox *knownname(const char *);
333
334static kvm_t *kvmd;
335static char *nlistf = NULL, *memf = NULL;
336
337int     Aflag;          /* show addresses of protocol control block */
338int     aflag;          /* show all sockets (including servers) */
339int     Bflag;          /* show information about bpf consumers */
340int     bflag;          /* show i/f total bytes in/out */
341int     dflag;          /* show i/f dropped packets */
342int     gflag;          /* show group (multicast) routing or stats */
343int     hflag;          /* show counters in human readable format */
344int     iflag;          /* show interfaces */
345int     Lflag;          /* show size of listen queues */
346int     mflag;          /* show memory stats */
347int     noutputs = 0;   /* how much outputs before we exit */
348int     numeric_addr;   /* show addresses numerically */
349int     numeric_port;   /* show ports numerically */
350static int pflag;       /* show given protocol */
351int     rflag;          /* show routing tables (or routing stats) */
352int     sflag;          /* show protocol statistics */
353int     tflag;          /* show i/f watchdog timers */
354int     Wflag;          /* wide display */
355int     xflag;          /* extra information, includes all socket buffer info */
356int     zflag;          /* zero stats */
357
358int     interval;       /* repeat interval for i/f stats */
359
360char    *interface;     /* desired i/f for stats, or NULL for all i/fs */
361int     unit;           /* unit number for above */
362
363int     af;             /* address family */
364int     live;           /* true if we are examining a live system */
365
366#ifdef __rtems__
367int     protopr_initialized;
368int     do_rtent;
369struct  radix_node_head **rt_tables;
370
371static int main(int argc, char *argv[]);
372
373int rtems_bsd_command_netstat(int argc, char *argv[])
374{
375        int exit_code;
376
377        rtems_bsd_program_lock();
378
379        Aflag = 0;
380        aflag = 0;
381        bflag = 0;
382        dflag = 0;
383        gflag = 0;
384        hflag = 0;
385        iflag = 0;
386        Lflag = 0;
387        mflag = 0;
388        noutputs = 0;
389        numeric_addr = 0;
390        numeric_port = 0;
391        pflag = 0;
392        rflag = 0;
393        sflag = 0;
394        tflag = 0;
395        Wflag = 0;
396        xflag = 0;
397        zflag = 0;
398        interval = 0;
399        interface = 0;
400        unit = 0;
401        af = 0;
402        live = 0;
403
404        protopr_initialized = 0;
405        do_rtent = 0;
406
407        exit_code = rtems_bsd_program_call_main("netstat", main, argc, argv);
408
409        free(rt_tables);
410        rt_tables = NULL;
411
412        rtems_bsd_program_unlock();
413
414        return exit_code;
415}
416#endif /* __rtems__ */
417int
418main(int argc, char *argv[])
419{
420        const struct protox *tp = NULL;  /* for printing cblocks & stats */
421        int ch;
422#ifdef __rtems__
423        struct getopt_data getopt_data;
424        memset(&getopt_data, 0, sizeof(getopt_data));
425#define optind getopt_data.optind
426#define optarg getopt_data.optarg
427#define opterr getopt_data.opterr
428#define optopt getopt_data.optopt
429#define getopt(argc, argv, opt) getopt_r(argc, argv, opt, &getopt_data)
430#endif /* __rtems__ */
431
432        af = AF_UNSPEC;
433
434        while ((ch = getopt(argc, argv, "AaBbdf:ghI:iLlM:mN:np:q:rSstuWw:xz")) != -1)
435                switch(ch) {
436                case 'A':
437                        Aflag = 1;
438                        break;
439                case 'a':
440                        aflag = 1;
441                        break;
442                case 'B':
443                        Bflag = 1;
444                        break;
445                case 'b':
446                        bflag = 1;
447                        break;
448                case 'd':
449                        dflag = 1;
450                        break;
451                case 'f':
452                        if (strcmp(optarg, "ipx") == 0)
453                                af = AF_IPX;
454                        else if (strcmp(optarg, "inet") == 0)
455                                af = AF_INET;
456#ifdef INET6
457                        else if (strcmp(optarg, "inet6") == 0)
458                                af = AF_INET6;
459#endif
460#ifdef IPSEC
461                        else if (strcmp(optarg, "pfkey") == 0)
462                                af = PF_KEY;
463#endif
464                        else if (strcmp(optarg, "unix") == 0)
465                                af = AF_UNIX;
466                        else if (strcmp(optarg, "atalk") == 0)
467                                af = AF_APPLETALK;
468#ifdef NETGRAPH
469                        else if (strcmp(optarg, "ng") == 0
470                            || strcmp(optarg, "netgraph") == 0)
471                                af = AF_NETGRAPH;
472#endif
473                        else if (strcmp(optarg, "link") == 0)
474                                af = AF_LINK;
475                        else {
476                                errx(1, "%s: unknown address family", optarg);
477                        }
478                        break;
479                case 'g':
480                        gflag = 1;
481                        break;
482                case 'h':
483                        hflag = 1;
484                        break;
485                case 'I': {
486                        char *cp;
487
488                        iflag = 1;
489                        for (cp = interface = optarg; isalpha((unsigned char) *cp); cp++)
490                                continue;
491                        unit = atoi(cp);
492                        break;
493                }
494                case 'i':
495                        iflag = 1;
496                        break;
497                case 'L':
498                        Lflag = 1;
499                        break;
500                case 'M':
501                        memf = optarg;
502                        break;
503                case 'm':
504                        mflag = 1;
505                        break;
506                case 'N':
507                        nlistf = optarg;
508                        break;
509                case 'n':
510                        numeric_addr = numeric_port = 1;
511                        break;
512                case 'p':
513                        if ((tp = name2protox(optarg)) == NULL) {
514                                errx(1,
515                                     "%s: unknown or uninstrumented protocol",
516                                     optarg);
517                        }
518                        pflag = 1;
519                        break;
520                case 'q':
521                        noutputs = atoi(optarg);
522                        if (noutputs != 0)
523                                noutputs++;
524                        break;
525                case 'r':
526                        rflag = 1;
527                        break;
528                case 's':
529                        ++sflag;
530                        break;
531                case 'S':
532                        numeric_addr = 1;
533                        break;
534                case 't':
535                        tflag = 1;
536                        break;
537                case 'u':
538                        af = AF_UNIX;
539                        break;
540                case 'W':
541                case 'l':
542                        Wflag = 1;
543                        break;
544                case 'w':
545                        interval = atoi(optarg);
546                        iflag = 1;
547                        break;
548                case 'x':
549                        xflag = 1;
550                        break;
551                case 'z':
552                        zflag = 1;
553                        break;
554                case '?':
555                default:
556                        usage();
557                }
558        argv += optind;
559        argc -= optind;
560
561#define BACKWARD_COMPATIBILITY
562#ifdef  BACKWARD_COMPATIBILITY
563        if (*argv) {
564                if (isdigit((unsigned char) **argv)) {
565                        interval = atoi(*argv);
566                        if (interval <= 0)
567                                usage();
568                        ++argv;
569                        iflag = 1;
570                }
571                if (*argv) {
572                        nlistf = *argv;
573                        if (*++argv)
574                                memf = *argv;
575                }
576        }
577#endif
578
579        /*
580         * Discard setgid privileges if not the running kernel so that bad
581         * guys can't print interesting stuff from kernel memory.
582         */
583        live = (nlistf == NULL && memf == NULL);
584        if (!live)
585                setgid(getgid());
586
587        if (Bflag) {
588                if (!live)
589                        usage();
590                bpf_stats(interface);
591                exit(0);
592        }
593        if (mflag) {
594                if (!live) {
595                        if (kread(0, NULL, 0) == 0)
596                                mbpr(kvmd, nl[N_MBSTAT].n_value);
597                } else
598                        mbpr(NULL, 0);
599                exit(0);
600        }
601#if 0
602        /*
603         * Keep file descriptors open to avoid overhead
604         * of open/close on each call to get* routines.
605         */
606        sethostent(1);
607        setnetent(1);
608#else
609        /*
610         * This does not make sense any more with DNS being default over
611         * the files.  Doing a setXXXXent(1) causes a tcp connection to be
612         * used for the queries, which is slower.
613         */
614#endif
615        kread(0, NULL, 0);
616        if (iflag && !sflag) {
617                intpr(interval, nl[N_IFNET].n_value, NULL);
618                exit(0);
619        }
620        if (rflag) {
621                if (sflag)
622                        rt_stats(nl[N_RTSTAT].n_value, nl[N_RTTRASH].n_value);
623                else
624                        routepr(nl[N_RTREE].n_value);
625                exit(0);
626        }
627        if (gflag) {
628                if (sflag) {
629                        if (af == AF_INET || af == AF_UNSPEC)
630                                mrt_stats(nl[N_MRTSTAT].n_value);
631#ifdef INET6
632                        if (af == AF_INET6 || af == AF_UNSPEC)
633                                mrt6_stats(nl[N_MRT6STAT].n_value);
634#endif
635                } else {
636                        if (af == AF_INET || af == AF_UNSPEC)
637                                mroutepr(nl[N_MFCHASHTBL].n_value,
638                                         nl[N_MFCTABLESIZE].n_value,
639                                         nl[N_VIFTABLE].n_value);
640#ifdef INET6
641                        if (af == AF_INET6 || af == AF_UNSPEC)
642                                mroute6pr(nl[N_MF6CTABLE].n_value,
643                                          nl[N_MIF6TABLE].n_value);
644#endif
645                }
646                exit(0);
647        }
648
649        if (tp) {
650                printproto(tp, tp->pr_name);
651                exit(0);
652        }
653        if (af == AF_INET || af == AF_UNSPEC)
654                for (tp = protox; tp->pr_name; tp++)
655                        printproto(tp, tp->pr_name);
656#ifdef INET6
657        if (af == AF_INET6 || af == AF_UNSPEC)
658                for (tp = ip6protox; tp->pr_name; tp++)
659                        printproto(tp, tp->pr_name);
660#endif /*INET6*/
661#ifdef IPSEC
662        if (af == PF_KEY || af == AF_UNSPEC)
663                for (tp = pfkeyprotox; tp->pr_name; tp++)
664                        printproto(tp, tp->pr_name);
665#endif /*IPSEC*/
666#ifdef IPX
667        if (af == AF_IPX || af == AF_UNSPEC) {
668                for (tp = ipxprotox; tp->pr_name; tp++)
669                        printproto(tp, tp->pr_name);
670        }
671#endif /* IPX */
672#ifndef __rtems__
673        if (af == AF_APPLETALK || af == AF_UNSPEC)
674                for (tp = atalkprotox; tp->pr_name; tp++)
675                        printproto(tp, tp->pr_name);
676#endif
677#ifdef NETGRAPH
678        if (af == AF_NETGRAPH || af == AF_UNSPEC)
679                for (tp = netgraphprotox; tp->pr_name; tp++)
680                        printproto(tp, tp->pr_name);
681#endif /* NETGRAPH */
682#ifndef __rtems__
683        if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)
684                unixpr(nl[N_UNP_COUNT].n_value, nl[N_UNP_GENCNT].n_value,
685                    nl[N_UNP_DHEAD].n_value, nl[N_UNP_SHEAD].n_value);
686#endif
687        exit(0);
688}
689
690/*
691 * Print out protocol statistics or control blocks (per sflag).
692 * If the interface was not specifically requested, and the symbol
693 * is not in the namelist, ignore this one.
694 */
695static void
696printproto(tp, name)
697        const struct protox *tp;
698        const char *name;
699{
700        void (*pr)(u_long, const char *, int, int);
701        u_long off;
702
703        if (sflag) {
704                if (iflag) {
705                        if (tp->pr_istats)
706                                intpr(interval, nl[N_IFNET].n_value,
707                                      tp->pr_istats);
708                        else if (pflag)
709                                printf("%s: no per-interface stats routine\n",
710                                    tp->pr_name);
711                        return;
712                } else {
713                        pr = tp->pr_stats;
714                        if (!pr) {
715                                if (pflag)
716                                        printf("%s: no stats routine\n",
717                                            tp->pr_name);
718                                return;
719                        }
720                        if (tp->pr_usesysctl && live)
721                                off = 0;
722                        else if (tp->pr_sindex < 0) {
723                                if (pflag)
724                                        printf(
725                                    "%s: stats routine doesn't work on cores\n",
726                                            tp->pr_name);
727                                return;
728                        } else
729                                off = nl[tp->pr_sindex].n_value;
730                }
731        } else {
732                pr = tp->pr_cblocks;
733                if (!pr) {
734                        if (pflag)
735                                printf("%s: no PCB routine\n", tp->pr_name);
736                        return;
737                }
738                if (tp->pr_usesysctl && live)
739                        off = 0;
740                else if (tp->pr_index < 0) {
741                        if (pflag)
742                                printf(
743                                    "%s: PCB routine doesn't work on cores\n",
744                                    tp->pr_name);
745                        return;
746                } else
747                        off = nl[tp->pr_index].n_value;
748        }
749        if (pr != NULL && (off || (live && tp->pr_usesysctl) ||
750            af != AF_UNSPEC))
751                (*pr)(off, name, af, tp->pr_protocol);
752}
753
754#ifdef __rtems__
755#define _POSIX2_LINE_MAX 128
756#endif
757
758/*
759 * Read kernel memory, return 0 on success.
760 */
761int
762kread(u_long addr, void *buf, size_t size)
763{
764        char errbuf[_POSIX2_LINE_MAX];
765#ifdef __rtems__
766        /* printf( "kread( %p to %p for %d)\n", (void *)addr, buf, size ); */
767#endif
768
769        if (kvmd == NULL) {
770                kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, errbuf);
771                setgid(getgid());
772                if (kvmd != NULL) {
773                        if (kvm_nlist(kvmd, nl) < 0) {
774                                if (nlistf)
775                                        errx(1, "%s: kvm_nlist: %s", nlistf,
776                                             kvm_geterr(kvmd));
777                                else
778                                        errx(1, "kvm_nlist: %s", kvm_geterr(kvmd));
779                        }
780
781                        if (nl[0].n_type == 0) {
782                                if (nlistf)
783                                        errx(1, "%s: no namelist", nlistf);
784                                else
785                                        errx(1, "no namelist");
786                        }
787                } else {
788                        warnx("kvm not available: %s", errbuf);
789                        return(-1);
790                }
791        }
792        if (!buf)
793                return (0);
794        if (kvm_read(kvmd, addr, buf, size) != (ssize_t)size) {
795                warnx("%s", kvm_geterr(kvmd));
796                return (-1);
797        }
798        return (0);
799}
800
801const char *
802plural(uintmax_t n)
803{
804        return (n != 1 ? "s" : "");
805}
806
807const char *
808plurales(uintmax_t n)
809{
810        return (n != 1 ? "es" : "");
811}
812
813const char *
814pluralies(uintmax_t n)
815{
816        return (n != 1 ? "ies" : "y");
817}
818
819/*
820 * Find the protox for the given "well-known" name.
821 */
822static const struct protox *
823knownname(const char *name)
824{
825        const struct protox **tpp, *tp;
826
827        for (tpp = protoprotox; *tpp; tpp++)
828                for (tp = *tpp; tp->pr_name; tp++)
829                        if (strcmp(tp->pr_name, name) == 0)
830                                return (tp);
831        return (NULL);
832}
833
834/*
835 * Find the protox corresponding to name.
836 */
837static const struct protox *
838name2protox(const char *name)
839{
840        const struct protox *tp;
841        char **alias;                   /* alias from p->aliases */
842        struct protoent *p;
843
844        /*
845         * Try to find the name in the list of "well-known" names. If that
846         * fails, check if name is an alias for an Internet protocol.
847         */
848        if ((tp = knownname(name)) != NULL)
849                return (tp);
850
851        setprotoent(1);                 /* make protocol lookup cheaper */
852        while ((p = getprotoent()) != NULL) {
853                /* assert: name not same as p->name */
854                for (alias = p->p_aliases; *alias; alias++)
855                        if (strcmp(name, *alias) == 0) {
856                                endprotoent();
857                                return (knownname(p->p_name));
858                        }
859        }
860        endprotoent();
861        return (NULL);
862}
863
864static void
865usage(void)
866{
867        (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",
868"usage: netstat [-AaLnSWx] [-f protocol_family | -p protocol]\n"
869"               [-M core] [-N system]",
870"       netstat -i | -I interface [-abdhntW] [-f address_family]\n"
871"               [-M core] [-N system]",
872"       netstat -w wait [-I interface] [-d] [-M core] [-N system] [-q howmany]",
873"       netstat -s [-s] [-z] [-f protocol_family | -p protocol]\n"
874"               [-M core] [-N system]",
875"       netstat -i | -I interface -s [-f protocol_family | -p protocol]\n"
876"               [-M core] [-N system]",
877"       netstat -m [-M core] [-N system]",
878"       netstat -B [-I interface]",
879"       netstat -r [-AanW] [-f address_family] [-M core] [-N system]",
880"       netstat -rs [-s] [-M core] [-N system]",
881"       netstat -g [-W] [-f address_family] [-M core] [-N system]",
882"       netstat -gs [-s] [-f address_family] [-M core] [-N system]");
883        exit(1);
884}
Note: See TracBrowser for help on using the repository browser.