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