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