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