network_cmds-245.19.tar.gz
[apple/network_cmds.git] / netstat.tproj / if.c
CommitLineData
b7080c8e
A
1/*
2 * Copyright (c) 1983, 1988, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35/*
36static char sccsid[] = "@(#)if.c 8.3 (Berkeley) 4/28/95";
37*/
38static const char rcsid[] =
3a228055 39 "$Id: if.c,v 1.6.40.1 2006/01/10 05:26:27 lindak Exp $";
b7080c8e
A
40#endif /* not lint */
41
42#include <sys/types.h>
b7080c8e 43#include <sys/socket.h>
7ba0088d 44#include <sys/sysctl.h>
b7080c8e
A
45#include <sys/time.h>
46
47#include <net/if.h>
48#include <net/if_var.h>
49#include <net/if_dl.h>
50#include <net/if_types.h>
2b484d24 51#include <net/if_mib.h>
b7080c8e 52#include <net/ethernet.h>
2b484d24
A
53#include <net/route.h>
54
b7080c8e
A
55#include <netinet/in.h>
56#include <netinet/in_var.h>
57
58#ifdef IPX
59#include <netipx/ipx.h>
60#include <netipx/ipx_if.h>
61#endif
62
63#ifdef NS
64#include <netns/ns.h>
65#include <netns/ns_if.h>
66#endif
b7080c8e
A
67#include <arpa/inet.h>
68
69#include <signal.h>
70#include <stdio.h>
71#include <string.h>
72#include <unistd.h>
2b484d24
A
73#include <stdlib.h>
74#include <err.h>
b7080c8e
A
75
76#include "netstat.h"
77
78#define YES 1
79#define NO 0
80
2b484d24
A
81#define ROUNDUP(a, size) (((a) & ((size) - 1)) ? (1 + ((a)|(size - 1))) : (a))
82
83#define NEXT_SA(p) (struct sockaddr *) \
84 ((caddr_t)p + (p->sa_len ? ROUNDUP(p->sa_len, sizeof(u_long)) : \
85 sizeof(u_long)))
86
87static void sidewaysintpr ();
7ba0088d
A
88static void catchalarm (int);
89
90#ifdef INET6
2b484d24 91char *netname6 (struct sockaddr_in6 *, struct sockaddr *);
7ba0088d 92static char ntop_buf[INET6_ADDRSTRLEN]; /* for inet_ntop() */
7ba0088d
A
93#endif
94
95#if 0
2b484d24
A
96#ifdef INET6
97static int bdg_done;
98#endif
99
7ba0088d
A
100/* print bridge statistics */
101void
102bdg_stats(u_long dummy , char *name, int af )
103{
104 int i;
105 size_t slen ;
106 struct bdg_stats s ;
107 int mib[4] ;
108
109 slen = sizeof(s);
110
111 mib[0] = CTL_NET ;
112 mib[1] = PF_LINK ;
113 mib[2] = IFT_ETHER ;
114 if (sysctl(mib,4, &s,&slen,NULL,0)==-1)
115 return ; /* no bridging */
116#ifdef INET6
117 if (bdg_done != 0)
118 return;
119 else
120 bdg_done = 1;
121#endif
122 printf("-- Bridging statistics (%s) --\n", name) ;
123 printf(
124"Name In Out Forward Drop Bcast Mcast Local Unknown\n");
125 for (i = 0 ; i < 16 ; i++) {
126 if (s.s[i].name[0])
127 printf("%-6s %9ld%9ld%9ld%9ld%9ld%9ld%9ld%9ld\n",
128 s.s[i].name,
129 s.s[i].p_in[(int)BDG_IN],
130 s.s[i].p_in[(int)BDG_OUT],
131 s.s[i].p_in[(int)BDG_FORWARD],
132 s.s[i].p_in[(int)BDG_DROP],
133 s.s[i].p_in[(int)BDG_BCAST],
134 s.s[i].p_in[(int)BDG_MCAST],
135 s.s[i].p_in[(int)BDG_LOCAL],
136 s.s[i].p_in[(int)BDG_UNKNOWN] );
137 }
138}
139
140#endif
141
142
143/*
144 * Display a formatted value, or a '-' in the same space.
145 */
146static void
2b484d24 147show_stat(const char *fmt, int width, u_int64_t value, short showvalue)
7ba0088d
A
148{
149 char newfmt[32];
150
151 /* Construct the format string */
152 if (showvalue) {
153 sprintf(newfmt, "%%%d%s", width, fmt);
154 printf(newfmt, value);
155 } else {
156 sprintf(newfmt, "%%%ds", width);
157 printf(newfmt, "-");
158 }
159}
160
2b484d24
A
161size_t
162get_rti_info(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
163{
164 int i;
165 size_t len = 0;
166
167 for (i = 0; i < RTAX_MAX; i++) {
168 if (addrs & (1 << i)) {
169 rti_info[i] = sa;
170 if (sa->sa_len < sizeof(struct sockaddr))
171 len += sizeof(struct sockaddr);
172 else
173 len += sa->sa_len;
174 sa = NEXT_SA(sa);
175 } else {
176 rti_info[i] = NULL;
177 }
178 }
179 return len;
180}
7ba0088d 181
2b484d24
A
182static void
183multipr(int family, char *buf, char *lim)
184{
185 char *next;
186
187 for (next = buf; next < lim; ) {
188 struct ifma_msghdr2 *ifmam = (struct ifma_msghdr2 *)next;
189 struct sockaddr *rti_info[RTAX_MAX];
190 struct sockaddr *sa;
191 const char *fmt = 0;
192
193 next += ifmam->ifmam_msglen;
194 if (ifmam->ifmam_type == RTM_IFINFO2)
195 break;
196 else if (ifmam->ifmam_type != RTM_NEWMADDR2)
197 continue;
198 get_rti_info(ifmam->ifmam_addrs, (struct sockaddr*)(ifmam + 1), rti_info);
199 sa = rti_info[RTAX_IFA];
200
201 if (sa->sa_family != family)
202 continue;
203 switch (sa->sa_family) {
204 case AF_INET: {
205 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
206
207 fmt = routename(sin->sin_addr.s_addr);
208 break;
209 }
210 #ifdef INET6
211 case AF_INET6: {
212 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
213
214 printf("%23s %-19.19s(refs: %d)\n", "",
215 inet_ntop(AF_INET6,
216 &sin6->sin6_addr,
217 ntop_buf,
218 sizeof(ntop_buf)),
219 ifmam->ifmam_refcount);
220 break;
221 }
222 #endif /* INET6 */
223 case AF_LINK: {
224 struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
225
226 switch (sdl->sdl_type) {
227 case IFT_ETHER:
228 case IFT_FDDI:
229 fmt = ether_ntoa(
230 (struct ether_addr *)
231 LLADDR(sdl));
232 break;
233 }
234 break;
235 }
236 }
237 if (fmt)
238 printf("%23s %s\n", "", fmt);
239 }
240}
b7080c8e
A
241
242/*
243 * Print a description of the network interfaces.
244 */
245void
2b484d24 246intpr(void (*pfunc)(char *))
b7080c8e 247{
2b484d24
A
248 u_int64_t opackets = 0;
249 u_int64_t ipackets = 0;
250 u_int64_t obytes = 0;
251 u_int64_t ibytes = 0;
252 u_int64_t oerrors = 0;
253 u_int64_t ierrors = 0;
254 u_int64_t collisions = 0;
255 u_long mtu = 0;
256 short timer = 0;
257 int drops = 0;
7ba0088d 258 struct sockaddr *sa = NULL;
2b484d24 259 char name[32];
7ba0088d
A
260 short network_layer;
261 short link_layer;
2b484d24
A
262 int mib[6];
263 char *buf = NULL, *lim, *next;
264 size_t len;
265 struct if_msghdr *ifm;
266 struct sockaddr *rti_info[RTAX_MAX];
267 unsigned int ifindex = 0;
268
b7080c8e 269 if (interval) {
2b484d24 270 sidewaysintpr();
b7080c8e
A
271 return;
272 }
2b484d24
A
273
274 if (interface != 0)
275 ifindex = if_nametoindex(interface);
276
277 mib[0] = CTL_NET; // networking subsystem
278 mib[1] = PF_ROUTE; // type of information
279 mib[2] = 0; // protocol (IPPROTO_xxx)
280 mib[3] = 0; // address family
281 mib[4] = NET_RT_IFLIST2; // operation
282 mib[5] = 0;
283 if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
b7080c8e 284 return;
2b484d24
A
285 if ((buf = malloc(len)) == NULL) {
286 printf("malloc failed\n");
287 exit(1);
288 }
289 if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
290 if (buf)
291 free(buf);
b7080c8e 292 return;
2b484d24 293 }
7ba0088d
A
294 if (!pfunc) {
295 printf("%-5.5s %-5.5s %-13.13s %-15.15s %8.8s %5.5s",
296 "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs");
297 if (bflag)
298 printf(" %10.10s","Ibytes");
299 printf(" %8.8s %5.5s", "Opkts", "Oerrs");
300 if (bflag)
301 printf(" %10.10s","Obytes");
302 printf(" %5s", "Coll");
303 if (tflag)
304 printf(" %s", "Time");
305 if (dflag)
306 printf(" %s", "Drop");
307 putchar('\n');
308 }
2b484d24
A
309 lim = buf + len;
310 for (next = buf; next < lim; ) {
311 char *cp;
b7080c8e 312 int n, m;
2b484d24 313
7ba0088d
A
314 network_layer = 0;
315 link_layer = 0;
2b484d24
A
316 ifm = (struct if_msghdr *)next;
317 next += ifm->ifm_msglen;
318
319 if (ifm->ifm_type == RTM_IFINFO2) {
320 struct if_msghdr2 *if2m = (struct if_msghdr2 *)ifm;
321 struct sockaddr_dl *sdl = (struct sockaddr_dl *)(if2m + 1);
7ba0088d 322
2b484d24
A
323 strncpy(name, sdl->sdl_data, sdl->sdl_nlen);
324 name[sdl->sdl_nlen] = 0;
325 if (interface != 0 && if2m->ifm_index != ifindex)
b7080c8e
A
326 continue;
327 cp = index(name, '\0');
7ba0088d
A
328
329 if (pfunc) {
330 (*pfunc)(name);
331 continue;
332 }
333
2b484d24 334 if ((if2m->ifm_flags & IFF_UP) == 0)
b7080c8e
A
335 *cp++ = '*';
336 *cp = '\0';
2b484d24
A
337
338 /*
339 * Get the interface stats. These may get
340 * overriden below on a per-interface basis.
341 */
342 opackets = if2m->ifm_data.ifi_opackets;
343 ipackets = if2m->ifm_data.ifi_ipackets;
344 obytes = if2m->ifm_data.ifi_obytes;
345 ibytes = if2m->ifm_data.ifi_ibytes;
346 oerrors =if2m->ifm_data.ifi_oerrors;
347 ierrors = if2m->ifm_data.ifi_ierrors;
348 collisions = if2m->ifm_data.ifi_collisions;
349 timer = if2m->ifm_timer;
350 drops = if2m->ifm_snd_drops;
351 mtu = if2m->ifm_data.ifi_mtu;
352
353 get_rti_info(if2m->ifm_addrs, (struct sockaddr*)(if2m + 1), rti_info);
354 sa = rti_info[RTAX_IFP];
355 } else if (ifm->ifm_type == RTM_NEWADDR) {
356 struct ifa_msghdr *ifam = (struct ifa_msghdr *)ifm;
357
358 if (interface != 0 && ifam->ifam_index != ifindex)
359 continue;
360 get_rti_info(ifam->ifam_addrs, (struct sockaddr*)(ifam + 1), rti_info);
361 sa = rti_info[RTAX_IFA];
362 } else
363 continue;
364 printf("%-5.5s %-5lu ", name, mtu);
365
366 if (sa == 0) {
b7080c8e
A
367 printf("%-13.13s ", "none");
368 printf("%-15.15s ", "none");
369 } else {
b7080c8e
A
370 switch (sa->sa_family) {
371 case AF_UNSPEC:
372 printf("%-13.13s ", "none");
373 printf("%-15.15s ", "none");
374 break;
2b484d24
A
375 case AF_INET: {
376 struct sockaddr_in *sin = (struct sockaddr_in *)sa;
377 struct sockaddr_in mask;
378
379 mask.sin_addr.s_addr = 0;
380 memcpy(&mask, rti_info[RTAX_NETMASK], ((struct sockaddr_in *)rti_info[RTAX_NETMASK])->sin_len);
381
382 printf("%-13.13s ", netname(sin->sin_addr.s_addr & mask.sin_addr.s_addr,
3a228055 383 ntohl(mask.sin_addr.s_addr)));
2b484d24 384
b7080c8e
A
385 printf("%-15.15s ",
386 routename(sin->sin_addr.s_addr));
7ba0088d
A
387
388 network_layer = 1;
b7080c8e 389 break;
2b484d24 390 }
7ba0088d 391#ifdef INET6
2b484d24
A
392 case AF_INET6: {
393 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
394 struct sockaddr *mask = (struct sockaddr *)rti_info[RTAX_NETMASK];
395
7ba0088d 396 printf("%-11.11s ",
2b484d24
A
397 netname6(sin6,
398 mask));
7ba0088d
A
399 printf("%-17.17s ",
400 (char *)inet_ntop(AF_INET6,
401 &sin6->sin6_addr,
402 ntop_buf, sizeof(ntop_buf)));
b7080c8e 403
7ba0088d
A
404 network_layer = 1;
405 break;
2b484d24 406 }
7ba0088d 407#endif /*INET6*/
b7080c8e
A
408 case AF_LINK:
409 {
410 struct sockaddr_dl *sdl =
411 (struct sockaddr_dl *)sa;
7ba0088d
A
412 char linknum[10];
413 cp = (char *)LLADDR(sdl);
414 n = sdl->sdl_alen;
415 sprintf(linknum, "<Link#%d>", sdl->sdl_index);
416 m = printf("%-11.11s ", linknum);
b7080c8e 417 }
b7080c8e
A
418 goto hexprint;
419 default:
420 m = printf("(%d)", sa->sa_family);
421 for (cp = sa->sa_len + (char *)sa;
422 --cp > sa->sa_data && (*cp == 0);) {}
423 n = cp - sa->sa_data + 1;
424 cp = sa->sa_data;
425 hexprint:
426 while (--n >= 0)
427 m += printf("%02x%c", *cp++ & 0xff,
7ba0088d 428 n > 0 ? ':' : ' ');
b7080c8e
A
429 m = 30 - m;
430 while (m-- > 0)
431 putchar(' ');
7ba0088d
A
432
433 link_layer = 1;
b7080c8e
A
434 break;
435 }
7ba0088d
A
436#ifndef __APPLE__
437 /*
438 * Fixup the statistics for interfaces that
439 * update stats for their network addresses
440 */
441 if (network_layer) {
442 opackets = ifaddr.in.ia_ifa.if_opackets;
443 ipackets = ifaddr.in.ia_ifa.if_ipackets;
444 obytes = ifaddr.in.ia_ifa.if_obytes;
445 ibytes = ifaddr.in.ia_ifa.if_ibytes;
446 }
447#endif
7ba0088d
A
448 }
449
2b484d24 450 show_stat("llu", 8, ipackets, link_layer|network_layer);
7ba0088d 451 printf(" ");
2b484d24 452 show_stat("llu", 5, ierrors, link_layer);
7ba0088d
A
453 printf(" ");
454 if (bflag) {
2b484d24 455 show_stat("llu", 10, ibytes, link_layer|network_layer);
7ba0088d
A
456 printf(" ");
457 }
2b484d24 458 show_stat("llu", 8, opackets, link_layer|network_layer);
7ba0088d 459 printf(" ");
2b484d24 460 show_stat("llu", 5, oerrors, link_layer);
7ba0088d
A
461 printf(" ");
462 if (bflag) {
2b484d24 463 show_stat("llu", 10, obytes, link_layer|network_layer);
7ba0088d
A
464 printf(" ");
465 }
2b484d24 466 show_stat("llu", 5, collisions, link_layer);
7ba0088d
A
467 if (tflag) {
468 printf(" ");
2b484d24 469 show_stat("ll", 3, timer, link_layer);
7ba0088d
A
470 }
471 if (dflag) {
472 printf(" ");
2b484d24 473 show_stat("ll", 3, drops, link_layer);
b7080c8e 474 }
b7080c8e 475 putchar('\n');
2b484d24
A
476
477 if (aflag)
478 multipr(sa->sa_family, next, lim);
b7080c8e
A
479 }
480}
481
b7080c8e 482struct iftot {
7ba0088d 483 SLIST_ENTRY(iftot) chain;
2b484d24
A
484 char ift_name[16]; /* interface name */
485 u_int64_t ift_ip; /* input packets */
486 u_int64_t ift_ie; /* input errors */
487 u_int64_t ift_op; /* output packets */
488 u_int64_t ift_oe; /* output errors */
489 u_int64_t ift_co; /* collisions */
490 u_int64_t ift_dr; /* drops */
491 u_int64_t ift_ib; /* input bytes */
492 u_int64_t ift_ob; /* output bytes */
7ba0088d 493};
b7080c8e
A
494
495u_char signalled; /* set if alarm goes off "early" */
496
497/*
498 * Print a running summary of interface statistics.
499 * Repeat display every interval seconds, showing statistics
500 * collected over that interval. Assumes that interval is non-zero.
501 * First line printed at top of screen is always cumulative.
502 * XXX - should be rewritten to use ifmib(4).
503 */
504static void
2b484d24 505sidewaysintpr()
b7080c8e 506{
2b484d24 507 struct iftot *total, *sum, *interesting;
b7080c8e 508 register int line;
b7080c8e 509 int oldmask, first;
2b484d24
A
510 int name[6];
511 size_t len;
512 unsigned int ifcount, i;
513 struct ifmibdata *ifmdall = 0;
514 int interesting_row;
515
516 /* Common OID prefix */
517 name[0] = CTL_NET;
518 name[1] = PF_LINK;
519 name[2] = NETLINK_GENERIC;
520
521 len = sizeof(int);
522 name[3] = IFMIB_SYSTEM;
523 name[4] = IFMIB_IFCOUNT;
524 if (sysctl(name, 5, &ifcount, &len, 0, 0) == 1)
525 err(1, "sysctl IFMIB_IFCOUNT");
526
527 len = ifcount * sizeof(struct ifmibdata);
528 ifmdall = malloc(len);
529 if (ifmdall == 0)
530 err(1, "malloc failed");
531 name[3] = IFMIB_IFALLDATA;
532 name[4] = 0;
533 name[5] = IFDATA_GENERAL;
534 if (sysctl(name, 6, ifmdall, &len, (void *)0, 0) == -1)
535 err(1, "sysctl IFMIB_IFALLDATA");
536
b7080c8e 537 interesting = NULL;
2b484d24
A
538 interesting_row = 0;
539 for (i = 0; i < ifcount; i++) {
540 struct ifmibdata *ifmd = ifmdall + i;
541
542 if (interface && strcmp(ifmd->ifmd_name, interface) == 0) {
543 if ((interesting = calloc(ifcount, sizeof(struct iftot))) == NULL)
544 err(1, "malloc failed");
545 interesting_row = i + 1;
546 snprintf(interesting->ift_name, 16, "(%s)", ifmd->ifmd_name);;
7ba0088d 547 }
7ba0088d 548 }
2b484d24
A
549 if ((total = calloc(1, sizeof(struct iftot))) == NULL)
550 err(1, "malloc failed");
551
552 if ((sum = calloc(1, sizeof(struct iftot))) == NULL)
553 err(1, "malloc failed");
7ba0088d 554
b7080c8e
A
555
556 (void)signal(SIGALRM, catchalarm);
557 signalled = NO;
558 (void)alarm(interval);
b7080c8e
A
559 first = 1;
560banner:
561 printf("%17s %14s %16s", "input",
562 interesting ? interesting->ift_name : "(Total)", "output");
563 putchar('\n');
564 printf("%10s %5s %10s %10s %5s %10s %5s",
565 "packets", "errs", "bytes", "packets", "errs", "bytes", "colls");
566 if (dflag)
567 printf(" %5.5s", "drops");
568 putchar('\n');
569 fflush(stdout);
570 line = 0;
571loop:
572 if (interesting != NULL) {
2b484d24
A
573 struct ifmibdata ifmd;
574
575 len = sizeof(struct ifmibdata);
576 name[3] = IFMIB_IFDATA;
577 name[4] = interesting_row;
578 name[5] = IFDATA_GENERAL;
579 if (sysctl(name, 6, &ifmd, &len, (void *)0, 0) == -1)
580 err(1, "sysctl IFDATA_GENERAL %d", interesting_row);
581
b7080c8e 582 if (!first) {
2b484d24
A
583 printf("%10llu %5llu %10llu %10llu %5llu %10llu %5llu",
584 ifmd.ifmd_data.ifi_ipackets - interesting->ift_ip,
585 ifmd.ifmd_data.ifi_ierrors - interesting->ift_ie,
586 ifmd.ifmd_data.ifi_ibytes - interesting->ift_ib,
587 ifmd.ifmd_data.ifi_opackets - interesting->ift_op,
588 ifmd.ifmd_data.ifi_oerrors - interesting->ift_oe,
589 ifmd.ifmd_data.ifi_obytes - interesting->ift_ob,
590 ifmd.ifmd_data.ifi_collisions - interesting->ift_co);
b7080c8e 591 if (dflag)
2b484d24 592 printf(" %5llu", ifmd.ifmd_snd_drops - interesting->ift_dr);
b7080c8e 593 }
2b484d24
A
594 interesting->ift_ip = ifmd.ifmd_data.ifi_ipackets;
595 interesting->ift_ie = ifmd.ifmd_data.ifi_ierrors;
596 interesting->ift_ib = ifmd.ifmd_data.ifi_ibytes;
597 interesting->ift_op = ifmd.ifmd_data.ifi_opackets;
598 interesting->ift_oe = ifmd.ifmd_data.ifi_oerrors;
599 interesting->ift_ob = ifmd.ifmd_data.ifi_obytes;
600 interesting->ift_co = ifmd.ifmd_data.ifi_collisions;
601 interesting->ift_dr = ifmd.ifmd_snd_drops;
b7080c8e 602 } else {
2b484d24
A
603 unsigned int latest_ifcount;
604
605 len = sizeof(int);
606 name[3] = IFMIB_SYSTEM;
607 name[4] = IFMIB_IFCOUNT;
608 if (sysctl(name, 5, &latest_ifcount, &len, 0, 0) == 1)
609 err(1, "sysctl IFMIB_IFCOUNT");
610 if (latest_ifcount > ifcount) {
611 ifcount = latest_ifcount;
612 len = ifcount * sizeof(struct ifmibdata);
613 free(ifmdall);
614 ifmdall = malloc(len);
615 if (ifmdall == 0)
616 err(1, "malloc failed");
617 } else if (latest_ifcount > ifcount) {
618 ifcount = latest_ifcount;
619 len = ifcount * sizeof(struct ifmibdata);
620 }
621 len = ifcount * sizeof(struct ifmibdata);
622 name[3] = IFMIB_IFALLDATA;
623 name[4] = 0;
624 name[5] = IFDATA_GENERAL;
625 if (sysctl(name, 6, ifmdall, &len, (void *)0, 0) == -1)
626 err(1, "sysctl IFMIB_IFALLDATA");
627
b7080c8e
A
628 sum->ift_ip = 0;
629 sum->ift_ie = 0;
630 sum->ift_ib = 0;
631 sum->ift_op = 0;
632 sum->ift_oe = 0;
633 sum->ift_ob = 0;
634 sum->ift_co = 0;
635 sum->ift_dr = 0;
2b484d24
A
636 for (i = 0; i < ifcount; i++) {
637 struct ifmibdata *ifmd = ifmdall + i;
638
639 sum->ift_ip += ifmd->ifmd_data.ifi_ipackets;
640 sum->ift_ie += ifmd->ifmd_data.ifi_ierrors;
641 sum->ift_ib += ifmd->ifmd_data.ifi_ibytes;
642 sum->ift_op += ifmd->ifmd_data.ifi_opackets;
643 sum->ift_oe += ifmd->ifmd_data.ifi_oerrors;
644 sum->ift_ob += ifmd->ifmd_data.ifi_obytes;
645 sum->ift_co += ifmd->ifmd_data.ifi_collisions;
646 sum->ift_dr += ifmd->ifmd_snd_drops;
b7080c8e
A
647 }
648 if (!first) {
2b484d24 649 printf("%10llu %5llu %10llu %10llu %5llu %10llu %5llu",
b7080c8e
A
650 sum->ift_ip - total->ift_ip,
651 sum->ift_ie - total->ift_ie,
652 sum->ift_ib - total->ift_ib,
653 sum->ift_op - total->ift_op,
654 sum->ift_oe - total->ift_oe,
655 sum->ift_ob - total->ift_ob,
656 sum->ift_co - total->ift_co);
657 if (dflag)
2b484d24 658 printf(" %5llu", sum->ift_dr - total->ift_dr);
b7080c8e
A
659 }
660 *total = *sum;
661 }
662 if (!first)
663 putchar('\n');
664 fflush(stdout);
665 oldmask = sigblock(sigmask(SIGALRM));
666 if (! signalled) {
667 sigpause(0);
668 }
669 sigsetmask(oldmask);
670 signalled = NO;
671 (void)alarm(interval);
672 line++;
673 first = 0;
674 if (line == 21)
675 goto banner;
676 else
677 goto loop;
678 /*NOTREACHED*/
679}
680
681/*
682 * Called if an interval expires before sidewaysintpr has completed a loop.
683 * Sets a flag to not wait for the alarm.
684 */
685static void
7ba0088d 686catchalarm(int signo )
b7080c8e
A
687{
688 signalled = YES;
689}