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 * @(#) Copyright (c) 1983, 1988, 1993 Regents of the University of California. All rights reserved. 34 * @(#)main.c 8.4 (Berkeley) 3/1/94 35 * $FreeBSD: src/usr.bin/netstat/main.c,v 1.34.2.12 2001/09/17 15:17:46 ru Exp $ 36 */ 37 38 #include <sys/param.h> 39 #include <sys/file.h> 40 #include <sys/protosw.h> 41 #include <sys/socket.h> 42 43 #include <netinet/in.h> 44 45 #include <netgraph/socket/ng_socket.h> 46 47 #include <ctype.h> 48 #include <err.h> 49 #include <errno.h> 50 #include <kvm.h> 51 #include <limits.h> 52 #include <netdb.h> 53 #include <nlist.h> 54 #include <paths.h> 55 #include <stdio.h> 56 #include <stdlib.h> 57 #include <string.h> 58 #include <unistd.h> 59 #include "netstat.h" 60 61 static struct nlist nl[] = { 62 #define N_IFNET 0 63 { .n_name = "_ifnet" }, 64 #define N_IMP 1 65 { .n_name = "_imp_softc" }, 66 #define N_RTSTAT 2 67 { .n_name = "_rtstat" }, 68 #define N_UNIXSW 3 69 { .n_name = "_localsw" }, 70 #define N_IDP 4 71 { .n_name = "_nspcb"}, 72 #define N_IDPSTAT 5 73 { .n_name = "_idpstat"}, 74 #define N_SPPSTAT 6 75 { .n_name = "_spp_istat"}, 76 #define N_NSERR 7 77 { .n_name = "_ns_errstat"}, 78 #define N_CLNPSTAT 8 79 { .n_name = "_clnp_stat"}, 80 #define IN_NOTUSED 9 81 { .n_name = "_tp_inpcb" }, 82 #define ISO_TP 10 83 { .n_name = "_tp_refinfo" }, 84 #define N_TPSTAT 11 85 { .n_name = "_tp_stat" }, 86 #define N_ESISSTAT 12 87 { .n_name = "_esis_stat"}, 88 #define N_NIMP 13 89 { .n_name = "_nimp"}, 90 #define N_RTREE 14 91 { .n_name = "_rt_tables"}, 92 #define N_CLTP 15 93 { .n_name = "_cltb"}, 94 #define N_CLTPSTAT 16 95 { .n_name = "_cltpstat"}, 96 #define N_NFILE 17 97 { .n_name = "_nfile" }, 98 #define N_FILE 18 99 { .n_name = "_file" }, 100 #define N_MRTSTAT 19 101 { .n_name = "_mrtstat" }, 102 #define N_MFCTABLE 20 103 { .n_name = "_mfctable" }, 104 #define N_VIFTABLE 21 105 { .n_name = "_viftable" }, 106 #define N_IPX 22 107 { .n_name = "_ipxpcb"}, 108 #define N_IPXSTAT 23 109 { .n_name = "_ipxstat"}, 110 #define N_SPXSTAT 24 111 { .n_name = "_spx_istat"}, 112 #define N_NGSOCKS 25 113 { .n_name = "_ngsocklist"}, 114 #define N_IP6STAT 26 115 { .n_name = "_ip6stat" }, 116 #define N_ICMP6STAT 27 117 { .n_name = "_icmp6stat" }, 118 #define N_IPSECSTAT 28 119 { .n_name = "_ipsecstat" }, 120 #define N_IPSEC6STAT 29 121 { .n_name = "_ipsec6stat" }, 122 #define N_PIM6STAT 30 123 { .n_name = "_pim6stat" }, 124 #define N_MRT6PROTO 31 125 { .n_name = "_ip6_mrtproto" }, 126 #define N_MRT6STAT 32 127 { .n_name = "_mrt6stat" }, 128 #define N_MF6CTABLE 33 129 { .n_name = "_mf6ctable" }, 130 #define N_MIF6TABLE 34 131 { .n_name = "_mif6table" }, 132 #define N_PFKEYSTAT 35 133 { .n_name = "_pfkeystat" }, 134 #define N_MBSTAT 36 135 { .n_name = "_mbstat" }, 136 #define N_MBTYPES 37 137 { .n_name = "_mbtypes" }, 138 #define N_NMBCLUSTERS 38 139 { .n_name = "_nmbclusters" }, 140 #define N_NMBUFS 39 141 { .n_name = "_nmbufs" }, 142 #define N_RTTRASH 40 143 { .n_name = "_rttrash" }, 144 #define N_NCPUS 41 145 { .n_name = "_ncpus" }, 146 #define N_CARPSTAT 42 147 { .n_name = "_carpstats" }, 148 { .n_name = NULL }, 149 }; 150 151 struct protox { 152 u_char pr_index; /* index into nlist of cb head */ 153 u_char pr_sindex; /* index into nlist of stat block */ 154 u_char pr_wanted; /* 1 if wanted, 0 otherwise */ 155 void (*pr_cblocks)(u_long, const char *, int); 156 /* control blocks printing routine */ 157 void (*pr_stats)(u_long, const char *, int); 158 /* statistics printing routine */ 159 void (*pr_istats)(char *); /* per/if statistics printing routine */ 160 const char *pr_name; /* well-known name */ 161 u_int pr_usesysctl; /* true if we use sysctl, not kvm */ 162 } protox[] = { 163 { -1, -1, 1, protopr, 164 tcp_stats, NULL, "tcp", IPPROTO_TCP }, 165 { -1, -1, 1, protopr, 166 udp_stats, NULL, "udp", IPPROTO_UDP }, 167 { -1, -1, 1, protopr, 168 NULL, NULL, "divert",IPPROTO_DIVERT }, 169 { -1, -1, 1, protopr, 170 ip_stats, NULL, "ip", IPPROTO_RAW }, 171 { -1, -1, 1, protopr, 172 icmp_stats, NULL, "icmp", IPPROTO_ICMP }, 173 { -1, -1, 1, protopr, 174 igmp_stats, NULL, "igmp", IPPROTO_IGMP }, 175 #ifdef IPSEC 176 { -1, N_IPSECSTAT, 1, 0, 177 ipsec_stats, NULL, "ipsec", 0}, 178 #endif 179 { -1, N_CARPSTAT, 1, 0, 180 carp_stats, NULL, "carp", 0}, 181 { -1, -1, 0, 0, 182 0, NULL, NULL, 0} 183 }; 184 185 #ifdef INET6 186 struct protox ip6protox[] = { 187 { -1, -1, 1, protopr, 188 tcp_stats, NULL, "tcp", IPPROTO_TCP }, 189 { -1, -1, 1, protopr, 190 udp_stats, NULL, "udp", IPPROTO_UDP }, 191 { -1, N_IP6STAT, 1, protopr, 192 ip6_stats, ip6_ifstats, "ip6", IPPROTO_RAW }, 193 { -1, N_ICMP6STAT, 1, protopr, 194 icmp6_stats, icmp6_ifstats, "icmp6",IPPROTO_ICMPV6 }, 195 #ifdef IPSEC 196 { -1, N_IPSEC6STAT, 1, 0, 197 ipsec_stats, NULL, "ipsec6",0 }, 198 #endif 199 #ifdef notyet 200 { -1, N_PIM6STAT, 1, 0, 201 pim6_stats, NULL, "pim6", 0 }, 202 #endif 203 { -1, -1, 1, 0, 204 rip6_stats, NULL, "rip6", 0 }, 205 { -1, -1, 1, protopr, 206 pim_stats, NULL, "pim", IPPROTO_PIM }, 207 { -1, -1, 0, 0, 208 0, NULL, 0, 0 } 209 }; 210 #endif /*INET6*/ 211 212 #ifdef IPSEC 213 struct protox pfkeyprotox[] = { 214 { -1, N_PFKEYSTAT, 1, 0, 215 pfkey_stats, NULL, "pfkey", 0 }, 216 { -1, -1, 0, 0, 217 0, NULL, 0, 0 } 218 }; 219 #endif 220 221 struct protox netgraphprotox[] = { 222 { N_NGSOCKS, -1, 1, netgraphprotopr, 223 NULL, NULL, "ctrl", 0 }, 224 { N_NGSOCKS, -1, 1, netgraphprotopr, 225 NULL, NULL, "data", 0 }, 226 { -1, -1, 0, 0, 227 0, NULL, NULL, 0 } 228 }; 229 230 struct protox ipxprotox[] = { 231 { N_IPX, N_IPXSTAT, 1, ipxprotopr, 232 ipx_stats, NULL, "ipx", 0 }, 233 { N_IPX, N_SPXSTAT, 1, ipxprotopr, 234 spx_stats, NULL, "spx", 0 }, 235 { -1, -1, 0, 0, 236 0, NULL, 0, 0 } 237 }; 238 239 #ifdef ISO 240 struct protox isoprotox[] = { 241 { ISO_TP, N_TPSTAT, 1, iso_protopr, 242 tp_stats, NULL, "tp" }, 243 { N_CLTP, N_CLTPSTAT, 1, iso_protopr, 244 cltp_stats, NULL, "cltp" }, 245 { -1, N_CLNPSTAT, 1, 0, 246 clnp_stats, NULL, "clnp"}, 247 { -1, N_ESISSTAT, 1, 0, 248 esis_stats, NULL, "esis"}, 249 { -1, -1, 0, 0, 250 0, NULL, 0 } 251 }; 252 #endif 253 254 struct protox *protoprotox[] = { 255 protox, 256 #ifdef INET6 257 ip6protox, 258 #endif 259 #ifdef IPSEC 260 pfkeyprotox, 261 #endif 262 ipxprotox, 263 #ifdef ISO 264 isoprotox, 265 #endif 266 NULL }; 267 268 static void printproto (struct protox *, const char *); 269 static void usage (void); 270 static struct protox *name2protox (char *); 271 static struct protox *knownname (char *); 272 273 static kvm_t *kvmd; 274 static char *nlistf = NULL, *memf = NULL; 275 276 int Aflag; /* show addresses of protocol control block */ 277 int aflag; /* show all sockets (including servers) */ 278 int bflag; /* show i/f total bytes in/out */ 279 int cpuflag = -1; /* dump route table from specific cpu */ 280 int dflag; /* show i/f dropped packets */ 281 int gflag; /* show group (multicast) routing or stats */ 282 int iflag; /* show interfaces */ 283 int Lflag; /* show size of listen queues */ 284 int mflag; /* show memory stats */ 285 int Pflag; /* show more protocol info (go past 80 columns) */ 286 int numeric_addr; /* show addresses numerically */ 287 int numeric_port; /* show ports numerically */ 288 static int pflag; /* show given protocol */ 289 int rflag; /* show routing tables (or routing stats) */ 290 int sflag; /* show protocol statistics */ 291 int tflag; /* show i/f watchdog timers */ 292 int Bflag; /* show buffer limit instead of buffer use */ 293 int Wflag; /* wide display */ 294 int zflag; /* zero stats */ 295 296 int interval; /* repeat interval for i/f stats */ 297 298 char *interface; /* desired i/f for stats, or NULL for all i/fs */ 299 int unit; /* unit number for above */ 300 301 int af; /* address family */ 302 303 int 304 main(int argc, char **argv) 305 { 306 struct protox *tp = NULL; /* for printing cblocks & stats */ 307 int ch; 308 int n; 309 310 af = AF_UNSPEC; 311 312 while ((ch = getopt(argc, argv, "Aabc:df:gI:iLlM:mN:nPp:rSsBtuWw:z")) != -1) 313 switch(ch) { 314 case 'A': 315 Aflag = 1; 316 break; 317 case 'a': 318 aflag = 1; 319 break; 320 case 'b': 321 bflag = 1; 322 break; 323 case 'c': 324 kread(0, 0, 0); 325 kread(nl[N_NCPUS].n_value, (char *)&n, sizeof(n)); 326 cpuflag = strtol(optarg, NULL, 0); 327 if (cpuflag < 0 || cpuflag >= n) 328 errx(1, "cpu %d does not exist", cpuflag); 329 break; 330 case 'd': 331 dflag = 1; 332 break; 333 case 'f': 334 if (strcmp(optarg, "ipx") == 0) 335 af = AF_IPX; 336 else if (strcmp(optarg, "inet") == 0) 337 af = AF_INET; 338 #ifdef INET6 339 else if (strcmp(optarg, "inet6") == 0) 340 af = AF_INET6; 341 #endif /*INET6*/ 342 #ifdef INET6 343 else if (strcmp(optarg, "pfkey") == 0) 344 af = PF_KEY; 345 #endif /*INET6*/ 346 else if (strcmp(optarg, "unix") == 0) 347 af = AF_UNIX; 348 else if (strcmp(optarg, "ng") == 0 349 || strcmp(optarg, "netgraph") == 0) 350 af = AF_NETGRAPH; 351 #ifdef ISO 352 else if (strcmp(optarg, "iso") == 0) 353 af = AF_ISO; 354 #endif 355 else if (strcmp(optarg, "link") == 0) 356 af = AF_LINK; 357 else if (strcmp(optarg, "mpls") == 0) 358 af = AF_MPLS; 359 else { 360 errx(1, "%s: unknown address family", optarg); 361 } 362 break; 363 case 'g': 364 gflag = 1; 365 break; 366 case 'I': { 367 char *cp; 368 369 iflag = 1; 370 for (cp = interface = optarg; isalpha(*cp); cp++) 371 continue; 372 unit = atoi(cp); 373 break; 374 } 375 case 'i': 376 iflag = 1; 377 break; 378 case 'L': 379 Lflag = 1; 380 break; 381 case 'M': 382 memf = optarg; 383 break; 384 case 'm': 385 mflag = 1; 386 break; 387 case 'N': 388 nlistf = optarg; 389 break; 390 case 'n': 391 numeric_addr = numeric_port = 1; 392 break; 393 case 'P': 394 Pflag = 1; 395 break; 396 case 'p': 397 if ((tp = name2protox(optarg)) == NULL) { 398 errx(1, 399 "%s: unknown or uninstrumented protocol", 400 optarg); 401 } 402 pflag = 1; 403 break; 404 case 'r': 405 rflag = 1; 406 break; 407 case 's': 408 ++sflag; 409 break; 410 case 'S': 411 numeric_addr = 1; 412 break; 413 case 'B': 414 Bflag = 1; 415 break; 416 case 't': 417 tflag = 1; 418 break; 419 case 'u': 420 af = AF_UNIX; 421 break; 422 case 'W': 423 case 'l': 424 Wflag = 1; 425 break; 426 case 'w': 427 interval = atoi(optarg); 428 iflag = 1; 429 break; 430 case 'z': 431 zflag = 1; 432 break; 433 case '?': 434 default: 435 usage(); 436 } 437 argv += optind; 438 argc -= optind; 439 440 #define BACKWARD_COMPATIBILITY 441 #ifdef BACKWARD_COMPATIBILITY 442 if (*argv) { 443 if (isdigit(**argv)) { 444 interval = atoi(*argv); 445 if (interval <= 0) 446 usage(); 447 ++argv; 448 iflag = 1; 449 } 450 if (*argv) { 451 nlistf = *argv; 452 if (*++argv) 453 memf = *argv; 454 } 455 } 456 #endif 457 458 /* 459 * Discard setgid privileges if not the running kernel so that bad 460 * guys can't print interesting stuff from kernel memory. 461 */ 462 if (nlistf != NULL || memf != NULL) 463 setgid(getgid()); 464 465 if (mflag) { 466 if (memf != NULL) { 467 if (kread(0, 0, 0) == 0) 468 mbpr(nl[N_MBSTAT].n_value, 469 nl[N_MBTYPES].n_value, 470 nl[N_NMBCLUSTERS].n_value, 471 nl[N_NMBUFS].n_value, 472 nl[N_NCPUS].n_value); 473 } else { 474 mbpr(0, 0, 0, 0, 0); 475 } 476 exit(0); 477 } 478 #if 0 479 /* 480 * Keep file descriptors open to avoid overhead 481 * of open/close on each call to get* routines. 482 */ 483 sethostent(1); 484 setnetent(1); 485 #else 486 /* 487 * This does not make sense any more with DNS being default over 488 * the files. Doing a setXXXXent(1) causes a tcp connection to be 489 * used for the queries, which is slower. 490 */ 491 #endif 492 if (iflag && !sflag) { 493 kread(0, 0, 0); 494 intpr(interval, nl[N_IFNET].n_value, NULL); 495 exit(0); 496 } 497 if (rflag) { 498 kread(0, 0, 0); 499 if (sflag) 500 rt_stats(); 501 else 502 routepr(nl[N_RTREE].n_value); 503 exit(0); 504 } 505 if (gflag) { 506 kread(0, 0, 0); 507 if (sflag) { 508 if (af == AF_INET || af == AF_UNSPEC) 509 mrt_stats(nl[N_MRTSTAT].n_value); 510 #ifdef INET6 511 if (af == AF_INET6 || af == AF_UNSPEC) 512 mrt6_stats(nl[N_MRT6STAT].n_value); 513 #endif 514 } else { 515 if (af == AF_INET || af == AF_UNSPEC) 516 mroutepr(nl[N_MFCTABLE].n_value, 517 nl[N_VIFTABLE].n_value); 518 #ifdef INET6 519 if (af == AF_INET6 || af == AF_UNSPEC) 520 mroute6pr(nl[N_MF6CTABLE].n_value, 521 nl[N_MIF6TABLE].n_value); 522 #endif 523 } 524 exit(0); 525 } 526 527 kread(0, 0, 0); 528 if (tp) { 529 printproto(tp, tp->pr_name); 530 exit(0); 531 } 532 if (af == AF_INET || af == AF_UNSPEC) 533 for (tp = protox; tp->pr_name; tp++) 534 printproto(tp, tp->pr_name); 535 #ifdef INET6 536 if (af == AF_INET6 || af == AF_UNSPEC) 537 for (tp = ip6protox; tp->pr_name; tp++) 538 printproto(tp, tp->pr_name); 539 #endif /*INET6*/ 540 #ifdef IPSEC 541 if (af == PF_KEY || af == AF_UNSPEC) 542 for (tp = pfkeyprotox; tp->pr_name; tp++) 543 printproto(tp, tp->pr_name); 544 #endif /*IPSEC*/ 545 if (af == AF_IPX || af == AF_UNSPEC) { 546 kread(0, 0, 0); 547 for (tp = ipxprotox; tp->pr_name; tp++) 548 printproto(tp, tp->pr_name); 549 } 550 if (af == AF_NETGRAPH || af == AF_UNSPEC) 551 for (tp = netgraphprotox; tp->pr_name; tp++) 552 printproto(tp, tp->pr_name); 553 #ifdef ISO 554 if (af == AF_ISO || af == AF_UNSPEC) 555 for (tp = isoprotox; tp->pr_name; tp++) 556 printproto(tp, tp->pr_name); 557 #endif 558 if ((af == AF_UNIX || af == AF_UNSPEC) && !Lflag && !sflag) 559 unixpr(); 560 exit(0); 561 } 562 563 /* 564 * Print out protocol statistics or control blocks (per sflag). 565 * If the interface was not specifically requested, and the symbol 566 * is not in the namelist, ignore this one. 567 */ 568 static void 569 printproto(struct protox *tp, const char *name) 570 { 571 void (*pr)(u_long, const char *, int); 572 u_long off; 573 574 if (sflag) { 575 if (iflag) { 576 if (tp->pr_istats) 577 intpr(interval, nl[N_IFNET].n_value, 578 tp->pr_istats); 579 else if (pflag) 580 printf("%s: no per-interface stats routine\n", 581 tp->pr_name); 582 return; 583 } 584 else { 585 pr = tp->pr_stats; 586 if (!pr) { 587 if (pflag) 588 printf("%s: no stats routine\n", 589 tp->pr_name); 590 return; 591 } 592 off = tp->pr_usesysctl ? tp->pr_usesysctl 593 : nl[tp->pr_sindex].n_value; 594 } 595 } else { 596 pr = tp->pr_cblocks; 597 if (!pr) { 598 if (pflag) 599 printf("%s: no PCB routine\n", tp->pr_name); 600 return; 601 } 602 off = tp->pr_usesysctl ? tp->pr_usesysctl 603 : nl[tp->pr_index].n_value; 604 } 605 if (pr != NULL && (off || af != AF_UNSPEC)) 606 (*pr)(off, name, af); 607 } 608 609 /* 610 * Read kernel memory, return 0 on success. 611 */ 612 int 613 kread(u_long addr, char *buf, int size) 614 { 615 if (kvmd == 0) { 616 /* 617 * XXX. 618 */ 619 kvmd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf); 620 if (kvmd != NULL) { 621 if (kvm_nlist(kvmd, nl) < 0) { 622 if(nlistf) 623 errx(1, "%s: kvm_nlist: %s", nlistf, 624 kvm_geterr(kvmd)); 625 else 626 errx(1, "kvm_nlist: %s", kvm_geterr(kvmd)); 627 } 628 629 if (nl[0].n_type == 0) { 630 if(nlistf) 631 errx(1, "%s: no namelist", nlistf); 632 else 633 errx(1, "no namelist"); 634 } 635 } else { 636 warnx("kvm not available"); 637 return(-1); 638 } 639 } 640 if (!buf) 641 return (0); 642 if (kvm_read(kvmd, addr, buf, size) != size) { 643 warnx("%s", kvm_geterr(kvmd)); 644 return (-1); 645 } 646 return (0); 647 } 648 649 const char * 650 plural(int n) 651 { 652 return (n != 1 ? "s" : ""); 653 } 654 655 const char * 656 plurales(int n) 657 { 658 return (n != 1 ? "es" : ""); 659 } 660 661 /* 662 * Find the protox for the given "well-known" name. 663 */ 664 static struct protox * 665 knownname(char *name) 666 { 667 struct protox **tpp, *tp; 668 669 for (tpp = protoprotox; *tpp; tpp++) 670 for (tp = *tpp; tp->pr_name; tp++) 671 if (strcmp(tp->pr_name, name) == 0) 672 return (tp); 673 return (NULL); 674 } 675 676 /* 677 * Find the protox corresponding to name. 678 */ 679 static struct protox * 680 name2protox(char *name) 681 { 682 struct protox *tp; 683 char **alias; /* alias from p->aliases */ 684 struct protoent *p; 685 686 /* 687 * Try to find the name in the list of "well-known" names. If that 688 * fails, check if name is an alias for an Internet protocol. 689 */ 690 if ((tp = knownname(name)) != NULL) 691 return (tp); 692 693 setprotoent(1); /* make protocol lookup cheaper */ 694 while ((p = getprotoent()) != NULL) { 695 /* assert: name not same as p->name */ 696 for (alias = p->p_aliases; *alias; alias++) 697 if (strcmp(name, *alias) == 0) { 698 endprotoent(); 699 return (knownname(p->p_name)); 700 } 701 } 702 endprotoent(); 703 return (NULL); 704 } 705 706 static void 707 usage(void) 708 { 709 (void)fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", 710 "usage: netstat [-AaLnPSW] [-c cpu] [-f protocol_family | -p protocol]\n" 711 " [-M core] [-N system]", 712 " netstat -i | -I interface [-aBbdnt] [-f address_family]\n" 713 " [-M core] [-N system]", 714 " netstat -w wait [-I interface] [-d] [-M core] [-N system]", 715 " netstat -s [-s] [-z] [-f protocol_family | -p protocol] [-M core]", 716 " netstat -i | -I interface -s [-f protocol_family | -p protocol]\n" 717 " [-M core] [-N system]", 718 " netstat -m [-M core] [-N system]", 719 " netstat -r [-AanW] [-f address_family] [-M core] [-N system]", 720 " netstat -rs [-s] [-M core] [-N system]", 721 " netstat -g [-W] [-f address_family] [-M core] [-N system]", 722 " netstat -gs [-s] [-f address_family] [-M core] [-N system]"); 723 exit(1); 724 } 725