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