1 /* $NetBSD: if.c,v 1.66 2009/09/13 21:46:23 pgoyette 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.66 2009/09/13 21:46:23 pgoyette 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>
49 #include <net/if_dl.h>
50 #include <net/if_types.h>
51 #include <net/route.h>
52 #include <netinet/in.h>
53 #include <netinet/in_var.h>
54 #include <netiso/iso.h>
55 #include <netiso/iso_var.h>
56 #include <arpa/inet.h>
72 char ift_name
[IFNAMSIZ
]; /* interface name */
73 u_quad_t ift_ip
; /* input packets */
74 u_quad_t ift_ib
; /* input bytes */
75 u_quad_t ift_ie
; /* input errors */
76 u_quad_t ift_op
; /* output packets */
77 u_quad_t ift_ob
; /* output bytes */
78 u_quad_t ift_oe
; /* output errors */
79 u_quad_t ift_co
; /* collisions */
80 int ift_dr
; /* drops */
83 static void print_addr(struct sockaddr
*, struct sockaddr
**, struct if_data
*);
84 static void sidewaysintpr(u_int
, u_long
);
86 static void iftot_banner(struct iftot
*);
87 static void iftot_print_sum(struct iftot
*, struct iftot
*);
88 static void iftot_print(struct iftot
*, struct iftot
*);
90 static void catchalarm
__P((int));
91 static void get_rtaddrs(int, struct sockaddr
*, struct sockaddr
**);
92 static void fetchifs(void);
94 static void intpr_sysctl(void);
95 static void intpr_kvm(u_long
, void (*)(const char *));
97 struct iftot iftot
[MAXIF
], ip_cur
, ip_old
, sum_cur
, sum_old
;
98 bool signalled
; /* set if alarm goes off "early" */
101 * Print a description of the network interfaces.
102 * NOTE: ifnetaddr is the location of the kernel global "ifnet",
103 * which is a TAILQ_HEAD.
106 intpr(interval
, ifnetaddr
, pfunc
)
109 void (*pfunc
)(const char *);
113 sidewaysintpr((unsigned)interval
, ifnetaddr
);
120 intpr_kvm(ifnetaddr
, pfunc
);
129 if (!sflag
& !pflag
) {
131 printf("%-5.5s %-5.5s %-13.13s %-17.17s "
133 "Name", "Mtu", "Network", "Address",
136 printf("%-5.5s %-5.5s %-13.13s %-17.17s "
137 "%8.8s %5.5s %8.8s %5.5s %5.5s",
138 "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs",
139 "Opkts", "Oerrs", "Colls");
142 printf(" %4.4s", "Time");
144 printf(" %5.5s", "Drops");
152 struct if_msghdr
*ifm
;
153 int mib
[6] = { CTL_NET
, AF_ROUTE
, 0, 0, NET_RT_IFLIST
, 0 };
154 char *buf
= NULL
, *next
, *lim
, *cp
;
155 struct rt_msghdr
*rtm
;
156 struct ifa_msghdr
*ifam
;
157 struct if_data
*ifd
= NULL
;
158 struct sockaddr
*sa
, *rti_info
[RTAX_MAX
];
159 struct sockaddr_dl
*sdl
;
162 char name
[IFNAMSIZ
+ 1]; /* + 1 for `*' */
164 if (sysctl(mib
, 6, NULL
, &len
, NULL
, 0) == -1)
166 if ((buf
= malloc(len
)) == NULL
)
168 if (sysctl(mib
, 6, buf
, &len
, NULL
, 0) == -1)
174 for (next
= buf
; next
< lim
; next
+= rtm
->rtm_msglen
) {
175 rtm
= (struct rt_msghdr
*)next
;
176 if (rtm
->rtm_version
!= RTM_VERSION
)
178 switch (rtm
->rtm_type
) {
181 ifm
= (struct if_msghdr
*)next
;
182 ifd
= &ifm
->ifm_data
;
184 sa
= (struct sockaddr
*)(ifm
+ 1);
185 get_rtaddrs(ifm
->ifm_addrs
, sa
, rti_info
);
187 sdl
= (struct sockaddr_dl
*)rti_info
[RTAX_IFP
];
188 if (sdl
== NULL
|| sdl
->sdl_family
!= AF_LINK
) {
191 bzero(name
, sizeof(name
));
192 if (sdl
->sdl_nlen
>= IFNAMSIZ
)
193 memcpy(name
, sdl
->sdl_data
, IFNAMSIZ
- 1);
194 else if (sdl
->sdl_nlen
> 0)
195 memcpy(name
, sdl
->sdl_data
, sdl
->sdl_nlen
);
197 if (interface
!= 0 && strcmp(name
, interface
) != 0)
200 /* mark inactive interfaces with a '*' */
201 cp
= strchr(name
, '\0');
202 if ((ifm
->ifm_flags
& IFF_UP
) == 0)
207 total
= ifd
->ifi_ibytes
+ ifd
->ifi_obytes
+
208 ifd
->ifi_ipackets
+ ifd
->ifi_ierrors
+
209 ifd
->ifi_opackets
+ ifd
->ifi_oerrors
+
212 total
+= 0; // XXX-elad ifnet.if_timer;
214 total
+= 0; // XXX-elad ifnet.if_snd.ifq_drops;
219 printf("%-5s %-5" PRIu64
, name
, ifd
->ifi_mtu
);
220 print_addr(rti_info
[RTAX_IFP
], rti_info
, ifd
);
224 if (qflag
&& total
== 0)
226 if (interface
!= 0 && strcmp(name
, interface
) != 0)
228 ifam
= (struct ifa_msghdr
*)next
;
229 if ((ifam
->ifam_addrs
& (RTA_NETMASK
| RTA_IFA
|
233 sa
= (struct sockaddr
*)(ifam
+ 1);
235 get_rtaddrs(ifam
->ifam_addrs
, sa
, rti_info
);
237 printf("%-5s %-5" PRIu64
, name
, ifd
->ifi_mtu
);
238 print_addr(rti_info
[RTAX_IFA
], rti_info
, ifd
);
245 intpr_kvm(u_long ifnetaddr
, void (*pfunc
)(const char *))
252 struct in6_ifaddr in6
;
254 struct iso_ifaddr iso
;
257 struct ifnet_head ifhead
; /* TAILQ_HEAD */
258 char name
[IFNAMSIZ
+ 1]; /* + 1 for `*' */
260 if (ifnetaddr
== 0) {
261 printf("ifnet: symbol not defined\n");
266 * Find the pointer to the first ifnet structure. Replace
267 * the pointer to the TAILQ_HEAD with the actual pointer
268 * to the first list element.
270 if (kread(ifnetaddr
, (char *)&ifhead
, sizeof ifhead
))
272 ifnetaddr
= (u_long
)ifhead
.tqh_first
;
277 while (ifnetaddr
|| ifaddraddr
) {
281 if (ifaddraddr
== 0) {
282 if (kread(ifnetaddr
, (char *)&ifnet
, sizeof ifnet
))
284 memmove(name
, ifnet
.if_xname
, IFNAMSIZ
);
285 name
[IFNAMSIZ
- 1] = '\0'; /* sanity */
286 ifnetaddr
= (u_long
)ifnet
.if_list
.tqe_next
;
287 if (interface
!= 0 && strcmp(name
, interface
) != 0)
289 cp
= strchr(name
, '\0');
296 if ((ifnet
.if_flags
& IFF_UP
) == 0)
299 ifaddraddr
= (u_long
)ifnet
.if_addrlist
.tqh_first
;
302 n
= strlen(name
) < 5 ? 5 : strlen(name
);
305 printf("%-*.*s %-5llu ", n
, n
, name
,
306 (unsigned long long)ifnet
.if_mtu
);
307 if (ifaddraddr
== 0) {
308 printf("%-13.13s ", "none");
309 printf("%-17.17s ", "none");
313 if (kread(ifaddraddr
, (char *)&ifaddr
, sizeof ifaddr
)) {
317 #define CP(x) ((char *)(x))
318 cp
= (CP(ifaddr
.ifa
.ifa_addr
) - CP(ifaddraddr
)) +
320 sa
= (struct sockaddr
*)cp
;
321 print_addr(sa
, (void *)&ifaddr
, &ifnet
.if_data
);
323 ifaddraddr
= (u_long
)ifaddr
.ifa
.ifa_list
.tqe_next
;
329 print_addr(struct sockaddr
*sa
, struct sockaddr
**rtinfo
, struct if_data
*ifd
)
331 char hexsep
= '.'; /* for hexprint */
332 static const char hexfmt
[] = "%02x%c"; /* for hexprint */
333 char hbuf
[NI_MAXHOST
]; /* for getnameinfo() */
335 const int niflag
= NI_NUMERICHOST
;
336 struct sockaddr_in6
*sin6
, *netmask6
;
339 struct sockaddr_in
*sin
;
343 switch (sa
->sa_family
) {
345 printf("%-13.13s ", "none");
346 printf("%-17.17s ", "none");
349 sin
= (struct sockaddr_in
*)sa
;
352 * can't use inet_makeaddr because kernel
353 * keeps nets unshifted.
355 in
= inet_makeaddr(ifaddr
.in
.ia_subnet
,
357 cp
= netname4(in
.s_addr
,
358 ifaddr
.in
.ia_subnetmask
);
361 netmask
= ((struct sockaddr_in
*)rtinfo
[RTAX_NETMASK
])->sin_addr
.s_addr
;
363 struct in_ifaddr
*ifaddr_in
= (void *)rtinfo
;
364 netmask
= ifaddr_in
->ia_subnetmask
;
366 cp
= netname4(sin
->sin_addr
.s_addr
, netmask
);
369 n
= strlen(cp
) < 13 ? 13 : strlen(cp
);
372 printf("%-*.*s ", n
, n
, cp
);
373 cp
= routename4(sin
->sin_addr
.s_addr
);
375 n
= strlen(cp
) < 17 ? 17 : strlen(cp
);
378 printf("%-*.*s ", n
, n
, cp
);
386 ifaddr
.in
.ia_multiaddrs
.lh_first
;
387 while (multiaddr
!= 0) {
388 kread(multiaddr
, (char *)&inm
,
390 printf("\n%25s %-17.17s ", "",
392 inm
.inm_addr
.s_addr
));
394 (u_long
)inm
.inm_list
.le_next
;
401 sin6
= (struct sockaddr_in6
*)sa
;
403 if (IN6_IS_ADDR_LINKLOCAL(&sin6
->sin6_addr
)) {
404 sin6
->sin6_scope_id
=
406 &sin6
->sin6_addr
.s6_addr
[2]);
407 /* too little width */
409 sin6
->sin6_scope_id
= 0;
410 sin6
->sin6_addr
.s6_addr
[2] = 0;
411 sin6
->sin6_addr
.s6_addr
[3] = 0;
416 netmask6
= (struct sockaddr_in6
*)rtinfo
[RTAX_NETMASK
];
418 struct in6_ifaddr
*ifaddr_in6
= (void *)rtinfo
;
419 netmask6
= &ifaddr_in6
->ia_prefixmask
;
422 cp
= netname6(sin6
, netmask6
);
424 n
= strlen(cp
) < 13 ? 13 : strlen(cp
);
427 printf("%-*.*s ", n
, n
, cp
);
428 if (getnameinfo((struct sockaddr
*)sin6
,
430 hbuf
, sizeof(hbuf
), NULL
, 0,
432 strlcpy(hbuf
, "?", sizeof(hbuf
));
436 n
= strlen(cp
) < 17 ? 17 : strlen(cp
);
439 printf("%-*.*s ", n
, n
, cp
);
444 struct in6_multi inm
;
445 struct sockaddr_in6 as6
;
448 ifaddr
.in6
.ia6_multiaddrs
.lh_first
;
449 while (multiaddr
!= 0) {
450 kread(multiaddr
, (char *)&inm
,
452 memset(&as6
, 0, sizeof(as6
));
453 as6
.sin6_len
= sizeof(struct sockaddr_in6
);
454 as6
.sin6_family
= AF_INET6
;
455 as6
.sin6_addr
= inm
.in6m_addr
;
457 if (IN6_IS_ADDR_MC_LINKLOCAL(&as6
.sin6_addr
)) {
460 &as6
.sin6_addr
.s6_addr
[2]);
461 as6
.sin6_addr
.s6_addr
[2] = 0;
462 as6
.sin6_addr
.s6_addr
[3] = 0;
465 if (getnameinfo((struct sockaddr
*)&as6
,
467 sizeof(hbuf
), NULL
, 0,
478 printf("\n%25s %-*.*s ", "",
481 (u_long
)inm
.in6m_entry
.le_next
;
489 printf("atalk:%-7.7s ",
490 atalk_print(sa
,0x10));
491 printf("%-17.17s ", atalk_print(sa
,0x0b));
495 printf("%-13.13s ", "<Link>");
496 if (getnameinfo(sa
, sa
->sa_len
,
497 hbuf
, sizeof(hbuf
), NULL
, 0,
498 NI_NUMERICHOST
) != 0) {
499 strlcpy(hbuf
, "?", sizeof(hbuf
));
503 n
= strlen(cp
) < 17 ? 17 : strlen(cp
);
506 printf("%-*.*s ", n
, n
, cp
);
510 m
= printf("(%d)", sa
->sa_family
);
511 for (cp
= sa
->sa_len
+ (char *)sa
;
512 --cp
> sa
->sa_data
&& (*cp
== 0);) {}
513 n
= cp
- sa
->sa_data
+ 1;
517 m
+= printf(hexfmt
, *cp
++ & 0xff,
518 n
> 0 ? hexsep
: ' ');
526 printf("%10llu %10llu",
527 (unsigned long long)ifd
->ifi_ibytes
,
528 (unsigned long long)ifd
->ifi_obytes
);
530 printf("%8llu %5llu %8llu %5llu %5llu",
531 (unsigned long long)ifd
->ifi_ipackets
,
532 (unsigned long long)ifd
->ifi_ierrors
,
533 (unsigned long long)ifd
->ifi_opackets
,
534 (unsigned long long)ifd
->ifi_oerrors
,
535 (unsigned long long)ifd
->ifi_collisions
);
538 printf(" %4d", 0 /* XXX-elad ifnet.if_timer */);
540 printf(" %5d", 0 /* XXX-elad ifnet.if_snd.ifq_drops */);
545 iftot_banner(struct iftot
*ift
)
548 printf("%7.7s in %8.8s %6.6s out %5.5s",
552 printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s",
554 ift
->ift_name
, " ", " ");
556 printf(" %5.5s", " ");
559 printf(" %7.7s in %8.8s %6.6s out %5.5s",
560 "total", " ", "total", " ");
562 printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s",
563 "total", " ", "total", " ", " ");
565 printf(" %5.5s", " ");
568 printf("%10.10s %8.8s %10.10s %5.5s",
569 "bytes", " ", "bytes", " ");
571 printf("%8.8s %5.5s %8.8s %5.5s %5.5s",
572 "packets", "errs", "packets", "errs", "colls");
574 printf(" %5.5s", "drops");
577 printf(" %10.10s %8.8s %10.10s %5.5s",
578 "bytes", " ", "bytes", " ");
580 printf(" %8.8s %5.5s %8.8s %5.5s %5.5s",
581 "packets", "errs", "packets", "errs", "colls");
583 printf(" %5.5s", "drops");
589 iftot_print(struct iftot
*cur
, struct iftot
*old
)
592 printf("%10" PRIu64
"%8.8s %10" PRIu64
"%5.5s",
593 cur
->ift_ib
- old
->ift_ib
, " ",
594 cur
->ift_ob
- old
->ift_ob
, " ");
596 printf("%8" PRIu64
"%5" PRIu64
"%8" PRIu64
"%5" PRIu64
"%5" PRIu64
,
597 cur
->ift_ip
- old
->ift_ip
,
598 cur
->ift_ie
- old
->ift_ie
,
599 cur
->ift_op
- old
->ift_op
,
600 cur
->ift_oe
- old
->ift_oe
,
601 cur
->ift_co
- old
->ift_co
);
604 /* XXX ifnet.if_snd.ifq_drops - ip->ift_dr); */
609 iftot_print_sum(struct iftot
*cur
, struct iftot
*old
)
612 printf(" %10" PRIu64
"%8.8s %10" PRIu64
"%5.5s",
613 cur
->ift_ib
- old
->ift_ib
, " ",
614 cur
->ift_ob
- old
->ift_ob
, " ");
616 printf(" %8" PRIu64
"%5" PRIu64
"%8" PRIu64
"%5" PRIu64
"%5" PRIu64
,
617 cur
->ift_ip
- old
->ift_ip
,
618 cur
->ift_ie
- old
->ift_ie
,
619 cur
->ift_op
- old
->ift_op
,
620 cur
->ift_oe
- old
->ift_oe
,
621 cur
->ift_co
- old
->ift_co
);
624 printf(" %5llu", (unsigned long long)(cur
->ift_dr
- old
->ift_dr
));
628 sidewaysintpr_sysctl(unsigned interval
)
634 if (ip_cur
.ift_name
[0] == '\0') {
635 fprintf(stderr
, "%s: %s: unknown interface\n",
636 getprogname(), interface
);
640 (void)signal(SIGALRM
, catchalarm
);
642 (void)alarm(interval
);
644 iftot_banner(&ip_cur
);
647 bzero(&ip_old
, sizeof(ip_old
));
648 bzero(&sum_old
, sizeof(sum_old
));
650 bzero(&sum_cur
, sizeof(sum_cur
));
654 iftot_print(&ip_cur
, &ip_old
);
658 iftot_print_sum(&sum_cur
, &sum_old
);
665 sigemptyset(&emptyset
);
667 sigsuspend(&emptyset
);
669 (void)alarm(interval
);
677 sidewaysintpr_kvm(unsigned interval
, u_long off
)
682 struct iftot
*ip
, *total
;
684 struct iftot
*lastif
, *sum
, *interesting
;
685 struct ifnet_head ifhead
; /* TAILQ_HEAD */
689 * Find the pointer to the first ifnet structure. Replace
690 * the pointer to the TAILQ_HEAD with the actual pointer
691 * to the first list element.
693 if (kread(off
, (char *)&ifhead
, sizeof ifhead
))
695 firstifnet
= (u_long
)ifhead
.tqh_first
;
698 sum
= iftot
+ MAXIF
- 1;
700 interesting
= (interface
== NULL
) ? iftot
: NULL
;
701 for (off
= firstifnet
, ip
= iftot
; off
;) {
702 if (kread(off
, (char *)&ifnet
, sizeof ifnet
))
704 memset(ip
->ift_name
, 0, sizeof(ip
->ift_name
));
705 snprintf(ip
->ift_name
, IFNAMSIZ
, "%s", ifnet
.if_xname
);
706 if (interface
&& strcmp(ifnet
.if_xname
, interface
) == 0)
709 if (ip
>= iftot
+ MAXIF
- 2)
711 off
= (u_long
)ifnet
.if_list
.tqe_next
;
713 if (interesting
== NULL
) {
714 fprintf(stderr
, "%s: %s: unknown interface\n",
715 getprogname(), interface
);
720 (void)signal(SIGALRM
, catchalarm
);
723 it
.it_interval
.tv_sec
= it
.it_value
.tv_sec
= interval
;
724 it
.it_interval
.tv_usec
= it
.it_value
.tv_usec
= 0;
725 setitimer(ITIMER_REAL
, &it
, NULL
);
729 printf("%7.7s in %8.8s %6.6s out %5.5s",
730 interesting
->ift_name
, " ",
731 interesting
->ift_name
, " ");
733 printf("%5.5s in %5.5s%5.5s out %5.5s %5.5s",
734 interesting
->ift_name
, " ",
735 interesting
->ift_name
, " ", " ");
737 printf(" %5.5s", " ");
738 if (lastif
- iftot
> 0) {
740 printf(" %7.7s in %8.8s %6.6s out %5.5s",
741 "total", " ", "total", " ");
743 printf(" %5.5s in %5.5s%5.5s out %5.5s %5.5s",
744 "total", " ", "total", " ", " ");
746 printf(" %5.5s", " ");
748 for (ip
= iftot
; ip
< iftot
+ MAXIF
; ip
++) {
760 printf("%10.10s %8.8s %10.10s %5.5s",
761 "bytes", " ", "bytes", " ");
763 printf("%8.8s %5.5s %8.8s %5.5s %5.5s",
764 "packets", "errs", "packets", "errs", "colls");
766 printf(" %5.5s", "drops");
767 if (lastif
- iftot
> 0) {
769 printf(" %10.10s %8.8s %10.10s %5.5s",
770 "bytes", " ", "bytes", " ");
772 printf(" %8.8s %5.5s %8.8s %5.5s %5.5s",
773 "packets", "errs", "packets", "errs", "colls");
775 printf(" %5.5s", "drops");
789 for (off
= firstifnet
, ip
= iftot
; off
&& ip
< lastif
; ip
++) {
790 if (kread(off
, (char *)&ifnet
, sizeof ifnet
)) {
794 if (ip
== interesting
) {
796 printf("%10llu %8.8s %10llu %5.5s",
797 (unsigned long long)(ifnet
.if_ibytes
-
799 (unsigned long long)(ifnet
.if_obytes
-
802 printf("%8llu %5llu %8llu %5llu %5llu",
804 (ifnet
.if_ipackets
- ip
->ift_ip
),
806 (ifnet
.if_ierrors
- ip
->ift_ie
),
808 (ifnet
.if_opackets
- ip
->ift_op
),
810 (ifnet
.if_oerrors
- ip
->ift_oe
),
812 (ifnet
.if_collisions
- ip
->ift_co
));
817 (ifnet
.if_snd
.ifq_drops
- ip
->ift_dr
));
819 ip
->ift_ip
= ifnet
.if_ipackets
;
820 ip
->ift_ib
= ifnet
.if_ibytes
;
821 ip
->ift_ie
= ifnet
.if_ierrors
;
822 ip
->ift_op
= ifnet
.if_opackets
;
823 ip
->ift_ob
= ifnet
.if_obytes
;
824 ip
->ift_oe
= ifnet
.if_oerrors
;
825 ip
->ift_co
= ifnet
.if_collisions
;
826 ip
->ift_dr
= ifnet
.if_snd
.ifq_drops
;
827 sum
->ift_ip
+= ip
->ift_ip
;
828 sum
->ift_ib
+= ip
->ift_ib
;
829 sum
->ift_ie
+= ip
->ift_ie
;
830 sum
->ift_op
+= ip
->ift_op
;
831 sum
->ift_ob
+= ip
->ift_ob
;
832 sum
->ift_oe
+= ip
->ift_oe
;
833 sum
->ift_co
+= ip
->ift_co
;
834 sum
->ift_dr
+= ip
->ift_dr
;
835 off
= (u_long
)ifnet
.if_list
.tqe_next
;
837 if (lastif
- iftot
> 0) {
839 printf(" %10llu %8.8s %10llu %5.5s",
841 (sum
->ift_ib
- total
->ift_ib
), " ",
843 (sum
->ift_ob
- total
->ift_ob
), " ");
845 printf(" %8llu %5llu %8llu %5llu %5llu",
847 (sum
->ift_ip
- total
->ift_ip
),
849 (sum
->ift_ie
- total
->ift_ie
),
851 (sum
->ift_op
- total
->ift_op
),
853 (sum
->ift_oe
- total
->ift_oe
),
855 (sum
->ift_co
- total
->ift_co
));
859 (unsigned long long)(sum
->ift_dr
- total
->ift_dr
));
865 oldmask
= sigblock(sigmask(SIGALRM
));
878 * Print a running summary of interface statistics.
879 * Repeat display every interval seconds, showing statistics
880 * collected over that interval. Assumes that interval is non-zero.
881 * First line printed at top of screen is always cumulative.
884 sidewaysintpr(interval
, off
)
890 sidewaysintpr_sysctl(interval
);
892 sidewaysintpr_kvm(interval
, off
);
897 * Called if an interval expires before sidewaysintpr has completed a loop.
898 * Sets a flag to not wait for the alarm.
908 #define ROUNDUP(a, size) \
909 (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
911 #define NEXT_SA(ap) (ap) = (struct sockaddr *) \
912 ((caddr_t)(ap) + ((ap)->sa_len ? ROUNDUP((ap)->sa_len,\
913 sizeof(u_long)) : sizeof(u_long)))
916 get_rtaddrs(int addrs
, struct sockaddr
*sa
, struct sockaddr
**rti_info
)
920 for (i
= 0; i
< RTAX_MAX
; i
++) {
921 if (addrs
& (1 << i
)) {
924 /* sa = (struct sockaddr *)((char *)(sa) +
925 roundup(sa->sa_len, sizeof(long))); */
934 struct if_msghdr
*ifm
;
935 int mib
[6] = { CTL_NET
, AF_ROUTE
, 0, 0, NET_RT_IFLIST
, 0 };
936 struct rt_msghdr
*rtm
;
937 struct if_data
*ifd
= NULL
;
938 struct sockaddr
*sa
, *rti_info
[RTAX_MAX
];
939 struct sockaddr_dl
*sdl
;
940 char *buf
, *next
, *lim
;
944 if (sysctl(mib
, 6, NULL
, &len
, NULL
, 0) == -1)
946 if ((buf
= malloc(len
)) == NULL
)
948 if (sysctl(mib
, 6, buf
, &len
, NULL
, 0) == -1)
952 for (next
= buf
; next
< lim
; next
+= rtm
->rtm_msglen
) {
953 rtm
= (struct rt_msghdr
*)next
;
954 if (rtm
->rtm_version
!= RTM_VERSION
)
956 switch (rtm
->rtm_type
) {
958 ifm
= (struct if_msghdr
*)next
;
959 ifd
= &ifm
->ifm_data
;
961 sa
= (struct sockaddr
*)(ifm
+ 1);
962 get_rtaddrs(ifm
->ifm_addrs
, sa
, rti_info
);
964 sdl
= (struct sockaddr_dl
*)rti_info
[RTAX_IFP
];
965 if (sdl
== NULL
|| sdl
->sdl_family
!= AF_LINK
)
967 bzero(name
, sizeof(name
));
968 if (sdl
->sdl_nlen
>= IFNAMSIZ
)
969 memcpy(name
, sdl
->sdl_data
, IFNAMSIZ
- 1);
970 else if (sdl
->sdl_nlen
> 0)
971 memcpy(name
, sdl
->sdl_data
, sdl
->sdl_nlen
);
973 if (interface
!= 0 && !strcmp(name
, interface
)) {
974 strlcpy(ip_cur
.ift_name
, name
,
975 sizeof(ip_cur
.ift_name
));
976 ip_cur
.ift_ip
= ifd
->ifi_ipackets
;
977 ip_cur
.ift_ib
= ifd
->ifi_ibytes
;
978 ip_cur
.ift_ie
= ifd
->ifi_ierrors
;
979 ip_cur
.ift_op
= ifd
->ifi_opackets
;
980 ip_cur
.ift_ob
= ifd
->ifi_obytes
;
981 ip_cur
.ift_oe
= ifd
->ifi_oerrors
;
982 ip_cur
.ift_co
= ifd
->ifi_collisions
;
984 /* XXX-elad ifnet.if_snd.ifq_drops */
987 sum_cur
.ift_ip
+= ifd
->ifi_ipackets
;
988 sum_cur
.ift_ib
+= ifd
->ifi_ibytes
;
989 sum_cur
.ift_ie
+= ifd
->ifi_ierrors
;
990 sum_cur
.ift_op
+= ifd
->ifi_opackets
;
991 sum_cur
.ift_ob
+= ifd
->ifi_obytes
;
992 sum_cur
.ift_oe
+= ifd
->ifi_oerrors
;
993 sum_cur
.ift_co
+= ifd
->ifi_collisions
;
994 sum_cur
.ift_dr
+= 0; /* XXX-elad ifnet.if_snd.ifq_drops */
998 if (interface
== NULL
) {
999 strlcpy(ip_cur
.ift_name
, name
,
1000 sizeof(ip_cur
.ift_name
));
1001 ip_cur
.ift_ip
= ifd
->ifi_ipackets
;
1002 ip_cur
.ift_ib
= ifd
->ifi_ibytes
;
1003 ip_cur
.ift_ie
= ifd
->ifi_ierrors
;
1004 ip_cur
.ift_op
= ifd
->ifi_opackets
;
1005 ip_cur
.ift_ob
= ifd
->ifi_obytes
;
1006 ip_cur
.ift_oe
= ifd
->ifi_oerrors
;
1007 ip_cur
.ift_co
= ifd
->ifi_collisions
;
1009 /* XXX-elad ifnet.if_snd.ifq_drops */