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