1 /*- 2 * Copyright (c) 1983, 1988, 1993 3 * The 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 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #if 0 31 #ifndef lint 32 static char sccsid[] = "@(#)if.c 8.3 (Berkeley) 4/28/95"; 33 #endif /* not lint */ 34 #endif 35 36 #include <sys/cdefs.h> 37 __FBSDID("$FreeBSD$"); 38 39 #include <sys/types.h> 40 #include <sys/protosw.h> 41 #include <sys/socket.h> 42 #include <sys/socketvar.h> 43 #include <sys/sysctl.h> 44 #include <sys/time.h> 45 46 #include <net/if.h> 47 #include <net/if_var.h> 48 #include <net/if_dl.h> 49 #include <net/if_types.h> 50 #include <net/ethernet.h> 51 #include <net/pfvar.h> 52 #include <net/if_pfsync.h> 53 #include <netinet/in.h> 54 #include <netinet/in_var.h> 55 #include <netipx/ipx.h> 56 #include <netipx/ipx_if.h> 57 #include <arpa/inet.h> 58 59 #include <err.h> 60 #include <errno.h> 61 #include <libutil.h> 62 #ifdef INET6 63 #include <netdb.h> 64 #endif 65 #include <signal.h> 66 #include <stdint.h> 67 #include <stdio.h> 68 #include <stdlib.h> 69 #include <string.h> 70 #include <unistd.h> 71 72 #include "netstat.h" 73 74 #define YES 1 75 #define NO 0 76 77 static void sidewaysintpr(int, u_long); 78 static void catchalarm(int); 79 80 #ifdef INET6 81 static char addr_buf[NI_MAXHOST]; /* for getnameinfo() */ 82 #endif 83 84 static const char* pfsyncacts[] = { 85 /* PFSYNC_ACT_CLR */ "clear all request", 86 /* PFSYNC_ACT_INS */ "state insert", 87 /* PFSYNC_ACT_INS_ACK */ "state inserted ack", 88 /* PFSYNC_ACT_UPD */ "state update", 89 /* PFSYNC_ACT_UPD_C */ "compressed state update", 90 /* PFSYNC_ACT_UPD_REQ */ "uncompressed state request", 91 /* PFSYNC_ACT_DEL */ "state delete", 92 /* PFSYNC_ACT_DEL_C */ "compressed state delete", 93 /* PFSYNC_ACT_INS_F */ "fragment insert", 94 /* PFSYNC_ACT_DEL_F */ "fragment delete", 95 /* PFSYNC_ACT_BUS */ "bulk update mark", 96 /* PFSYNC_ACT_TDB */ "TDB replay counter update", 97 /* PFSYNC_ACT_EOF */ "end of frame mark", 98 }; 99 100 static void 101 pfsync_acts_stats(const char *fmt, uint64_t *a) 102 { 103 int i; 104 105 for (i = 0; i < PFSYNC_ACT_MAX; i++, a++) 106 if (*a || sflag <= 1) 107 printf(fmt, *a, pfsyncacts[i], plural(*a)); 108 } 109 110 /* 111 * Dump pfsync statistics structure. 112 */ 113 void 114 pfsync_stats(u_long off, const char *name, int af1 __unused, int proto __unused) 115 { 116 struct pfsyncstats pfsyncstat, zerostat; 117 size_t len = sizeof(struct pfsyncstats); 118 119 if (live) { 120 if (zflag) 121 memset(&zerostat, 0, len); 122 if (sysctlbyname("net.pfsync.stats", &pfsyncstat, &len, 123 zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { 124 if (errno != ENOENT) 125 warn("sysctl: net.pfsync.stats"); 126 return; 127 } 128 } else 129 kread(off, &pfsyncstat, len); 130 131 printf("%s:\n", name); 132 133 #define p(f, m) if (pfsyncstat.f || sflag <= 1) \ 134 printf(m, (uintmax_t)pfsyncstat.f, plural(pfsyncstat.f)) 135 136 p(pfsyncs_ipackets, "\t%ju packet%s received (IPv4)\n"); 137 p(pfsyncs_ipackets6, "\t%ju packet%s received (IPv6)\n"); 138 pfsync_acts_stats("\t %ju %s%s received\n", 139 &pfsyncstat.pfsyncs_iacts[0]); 140 p(pfsyncs_badif, "\t\t%ju packet%s discarded for bad interface\n"); 141 p(pfsyncs_badttl, "\t\t%ju packet%s discarded for bad ttl\n"); 142 p(pfsyncs_hdrops, "\t\t%ju packet%s shorter than header\n"); 143 p(pfsyncs_badver, "\t\t%ju packet%s discarded for bad version\n"); 144 p(pfsyncs_badauth, "\t\t%ju packet%s discarded for bad HMAC\n"); 145 p(pfsyncs_badact,"\t\t%ju packet%s discarded for bad action\n"); 146 p(pfsyncs_badlen, "\t\t%ju packet%s discarded for short packet\n"); 147 p(pfsyncs_badval, "\t\t%ju state%s discarded for bad values\n"); 148 p(pfsyncs_stale, "\t\t%ju stale state%s\n"); 149 p(pfsyncs_badstate, "\t\t%ju failed state lookup/insert%s\n"); 150 p(pfsyncs_opackets, "\t%ju packet%s sent (IPv4)\n"); 151 p(pfsyncs_opackets6, "\t%ju packet%s sent (IPv6)\n"); 152 pfsync_acts_stats("\t %ju %s%s sent\n", 153 &pfsyncstat.pfsyncs_oacts[0]); 154 p(pfsyncs_onomem, "\t\t%ju failure%s due to mbuf memory error\n"); 155 p(pfsyncs_oerrors, "\t\t%ju send error%s\n"); 156 #undef p 157 } 158 159 /* 160 * Display a formatted value, or a '-' in the same space. 161 */ 162 static void 163 show_stat(const char *fmt, int width, u_long value, short showvalue) 164 { 165 const char *lsep, *rsep; 166 char newfmt[32]; 167 168 lsep = ""; 169 if (strncmp(fmt, "LS", 2) == 0) { 170 lsep = " "; 171 fmt += 2; 172 } 173 rsep = " "; 174 if (strncmp(fmt, "NRS", 3) == 0) { 175 rsep = ""; 176 fmt += 3; 177 } 178 if (showvalue == 0) { 179 /* Print just dash. */ 180 sprintf(newfmt, "%s%%%ds%s", lsep, width, rsep); 181 printf(newfmt, "-"); 182 return; 183 } 184 185 if (hflag) { 186 char buf[5]; 187 188 /* Format in human readable form. */ 189 humanize_number(buf, sizeof(buf), (int64_t)value, "", 190 HN_AUTOSCALE, HN_NOSPACE | HN_DECIMAL); 191 sprintf(newfmt, "%s%%%ds%s", lsep, width, rsep); 192 printf(newfmt, buf); 193 } else { 194 /* Construct the format string. */ 195 sprintf(newfmt, "%s%%%d%s%s", lsep, width, fmt, rsep); 196 printf(newfmt, value); 197 } 198 } 199 200 /* 201 * Print a description of the network interfaces. 202 */ 203 void 204 intpr(int interval1, u_long ifnetaddr, void (*pfunc)(char *)) 205 { 206 struct ifnet ifnet; 207 struct ifnethead ifnethead; 208 union { 209 struct ifaddr ifa; 210 struct in_ifaddr in; 211 #ifdef INET6 212 struct in6_ifaddr in6; 213 #endif 214 struct ipx_ifaddr ipx; 215 } ifaddr; 216 u_long ifaddraddr; 217 u_long ifaddrfound; 218 u_long opackets; 219 u_long ipackets; 220 u_long obytes; 221 u_long ibytes; 222 u_long omcasts; 223 u_long imcasts; 224 u_long oerrors; 225 u_long ierrors; 226 u_long idrops; 227 u_long collisions; 228 int drops; 229 struct sockaddr *sa = NULL; 230 char name[IFNAMSIZ]; 231 short network_layer; 232 short link_layer; 233 234 if (ifnetaddr == 0) { 235 printf("ifnet: symbol not defined\n"); 236 return; 237 } 238 if (interval1) { 239 sidewaysintpr(interval1, ifnetaddr); 240 return; 241 } 242 if (kread(ifnetaddr, (char *)&ifnethead, sizeof ifnethead) != 0) 243 return; 244 ifnetaddr = (u_long)TAILQ_FIRST(&ifnethead); 245 if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) != 0) 246 return; 247 248 if (!pfunc) { 249 if (Wflag) 250 printf("%-7.7s", "Name"); 251 else 252 printf("%-5.5s", "Name"); 253 printf(" %5.5s %-13.13s %-17.17s %8.8s %5.5s %5.5s", 254 "Mtu", "Network", "Address", "Ipkts", "Ierrs", "Idrop"); 255 if (bflag) 256 printf(" %10.10s","Ibytes"); 257 printf(" %8.8s %5.5s", "Opkts", "Oerrs"); 258 if (bflag) 259 printf(" %10.10s","Obytes"); 260 printf(" %5s", "Coll"); 261 if (dflag) 262 printf(" %s", "Drop"); 263 putchar('\n'); 264 } 265 ifaddraddr = 0; 266 while (ifnetaddr || ifaddraddr) { 267 struct sockaddr_in *sockin; 268 #ifdef INET6 269 struct sockaddr_in6 *sockin6; 270 #endif 271 char *cp; 272 int n, m; 273 274 network_layer = 0; 275 link_layer = 0; 276 277 if (ifaddraddr == 0) { 278 if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) != 0) 279 return; 280 strlcpy(name, ifnet.if_xname, sizeof(name)); 281 ifnetaddr = (u_long)TAILQ_NEXT(&ifnet, if_link); 282 if (interface != 0 && strcmp(name, interface) != 0) 283 continue; 284 cp = strchr(name, '\0'); 285 286 if (pfunc) { 287 (*pfunc)(name); 288 continue; 289 } 290 291 if ((ifnet.if_flags&IFF_UP) == 0) 292 *cp++ = '*'; 293 *cp = '\0'; 294 ifaddraddr = (u_long)TAILQ_FIRST(&ifnet.if_addrhead); 295 } 296 ifaddrfound = ifaddraddr; 297 298 /* 299 * Get the interface stats. These may get 300 * overriden below on a per-interface basis. 301 */ 302 opackets = ifnet.if_opackets; 303 ipackets = ifnet.if_ipackets; 304 obytes = ifnet.if_obytes; 305 ibytes = ifnet.if_ibytes; 306 omcasts = ifnet.if_omcasts; 307 imcasts = ifnet.if_imcasts; 308 oerrors = ifnet.if_oerrors; 309 ierrors = ifnet.if_ierrors; 310 idrops = ifnet.if_iqdrops; 311 collisions = ifnet.if_collisions; 312 drops = ifnet.if_snd.ifq_drops; 313 314 if (ifaddraddr == 0) { 315 if (Wflag) 316 printf("%-7.7s", name); 317 else 318 printf("%-5.5s", name); 319 printf(" %5lu ", ifnet.if_mtu); 320 printf("%-13.13s ", "none"); 321 printf("%-17.17s ", "none"); 322 } else { 323 if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr) 324 != 0) { 325 ifaddraddr = 0; 326 continue; 327 } 328 #define CP(x) ((char *)(x)) 329 cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + 330 CP(&ifaddr); 331 sa = (struct sockaddr *)cp; 332 if (af != AF_UNSPEC && sa->sa_family != af) { 333 ifaddraddr = 334 (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link); 335 continue; 336 } 337 if (Wflag) 338 printf("%-7.7s", name); 339 else 340 printf("%-5.5s", name); 341 printf(" %5lu ", ifnet.if_mtu); 342 switch (sa->sa_family) { 343 case AF_UNSPEC: 344 printf("%-13.13s ", "none"); 345 printf("%-15.15s ", "none"); 346 break; 347 case AF_INET: 348 sockin = (struct sockaddr_in *)sa; 349 #ifdef notdef 350 /* can't use inet_makeaddr because kernel 351 * keeps nets unshifted. 352 */ 353 in = inet_makeaddr(ifaddr.in.ia_subnet, 354 INADDR_ANY); 355 printf("%-13.13s ", netname(in.s_addr, 356 ifaddr.in.ia_subnetmask)); 357 #else 358 printf("%-13.13s ", 359 netname(htonl(ifaddr.in.ia_subnet), 360 ifaddr.in.ia_subnetmask)); 361 #endif 362 printf("%-17.17s ", 363 routename(sockin->sin_addr.s_addr)); 364 365 network_layer = 1; 366 break; 367 #ifdef INET6 368 case AF_INET6: 369 sockin6 = (struct sockaddr_in6 *)sa; 370 in6_fillscopeid(&ifaddr.in6.ia_addr); 371 printf("%-13.13s ", 372 netname6(&ifaddr.in6.ia_addr, 373 &ifaddr.in6.ia_prefixmask.sin6_addr)); 374 in6_fillscopeid(sockin6); 375 getnameinfo(sa, sa->sa_len, addr_buf, 376 sizeof(addr_buf), 0, 0, NI_NUMERICHOST); 377 printf("%-17.17s ", addr_buf); 378 379 network_layer = 1; 380 break; 381 #endif /*INET6*/ 382 case AF_IPX: 383 { 384 struct sockaddr_ipx *sipx = 385 (struct sockaddr_ipx *)sa; 386 u_long net; 387 char netnum[10]; 388 389 *(union ipx_net *) &net = sipx->sipx_addr.x_net; 390 sprintf(netnum, "%lx", (u_long)ntohl(net)); 391 printf("ipx:%-8s ", netnum); 392 /* printf("ipx:%-8s ", netname(net, 0L)); */ 393 printf("%-17s ", 394 ipx_phost((struct sockaddr *)sipx)); 395 } 396 397 network_layer = 1; 398 break; 399 400 case AF_APPLETALK: 401 printf("atalk:%-12.12s ",atalk_print(sa,0x10) ); 402 printf("%-11.11s ",atalk_print(sa,0x0b) ); 403 break; 404 case AF_LINK: 405 { 406 struct sockaddr_dl *sdl = 407 (struct sockaddr_dl *)sa; 408 char linknum[10]; 409 cp = (char *)LLADDR(sdl); 410 n = sdl->sdl_alen; 411 sprintf(linknum, "<Link#%d>", sdl->sdl_index); 412 m = printf("%-13.13s ", linknum); 413 } 414 goto hexprint; 415 default: 416 m = printf("(%d)", sa->sa_family); 417 for (cp = sa->sa_len + (char *)sa; 418 --cp > sa->sa_data && (*cp == 0);) {} 419 n = cp - sa->sa_data + 1; 420 cp = sa->sa_data; 421 hexprint: 422 while ((--n >= 0) && (m < 30)) 423 m += printf("%02x%c", *cp++ & 0xff, 424 n > 0 ? ':' : ' '); 425 m = 32 - m; 426 while (m-- > 0) 427 putchar(' '); 428 429 link_layer = 1; 430 break; 431 } 432 433 /* 434 * Fixup the statistics for interfaces that 435 * update stats for their network addresses 436 */ 437 if (network_layer) { 438 opackets = ifaddr.in.ia_ifa.if_opackets; 439 ipackets = ifaddr.in.ia_ifa.if_ipackets; 440 obytes = ifaddr.in.ia_ifa.if_obytes; 441 ibytes = ifaddr.in.ia_ifa.if_ibytes; 442 } 443 444 ifaddraddr = (u_long)TAILQ_NEXT(&ifaddr.ifa, ifa_link); 445 } 446 447 show_stat("lu", 8, ipackets, link_layer|network_layer); 448 show_stat("lu", 5, ierrors, link_layer); 449 show_stat("lu", 5, idrops, link_layer); 450 if (bflag) 451 show_stat("lu", 10, ibytes, link_layer|network_layer); 452 453 show_stat("lu", 8, opackets, link_layer|network_layer); 454 show_stat("lu", 5, oerrors, link_layer); 455 if (bflag) 456 show_stat("lu", 10, obytes, link_layer|network_layer); 457 458 show_stat("NRSlu", 5, collisions, link_layer); 459 if (dflag) 460 show_stat("LSd", 4, drops, link_layer); 461 putchar('\n'); 462 463 if (aflag && ifaddrfound) { 464 /* 465 * Print family's multicast addresses 466 */ 467 struct ifmultiaddr *multiaddr; 468 struct ifmultiaddr ifma; 469 union { 470 struct sockaddr sa; 471 struct sockaddr_in in; 472 #ifdef INET6 473 struct sockaddr_in6 in6; 474 #endif /* INET6 */ 475 struct sockaddr_dl dl; 476 } msa; 477 const char *fmt; 478 479 TAILQ_FOREACH(multiaddr, &ifnet.if_multiaddrs, ifma_link) { 480 if (kread((u_long)multiaddr, (char *)&ifma, 481 sizeof ifma) != 0) 482 break; 483 multiaddr = &ifma; 484 if (kread((u_long)ifma.ifma_addr, (char *)&msa, 485 sizeof msa) != 0) 486 break; 487 if (msa.sa.sa_family != sa->sa_family) 488 continue; 489 490 fmt = 0; 491 switch (msa.sa.sa_family) { 492 case AF_INET: 493 fmt = routename(msa.in.sin_addr.s_addr); 494 break; 495 #ifdef INET6 496 case AF_INET6: 497 in6_fillscopeid(&msa.in6); 498 getnameinfo(&msa.sa, msa.sa.sa_len, 499 addr_buf, sizeof(addr_buf), 0, 0, 500 NI_NUMERICHOST); 501 printf("%*s %-19.19s(refs: %d)\n", 502 Wflag ? 27 : 25, "", 503 addr_buf, ifma.ifma_refcount); 504 break; 505 #endif /* INET6 */ 506 case AF_LINK: 507 switch (msa.dl.sdl_type) { 508 case IFT_ETHER: 509 case IFT_FDDI: 510 fmt = ether_ntoa( 511 (struct ether_addr *) 512 LLADDR(&msa.dl)); 513 break; 514 } 515 break; 516 } 517 if (fmt) { 518 printf("%*s %-17.17s", 519 Wflag ? 27 : 25, "", fmt); 520 if (msa.sa.sa_family == AF_LINK) { 521 printf(" %8lu", imcasts); 522 printf("%*s", 523 bflag ? 17 : 6, ""); 524 printf(" %8lu", omcasts); 525 } 526 putchar('\n'); 527 } 528 } 529 } 530 } 531 } 532 533 struct iftot { 534 SLIST_ENTRY(iftot) chain; 535 char ift_name[IFNAMSIZ]; /* interface name */ 536 u_long ift_ip; /* input packets */ 537 u_long ift_ie; /* input errors */ 538 u_long ift_id; /* input drops */ 539 u_long ift_op; /* output packets */ 540 u_long ift_oe; /* output errors */ 541 u_long ift_co; /* collisions */ 542 u_int ift_dr; /* drops */ 543 u_long ift_ib; /* input bytes */ 544 u_long ift_ob; /* output bytes */ 545 }; 546 547 u_char signalled; /* set if alarm goes off "early" */ 548 549 /* 550 * Print a running summary of interface statistics. 551 * Repeat display every interval1 seconds, showing statistics 552 * collected over that interval. Assumes that interval1 is non-zero. 553 * First line printed at top of screen is always cumulative. 554 * XXX - should be rewritten to use ifmib(4). 555 */ 556 static void 557 sidewaysintpr(int interval1, u_long off) 558 { 559 struct ifnet ifnet; 560 u_long firstifnet; 561 struct ifnethead ifnethead; 562 struct itimerval interval_it; 563 struct iftot *iftot, *ip, *ipn, *total, *sum, *interesting; 564 int line; 565 int oldmask, first; 566 u_long interesting_off; 567 568 if (kread(off, (char *)&ifnethead, sizeof ifnethead) != 0) 569 return; 570 firstifnet = (u_long)TAILQ_FIRST(&ifnethead); 571 572 if ((iftot = malloc(sizeof(struct iftot))) == NULL) { 573 printf("malloc failed\n"); 574 exit(1); 575 } 576 memset(iftot, 0, sizeof(struct iftot)); 577 578 interesting = NULL; 579 interesting_off = 0; 580 for (off = firstifnet, ip = iftot; off;) { 581 char name[IFNAMSIZ]; 582 583 if (kread(off, (char *)&ifnet, sizeof ifnet) != 0) 584 break; 585 strlcpy(name, ifnet.if_xname, sizeof(name)); 586 if (interface && strcmp(name, interface) == 0) { 587 interesting = ip; 588 interesting_off = off; 589 } 590 snprintf(ip->ift_name, sizeof(ip->ift_name), "(%s)", name); 591 if ((ipn = malloc(sizeof(struct iftot))) == NULL) { 592 printf("malloc failed\n"); 593 exit(1); 594 } 595 memset(ipn, 0, sizeof(struct iftot)); 596 SLIST_NEXT(ip, chain) = ipn; 597 ip = ipn; 598 off = (u_long)TAILQ_NEXT(&ifnet, if_link); 599 } 600 if (interface && interesting == NULL) 601 errx(1, "%s: unknown interface", interface); 602 if ((total = malloc(sizeof(struct iftot))) == NULL) { 603 printf("malloc failed\n"); 604 exit(1); 605 } 606 memset(total, 0, sizeof(struct iftot)); 607 if ((sum = malloc(sizeof(struct iftot))) == NULL) { 608 printf("malloc failed\n"); 609 exit(1); 610 } 611 memset(sum, 0, sizeof(struct iftot)); 612 613 (void)signal(SIGALRM, catchalarm); 614 signalled = NO; 615 interval_it.it_interval.tv_sec = interval1; 616 interval_it.it_interval.tv_usec = 0; 617 interval_it.it_value = interval_it.it_interval; 618 setitimer(ITIMER_REAL, &interval_it, NULL); 619 first = 1; 620 banner: 621 printf("%17s %14s %16s", "input", 622 interesting ? interesting->ift_name : "(Total)", "output"); 623 putchar('\n'); 624 printf("%10s %5s %5s %10s %10s %5s %10s %5s", 625 "packets", "errs", "idrops", "bytes", "packets", "errs", "bytes", 626 "colls"); 627 if (dflag) 628 printf(" %5.5s", "drops"); 629 putchar('\n'); 630 fflush(stdout); 631 line = 0; 632 loop: 633 if (interesting != NULL) { 634 ip = interesting; 635 if (kread(interesting_off, (char *)&ifnet, sizeof ifnet) != 0) { 636 printf("???\n"); 637 exit(1); 638 }; 639 if (!first) { 640 show_stat("lu", 10, ifnet.if_ipackets - ip->ift_ip, 1); 641 show_stat("lu", 5, ifnet.if_ierrors - ip->ift_ie, 1); 642 show_stat("lu", 5, ifnet.if_iqdrops - ip->ift_id, 1); 643 show_stat("lu", 10, ifnet.if_ibytes - ip->ift_ib, 1); 644 show_stat("lu", 10, ifnet.if_opackets - ip->ift_op, 1); 645 show_stat("lu", 5, ifnet.if_oerrors - ip->ift_oe, 1); 646 show_stat("lu", 10, ifnet.if_obytes - ip->ift_ob, 1); 647 show_stat("NRSlu", 5, 648 ifnet.if_collisions - ip->ift_co, 1); 649 if (dflag) 650 show_stat("LSu", 5, 651 ifnet.if_snd.ifq_drops - ip->ift_dr, 1); 652 } 653 ip->ift_ip = ifnet.if_ipackets; 654 ip->ift_ie = ifnet.if_ierrors; 655 ip->ift_id = ifnet.if_iqdrops; 656 ip->ift_ib = ifnet.if_ibytes; 657 ip->ift_op = ifnet.if_opackets; 658 ip->ift_oe = ifnet.if_oerrors; 659 ip->ift_ob = ifnet.if_obytes; 660 ip->ift_co = ifnet.if_collisions; 661 ip->ift_dr = ifnet.if_snd.ifq_drops; 662 } else { 663 sum->ift_ip = 0; 664 sum->ift_ie = 0; 665 sum->ift_id = 0; 666 sum->ift_ib = 0; 667 sum->ift_op = 0; 668 sum->ift_oe = 0; 669 sum->ift_ob = 0; 670 sum->ift_co = 0; 671 sum->ift_dr = 0; 672 for (off = firstifnet, ip = iftot; 673 off && SLIST_NEXT(ip, chain) != NULL; 674 ip = SLIST_NEXT(ip, chain)) { 675 if (kread(off, (char *)&ifnet, sizeof ifnet) != 0) { 676 off = 0; 677 continue; 678 } 679 sum->ift_ip += ifnet.if_ipackets; 680 sum->ift_ie += ifnet.if_ierrors; 681 sum->ift_id += ifnet.if_iqdrops; 682 sum->ift_ib += ifnet.if_ibytes; 683 sum->ift_op += ifnet.if_opackets; 684 sum->ift_oe += ifnet.if_oerrors; 685 sum->ift_ob += ifnet.if_obytes; 686 sum->ift_co += ifnet.if_collisions; 687 sum->ift_dr += ifnet.if_snd.ifq_drops; 688 off = (u_long)TAILQ_NEXT(&ifnet, if_link); 689 } 690 if (!first) { 691 show_stat("lu", 10, sum->ift_ip - total->ift_ip, 1); 692 show_stat("lu", 5, sum->ift_ie - total->ift_ie, 1); 693 show_stat("lu", 5, sum->ift_id - total->ift_id, 1); 694 show_stat("lu", 10, sum->ift_ib - total->ift_ib, 1); 695 show_stat("lu", 10, sum->ift_op - total->ift_op, 1); 696 show_stat("lu", 5, sum->ift_oe - total->ift_oe, 1); 697 show_stat("lu", 10, sum->ift_ob - total->ift_ob, 1); 698 show_stat("NRSlu", 5, sum->ift_co - total->ift_co, 1); 699 if (dflag) 700 show_stat("LSu", 5, 701 sum->ift_dr - total->ift_dr, 1); 702 } 703 *total = *sum; 704 } 705 if (!first) 706 putchar('\n'); 707 fflush(stdout); 708 if ((noutputs != 0) && (--noutputs == 0)) 709 exit(0); 710 oldmask = sigblock(sigmask(SIGALRM)); 711 while (!signalled) 712 sigpause(0); 713 signalled = NO; 714 sigsetmask(oldmask); 715 line++; 716 first = 0; 717 if (line == 21) 718 goto banner; 719 else 720 goto loop; 721 /*NOTREACHED*/ 722 } 723 724 /* 725 * Set a flag to indicate that a signal from the periodic itimer has been 726 * caught. 727 */ 728 static void 729 catchalarm(int signo __unused) 730 { 731 signalled = YES; 732 } 733