Annotation of src/usr.bin/netstat/if.c, Revision 1.94.4.2
1.94.4.2! martin 1: /* $NetBSD: if.c,v 1.94.4.1 2018/07/26 23:43:31 snj Exp $ */
1.13 thorpej 2:
1.1 cgd 3: /*
1.8 mycroft 4: * Copyright (c) 1983, 1988, 1993
5: * The Regents of the University of California. All rights reserved.
1.1 cgd 6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
1.55 agc 15: * 3. Neither the name of the University nor the names of its contributors
1.1 cgd 16: * may be used to endorse or promote products derived from this software
17: * without specific prior written permission.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29: * SUCH DAMAGE.
30: */
31:
1.25 lukem 32: #include <sys/cdefs.h>
1.1 cgd 33: #ifndef lint
1.13 thorpej 34: #if 0
35: static char sccsid[] = "from: @(#)if.c 8.2 (Berkeley) 2/21/94";
36: #else
1.94.4.2! martin 37: __RCSID("$NetBSD: if.c,v 1.94.4.1 2018/07/26 23:43:31 snj Exp $");
1.13 thorpej 38: #endif
1.1 cgd 39: #endif /* not lint */
40:
1.64 elad 41: #include <sys/param.h>
1.1 cgd 42: #include <sys/types.h>
1.8 mycroft 43: #include <sys/protosw.h>
1.1 cgd 44: #include <sys/socket.h>
1.57 ragge 45: #include <sys/time.h>
1.64 elad 46: #include <sys/sysctl.h>
1.82 mrg 47: #include <sys/ioctl.h>
1.1 cgd 48:
49: #include <net/if.h>
50: #include <net/if_dl.h>
1.20 thorpej 51: #include <net/if_types.h>
1.64 elad 52: #include <net/route.h>
1.1 cgd 53: #include <netinet/in.h>
54: #include <netinet/in_var.h>
1.8 mycroft 55: #include <arpa/inet.h>
1.1 cgd 56:
1.59 rpaulo 57: #include <kvm.h>
1.8 mycroft 58: #include <signal.h>
1.1 cgd 59: #include <stdio.h>
1.42 matt 60: #include <stdlib.h>
1.8 mycroft 61: #include <string.h>
62: #include <unistd.h>
1.34 itojun 63: #include <netdb.h>
1.64 elad 64: #include <err.h>
1.8 mycroft 65:
66: #include "netstat.h"
1.80 christos 67: #include "rtutil.h"
1.70 pooka 68: #include "prog_ops.h"
1.1 cgd 69:
1.64 elad 70: #define MAXIF 100
71:
1.68 pooka 72: #define HUMBUF_SIZE 7
73:
1.64 elad 74: struct iftot {
75: char ift_name[IFNAMSIZ]; /* interface name */
76: u_quad_t ift_ip; /* input packets */
77: u_quad_t ift_ib; /* input bytes */
78: u_quad_t ift_ie; /* input errors */
1.94.4.2! martin 79: u_quad_t ift_iq; /* input drops */
1.64 elad 80: u_quad_t ift_op; /* output packets */
81: u_quad_t ift_ob; /* output bytes */
82: u_quad_t ift_oe; /* output errors */
1.94.4.2! martin 83: u_quad_t ift_oq; /* output drops */
1.64 elad 84: u_quad_t ift_co; /* collisions */
1.94.4.2! martin 85: };
! 86:
! 87: struct if_data_ext {
! 88: uint64_t ifi_oqdrops;
1.64 elad 89: };
90:
1.82 mrg 91: static void set_lines(void);
1.91 ozaki-r 92: static void print_addr(const int, struct sockaddr *, struct sockaddr **,
1.94.4.2! martin 93: struct if_data *, struct ifnet *, struct if_data_ext *);
1.64 elad 94: static void sidewaysintpr(u_int, u_long);
95:
96: static void iftot_banner(struct iftot *);
97: static void iftot_print_sum(struct iftot *, struct iftot *);
98: static void iftot_print(struct iftot *, struct iftot *);
1.1 cgd 99:
1.87 christos 100: static void catchalarm(int);
1.64 elad 101: static void get_rtaddrs(int, struct sockaddr *, struct sockaddr **);
102: static void fetchifs(void);
103:
1.94.4.2! martin 104: static int if_data_ext_get(const char *, struct if_data_ext *);
1.64 elad 105: static void intpr_sysctl(void);
106: static void intpr_kvm(u_long, void (*)(const char *));
107:
108: struct iftot iftot[MAXIF], ip_cur, ip_old, sum_cur, sum_old;
1.90 dholland 109: static sig_atomic_t signalled; /* set when alarm goes off */
1.32 itojun 110:
1.82 mrg 111: static unsigned redraw_lines = 21;
112:
113: static void
114: set_lines(void)
115: {
116: static bool first = true;
117: struct ttysize ts;
118:
119: if (!first)
120: return;
121: first = false;
122: if (ioctl(STDOUT_FILENO, TIOCGSIZE, &ts) != -1 && ts.ts_lines)
123: redraw_lines = ts.ts_lines - 3;
124: }
125:
126:
1.1 cgd 127: /*
128: * Print a description of the network interfaces.
1.15 thorpej 129: * NOTE: ifnetaddr is the location of the kernel global "ifnet",
130: * which is a TAILQ_HEAD.
1.1 cgd 131: */
1.8 mycroft 132: void
1.74 matt 133: intpr(int interval, u_long ifnetaddr, void (*pfunc)(const char *))
1.1 cgd 134: {
1.64 elad 135:
136: if (interval) {
137: sidewaysintpr((unsigned)interval, ifnetaddr);
138: return;
139: }
140:
1.94.4.2! martin 141: if (use_sysctl)
1.64 elad 142: intpr_sysctl();
1.94.4.2! martin 143: else
1.64 elad 144: intpr_kvm(ifnetaddr, pfunc);
145: }
146:
147: static void
148: intpr_header(void)
149: {
150:
1.83 christos 151: if (!sflag && !pflag) {
1.64 elad 152: if (bflag) {
153: printf("%-5.5s %-5.5s %-13.13s %-17.17s "
1.94.4.2! martin 154: "%10.10s %10.10s",
! 155: "Name", "Mtu", "Network", "Address",
! 156: "Ibytes", "Obytes");
1.64 elad 157: } else {
158: printf("%-5.5s %-5.5s %-13.13s %-17.17s "
1.94.4.1 snj 159: "%8.8s %5.5s",
160: "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs");
161: if (dflag)
162: printf(" %6.6s", "Idrops");
163: printf(" %8.8s %5.5s %5.5s",
164: "Opkts", "Oerrs", "Colls");
1.64 elad 165: }
1.94.4.1 snj 166: if (dflag)
167: printf(" %6.6s", "Odrops");
1.64 elad 168: if (tflag)
169: printf(" %4.4s", "Time");
170: putchar('\n');
171: }
172: }
173:
1.94.4.2! martin 174: int
! 175: if_data_ext_get(const char *ifname, struct if_data_ext *dext)
! 176: {
! 177: char namebuf[1024];
! 178: size_t len;
! 179: int drops;
! 180:
! 181: /* For sysctl */
! 182: snprintf(namebuf, sizeof(namebuf),
! 183: "net.interfaces.%s.sndq.drops", ifname);
! 184: len = sizeof(drops);
! 185: if (sysctlbyname(namebuf, &drops, &len, NULL, 0)
! 186: == -1) {
! 187: warnx("'%s' not found", namebuf);
! 188: dext->ifi_oqdrops = 0;
! 189: return -1;
! 190: } else
! 191: dext->ifi_oqdrops = drops;
! 192:
! 193: return 0;
! 194: }
! 195:
1.64 elad 196: static void
197: intpr_sysctl(void)
198: {
199: struct if_msghdr *ifm;
200: int mib[6] = { CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
1.93 mrg 201: static char *buf = NULL;
202: static size_t olen;
203: char *next, *lim, *cp;
1.64 elad 204: struct rt_msghdr *rtm;
205: struct ifa_msghdr *ifam;
206: struct if_data *ifd = NULL;
207: struct sockaddr *sa, *rti_info[RTAX_MAX];
208: struct sockaddr_dl *sdl;
209: uint64_t total = 0;
210: size_t len;
1.84 christos 211: int did = 1, rtax = 0, n;
1.64 elad 212: char name[IFNAMSIZ + 1]; /* + 1 for `*' */
1.94.4.2! martin 213: char origname[IFNAMSIZ]; /* without `*' */
1.91 ozaki-r 214: int ifindex = 0;
1.64 elad 215:
1.70 pooka 216: if (prog_sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
1.64 elad 217: err(1, "sysctl");
1.93 mrg 218: if (len > olen) {
219: free(buf);
220: if ((buf = malloc(len)) == NULL)
221: err(1, NULL);
222: olen = len;
223: }
1.70 pooka 224: if (prog_sysctl(mib, 6, buf, &len, NULL, 0) == -1)
1.64 elad 225: err(1, "sysctl");
226:
227: intpr_header();
228:
229: lim = buf + len;
230: for (next = buf; next < lim; next += rtm->rtm_msglen) {
1.94.4.2! martin 231: struct if_data_ext dext;
! 232:
1.64 elad 233: rtm = (struct rt_msghdr *)next;
234: if (rtm->rtm_version != RTM_VERSION)
235: continue;
236: switch (rtm->rtm_type) {
237: case RTM_IFINFO:
238: total = 0;
239: ifm = (struct if_msghdr *)next;
240: ifd = &ifm->ifm_data;
241:
242: sa = (struct sockaddr *)(ifm + 1);
243: get_rtaddrs(ifm->ifm_addrs, sa, rti_info);
244:
245: sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP];
1.94.4.2! martin 246: if (sdl == NULL || sdl->sdl_family != AF_LINK)
1.64 elad 247: continue;
1.94.4.2! martin 248:
1.64 elad 249: bzero(name, sizeof(name));
250: if (sdl->sdl_nlen >= IFNAMSIZ)
251: memcpy(name, sdl->sdl_data, IFNAMSIZ - 1);
1.94.4.2! martin 252: else if (sdl->sdl_nlen > 0)
1.64 elad 253: memcpy(name, sdl->sdl_data, sdl->sdl_nlen);
254:
1.94.4.2! martin 255: if (interface != NULL && strcmp(name, interface) != 0)
1.64 elad 256: continue;
257:
1.91 ozaki-r 258: ifindex = sdl->sdl_index;
259:
1.94.4.2! martin 260: /* Keep the original name */
! 261: strcpy(origname, name);
! 262:
! 263: /* Mark inactive interfaces with a '*' */
1.64 elad 264: cp = strchr(name, '\0');
1.94.4.2! martin 265: if ((ifm->ifm_flags & IFF_UP) == 0) {
1.64 elad 266: *cp++ = '*';
1.94.4.2! martin 267: *cp = '\0';
! 268: }
1.64 elad 269:
270: if (qflag) {
271: total = ifd->ifi_ibytes + ifd->ifi_obytes +
272: ifd->ifi_ipackets + ifd->ifi_ierrors +
273: ifd->ifi_opackets + ifd->ifi_oerrors +
274: ifd->ifi_collisions;
275: if (dflag)
1.88 christos 276: total += ifd->ifi_iqdrops;
1.64 elad 277: if (total == 0)
278: continue;
279: }
1.84 christos 280: /* Skip the first one */
281: if (did) {
282: did = 0;
283: continue;
284: }
285: rtax = RTAX_IFP;
1.64 elad 286: break;
287: case RTM_NEWADDR:
288: if (qflag && total == 0)
289: continue;
1.94.4.2! martin 290: if (interface != NULL && strcmp(name, interface) != 0)
1.64 elad 291: continue;
292: ifam = (struct ifa_msghdr *)next;
293: if ((ifam->ifam_addrs & (RTA_NETMASK | RTA_IFA |
294: RTA_BRD)) == 0)
295: break;
296:
297: sa = (struct sockaddr *)(ifam + 1);
298:
299: get_rtaddrs(ifam->ifam_addrs, sa, rti_info);
1.84 christos 300: rtax = RTAX_IFA;
301: did = 1;
1.64 elad 302: break;
1.84 christos 303: default:
304: continue;
1.64 elad 305: }
1.84 christos 306: if (vflag)
307: n = strlen(name) < 5 ? 5 : strlen(name);
308: else
309: n = 5;
310:
311: printf("%-*.*s %-5" PRIu64 " ", n, n, name, ifd->ifi_mtu);
1.94.4.2! martin 312: if (dflag)
! 313: if_data_ext_get(origname, &dext);
! 314:
! 315: print_addr(ifindex, rti_info[rtax], rti_info, ifd,
! 316: NULL, dflag ? &dext : NULL);
1.64 elad 317: }
318: }
319:
1.73 christos 320: union ifaddr_u {
321: struct ifaddr ifa;
322: struct in_ifaddr in;
323: #ifdef INET6
324: struct in6_ifaddr in6;
325: #endif /* INET6 */
326: };
327:
1.64 elad 328: static void
329: intpr_kvm(u_long ifnetaddr, void (*pfunc)(const char *))
330: {
1.1 cgd 331: struct ifnet ifnet;
1.73 christos 332: union ifaddr_u ifaddr;
1.7 cgd 333: u_long ifaddraddr;
1.15 thorpej 334: struct ifnet_head ifhead; /* TAILQ_HEAD */
1.43 enami 335: char name[IFNAMSIZ + 1]; /* + 1 for `*' */
1.1 cgd 336:
337: if (ifnetaddr == 0) {
338: printf("ifnet: symbol not defined\n");
339: return;
340: }
1.15 thorpej 341:
342: /*
343: * Find the pointer to the first ifnet structure. Replace
344: * the pointer to the TAILQ_HEAD with the actual pointer
345: * to the first list element.
346: */
347: if (kread(ifnetaddr, (char *)&ifhead, sizeof ifhead))
1.8 mycroft 348: return;
1.15 thorpej 349: ifnetaddr = (u_long)ifhead.tqh_first;
350:
1.64 elad 351: intpr_header();
352:
1.1 cgd 353: ifaddraddr = 0;
354: while (ifnetaddr || ifaddraddr) {
1.25 lukem 355: char *cp;
1.64 elad 356: int n;
1.1 cgd 357:
358: if (ifaddraddr == 0) {
1.15 thorpej 359: if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet))
1.8 mycroft 360: return;
1.25 lukem 361: memmove(name, ifnet.if_xname, IFNAMSIZ);
1.15 thorpej 362: name[IFNAMSIZ - 1] = '\0'; /* sanity */
1.10 mycroft 363: ifnetaddr = (u_long)ifnet.if_list.tqe_next;
1.94.4.2! martin 364: if (interface != NULL && strcmp(name, interface) != 0)
1.1 cgd 365: continue;
1.25 lukem 366: cp = strchr(name, '\0');
1.34 itojun 367:
368: if (pfunc) {
369: (*pfunc)(name);
370: continue;
371: }
372:
1.10 mycroft 373: if ((ifnet.if_flags & IFF_UP) == 0)
1.1 cgd 374: *cp++ = '*';
375: *cp = '\0';
1.10 mycroft 376: ifaddraddr = (u_long)ifnet.if_addrlist.tqh_first;
1.1 cgd 377: }
1.41 itojun 378: if (vflag)
379: n = strlen(name) < 5 ? 5 : strlen(name);
380: else
381: n = 5;
382: printf("%-*.*s %-5llu ", n, n, name,
1.33 bouyer 383: (unsigned long long)ifnet.if_mtu);
1.1 cgd 384: if (ifaddraddr == 0) {
1.21 christos 385: printf("%-13.13s ", "none");
1.23 mikel 386: printf("%-17.17s ", "none");
1.1 cgd 387: } else {
1.64 elad 388: struct sockaddr *sa;
389:
1.94.4.2! martin 390: if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr))
! 391: {
1.8 mycroft 392: ifaddraddr = 0;
393: continue;
394: }
1.1 cgd 395: #define CP(x) ((char *)(x))
1.8 mycroft 396: cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) +
1.56 itojun 397: CP(&ifaddr);
398: sa = (struct sockaddr *)cp;
1.91 ozaki-r 399: print_addr(ifnet.if_index, sa, (void *)&ifaddr,
1.94.4.2! martin 400: &ifnet.if_data, &ifnet, NULL);
1.64 elad 401: }
402: ifaddraddr = (u_long)ifaddr.ifa.ifa_list.tqe_next;
403: }
404:
405: }
406:
407: static void
1.91 ozaki-r 408: mc_print(const int ifindex, const size_t ias, const char *oid, int *mcast_oids,
1.86 christos 409: void (*pr)(const void *))
1.84 christos 410: {
1.85 christos 411: uint8_t *mcast_addrs, *p;
1.86 christos 412: const size_t incr = 2 * ias + sizeof(uint32_t);
1.85 christos 413: size_t len;
414:
415: if (mcast_oids[0] == 0) {
1.86 christos 416: size_t oidlen = 4;
417: if (sysctlnametomib(oid, mcast_oids, &oidlen) == -1) {
418: warnx("'%s' not found", oid);
1.85 christos 419: return;
420: }
421: if (oidlen != 3) {
1.86 christos 422: warnx("Wrong OID path for '%s'", oid);
1.85 christos 423: return;
424: }
425: }
1.86 christos 426:
427: if (mcast_oids[3] == ifindex)
428: return;
1.85 christos 429: mcast_oids[3] = ifindex;
430:
431: mcast_addrs = asysctl(mcast_oids, 4, &len);
432: if (mcast_addrs == NULL && len != 0) {
1.86 christos 433: warn("failed to read '%s'", oid);
1.85 christos 434: return;
435: }
436: if (len) {
437: p = mcast_addrs;
438: while (len >= incr) {
1.86 christos 439: (*pr)((p + ias));
1.85 christos 440: p += incr;
441: len -= incr;
442: }
443: }
444: free(mcast_addrs);
445: }
446:
1.86 christos 447: #ifdef INET6
448: static void
449: ia6_print(const struct in6_addr *ia)
450: {
451: struct sockaddr_in6 as6;
452: char hbuf[NI_MAXHOST]; /* for getnameinfo() */
453: int n;
454:
455: memset(&as6, 0, sizeof(as6));
456: as6.sin6_len = sizeof(struct sockaddr_in6);
457: as6.sin6_family = AF_INET6;
458: as6.sin6_addr = *ia;
459: inet6_getscopeid(&as6, INET6_IS_ADDR_MC_LINKLOCAL);
460: if (getnameinfo((struct sockaddr *)&as6, as6.sin6_len, hbuf,
461: sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) {
462: strlcpy(hbuf, "??", sizeof(hbuf));
463: }
464: if (vflag)
465: n = strlen(hbuf) < 17 ? 17 : strlen(hbuf);
466: else
467: n = 17;
468: printf("\n%25s %-*.*s ", "", n, n, hbuf);
469: }
470:
471: static void
1.91 ozaki-r 472: mc6_print(const int ifindex)
1.86 christos 473: {
474: static int mcast_oids[4];
475:
1.91 ozaki-r 476: mc_print(ifindex, sizeof(struct in6_addr), "net.inet6.multicast",
1.86 christos 477: mcast_oids, (void (*)(const void *))ia6_print);
478: }
479: #endif
480:
1.85 christos 481: static void
482: ia4_print(const struct in_addr *ia)
483: {
484: printf("\n%25s %-17.17s ", "", routename4(ia->s_addr, nflag));
485: }
486:
487: static void
1.91 ozaki-r 488: mc4_print(const int ifindex)
1.85 christos 489: {
490: static int mcast_oids[4];
491:
1.91 ozaki-r 492: mc_print(ifindex, sizeof(struct in_addr), "net.inet.multicast",
1.86 christos 493: mcast_oids, (void (*)(const void *))ia4_print);
1.85 christos 494: }
495:
496: static void
1.94.4.2! martin 497: print_addr(const int ifindex, struct sockaddr *sa, struct sockaddr **rtinfo,
! 498: struct if_data *ifd, struct ifnet *ifnet, struct if_data_ext *dext)
1.64 elad 499: {
500: char hexsep = '.'; /* for hexprint */
501: static const char hexfmt[] = "%02x%c"; /* for hexprint */
502: char hbuf[NI_MAXHOST]; /* for getnameinfo() */
503: #ifdef INET6
504: const int niflag = NI_NUMERICHOST;
1.67 plunky 505: struct sockaddr_in6 *sin6, *netmask6;
1.64 elad 506: #endif
1.81 christos 507: struct sockaddr_in netmask;
1.64 elad 508: struct sockaddr_in *sin;
509: char *cp;
510: int n, m;
511:
512: switch (sa->sa_family) {
513: case AF_UNSPEC:
514: printf("%-13.13s ", "none");
515: printf("%-17.17s ", "none");
516: break;
517: case AF_INET:
518: sin = (struct sockaddr_in *)sa;
519: if (use_sysctl) {
1.94.4.2! martin 520: netmask =
! 521: *((struct sockaddr_in *)rtinfo[RTAX_NETMASK]);
1.64 elad 522: } else {
523: struct in_ifaddr *ifaddr_in = (void *)rtinfo;
1.81 christos 524: netmask.sin_addr.s_addr = ifaddr_in->ia_subnetmask;
1.64 elad 525: }
1.81 christos 526: cp = netname4(sin, &netmask, nflag);
1.64 elad 527: if (vflag)
528: n = strlen(cp) < 13 ? 13 : strlen(cp);
529: else
530: n = 13;
531: printf("%-*.*s ", n, n, cp);
1.80 christos 532: cp = routename4(sin->sin_addr.s_addr, nflag);
1.64 elad 533: if (vflag)
534: n = strlen(cp) < 17 ? 17 : strlen(cp);
535: else
536: n = 17;
537: printf("%-*.*s ", n, n, cp);
538:
1.84 christos 539: if (!aflag)
540: break;
541: if (ifnet) {
1.64 elad 542: u_long multiaddr;
543: struct in_multi inm;
1.73 christos 544: union ifaddr_u *ifaddr = (union ifaddr_u *)rtinfo;
1.64 elad 545:
1.85 christos 546: multiaddr = (u_long)ifaddr->in.ia_multiaddrs.lh_first;
1.64 elad 547: while (multiaddr != 0) {
1.85 christos 548: kread(multiaddr, (char *)&inm, sizeof inm);
549: ia4_print(&inm.inm_addr);
550: multiaddr = (u_long)inm.inm_list.le_next;
1.64 elad 551: }
1.94.4.2! martin 552: } else
1.91 ozaki-r 553: mc4_print(ifindex);
1.64 elad 554: break;
1.32 itojun 555: #ifdef INET6
1.64 elad 556: case AF_INET6:
557: sin6 = (struct sockaddr_in6 *)sa;
1.79 christos 558: inet6_getscopeid(sin6, INET6_IS_ADDR_LINKLOCAL);
1.54 itojun 559: #ifdef __KAME__
1.78 christos 560: if (!vflag)
561: sin6->sin6_scope_id = 0;
1.34 itojun 562: #endif
1.64 elad 563:
1.94.4.2! martin 564: if (use_sysctl)
1.64 elad 565: netmask6 = (struct sockaddr_in6 *)rtinfo[RTAX_NETMASK];
1.94.4.2! martin 566: else {
1.64 elad 567: struct in6_ifaddr *ifaddr_in6 = (void *)rtinfo;
568: netmask6 = &ifaddr_in6->ia_prefixmask;
569: }
570:
1.80 christos 571: cp = netname6(sin6, netmask6, nflag);
1.64 elad 572: if (vflag)
573: n = strlen(cp) < 13 ? 13 : strlen(cp);
574: else
575: n = 13;
576: printf("%-*.*s ", n, n, cp);
577: if (getnameinfo((struct sockaddr *)sin6,
578: sin6->sin6_len,
579: hbuf, sizeof(hbuf), NULL, 0,
580: niflag) != 0) {
581: strlcpy(hbuf, "?", sizeof(hbuf));
582: }
583: cp = hbuf;
584: if (vflag)
585: n = strlen(cp) < 17 ? 17 : strlen(cp);
586: else
587: n = 17;
588: printf("%-*.*s ", n, n, cp);
589:
1.94.4.2! martin 590: if (!aflag)
1.84 christos 591: break;
592: if (ifnet) {
1.64 elad 593: u_long multiaddr;
594: struct in6_multi inm;
1.73 christos 595: union ifaddr_u *ifaddr = (union ifaddr_u *)rtinfo;
1.94.4.2! martin 596:
1.94 ozaki-r 597: multiaddr = (u_long)ifaddr->in6._ia6_multiaddrs.lh_first;
1.64 elad 598: while (multiaddr != 0) {
1.84 christos 599: kread(multiaddr, (char *)&inm, sizeof inm);
600: ia6_print(&inm.in6m_addr);
601: multiaddr = (u_long)inm.in6m_entry.le_next;
1.1 cgd 602: }
1.94.4.2! martin 603: } else
1.91 ozaki-r 604: mc6_print(ifindex);
1.64 elad 605: break;
606: #endif /*INET6*/
607: #ifndef SMALL
608: case AF_APPLETALK:
1.94.4.2! martin 609: printf("atalk:%-7.7s ", atalk_print(sa, 0x10));
! 610: printf("%-17.17s ", atalk_print(sa, 0x0b));
1.64 elad 611: break;
612: #endif
613: case AF_LINK:
614: printf("%-13.13s ", "<Link>");
615: if (getnameinfo(sa, sa->sa_len,
616: hbuf, sizeof(hbuf), NULL, 0,
617: NI_NUMERICHOST) != 0) {
618: strlcpy(hbuf, "?", sizeof(hbuf));
1.26 kml 619: }
1.64 elad 620: cp = hbuf;
621: if (vflag)
622: n = strlen(cp) < 17 ? 17 : strlen(cp);
623: else
624: n = 17;
625: printf("%-*.*s ", n, n, cp);
626: break;
627:
628: default:
629: m = printf("(%d)", sa->sa_family);
630: for (cp = sa->sa_len + (char *)sa;
631: --cp > sa->sa_data && (*cp == 0);) {}
632: n = cp - sa->sa_data + 1;
633: cp = sa->sa_data;
634:
635: while (--n >= 0)
636: m += printf(hexfmt, *cp++ & 0xff,
637: n > 0 ? hexsep : ' ');
638: m = 32 - m;
639: while (m-- > 0)
640: putchar(' ');
641: break;
642: }
643:
644: if (bflag) {
1.68 pooka 645: char humbuf[HUMBUF_SIZE];
646:
647: if (hflag && humanize_number(humbuf, sizeof(humbuf),
648: ifd->ifi_ibytes, "", HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0)
649: printf("%10s ", humbuf);
650: else
651: printf("%10llu ", (unsigned long long)ifd->ifi_ibytes);
652:
653: if (hflag && humanize_number(humbuf, sizeof(humbuf),
654: ifd->ifi_obytes, "", HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0)
655: printf("%10s", humbuf);
656: else
657: printf("%10llu", (unsigned long long)ifd->ifi_obytes);
1.64 elad 658: } else {
1.94.4.1 snj 659: printf("%8llu %5llu",
1.64 elad 660: (unsigned long long)ifd->ifi_ipackets,
1.94.4.1 snj 661: (unsigned long long)ifd->ifi_ierrors);
662: if (dflag)
663: printf(" %6" PRIu64, ifd->ifi_iqdrops);
664: printf(" %8llu %5llu %5llu",
1.64 elad 665: (unsigned long long)ifd->ifi_opackets,
666: (unsigned long long)ifd->ifi_oerrors,
667: (unsigned long long)ifd->ifi_collisions);
1.1 cgd 668: }
1.94.4.1 snj 669: if (dflag)
670: printf(" %6lld", ifnet ?
1.94.4.2! martin 671: (unsigned long long)ifnet->if_snd.ifq_drops :
! 672: dext->ifi_oqdrops);
1.64 elad 673: if (tflag)
1.73 christos 674: printf(" %4d", ifnet ? ifnet->if_timer : 0);
1.64 elad 675: putchar('\n');
676: }
677:
678: static void
679: iftot_banner(struct iftot *ift)
680: {
681: if (bflag)
682: printf("%7.7s in %8.8s %6.6s out %5.5s",
683: ift->ift_name, " ",
684: ift->ift_name, " ");
685: else
686: printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s",
687: ift->ift_name, " ",
688: ift->ift_name, " ", " ");
689: if (dflag)
690: printf(" %5.5s", " ");
691:
692: if (bflag)
693: printf(" %7.7s in %8.8s %6.6s out %5.5s",
694: "total", " ", "total", " ");
695: else
696: printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s",
697: "total", " ", "total", " ", " ");
698: if (dflag)
699: printf(" %5.5s", " ");
700: putchar('\n');
701: if (bflag)
702: printf("%10.10s %8.8s %10.10s %5.5s",
703: "bytes", " ", "bytes", " ");
704: else
705: printf("%8.8s %5.5s %8.8s %5.5s %5.5s",
706: "packets", "errs", "packets", "errs", "colls");
707: if (dflag)
708: printf(" %5.5s", "drops");
709:
710: if (bflag)
711: printf(" %10.10s %8.8s %10.10s %5.5s",
712: "bytes", " ", "bytes", " ");
713: else
714: printf(" %8.8s %5.5s %8.8s %5.5s %5.5s",
715: "packets", "errs", "packets", "errs", "colls");
716: if (dflag)
717: printf(" %5.5s", "drops");
718: putchar('\n');
719: fflush(stdout);
1.1 cgd 720: }
721:
1.64 elad 722: static void
723: iftot_print(struct iftot *cur, struct iftot *old)
724: {
725: if (bflag)
1.75 msaitoh 726: printf("%10" PRIu64 " %8.8s %10" PRIu64 " %5.5s",
1.66 pgoyette 727: cur->ift_ib - old->ift_ib, " ",
728: cur->ift_ob - old->ift_ob, " ");
1.64 elad 729: else
1.75 msaitoh 730: printf("%8" PRIu64 " %5" PRIu64 " %8" PRIu64 " %5" PRIu64 " %5" PRIu64,
1.66 pgoyette 731: cur->ift_ip - old->ift_ip,
732: cur->ift_ie - old->ift_ie,
733: cur->ift_op - old->ift_op,
734: cur->ift_oe - old->ift_oe,
735: cur->ift_co - old->ift_co);
1.64 elad 736: if (dflag)
1.94.4.2! martin 737: printf(" %5" PRIu64, cur->ift_oq - old->ift_oq);
1.64 elad 738: }
739:
740: static void
741: iftot_print_sum(struct iftot *cur, struct iftot *old)
742: {
743: if (bflag)
1.75 msaitoh 744: printf(" %10" PRIu64 " %8.8s %10" PRIu64 " %5.5s",
1.66 pgoyette 745: cur->ift_ib - old->ift_ib, " ",
746: cur->ift_ob - old->ift_ob, " ");
1.64 elad 747: else
1.75 msaitoh 748: printf(" %8" PRIu64 " %5" PRIu64 " %8" PRIu64 " %5" PRIu64 " %5" PRIu64,
1.66 pgoyette 749: cur->ift_ip - old->ift_ip,
750: cur->ift_ie - old->ift_ie,
751: cur->ift_op - old->ift_op,
752: cur->ift_oe - old->ift_oe,
753: cur->ift_co - old->ift_co);
1.64 elad 754:
755: if (dflag)
1.94.4.2! martin 756: printf(" %5" PRIu64, cur->ift_oq - old->ift_oq);
1.64 elad 757: }
758:
1.72 joerg 759: __dead static void
1.64 elad 760: sidewaysintpr_sysctl(unsigned interval)
761: {
1.90 dholland 762: struct itimerval it;
1.64 elad 763: sigset_t emptyset;
1.90 dholland 764: sigset_t noalrm;
1.82 mrg 765: unsigned line;
766:
767: set_lines();
1.64 elad 768:
769: fetchifs();
770: if (ip_cur.ift_name[0] == '\0') {
771: fprintf(stderr, "%s: %s: unknown interface\n",
772: getprogname(), interface);
773: exit(1);
774: }
775:
1.90 dholland 776: sigemptyset(&emptyset);
777: sigemptyset(&noalrm);
778: sigaddset(&noalrm, SIGALRM);
779: sigprocmask(SIG_SETMASK, &noalrm, NULL);
780:
781: signalled = 0;
1.64 elad 782: (void)signal(SIGALRM, catchalarm);
1.90 dholland 783:
784: it.it_interval.tv_sec = it.it_value.tv_sec = interval;
785: it.it_interval.tv_usec = it.it_value.tv_usec = 0;
786: setitimer(ITIMER_REAL, &it, NULL);
787:
1.64 elad 788: banner:
789: iftot_banner(&ip_cur);
790:
791: line = 0;
792: bzero(&ip_old, sizeof(ip_old));
793: bzero(&sum_old, sizeof(sum_old));
794: loop:
795: bzero(&sum_cur, sizeof(sum_cur));
796:
797: fetchifs();
798:
799: iftot_print(&ip_cur, &ip_old);
800:
801: ip_old = ip_cur;
802:
803: iftot_print_sum(&sum_cur, &sum_old);
804:
805: sum_old = sum_cur;
1.1 cgd 806:
1.64 elad 807: putchar('\n');
808: fflush(stdout);
809: line++;
1.94.4.2! martin 810: if (signalled == 0)
1.64 elad 811: sigsuspend(&emptyset);
1.94.4.2! martin 812:
1.64 elad 813: signalled = 0;
1.82 mrg 814: if (line == redraw_lines)
1.64 elad 815: goto banner;
816: goto loop;
817: /*NOTREACHED*/
818: }
1.1 cgd 819:
1.8 mycroft 820: static void
1.64 elad 821: sidewaysintpr_kvm(unsigned interval, u_long off)
1.1 cgd 822: {
1.57 ragge 823: struct itimerval it;
1.90 dholland 824: sigset_t emptyset;
825: sigset_t noalrm;
1.1 cgd 826: struct ifnet ifnet;
1.7 cgd 827: u_long firstifnet;
1.25 lukem 828: struct iftot *ip, *total;
1.82 mrg 829: unsigned line;
1.1 cgd 830: struct iftot *lastif, *sum, *interesting;
1.15 thorpej 831: struct ifnet_head ifhead; /* TAILQ_HEAD */
1.1 cgd 832:
1.82 mrg 833: set_lines();
834:
1.15 thorpej 835: /*
836: * Find the pointer to the first ifnet structure. Replace
837: * the pointer to the TAILQ_HEAD with the actual pointer
838: * to the first list element.
839: */
840: if (kread(off, (char *)&ifhead, sizeof ifhead))
1.8 mycroft 841: return;
1.15 thorpej 842: firstifnet = (u_long)ifhead.tqh_first;
843:
1.1 cgd 844: lastif = iftot;
845: sum = iftot + MAXIF - 1;
846: total = sum - 1;
1.17 cgd 847: interesting = (interface == NULL) ? iftot : NULL;
1.1 cgd 848: for (off = firstifnet, ip = iftot; off;) {
1.8 mycroft 849: if (kread(off, (char *)&ifnet, sizeof ifnet))
850: break;
1.25 lukem 851: memset(ip->ift_name, 0, sizeof(ip->ift_name));
1.31 mycroft 852: snprintf(ip->ift_name, IFNAMSIZ, "%s", ifnet.if_xname);
1.19 thorpej 853: if (interface && strcmp(ifnet.if_xname, interface) == 0)
1.1 cgd 854: interesting = ip;
855: ip++;
856: if (ip >= iftot + MAXIF - 2)
857: break;
1.10 mycroft 858: off = (u_long)ifnet.if_list.tqe_next;
1.17 cgd 859: }
860: if (interesting == NULL) {
861: fprintf(stderr, "%s: %s: unknown interface\n",
1.47 cgd 862: getprogname(), interface);
1.17 cgd 863: exit(1);
1.1 cgd 864: }
865: lastif = ip;
866:
1.90 dholland 867: sigemptyset(&emptyset);
868: sigemptyset(&noalrm);
869: sigaddset(&noalrm, SIGALRM);
870: sigprocmask(SIG_SETMASK, &noalrm, NULL);
871:
872: signalled = 0;
1.1 cgd 873: (void)signal(SIGALRM, catchalarm);
1.57 ragge 874:
875: it.it_interval.tv_sec = it.it_value.tv_sec = interval;
876: it.it_interval.tv_usec = it.it_value.tv_usec = 0;
877: setitimer(ITIMER_REAL, &it, NULL);
878:
1.1 cgd 879: banner:
1.31 mycroft 880: if (bflag)
881: printf("%7.7s in %8.8s %6.6s out %5.5s",
882: interesting->ift_name, " ",
883: interesting->ift_name, " ");
884: else
885: printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s",
886: interesting->ift_name, " ",
887: interesting->ift_name, " ", " ");
888: if (dflag)
889: printf(" %5.5s", " ");
1.1 cgd 890: if (lastif - iftot > 0) {
1.31 mycroft 891: if (bflag)
892: printf(" %7.7s in %8.8s %6.6s out %5.5s",
893: "total", " ", "total", " ");
894: else
895: printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s",
896: "total", " ", "total", " ", " ");
1.1 cgd 897: if (dflag)
1.31 mycroft 898: printf(" %5.5s", " ");
1.1 cgd 899: }
900: for (ip = iftot; ip < iftot + MAXIF; ip++) {
901: ip->ift_ip = 0;
1.26 kml 902: ip->ift_ib = 0;
1.1 cgd 903: ip->ift_ie = 0;
1.94.4.2! martin 904: ip->ift_iq = 0;
1.1 cgd 905: ip->ift_op = 0;
1.26 kml 906: ip->ift_ob = 0;
1.1 cgd 907: ip->ift_oe = 0;
1.94.4.2! martin 908: ip->ift_oq = 0;
1.1 cgd 909: ip->ift_co = 0;
910: }
911: putchar('\n');
1.31 mycroft 912: if (bflag)
1.26 kml 913: printf("%10.10s %8.8s %10.10s %5.5s",
1.31 mycroft 914: "bytes", " ", "bytes", " ");
915: else
916: printf("%8.8s %5.5s %8.8s %5.5s %5.5s",
917: "packets", "errs", "packets", "errs", "colls");
1.1 cgd 918: if (dflag)
1.31 mycroft 919: printf(" %5.5s", "drops");
1.29 ross 920: if (lastif - iftot > 0) {
1.31 mycroft 921: if (bflag)
922: printf(" %10.10s %8.8s %10.10s %5.5s",
923: "bytes", " ", "bytes", " ");
924: else
925: printf(" %8.8s %5.5s %8.8s %5.5s %5.5s",
926: "packets", "errs", "packets", "errs", "colls");
927: if (dflag)
928: printf(" %5.5s", "drops");
1.29 ross 929: }
1.1 cgd 930: putchar('\n');
931: fflush(stdout);
932: line = 0;
933: loop:
934: sum->ift_ip = 0;
1.26 kml 935: sum->ift_ib = 0;
1.1 cgd 936: sum->ift_ie = 0;
1.94.4.2! martin 937: sum->ift_iq = 0;
1.1 cgd 938: sum->ift_op = 0;
1.26 kml 939: sum->ift_ob = 0;
1.1 cgd 940: sum->ift_oe = 0;
1.94.4.2! martin 941: sum->ift_oq = 0;
1.1 cgd 942: sum->ift_co = 0;
943: for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) {
1.8 mycroft 944: if (kread(off, (char *)&ifnet, sizeof ifnet)) {
945: off = 0;
946: continue;
947: }
1.1 cgd 948: if (ip == interesting) {
1.26 kml 949: if (bflag) {
1.68 pooka 950: char humbuf[HUMBUF_SIZE];
951:
952: if (hflag && humanize_number(humbuf,
953: sizeof(humbuf),
954: ifnet.if_ibytes - ip->ift_ib, "",
955: HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0)
956: printf("%10s %8.8s ", humbuf, " ");
957: else
1.94.4.2! martin 958: printf("%10llu %8.8s ",
1.68 pooka 959: (unsigned long long)
960: (ifnet.if_ibytes-ip->ift_ib), " ");
961:
962: if (hflag && humanize_number(humbuf,
963: sizeof(humbuf),
964: ifnet.if_obytes - ip->ift_ob, "",
965: HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0)
966: printf("%10s %5.5s", humbuf, " ");
967: else
1.94.4.2! martin 968: printf("%10llu %5.5s",
1.68 pooka 969: (unsigned long long)
970: (ifnet.if_obytes-ip->ift_ob), " ");
1.26 kml 971: } else {
1.33 bouyer 972: printf("%8llu %5llu %8llu %5llu %5llu",
973: (unsigned long long)
974: (ifnet.if_ipackets - ip->ift_ip),
975: (unsigned long long)
976: (ifnet.if_ierrors - ip->ift_ie),
977: (unsigned long long)
978: (ifnet.if_opackets - ip->ift_op),
979: (unsigned long long)
980: (ifnet.if_oerrors - ip->ift_oe),
981: (unsigned long long)
982: (ifnet.if_collisions - ip->ift_co));
1.26 kml 983: }
1.1 cgd 984: if (dflag)
1.89 christos 985: printf(" %5" PRIu64,
1.94.4.2! martin 986: ifnet.if_snd.ifq_drops - ip->ift_oq);
1.1 cgd 987: }
988: ip->ift_ip = ifnet.if_ipackets;
1.26 kml 989: ip->ift_ib = ifnet.if_ibytes;
1.1 cgd 990: ip->ift_ie = ifnet.if_ierrors;
991: ip->ift_op = ifnet.if_opackets;
1.26 kml 992: ip->ift_ob = ifnet.if_obytes;
1.1 cgd 993: ip->ift_oe = ifnet.if_oerrors;
994: ip->ift_co = ifnet.if_collisions;
1.94.4.2! martin 995: ip->ift_oq = ifnet.if_snd.ifq_drops;
1.1 cgd 996: sum->ift_ip += ip->ift_ip;
1.26 kml 997: sum->ift_ib += ip->ift_ib;
1.1 cgd 998: sum->ift_ie += ip->ift_ie;
999: sum->ift_op += ip->ift_op;
1.26 kml 1000: sum->ift_ob += ip->ift_ob;
1.1 cgd 1001: sum->ift_oe += ip->ift_oe;
1002: sum->ift_co += ip->ift_co;
1.94.4.2! martin 1003: sum->ift_oq += ip->ift_oq;
1.10 mycroft 1004: off = (u_long)ifnet.if_list.tqe_next;
1.1 cgd 1005: }
1006: if (lastif - iftot > 0) {
1.26 kml 1007: if (bflag) {
1.68 pooka 1008: char humbuf[HUMBUF_SIZE];
1009:
1010: if (hflag && humanize_number(humbuf,
1011: sizeof(humbuf), sum->ift_ib - total->ift_ib, "",
1012: HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0)
1.69 enami 1013: printf(" %10s %8.8s ", humbuf, " ");
1.68 pooka 1014: else
1.94.4.2! martin 1015: printf(" %10llu %8.8s ",
1.68 pooka 1016: (unsigned long long)
1017: (sum->ift_ib - total->ift_ib), " ");
1018:
1019: if (hflag && humanize_number(humbuf,
1020: sizeof(humbuf), sum->ift_ob - total->ift_ob, "",
1021: HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0)
1022: printf("%10s %5.5s", humbuf, " ");
1023: else
1.94.4.2! martin 1024: printf("%10llu %5.5s",
1.68 pooka 1025: (unsigned long long)
1026: (sum->ift_ob - total->ift_ob), " ");
1.26 kml 1027: } else {
1.33 bouyer 1028: printf(" %8llu %5llu %8llu %5llu %5llu",
1029: (unsigned long long)
1030: (sum->ift_ip - total->ift_ip),
1031: (unsigned long long)
1032: (sum->ift_ie - total->ift_ie),
1033: (unsigned long long)
1034: (sum->ift_op - total->ift_op),
1035: (unsigned long long)
1036: (sum->ift_oe - total->ift_oe),
1037: (unsigned long long)
1038: (sum->ift_co - total->ift_co));
1.26 kml 1039: }
1.1 cgd 1040: if (dflag)
1.33 bouyer 1041: printf(" %5llu",
1.94.4.2! martin 1042: (unsigned long long)(sum->ift_oq - total->ift_oq));
1.1 cgd 1043: }
1044: *total = *sum;
1045: putchar('\n');
1046: fflush(stdout);
1047: line++;
1.94.4.2! martin 1048: if (signalled == 0)
1.90 dholland 1049: sigsuspend(&emptyset);
1.94.4.2! martin 1050:
1.90 dholland 1051: signalled = 0;
1.82 mrg 1052: if (line == redraw_lines)
1.1 cgd 1053: goto banner;
1054: goto loop;
1055: /*NOTREACHED*/
1056: }
1057:
1058: /*
1.64 elad 1059: * Print a running summary of interface statistics.
1060: * Repeat display every interval seconds, showing statistics
1061: * collected over that interval. Assumes that interval is non-zero.
1062: * First line printed at top of screen is always cumulative.
1063: */
1064: static void
1.74 matt 1065: sidewaysintpr(unsigned int interval, u_long off)
1.64 elad 1066: {
1067:
1.94.4.2! martin 1068: if (use_sysctl)
1.64 elad 1069: sidewaysintpr_sysctl(interval);
1.94.4.2! martin 1070: else
1.64 elad 1071: sidewaysintpr_kvm(interval, off);
1072: }
1073:
1074: /*
1.1 cgd 1075: * Called if an interval expires before sidewaysintpr has completed a loop.
1076: * Sets a flag to not wait for the alarm.
1077: */
1.8 mycroft 1078: static void
1.74 matt 1079: catchalarm(int signo)
1.1 cgd 1080: {
1.28 mrg 1081:
1.64 elad 1082: signalled = true;
1083: }
1084:
1085: static void
1086: get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
1.94.4.2! martin 1087: {
1.64 elad 1088: int i;
1089:
1090: for (i = 0; i < RTAX_MAX; i++) {
1091: if (addrs & (1 << i)) {
1092: rti_info[i] = sa;
1.71 martin 1093: sa = (struct sockaddr *)((char *)(sa) +
1094: RT_ROUNDUP(sa->sa_len));
1.94.4.2! martin 1095: } else
1.64 elad 1096: rti_info[i] = NULL;
1097: }
1098: }
1099:
1100: static void
1101: fetchifs(void)
1102: {
1103: struct if_msghdr *ifm;
1104: int mib[6] = { CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
1105: struct rt_msghdr *rtm;
1106: struct if_data *ifd = NULL;
1107: struct sockaddr *sa, *rti_info[RTAX_MAX];
1108: struct sockaddr_dl *sdl;
1.93 mrg 1109: static char *buf = NULL;
1110: static size_t olen;
1.94.4.2! martin 1111: struct if_data_ext dext;
1.93 mrg 1112: char *next, *lim;
1.64 elad 1113: char name[IFNAMSIZ];
1114: size_t len;
1115:
1.70 pooka 1116: if (prog_sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
1.64 elad 1117: err(1, "sysctl");
1.93 mrg 1118: if (len > olen) {
1119: free(buf);
1120: if ((buf = malloc(len)) == NULL)
1121: err(1, NULL);
1122: olen = len;
1123: }
1.70 pooka 1124: if (prog_sysctl(mib, 6, buf, &len, NULL, 0) == -1)
1.64 elad 1125: err(1, "sysctl");
1126:
1.94.4.2! martin 1127: memset(&dext, 0, sizeof(dext));
1.64 elad 1128: lim = buf + len;
1129: for (next = buf; next < lim; next += rtm->rtm_msglen) {
1130: rtm = (struct rt_msghdr *)next;
1131: if (rtm->rtm_version != RTM_VERSION)
1132: continue;
1133: switch (rtm->rtm_type) {
1134: case RTM_IFINFO:
1135: ifm = (struct if_msghdr *)next;
1136: ifd = &ifm->ifm_data;
1137:
1138: sa = (struct sockaddr *)(ifm + 1);
1139: get_rtaddrs(ifm->ifm_addrs, sa, rti_info);
1140:
1141: sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP];
1142: if (sdl == NULL || sdl->sdl_family != AF_LINK)
1143: continue;
1144: bzero(name, sizeof(name));
1145: if (sdl->sdl_nlen >= IFNAMSIZ)
1146: memcpy(name, sdl->sdl_data, IFNAMSIZ - 1);
1.94.4.2! martin 1147: else if (sdl->sdl_nlen > 0)
1.64 elad 1148: memcpy(name, sdl->sdl_data, sdl->sdl_nlen);
1149:
1.94.4.2! martin 1150: if_data_ext_get(name, &dext);
! 1151:
! 1152: if (interface != NULL && !strcmp(name, interface)) {
1.64 elad 1153: strlcpy(ip_cur.ift_name, name,
1154: sizeof(ip_cur.ift_name));
1155: ip_cur.ift_ip = ifd->ifi_ipackets;
1156: ip_cur.ift_ib = ifd->ifi_ibytes;
1157: ip_cur.ift_ie = ifd->ifi_ierrors;
1158: ip_cur.ift_op = ifd->ifi_opackets;
1159: ip_cur.ift_ob = ifd->ifi_obytes;
1160: ip_cur.ift_oe = ifd->ifi_oerrors;
1161: ip_cur.ift_co = ifd->ifi_collisions;
1.94.4.2! martin 1162: ip_cur.ift_iq = ifd->ifi_iqdrops;
! 1163: ip_cur.ift_oq = dext.ifi_oqdrops;
1.64 elad 1164: }
1165:
1166: sum_cur.ift_ip += ifd->ifi_ipackets;
1167: sum_cur.ift_ib += ifd->ifi_ibytes;
1168: sum_cur.ift_ie += ifd->ifi_ierrors;
1169: sum_cur.ift_op += ifd->ifi_opackets;
1170: sum_cur.ift_ob += ifd->ifi_obytes;
1171: sum_cur.ift_oe += ifd->ifi_oerrors;
1172: sum_cur.ift_co += ifd->ifi_collisions;
1.94.4.2! martin 1173: sum_cur.ift_iq += ifd->ifi_iqdrops;
! 1174: sum_cur.ift_oq += dext.ifi_oqdrops;
1.64 elad 1175: break;
1176: }
1177: }
1178: if (interface == NULL) {
1179: strlcpy(ip_cur.ift_name, name,
1180: sizeof(ip_cur.ift_name));
1181: ip_cur.ift_ip = ifd->ifi_ipackets;
1182: ip_cur.ift_ib = ifd->ifi_ibytes;
1183: ip_cur.ift_ie = ifd->ifi_ierrors;
1184: ip_cur.ift_op = ifd->ifi_opackets;
1185: ip_cur.ift_ob = ifd->ifi_obytes;
1186: ip_cur.ift_oe = ifd->ifi_oerrors;
1187: ip_cur.ift_co = ifd->ifi_collisions;
1.94.4.2! martin 1188: ip_cur.ift_iq = ifd->ifi_iqdrops;
! 1189: ip_cur.ift_oq = dext.ifi_oqdrops;
1.64 elad 1190: }
1.1 cgd 1191: }
CVSweb <webmaster@jp.NetBSD.org>