]> git.saurik.com Git - apple/network_cmds.git/blobdiff - netstat.tproj/main.c
network_cmds-511.50.3.tar.gz
[apple/network_cmds.git] / netstat.tproj / main.c
index db882fc4c2e0e44d626171e13cf54b7cc488c3ee..6830b67d810ca127a72a775e7fc930b483434fcd 100644 (file)
@@ -1,25 +1,29 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2008-2015 Apple Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
  * 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*
  * Copyright (c) 1983, 1988, 1993
@@ -60,17 +64,10 @@ char const copyright[] =
        Regents of the University of California.  All rights reserved.\n";
 #endif /* not lint */
 
-#ifndef lint
-#if 0
-static char sccsid[] = "@(#)main.c     8.4 (Berkeley) 3/1/94";
-#endif
-static const char rcsid[] =
-       "$Id: main.c,v 1.8 2004/10/14 22:24:09 lindak Exp $";
-#endif /* not lint */
-
 #include <sys/param.h>
 #include <sys/file.h>
 #include <sys/socket.h>
+#include <sys/sys_domain.h>
 
 #include <netinet/in.h>
 #include <net/pfkeyv2.h>
@@ -78,7 +75,6 @@ static const char rcsid[] =
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
-#include <kvm.h>
 #include <limits.h>
 #include <netdb.h>
 #include <nlist.h>
@@ -91,6 +87,9 @@ static const char rcsid[] =
 #include <sys/types.h>
 #include <sys/sysctl.h>
 
+#ifdef __APPLE__
+#include <TargetConditionals.h>
+#endif
 
 /*
  * ----------------------------------------------------------------------------
@@ -104,236 +103,83 @@ static const char rcsid[] =
  *
  */
 
