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