1 /* $OpenBSD: if.c,v 1.66 2012/08/26 19:42:53 tedu Exp $ */ 2 /* $NetBSD: if.c,v 1.16.4.2 1996/06/07 21:46:46 thorpej Exp $ */ 3 4 /* 5 * Copyright (c) 1983, 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include <sys/param.h> 34 #include <sys/types.h> 35 #include <sys/ioctl.h> 36 #include <sys/protosw.h> 37 #include <sys/socket.h> 38 #include <sys/sysctl.h> 39 40 #include <net/if.h> 41 #include <net/if_dl.h> 42 #include <net/if_types.h> 43 #include <net/route.h> 44 #include <netinet/in.h> 45 #include <netinet/in_var.h> 46 #include <netinet/if_ether.h> 47 #include <arpa/inet.h> 48 49 #include <err.h> 50 #include <limits.h> 51 #include <signal.h> 52 #include <stdio.h> 53 #include <stdlib.h> 54 #include <string.h> 55 #include <unistd.h> 56 #include <util.h> 57 58 #include "netstat.h" 59 60 static void print_addr(struct sockaddr *, struct sockaddr **, struct if_data *); 61 static void sidewaysintpr(u_int, int); 62 static void catchalarm(int); 63 static void get_rtaddrs(int, struct sockaddr *, struct sockaddr **); 64 static void fetchifs(void); 65 66 /* 67 * Print a description of the network interfaces. 68 * NOTE: ifnetaddr is the location of the kernel global "ifnet", 69 * which is a TAILQ_HEAD. 70 */ 71 void 72 intpr(int interval, int repeatcount) 73 { 74 struct if_msghdr ifm; 75 int mib[6] = { CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; 76 char name[IFNAMSIZ + 1]; /* + 1 for the '*' */ 77 char *buf, *next, *lim, *cp; 78 struct rt_msghdr *rtm; 79 struct ifa_msghdr *ifam; 80 struct if_data *ifd; 81 struct sockaddr *sa, *rti_info[RTAX_MAX]; 82 struct sockaddr_dl *sdl; 83 u_int64_t total = 0; 84 size_t len; 85 86 if (interval) { 87 sidewaysintpr((unsigned)interval, repeatcount); 88 return; 89 } 90 91 if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) 92 err(1, "sysctl"); 93 if ((buf = malloc(len)) == NULL) 94 err(1, NULL); 95 if (sysctl(mib, 6, buf, &len, NULL, 0) == -1) 96 err(1, "sysctl"); 97 98 printf("%-7.7s %-5.5s %-11.11s %-17.17s ", 99 "Name", "Mtu", "Network", "Address"); 100 if (bflag) 101 printf("%10.10s %10.10s", "Ibytes", "Obytes"); 102 else 103 printf("%8.8s %5.5s %8.8s %5.5s %5.5s", 104 "Ipkts", "Ierrs", "Opkts", "Oerrs", "Colls"); 105 if (tflag) 106 printf(" %s", "Time"); 107 if (dflag) 108 printf(" %s", "Drop"); 109 putchar('\n'); 110 111 lim = buf + len; 112 for (next = buf; next < lim; next += rtm->rtm_msglen) { 113 rtm = (struct rt_msghdr *)next; 114 if (rtm->rtm_version != RTM_VERSION) 115 continue; 116 switch (rtm->rtm_type) { 117 case RTM_IFINFO: 118 total = 0; 119 bcopy(next, &ifm, sizeof ifm); 120 ifd = &ifm.ifm_data; 121 122 sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); 123 get_rtaddrs(ifm.ifm_addrs, sa, rti_info); 124 125 sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP]; 126 if (sdl == NULL || sdl->sdl_family != AF_LINK) 127 continue; 128 bzero(name, sizeof(name)); 129 if (sdl->sdl_nlen >= IFNAMSIZ) 130 memcpy(name, sdl->sdl_data, IFNAMSIZ - 1); 131 else if (sdl->sdl_nlen > 0) 132 memcpy(name, sdl->sdl_data, sdl->sdl_nlen); 133 134 if (interface != 0 && strcmp(name, interface) != 0) 135 continue; 136 137 /* mark inactive interfaces with a '*' */ 138 cp = strchr(name, '\0'); 139 if ((ifm.ifm_flags & IFF_UP) == 0) 140 *cp++ = '*'; 141 *cp = '\0'; 142 143 if (qflag) { 144 total = ifd->ifi_ibytes + ifd->ifi_obytes + 145 ifd->ifi_ipackets + ifd->ifi_ierrors + 146 ifd->ifi_opackets + ifd->ifi_oerrors + 147 ifd->ifi_collisions; 148 if (tflag) 149 total += 0; // XXX ifnet.if_timer; 150 if (dflag) 151 total += 0; // XXX ifnet.if_snd.ifq_drops; 152 if (total == 0) 153 continue; 154 } 155 156 printf("%-7s %-5d ", name, ifd->ifi_mtu); 157 print_addr(rti_info[RTAX_IFP], rti_info, ifd); 158 break; 159 case RTM_NEWADDR: 160 if (qflag && total == 0) 161 continue; 162 if (interface != 0 && strcmp(name, interface) != 0) 163 continue; 164 165 ifam = (struct ifa_msghdr *)next; 166 if ((ifam->ifam_addrs & (RTA_NETMASK | RTA_IFA | 167 RTA_BRD)) == 0) 168 break; 169 170 sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); 171 get_rtaddrs(ifam->ifam_addrs, sa, rti_info); 172 173 printf("%-7s %-5d ", name, ifd->ifi_mtu); 174 print_addr(rti_info[RTAX_IFA], rti_info, ifd); 175 break; 176 } 177 } 178 free(buf); 179 } 180 181 static void 182 print_addr(struct sockaddr *sa, struct sockaddr **rtinfo, struct if_data *ifd) 183 { 184 struct sockaddr_dl *sdl; 185 struct sockaddr_in *sin; 186 struct sockaddr_in6 *sin6; 187 char *cp; 188 int m, n; 189 190 switch (sa->sa_family) { 191 case AF_UNSPEC: 192 printf("%-11.11s ", "none"); 193 printf("%-17.17s ", "none"); 194 break; 195 case AF_INET: 196 sin = (struct sockaddr_in *)sa; 197 cp = netname4(sin->sin_addr.s_addr, 198 ((struct sockaddr_in *)rtinfo[RTAX_NETMASK])->sin_addr.s_addr); 199 if (vflag) 200 n = strlen(cp) < 11 ? 11 : strlen(cp); 201 else 202 n = 11; 203 printf("%-*.*s ", n, n, cp); 204 cp = routename4(sin->sin_addr.s_addr); 205 if (vflag) 206 n = strlen(cp) < 17 ? 17 : strlen(cp); 207 else 208 n = 17; 209 printf("%-*.*s ", n, n, cp); 210 211 #if 0 212 if (aflag) { 213 u_long multiaddr; 214 struct in_multi inm; 215 216 multiaddr = (u_long)LIST_FIRST(&ifaddr.in.ia_multiaddrs); 217 while (multiaddr != 0) { 218 kread(multiaddr, &inm, sizeof inm); 219 printf("\n%25s %-17.17s ", "", 220 routename4(inm.inm_addr.s_addr)); 221 multiaddr = (u_long)LIST_NEXT(&inm, inm_list); 222 } 223 } 224 #endif 225 break; 226 case AF_INET6: 227 sin6 = (struct sockaddr_in6 *)sa; 228 #ifdef __KAME__ 229 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { 230 sin6->sin6_scope_id = 231 ntohs(*(u_int16_t *) 232 &sin6->sin6_addr.s6_addr[2]); 233 sin6->sin6_addr.s6_addr[2] = 0; 234 sin6->sin6_addr.s6_addr[3] = 0; 235 } 236 #endif 237 cp = netname6(sin6, 238 (struct sockaddr_in6 *)rtinfo[RTAX_NETMASK]); 239 if (vflag) 240 n = strlen(cp) < 11 ? 11 : strlen(cp); 241 else 242 n = 11; 243 printf("%-*.*s ", n, n, cp); 244 cp = routename6(sin6); 245 if (vflag) 246 n = strlen(cp) < 17 ? 17 : strlen(cp); 247 else 248 n = 17; 249 printf("%-*.*s ", n, n, cp); 250 #if 0 251 if (aflag) { 252 u_long multiaddr; 253 struct in6_multi inm; 254 struct sockaddr_in6 m6; 255 256 multiaddr = (u_long)LIST_FIRST(&ifaddr.in6.ia6_multiaddrs); 257 while (multiaddr != 0) { 258 kread(multiaddr, &inm, sizeof inm); 259 memset(&m6, 0, sizeof(m6)); 260 m6.sin6_len = sizeof(struct sockaddr_in6); 261 m6.sin6_family = AF_INET6; 262 m6.sin6_addr = inm.in6m_addr; 263 #ifdef __KAME__ 264 if (IN6_IS_ADDR_MC_LINKLOCAL(&m6.sin6_addr) || 265 IN6_IS_ADDR_MC_INTFACELOCAL(&m6.sin6_addr)) { 266 m6.sin6_scope_id = 267 ntohs(*(u_int16_t *) 268 &m6.sin6_addr.s6_addr[2]); 269 m6.sin6_addr.s6_addr[2] = 0; 270 m6.sin6_addr.s6_addr[3] = 0; 271 } 272 #endif 273 cp = routename6(&m6); 274 if (vflag) 275 n = strlen(cp) < 17 ? 17 : strlen(cp); 276 else 277 n = 17; 278 printf("\n%25s %-*.*s ", "", 279 n, n, cp); 280 multiaddr = (u_long)LIST_NEXT(&inm, in6m_entry); 281 } 282 } 283 #endif 284 break; 285 case AF_LINK: 286 sdl = (struct sockaddr_dl *)sa; 287 m = printf("%-11.11s ", "<Link>"); 288 if (sdl->sdl_type == IFT_ETHER || 289 sdl->sdl_type == IFT_CARP || 290 sdl->sdl_type == IFT_FDDI || 291 sdl->sdl_type == IFT_ISO88025) 292 printf("%-17.17s ", 293 ether_ntoa((struct ether_addr *)LLADDR(sdl))); 294 else { 295 cp = (char *)LLADDR(sdl); 296 n = sdl->sdl_alen; 297 goto hexprint; 298 } 299 break; 300 default: 301 m = printf("(%d)", sa->sa_family); 302 for (cp = sa->sa_len + (char *)sa; 303 --cp > sa->sa_data && (*cp == 0);) {} 304 n = cp - sa->sa_data + 1; 305 cp = sa->sa_data; 306 hexprint: 307 while (--n >= 0) 308 m += printf("%x%c", *cp++ & 0xff, 309 n > 0 ? '.' : ' '); 310 m = 30 - m; 311 while (m-- > 0) 312 putchar(' '); 313 break; 314 } 315 if (bflag) { 316 if (hflag) { 317 char ibytes[FMT_SCALED_STRSIZE]; 318 char obytes[FMT_SCALED_STRSIZE]; 319 fmt_scaled(ifd->ifi_ibytes, ibytes); 320 fmt_scaled(ifd->ifi_obytes, obytes); 321 printf("%10s %10s", ibytes, obytes); 322 } else 323 printf("%10llu %10llu", 324 ifd->ifi_ibytes, ifd->ifi_obytes); 325 } else 326 printf("%8llu %5llu %8llu %5llu %5llu", 327 ifd->ifi_ipackets, ifd->ifi_ierrors, 328 ifd->ifi_opackets, ifd->ifi_oerrors, 329 ifd->ifi_collisions); 330 if (tflag) 331 printf(" %4d", 0 /* XXX ifnet.if_timer */); 332 if (dflag) 333 printf(" %4d", 0 /* XXX ifnet.if_snd.ifq_drops */); 334 putchar('\n'); 335 } 336 337 struct iftot { 338 char ift_name[IFNAMSIZ]; /* interface name */ 339 u_int64_t ift_ip; /* input packets */ 340 u_int64_t ift_ib; /* input bytes */ 341 u_int64_t ift_ie; /* input errors */ 342 u_int64_t ift_op; /* output packets */ 343 u_int64_t ift_ob; /* output bytes */ 344 u_int64_t ift_oe; /* output errors */ 345 u_int64_t ift_co; /* collisions */ 346 u_int64_t ift_dr; /* drops */ 347 } ip_cur, ip_old, sum_cur, sum_old; 348 349 volatile sig_atomic_t signalled; /* set if alarm goes off "early" */ 350 351 /* 352 * Print a running summary of interface statistics. 353 * Repeat display every interval seconds, showing statistics 354 * collected over that interval. Assumes that interval is non-zero. 355 * First line printed at top of screen is always cumulative. 356 */ 357 static void 358 sidewaysintpr(unsigned int interval, int repeatcount) 359 { 360 sigset_t emptyset; 361 int line; 362 char ibytes[FMT_SCALED_STRSIZE]; 363 char obytes[FMT_SCALED_STRSIZE]; 364 365 fetchifs(); 366 if (ip_cur.ift_name[0] == '\0') { 367 fprintf(stderr, "%s: %s: unknown interface\n", 368 __progname, interface); 369 exit(1); 370 } 371 372 (void)signal(SIGALRM, catchalarm); 373 signalled = 0; 374 (void)alarm(interval); 375 banner: 376 if (bflag) 377 printf("%7.7s in %8.8s %6.6s out %5.5s", 378 ip_cur.ift_name, " ", 379 ip_cur.ift_name, " "); 380 else 381 printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s", 382 ip_cur.ift_name, " ", 383 ip_cur.ift_name, " ", " "); 384 if (dflag) 385 printf(" %5.5s", " "); 386 387 if (bflag) 388 printf(" %7.7s in %8.8s %6.6s out %5.5s", 389 "total", " ", "total", " "); 390 else 391 printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s", 392 "total", " ", "total", " ", " "); 393 if (dflag) 394 printf(" %5.5s", " "); 395 putchar('\n'); 396 if (bflag) 397 printf("%10.10s %8.8s %10.10s %5.5s", 398 "bytes", " ", "bytes", " "); 399 else 400 printf("%8.8s %5.5s %8.8s %5.5s %5.5s", 401 "packets", "errs", "packets", "errs", "colls"); 402 if (dflag) 403 printf(" %5.5s", "drops"); 404 405 if (bflag) 406 printf("%10.10s %8.8s %10.10s %5.5s", 407 "bytes", " ", "bytes", " "); 408 else 409 printf(" %8.8s %5.5s %8.8s %5.5s %5.5s", 410 "packets", "errs", "packets", "errs", "colls"); 411 if (dflag) 412 printf(" %5.5s", "drops"); 413 putchar('\n'); 414 fflush(stdout); 415 line = 0; 416 bzero(&ip_old, sizeof(ip_old)); 417 bzero(&sum_old, sizeof(sum_old)); 418 loop: 419 bzero(&sum_cur, sizeof(sum_cur)); 420 421 fetchifs(); 422 423 if (bflag) { 424 if (hflag) { 425 fmt_scaled(ip_cur.ift_ib - ip_old.ift_ib, ibytes); 426 fmt_scaled(ip_cur.ift_ob - ip_old.ift_ob, obytes); 427 printf("%10s %8.8s %10s %5.5s", 428 ibytes, " ", obytes, " "); 429 } else 430 printf("%10llu %8.8s %10llu %5.5s", 431 ip_cur.ift_ib - ip_old.ift_ib, " ", 432 ip_cur.ift_ob - ip_old.ift_ob, " "); 433 } else 434 printf("%8llu %5llu %8llu %5llu %5llu", 435 ip_cur.ift_ip - ip_old.ift_ip, 436 ip_cur.ift_ie - ip_old.ift_ie, 437 ip_cur.ift_op - ip_old.ift_op, 438 ip_cur.ift_oe - ip_old.ift_oe, 439 ip_cur.ift_co - ip_old.ift_co); 440 if (dflag) 441 printf(" %5llu", 442 /* XXX ifnet.if_snd.ifq_drops - ip->ift_dr); */ 443 0LL); 444 445 ip_old = ip_cur; 446 447 if (bflag) { 448 if (hflag) { 449 fmt_scaled(sum_cur.ift_ib - sum_old.ift_ib, ibytes); 450 fmt_scaled(sum_cur.ift_ob - sum_old.ift_ob, obytes); 451 printf(" %10s %8.8s %10s %5.5s", 452 ibytes, " ", obytes, " "); 453 } else 454 printf(" %10llu %8.8s %10llu %5.5s", 455 sum_cur.ift_ib - sum_old.ift_ib, " ", 456 sum_cur.ift_ob - sum_old.ift_ob, " "); 457 } else 458 printf(" %8llu %5llu %8llu %5llu %5llu", 459 sum_cur.ift_ip - sum_old.ift_ip, 460 sum_cur.ift_ie - sum_old.ift_ie, 461 sum_cur.ift_op - sum_old.ift_op, 462 sum_cur.ift_oe - sum_old.ift_oe, 463 sum_cur.ift_co - sum_old.ift_co); 464 if (dflag) 465 printf(" %5llu", sum_cur.ift_dr - sum_old.ift_dr); 466 467 sum_old = sum_cur; 468 469 putchar('\n'); 470 fflush(stdout); 471 if (repeatcount && --repeatcount == 0) 472 return; 473 line++; 474 sigemptyset(&emptyset); 475 if (!signalled) 476 sigsuspend(&emptyset); 477 signalled = 0; 478 (void)alarm(interval); 479 if (line == 21 && isatty(STDOUT_FILENO)) 480 goto banner; 481 goto loop; 482 } 483 484 /* 485 * Called if an interval expires before sidewaysintpr has completed a loop. 486 * Sets a flag to not wait for the alarm. 487 */ 488 /* ARGSUSED */ 489 static void 490 catchalarm(int signo) 491 { 492 signalled = 1; 493 } 494 495 static void 496 get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info) 497 { 498 int i; 499 500 for (i = 0; i < RTAX_MAX; i++) { 501 if (addrs & (1 << i)) { 502 rti_info[i] = sa; 503 sa = (struct sockaddr *)((char *)(sa) + 504 roundup(sa->sa_len, sizeof(long))); 505 } else 506 rti_info[i] = NULL; 507 } 508 } 509 510 511 static int 512 isegress(char *name) 513 { 514 static int s = -1; 515 int len; 516 struct ifgroupreq ifgr; 517 struct ifg_req *ifg; 518 int rv = 0; 519 520 if (s == -1) { 521 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 522 return 0; 523 } 524 525 memset(&ifgr, 0, sizeof(ifgr)); 526 strlcpy(ifgr.ifgr_name, name, IFNAMSIZ); 527 528 if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) { 529 return 0; 530 } 531 532 len = ifgr.ifgr_len; 533 ifgr.ifgr_groups = calloc(len, 1); 534 if (ifgr.ifgr_groups == NULL) 535 err(1, "getifgroups"); 536 if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) 537 err(1, "SIOCGIFGROUP"); 538 539 ifg = ifgr.ifgr_groups; 540 for (; ifg && len >= sizeof(struct ifg_req); ifg++) { 541 len -= sizeof(struct ifg_req); 542 if (strcmp(ifg->ifgrq_group, IFG_EGRESS) == 0) 543 rv = 1; 544 } 545 546 free(ifgr.ifgr_groups); 547 return rv; 548 } 549 550 static void 551 fetchifs(void) 552 { 553 struct if_msghdr ifm; 554 int mib[6] = { CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0 }; 555 struct rt_msghdr *rtm; 556 struct if_data *ifd; 557 struct sockaddr *sa, *rti_info[RTAX_MAX]; 558 struct sockaddr_dl *sdl; 559 char *buf, *next, *lim; 560 char name[IFNAMSIZ]; 561 size_t len; 562 int takeit = 0; 563 int foundone = 0; 564 565 if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1) 566 err(1, "sysctl"); 567 if ((buf = malloc(len)) == NULL) 568 err(1, NULL); 569 if (sysctl(mib, 6, buf, &len, NULL, 0) == -1) 570 err(1, "sysctl"); 571 572 memset(&ip_cur, 0, sizeof(ip_cur)); 573 lim = buf + len; 574 for (next = buf; next < lim; next += rtm->rtm_msglen) { 575 rtm = (struct rt_msghdr *)next; 576 if (rtm->rtm_version != RTM_VERSION) 577 continue; 578 switch (rtm->rtm_type) { 579 case RTM_IFINFO: 580 bcopy(next, &ifm, sizeof ifm); 581 ifd = &ifm.ifm_data; 582 583 sa = (struct sockaddr *)(next + rtm->rtm_hdrlen); 584 get_rtaddrs(ifm.ifm_addrs, sa, rti_info); 585 586 sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP]; 587 if (sdl == NULL || sdl->sdl_family != AF_LINK) 588 continue; 589 bzero(name, sizeof(name)); 590 if (sdl->sdl_nlen >= IFNAMSIZ) 591 memcpy(name, sdl->sdl_data, IFNAMSIZ - 1); 592 else if (sdl->sdl_nlen > 0) 593 memcpy(name, sdl->sdl_data, sdl->sdl_nlen); 594 595 if (interface != NULL && !strcmp(name, interface)) { 596 takeit = 1; 597 } else if (interface == NULL && foundone == 0 && 598 isegress(name)) { 599 takeit = 1; 600 foundone = 1; 601 } else 602 takeit = 0; 603 if (takeit) { 604 strlcpy(ip_cur.ift_name, name, 605 sizeof(ip_cur.ift_name)); 606 ip_cur.ift_ip = ifd->ifi_ipackets; 607 ip_cur.ift_ib = ifd->ifi_ibytes; 608 ip_cur.ift_ie = ifd->ifi_ierrors; 609 ip_cur.ift_op = ifd->ifi_opackets; 610 ip_cur.ift_ob = ifd->ifi_obytes; 611 ip_cur.ift_oe = ifd->ifi_oerrors; 612 ip_cur.ift_co = ifd->ifi_collisions; 613 ip_cur.ift_dr = 0; 614 /* XXX ifnet.if_snd.ifq_drops */ 615 } 616 617 sum_cur.ift_ip += ifd->ifi_ipackets; 618 sum_cur.ift_ib += ifd->ifi_ibytes; 619 sum_cur.ift_ie += ifd->ifi_ierrors; 620 sum_cur.ift_op += ifd->ifi_opackets; 621 sum_cur.ift_ob += ifd->ifi_obytes; 622 sum_cur.ift_oe += ifd->ifi_oerrors; 623 sum_cur.ift_co += ifd->ifi_collisions; 624 sum_cur.ift_dr += 0; /* XXX ifnet.if_snd.ifq_drops */ 625 break; 626 } 627 } 628 if (interface == NULL && foundone == 0) { 629 strlcpy(ip_cur.ift_name, name, 630 sizeof(ip_cur.ift_name)); 631 ip_cur.ift_ip = ifd->ifi_ipackets; 632 ip_cur.ift_ib = ifd->ifi_ibytes; 633 ip_cur.ift_ie = ifd->ifi_ierrors; 634 ip_cur.ift_op = ifd->ifi_opackets; 635 ip_cur.ift_ob = ifd->ifi_obytes; 636 ip_cur.ift_oe = ifd->ifi_oerrors; 637 ip_cur.ift_co = ifd->ifi_collisions; 638 ip_cur.ift_dr = 0; 639 /* XXX ifnet.if_snd.ifq_drops */ 640 } 641 free(buf); 642 } 643