Annotation of src/usr.bin/netstat/if.c, Revision 1.102
1.102 ! msaitoh 1: /* $NetBSD: if.c,v 1.101 2022/09/05 02:26:22 msaitoh 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.102 ! msaitoh 37: __RCSID("$NetBSD: if.c,v 1.101 2022/09/05 02:26:22 msaitoh 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.101 msaitoh 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.101 msaitoh 83: u_quad_t ift_oq; /* output drops */
1.64 elad 84: u_quad_t ift_co; /* collisions */
1.101 msaitoh 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.101 msaitoh 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.101 msaitoh 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.99 msaitoh 141: if (use_sysctl)
1.64 elad 142: intpr_sysctl();
1.99 msaitoh 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.98 msaitoh 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.95 msaitoh 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.95 msaitoh 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.101 msaitoh 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.101 msaitoh 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.101 msaitoh 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.99 msaitoh 246: if (sdl == NULL || sdl->sdl_family != AF_LINK)
1.64 elad 247: continue;
1.99 msaitoh 248:
1.64 elad 249: bzero(name, sizeof(name));
250: if (sdl->sdl_nlen >= IFNAMSIZ)
251: memcpy(name, sdl->sdl_data, IFNAMSIZ - 1);
1.98 msaitoh 252: else if (sdl->sdl_nlen > 0)
1.64 elad 253: memcpy(name, sdl->sdl_data, sdl->sdl_nlen);
254:
1.97 msaitoh 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.101 msaitoh 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.101 msaitoh 265: if ((ifm->ifm_flags & IFF_UP) == 0) {
1.64 elad 266: *cp++ = '*';
1.101 msaitoh 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.97 msaitoh 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.102 ! msaitoh 312: if (dflag)
1.101 msaitoh 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
1.100 msaitoh 329: ifname_to_ifdata(int s, const char *ifname, struct if_data * const ifd)
1.96 thorpej 330: {
1.100 msaitoh 331: struct ifdatareq ifdr;
1.96 thorpej 332:
333: memset(ifd, 0, sizeof(*ifd));
1.100 msaitoh 334: strlcpy(ifdr.ifdr_name, ifname, sizeof(ifdr.ifdr_name));
335: if (ioctl(s, SIOCGIFDATA, &ifdr) != 0)
336: return;
337: memcpy(ifd, &ifdr.ifdr_data, sizeof(ifdr.ifdr_data));
1.96 thorpej 338: }
339:
340: static void
1.64 elad 341: intpr_kvm(u_long ifnetaddr, void (*pfunc)(const char *))
342: {
1.1 cgd 343: struct ifnet ifnet;
1.96 thorpej 344: struct if_data ifd;
1.73 christos 345: union ifaddr_u ifaddr;
1.7 cgd 346: u_long ifaddraddr;
1.15 thorpej 347: struct ifnet_head ifhead; /* TAILQ_HEAD */
1.43 enami 348: char name[IFNAMSIZ + 1]; /* + 1 for `*' */
1.100 msaitoh 349: int s;
1.1 cgd 350:
351: if (ifnetaddr == 0) {
352: printf("ifnet: symbol not defined\n");
353: return;
354: }
1.15 thorpej 355:
356: /*
357: * Find the pointer to the first ifnet structure. Replace
358: * the pointer to the TAILQ_HEAD with the actual pointer
359: * to the first list element.
360: */
361: if (kread(ifnetaddr, (char *)&ifhead, sizeof ifhead))
1.8 mycroft 362: return;
1.15 thorpej 363: ifnetaddr = (u_long)ifhead.tqh_first;
364:
1.100 msaitoh 365: if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
366: return;
367:
1.64 elad 368: intpr_header();
369:
1.1 cgd 370: ifaddraddr = 0;
371: while (ifnetaddr || ifaddraddr) {
1.25 lukem 372: char *cp;
1.64 elad 373: int n;
1.1 cgd 374:
375: if (ifaddraddr == 0) {
1.15 thorpej 376: if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet))
1.8 mycroft 377: return;
1.25 lukem 378: memmove(name, ifnet.if_xname, IFNAMSIZ);
1.15 thorpej 379: name[IFNAMSIZ - 1] = '\0'; /* sanity */
1.10 mycroft 380: ifnetaddr = (u_long)ifnet.if_list.tqe_next;
1.97 msaitoh 381: if (interface != NULL && strcmp(name, interface) != 0)
1.1 cgd 382: continue;
1.25 lukem 383: cp = strchr(name, '\0');
1.34 itojun 384:
385: if (pfunc) {
386: (*pfunc)(name);
387: continue;
388: }
389:
1.10 mycroft 390: if ((ifnet.if_flags & IFF_UP) == 0)
1.1 cgd 391: *cp++ = '*';
392: *cp = '\0';
1.10 mycroft 393: ifaddraddr = (u_long)ifnet.if_addrlist.tqh_first;
1.1 cgd 394: }
1.41 itojun 395: if (vflag)
396: n = strlen(name) < 5 ? 5 : strlen(name);
397: else
398: n = 5;
399: printf("%-*.*s %-5llu ", n, n, name,
1.33 bouyer 400: (unsigned long long)ifnet.if_mtu);
1.1 cgd 401: if (ifaddraddr == 0) {
1.21 christos 402: printf("%-13.13s ", "none");
1.23 mikel 403: printf("%-17.17s ", "none");
1.1 cgd 404: } else {
1.64 elad 405: struct sockaddr *sa;
406:
1.98 msaitoh 407: if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr))
408: {
1.8 mycroft 409: ifaddraddr = 0;
410: continue;
411: }
1.1 cgd 412: #define CP(x) ((char *)(x))
1.8 mycroft 413: cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) +
1.56 itojun 414: CP(&ifaddr);
415: sa = (struct sockaddr *)cp;
1.100 msaitoh 416: ifname_to_ifdata(s, name, &ifd);
1.91 ozaki-r 417: print_addr(ifnet.if_index, sa, (void *)&ifaddr,
1.101 msaitoh 418: &ifd, &ifnet, NULL);
1.64 elad 419: }
420: ifaddraddr = (u_long)ifaddr.ifa.ifa_list.tqe_next;
421: }
1.100 msaitoh 422: close(s);
1.64 elad 423: }
424:
425: static void
1.91 ozaki-r 426: mc_print(const int ifindex, const size_t ias, const char *oid, int *mcast_oids,
1.86 christos 427: void (*pr)(const void *))
1.84 christos 428: {
1.85 christos 429: uint8_t *mcast_addrs, *p;
1.86 christos 430: const size_t incr = 2 * ias + sizeof(uint32_t);
1.85 christos 431: size_t len;
432:
433: if (mcast_oids[0] == 0) {
1.86 christos 434: size_t oidlen = 4;
435: if (sysctlnametomib(oid, mcast_oids, &oidlen) == -1) {
436: warnx("'%s' not found", oid);
1.85 christos 437: return;
438: }
439: if (oidlen != 3) {
1.86 christos 440: warnx("Wrong OID path for '%s'", oid);
1.85 christos 441: return;
442: }
443: }
1.86 christos 444:
445: if (mcast_oids[3] == ifindex)
446: return;
1.85 christos 447: mcast_oids[3] = ifindex;
448:
449: mcast_addrs = asysctl(mcast_oids, 4, &len);
450: if (mcast_addrs == NULL && len != 0) {
1.86 christos 451: warn("failed to read '%s'", oid);
1.85 christos 452: return;
453: }
454: if (len) {
455: p = mcast_addrs;
456: while (len >= incr) {
1.86 christos 457: (*pr)((p + ias));
1.85 christos 458: p += incr;
459: len -= incr;
460: }
461: }
462: free(mcast_addrs);
463: }
464:
1.86 christos 465: #ifdef INET6
466: static void
467: ia6_print(const struct in6_addr *ia)
468: {
469: struct sockaddr_in6 as6;
470: char hbuf[NI_MAXHOST]; /* for getnameinfo() */
471: int n;
472:
473: memset(&as6, 0, sizeof(as6));
474: as6.sin6_len = sizeof(struct sockaddr_in6);
475: as6.sin6_family = AF_INET6;
476: as6.sin6_addr = *ia;
477: inet6_getscopeid(&as6, INET6_IS_ADDR_MC_LINKLOCAL);
478: if (getnameinfo((struct sockaddr *)&as6, as6.sin6_len, hbuf,
479: sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0) {
480: strlcpy(hbuf, "??", sizeof(hbuf));
481: }
482: if (vflag)
483: n = strlen(hbuf) < 17 ? 17 : strlen(hbuf);
484: else
485: n = 17;
486: printf("\n%25s %-*.*s ", "", n, n, hbuf);
487: }
488:
489: static void
1.91 ozaki-r 490: mc6_print(const int ifindex)
1.86 christos 491: {
492: static int mcast_oids[4];
493:
1.91 ozaki-r 494: mc_print(ifindex, sizeof(struct in6_addr), "net.inet6.multicast",
1.86 christos 495: mcast_oids, (void (*)(const void *))ia6_print);
496: }
497: #endif
498:
1.85 christos 499: static void
500: ia4_print(const struct in_addr *ia)
501: {
502: printf("\n%25s %-17.17s ", "", routename4(ia->s_addr, nflag));
503: }
504:
505: static void
1.91 ozaki-r 506: mc4_print(const int ifindex)
1.85 christos 507: {
508: static int mcast_oids[4];
509:
1.91 ozaki-r 510: mc_print(ifindex, sizeof(struct in_addr), "net.inet.multicast",
1.86 christos 511: mcast_oids, (void (*)(const void *))ia4_print);
1.85 christos 512: }
513:
514: static void
1.101 msaitoh 515: print_addr(const int ifindex, struct sockaddr *sa, struct sockaddr **rtinfo,
516: struct if_data *ifd, struct ifnet *ifnet, struct if_data_ext *dext)
1.64 elad 517: {
518: char hexsep = '.'; /* for hexprint */
519: static const char hexfmt[] = "%02x%c"; /* for hexprint */
520: char hbuf[NI_MAXHOST]; /* for getnameinfo() */
521: #ifdef INET6
522: const int niflag = NI_NUMERICHOST;
1.67 plunky 523: struct sockaddr_in6 *sin6, *netmask6;
1.64 elad 524: #endif
1.81 christos 525: struct sockaddr_in netmask;
1.64 elad 526: struct sockaddr_in *sin;
527: char *cp;
528: int n, m;
529:
530: switch (sa->sa_family) {
531: case AF_UNSPEC:
532: printf("%-13.13s ", "none");
533: printf("%-17.17s ", "none");
534: break;
535: case AF_INET:
536: sin = (struct sockaddr_in *)sa;
537: if (use_sysctl) {
1.98 msaitoh 538: netmask =
539: *((struct sockaddr_in *)rtinfo[RTAX_NETMASK]);
1.64 elad 540: } else {
541: struct in_ifaddr *ifaddr_in = (void *)rtinfo;
1.81 christos 542: netmask.sin_addr.s_addr = ifaddr_in->ia_subnetmask;
1.64 elad 543: }
1.81 christos 544: cp = netname4(sin, &netmask, nflag);
1.64 elad 545: if (vflag)
546: n = strlen(cp) < 13 ? 13 : strlen(cp);
547: else
548: n = 13;
549: printf("%-*.*s ", n, n, cp);
1.80 christos 550: cp = routename4(sin->sin_addr.s_addr, nflag);
1.64 elad 551: if (vflag)
552: n = strlen(cp) < 17 ? 17 : strlen(cp);
553: else
554: n = 17;
555: printf("%-*.*s ", n, n, cp);
556:
1.84 christos 557: if (!aflag)
558: break;
559: if (ifnet) {
1.64 elad 560: u_long multiaddr;
561: struct in_multi inm;
1.73 christos 562: union ifaddr_u *ifaddr = (union ifaddr_u *)rtinfo;
1.64 elad 563:
1.85 christos 564: multiaddr = (u_long)ifaddr->in.ia_multiaddrs.lh_first;
1.64 elad 565: while (multiaddr != 0) {
1.85 christos 566: kread(multiaddr, (char *)&inm, sizeof inm);
567: ia4_print(&inm.inm_addr);
568: multiaddr = (u_long)inm.inm_list.le_next;
1.64 elad 569: }
1.99 msaitoh 570: } else
1.91 ozaki-r 571: mc4_print(ifindex);
1.64 elad 572: break;
1.32 itojun 573: #ifdef INET6
1.64 elad 574: case AF_INET6:
575: sin6 = (struct sockaddr_in6 *)sa;
1.79 christos 576: inet6_getscopeid(sin6, INET6_IS_ADDR_LINKLOCAL);
1.54 itojun 577: #ifdef __KAME__
1.78 christos 578: if (!vflag)
579: sin6->sin6_scope_id = 0;
1.34 itojun 580: #endif
1.64 elad 581:
1.99 msaitoh 582: if (use_sysctl)
1.64 elad 583: netmask6 = (struct sockaddr_in6 *)rtinfo[RTAX_NETMASK];
1.99 msaitoh 584: else {
1.64 elad 585: struct in6_ifaddr *ifaddr_in6 = (void *)rtinfo;
586: netmask6 = &ifaddr_in6->ia_prefixmask;
587: }
588:
1.80 christos 589: cp = netname6(sin6, netmask6, nflag);
1.64 elad 590: if (vflag)
591: n = strlen(cp) < 13 ? 13 : strlen(cp);
592: else
593: n = 13;
594: printf("%-*.*s ", n, n, cp);
595: if (getnameinfo((struct sockaddr *)sin6,
596: sin6->sin6_len,
597: hbuf, sizeof(hbuf), NULL, 0,
598: niflag) != 0) {
599: strlcpy(hbuf, "?", sizeof(hbuf));
600: }
601: cp = hbuf;
602: if (vflag)
603: n = strlen(cp) < 17 ? 17 : strlen(cp);
604: else
605: n = 17;
606: printf("%-*.*s ", n, n, cp);
607:
1.98 msaitoh 608: if (!aflag)
1.84 christos 609: break;
610: if (ifnet) {
1.64 elad 611: u_long multiaddr;
612: struct in6_multi inm;
1.73 christos 613: union ifaddr_u *ifaddr = (union ifaddr_u *)rtinfo;
1.98 msaitoh 614:
1.94 ozaki-r 615: multiaddr = (u_long)ifaddr->in6._ia6_multiaddrs.lh_first;
1.64 elad 616: while (multiaddr != 0) {
1.84 christos 617: kread(multiaddr, (char *)&inm, sizeof inm);
618: ia6_print(&inm.in6m_addr);
619: multiaddr = (u_long)inm.in6m_entry.le_next;
1.1 cgd 620: }
1.99 msaitoh 621: } else
1.91 ozaki-r 622: mc6_print(ifindex);
1.64 elad 623: break;
624: #endif /*INET6*/
625: #ifndef SMALL
626: case AF_APPLETALK:
1.98 msaitoh 627: printf("atalk:%-7.7s ", atalk_print(sa, 0x10));
628: printf("%-17.17s ", atalk_print(sa, 0x0b));
1.64 elad 629: break;
630: #endif
631: case AF_LINK:
632: printf("%-13.13s ", "<Link>");
633: if (getnameinfo(sa, sa->sa_len,
634: hbuf, sizeof(hbuf), NULL, 0,
635: NI_NUMERICHOST) != 0) {
636: strlcpy(hbuf, "?", sizeof(hbuf));
1.26 kml 637: }
1.64 elad 638: cp = hbuf;
639: if (vflag)
640: n = strlen(cp) < 17 ? 17 : strlen(cp);
641: else
642: n = 17;
643: printf("%-*.*s ", n, n, cp);
644: break;
645:
646: default:
647: m = printf("(%d)", sa->sa_family);
648: for (cp = sa->sa_len + (char *)sa;
649: --cp > sa->sa_data && (*cp == 0);) {}
650: n = cp - sa->sa_data + 1;
651: cp = sa->sa_data;
652:
653: while (--n >= 0)
654: m += printf(hexfmt, *cp++ & 0xff,
655: n > 0 ? hexsep : ' ');
656: m = 32 - m;
657: while (m-- > 0)
658: putchar(' ');
659: break;
660: }
661:
662: if (bflag) {
1.68 pooka 663: char humbuf[HUMBUF_SIZE];
664:
665: if (hflag && humanize_number(humbuf, sizeof(humbuf),
666: ifd->ifi_ibytes, "", HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0)
667: printf("%10s ", humbuf);
668: else
669: printf("%10llu ", (unsigned long long)ifd->ifi_ibytes);
670:
671: if (hflag && humanize_number(humbuf, sizeof(humbuf),
672: ifd->ifi_obytes, "", HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0)
673: printf("%10s", humbuf);
674: else
675: printf("%10llu", (unsigned long long)ifd->ifi_obytes);
1.64 elad 676: } else {
1.95 msaitoh 677: printf("%8llu %5llu",
1.64 elad 678: (unsigned long long)ifd->ifi_ipackets,
1.95 msaitoh 679: (unsigned long long)ifd->ifi_ierrors);
680: if (dflag)
681: printf(" %6" PRIu64, ifd->ifi_iqdrops);
682: printf(" %8llu %5llu %5llu",
1.64 elad 683: (unsigned long long)ifd->ifi_opackets,
684: (unsigned long long)ifd->ifi_oerrors,
685: (unsigned long long)ifd->ifi_collisions);
1.1 cgd 686: }
1.95 msaitoh 687: if (dflag)
688: printf(" %6lld", ifnet ?
1.101 msaitoh 689: (unsigned long long)ifnet->if_snd.ifq_drops :
690: dext->ifi_oqdrops);
1.64 elad 691: if (tflag)
1.73 christos 692: printf(" %4d", ifnet ? ifnet->if_timer : 0);
1.64 elad 693: putchar('\n');
694: }
695:
696: static void
697: iftot_banner(struct iftot *ift)
698: {
699: if (bflag)
700: printf("%7.7s in %8.8s %6.6s out %5.5s",
701: ift->ift_name, " ",
702: ift->ift_name, " ");
703: else
704: printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s",
705: ift->ift_name, " ",
706: ift->ift_name, " ", " ");
707: if (dflag)
708: printf(" %5.5s", " ");
709:
710: if (bflag)
711: printf(" %7.7s in %8.8s %6.6s out %5.5s",
712: "total", " ", "total", " ");
713: else
714: printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s",
715: "total", " ", "total", " ", " ");
716: if (dflag)
717: printf(" %5.5s", " ");
718: putchar('\n');
719: if (bflag)
720: printf("%10.10s %8.8s %10.10s %5.5s",
721: "bytes", " ", "bytes", " ");
722: else
723: printf("%8.8s %5.5s %8.8s %5.5s %5.5s",
724: "packets", "errs", "packets", "errs", "colls");
725: if (dflag)
726: printf(" %5.5s", "drops");
727:
728: if (bflag)
729: printf(" %10.10s %8.8s %10.10s %5.5s",
730: "bytes", " ", "bytes", " ");
731: else
732: printf(" %8.8s %5.5s %8.8s %5.5s %5.5s",
733: "packets", "errs", "packets", "errs", "colls");
734: if (dflag)
735: printf(" %5.5s", "drops");
736: putchar('\n');
737: fflush(stdout);
1.1 cgd 738: }
739:
1.64 elad 740: static void
741: iftot_print(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: if (dflag)
1.101 msaitoh 755: printf(" %5" PRIu64, cur->ift_oq - old->ift_oq);
1.64 elad 756: }
757:
758: static void
759: iftot_print_sum(struct iftot *cur, struct iftot *old)
760: {
761: if (bflag)
1.75 msaitoh 762: printf(" %10" PRIu64 " %8.8s %10" PRIu64 " %5.5s",
1.66 pgoyette 763: cur->ift_ib - old->ift_ib, " ",
764: cur->ift_ob - old->ift_ob, " ");
1.64 elad 765: else
1.75 msaitoh 766: printf(" %8" PRIu64 " %5" PRIu64 " %8" PRIu64 " %5" PRIu64 " %5" PRIu64,
1.66 pgoyette 767: cur->ift_ip - old->ift_ip,
768: cur->ift_ie - old->ift_ie,
769: cur->ift_op - old->ift_op,
770: cur->ift_oe - old->ift_oe,
771: cur->ift_co - old->ift_co);
1.64 elad 772:
773: if (dflag)
1.101 msaitoh 774: printf(" %5" PRIu64, cur->ift_oq - old->ift_oq);
1.64 elad 775: }
776:
1.72 joerg 777: __dead static void
1.64 elad 778: sidewaysintpr_sysctl(unsigned interval)
779: {
1.90 dholland 780: struct itimerval it;
1.64 elad 781: sigset_t emptyset;
1.90 dholland 782: sigset_t noalrm;
1.82 mrg 783: unsigned line;
784:
785: set_lines();
1.64 elad 786:
787: fetchifs();
788: if (ip_cur.ift_name[0] == '\0') {
789: fprintf(stderr, "%s: %s: unknown interface\n",
790: getprogname(), interface);
791: exit(1);
792: }
793:
1.90 dholland 794: sigemptyset(&emptyset);
795: sigemptyset(&noalrm);
796: sigaddset(&noalrm, SIGALRM);
797: sigprocmask(SIG_SETMASK, &noalrm, NULL);
798:
799: signalled = 0;
1.64 elad 800: (void)signal(SIGALRM, catchalarm);
1.90 dholland 801:
802: it.it_interval.tv_sec = it.it_value.tv_sec = interval;
803: it.it_interval.tv_usec = it.it_value.tv_usec = 0;
804: setitimer(ITIMER_REAL, &it, NULL);
805:
1.64 elad 806: banner:
807: iftot_banner(&ip_cur);
808:
809: line = 0;
810: bzero(&ip_old, sizeof(ip_old));
811: bzero(&sum_old, sizeof(sum_old));
812: loop:
813: bzero(&sum_cur, sizeof(sum_cur));
814:
815: fetchifs();
816:
817: iftot_print(&ip_cur, &ip_old);
818:
819: ip_old = ip_cur;
820:
821: iftot_print_sum(&sum_cur, &sum_old);
822:
823: sum_old = sum_cur;
1.1 cgd 824:
1.64 elad 825: putchar('\n');
826: fflush(stdout);
827: line++;
1.98 msaitoh 828: if (signalled == 0)
1.64 elad 829: sigsuspend(&emptyset);
1.98 msaitoh 830:
1.64 elad 831: signalled = 0;
1.82 mrg 832: if (line == redraw_lines)
1.64 elad 833: goto banner;
834: goto loop;
835: /*NOTREACHED*/
836: }
1.1 cgd 837:
1.8 mycroft 838: static void
1.64 elad 839: sidewaysintpr_kvm(unsigned interval, u_long off)
1.1 cgd 840: {
1.57 ragge 841: struct itimerval it;
1.90 dholland 842: sigset_t emptyset;
843: sigset_t noalrm;
1.1 cgd 844: struct ifnet ifnet;
1.96 thorpej 845: struct if_data ifd;
1.7 cgd 846: u_long firstifnet;
1.25 lukem 847: struct iftot *ip, *total;
1.82 mrg 848: unsigned line;
1.1 cgd 849: struct iftot *lastif, *sum, *interesting;
1.15 thorpej 850: struct ifnet_head ifhead; /* TAILQ_HEAD */
1.100 msaitoh 851: int s;
1.1 cgd 852:
1.82 mrg 853: set_lines();
854:
1.15 thorpej 855: /*
856: * Find the pointer to the first ifnet structure. Replace
857: * the pointer to the TAILQ_HEAD with the actual pointer
858: * to the first list element.
859: */
860: if (kread(off, (char *)&ifhead, sizeof ifhead))
1.8 mycroft 861: return;
1.15 thorpej 862: firstifnet = (u_long)ifhead.tqh_first;
863:
1.100 msaitoh 864: if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
865: return;
866:
1.1 cgd 867: lastif = iftot;
868: sum = iftot + MAXIF - 1;
869: total = sum - 1;
1.17 cgd 870: interesting = (interface == NULL) ? iftot : NULL;
1.1 cgd 871: for (off = firstifnet, ip = iftot; off;) {
1.8 mycroft 872: if (kread(off, (char *)&ifnet, sizeof ifnet))
873: break;
1.25 lukem 874: memset(ip->ift_name, 0, sizeof(ip->ift_name));
1.31 mycroft 875: snprintf(ip->ift_name, IFNAMSIZ, "%s", ifnet.if_xname);
1.19 thorpej 876: if (interface && strcmp(ifnet.if_xname, interface) == 0)
1.1 cgd 877: interesting = ip;
878: ip++;
879: if (ip >= iftot + MAXIF - 2)
880: break;
1.10 mycroft 881: off = (u_long)ifnet.if_list.tqe_next;
1.17 cgd 882: }
883: if (interesting == NULL) {
884: fprintf(stderr, "%s: %s: unknown interface\n",
1.47 cgd 885: getprogname(), interface);
1.17 cgd 886: exit(1);
1.1 cgd 887: }
888: lastif = ip;
889:
1.90 dholland 890: sigemptyset(&emptyset);
891: sigemptyset(&noalrm);
892: sigaddset(&noalrm, SIGALRM);
893: sigprocmask(SIG_SETMASK, &noalrm, NULL);
894:
895: signalled = 0;
1.1 cgd 896: (void)signal(SIGALRM, catchalarm);
1.57 ragge 897:
898: it.it_interval.tv_sec = it.it_value.tv_sec = interval;
899: it.it_interval.tv_usec = it.it_value.tv_usec = 0;
900: setitimer(ITIMER_REAL, &it, NULL);
901:
1.1 cgd 902: banner:
1.31 mycroft 903: if (bflag)
904: printf("%7.7s in %8.8s %6.6s out %5.5s",
905: interesting->ift_name, " ",
906: interesting->ift_name, " ");
907: else
908: printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s",
909: interesting->ift_name, " ",
910: interesting->ift_name, " ", " ");
911: if (dflag)
912: printf(" %5.5s", " ");
1.1 cgd 913: if (lastif - iftot > 0) {
1.31 mycroft 914: if (bflag)
915: printf(" %7.7s in %8.8s %6.6s out %5.5s",
916: "total", " ", "total", " ");
917: else
918: printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s",
919: "total", " ", "total", " ", " ");
1.1 cgd 920: if (dflag)
1.31 mycroft 921: printf(" %5.5s", " ");
1.1 cgd 922: }
923: for (ip = iftot; ip < iftot + MAXIF; ip++) {
924: ip->ift_ip = 0;
1.26 kml 925: ip->ift_ib = 0;
1.1 cgd 926: ip->ift_ie = 0;
927: ip->ift_op = 0;
1.26 kml 928: ip->ift_ob = 0;
1.1 cgd 929: ip->ift_oe = 0;
930: ip->ift_co = 0;
1.101 msaitoh 931: ip->ift_iq = 0;
1.1 cgd 932: }
933: putchar('\n');
1.31 mycroft 934: if (bflag)
1.26 kml 935: printf("%10.10s %8.8s %10.10s %5.5s",
1.31 mycroft 936: "bytes", " ", "bytes", " ");
937: else
938: printf("%8.8s %5.5s %8.8s %5.5s %5.5s",
939: "packets", "errs", "packets", "errs", "colls");
1.1 cgd 940: if (dflag)
1.31 mycroft 941: printf(" %5.5s", "drops");
1.29 ross 942: if (lastif - iftot > 0) {
1.31 mycroft 943: if (bflag)
944: printf(" %10.10s %8.8s %10.10s %5.5s",
945: "bytes", " ", "bytes", " ");
946: else
947: printf(" %8.8s %5.5s %8.8s %5.5s %5.5s",
948: "packets", "errs", "packets", "errs", "colls");
949: if (dflag)
950: printf(" %5.5s", "drops");
1.29 ross 951: }
1.1 cgd 952: putchar('\n');
953: fflush(stdout);
954: line = 0;
955: loop:
956: sum->ift_ip = 0;
1.26 kml 957: sum->ift_ib = 0;
1.1 cgd 958: sum->ift_ie = 0;
959: sum->ift_op = 0;
1.26 kml 960: sum->ift_ob = 0;
1.1 cgd 961: sum->ift_oe = 0;
962: sum->ift_co = 0;
1.101 msaitoh 963: sum->ift_iq = 0;
1.1 cgd 964: for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) {
1.8 mycroft 965: if (kread(off, (char *)&ifnet, sizeof ifnet)) {
966: off = 0;
967: continue;
968: }
1.100 msaitoh 969: ifname_to_ifdata(s, ip->ift_name, &ifd);
1.1 cgd 970: if (ip == interesting) {
1.26 kml 971: if (bflag) {
1.68 pooka 972: char humbuf[HUMBUF_SIZE];
973:
974: if (hflag && humanize_number(humbuf,
975: sizeof(humbuf),
1.96 thorpej 976: ifd.ifi_ibytes - ip->ift_ib, "",
1.68 pooka 977: HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0)
978: printf("%10s %8.8s ", humbuf, " ");
979: else
1.98 msaitoh 980: printf("%10llu %8.8s ",
1.68 pooka 981: (unsigned long long)
1.96 thorpej 982: (ifd.ifi_ibytes-ip->ift_ib), " ");
1.68 pooka 983:
984: if (hflag && humanize_number(humbuf,
985: sizeof(humbuf),
1.96 thorpej 986: ifd.ifi_obytes - ip->ift_ob, "",
1.68 pooka 987: HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0)
988: printf("%10s %5.5s", humbuf, " ");
989: else
1.98 msaitoh 990: printf("%10llu %5.5s",
1.68 pooka 991: (unsigned long long)
1.96 thorpej 992: (ifd.ifi_obytes-ip->ift_ob), " ");
1.26 kml 993: } else {
1.33 bouyer 994: printf("%8llu %5llu %8llu %5llu %5llu",
995: (unsigned long long)
1.96 thorpej 996: (ifd.ifi_ipackets - ip->ift_ip),
1.33 bouyer 997: (unsigned long long)
1.96 thorpej 998: (ifd.ifi_ierrors - ip->ift_ie),
1.33 bouyer 999: (unsigned long long)
1.96 thorpej 1000: (ifd.ifi_opackets - ip->ift_op),
1.33 bouyer 1001: (unsigned long long)
1.96 thorpej 1002: (ifd.ifi_oerrors - ip->ift_oe),
1.33 bouyer 1003: (unsigned long long)
1.96 thorpej 1004: (ifd.ifi_collisions - ip->ift_co));
1.26 kml 1005: }
1.1 cgd 1006: if (dflag)
1.89 christos 1007: printf(" %5" PRIu64,
1.101 msaitoh 1008: ifnet.if_snd.ifq_drops - ip->ift_oq);
1.1 cgd 1009: }
1.96 thorpej 1010: ip->ift_ip = ifd.ifi_ipackets;
1011: ip->ift_ib = ifd.ifi_ibytes;
1012: ip->ift_ie = ifd.ifi_ierrors;
1013: ip->ift_op = ifd.ifi_opackets;
1014: ip->ift_ob = ifd.ifi_obytes;
1015: ip->ift_oe = ifd.ifi_oerrors;
1016: ip->ift_co = ifd.ifi_collisions;
1.101 msaitoh 1017: ip->ift_oq = ifnet.if_snd.ifq_drops;
1.1 cgd 1018: sum->ift_ip += ip->ift_ip;
1.26 kml 1019: sum->ift_ib += ip->ift_ib;
1.1 cgd 1020: sum->ift_ie += ip->ift_ie;
1021: sum->ift_op += ip->ift_op;
1.26 kml 1022: sum->ift_ob += ip->ift_ob;
1.1 cgd 1023: sum->ift_oe += ip->ift_oe;
1024: sum->ift_co += ip->ift_co;
1.101 msaitoh 1025: sum->ift_oq += ip->ift_oq;
1.10 mycroft 1026: off = (u_long)ifnet.if_list.tqe_next;
1.1 cgd 1027: }
1028: if (lastif - iftot > 0) {
1.26 kml 1029: if (bflag) {
1.68 pooka 1030: char humbuf[HUMBUF_SIZE];
1031:
1032: if (hflag && humanize_number(humbuf,
1033: sizeof(humbuf), sum->ift_ib - total->ift_ib, "",
1034: HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0)
1.69 enami 1035: printf(" %10s %8.8s ", humbuf, " ");
1.68 pooka 1036: else
1.98 msaitoh 1037: printf(" %10llu %8.8s ",
1.68 pooka 1038: (unsigned long long)
1039: (sum->ift_ib - total->ift_ib), " ");
1040:
1041: if (hflag && humanize_number(humbuf,
1042: sizeof(humbuf), sum->ift_ob - total->ift_ob, "",
1043: HN_AUTOSCALE, HN_NOSPACE | HN_B) > 0)
1044: printf("%10s %5.5s", humbuf, " ");
1045: else
1.98 msaitoh 1046: printf("%10llu %5.5s",
1.68 pooka 1047: (unsigned long long)
1048: (sum->ift_ob - total->ift_ob), " ");
1.26 kml 1049: } else {
1.33 bouyer 1050: printf(" %8llu %5llu %8llu %5llu %5llu",
1051: (unsigned long long)
1052: (sum->ift_ip - total->ift_ip),
1053: (unsigned long long)
1054: (sum->ift_ie - total->ift_ie),
1055: (unsigned long long)
1056: (sum->ift_op - total->ift_op),
1057: (unsigned long long)
1058: (sum->ift_oe - total->ift_oe),
1059: (unsigned long long)
1060: (sum->ift_co - total->ift_co));
1.26 kml 1061: }
1.1 cgd 1062: if (dflag)
1.33 bouyer 1063: printf(" %5llu",
1.101 msaitoh 1064: (unsigned long long)(sum->ift_oq - total->ift_oq));
1.1 cgd 1065: }
1066: *total = *sum;
1067: putchar('\n');
1068: fflush(stdout);
1069: line++;
1.98 msaitoh 1070: if (signalled == 0)
1.90 dholland 1071: sigsuspend(&emptyset);
1.98 msaitoh 1072:
1.90 dholland 1073: signalled = 0;
1.82 mrg 1074: if (line == redraw_lines)
1.1 cgd 1075: goto banner;
1076: goto loop;
1077: /*NOTREACHED*/
1078: }
1079:
1080: /*
1.64 elad 1081: * Print a running summary of interface statistics.
1082: * Repeat display every interval seconds, showing statistics
1083: * collected over that interval. Assumes that interval is non-zero.
1084: * First line printed at top of screen is always cumulative.
1085: */
1086: static void
1.74 matt 1087: sidewaysintpr(unsigned int interval, u_long off)
1.64 elad 1088: {
1089:
1.98 msaitoh 1090: if (use_sysctl)
1.64 elad 1091: sidewaysintpr_sysctl(interval);
1.98 msaitoh 1092: else
1.64 elad 1093: sidewaysintpr_kvm(interval, off);
1094: }
1095:
1096: /*
1.1 cgd 1097: * Called if an interval expires before sidewaysintpr has completed a loop.
1098: * Sets a flag to not wait for the alarm.
1099: */
1.8 mycroft 1100: static void
1.74 matt 1101: catchalarm(int signo)
1.1 cgd 1102: {
1.28 mrg 1103:
1.64 elad 1104: signalled = true;
1105: }
1106:
1107: static void
1108: get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
1.98 msaitoh 1109: {
1.64 elad 1110: int i;
1111:
1112: for (i = 0; i < RTAX_MAX; i++) {
1113: if (addrs & (1 << i)) {
1114: rti_info[i] = sa;
1.71 martin 1115: sa = (struct sockaddr *)((char *)(sa) +
1116: RT_ROUNDUP(sa->sa_len));
1.98 msaitoh 1117: } else
1.64 elad 1118: rti_info[i] = NULL;
1119: }
1120: }
1121:
1122: static void
1123: fetchifs(void)
1124: {
1125: struct if_msghdr *ifm;
1126: int mib[6] = { CTL_NET, AF_ROUTE, 0, 0, NET_RT_IFLIST, 0 };
1127: struct rt_msghdr *rtm;
1128: struct if_data *ifd = NULL;
1129: struct sockaddr *sa, *rti_info[RTAX_MAX];
1130: struct sockaddr_dl *sdl;
1.93 mrg 1131: static char *buf = NULL;
1132: static size_t olen;
1.101 msaitoh 1133: struct if_data_ext dext;
1.93 mrg 1134: char *next, *lim;
1.64 elad 1135: char name[IFNAMSIZ];
1136: size_t len;
1137:
1.70 pooka 1138: if (prog_sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
1.64 elad 1139: err(1, "sysctl");
1.93 mrg 1140: if (len > olen) {
1141: free(buf);
1142: if ((buf = malloc(len)) == NULL)
1143: err(1, NULL);
1144: olen = len;
1145: }
1.70 pooka 1146: if (prog_sysctl(mib, 6, buf, &len, NULL, 0) == -1)
1.64 elad 1147: err(1, "sysctl");
1148:
1.101 msaitoh 1149: memset(&dext, 0, sizeof(dext));
1.64 elad 1150: lim = buf + len;
1151: for (next = buf; next < lim; next += rtm->rtm_msglen) {
1152: rtm = (struct rt_msghdr *)next;
1153: if (rtm->rtm_version != RTM_VERSION)
1154: continue;
1155: switch (rtm->rtm_type) {
1156: case RTM_IFINFO:
1157: ifm = (struct if_msghdr *)next;
1158: ifd = &ifm->ifm_data;
1159:
1160: sa = (struct sockaddr *)(ifm + 1);
1161: get_rtaddrs(ifm->ifm_addrs, sa, rti_info);
1162:
1163: sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP];
1164: if (sdl == NULL || sdl->sdl_family != AF_LINK)
1165: continue;
1166: bzero(name, sizeof(name));
1167: if (sdl->sdl_nlen >= IFNAMSIZ)
1168: memcpy(name, sdl->sdl_data, IFNAMSIZ - 1);
1.98 msaitoh 1169: else if (sdl->sdl_nlen > 0)
1.64 elad 1170: memcpy(name, sdl->sdl_data, sdl->sdl_nlen);
1171:
1.101 msaitoh 1172: if_data_ext_get(name, &dext);
1173:
1.97 msaitoh 1174: if (interface != NULL && !strcmp(name, interface)) {
1.64 elad 1175: strlcpy(ip_cur.ift_name, name,
1176: sizeof(ip_cur.ift_name));
1177: ip_cur.ift_ip = ifd->ifi_ipackets;
1178: ip_cur.ift_ib = ifd->ifi_ibytes;
1179: ip_cur.ift_ie = ifd->ifi_ierrors;
1180: ip_cur.ift_op = ifd->ifi_opackets;
1181: ip_cur.ift_ob = ifd->ifi_obytes;
1182: ip_cur.ift_oe = ifd->ifi_oerrors;
1183: ip_cur.ift_co = ifd->ifi_collisions;
1.101 msaitoh 1184: ip_cur.ift_iq = ifd->ifi_iqdrops;
1185: ip_cur.ift_oq = ifd->ifi_iqdrops; /* XXX */
1.64 elad 1186: }
1187:
1188: sum_cur.ift_ip += ifd->ifi_ipackets;
1189: sum_cur.ift_ib += ifd->ifi_ibytes;
1190: sum_cur.ift_ie += ifd->ifi_ierrors;
1191: sum_cur.ift_op += ifd->ifi_opackets;
1192: sum_cur.ift_ob += ifd->ifi_obytes;
1193: sum_cur.ift_oe += ifd->ifi_oerrors;
1194: sum_cur.ift_co += ifd->ifi_collisions;
1.101 msaitoh 1195: sum_cur.ift_iq += ifd->ifi_iqdrops;
1196: sum_cur.ift_oq += dext.ifi_oqdrops;
1.64 elad 1197: break;
1198: }
1199: }
1200: if (interface == NULL) {
1201: strlcpy(ip_cur.ift_name, name,
1202: sizeof(ip_cur.ift_name));
1203: ip_cur.ift_ip = ifd->ifi_ipackets;
1204: ip_cur.ift_ib = ifd->ifi_ibytes;
1205: ip_cur.ift_ie = ifd->ifi_ierrors;
1206: ip_cur.ift_op = ifd->ifi_opackets;
1207: ip_cur.ift_ob = ifd->ifi_obytes;
1208: ip_cur.ift_oe = ifd->ifi_oerrors;
1209: ip_cur.ift_co = ifd->ifi_collisions;
1.101 msaitoh 1210: ip_cur.ift_iq = ifd->ifi_iqdrops;
1211: ip_cur.ift_oq = dext.ifi_oqdrops;
1.64 elad 1212: }
1.1 cgd 1213: }
CVSweb <webmaster@jp.NetBSD.org>