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 u_long oqdrops; 128 short timer; 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("%-9.9s %-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(" %5s", "Time"); 163 if (dflag) 164 printf(" %5s", "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 = (u_long)TAILQ_FIRST(&head); 205 if (ifaddrcont_addr == 0) { 206 ifaddraddr = 0; 207 } else { 208 if (kread(ifaddrcont_addr, (char *)&ifac, 209 sizeof(ifac))) 210 return; 211 ifaddraddr = (u_long)ifac.ifa; 212 } 213 } 214 ifaddrfound = ifaddraddr; 215 216 /* 217 * Get the interface stats. These may get 218 * overridden below on a per-interface basis. 219 */ 220 ifdataaddr = (u_long)ifnet.if_data_pcpu; 221 if (kread(ifdataaddr, (char *)&ifdata, sizeof(ifdata))) 222 return; 223 opackets = ifdata.ifd_opackets; 224 ipackets = ifdata.ifd_ipackets; 225 obytes = ifdata.ifd_obytes; 226 ibytes = ifdata.ifd_ibytes; 227 oerrors = ifdata.ifd_oerrors; 228 ierrors = ifdata.ifd_ierrors; 229 collisions = ifdata.ifd_collisions; 230 oqdrops = ifdata.ifd_oqdrops; 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 oqdrops += ifdata.ifd_oqdrops; 244 } 245 246 timer = ifnet.if_timer; 247 248 if (ifaddraddr == 0) { 249 printf("%-9.9s %-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#%hu>", 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", 5, timer, link_layer); 410 } 411 if (dflag) { 412 printf(" "); 413 show_stat("lu", 5, oqdrops, 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_long 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, "(%.13s)", 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 ifnet.if_oqdrops = ifdata.ifd_oqdrops; 591 592 for (cpu = 1; cpu < ncpus; ++cpu) { 593 if (kread(ifdata_addr + (cpu * sizeof(ifdata)), 594 (char *)&ifdata, sizeof(ifdata))) { 595 printf("ifdata 2\n"); 596 exit(1); 597 } 598 ifnet.if_ipackets += ifdata.ifd_ipackets; 599 ifnet.if_ierrors += ifdata.ifd_ierrors; 600 ifnet.if_ibytes += ifdata.ifd_ibytes; 601 ifnet.if_opackets += ifdata.ifd_opackets; 602 ifnet.if_oerrors += ifdata.ifd_oerrors; 603 ifnet.if_obytes += ifdata.ifd_obytes; 604 ifnet.if_collisions += ifdata.ifd_collisions; 605 ifnet.if_oqdrops += ifdata.ifd_oqdrops; 606 } 607 608 if (!first) { 609 printf("%10lu %5lu %10lu %10lu %5lu %10lu %5lu", 610 ifnet.if_ipackets - ip->ift_ip, 611 ifnet.if_ierrors - ip->ift_ie, 612 ifnet.if_ibytes - ip->ift_ib, 613 ifnet.if_opackets - ip->ift_op, 614 ifnet.if_oerrors - ip->ift_oe, 615 ifnet.if_obytes - ip->ift_ob, 616 ifnet.if_collisions - ip->ift_co); 617 if (dflag) 618 printf(" %5lu", ifnet.if_oqdrops - ip->ift_dr); 619 } 620 ip->ift_ip = ifnet.if_ipackets; 621 ip->ift_ie = ifnet.if_ierrors; 622 ip->ift_ib = ifnet.if_ibytes; 623 ip->ift_op = ifnet.if_opackets; 624 ip->ift_oe = ifnet.if_oerrors; 625 ip->ift_ob = ifnet.if_obytes; 626 ip->ift_co = ifnet.if_collisions; 627 ip->ift_dr = ifnet.if_oqdrops; 628 } else { 629 sum->ift_ip = 0; 630 sum->ift_ie = 0; 631 sum->ift_ib = 0; 632 sum->ift_op = 0; 633 sum->ift_oe = 0; 634 sum->ift_ob = 0; 635 sum->ift_co = 0; 636 sum->ift_dr = 0; 637 for (off = firstifnet, ip = iftot; 638 off && SLIST_NEXT(ip, chain) != NULL; 639 ip = SLIST_NEXT(ip, chain)) { 640 if (kread(off, (char *)&ifnet, sizeof ifnet)) { 641 off = 0; 642 continue; 643 } 644 645 ifdata_addr = (u_long)ifnet.if_data_pcpu; 646 if (kread(ifdata_addr, (char *)&ifdata, 647 sizeof(ifdata))) { 648 printf("ifdata 3\n"); 649 exit(1); 650 } 651 ifnet.if_ipackets = ifdata.ifd_ipackets; 652 ifnet.if_ierrors = ifdata.ifd_ierrors; 653 ifnet.if_ibytes = ifdata.ifd_ibytes; 654 ifnet.if_opackets = ifdata.ifd_opackets; 655 ifnet.if_oerrors = ifdata.ifd_oerrors; 656 ifnet.if_obytes = ifdata.ifd_obytes; 657 ifnet.if_collisions = ifdata.ifd_collisions; 658 ifnet.if_oqdrops = ifdata.ifd_oqdrops; 659 660 for (cpu = 1; cpu < ncpus; ++cpu) { 661 if (kread(ifdata_addr + (cpu * sizeof(ifdata)), 662 (char *)&ifdata, sizeof(ifdata))) { 663 printf("ifdata 2\n"); 664 exit(1); 665 } 666 ifnet.if_ipackets += ifdata.ifd_ipackets; 667 ifnet.if_ierrors += ifdata.ifd_ierrors; 668 ifnet.if_ibytes += ifdata.ifd_ibytes; 669 ifnet.if_opackets += ifdata.ifd_opackets; 670 ifnet.if_oerrors += ifdata.ifd_oerrors; 671 ifnet.if_obytes += ifdata.ifd_obytes; 672 ifnet.if_collisions += ifdata.ifd_collisions; 673 ifnet.if_oqdrops += ifdata.ifd_oqdrops; 674 } 675 676 /* 677 * Don't double-count interfaces that are associated 678 * with bridges, they will be rolled up by the 679 * bridge. Errors and collisions are not rolled up. 680 */ 681 if (ifnet.if_bridge) { 682 sum->ift_ie += ifnet.if_ierrors; 683 sum->ift_oe += ifnet.if_oerrors; 684 sum->ift_co += ifnet.if_collisions; 685 } else { 686 sum->ift_ip += ifnet.if_ipackets; 687 sum->ift_ie += ifnet.if_ierrors; 688 sum->ift_ib += ifnet.if_ibytes; 689 sum->ift_op += ifnet.if_opackets; 690 sum->ift_oe += ifnet.if_oerrors; 691 sum->ift_ob += ifnet.if_obytes; 692 sum->ift_co += ifnet.if_collisions; 693 sum->ift_dr += ifnet.if_oqdrops; 694 } 695 off = (u_long)TAILQ_NEXT(&ifnet, if_link); 696 } 697 if (!first) { 698 /* %10lu %5lu %10lu %10lu %5lu %10lu %5lu */ 699 show_stat("lu", 10, sum->ift_ip - total->ift_ip, 1); 700 show_stat("lu", 5+1, sum->ift_ie - total->ift_ie, 1); 701 show_stat("lu", 10+1, sum->ift_ib - total->ift_ib, 1); 702 show_stat("lu", 10+1, sum->ift_op - total->ift_op, 1); 703 show_stat("lu", 5+1, sum->ift_oe - total->ift_oe, 1); 704 show_stat("lu", 10+1, sum->ift_ob - total->ift_ob, 1); 705 show_stat("lu", 5+1, sum->ift_co - total->ift_co, 1); 706 if (dflag) 707 show_stat("u", 5+1, sum->ift_dr - total->ift_dr, 1); 708 } 709 *total = *sum; 710 } 711 if (!first) 712 putchar('\n'); 713 fflush(stdout); 714 oldmask = sigblock(sigmask(SIGALRM)); 715 if (! signalled) { 716 sigpause(0); 717 } 718 sigsetmask(oldmask); 719 signalled = NO; 720 (void)alarm(interval1); 721 line++; 722 first = 0; 723 if (line == 21) 724 goto banner; 725 else 726 goto loop; 727 /*NOTREACHED*/ 728 } 729 730 /* 731 * Called if an interval expires before sidewaysintpr has completed a loop. 732 * Sets a flag to not wait for the alarm. 733 */ 734 static void 735 catchalarm(int signo __unused) 736 { 737 signalled = YES; 738 } 739