-static struct nlist nl[] = {
-#define        N_IFNET         0
-       { "_ifnet" },
-#define        N_IMP           1
-       { "_imp_softc" },
-#define        N_RTSTAT        2
-       { "_rtstat" },
-#define        N_UNIXSW        3
-       { "_localsw" },
-#define N_IDP          4
-       { "_nspcb"},
-#define N_IDPSTAT      5
-       { "_idpstat"},
-#define N_SPPSTAT      6
-       { "_spp_istat"},
-#define N_NSERR                7
-       { "_ns_errstat"},
-#define        N_CLNPSTAT      8
-       { "_clnp_stat"},
-#define        IN_NOTUSED      9
-       { "_tp_inpcb" },
-#define        ISO_TP          10
-       { "_tp_refinfo" },
-#define        N_TPSTAT        11
-       { "_tp_stat" },
-#define        N_ESISSTAT      12
-       { "_esis_stat"},
-#define N_NIMP         13
-       { "_nimp"},
-#define N_RTREE                14
-       { "_rt_tables"},
-#define N_CLTP         15
-       { "_cltb"},
-#define N_CLTPSTAT     16
-       { "_cltpstat"},
-#define        N_NFILE         17
-       { "_nfile" },
-#define        N_FILE          18
-       { "_file" },
-#define N_IPX          22
-       { "_ipxpcb"},
-#define N_IPXSTAT      23
-       { "_ipxstat"},
-#define N_SPXSTAT      24
-       { "_spx_istat"},
-#define N_DDPSTAT      25
-       { "_ddpstat"},
-#define N_DDPCB                26
-       { "_ddpcb"},
-#define N_NGSOCKS      27
-       { "_ngsocklist"},
-#define N_IP6STAT      28
-       { "_ip6stat" },
-#define N_ICMP6STAT    29
-       { "_icmp6stat" },
-#define N_IPSECSTAT    30
-       { "_ipsecstat" },
-#define N_IPSEC6STAT   31
-       { "_ipsec6stat" },
-#define N_PIM6STAT     32
-       { "_pim6stat" },
-#define N_MRT6PROTO    33
-       { "_ip6_mrtproto" },
-#define N_MRT6STAT     34
-       { "_mrt6stat" },
-#define N_MF6CTABLE    35
-       { "_mf6ctable" },
-#define N_MIF6TABLE    36
-       { "_mif6table" },
-#define N_PFKEYSTAT    37
-       { "_pfkeystat" },
-#define N_MBSTAT       38
-       { "_mbstat" },
-#define N_MBTYPES      39
-       { "_mbtypes" },
-#define N_NMBCLUSTERS  40
-       { "_nmbclusters" },
-#define N_NMBUFS       41
-       { "_nmbufs" },
-#define        N_RTTRASH       42
-       { "_rttrash" },
-       { "" },
-};
-
-
 struct protox {
-       u_char  pr_index;               /* index into nlist of cb head */
-       u_char  pr_sindex;              /* index into nlist of stat block */
-       u_char  pr_wanted;              /* 1 if wanted, 0 otherwise */
-       void    (*pr_cblocks)(u_long, char *, int);
+       void    (*pr_cblocks)(uint32_t, char *, int);
                                        /* control blocks printing routine */
-       void    (*pr_stats)(u_long, char *, int);
+       void    (*pr_stats)(uint32_t, char *, int);
                                        /* statistics printing routine */
        void    (*pr_istats)(char *);   /* per/if statistics printing routine */
        char    *pr_name;               /* well-known name */
-       int     pr_usesysctl;           /* true if we use sysctl, not kvm */
+       int     pr_protocol;
 } protox[] = {
-       { -1,           -1,             1,      protopr,
-         tcp_stats,    NULL,           "tcp",  IPPROTO_TCP },
-       { -1,           -1,             1,      protopr,
-         udp_stats,    NULL,           "udp",  IPPROTO_UDP },
-       { -1,           -1,             1,      protopr,
-         NULL,         NULL,           "divert",IPPROTO_DIVERT },
-       { -1,           -1,             1,      protopr,
-         ip_stats,     NULL,           "ip",   IPPROTO_RAW },
-       { -1,           -1,             1,      protopr,
-         icmp_stats,   NULL,           "icmp", IPPROTO_ICMP },
-       { -1,           -1,             1,      protopr,
-         igmp_stats,   NULL,           "igmp", IPPROTO_IGMP },
+       { protopr,      tcp_stats,      NULL,   "tcp",  IPPROTO_TCP },
+       { protopr,      udp_stats,      NULL,   "udp",  IPPROTO_UDP },
+       { protopr,      NULL,           NULL,   "divert", IPPROTO_DIVERT },
+       { protopr,      ip_stats,       NULL,   "ip",   IPPROTO_RAW },
+       { protopr,      icmp_stats,     NULL,   "icmp", IPPROTO_ICMP },
+       { protopr,      igmp_stats,     NULL,   "igmp", IPPROTO_IGMP },
 #ifdef IPSEC
-       { -1,           -1,     1,      0,
-         ipsec_stats,  NULL,           "ipsec",        IPPROTO_ESP},
-#endif
-#if 0
-       { -1,           -1,             1,      0,
-         bdg_stats,    NULL,           "bdg",  1 /* bridging... */ },
+       { NULL,         ipsec_stats,    NULL,   "ipsec", IPPROTO_ESP},
 #endif
-       { -1,           -1,             0,      0,
-         0,            NULL,           0 }
+       { NULL,         arp_stats,      NULL,   "arp",  0 },
+       { mptcppr,      mptcp_stats,    NULL,   "mptcp", IPPROTO_TCP },
+       { NULL,         NULL,           NULL,   NULL,   0 }
 };
 
 #ifdef INET6
 struct protox ip6protox[] = {
-       { -1,           -1,             1,      protopr,
-         tcp_stats,    NULL,           "tcp",  IPPROTO_TCP },
-       { -1,           -1,             1,      protopr,
-         udp_stats,    NULL,           "udp",  IPPROTO_UDP },
-       { -1,           N_IP6STAT,      1,      protopr,
-         ip6_stats,    ip6_ifstats,    "ip6",  IPPROTO_RAW },
-       { -1,           N_ICMP6STAT,    1,      protopr,
-         icmp6_stats,  icmp6_ifstats,  "icmp6",IPPROTO_ICMPV6 },
+       { protopr,      tcp_stats,      NULL,   "tcp",  IPPROTO_TCP },
+       { protopr,      udp_stats,      NULL,   "udp",  IPPROTO_UDP },
+       { protopr,      ip6_stats,      ip6_ifstats,    "ip6",  IPPROTO_RAW },
+       { protopr,      icmp6_stats,    icmp6_ifstats,  "icmp6",IPPROTO_ICMPV6 },
 #ifdef IPSEC
-       { -1,           N_IPSEC6STAT,   1,      0,
-         ipsec_stats,  NULL,           "ipsec6",IPPROTO_ESP },
+       { NULL,         ipsec_stats,    NULL,   "ipsec6", IPPROTO_ESP },
 #endif
-#ifdef notyet
-       { -1,           N_PIM6STAT,     1,      0,
-         pim6_stats,   NULL,           "pim6", 0 },
-#endif
-       { -1,           -1,             1,      0,
-         rip6_stats,   NULL,           "rip6", IPPROTO_RAW },
-#if 0
-       { -1,           -1,             1,      0,
-         bdg_stats,    NULL,           "bdg",  1 /* bridging... */ },
-#endif
-       { -1,           -1,             0,      0,
-         0,            NULL,           0,      0 }
+       { NULL,         rip6_stats,     NULL,   "rip6", IPPROTO_RAW },
+       { mptcppr,      mptcp_stats,    NULL,   "mptcp", IPPROTO_TCP },
+       { NULL,         NULL,           NULL,   NULL,   0 }
 };
 #endif /*INET6*/
 
 #ifdef IPSEC
 struct protox pfkeyprotox[] = {
-       { -1,           N_PFKEYSTAT,    1,      0,
-         pfkey_stats,  NULL,           "pfkey", PF_KEY_V2 },
-       { -1,           -1,             0,      0,
-         0,            NULL,           0,      0 }
+       { NULL,         pfkey_stats,    NULL,   "pfkey", PF_KEY_V2 },
+       { NULL,         NULL,           NULL,   NULL,   0 }
 };
 #endif
