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