]> git.saurik.com Git - apple/network_cmds.git/blob - netstat.tproj/main.c
d1fc0a8de33e7a6925239900a89d6ffe9bc7ee08
[apple/network_cmds.git] / netstat.tproj / main.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * Copyright (c) 1983, 1988, 1993
26 * Regents of the University of California. All rights reserved.
27 *
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
30 * are met:
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgement:
38 * This product includes software developed by the University of
39 * California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
43 *
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 */
56
57 #ifndef lint
58 char const copyright[] =
59 "@(#) Copyright (c) 1983, 1988, 1993\n\
60 Regents of the University of California. All rights reserved.\n";
61 #endif /* not lint */
62
63 #ifndef lint
64 #if 0
65 static char sccsid[] = "@(#)main.c 8.4 (Berkeley) 3/1/94";
66 #endif
67 static const char rcsid[] =
68 "$Id: main.c,v 1.8 2004/10/14 22:24:09 lindak Exp $";
69 #endif /* not lint */
70
71 #include <sys/param.h>
72 #include <sys/file.h>
73 #include <sys/socket.h>
74
75 #include <netinet/in.h>
76 #include <net/pfkeyv2.h>
77
78 #include <ctype.h>
79 #include <err.h>
80 #include <errno.h>
81 #include <limits.h>
82 #include <netdb.h>
83 #include <nlist.h>
84 #include <paths.h>
85 #include <stdio.h>
86 #include <stdlib.h>
87 #include <string.h>
88 #include <unistd.h>
89 #include "netstat.h"
90 #include <sys/types.h>
91 #include <sys/sysctl.h>
92
93 #ifdef __APPLE__
94 #include <TargetConditionals.h>
95 #endif
96
97 /*
98 * ----------------------------------------------------------------------------
99 * "THE BEER-WARE LICENSE" (Revision 42):
100 * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
101 * can do whatever you want with this stuff. If we meet some day, and you think
102 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
103 * ----------------------------------------------------------------------------
104 *
105 * $Id: main.c,v 1.8 2004/10/14 22:24:09 lindak Exp $
106 *
107 */
108
109 static struct nlist nl[] = {
110 #define N_IFNET 0
111 { "_ifnet" },
112 #define N_IMP 1
113 { "_imp_softc" },
114 #define N_RTSTAT 2
115 { "_rtstat" },
116 #define N_UNIXSW 3
117 { "_localsw" },
118 #define N_IDP 4
119 { "_nspcb"},
120 #define N_IDPSTAT 5
121 { "_idpstat"},
122 #define N_SPPSTAT 6
123 { "_spp_istat"},
124 #define N_NSERR 7
125 { "_ns_errstat"},
126 #define N_CLNPSTAT 8
127 { "_clnp_stat"},
128 #define IN_NOTUSED 9
129 { "_tp_inpcb" },
130 #define ISO_TP 10
131 { "_tp_refinfo" },
132 #define N_TPSTAT 11
133 { "_tp_stat" },
134 #define N_ESISSTAT 12
135 { "_esis_stat"},
136 #define N_NIMP 13
137 { "_nimp"},
138 #define N_RTREE 14
139 { "_rt_tables"},
140 #define N_CLTP 15
141 { "_cltb"},
142 #define N_CLTPSTAT 16
143 { "_cltpstat"},
144 #define N_NFILE 17
145 { "_nfile" },
146 #define N_FILE 18
147 { "_file" },
148 #define N_IPX 22
149 { "_ipxpcb"},
150 #define N_IPXSTAT 23
151 { "_ipxstat"},
152 #define N_SPXSTAT 24
153 { "_spx_istat"},
154 #define N_DDPSTAT 25
155 { "_ddpstat"},
156 #define N_DDPCB 26
157 { "_ddpcb"},
158 #define N_NGSOCKS 27
159 { "_ngsocklist"},
160 #define N_IP6STAT 28
161 { "_ip6stat" },
162 #define N_ICMP6STAT 29
163 { "_icmp6stat" },
164 #define N_IPSECSTAT 30
165 { "_ipsecstat" },
166 #define N_IPSEC6STAT 31
167 { "_ipsec6stat" },
168 #define N_PIM6STAT 32
169 { "_pim6stat" },
170 #define N_MRT6PROTO 33
171 { "_ip6_mrtproto" },
172 #define N_MRT6STAT 34
173 { "_mrt6stat" },
174 #define N_MF6CTABLE 35
175 { "_mf6ctable" },
176 #define N_MIF6TABLE 36
177 { "_mif6table" },
178 #define N_PFKEYSTAT 37
179 { "_pfkeystat" },
180 #define N_MBSTAT 38
181 { "_mbstat" },
182 #define N_MBTYPES 39
183 { "_mbtypes" },
184 #define N_NMBCLUSTERS 40
185 { "_nmbclusters" },
186 #define N_NMBUFS 41
187 { "_nmbufs" },
188 #define N_RTTRASH 42
189 { "_rttrash" },
190 { "" },
191 };
192
193
194 struct protox {
195 u_char pr_index; /* index into nlist of cb head */
196 u_char pr_sindex; /* index into nlist of stat block */
197 u_char pr_wanted; /* 1 if wanted, 0 otherwise */
198 void (*pr_cblocks)(u_long, char *, int);
199 /* control blocks printing routine */
200 void (*pr_stats)(u_long, char *, int);
201 /* statistics printing routine */
202 void (*pr_istats)(char *); /* per/if statistics printing routine */
203 char *pr_name; /* well-known name */
204 int pr_usesysctl; /* true if we use sysctl, not kvm */
205 } protox[] = {
206 { -1, -1, 1, protopr,
207 tcp_stats, NULL, "tcp", IPPROTO_TCP },
208 { -1, -1, 1, protopr,
209 udp_stats, NULL, "udp", IPPROTO_UDP },
210 { -1, -1, 1, protopr,
211 NULL, NULL, "divert",IPPROTO_DIVERT },
212 { -1, -1, 1, protopr,
213 ip_stats, NULL, "ip", IPPROTO_RAW },
214 { -1, -1, 1, protopr,
215 icmp_stats, NULL, "icmp", IPPROTO_ICMP },
216 { -1, -1, 1, protopr,
217 igmp_stats, NULL, "igmp", IPPROTO_IGMP },
218 #ifdef IPSEC
219 { -1, -1, 1, 0,
220 ipsec_stats, NULL, "ipsec", IPPROTO_ESP},
221 #endif
222 #if 0
223 { -1, -1, 1, 0,
224 bdg_stats, NULL, "bdg", 1 /* bridging... */ },
225 #endif
226 { -1, -1, 0, 0,
227 0, NULL, 0 }
228 };
229
230 #ifdef INET6
231 struct protox ip6protox[] = {
232 { -1, -1, 1, protopr,
233 tcp_stats, NULL, "tcp", IPPROTO_TCP },
234 { -1, -1, 1, protopr,
235 udp_stats, NULL, "udp", IPPROTO_UDP },
236 { -1, N_IP6STAT, 1, protopr,
237 ip6_stats, ip6_ifstats, "ip6", IPPROTO_RAW },
238 { -1, N_ICMP6STAT, 1, protopr,
239 icmp6_stats, icmp6_ifstats, "icmp6",IPPROTO_ICMPV6 },
240 #ifdef IPSEC
241 { -1, N_IPSEC6STAT, 1, 0,
242 ipsec_stats, NULL, "ipsec6",IPPROTO_ESP },
243 #endif
244 #ifdef notyet
245 { -1, N_PIM6STAT, 1, 0,
246 pim6_stats, NULL, "pim6", 0 },
247 #endif
248 { -1, -1, 1, 0,
249 rip6_stats, NULL, "rip6", IPPROTO_RAW },
250 #if 0
251 { -1, -1, 1, 0,
252 bdg_stats, NULL, "bdg", 1 /* bridging... */ },
253 #endif
254 { -1, -1, 0, 0,
255 0, NULL, 0, 0 }
256 };
257 #endif /*INET6*/
258
259 #ifdef IPSEC
260 struct protox pfkeyprotox[] = {
261 { -1, N_PFKEYSTAT, 1, 0,
262 pfkey_stats, NULL, "pfkey", PF_KEY_V2 },
263 { -1, -1, 0, 0,
264 0, NULL, 0, 0 }
265 };
266 #endif
267 #ifndef __APPLE__
268 struct protox atalkprotox[] = {
269 { N_DDPCB, N_DDPSTAT, 1, atalkprotopr,
270 ddp_stats, NULL, "ddp" },
271 { -1, -1, 0, 0,
272 0, NULL, 0 }
273 };
274
275 struct protox netgraphprotox[] = {
276 { N_NGSOCKS, -1, 1, netgraphprotopr,
277 NULL, NULL, "ctrl" },
278 { N_NGSOCKS, -1, 1, netgraphprotopr,
279 NULL, NULL, "data" },
280 { -1, NULL, 0, 0,
281 0, NULL, 0 }
282 };
283
284 struct protox ipxprotox[] = {
285 { N_IPX, N_IPXSTAT, 1, ipxprotopr,
286 ipx_stats, NULL, "ipx", 0 },
287 { N_IPX, N_SPXSTAT, 1, ipxprotopr,
288 spx_stats, NULL, "spx", 0 },
289 { -1, -1, 0, 0,
290 0, NULL, 0, 0 }
291 };
292 #endif
293 #ifdef NS
294 struct protox nsprotox[] = {
295 { N_IDP, N_IDPSTAT, 1, nsprotopr,
296 idp_stats, NULL, "idp" },
297 { N_IDP, N_SPPSTAT, 1, nsprotopr,
298 spp_stats, NULL, "spp" },
299 { -1, N_NSERR, 1, 0,
300 nserr_stats, NULL, "ns_err" },
301 { -1, -1, 0, 0,
302 0, NULL, 0 }
303 };
304 #endif
305
306 #ifdef ISO
307 struct protox isoprotox[] = {
308 { ISO_TP, N_TPSTAT, 1, iso_protopr,
309 tp_stats, NULL, "tp" },
310 { N_CLTP, N_CLTPSTAT, 1, iso_protopr,
311 cltp_stats, NULL, "cltp" },
312 { -1, N_CLNPSTAT, 1, 0,
313 clnp_stats, NULL, "clnp"},
314 { -1, N_ESISSTAT, 1, 0,
315 esis_stats, NULL, "esis"},
316 { -1, -1, 0, 0,
317 0, NULL, 0 }
318 };
319 #endif
320
321 struct protox *protoprotox[] = {
322 protox,
323 #ifdef INET6
324 ip6protox,
325 #endif
326 #ifdef IPSEC
327 pfkeyprotox,
328 #endif
329 #ifndef __APPLE__
330 ipxprotox, atalkprotox,
331 #endif
332 #ifdef NS
333 nsprotox,
334 #endif
335 #ifdef ISO
336 isoprotox,
337 #endif
338 NULL };
339
340 static void printproto (struct protox *, char *);
341 static void usage (void);
342 static struct protox *name2protox (char *);
343 static struct protox *knownname (char *);
344 #ifdef SRVCACHE
345 extern void _serv_cache_close();
346 #endif
347
348 int Aflag; /* show addresses of protocol control block */
349 int aflag; /* show all sockets (including servers) */
350 int bflag; /* show i/f total bytes in/out */
351 int dflag; /* show i/f dropped packets */
352 #if defined(__APPLE__) && !TARGET_OS_EMBEDDED
353 int gflag; /* show group (multicast) routing or stats */
354 #endif
355 int iflag; /* show interfaces */
356 int lflag; /* show routing table with use and ref */
357 int Lflag; /* show size of listen queues */
358 int mflag; /* show memory stats */
359 int nflag; /* show addresses numerically */
360 static int pflag; /* show given protocol */
361 int rflag; /* show routing tables (or routing stats) */
362 int sflag; /* show protocol statistics */
363 int tflag; /* show i/f watchdog timers */
364 int Wflag; /* wide display */
365
366 int interval; /* repeat interval for i/f stats */
367
368 char *interface; /* desired i/f for stats, or NULL for all i/fs */
369 int unit; /* unit number for above */
370
371 int af; /* address family */
372
373 int
374 main(argc, argv)
375 int argc;
376 char *argv[];
377 {
378 register struct protox *tp = NULL; /* for printing cblocks & stats */
379 int ch;
380
381 af = AF_UNSPEC;
382
383 while ((ch = getopt(argc, argv, "Aabdf:gI:iLlmnp:rRstuWw:")) != -1)
384 switch(ch) {
385 case 'A':
386 Aflag = 1;
387 break;
388 case 'a':
389 aflag = 1;
390 break;
391 case 'b':
392 bflag = 1;
393 break;
394 case 'd':
395 dflag = 1;
396 break;
397 case 'f':
398 #ifdef NS
399 if (strcmp(optarg, "ns") == 0)
400 af = AF_NS;
401 else
402 #endif
403 if (strcmp(optarg, "ipx") == 0)
404 af = AF_IPX;
405 else if (strcmp(optarg, "inet") == 0)
406 af = AF_INET;
407 #ifdef INET6
408 else if (strcmp(optarg, "inet6") == 0)
409 af = AF_INET6;
410 #endif /*INET6*/
411 #ifdef INET6
412 else if (strcmp(optarg, "pfkey") == 0)
413 af = PF_KEY;
414 #endif /*INET6*/
415 else if (strcmp(optarg, "unix") == 0)
416 af = AF_UNIX;
417 #ifndef __APPLE__
418 else if (strcmp(optarg, "atalk") == 0)
419 af = AF_APPLETALK;
420 else if (strcmp(optarg, "ng") == 0
421 || strcmp(optarg, "netgraph") == 0)
422 af = AF_NETGRAPH;
423 #endif
424 #ifdef ISO
425 else if (strcmp(optarg, "iso") == 0)
426 af = AF_ISO;
427 #endif
428 else {
429 errx(1, "%s: unknown address family", optarg);
430 }
431 break;
432 #if defined(__APPLE__) && !TARGET_OS_EMBEDDED
433 case 'g':
434 gflag = 1;
435 break;
436 #endif
437 case 'I': {
438 char *cp;
439
440 iflag = 1;
441 for (cp = interface = optarg; isalpha(*cp); cp++)
442 continue;
443 unit = atoi(cp);
444 break;
445 }
446 case 'i':
447 iflag = 1;
448 break;
449 case 'l':
450 lflag = 1;
451 break;
452 case 'L':
453 Lflag = 1;
454 break;
455 case 'm':
456 mflag++;
457 break;
458 case 'n':
459 nflag = 1;
460 break;
461 case 'p':
462 if ((tp = name2protox(optarg)) == NULL) {
463 errx(1,
464 "%s: unknown or uninstrumented protocol",
465 optarg);
466 }
467 pflag = 1;
468 break;
469 case 'r':
470 rflag = 1;
471 break;
472 case 's':
473 ++sflag;
474 break;
475 case 't':
476 tflag = 1;
477 break;
478 case 'u':
479 af = AF_UNIX;
480 break;
481 case 'W':
482 Wflag = 1;
483 break;
484 case 'w':
485 interval = atoi(optarg);
486 iflag = 1;
487 break;
488 case '?':
489 default:
490 usage();
491 }
492 argv += optind;
493 argc -= optind;
494
495 #define BACKWARD_COMPATIBILITY
496 #ifdef BACKWARD_COMPATIBILITY
497 if (*argv) {
498 if (isdigit(**argv)) {
499 interval = atoi(*argv);
500 if (interval <= 0)
501 usage();
502 ++argv;
503 iflag = 1;
504 }
505 }
506 #endif
507
508 if (mflag) {
509 mbpr();
510 exit(0);
511 }
512 #if 0
513 /*
514 * Keep file descriptors open to avoid overhead
515 * of open/close on each call to get* routines.
516 */
517 sethostent(1);
518 setnetent(1);
519 #else
520 /*
521 * This does not make sense any more with DNS being default over
522 * the files. Doing a setXXXXent(1) causes a tcp connection to be
523 * used for the queries, which is slower.
524 */
525 #endif
526 if (iflag && !sflag) {
527 intpr(NULL);
528 exit(0);
529 }
530 if (rflag) {
531 if (sflag)
532 rt_stats();
533 else
534 routepr(nl[N_RTREE].n_value);
535 exit(0);
536 }
537 #if defined(__APPLE__) && !TARGET_OS_EMBEDDED
538 if (gflag) {
539 if (sflag) {
540 if (af == AF_INET || af == AF_UNSPEC)
541 mrt_stats();
542 #ifdef INET6
543 if (af == AF_INET6 || af == AF_UNSPEC)
544 mrt6_stats();
545 #endif
546 } else {
547 if (af == AF_INET || af == AF_UNSPEC)
548 mroutepr();
549 #ifdef INET6
550 if (af == AF_INET6 || af == AF_UNSPEC)
551 mroute6pr();
552 #endif
553 }
554 ifmalist_dump();
555 exit(0);
556 }
557 #endif
558
559 if (tp) {
560 printproto(tp, tp->pr_name);
561 exit(0);
562 }
563 if (af == AF_INET || af == AF_UNSPEC)
564 for (tp = protox; tp->pr_name; tp++)
565 printproto(tp, tp->pr_name);
566 #ifdef INET6
567 if (af == AF_INET6 || af == AF_UNSPEC)
568 for (tp = ip6protox; tp->pr_name; tp++)
569 printproto(tp, tp->pr_name);
570 #endif /*INET6*/
571 #ifdef IPSEC
572 if (af == PF_KEY || af == AF_UNSPEC)
573 for (tp = pfkeyprotox; tp->pr_name; tp++)
574 printproto(tp, tp->pr_name);
575 #endif /*IPSEC*/
576 #ifndef __APPLE__
577 if (af == AF_IPX || af == AF_UNSPEC) {
578 for (tp = ipxprotox; tp->pr_name; tp++)
579 printproto(tp, tp->pr_name);
580 }
581 if (af == AF_APPLETALK || af == AF_UNSPEC)
582 for (tp = atalkprotox; tp->pr_name; tp++)
583 printproto(tp, tp->pr_name);
584 if (af == AF_NETGRAPH || af == AF_UNSPEC)
585 for (tp = netgraphprotox; tp->pr_name; tp++)
586 printproto(tp, tp->pr_name);
587 #endif
588 #ifdef NS
589 if (af == AF_NS || af == AF_UNSPEC)
590 for (tp = nsprotox; tp->pr_name; tp++)
591 printproto(tp, tp->pr_name);
592 #endif
593 #ifdef ISO
594 if (af == AF_ISO || af == AF_UNSPEC)
595 for (tp = isoprotox; tp->pr_name; tp++)
596 printproto(tp, tp->pr_name);
597 #endif
598 if ((af == AF_UNIX || af == AF_UNSPEC) && !Lflag && !sflag)
599 unixpr();
600 #ifdef SRVCACHE
601 _serv_cache_close();
602 #endif
603 exit(0);
604 }
605
606 /*
607 * Print out protocol statistics or control blocks (per sflag).
608 * If the interface was not specifically requested, and the symbol
609 * is not in the namelist, ignore this one.
610 */
611 static void
612 printproto(tp, name)
613 register struct protox *tp;
614 char *name;
615 {
616 void (*pr)(u_long, char *, int);
617 u_long off;
618
619 if (sflag) {
620 if (iflag && !pflag) {
621 if (tp->pr_istats)
622 intpr(tp->pr_istats);
623 else
624 printf("%s: no per-interface stats routine\n",
625 tp->pr_name);
626 return;
627 }
628 else {
629 pr = tp->pr_stats;
630 if (!pr) {
631 if (pflag)
632 printf("%s: no stats routine\n",
633 tp->pr_name);
634 return;
635 }
636 off = tp->pr_usesysctl ? tp->pr_usesysctl
637 : nl[tp->pr_sindex].n_value;
638 }
639 } else {
640 pr = tp->pr_cblocks;
641 if (!pr) {
642 if (pflag)
643 printf("%s: no PCB routine\n", tp->pr_name);
644 return;
645 }
646 off = tp->pr_usesysctl ? tp->pr_usesysctl
647 : nl[tp->pr_index].n_value;
648 }
649 if (pr != NULL && (off || af != AF_UNSPEC)) {
650 if (sflag && iflag && pflag)
651 intervalpr(pr, off, name, af);
652 else
653 (*pr)(off, name, af);
654 } else {
655 printf("### no stats for %s\n", name);
656 }
657 }
658
659 char *
660 plural(int n)
661 {
662 return (n != 1 ? "s" : "");
663 }
664
665 char *
666 plurales(int n)
667 {
668 return (n != 1 ? "es" : "");
669 }
670
671 /*
672 * Find the protox for the given "well-known" name.
673 */
674 static struct protox *
675 knownname(char *name)
676 {
677 struct protox **tpp, *tp;
678
679 for (tpp = protoprotox; *tpp; tpp++)
680 for (tp = *tpp; tp->pr_name; tp++)
681 if (strcmp(tp->pr_name, name) == 0)
682 return (tp);
683 return (NULL);
684 }
685
686 /*
687 * Find the protox corresponding to name.
688 */
689 static struct protox *
690 name2protox(char *name)
691 {
692 struct protox *tp;
693 char **alias; /* alias from p->aliases */
694 struct protoent *p;
695
696 /*
697 * Try to find the name in the list of "well-known" names. If that
698 * fails, check if name is an alias for an Internet protocol.
699 */
700 if ((tp = knownname(name)) != NULL)
701 return (tp);
702
703 setprotoent(1); /* make protocol lookup cheaper */
704 while ((p = getprotoent()) != NULL) {
705 /* assert: name not same as p->name */
706 for (alias = p->p_aliases; *alias; alias++)
707 if (strcmp(name, *alias) == 0) {
708 endprotoent();
709 return (knownname(p->p_name));
710 }
711 }
712 endprotoent();
713 return (NULL);
714 }
715
716 #define NETSTAT_USAGE "\
717 Usage: netstat [-AaLlnW] [-f address_family | -p protocol]\n\
718 netstat [-gilns] [-f address_family]\n\
719 netstat -i | -I interface [-w wait] [-abdgt]\n\
720 netstat -s [-s] [-f address_family | -p protocol] [-w wait]\n\
721 netstat -i | -I interface -s [-f address_family | -p protocol]\n\
722 netstat -m [-m]\n\
723 netstat -r [-Aaln] [-f address_family]\n\
724 netstat -rs [-s]\n\
725 "
726
727 static void
728 usage(void)
729 {
730 (void) fprintf(stderr, "%s\n", NETSTAT_USAGE);
731 exit(1);
732 }
733