-#ifndef __APPLE__
-struct protox atalkprotox[] = {
-       { N_DDPCB,      N_DDPSTAT,      1,      atalkprotopr,
-         ddp_stats,    NULL,           "ddp" },
-       { -1,           -1,             0,      0,
-         0,            NULL,           0 }
-};
 
-struct protox netgraphprotox[] = {
-       { N_NGSOCKS,    -1,             1,      netgraphprotopr,
-         NULL,         NULL,           "ctrl" },
-       { N_NGSOCKS,    -1,             1,      netgraphprotopr,
-         NULL,         NULL,           "data" },
-       { -1,           NULL,           0,      0,
-         0,            NULL,           0 }
-};
 
-struct protox ipxprotox[] = {
-       { N_IPX,        N_IPXSTAT,      1,      ipxprotopr,
-         ipx_stats,    NULL,           "ipx",  0 },
-       { N_IPX,        N_SPXSTAT,      1,      ipxprotopr,
-         spx_stats,    NULL,           "spx",  0 },
-       { -1,           -1,             0,      0,
-         0,            NULL,           0,      0 }
+struct protox systmprotox[] = {
+       { systmpr,      NULL,           NULL,   "reg", 0 },
+       { systmpr,      kevt_stats,             NULL,   "kevt", SYSPROTO_EVENT },
+       { systmpr,      kctl_stats,     NULL,   "kctl", SYSPROTO_CONTROL },
+       { NULL,         NULL,           NULL,   NULL,   0 }
 };
-#endif
-#ifdef NS
-struct protox nsprotox[] = {
-       { N_IDP,        N_IDPSTAT,      1,      nsprotopr,
-         idp_stats,    NULL,           "idp" },
-       { N_IDP,        N_SPPSTAT,      1,      nsprotopr,
-         spp_stats,    NULL,           "spp" },
-       { -1,           N_NSERR,        1,      0,
-         nserr_stats,  NULL,           "ns_err" },
-       { -1,           -1,             0,      0,
-         0,            NULL,           0 }
+
+struct protox nstatprotox[] = {
+       { NULL,         print_nstat_stats,      NULL,   "nstat", 0 },
+       { NULL,         NULL,           NULL,   NULL,   0 }
 };
-#endif
 
-#ifdef ISO
-struct protox isoprotox[] = {
-       { ISO_TP,       N_TPSTAT,       1,      iso_protopr,
-         tp_stats,     NULL,           "tp" },
-       { N_CLTP,       N_CLTPSTAT,     1,      iso_protopr,
-         cltp_stats,   NULL,           "cltp" },
-       { -1,           N_CLNPSTAT,     1,       0,
-         clnp_stats,   NULL,           "clnp"},
-       { -1,           N_ESISSTAT,     1,       0,
-         esis_stats,   NULL,           "esis"},
-       { -1,           -1,             0,      0,
-         0,            NULL,           0 }
+struct protox ipcprotox[] = {
+       { NULL,         print_extbkidle_stats,  NULL,   "xbkidle", 0 },
+       { NULL,         NULL,           NULL,   NULL,   0 }
 };
-#endif
+
 
 struct protox *protoprotox[] = {
-                                        protox,
+       protox,
 #ifdef INET6
-                                        ip6protox,
+       ip6protox,
 #endif
 #ifdef IPSEC
-                                        pfkeyprotox,
-#endif
-#ifndef __APPLE__
-                                        ipxprotox, atalkprotox,
+       pfkeyprotox,
 #endif
-#ifdef NS
-                                        nsprotox, 
-#endif
-#ifdef ISO
-                                        isoprotox, 
-#endif
-                                        NULL };
+       systmprotox,
+       nstatprotox,
+       ipcprotox,
+       NULL
+};
 
 static void printproto (struct protox *, char *);
 static void usage (void);
@@ -343,27 +189,34 @@ static struct protox *knownname (char *);
 extern void _serv_cache_close();
 #endif
 
-#if 0
-static kvm_t *kvmd;
-#endif
-static char *nlistf = NULL, *memf = NULL;
-
 int    Aflag;          /* show addresses of protocol control block */
 int    aflag;          /* show all sockets (including servers) */
 int    bflag;          /* show i/f total bytes in/out */
+int    cflag;          /* show specific classq */
 int    dflag;          /* show i/f dropped packets */
+int    Fflag;          /* show i/f forwarded packets */
+#if defined(__APPLE__)
 int    gflag;          /* show group (multicast) routing or stats */
+#endif
 int    iflag;          /* show interfaces */
 int    lflag;          /* show routing table with use and ref */
 int    Lflag;          /* show size of listen queues */
 int    mflag;          /* show memory stats */
 int    nflag;          /* show addresses numerically */
 static int pflag;      /* show given protocol */
+int    prioflag = -1;  /* show packet priority statistics */
+int    Rflag;          /* show reachability information */
 int    rflag;          /* show routing tables (or routing stats) */
 int    sflag;          /* show protocol statistics */
+int    Sflag;          /* show additional i/f link status */
 int    tflag;          /* show i/f watchdog timers */
+int    vflag;          /* more verbose */
 int    Wflag;          /* wide display */
+int    qflag;          /* classq stats display */
+int    Qflag;          /* opportunistic polling stats display */
+int    xflag;          /* show extended link-layer reachability information */
 
+int    cq = -1;        /* send classq index (-1 for all) */
 int    interval;       /* repeat interval for i/f stats */
 
 char   *interface;     /* desired i/f for stats, or NULL for all i/fs */
@@ -381,7 +234,7 @@ main(argc, argv)
 
        af = AF_UNSPEC;
 
-       while ((ch = getopt(argc, argv, "Aabdf:gI:iLlM:mN:np:rRstuWw:")) != -1)
+       while ((ch = getopt(argc, argv, "Aabc:dFf:gI:ikLlmnP:p:qQrRsStuvWw:x")) != -1)
                switch(ch) {
                case 'A':
                        Aflag = 1;
@@ -392,15 +245,17 @@ main(argc, argv)
                case 'b':
                        bflag = 1;
                        break;
+               case 'c':
+                       cflag = 1;
+                       cq = atoi(optarg);
+                       break;
                case 'd':
                        dflag = 1;
                        break;
+               case 'F':
+                       Fflag = 1;
+                       break;
                case 'f':
-#ifdef NS
-                       if (strcmp(optarg, "ns") == 0)
-                               af = AF_NS;
-                       else
-#endif
                        if (strcmp(optarg, "ipx") == 0)
                                af = AF_IPX;
                        else if (strcmp(optarg, "inet") == 0)
@@ -415,24 +270,17 @@ main(argc, argv)
 #endif /*INET6*/
                        else if (strcmp(optarg, "unix") == 0)
                                af = AF_UNIX;
-#ifndef __APPLE__
-                       else if (strcmp(optarg, "atalk") == 0)
-                               af = AF_APPLETALK;
-                       else if (strcmp(optarg, "ng") == 0
-                           || strcmp(optarg, "netgraph") == 0)
-                               af = AF_NETGRAPH;
-#endif
-#ifdef ISO
-                       else if (strcmp(optarg, "iso") == 0)
-                               af = AF_ISO;
-#endif
+                       else if (strcmp(optarg, "systm") == 0)
+                               af = AF_SYSTEM;
                        else {
                                errx(1, "%s: unknown address family", optarg);
                        }
                        break;
+#if defined(__APPLE__)
                case 'g':
                        gflag = 1;
                        break;
+#endif
                case 'I': {
                        char *cp;
 
@@ -451,18 +299,15 @@ main(argc, argv)
                case 'L':
                        Lflag = 1;
                        break;
-               case 'M':
-                       memf = optarg;
-                       break;
                case 'm':
-                       mflag = 1;
-                       break;
-               case 'N':
-                       nlistf = optarg;
+                       mflag++;
                        break;
                case 'n':
                        nflag = 1;
                        break;
+               case 'P':
+                       prioflag = atoi(optarg);
+                       break;
                case 'p':
                        if ((tp = name2protox(optarg)) == NULL) {
                                errx(1, 
@@ -471,18 +316,33 @@ main(argc, argv)
                        }
                        pflag = 1;
                        break;
+               case 'q':
+                       qflag++;
+                       break;
+               case 'Q':
+                       Qflag++;
+                       break;
+               case 'R':
+                       Rflag = 1;
+                       break;
                case 'r':
                        rflag = 1;
                        break;
                case 's':
                        ++sflag;
                        break;
+               case 'S':
+                       Sflag = 1;
+                       break;
                case 't':
                        tflag = 1;
                        break;
                case 'u':
                        af = AF_UNIX;
                        break;
+               case 'v':
+                       vflag++;
+                       break;
                case 'W':
                        Wflag = 1;
                        break;
@@ -490,6 +350,10 @@ main(argc, argv)
                        interval = atoi(optarg);
                        iflag = 1;
                        break;
+               case 'x':
+                       xflag = 1;
+                       Rflag = 1;
+                       break;
                case '?':
                default:
                        usage();
@@ -507,68 +371,55 @@ main(argc, argv)
                        ++argv;
                        iflag = 1;
                }
-               if (*argv) {
-                       nlistf = *argv;
-                       if (*++argv)
-                               memf = *argv;
-               }
        }
 #endif
 
-       /*
-        * Discard setgid privileges if not the running kernel so that bad
-        * guys can't print interesting stuff from kernel memory.
-        */
-       if (nlistf != NULL || memf != NULL)
-               setgid(getgid());
-
        if (mflag) {
                mbpr();
                exit(0);
        }
-#if 0
-       /*
-        * Keep file descriptors open to avoid overhead
-        * of open/close on each call to get* routines.
-        */
-       sethostent(1);
-       setnetent(1);
-#else
-       /*
-        * This does not make sense any more with DNS being default over
-        * the files.  Doing a setXXXXent(1) causes a tcp connection to be
-        * used for the queries, which is slower.
-        */
-#endif
-       if (iflag && !sflag) {
-               intpr(NULL);
+       if (iflag && !sflag && !Sflag && !gflag && !qflag && !Qflag) {
+               if (Rflag)
+                       intpr_ri(NULL);
+               else
+                       intpr(NULL);
                exit(0);
        }
        if (rflag) {
                if (sflag)
                        rt_stats();
                else
-                       routepr(nl[N_RTREE].n_value);
+                       routepr();
                exit(0);
        }
-       if (gflag) {
-               if (sflag) {
-                       if (af == AF_INET || af == AF_UNSPEC)
-                               mrt_stats();
-#ifdef INET6
-                       if (af == AF_INET6 || af == AF_UNSPEC)
-                               mrt6_stats();
-#endif
+       if (qflag || Qflag) {
+               if (interface == NULL) {
+                       fprintf(stderr, "%s statistics option "
+                           "requires interface name\n", qflag ? "Queue" :
+                           "Polling");
+               } else if (qflag) {
+                       aqstatpr();
                } else {
-                       if (af == AF_INET || af == AF_UNSPEC)
-                               mroutepr();
-#ifdef INET6
-                       if (af == AF_INET6 || af == AF_UNSPEC)
-                               mroute6pr();
-#endif
+                       rxpollstatpr();
                }
                exit(0);
        }
+       if (Sflag) {
+               if (interface == NULL) {
+                       fprintf(stderr, "additional link status option"
+                               " requires interface name\n");
+               } else {
+                       print_link_status(interface);
+               }
+               exit(0);
+       }
+
+#if defined(__APPLE__)
+       if (gflag) {
+               ifmalist_dump();
+               exit(0);
+       }
+#endif
 
        if (tp) {
                printproto(tp, tp->pr_name);
@@ -587,30 +438,22 @@ main(argc, argv)
                for (tp = pfkeyprotox; tp->pr_name; tp++)
                        printproto(tp, tp->pr_name);
 #endif /*IPSEC*/
-#ifndef __APPLE__
-       if (af == AF_IPX || af == AF_UNSPEC) {
-               for (tp = ipxprotox; tp->pr_name; tp++)
-                       printproto(tp, tp->pr_name);
-       }
-       if (af == AF_APPLETALK || af == AF_UNSPEC)
-               for (tp = atalkprotox; tp->pr_name; tp++)
-                       printproto(tp, tp->pr_name);
-       if (af == AF_NETGRAPH || af == AF_UNSPEC)
-               for (tp = netgraphprotox; tp->pr_name; tp++)
+       if ((af == AF_UNIX || af == AF_UNSPEC) && !Lflag && !sflag)
+               unixpr();
+               
+       if ((af == AF_SYSTEM || af == AF_UNSPEC) && !Lflag)
+               for (tp = systmprotox; tp->pr_name; tp++)
                        printproto(tp, tp->pr_name);
-#endif
-#ifdef NS
-       if (af == AF_NS || af == AF_UNSPEC)
-               for (tp = nsprotox; tp->pr_name; tp++)
+#if TARGET_OS_IPHONE
+       if (af == AF_UNSPEC && !Lflag)
+               for (tp = nstatprotox; tp->pr_name; tp++)
                        printproto(tp, tp->pr_name);
-#endif
-#ifdef ISO
-       if (af == AF_ISO || af == AF_UNSPEC)
-               for (tp = isoprotox; tp->pr_name; tp++)
+#endif /* TARGET_OS_IPHONE */
+
+       if (af == AF_UNSPEC && !Lflag)
+               for (tp = ipcprotox; tp->pr_name; tp++)
                        printproto(tp, tp->pr_name);
-#endif
-       if ((af == AF_UNIX || af == AF_UNSPEC) && !Lflag && !sflag)
-               unixpr();
+
 #ifdef SRVCACHE
        _serv_cache_close();
 #endif
@@ -627,14 +470,14 @@ printproto(tp, name)
        register struct protox *tp;
        char *name;
 {
-       void (*pr)(u_long, char *, int);
-       u_long off;
+       void (*pr)(uint32_t, char *, int);
+       uint32_t off;
 
        if (sflag) {
-               if (iflag) {
+               if (iflag && !pflag) {
                        if (tp->pr_istats)
                                intpr(tp->pr_istats);
-                       else if (pflag)
+                       else if (vflag)
                                printf("%s: no per-interface stats routine\n",
                                    tp->pr_name);
                        return;
@@ -642,82 +485,48 @@ printproto(tp, name)
                else {
                        pr = tp->pr_stats;
                        if (!pr) {
-                               if (pflag)
+                               if (pflag && vflag)
                                        printf("%s: no stats routine\n",
                                            tp->pr_name);
                                return;
                        }
-                       off = tp->pr_usesysctl ? tp->pr_usesysctl 
-                               : nl[tp->pr_sindex].n_value;
+                       off = tp->pr_protocol;
                }
        } else {
                pr = tp->pr_cblocks;
                if (!pr) {
-                       if (pflag)
+                       if (pflag && vflag)
                                printf("%s: no PCB routine\n", tp->pr_name);
                        return;
                }
-               off = tp->pr_usesysctl ? tp->pr_usesysctl
-                       : nl[tp->pr_index].n_value;
+               off = tp->pr_protocol;
        }
-       if (pr != NULL && (off || af != AF_UNSPEC))
-               (*pr)(off, name, af);
-       else
+       if (pr != NULL) {
+               if (sflag && iflag && pflag)
+                       intervalpr(pr, off, name, af);
+               else
+                       (*pr)(off, name, af);
+       } else {
                printf("### no stats for %s\n", name);
-}
-
-/*
- * Read kernel memory, return 0 on success.
- */
-#if 0
-int
-kread(u_long addr, char *buf, int size)
-{
-       if (kvmd == 0) {
-               /*
-                * XXX.
-                */
-               kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf);
-               if (kvmd != NULL) {
-                       if (kvm_nlist(kvmd, nl) < 0) {
-                               if(nlistf)
-                                       errx(1, "%s: kvm_nlist: %s", nlistf,
-                                            kvm_geterr(kvmd));
-                               else
-                                       errx(1, "kvm_nlist: %s", kvm_geterr(kvmd));
-                       }
-
-                       if (nl[0].n_type == 0) {
-                               if(nlistf)
-                                       errx(1, "%s: no namelist", nlistf);
-                               else
-                                       errx(1, "no namelist");
-                       }
-               } else {
-                       warnx("kvm not available");
-                       return(-1);
-               }
        }
-       if (!buf)
-               return (0);
-       if (kvm_read(kvmd, addr, buf, size) != size) {
-               warnx("%s", kvm_geterr(kvmd));
-               return (-1);
-       }
-       return (0);
 }
-#endif
 
 char *
 plural(int n)
 {
-       return (n != 1 ? "s" : "");
+       return (n > 1 ? "s" : "");
 }
 
 char *
 plurales(int n)
 {
-       return (n != 1 ? "es" : "");
+       return (n > 1 ? "es" : "");
+}
+
+char *
+pluralies(int n)
+{
+       return (n > 1 ? "ies" : "y");
 }
 
 /*
@@ -765,14 +574,36 @@ name2protox(char *name)
        return (NULL);
 }
 
+#define        NETSTAT_USAGE "\
+Usage: netstat [-AaLlnW] [-f address_family | -p protocol]\n\
+       netstat [-gilns] [-f address_family]\n\
+       netstat -i | -I interface [-w wait] [-abdgRtS]\n\
+       netstat -s [-s] [-f address_family | -p protocol] [-w wait]\n\
+       netstat -i | -I interface -s [-f address_family | -p protocol]\n\
+       netstat -m [-m]\n\
+       netstat -r [-Aaln] [-f address_family]\n\
+       netstat -rs [-s]\n\
+"
+
 static void
 usage(void)
 {
-       (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
-"usage: netstat [-Aan] [-f address_family] [-M core] [-N system]",
-"       netstat [-bdghimnrs] [-f address_family] [-M core] [-N system]",
-"       netstat [-bdn] [-I interface] [-M core] [-N system] [-w wait]",
-"       netstat -m [-M core] [-N system]",
-"       netstat [-M core] [-N system] [-p protocol]");
+       (void) fprintf(stderr, "%s\n", NETSTAT_USAGE);
        exit(1);
 }
+
+int
+print_time(void)
+{
+    time_t now;
+    struct tm tm;
+    int num_written = 0;
+    
+    (void) time(&now);
+    (void) localtime_r(&now, &tm);
+    
+    num_written += printf("%02d:%02d:%02d ", tm.tm_hour, tm.tm_min, tm.tm_sec);
+    
+    return (num_written);
+}
+