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