1 /* $NetBSD: if.c,v 1.82 2015/09/20 00:30:04 mrg Exp $ */
4 * Copyright (c) 1983, 1988, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
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
32 #include <sys/cdefs.h>
35 static char sccsid
[] = "from: @(#)if.c 8.2 (Berkeley) 2/21/94";
37 __RCSID("$NetBSD: if.c,v 1.82 2015/09/20 00:30:04 mrg Exp $");
41 #include <sys/param.h>
42 #include <sys/types.h>
43 #include <sys/protosw.h>
44 #include <sys/socket.h>
46 #include <sys/sysctl.h>
47 #include <sys/ioctl.h>
50 #include <net/if_dl.h>
51 #include <net/if_types.h>
52 #include <net/route.h>
53 #include <netinet/in.h>
54 #include <netinet/in_var.h>
55 #include <arpa/inet.h>
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 */
79 u_quad_t ift_op
; /* output packets */
80 u_quad_t ift_ob
; /* output bytes */
81 u_quad_t ift_oe
; /* output errors */
82 u_quad_t ift_co
; /* collisions */
83 int ift_dr
; /* drops */
86 static void set_lines(void);
87 static void print_addr(struct sockaddr
*, struct sockaddr
**, struct if_data
*,
89 static void sidewaysintpr(u_int
, u_long
);
91 static void iftot_banner(struct iftot
*);
92 static void iftot_print_sum(struct iftot
*, struct iftot
*);
93 static void iftot_print(struct iftot
*, struct iftot
*);
95 static void catchalarm
__P((int));
96 static void get_rtaddrs(int, struct sockaddr
*, struct sockaddr
**);
97 static void fetchifs(void);
99 static void intpr_sysctl(void);
100 static void intpr_kvm(u_long
, void (*)(const char *));
102 struct iftot iftot
[MAXIF
], ip_cur
, ip_old
, sum_cur
, sum_old
;
103 bool signalled
; /* set if alarm goes off "early" */
105 static unsigned redraw_lines
= 21;
110 static bool first
= true;
116 if (ioctl(STDOUT_FILENO
, TIOCGSIZE
, &ts
) != -1 && ts
.ts_lines
)
117 redraw_lines
= ts
.ts_lines
- 3;
122 * Print a description of the network interfaces.
123 * NOTE: ifnetaddr is the location of the kernel global "ifnet",
124 * which is a TAILQ_HEAD.
127 intpr(int interval
, u_long ifnetaddr
, void (*pfunc
)(const char *))
131 sidewaysintpr((unsigned)interval
, ifnetaddr
);
138 intpr_kvm(ifnetaddr
, pfunc
);
147 if (!sflag
& !pflag
) {
149 printf("%-5.5s %-5.5s %-13.13s %-17.17s "
151 "Name", "Mtu", "Network", "Address",
154 printf("%-5.5s %-5.5s %-13.13s %-17.17s "
155 "%8.8s %5.5s %8.8s %5.5s %5.5s",
156 "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs",
157 "Opkts", "Oerrs", "Colls");
160 printf(" %4.4s", "Time");
162 printf(" %5.5s", "Drops");
170 struct if_msghdr
*ifm
;
171 int mib
[6] = { CTL_NET
, AF_ROUTE
, 0, 0, NET_RT_IFLIST
, 0 };
172 char *buf
= NULL
, *next
, *lim
, *cp
;
173 struct rt_msghdr
*rtm
;
174 struct ifa_msghdr
*ifam
;
175 struct if_data
*ifd
= NULL
;
176 struct sockaddr
*sa
, *rti_info
[RTAX_MAX
];
177 struct sockaddr_dl
*sdl
;
180 char name
[IFNAMSIZ
+ 1]; /* + 1 for `*' */
182 if (prog_sysctl(mib
, 6, NULL
, &len
, NULL
, 0) == -1)
184 if ((buf
= malloc(len
)) == NULL
)
186 if (prog_sysctl(mib
, 6, buf
, &len
, NULL
, 0) == -1)
192 for (next
= buf
; next
< lim
; next
+= rtm
->rtm_msglen
) {
193 rtm
= (struct rt_msghdr
*)next
;
194 if (rtm
->rtm_version
!= RTM_VERSION
)
196 switch (rtm
->rtm_type
) {
199 ifm
= (struct if_msghdr
*)next
;
200 ifd
= &ifm
->ifm_data
;
202 sa
= (struct sockaddr
*)(ifm
+ 1);
203 get_rtaddrs(ifm
->ifm_addrs
, sa
, rti_info
);
205 sdl
= (struct sockaddr_dl
*)rti_info
[RTAX_IFP
];
206 if (sdl
== NULL
|| sdl
->sdl_family
!= AF_LINK
) {
209 bzero(name
, sizeof(name
));
210 if (sdl
->sdl_nlen
>= IFNAMSIZ
)
211 memcpy(name
, sdl
->sdl_data
, IFNAMSIZ
- 1);
212 else if (sdl
->sdl_nlen
> 0)
213 memcpy(name
, sdl
->sdl_data
, sdl
->sdl_nlen
);
215 if (interface
!= 0 && strcmp(name
, interface
) != 0)
218 /* mark inactive interfaces with a '*' */
219 cp
= strchr(name
, '\0');
220 if ((ifm
->ifm_flags
& IFF_UP
) == 0)
225 total
= ifd
->ifi_ibytes
+ ifd
->ifi_obytes
+
226 ifd
->ifi_ipackets
+ ifd
->ifi_ierrors
+
227 ifd
->ifi_opackets
+ ifd
->ifi_oerrors
+
230 total
+= 0; // XXX-elad ifnet.if_timer;
232 total
+= 0; // XXX-elad ifnet.if_snd.ifq_drops;
237 printf("%-5s %-5" PRIu64
, name
, ifd
->ifi_mtu
);
239 /* There should be a space between Mtu and Network. */
242 print_addr(rti_info
[RTAX_IFP
], rti_info
, ifd
, NULL
);
246 if (qflag
&& total
== 0)
248 if (interface
!= 0 && strcmp(name
, interface
) != 0)
250 ifam
= (struct ifa_msghdr
*)next
;
251 if ((ifam
->ifam_addrs
& (RTA_NETMASK
| RTA_IFA
|
255 sa
= (struct sockaddr
*)(ifam
+ 1);
257 get_rtaddrs(ifam
->ifam_addrs
, sa
, rti_info
);
259 printf("%-5s %-5" PRIu64
, name
, ifd
->ifi_mtu
);
262 * There should be a space between Mtu and Network.
263 * Maintainer's note: this has been fixed in NetBSD
264 * upstream already; drop this change as soon as it
265 * creates any conflict at all! --dcvmoole
269 print_addr(rti_info
[RTAX_IFA
], rti_info
, ifd
, NULL
);
279 struct in6_ifaddr in6
;
284 intpr_kvm(u_long ifnetaddr
, void (*pfunc
)(const char *))
287 union ifaddr_u ifaddr
;
289 struct ifnet_head ifhead
; /* TAILQ_HEAD */
290 char name
[IFNAMSIZ
+ 1]; /* + 1 for `*' */
292 if (ifnetaddr
== 0) {
293 printf("ifnet: symbol not defined\n");
298 * Find the pointer to the first ifnet structure. Replace
299 * the pointer to the TAILQ_HEAD with the actual pointer
300 * to the first list element.
302 if (kread(ifnetaddr
, (char *)&ifhead
, sizeof ifhead
))
304 ifnetaddr
= (u_long
)ifhead
.tqh_first
;
309 while (ifnetaddr
|| ifaddraddr
) {
313 if (ifaddraddr
== 0) {
314 if (kread(ifnetaddr
, (char *)&ifnet
, sizeof ifnet
))
316 memmove(name
, ifnet
.if_xname
, IFNAMSIZ
);
317 name
[IFNAMSIZ
- 1] = '\0'; /* sanity */
318 ifnetaddr
= (u_long
)ifnet
.if_list
.tqe_next
;
319 if (interface
!= 0 && strcmp(name
, interface
) != 0)
321 cp
= strchr(name
, '\0');
328 if ((ifnet
.if_flags
& IFF_UP
) == 0)
331 ifaddraddr
= (u_long
)ifnet
.if_addrlist
.tqh_first
;
334 n
= strlen(name
) < 5 ? 5 : strlen(name
);
337 printf("%-*.*s %-5llu ", n
, n
, name
,
338 (unsigned long long)ifnet
.if_mtu
);
339 if (ifaddraddr
== 0) {
340 printf("%-13.13s ", "none");
341 printf("%-17.17s ", "none");
345 if (kread(ifaddraddr
, (char *)&ifaddr
, sizeof ifaddr
)) {
349 #define CP(x) ((char *)(x))
350 cp
= (CP(ifaddr
.ifa
.ifa_addr
) - CP(ifaddraddr
)) +
352 sa
= (struct sockaddr
*)cp
;
353 print_addr(sa
, (void *)&ifaddr
, &ifnet
.if_data
, &ifnet
);
355 ifaddraddr
= (u_long
)ifaddr
.ifa
.ifa_list
.tqe_next
;
361 print_addr(struct sockaddr
*sa
, struct sockaddr
**rtinfo
, struct if_data
*ifd
,
364 char hexsep
= '.'; /* for hexprint */
365 static const char hexfmt
[] = "%02x%c"; /* for hexprint */
366 char hbuf
[NI_MAXHOST
]; /* for getnameinfo() */
368 const int niflag
= NI_NUMERICHOST
;
369 struct sockaddr_in6
*sin6
, *netmask6
;
371 struct sockaddr_in netmask
;
372 struct sockaddr_in
*sin
;
376 switch (sa
->sa_family
) {
378 printf("%-13.13s ", "none");
379 printf("%-17.17s ", "none");
382 sin
= (struct sockaddr_in
*)sa
;
384 netmask
= *((struct sockaddr_in
*)rtinfo
[RTAX_NETMASK
]);
386 struct in_ifaddr
*ifaddr_in
= (void *)rtinfo
;
387 netmask
.sin_addr
.s_addr
= ifaddr_in
->ia_subnetmask
;
389 cp
= netname4(sin
, &netmask
, nflag
);
391 n
= strlen(cp
) < 13 ? 13 : strlen(cp
);
394 printf("%-*.*s ", n
, n
, cp
);
395 cp
= routename4(sin
->sin_addr
.s_addr
, nflag
);
397 n
= strlen(cp
) < 17 ? 17 : strlen(cp
);
400 printf("%-*.*s ", n
, n
, cp
);
402 if (aflag
&& ifnet
) {
405 union ifaddr_u
*ifaddr
= (union ifaddr_u
*)rtinfo
;
408 ifaddr
->in
.ia_multiaddrs
.lh_first
;
409 while (multiaddr
!= 0) {
410 kread(multiaddr
, (char *)&inm
,
412 printf("\n%25s %-17.17s ", "",
414 inm
.inm_addr
.s_addr
, nflag
));
416 (u_long
)inm
.inm_list
.le_next
;
422 sin6
= (struct sockaddr_in6
*)sa
;
423 inet6_getscopeid(sin6
, INET6_IS_ADDR_LINKLOCAL
);
426 sin6
->sin6_scope_id
= 0;
430 netmask6
= (struct sockaddr_in6
*)rtinfo
[RTAX_NETMASK
];
432 struct in6_ifaddr
*ifaddr_in6
= (void *)rtinfo
;
433 netmask6
= &ifaddr_in6
->ia_prefixmask
;
436 cp
= netname6(sin6
, netmask6
, nflag
);
438 n
= strlen(cp
) < 13 ? 13 : strlen(cp
);
441 printf("%-*.*s ", n
, n
, cp
);
442 if (getnameinfo((struct sockaddr
*)sin6
,
444 hbuf
, sizeof(hbuf
), NULL
, 0,
446 strlcpy(hbuf
, "?", sizeof(hbuf
));
450 n
= strlen(cp
) < 17 ? 17 : strlen(cp
);
453 printf("%-*.*s ", n
, n
, cp
);
455 if (aflag
&& ifnet
) {
457 struct in6_multi inm
;
458 struct sockaddr_in6 as6
;
459 union ifaddr_u
*ifaddr
= (union ifaddr_u
*)rtinfo
;
462 ifaddr
->in6
.ia6_multiaddrs
.lh_first
;
463 while (multiaddr
!= 0) {
464 kread(multiaddr
, (char *)&inm
,
466 memset(&as6
, 0, sizeof(as6
));
467 as6
.sin6_len
= sizeof(struct sockaddr_in6
);
468 as6
.sin6_family
= AF_INET6
;
469 as6
.sin6_addr
= inm
.in6m_addr
;
470 inet6_getscopeid(&as6
,
471 INET6_IS_ADDR_MC_LINKLOCAL
);
472 if (getnameinfo((struct sockaddr
*)&as6
,
474 sizeof(hbuf
), NULL
, 0,
485 printf("\n%25s %-*.*s ", "",
488 (u_long
)inm
.in6m_entry
.le_next
;
495 printf("atalk:%-7.7s ",
496 atalk_print(sa
,0x10));
497 printf("%-17.17s ", atalk_print(sa
,0x0b));
501 printf("%-13.13s ", "<Link>");
502 if (getnameinfo(sa
, sa
->sa_len
,
503 hbuf
, sizeof(hbuf
), NULL
, 0,
504 NI_NUMERICHOST
) != 0) {
505 strlcpy(hbuf
, "?", sizeof(hbuf
));
509 n
= strlen(cp
) < 17 ? 17 : strlen(cp
);
512 printf("%-*.*s ", n
, n
, cp
);
516 m
= printf("(%d)", sa
->sa_family
);
517 for (cp
= sa
->sa_len
+ (char *)sa
;
518 --cp
> sa
->sa_data
&& (*cp
== 0);) {}
519 n
= cp
- sa
->sa_data
+ 1;
523 m
+= printf(hexfmt
, *cp
++ & 0xff,
524 n
> 0 ? hexsep
: ' ');
532 char humbuf
[HUMBUF_SIZE
];
534 if (hflag
&& humanize_number(humbuf
, sizeof(humbuf
),
535 ifd
->ifi_ibytes
, "", HN_AUTOSCALE
, HN_NOSPACE
| HN_B
) > 0)
536 printf("%10s ", humbuf
);
538 printf("%10llu ", (unsigned long long)ifd
->ifi_ibytes
);
540 if (hflag
&& humanize_number(humbuf
, sizeof(humbuf
),
541 ifd
->ifi_obytes
, "", HN_AUTOSCALE
, HN_NOSPACE
| HN_B
) > 0)
542 printf("%10s", humbuf
);
544 printf("%10llu", (unsigned long long)ifd
->ifi_obytes
);
546 printf("%8llu %5llu %8llu %5llu %5llu",
547 (unsigned long long)ifd
->ifi_ipackets
,
548 (unsigned long long)ifd
->ifi_ierrors
,
549 (unsigned long long)ifd
->ifi_opackets
,
550 (unsigned long long)ifd
->ifi_oerrors
,
551 (unsigned long long)ifd
->ifi_collisions
);
554 printf(" %4d", ifnet
? ifnet
->if_timer
: 0);
556 printf(" %5d", ifnet
? ifnet
->if_snd
.ifq_drops
: 0);
561 iftot_banner(struct iftot
*ift
)
564 printf("%7.7s in %8.8s %6.6s out %5.5s",
568 printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s",
570 ift
->ift_name
, " ", " ");
572 printf(" %5.5s", " ");
575 printf(" %7.7s in %8.8s %6.6s out %5.5s",
576 "total", " ", "total", " ");
578 printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s",
579 "total", " ", "total", " ", " ");
581 printf(" %5.5s", " ");
584 printf("%10.10s %8.8s %10.10s %5.5s",
585 "bytes", " ", "bytes", " ");
587 printf("%8.8s %5.5s %8.8s %5.5s %5.5s",
588 "packets", "errs", "packets", "errs", "colls");
590 printf(" %5.5s", "drops");
593 printf(" %10.10s %8.8s %10.10s %5.5s",
594 "bytes", " ", "bytes", " ");
596 printf(" %8.8s %5.5s %8.8s %5.5s %5.5s",
597 "packets", "errs", "packets", "errs", "colls");
599 printf(" %5.5s", "drops");
605 iftot_print(struct iftot
*cur
, struct iftot
*old
)
608 printf("%10" PRIu64
" %8.8s %10" PRIu64
" %5.5s",
609 cur
->ift_ib
- old
->ift_ib
, " ",
610 cur
->ift_ob
- old
->ift_ob
, " ");
612 printf("%8" PRIu64
" %5" PRIu64
" %8" PRIu64
" %5" PRIu64
" %5" PRIu64
,
613 cur
->ift_ip
- old
->ift_ip
,
614 cur
->ift_ie
- old
->ift_ie
,
615 cur
->ift_op
- old
->ift_op
,
616 cur
->ift_oe
- old
->ift_oe
,
617 cur
->ift_co
- old
->ift_co
);
620 /* XXX ifnet.if_snd.ifq_drops - ip->ift_dr); */
625 iftot_print_sum(struct iftot
*cur
, struct iftot
*old
)
628 printf(" %10" PRIu64
" %8.8s %10" PRIu64
" %5.5s",
629 cur
->ift_ib
- old
->ift_ib
, " ",
630 cur
->ift_ob
- old
->ift_ob
, " ");
632 printf(" %8" PRIu64
" %5" PRIu64
" %8" PRIu64
" %5" PRIu64
" %5" PRIu64
,
633 cur
->ift_ip
- old
->ift_ip
,
634 cur
->ift_ie
- old
->ift_ie
,
635 cur
->ift_op
- old
->ift_op
,
636 cur
->ift_oe
- old
->ift_oe
,
637 cur
->ift_co
- old
->ift_co
);
640 printf(" %5llu", (unsigned long long)(cur
->ift_dr
- old
->ift_dr
));
644 sidewaysintpr_sysctl(unsigned interval
)
652 if (ip_cur
.ift_name
[0] == '\0') {
653 fprintf(stderr
, "%s: %s: unknown interface\n",
654 getprogname(), interface
);
658 (void)signal(SIGALRM
, catchalarm
);
660 (void)alarm(interval
);
662 iftot_banner(&ip_cur
);
665 bzero(&ip_old
, sizeof(ip_old
));
666 bzero(&sum_old
, sizeof(sum_old
));
668 bzero(&sum_cur
, sizeof(sum_cur
));
672 iftot_print(&ip_cur
, &ip_old
);
676 iftot_print_sum(&sum_cur
, &sum_old
);
683 sigemptyset(&emptyset
);
685 sigsuspend(&emptyset
);
687 (void)alarm(interval
);
688 if (line
== redraw_lines
)
695 sidewaysintpr_kvm(unsigned interval
, u_long off
)
700 struct iftot
*ip
, *total
;
702 struct iftot
*lastif
, *sum
, *interesting
;
703 struct ifnet_head ifhead
; /* TAILQ_HEAD */
709 * Find the pointer to the first ifnet structure. Replace
710 * the pointer to the TAILQ_HEAD with the actual pointer
711 * to the first list element.
713 if (kread(off
, (char *)&ifhead
, sizeof ifhead
))
715 firstifnet
= (u_long
)ifhead
.tqh_first
;
718 sum
= iftot
+ MAXIF
- 1;
720 interesting
= (interface
== NULL
) ? iftot
: NULL
;
721 for (off
= firstifnet
, ip
= iftot
; off
;) {
722 if (kread(off
, (char *)&ifnet
, sizeof ifnet
))
724 memset(ip
->ift_name
, 0, sizeof(ip
->ift_name
));
725 snprintf(ip
->ift_name
, IFNAMSIZ
, "%s", ifnet
.if_xname
);
726 if (interface
&& strcmp(ifnet
.if_xname
, interface
) == 0)
729 if (ip
>= iftot
+ MAXIF
- 2)
731 off
= (u_long
)ifnet
.if_list
.tqe_next
;
733 if (interesting
== NULL
) {
734 fprintf(stderr
, "%s: %s: unknown interface\n",
735 getprogname(), interface
);
740 (void)signal(SIGALRM
, catchalarm
);
743 it
.it_interval
.tv_sec
= it
.it_value
.tv_sec
= interval
;
744 it
.it_interval
.tv_usec
= it
.it_value
.tv_usec
= 0;
745 setitimer(ITIMER_REAL
, &it
, NULL
);
749 printf("%7.7s in %8.8s %6.6s out %5.5s",
750 interesting
->ift_name
, " ",
751 interesting
->ift_name
, " ");
753 printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s",
754 interesting
->ift_name
, " ",
755 interesting
->ift_name
, " ", " ");
757 printf(" %5.5s", " ");
758 if (lastif
- iftot
> 0) {
760 printf(" %7.7s in %8.8s %6.6s out %5.5s",
761 "total", " ", "total", " ");
763 printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s",
764 "total", " ", "total", " ", " ");
766 printf(" %5.5s", " ");
768 for (ip
= iftot
; ip
< iftot
+ MAXIF
; ip
++) {
780 printf("%10.10s %8.8s %10.10s %5.5s",
781 "bytes", " ", "bytes", " ");
783 printf("%8.8s %5.5s %8.8s %5.5s %5.5s",
784 "packets", "errs", "packets", "errs", "colls");
786 printf(" %5.5s", "drops");
787 if (lastif
- iftot
> 0) {
789 printf(" %10.10s %8.8s %10.10s %5.5s",
790 "bytes", " ", "bytes", " ");
792 printf(" %8.8s %5.5s %8.8s %5.5s %5.5s",
793 "packets", "errs", "packets", "errs", "colls");
795 printf(" %5.5s", "drops");
809 for (off
= firstifnet
, ip
= iftot
; off
&& ip
< lastif
; ip
++) {
810 if (kread(off
, (char *)&ifnet
, sizeof ifnet
)) {
814 if (ip
== interesting
) {
816 char humbuf
[HUMBUF_SIZE
];
818 if (hflag
&& humanize_number(humbuf
,
820 ifnet
.if_ibytes
- ip
->ift_ib
, "",
821 HN_AUTOSCALE
, HN_NOSPACE
| HN_B
) > 0)
822 printf("%10s %8.8s ", humbuf
, " ");
824 printf("%10llu %8.8s ",
826 (ifnet
.if_ibytes
-ip
->ift_ib
), " ");
828 if (hflag
&& humanize_number(humbuf
,
830 ifnet
.if_obytes
- ip
->ift_ob
, "",
831 HN_AUTOSCALE
, HN_NOSPACE
| HN_B
) > 0)
832 printf("%10s %5.5s", humbuf
, " ");
834 printf("%10llu %5.5s",
836 (ifnet
.if_obytes
-ip
->ift_ob
), " ");
838 printf("%8llu %5llu %8llu %5llu %5llu",
840 (ifnet
.if_ipackets
- ip
->ift_ip
),
842 (ifnet
.if_ierrors
- ip
->ift_ie
),
844 (ifnet
.if_opackets
- ip
->ift_op
),
846 (ifnet
.if_oerrors
- ip
->ift_oe
),
848 (ifnet
.if_collisions
- ip
->ift_co
));
853 (ifnet
.if_snd
.ifq_drops
- ip
->ift_dr
));
855 ip
->ift_ip
= ifnet
.if_ipackets
;
856 ip
->ift_ib
= ifnet
.if_ibytes
;
857 ip
->ift_ie
= ifnet
.if_ierrors
;
858 ip
->ift_op
= ifnet
.if_opackets
;
859 ip
->ift_ob
= ifnet
.if_obytes
;
860 ip
->ift_oe
= ifnet
.if_oerrors
;
861 ip
->ift_co
= ifnet
.if_collisions
;
862 ip
->ift_dr
= ifnet
.if_snd
.ifq_drops
;
863 sum
->ift_ip
+= ip
->ift_ip
;
864 sum
->ift_ib
+= ip
->ift_ib
;
865 sum
->ift_ie
+= ip
->ift_ie
;
866 sum
->ift_op
+= ip
->ift_op
;
867 sum
->ift_ob
+= ip
->ift_ob
;
868 sum
->ift_oe
+= ip
->ift_oe
;
869 sum
->ift_co
+= ip
->ift_co
;
870 sum
->ift_dr
+= ip
->ift_dr
;
871 off
= (u_long
)ifnet
.if_list
.tqe_next
;
873 if (lastif
- iftot
> 0) {
875 char humbuf
[HUMBUF_SIZE
];
877 if (hflag
&& humanize_number(humbuf
,
878 sizeof(humbuf
), sum
->ift_ib
- total
->ift_ib
, "",
879 HN_AUTOSCALE
, HN_NOSPACE
| HN_B
) > 0)
880 printf(" %10s %8.8s ", humbuf
, " ");
882 printf(" %10llu %8.8s ",
884 (sum
->ift_ib
- total
->ift_ib
), " ");
886 if (hflag
&& humanize_number(humbuf
,
887 sizeof(humbuf
), sum
->ift_ob
- total
->ift_ob
, "",
888 HN_AUTOSCALE
, HN_NOSPACE
| HN_B
) > 0)
889 printf("%10s %5.5s", humbuf
, " ");
891 printf("%10llu %5.5s",
893 (sum
->ift_ob
- total
->ift_ob
), " ");
895 printf(" %8llu %5llu %8llu %5llu %5llu",
897 (sum
->ift_ip
- total
->ift_ip
),
899 (sum
->ift_ie
- total
->ift_ie
),
901 (sum
->ift_op
- total
->ift_op
),
903 (sum
->ift_oe
- total
->ift_oe
),
905 (sum
->ift_co
- total
->ift_co
));
909 (unsigned long long)(sum
->ift_dr
- total
->ift_dr
));
915 oldmask
= sigblock(sigmask(SIGALRM
));
921 if (line
== redraw_lines
)
928 * Print a running summary of interface statistics.
929 * Repeat display every interval seconds, showing statistics
930 * collected over that interval. Assumes that interval is non-zero.
931 * First line printed at top of screen is always cumulative.
934 sidewaysintpr(unsigned int interval
, u_long off
)
938 sidewaysintpr_sysctl(interval
);
940 sidewaysintpr_kvm(interval
, off
);
945 * Called if an interval expires before sidewaysintpr has completed a loop.
946 * Sets a flag to not wait for the alarm.
949 catchalarm(int signo
)
956 get_rtaddrs(int addrs
, struct sockaddr
*sa
, struct sockaddr
**rti_info
)
960 for (i
= 0; i
< RTAX_MAX
; i
++) {
961 if (addrs
& (1 << i
)) {
963 sa
= (struct sockaddr
*)((char *)(sa
) +
964 RT_ROUNDUP(sa
->sa_len
));
973 struct if_msghdr
*ifm
;
974 int mib
[6] = { CTL_NET
, AF_ROUTE
, 0, 0, NET_RT_IFLIST
, 0 };
975 struct rt_msghdr
*rtm
;
976 struct if_data
*ifd
= NULL
;
977 struct sockaddr
*sa
, *rti_info
[RTAX_MAX
];
978 struct sockaddr_dl
*sdl
;
979 char *buf
, *next
, *lim
;
983 if (prog_sysctl(mib
, 6, NULL
, &len
, NULL
, 0) == -1)
985 if ((buf
= malloc(len
)) == NULL
)
987 if (prog_sysctl(mib
, 6, buf
, &len
, NULL
, 0) == -1)
991 for (next
= buf
; next
< lim
; next
+= rtm
->rtm_msglen
) {
992 rtm
= (struct rt_msghdr
*)next
;
993 if (rtm
->rtm_version
!= RTM_VERSION
)
995 switch (rtm
->rtm_type
) {
997 ifm
= (struct if_msghdr
*)next
;
998 ifd
= &ifm
->ifm_data
;
1000 sa
= (struct sockaddr
*)(ifm
+ 1);
1001 get_rtaddrs(ifm
->ifm_addrs
, sa
, rti_info
);
1003 sdl
= (struct sockaddr_dl
*)rti_info
[RTAX_IFP
];
1004 if (sdl
== NULL
|| sdl
->sdl_family
!= AF_LINK
)
1006 bzero(name
, sizeof(name
));
1007 if (sdl
->sdl_nlen
>= IFNAMSIZ
)
1008 memcpy(name
, sdl
->sdl_data
, IFNAMSIZ
- 1);
1009 else if (sdl
->sdl_nlen
> 0)
1010 memcpy(name
, sdl
->sdl_data
, sdl
->sdl_nlen
);
1012 if (interface
!= 0 && !strcmp(name
, interface
)) {
1013 strlcpy(ip_cur
.ift_name
, name
,
1014 sizeof(ip_cur
.ift_name
));
1015 ip_cur
.ift_ip
= ifd
->ifi_ipackets
;
1016 ip_cur
.ift_ib
= ifd
->ifi_ibytes
;
1017 ip_cur
.ift_ie
= ifd
->ifi_ierrors
;
1018 ip_cur
.ift_op
= ifd
->ifi_opackets
;
1019 ip_cur
.ift_ob
= ifd
->ifi_obytes
;
1020 ip_cur
.ift_oe
= ifd
->ifi_oerrors
;
1021 ip_cur
.ift_co
= ifd
->ifi_collisions
;
1023 /* XXX-elad ifnet.if_snd.ifq_drops */
1026 sum_cur
.ift_ip
+= ifd
->ifi_ipackets
;
1027 sum_cur
.ift_ib
+= ifd
->ifi_ibytes
;
1028 sum_cur
.ift_ie
+= ifd
->ifi_ierrors
;
1029 sum_cur
.ift_op
+= ifd
->ifi_opackets
;
1030 sum_cur
.ift_ob
+= ifd
->ifi_obytes
;
1031 sum_cur
.ift_oe
+= ifd
->ifi_oerrors
;
1032 sum_cur
.ift_co
+= ifd
->ifi_collisions
;
1033 sum_cur
.ift_dr
+= 0; /* XXX-elad ifnet.if_snd.ifq_drops */
1037 if (interface
== NULL
) {
1038 strlcpy(ip_cur
.ift_name
, name
,
1039 sizeof(ip_cur
.ift_name
));
1040 ip_cur
.ift_ip
= ifd
->ifi_ipackets
;
1041 ip_cur
.ift_ib
= ifd
->ifi_ibytes
;
1042 ip_cur
.ift_ie
= ifd
->ifi_ierrors
;
1043 ip_cur
.ift_op
= ifd
->ifi_opackets
;
1044 ip_cur
.ift_ob
= ifd
->ifi_obytes
;
1045 ip_cur
.ift_oe
= ifd
->ifi_oerrors
;
1046 ip_cur
.ift_co
= ifd
->ifi_collisions
;
1048 /* XXX-elad ifnet.if_snd.ifq_drops */