Annotation of src/usr.bin/netstat/if.c, Revision 1.64
1.64 ! henning 1: /* $OpenBSD: if.c,v 1.63 2011/01/09 19:12:19 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_LINK:
285: sdl = (struct sockaddr_dl *)sa;
286: m = printf("%-11.11s ", "<Link>");
287: if (sdl->sdl_type == IFT_ETHER ||
288: sdl->sdl_type == IFT_CARP ||
289: sdl->sdl_type == IFT_FDDI ||
290: sdl->sdl_type == IFT_ISO88025)
291: printf("%-17.17s ",
292: ether_ntoa((struct ether_addr *)LLADDR(sdl)));
293: else {
294: cp = (char *)LLADDR(sdl);
295: n = sdl->sdl_alen;
296: goto hexprint;
1.1 deraadt 297: }
1.56 claudio 298: break;
299: default:
300: m = printf("(%d)", sa->sa_family);
301: for (cp = sa->sa_len + (char *)sa;
302: --cp > sa->sa_data && (*cp == 0);) {}
303: n = cp - sa->sa_data + 1;
304: cp = sa->sa_data;
305: hexprint:
306: while (--n >= 0)
307: m += printf("%x%c", *cp++ & 0xff,
308: n > 0 ? '.' : ' ');
309: m = 30 - m;
310: while (m-- > 0)
311: putchar(' ');
312: break;
1.1 deraadt 313: }
1.56 claudio 314: if (bflag)
315: printf("%10llu %10llu",
316: ifd->ifi_ibytes, ifd->ifi_obytes);
317: else
318: printf("%8llu %5llu %8llu %5llu %5llu",
319: ifd->ifi_ipackets, ifd->ifi_ierrors,
320: ifd->ifi_opackets, ifd->ifi_oerrors,
321: ifd->ifi_collisions);
322: if (tflag)
323: printf(" %4d", 0 /* XXX ifnet.if_timer */);
324: if (dflag)
325: printf(" %4d", 0 /* XXX ifnet.if_snd.ifq_drops */);
326: putchar('\n');
1.1 deraadt 327: }
328:
329: struct iftot {
1.3 deraadt 330: char ift_name[IFNAMSIZ]; /* interface name */
1.53 mk 331: u_int64_t ift_ip; /* input packets */
332: u_int64_t ift_ib; /* input bytes */
333: u_int64_t ift_ie; /* input errors */
334: u_int64_t ift_op; /* output packets */
335: u_int64_t ift_ob; /* output bytes */
336: u_int64_t ift_oe; /* output errors */
337: u_int64_t ift_co; /* collisions */
338: u_int64_t ift_dr; /* drops */
1.56 claudio 339: } ip_cur, ip_old, sum_cur, sum_old;
1.1 deraadt 340:
1.26 millert 341: volatile sig_atomic_t signalled; /* set if alarm goes off "early" */
1.1 deraadt 342:
343: /*
344: * Print a running summary of interface statistics.
345: * Repeat display every interval seconds, showing statistics
346: * collected over that interval. Assumes that interval is non-zero.
347: * First line printed at top of screen is always cumulative.
348: */
349: static void
1.62 tedu 350: sidewaysintpr(unsigned int interval, int repeatcount)
1.1 deraadt 351: {
1.56 claudio 352: sigset_t emptyset;
1.27 mpech 353: int line;
1.3 deraadt 354:
1.56 claudio 355: fetchifs();
356: if (ip_cur.ift_name[0] == '\0') {
1.4 deraadt 357: fprintf(stderr, "%s: %s: unknown interface\n",
358: __progname, interface);
359: exit(1);
1.1 deraadt 360: }
361:
362: (void)signal(SIGALRM, catchalarm);
1.56 claudio 363: signalled = 0;
1.1 deraadt 364: (void)alarm(interval);
365: banner:
1.22 camield 366: if (bflag)
367: printf("%7.7s in %8.8s %6.6s out %5.5s",
1.56 claudio 368: ip_cur.ift_name, " ",
369: ip_cur.ift_name, " ");
1.22 camield 370: else
371: printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s",
1.56 claudio 372: ip_cur.ift_name, " ",
373: ip_cur.ift_name, " ", " ");
374: if (dflag)
375: printf(" %5.5s", " ");
376:
377: if (bflag)
378: printf(" %7.7s in %8.8s %6.6s out %5.5s",
379: "total", " ", "total", " ");
380: else
381: printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s",
382: "total", " ", "total", " ", " ");
1.22 camield 383: if (dflag)
384: printf(" %5.5s", " ");
1.1 deraadt 385: putchar('\n');
1.22 camield 386: if (bflag)
387: printf("%10.10s %8.8s %10.10s %5.5s",
388: "bytes", " ", "bytes", " ");
389: else
390: printf("%8.8s %5.5s %8.8s %5.5s %5.5s",
391: "packets", "errs", "packets", "errs", "colls");
1.1 deraadt 392: if (dflag)
393: printf(" %5.5s", "drops");
1.56 claudio 394:
395: if (bflag)
396: printf(" %10.10s %8.8s %10.10s %5.5s",
397: "bytes", " ", "bytes", " ");
398: else
399: printf(" %8.8s %5.5s %8.8s %5.5s %5.5s",
400: "packets", "errs", "packets", "errs", "colls");
401: if (dflag)
402: printf(" %5.5s", "drops");
1.1 deraadt 403: putchar('\n');
404: fflush(stdout);
405: line = 0;
1.56 claudio 406: bzero(&ip_old, sizeof(ip_old));
407: bzero(&sum_old, sizeof(sum_old));
1.1 deraadt 408: loop:
1.56 claudio 409: bzero(&sum_cur, sizeof(sum_cur));
410:
411: fetchifs();
412:
413: if (bflag)
414: printf("%10llu %8.8s %10llu %5.5s",
415: ip_cur.ift_ib - ip_old.ift_ib, " ",
416: ip_cur.ift_ob - ip_old.ift_ob, " ");
417: else
418: printf("%8llu %5llu %8llu %5llu %5llu",
419: ip_cur.ift_ip - ip_old.ift_ip,
420: ip_cur.ift_ie - ip_old.ift_ie,
421: ip_cur.ift_op - ip_old.ift_op,
422: ip_cur.ift_oe - ip_old.ift_oe,
423: ip_cur.ift_co - ip_old.ift_co);
424: if (dflag)
425: printf(" %5llu",
426: /* XXX ifnet.if_snd.ifq_drops - ip->ift_dr); */
1.61 tedu 427: 0LL);
1.56 claudio 428:
429: ip_old = ip_cur;
430:
431: if (bflag)
432: printf(" %10llu %8.8s %10llu %5.5s",
433: sum_cur.ift_ib - sum_old.ift_ib, " ",
434: sum_cur.ift_ob - sum_old.ift_ob, " ");
435: else
436: printf(" %8llu %5llu %8llu %5llu %5llu",
437: sum_cur.ift_ip - sum_old.ift_ip,
438: sum_cur.ift_ie - sum_old.ift_ie,
439: sum_cur.ift_op - sum_old.ift_op,
440: sum_cur.ift_oe - sum_old.ift_oe,
441: sum_cur.ift_co - sum_old.ift_co);
442: if (dflag)
443: printf(" %5llu", sum_cur.ift_dr - sum_old.ift_dr);
444:
445: sum_old = sum_cur;
446:
1.1 deraadt 447: putchar('\n');
448: fflush(stdout);
1.62 tedu 449: if (repeatcount && --repeatcount == 0)
450: return;
1.1 deraadt 451: line++;
1.26 millert 452: sigemptyset(&emptyset);
453: if (!signalled)
454: sigsuspend(&emptyset);
1.56 claudio 455: signalled = 0;
1.1 deraadt 456: (void)alarm(interval);
1.62 tedu 457: if (line == 21 && isatty(STDOUT_FILENO))
1.1 deraadt 458: goto banner;
459: goto loop;
460: }
461:
462: /*
463: * Called if an interval expires before sidewaysintpr has completed a loop.
464: * Sets a flag to not wait for the alarm.
465: */
1.46 deraadt 466: /* ARGSUSED */
1.1 deraadt 467: static void
1.33 deraadt 468: catchalarm(int signo)
1.1 deraadt 469: {
1.56 claudio 470: signalled = 1;
471: }
472:
473: static void
474: get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
475: {
476: int i;
477:
478: for (i = 0; i < RTAX_MAX; i++) {
479: if (addrs & (1 << i)) {
480: rti_info[i] = sa;
481: sa = (struct sockaddr *)((char *)(sa) +
482: roundup(sa->sa_len, sizeof(long)));
483: } else
484: rti_info[i] = NULL;
485: }
486: }
487:
1.63 tedu 488:
489: static int
490: isegress(char *name)
491: {
492: static int s = -1;
493: int len;
494: struct ifgroupreq ifgr;
495: struct ifg_req *ifg;
496: int rv = 0;
497:
498: if (s == -1) {
499: if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
500: return 0;
501: }
502:
503: memset(&ifgr, 0, sizeof(ifgr));
504: strlcpy(ifgr.ifgr_name, name, IFNAMSIZ);
505:
506: if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1) {
507: return 0;
508: }
509:
510: len = ifgr.ifgr_len;
511: ifgr.ifgr_groups = calloc(len, 1);
512: if (ifgr.ifgr_groups == NULL)
513: err(1, "getifgroups");
514: if (ioctl(s, SIOCGIFGROUP, (caddr_t)&ifgr) == -1)
515: err(1, "SIOCGIFGROUP");
516:
517: ifg = ifgr.ifgr_groups;
518: for (; ifg && len >= sizeof(struct ifg_req); ifg++) {
519: len -= sizeof(struct ifg_req);
520: if (strcmp(ifg->ifgrq_group, IFG_EGRESS) == 0)
521: rv = 1;
522: }
523:
524: free(ifgr.ifgr_groups);
525: return rv;
526: }
527:
1.56 claudio 528: static void
529: fetchifs(void)
530: {
531: struct if_msghdr ifm;
532: int mib[6] = { CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
533: struct rt_msghdr *rtm;
534: struct if_data *ifd;
535: struct sockaddr *sa, *rti_info[RTAX_MAX];
536: struct sockaddr_dl *sdl;
537: char *buf, *next, *lim;
538: char name[IFNAMSIZ];
539: size_t len;
1.63 tedu 540: int takeit = 0;
541: int foundone = 0;
1.56 claudio 542:
543: if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
544: err(1, "sysctl");
545: if ((buf = malloc(len)) == NULL)
546: err(1, NULL);
547: if (sysctl(mib, 6, buf, &len, NULL, 0) == -1)
548: err(1, "sysctl");
549:
1.63 tedu 550: memset(&ip_cur, 0, sizeof(ip_cur));
1.56 claudio 551: lim = buf + len;
552: for (next = buf; next < lim; next += rtm->rtm_msglen) {
553: rtm = (struct rt_msghdr *)next;
554: if (rtm->rtm_version != RTM_VERSION)
555: continue;
556: switch (rtm->rtm_type) {
557: case RTM_IFINFO:
558: bcopy(next, &ifm, sizeof ifm);
559: ifd = &ifm.ifm_data;
560:
561: sa = (struct sockaddr *)(next + rtm->rtm_hdrlen);
562: get_rtaddrs(ifm.ifm_addrs, sa, rti_info);
563:
564: sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP];
565: if (sdl == NULL || sdl->sdl_family != AF_LINK)
566: continue;
567: bzero(name, sizeof(name));
568: if (sdl->sdl_nlen >= IFNAMSIZ)
569: memcpy(name, sdl->sdl_data, IFNAMSIZ - 1);
570: else if (sdl->sdl_nlen > 0)
571: memcpy(name, sdl->sdl_data, sdl->sdl_nlen);
572:
1.59 claudio 573: if (interface != NULL && !strcmp(name, interface)) {
1.63 tedu 574: takeit = 1;
575: } else if (interface == NULL && foundone == 0 &&
576: isegress(name)) {
577: takeit = 1;
578: foundone = 1;
579: } else
580: takeit = 0;
581: if (takeit) {
1.56 claudio 582: strlcpy(ip_cur.ift_name, name,
583: sizeof(ip_cur.ift_name));
584: ip_cur.ift_ip = ifd->ifi_ipackets;
585: ip_cur.ift_ib = ifd->ifi_ibytes;
586: ip_cur.ift_ie = ifd->ifi_ierrors;
587: ip_cur.ift_op = ifd->ifi_opackets;
588: ip_cur.ift_ob = ifd->ifi_obytes;
589: ip_cur.ift_oe = ifd->ifi_oerrors;
590: ip_cur.ift_co = ifd->ifi_collisions;
591: ip_cur.ift_dr = 0;
592: /* XXX ifnet.if_snd.ifq_drops */
593: }
594:
595: sum_cur.ift_ip += ifd->ifi_ipackets;
596: sum_cur.ift_ib += ifd->ifi_ibytes;
597: sum_cur.ift_ie += ifd->ifi_ierrors;
598: sum_cur.ift_op += ifd->ifi_opackets;
599: sum_cur.ift_ob += ifd->ifi_obytes;
600: sum_cur.ift_oe += ifd->ifi_oerrors;
601: sum_cur.ift_co += ifd->ifi_collisions;
602: sum_cur.ift_dr += 0; /* XXX ifnet.if_snd.ifq_drops */
603: break;
604: }
605: }
1.63 tedu 606: if (interface == NULL && foundone == 0) {
1.56 claudio 607: strlcpy(ip_cur.ift_name, name,
608: sizeof(ip_cur.ift_name));
609: ip_cur.ift_ip = ifd->ifi_ipackets;
610: ip_cur.ift_ib = ifd->ifi_ibytes;
611: ip_cur.ift_ie = ifd->ifi_ierrors;
612: ip_cur.ift_op = ifd->ifi_opackets;
613: ip_cur.ift_ob = ifd->ifi_obytes;
614: ip_cur.ift_oe = ifd->ifi_oerrors;
615: ip_cur.ift_co = ifd->ifi_collisions;
616: ip_cur.ift_dr = 0;
617: /* XXX ifnet.if_snd.ifq_drops */
618: }
1.58 dhill 619: free(buf);
1.47 claudio 620: }