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