2 * Copyright (c) 2008-2013 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 * Copyright (c) 1983, 1988, 1993
30 * The Regents of the University of California. All rights reserved.
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. All advertising materials mentioning features or use of this software
41 * must display the following acknowledgement:
42 * This product includes software developed by the University of
43 * California, Berkeley and its contributors.
44 * 4. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63 static char sccsid[] = "@(#)if.c 8.3 (Berkeley) 4/28/95";
65 static const char rcsid
[] =
66 "$Id: if.c,v 1.7 2006/01/16 04:53:59 lindak Exp $";
69 #include <sys/types.h>
70 #include <sys/socket.h>
71 #include <sys/sysctl.h>
72 #include <sys/ioctl.h>
76 #include <net/if_var.h>
77 #include <net/if_dl.h>
78 #include <net/if_types.h>
79 #include <net/if_mib.h>
80 #include <net/if_llreach.h>
81 #include <net/ethernet.h>
82 #include <net/route.h>
84 #include <net/pktsched/pktsched.h>
85 #include <net/classq/if_classq.h>
87 #include <netinet/in.h>
88 #include <netinet/in_var.h>
90 #include <arpa/inet.h>
105 #define ROUNDUP(a, size) (((a) & ((size) - 1)) ? (1 + ((a)|(size - 1))) : (a))
107 #define NEXT_SA(p) (struct sockaddr *) \
108 ((caddr_t)p + (p->sa_len ? ROUNDUP(p->sa_len, sizeof(uint32_t)) : \
111 static void sidewaysintpr ();
112 static void catchalarm (int);
113 static char *sec2str(time_t);
114 static void llreach_sysctl(uint32_t);
115 static char *nsec_to_str(unsigned long long);
116 static char *qtype2str(classq_type_t
);
117 static char *sched2str(unsigned int);
118 static char *qid2str(unsigned int);
119 static char *qstate2str(unsigned int);
120 static char *tcqslot2str(unsigned int);
121 static char *rate2str(long double);
129 u_int64_t prev_bytes
;
130 u_int64_t prev_packets
;
131 unsigned int printed
;
135 static void print_cbqstats(int slot
, struct cbq_classstats
*,
136 struct queue_stats
*);
137 static void print_priqstats(int slot
, struct priq_classstats
*,
138 struct queue_stats
*);
139 static void print_hfscstats(int slot
, struct hfsc_classstats
*,
140 struct queue_stats
*);
141 static void print_fairqstats(int slot
, struct fairq_classstats
*,
142 struct queue_stats
*);
143 static void print_tcqstats(int slot
, struct tcq_classstats
*,
144 struct queue_stats
*);
145 static void print_qfqstats(int slot
, struct qfq_classstats
*,
146 struct queue_stats
*);
147 static void print_sfbstats(struct sfb_stats
*);
148 static void update_avg(struct if_ifclassq_stats
*, struct queue_stats
*);
150 struct queue_stats qstats
[IFCQ_SC_MAX
];
153 char *netname6 (struct sockaddr_in6
*, struct sockaddr
*);
154 static char ntop_buf
[INET6_ADDRSTRLEN
]; /* for inet_ntop() */
158 * Display a formatted value, or a '-' in the same space.
161 show_stat(const char *fmt
, int width
, u_int64_t value
, short showvalue
)
165 /* Construct the format string */
167 snprintf(newfmt
, sizeof(newfmt
), "%%%d%s", width
, fmt
);
168 printf(newfmt
, value
);
170 snprintf(newfmt
, sizeof(newfmt
), "%%%ds", width
);
176 get_rti_info(int addrs
, struct sockaddr
*sa
, struct sockaddr
**rti_info
)
181 for (i
= 0; i
< RTAX_MAX
; i
++) {
182 if (addrs
& (1 << i
)) {
184 if (sa
->sa_len
< sizeof(struct sockaddr
))
185 len
+= sizeof(struct sockaddr
);
197 multipr(int family
, char *buf
, char *lim
)
201 for (next
= buf
; next
< lim
; ) {
202 struct ifma_msghdr2
*ifmam
= (struct ifma_msghdr2
*)next
;
203 struct sockaddr
*rti_info
[RTAX_MAX
];
207 next
+= ifmam
->ifmam_msglen
;
208 if (ifmam
->ifmam_type
== RTM_IFINFO2
)
210 else if (ifmam
->ifmam_type
!= RTM_NEWMADDR2
)
212 get_rti_info(ifmam
->ifmam_addrs
, (struct sockaddr
*)(ifmam
+ 1), rti_info
);
213 sa
= rti_info
[RTAX_IFA
];
215 if (sa
->sa_family
!= family
)
217 switch (sa
->sa_family
) {
219 struct sockaddr_in
*sin
= (struct sockaddr_in
*)sa
;
221 fmt
= routename(sin
->sin_addr
.s_addr
);
226 struct sockaddr_in6 sin6
;
228 memcpy(&sin6
, sa
, sizeof(struct sockaddr_in6
));
230 if (IN6_IS_ADDR_LINKLOCAL(&sin6
.sin6_addr
) ||
231 IN6_IS_ADDR_MC_NODELOCAL(&sin6
.sin6_addr
) ||
232 IN6_IS_ADDR_MC_LINKLOCAL(&sin6
.sin6_addr
)) {
233 sin6
.sin6_scope_id
= ntohs(*(u_int16_t
*)&sin6
.sin6_addr
.s6_addr
[2]);
234 sin6
.sin6_addr
.s6_addr
[2] = 0;
235 sin6
.sin6_addr
.s6_addr
[3] = 0;
238 printf("%23s %-19.19s(refs: %d)\n", "",
239 inet_ntop(AF_INET6
, &sin6
.sin6_addr
,
240 ntop_buf
, sizeof(ntop_buf
)),
241 ifmam
->ifmam_refcount
);
246 struct sockaddr_dl
*sdl
= (struct sockaddr_dl
*)sa
;
248 switch (sdl
->sdl_type
) {
251 fmt
= ether_ntoa((struct ether_addr
*)
259 printf("%23s %s\n", "", fmt
);
264 * Print a description of the network interfaces.
267 intpr(void (*pfunc
)(char *))
269 u_int64_t opackets
= 0;
270 u_int64_t ipackets
= 0;
271 u_int64_t obytes
= 0;
272 u_int64_t ibytes
= 0;
273 u_int64_t oerrors
= 0;
274 u_int64_t ierrors
= 0;
275 u_int64_t collisions
= 0;
276 u_int64_t fpackets
= 0;
277 u_int64_t fbytes
= 0;
281 struct sockaddr
*sa
= NULL
;
286 char *buf
= NULL
, *lim
, *next
;
288 struct if_msghdr
*ifm
;
289 struct sockaddr
*rti_info
[RTAX_MAX
];
290 unsigned int ifindex
= 0;
298 ifindex
= if_nametoindex(interface
);
300 mib
[0] = CTL_NET
; // networking subsystem
301 mib
[1] = PF_ROUTE
; // type of information
302 mib
[2] = 0; // protocol (IPPROTO_xxx)
303 mib
[3] = 0; // address family
304 mib
[4] = NET_RT_IFLIST2
; // operation
306 if (sysctl(mib
, 6, NULL
, &len
, NULL
, 0) < 0)
308 if ((buf
= malloc(len
)) == NULL
) {
309 printf("malloc failed\n");
312 if (sysctl(mib
, 6, buf
, &len
, NULL
, 0) < 0) {
319 printf("%-5.5s %-5.5s %-13.13s %-15.15s %8.8s %5.5s",
320 "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs");
322 printf(" %8.8s %8.8s", "Itcpkts", "Ipvpkts");
324 printf(" %10.10s","Ibytes");
326 printf(" %8.8s %8.8s", "Itcbytes", "Ipvbytes");
328 printf(" %8.8s %5.5s", "Opkts", "Oerrs");
330 printf(" %8.8s %8.8s", "Otcpkts", "Opvpkts");
332 printf(" %10.10s","Obytes");
334 printf(" %8.8s %8.8s", "Otcbytes", "Opvbytes");
336 printf(" %5s", "Coll");
338 printf(" %s", "Time");
340 printf(" %s", "Drop");
342 printf(" %8.8s", "Fpkts");
344 printf(" %10.10s", "Fbytes");
349 for (next
= buf
; next
< lim
; ) {
352 struct ifmibdata_supplemental ifmsupp
;
353 u_int64_t ift_itcp
= 0; /* input tc packets */
354 u_int64_t ift_itcb
= 0; /* input tc bytes */
355 u_int64_t ift_otcp
= 0; /* output tc packets */
356 u_int64_t ift_otcb
= 0; /* output tc bytes */
357 u_int64_t ift_ipvp
= 0; /* input priv tc packets */
358 u_int64_t ift_ipvb
= 0; /* input priv tc bytes */
359 u_int64_t ift_opvp
= 0; /* output priv tc packets */
360 u_int64_t ift_opvb
= 0; /* output priv tc bytes */
362 bzero(&ifmsupp
, sizeof(struct ifmibdata_supplemental
));
366 ifm
= (struct if_msghdr
*)next
;
367 next
+= ifm
->ifm_msglen
;
369 if (ifm
->ifm_type
== RTM_IFINFO2
) {
370 struct if_msghdr2
*if2m
= (struct if_msghdr2
*)ifm
;
371 struct sockaddr_dl
*sdl
=
372 (struct sockaddr_dl
*)(if2m
+ 1);
374 size_t miblen
= sizeof(struct ifmibdata_supplemental
);
376 strncpy(name
, sdl
->sdl_data
, sdl
->sdl_nlen
);
377 name
[sdl
->sdl_nlen
] = 0;
378 if (interface
!= 0 && if2m
->ifm_index
!= ifindex
)
380 cp
= index(name
, '\0');
387 if ((if2m
->ifm_flags
& IFF_UP
) == 0)
392 * Get the interface stats. These may get
393 * overriden below on a per-interface basis.
395 opackets
= if2m
->ifm_data
.ifi_opackets
;
396 ipackets
= if2m
->ifm_data
.ifi_ipackets
;
397 obytes
= if2m
->ifm_data
.ifi_obytes
;
398 ibytes
= if2m
->ifm_data
.ifi_ibytes
;
399 oerrors
=if2m
->ifm_data
.ifi_oerrors
;
400 ierrors
= if2m
->ifm_data
.ifi_ierrors
;
401 collisions
= if2m
->ifm_data
.ifi_collisions
;
402 timer
= if2m
->ifm_timer
;
403 drops
= if2m
->ifm_snd_drops
;
404 mtu
= if2m
->ifm_data
.ifi_mtu
;
406 /* Common OID prefix */
407 mibname
[0] = CTL_NET
;
408 mibname
[1] = PF_LINK
;
409 mibname
[2] = NETLINK_GENERIC
;
410 mibname
[3] = IFMIB_IFDATA
;
411 mibname
[4] = if2m
->ifm_index
;
412 mibname
[5] = IFDATA_SUPPLEMENTAL
;
413 if (sysctl(mibname
, 6, &ifmsupp
, &miblen
, NULL
, 0) == -1)
414 err(1, "sysctl IFDATA_SUPPLEMENTAL");
416 fpackets
= ifmsupp
.ifmd_data_extended
.ifi_fpackets
;
417 fbytes
= ifmsupp
.ifmd_data_extended
.ifi_fbytes
;
422 ift_itcp
= ifmsupp
.ifmd_traffic_class
.ifi_ibepackets
;
423 ift_itcb
= ifmsupp
.ifmd_traffic_class
.ifi_ibebytes
;
424 ift_otcp
= ifmsupp
.ifmd_traffic_class
.ifi_obepackets
;
425 ift_otcb
= ifmsupp
.ifmd_traffic_class
.ifi_obebytes
;
428 ift_itcp
= ifmsupp
.ifmd_traffic_class
.ifi_ibkpackets
;
429 ift_itcb
= ifmsupp
.ifmd_traffic_class
.ifi_ibkbytes
;
430 ift_otcp
= ifmsupp
.ifmd_traffic_class
.ifi_obkpackets
;
431 ift_otcb
= ifmsupp
.ifmd_traffic_class
.ifi_obkbytes
;
434 ift_itcp
= ifmsupp
.ifmd_traffic_class
.ifi_ivipackets
;
435 ift_itcb
= ifmsupp
.ifmd_traffic_class
.ifi_ivibytes
;
436 ift_otcp
= ifmsupp
.ifmd_traffic_class
.ifi_ovipackets
;
437 ift_otcb
= ifmsupp
.ifmd_traffic_class
.ifi_ovibytes
;
440 ift_itcp
= ifmsupp
.ifmd_traffic_class
.ifi_ivopackets
;
441 ift_itcb
= ifmsupp
.ifmd_traffic_class
.ifi_ivobytes
;
442 ift_otcp
= ifmsupp
.ifmd_traffic_class
.ifi_ovopackets
;
443 ift_otcb
= ifmsupp
.ifmd_traffic_class
.ifi_ovobytes
;
456 ift_ipvp
= ifmsupp
.ifmd_traffic_class
.ifi_ipvpackets
;
457 ift_ipvb
= ifmsupp
.ifmd_traffic_class
.ifi_ipvbytes
;
458 ift_opvp
= ifmsupp
.ifmd_traffic_class
.ifi_opvpackets
;
459 ift_opvb
= ifmsupp
.ifmd_traffic_class
.ifi_opvbytes
;
462 get_rti_info(if2m
->ifm_addrs
,
463 (struct sockaddr
*)(if2m
+ 1), rti_info
);
464 sa
= rti_info
[RTAX_IFP
];
465 } else if (ifm
->ifm_type
== RTM_NEWADDR
) {
466 struct ifa_msghdr
*ifam
= (struct ifa_msghdr
*)ifm
;
468 if (interface
!= 0 && ifam
->ifam_index
!= ifindex
)
470 get_rti_info(ifam
->ifam_addrs
,
471 (struct sockaddr
*)(ifam
+ 1), rti_info
);
472 sa
= rti_info
[RTAX_IFA
];
476 printf("%-5.5s %-5u ", name
, mtu
);
479 printf("%-13.13s ", "none");
480 printf("%-15.15s ", "none");
482 switch (sa
->sa_family
) {
484 printf("%-13.13s ", "none");
485 printf("%-15.15s ", "none");
489 struct sockaddr_in
*sin
=
490 (struct sockaddr_in
*)sa
;
491 struct sockaddr_in mask
;
493 mask
.sin_addr
.s_addr
= 0;
494 memcpy(&mask
, rti_info
[RTAX_NETMASK
],
495 ((struct sockaddr_in
*)
496 rti_info
[RTAX_NETMASK
])->sin_len
);
499 netname(sin
->sin_addr
.s_addr
&
500 mask
.sin_addr
.s_addr
,
501 ntohl(mask
.sin_addr
.s_addr
)));
504 routename(sin
->sin_addr
.s_addr
));
511 struct sockaddr_in6
*sin6
=
512 (struct sockaddr_in6
*)sa
;
513 struct sockaddr
*mask
=
514 (struct sockaddr
*)rti_info
[RTAX_NETMASK
];
516 printf("%-11.11s ", netname6(sin6
, mask
));
517 printf("%-17.17s ", (char *)inet_ntop(AF_INET6
,
518 &sin6
->sin6_addr
, ntop_buf
,
526 struct sockaddr_dl
*sdl
=
527 (struct sockaddr_dl
*)sa
;
529 cp
= (char *)LLADDR(sdl
);
531 snprintf(linknum
, sizeof(linknum
),
532 "<Link#%d>", sdl
->sdl_index
);
533 m
= printf("%-11.11s ", linknum
);
538 m
= printf("(%d)", sa
->sa_family
);
539 for (cp
= sa
->sa_len
+ (char *)sa
;
540 --cp
> sa
->sa_data
&& (*cp
== 0);) {}
541 n
= cp
- sa
->sa_data
+ 1;
545 m
+= printf("%02x%c", *cp
++ & 0xff,
556 show_stat("llu", 8, ipackets
, link_layer
|network_layer
);
558 show_stat("llu", 5, ierrors
, link_layer
);
561 show_stat("llu", 8, ift_itcp
, link_layer
|network_layer
);
563 show_stat("llu", 8, ift_ipvp
, link_layer
|network_layer
);
567 show_stat("llu", 10, ibytes
, link_layer
|network_layer
);
570 show_stat("llu", 8, ift_itcb
, link_layer
|network_layer
);
572 show_stat("llu", 8, ift_ipvb
, link_layer
|network_layer
);
576 show_stat("llu", 8, opackets
, link_layer
|network_layer
);
578 show_stat("llu", 5, oerrors
, link_layer
);
581 show_stat("llu", 8, ift_otcp
, link_layer
|network_layer
);
583 show_stat("llu", 8, ift_opvp
, link_layer
|network_layer
);
587 show_stat("llu", 10, obytes
, link_layer
|network_layer
);
590 show_stat("llu", 8, ift_otcb
, link_layer
|network_layer
);
592 show_stat("llu", 8, ift_opvb
, link_layer
|network_layer
);
596 show_stat("llu", 5, collisions
, link_layer
);
599 show_stat("d", 3, timer
, link_layer
);
603 show_stat("d", 3, drops
, link_layer
);
607 show_stat("llu", 8, fpackets
, link_layer
|network_layer
);
610 show_stat("llu", 10, fbytes
,
611 link_layer
|network_layer
);
617 multipr(sa
->sa_family
, next
, lim
);
623 SLIST_ENTRY(iftot
) chain
;
624 char ift_name
[16]; /* interface name */
625 u_int64_t ift_ip
; /* input packets */
626 u_int64_t ift_ie
; /* input errors */
627 u_int64_t ift_op
; /* output packets */
628 u_int64_t ift_oe
; /* output errors */
629 u_int64_t ift_co
; /* collisions */
630 u_int64_t ift_dr
; /* drops */
631 u_int64_t ift_ib
; /* input bytes */
632 u_int64_t ift_ob
; /* output bytes */
633 u_int64_t ift_itcp
; /* input tc packets */
634 u_int64_t ift_itcb
; /* input tc bytes */
635 u_int64_t ift_otcp
; /* output tc packets */
636 u_int64_t ift_otcb
; /* output tc bytes */
637 u_int64_t ift_ipvp
; /* input priv tc packets */
638 u_int64_t ift_ipvb
; /* input priv tc bytes */
639 u_int64_t ift_opvp
; /* output priv tc packets */
640 u_int64_t ift_opvb
; /* output priv tc bytes */
641 u_int64_t ift_fp
; /* forwarded packets */
642 u_int64_t ift_fb
; /* forwarded bytes */
645 u_char signalled
; /* set if alarm goes off "early" */
648 * Print a running summary of interface statistics.
649 * Repeat display every interval seconds, showing statistics
650 * collected over that interval. Assumes that interval is non-zero.
651 * First line printed at top of screen is always cumulative.
652 * XXX - should be rewritten to use ifmib(4).
657 struct iftot
*total
, *sum
, *interesting
;
662 unsigned int ifcount
, i
;
663 struct ifmibdata
*ifmdall
= 0;
665 sigset_t sigset
, oldsigset
;
666 struct itimerval timer_interval
;
668 /* Common OID prefix */
671 name
[2] = NETLINK_GENERIC
;
674 name
[3] = IFMIB_SYSTEM
;
675 name
[4] = IFMIB_IFCOUNT
;
676 if (sysctl(name
, 5, &ifcount
, &len
, 0, 0) == 1)
677 err(1, "sysctl IFMIB_IFCOUNT");
679 len
= ifcount
* sizeof(struct ifmibdata
);
680 ifmdall
= malloc(len
);
682 err(1, "malloc failed");
683 name
[3] = IFMIB_IFALLDATA
;
685 name
[5] = IFDATA_GENERAL
;
686 if (sysctl(name
, 6, ifmdall
, &len
, (void *)0, 0) == -1)
687 err(1, "sysctl IFMIB_IFALLDATA");
691 for (i
= 0; i
< ifcount
; i
++) {
692 struct ifmibdata
*ifmd
= ifmdall
+ i
;
694 if (interface
&& strcmp(ifmd
->ifmd_name
, interface
) == 0) {
695 if ((interesting
= calloc(ifcount
,
696 sizeof(struct iftot
))) == NULL
)
697 err(1, "malloc failed");
698 interesting_row
= if_nametoindex(interface
);
699 snprintf(interesting
->ift_name
, 16, "(%s)",
703 if ((total
= calloc(1, sizeof(struct iftot
))) == NULL
)
704 err(1, "malloc failed");
706 if ((sum
= calloc(1, sizeof(struct iftot
))) == NULL
)
707 err(1, "malloc failed");
709 /* create a timer that fires repeatedly every interval seconds */
710 timer_interval
.it_value
.tv_sec
= interval
;
711 timer_interval
.it_value
.tv_usec
= 0;
712 timer_interval
.it_interval
.tv_sec
= interval
;
713 timer_interval
.it_interval
.tv_usec
= 0;
714 (void)signal(SIGALRM
, catchalarm
);
716 (void)setitimer(ITIMER_REAL
, &timer_interval
, NULL
);
723 printf("%39s %39s %36s", "input",
724 interesting
? interesting
->ift_name
: "(Total)", "output");
726 printf("%17s %14s %16s", "input",
727 interesting
? interesting
->ift_name
: "(Total)", "output");
733 printf("%10s %5s %10s ", "packets", "errs", "bytes");
735 printf(" %10s %10s %10s %10s",
736 "tcpkts", "tcbytes", "pvpkts", "pvbytes");
737 printf("%10s %5s %10s %5s", "packets", "errs", "bytes", "colls");
739 printf(" %5.5s", "drops");
741 printf(" %10s %10s %10s %10s",
742 "tcpkts", "tcbytes", "pvpkts", "pvbytes");
744 printf(" %10s %10s", "fpackets", "fbytes");
752 if (interesting
!= NULL
) {
753 struct ifmibdata ifmd
;
754 struct ifmibdata_supplemental ifmsupp
;
756 len
= sizeof(struct ifmibdata
);
757 name
[3] = IFMIB_IFDATA
;
758 name
[4] = interesting_row
;
759 name
[5] = IFDATA_GENERAL
;
760 if (sysctl(name
, 6, &ifmd
, &len
, (void *)0, 0) == -1)
761 err(1, "sysctl IFDATA_GENERAL %d", interesting_row
);
763 len
= sizeof(struct ifmibdata_supplemental
);
764 name
[3] = IFMIB_IFDATA
;
765 name
[4] = interesting_row
;
766 name
[5] = IFDATA_SUPPLEMENTAL
;
767 if (sysctl(name
, 6, &ifmsupp
, &len
, (void *)0, 0) == -1)
768 err(1, "sysctl IFDATA_SUPPLEMENTAL %d",
772 printf("%10llu %5llu %10llu ",
773 ifmd
.ifmd_data
.ifi_ipackets
- interesting
->ift_ip
,
774 ifmd
.ifmd_data
.ifi_ierrors
- interesting
->ift_ie
,
775 ifmd
.ifmd_data
.ifi_ibytes
- interesting
->ift_ib
);
778 printf("%10llu %10llu ",
779 ifmsupp
.ifmd_traffic_class
.ifi_ibepackets
-
780 interesting
->ift_itcp
,
781 ifmsupp
.ifmd_traffic_class
.ifi_ibebytes
-
782 interesting
->ift_itcb
);
785 printf("%10llu %10llu ",
786 ifmsupp
.ifmd_traffic_class
.ifi_ibkpackets
-
787 interesting
->ift_itcp
,
788 ifmsupp
.ifmd_traffic_class
.ifi_ibkbytes
-
789 interesting
->ift_itcb
);
792 printf("%10llu %10llu ",
793 ifmsupp
.ifmd_traffic_class
.ifi_ivipackets
-
794 interesting
->ift_itcp
,
795 ifmsupp
.ifmd_traffic_class
.ifi_ivibytes
-
796 interesting
->ift_itcb
);
799 printf("%10llu %10llu ",
800 ifmsupp
.ifmd_traffic_class
.ifi_ivopackets
-
801 interesting
->ift_itcp
,
802 ifmsupp
.ifmd_traffic_class
.ifi_ivobytes
-
803 interesting
->ift_itcb
);
809 printf("%10llu %10llu ",
810 ifmsupp
.ifmd_traffic_class
.ifi_ipvpackets
-
811 interesting
->ift_ipvp
,
812 ifmsupp
.ifmd_traffic_class
.ifi_ipvbytes
-
813 interesting
->ift_ipvb
);
815 printf("%10llu %5llu %10llu %5llu",
816 ifmd
.ifmd_data
.ifi_opackets
- interesting
->ift_op
,
817 ifmd
.ifmd_data
.ifi_oerrors
- interesting
->ift_oe
,
818 ifmd
.ifmd_data
.ifi_obytes
- interesting
->ift_ob
,
819 ifmd
.ifmd_data
.ifi_collisions
- interesting
->ift_co
);
822 ifmd
.ifmd_snd_drops
- interesting
->ift_dr
);
825 printf(" %10llu %10llu",
826 ifmsupp
.ifmd_traffic_class
.ifi_obepackets
-
827 interesting
->ift_otcp
,
828 ifmsupp
.ifmd_traffic_class
.ifi_obebytes
-
829 interesting
->ift_otcb
);
832 printf(" %10llu %10llu",
833 ifmsupp
.ifmd_traffic_class
.ifi_obkpackets
-
834 interesting
->ift_otcp
,
835 ifmsupp
.ifmd_traffic_class
.ifi_obkbytes
-
836 interesting
->ift_otcb
);
839 printf(" %10llu %10llu",
840 ifmsupp
.ifmd_traffic_class
.ifi_ovipackets
-
841 interesting
->ift_otcp
,
842 ifmsupp
.ifmd_traffic_class
.ifi_ovibytes
-
843 interesting
->ift_otcb
);
846 printf(" %10llu %10llu",
847 ifmsupp
.ifmd_traffic_class
.ifi_ovopackets
-
848 interesting
->ift_otcp
,
849 ifmsupp
.ifmd_traffic_class
.ifi_ovobytes
-
850 interesting
->ift_otcb
);
856 printf("%10llu %10llu ",
857 ifmsupp
.ifmd_traffic_class
.ifi_opvpackets
-
858 interesting
->ift_opvp
,
859 ifmsupp
.ifmd_traffic_class
.ifi_opvbytes
-
860 interesting
->ift_opvb
);
863 printf("%10llu %10llu",
864 ifmsupp
.ifmd_data_extended
.ifi_fpackets
-
866 ifmsupp
.ifmd_data_extended
.ifi_fbytes
-
867 interesting
->ift_fb
);
870 interesting
->ift_ip
= ifmd
.ifmd_data
.ifi_ipackets
;
871 interesting
->ift_ie
= ifmd
.ifmd_data
.ifi_ierrors
;
872 interesting
->ift_ib
= ifmd
.ifmd_data
.ifi_ibytes
;
873 interesting
->ift_op
= ifmd
.ifmd_data
.ifi_opackets
;
874 interesting
->ift_oe
= ifmd
.ifmd_data
.ifi_oerrors
;
875 interesting
->ift_ob
= ifmd
.ifmd_data
.ifi_obytes
;
876 interesting
->ift_co
= ifmd
.ifmd_data
.ifi_collisions
;
877 interesting
->ift_dr
= ifmd
.ifmd_snd_drops
;
879 /* private counters */
882 interesting
->ift_itcp
=
883 ifmsupp
.ifmd_traffic_class
.ifi_ibepackets
;
884 interesting
->ift_itcb
=
885 ifmsupp
.ifmd_traffic_class
.ifi_ibebytes
;
886 interesting
->ift_otcp
=
887 ifmsupp
.ifmd_traffic_class
.ifi_obepackets
;
888 interesting
->ift_otcb
=
889 ifmsupp
.ifmd_traffic_class
.ifi_obebytes
;
892 interesting
->ift_itcp
=
893 ifmsupp
.ifmd_traffic_class
.ifi_ibkpackets
;
894 interesting
->ift_itcb
=
895 ifmsupp
.ifmd_traffic_class
.ifi_ibkbytes
;
896 interesting
->ift_otcp
=
897 ifmsupp
.ifmd_traffic_class
.ifi_obkpackets
;
898 interesting
->ift_otcb
=
899 ifmsupp
.ifmd_traffic_class
.ifi_obkbytes
;
902 interesting
->ift_itcp
=
903 ifmsupp
.ifmd_traffic_class
.ifi_ivipackets
;
904 interesting
->ift_itcb
=
905 ifmsupp
.ifmd_traffic_class
.ifi_ivibytes
;
906 interesting
->ift_otcp
=
907 ifmsupp
.ifmd_traffic_class
.ifi_ovipackets
;
908 interesting
->ift_otcb
=
909 ifmsupp
.ifmd_traffic_class
.ifi_ovibytes
;
912 interesting
->ift_itcp
=
913 ifmsupp
.ifmd_traffic_class
.ifi_ivopackets
;
914 interesting
->ift_itcb
=
915 ifmsupp
.ifmd_traffic_class
.ifi_ivobytes
;
916 interesting
->ift_otcp
=
917 ifmsupp
.ifmd_traffic_class
.ifi_ovopackets
;
918 interesting
->ift_otcb
=
919 ifmsupp
.ifmd_traffic_class
.ifi_ovobytes
;
925 interesting
->ift_ipvp
=
926 ifmsupp
.ifmd_traffic_class
.ifi_ipvpackets
;
927 interesting
->ift_ipvb
=
928 ifmsupp
.ifmd_traffic_class
.ifi_ipvbytes
;
929 interesting
->ift_opvp
=
930 ifmsupp
.ifmd_traffic_class
.ifi_opvpackets
;
931 interesting
->ift_opvb
=
932 ifmsupp
.ifmd_traffic_class
.ifi_opvbytes
;
934 interesting
->ift_fp
= ifmsupp
.ifmd_data_extended
.ifi_fpackets
;
935 interesting
->ift_fb
= ifmsupp
.ifmd_data_extended
.ifi_fbytes
;
937 unsigned int latest_ifcount
;
938 struct ifmibdata_supplemental
*ifmsuppall
= NULL
;
941 name
[3] = IFMIB_SYSTEM
;
942 name
[4] = IFMIB_IFCOUNT
;
943 if (sysctl(name
, 5, &latest_ifcount
, &len
, 0, 0) == 1)
944 err(1, "sysctl IFMIB_IFCOUNT");
945 if (latest_ifcount
> ifcount
) {
946 ifcount
= latest_ifcount
;
947 len
= ifcount
* sizeof(struct ifmibdata
);
949 ifmdall
= malloc(len
);
951 err(1, "malloc ifmdall failed");
952 } else if (latest_ifcount
> ifcount
) {
953 ifcount
= latest_ifcount
;
954 len
= ifcount
* sizeof(struct ifmibdata
);
956 len
= ifcount
* sizeof(struct ifmibdata
);
957 name
[3] = IFMIB_IFALLDATA
;
959 name
[5] = IFDATA_GENERAL
;
960 if (sysctl(name
, 6, ifmdall
, &len
, (void *)0, 0) == -1)
961 err(1, "sysctl IFMIB_IFALLDATA");
963 len
= ifcount
* sizeof(struct ifmibdata_supplemental
);
964 ifmsuppall
= malloc(len
);
965 if (ifmsuppall
== NULL
)
966 err(1, "malloc ifmsuppall failed");
967 name
[3] = IFMIB_IFALLDATA
;
969 name
[5] = IFDATA_SUPPLEMENTAL
;
970 if (sysctl(name
, 6, ifmsuppall
, &len
, (void *)0, 0) == -1)
971 err(1, "sysctl IFMIB_IFALLDATA SUPPLEMENTAL");
991 for (i
= 0; i
< ifcount
; i
++) {
992 struct ifmibdata
*ifmd
= ifmdall
+ i
;
993 struct ifmibdata_supplemental
*ifmsupp
= ifmsuppall
+ i
;
995 sum
->ift_ip
+= ifmd
->ifmd_data
.ifi_ipackets
;
996 sum
->ift_ie
+= ifmd
->ifmd_data
.ifi_ierrors
;
997 sum
->ift_ib
+= ifmd
->ifmd_data
.ifi_ibytes
;
998 sum
->ift_op
+= ifmd
->ifmd_data
.ifi_opackets
;
999 sum
->ift_oe
+= ifmd
->ifmd_data
.ifi_oerrors
;
1000 sum
->ift_ob
+= ifmd
->ifmd_data
.ifi_obytes
;
1001 sum
->ift_co
+= ifmd
->ifmd_data
.ifi_collisions
;
1002 sum
->ift_dr
+= ifmd
->ifmd_snd_drops
;
1003 /* private counters */
1004 if (prioflag
>= 0) {
1007 sum
->ift_itcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ibepackets
;
1008 sum
->ift_itcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ibebytes
;
1009 sum
->ift_otcp
+= ifmsupp
->ifmd_traffic_class
.ifi_obepackets
;
1010 sum
->ift_otcb
+= ifmsupp
->ifmd_traffic_class
.ifi_obebytes
;
1013 sum
->ift_itcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ibkpackets
;
1014 sum
->ift_itcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ibkbytes
;
1015 sum
->ift_otcp
+= ifmsupp
->ifmd_traffic_class
.ifi_obkpackets
;
1016 sum
->ift_otcb
+= ifmsupp
->ifmd_traffic_class
.ifi_obkbytes
;
1019 sum
->ift_itcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ivipackets
;
1020 sum
->ift_itcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ivibytes
;
1021 sum
->ift_otcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ovipackets
;
1022 sum
->ift_otcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ovibytes
;
1025 sum
->ift_itcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ivopackets
;
1026 sum
->ift_itcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ivobytes
;
1027 sum
->ift_otcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ovopackets
;
1028 sum
->ift_otcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ovobytes
;
1033 sum
->ift_ipvp
+= ifmsupp
->ifmd_traffic_class
.ifi_ipvpackets
;
1034 sum
->ift_ipvb
+= ifmsupp
->ifmd_traffic_class
.ifi_ipvbytes
;
1035 sum
->ift_opvp
+= ifmsupp
->ifmd_traffic_class
.ifi_opvpackets
;
1036 sum
->ift_opvb
+= ifmsupp
->ifmd_traffic_class
.ifi_opvbytes
;
1038 sum
->ift_fp
+= ifmsupp
->ifmd_data_extended
.ifi_fpackets
;
1039 sum
->ift_fb
+= ifmsupp
->ifmd_data_extended
.ifi_fbytes
;
1042 printf("%10llu %5llu %10llu ",
1043 sum
->ift_ip
- total
->ift_ip
,
1044 sum
->ift_ie
- total
->ift_ie
,
1045 sum
->ift_ib
- total
->ift_ib
);
1047 printf(" %10llu %10llu %10llu %10llu",
1048 sum
->ift_itcp
- total
->ift_itcp
,
1049 sum
->ift_itcb
- total
->ift_itcb
,
1050 sum
->ift_ipvp
- total
->ift_ipvp
,
1051 sum
->ift_ipvb
- total
->ift_ipvb
);
1052 printf("%10llu %5llu %10llu %5llu",
1053 sum
->ift_op
- total
->ift_op
,
1054 sum
->ift_oe
- total
->ift_oe
,
1055 sum
->ift_ob
- total
->ift_ob
,
1056 sum
->ift_co
- total
->ift_co
);
1058 printf(" %5llu", sum
->ift_dr
- total
->ift_dr
);
1060 printf(" %10llu %10llu %10llu %10llu",
1061 sum
->ift_otcp
- total
->ift_otcp
,
1062 sum
->ift_otcb
- total
->ift_otcb
,
1063 sum
->ift_opvp
- total
->ift_opvp
,
1064 sum
->ift_opvb
- total
->ift_opvb
);
1066 printf(" %10llu %10llu",
1067 sum
->ift_fp
- total
->ift_fp
,
1068 sum
->ift_fb
- total
->ift_fb
);
1075 sigemptyset(&sigset
);
1076 sigaddset(&sigset
, SIGALRM
);
1077 (void)sigprocmask(SIG_BLOCK
, &sigset
, &oldsigset
);
1079 sigemptyset(&sigset
);
1080 sigsuspend(&sigset
);
1082 (void)sigprocmask(SIG_SETMASK
, &oldsigset
, NULL
);
1095 intervalpr(void (*pr
)(uint32_t, char *, int), uint32_t off
, char *name
, int af
)
1097 struct itimerval timer_interval
;
1098 sigset_t sigset
, oldsigset
;
1100 /* create a timer that fires repeatedly every interval seconds */
1101 timer_interval
.it_value
.tv_sec
= interval
;
1102 timer_interval
.it_value
.tv_usec
= 0;
1103 timer_interval
.it_interval
.tv_sec
= interval
;
1104 timer_interval
.it_interval
.tv_usec
= 0;
1105 (void) signal(SIGALRM
, catchalarm
);
1107 (void) setitimer(ITIMER_REAL
, &timer_interval
, NULL
);
1113 sigemptyset(&sigset
);
1114 sigaddset(&sigset
, SIGALRM
);
1115 (void) sigprocmask(SIG_BLOCK
, &sigset
, &oldsigset
);
1117 sigemptyset(&sigset
);
1118 sigsuspend(&sigset
);
1120 (void) sigprocmask(SIG_SETMASK
, &oldsigset
, NULL
);
1126 * Called if an interval expires before sidewaysintpr has completed a loop.
1127 * Sets a flag to not wait for the alarm.
1130 catchalarm(int signo
)
1139 static char result
[256];
1140 int days
, hours
, mins
, secs
;
1144 days
= total
/ 3600 / 24;
1145 hours
= (total
/ 3600) % 24;
1146 mins
= (total
/ 60) % 60;
1151 p
+= snprintf(p
, sizeof(result
) - (p
- result
), "%dd", days
);
1153 if (!first
|| hours
) {
1155 p
+= snprintf(p
, sizeof(result
) - (p
- result
), "%dh", hours
);
1157 if (!first
|| mins
) {
1159 p
+= snprintf(p
, sizeof(result
) - (p
- result
), "%dm", mins
);
1161 snprintf(p
, sizeof(result
) - (p
- result
), "%ds", secs
);
1167 intpr_ri(void (*pfunc
)(char *))
1170 char *buf
= NULL
, *lim
, *next
;
1172 unsigned int ifindex
= 0;
1173 struct if_msghdr2
*if2m
;
1175 if (interface
!= 0) {
1176 ifindex
= if_nametoindex(interface
);
1178 printf("interface name is not valid: %s\n", interface
);
1183 mib
[0] = CTL_NET
; /* networking subsystem */
1184 mib
[1] = PF_ROUTE
; /* type of information */
1185 mib
[2] = 0; /* protocol (IPPROTO_xxx) */
1186 mib
[3] = 0; /* address family */
1187 mib
[4] = NET_RT_IFLIST2
; /* operation */
1189 if (sysctl(mib
, 6, NULL
, &len
, NULL
, 0) < 0)
1191 if ((buf
= malloc(len
)) == NULL
) {
1192 printf("malloc failed\n");
1195 if (sysctl(mib
, 6, buf
, &len
, NULL
, 0) < 0) {
1200 printf("%-6s %-17s %8.8s %-9.9s %4s %4s",
1201 "Proto", "Linklayer Address", "Netif", "Expire", "Refs",
1204 printf(" %7s %7s %7s", "RSSI", "LQM", "NPM");
1208 if2m
= (struct if_msghdr2
*)buf
;
1210 for (next
= buf
; next
< lim
; ) {
1211 if2m
= (struct if_msghdr2
*)next
;
1212 next
+= if2m
->ifm_msglen
;
1214 if (if2m
->ifm_type
!= RTM_IFINFO2
)
1216 else if (interface
!= 0 && if2m
->ifm_index
!= ifindex
)
1219 llreach_sysctl(if2m
->ifm_index
);
1225 llreach_sysctl(uint32_t ifindex
)
1227 #define MAX_SYSCTL_TRY 5
1228 int mib
[6], i
, ntry
= 0;
1229 size_t mibsize
, len
, needed
, cnt
;
1230 struct if_llreach_info
*lri
;
1231 struct timeval time
;
1233 char ifname
[IF_NAMESIZE
];
1235 bzero(&mib
, sizeof (mib
));
1236 mibsize
= sizeof (mib
) / sizeof (mib
[0]);
1237 if (sysctlnametomib("net.link.generic.system.llreach_info", mib
,
1239 perror("sysctlnametomib");
1246 mibsize
= sizeof (mib
) / sizeof (mib
[0]);
1248 if (sysctl(mib
, mibsize
, NULL
, &needed
, NULL
, 0) == -1) {
1249 perror("sysctl net.link.generic.system.llreach_info");
1252 if ((buf
= malloc(needed
)) == NULL
) {
1256 if (sysctl(mib
, mibsize
, buf
, &needed
, NULL
, 0) == -1) {
1257 if (errno
!= ENOMEM
|| ++ntry
>= MAX_SYSCTL_TRY
) {
1264 } while (buf
== NULL
);
1267 cnt
= len
/ sizeof (*lri
);
1268 lri
= (struct if_llreach_info
*)buf
;
1270 gettimeofday(&time
, 0);
1271 if (if_indextoname(ifindex
, ifname
) == NULL
)
1272 snprintf(ifname
, sizeof (ifname
), "%s", "?");
1274 for (i
= 0; i
< cnt
; i
++, lri
++) {
1275 printf("0x%-4x %-17s %8.8s ", lri
->lri_proto
,
1276 ether_ntoa((struct ether_addr
*)lri
->lri_addr
), ifname
);
1278 if (lri
->lri_expire
> time
.tv_sec
)
1279 printf("%-9.9s", sec2str(lri
->lri_expire
- time
.tv_sec
));
1280 else if (lri
->lri_expire
== 0)
1281 printf("%-9.9s", "permanent");
1283 printf("%-9.9s", "expired");
1285 printf(" %4d", lri
->lri_refcnt
);
1286 if (lri
->lri_probes
)
1287 printf(" %4d", lri
->lri_probes
);
1290 if (!lri
->lri_probes
)
1291 printf(" %-4.4s", "none");
1293 if (lri
->lri_rssi
!= IFNET_RSSI_UNKNOWN
)
1294 printf(" %7d", lri
->lri_rssi
);
1296 printf(" %-7.7s", "unknown");
1298 switch (lri
->lri_lqm
)
1300 case IFNET_LQM_THRESH_OFF
:
1301 printf(" %-7.7s", "off");
1303 case IFNET_LQM_THRESH_UNKNOWN
:
1304 printf(" %-7.7s", "unknown");
1306 case IFNET_LQM_THRESH_POOR
:
1307 printf(" %-7.7s", "poor");
1309 case IFNET_LQM_THRESH_GOOD
:
1310 printf(" %-7.7s", "good");
1313 printf(" %7d", lri
->lri_lqm
);
1317 switch (lri
->lri_npm
)
1319 case IFNET_NPM_THRESH_UNKNOWN
:
1320 printf(" %-7.7s", "unknown");
1322 case IFNET_NPM_THRESH_NEAR
:
1323 printf(" %-7.7s", "near");
1325 case IFNET_NPM_THRESH_GENERAL
:
1326 printf(" %-7.7s", "general");
1328 case IFNET_NPM_THRESH_FAR
:
1329 printf(" %-7.7s", "far");
1332 printf(" %7d", lri
->lri_npm
);
1338 len
-= sizeof (*lri
);
1342 fprintf(stderr
, "warning: %u trailing bytes from %s\n",
1343 (unsigned int)len
, "net.link.generic.system.llreach_info");
1348 #undef MAX_SYSCTL_TRY
1354 unsigned int ifindex
;
1355 struct itimerval timer_interval
;
1356 struct if_qstatsreq ifqr
;
1357 struct if_ifclassq_stats
*ifcqs
;
1358 sigset_t sigset
, oldsigset
;
1359 u_int32_t scheduler
;
1362 if (cq
< -1 || cq
>= IFCQ_SC_MAX
) {
1363 fprintf(stderr
, "Invalid classq index (range is 0-%d)\n",
1367 ifindex
= if_nametoindex(interface
);
1369 fprintf(stderr
, "Invalid interface name\n");
1373 ifcqs
= malloc(sizeof (*ifcqs
));
1374 if (ifcqs
== NULL
) {
1375 fprintf(stderr
, "Unable to allocate memory\n");
1379 if ((s
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) {
1380 perror("Warning: socket(AF_INET)");
1385 bzero(&ifqr
, sizeof (ifqr
));
1386 strlcpy(ifqr
.ifqr_name
, interface
, sizeof (ifqr
.ifqr_name
));
1387 ifqr
.ifqr_buf
= ifcqs
;
1388 ifqr
.ifqr_len
= sizeof (*ifcqs
);
1392 /* create a timer that fires repeatedly every interval seconds */
1393 timer_interval
.it_value
.tv_sec
= interval
;
1394 timer_interval
.it_value
.tv_usec
= 0;
1395 timer_interval
.it_interval
.tv_sec
= interval
;
1396 timer_interval
.it_interval
.tv_usec
= 0;
1397 (void) signal(SIGALRM
, catchalarm
);
1399 (void) setitimer(ITIMER_REAL
, &timer_interval
, NULL
);
1403 if (ioctl(s
, SIOCGIFQUEUESTATS
, (char *)&ifqr
) < 0) {
1404 if (errno
== ENXIO
) {
1405 printf("Queue statistics are not available on %s\n",
1408 perror("Warning: ioctl(SIOCGIFQUEUESTATS)");
1412 scheduler
= ifcqs
->ifqs_scheduler
;
1413 tcq
= (scheduler
== PKTSCHEDT_TCQ
);
1416 "%s [ sched: %9s %sqlength: %3d/%3d ]\n",
1417 interface
, tcq
? " " : "", sched2str(ifcqs
->ifqs_scheduler
),
1418 tcq
? "" : " ", ifcqs
->ifqs_len
, ifcqs
->ifqs_maxlen
);
1419 printf("%s [ pkts: %10llu %sbytes: %10llu "
1420 "%sdropped pkts: %6llu bytes: %6llu ]\n",
1421 (scheduler
!= PKTSCHEDT_TCQ
) ? "" : " ",
1422 ifcqs
->ifqs_xmitcnt
.packets
, tcq
? "" : " ",
1423 ifcqs
->ifqs_xmitcnt
.bytes
, tcq
? "" : " ",
1424 ifcqs
->ifqs_dropcnt
.packets
, ifcqs
->ifqs_dropcnt
.bytes
);
1426 for (n
= 0; n
< IFCQ_SC_MAX
; n
++) {
1427 qstats
[n
].printed
= 0;
1431 if (ioctl(s
, SIOCGIFQUEUESTATS
, (char *)&ifqr
) < 0) {
1432 perror("Warning: ioctl(SIOCGIFQUEUESTATS)");
1435 qstats
[n
].handle
= ifcqs
->ifqs_tcq_stats
.class_handle
;
1438 for (n
= 0; n
< IFCQ_SC_MAX
&& scheduler
!= PKTSCHEDT_NONE
; n
++) {
1439 if (cq
>= 0 && cq
!= n
)
1443 if (ioctl(s
, SIOCGIFQUEUESTATS
, (char *)&ifqr
) < 0) {
1444 perror("Warning: ioctl(SIOCGIFQUEUESTATS)");
1448 update_avg(ifcqs
, &qstats
[n
]);
1450 switch (scheduler
) {
1452 print_cbqstats(n
, &ifcqs
->ifqs_cbq_stats
,
1455 case PKTSCHEDT_HFSC
:
1456 print_hfscstats(n
, &ifcqs
->ifqs_hfsc_stats
,
1459 case PKTSCHEDT_PRIQ
:
1460 print_priqstats(n
, &ifcqs
->ifqs_priq_stats
,
1463 case PKTSCHEDT_FAIRQ
:
1464 print_fairqstats(n
, &ifcqs
->ifqs_fairq_stats
,
1468 print_tcqstats(n
, &ifcqs
->ifqs_tcq_stats
,
1472 print_qfqstats(n
, &ifcqs
->ifqs_qfq_stats
,
1475 case PKTSCHEDT_NONE
:
1484 sigemptyset(&sigset
);
1485 sigaddset(&sigset
, SIGALRM
);
1486 (void) sigprocmask(SIG_BLOCK
, &sigset
, &oldsigset
);
1488 sigemptyset(&sigset
);
1489 sigsuspend(&sigset
);
1491 (void) sigprocmask(SIG_SETMASK
, &oldsigset
, NULL
);
1503 print_cbqstats(int slot
, struct cbq_classstats
*cs
, struct queue_stats
*qs
)
1505 printf(" %2d: [ pkts: %10llu bytes: %10llu "
1506 "dropped pkts: %6llu bytes: %6llu ]\n", slot
,
1507 (unsigned long long)cs
->xmit_cnt
.packets
,
1508 (unsigned long long)cs
->xmit_cnt
.bytes
,
1509 (unsigned long long)cs
->drop_cnt
.packets
,
1510 (unsigned long long)cs
->drop_cnt
.bytes
);
1511 printf(" [ qlength: %3d/%3d borrows: %6u "
1512 "suspends: %6u qalg: %s ]\n", cs
->qcnt
, cs
->qmax
,
1513 cs
->borrows
, cs
->delays
, qtype2str(cs
->qtype
));
1514 printf(" [ service class: %5s ]\n", qid2str(cs
->handle
));
1516 if (qs
->avgn
>= 2) {
1517 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1518 qs
->avg_packets
/ interval
,
1519 rate2str((8 * qs
->avg_bytes
) / interval
));
1525 switch (cs
->qtype
) {
1527 print_sfbstats(&cs
->sfb
);
1535 print_priqstats(int slot
, struct priq_classstats
*cs
, struct queue_stats
*qs
)
1537 printf(" %2d: [ pkts: %10llu bytes: %10llu "
1538 "dropped pkts: %6llu bytes: %6llu ]\n", slot
,
1539 (unsigned long long)cs
->xmitcnt
.packets
,
1540 (unsigned long long)cs
->xmitcnt
.bytes
,
1541 (unsigned long long)cs
->dropcnt
.packets
,
1542 (unsigned long long)cs
->dropcnt
.bytes
);
1543 printf(" [ qlength: %3d/%3d qalg: %11s service class: %5s ]\n",
1544 cs
->qlength
, cs
->qlimit
, qtype2str(cs
->qtype
),
1545 qid2str(cs
->class_handle
));
1547 if (qs
->avgn
>= 2) {
1548 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1549 qs
->avg_packets
/ interval
,
1550 rate2str((8 * qs
->avg_bytes
) / interval
));
1556 switch (cs
->qtype
) {
1558 print_sfbstats(&cs
->sfb
);
1566 print_hfscstats(int slot
, struct hfsc_classstats
*cs
, struct queue_stats
*qs
)
1568 printf(" %2d: [ pkts: %10llu bytes: %10llu "
1569 "dropped pkts: %6llu bytes: %6llu ]\n", slot
,
1570 (unsigned long long)cs
->xmit_cnt
.packets
,
1571 (unsigned long long)cs
->xmit_cnt
.bytes
,
1572 (unsigned long long)cs
->drop_cnt
.packets
,
1573 (unsigned long long)cs
->drop_cnt
.bytes
);
1574 printf(" [ qlength: %3d/%3d qalg: %11s service class: %5s ]\n",
1575 cs
->qlength
, cs
->qlimit
, qtype2str(cs
->qtype
),
1576 qid2str(cs
->class_handle
));
1578 if (qs
->avgn
>= 2) {
1579 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1580 qs
->avg_packets
/ interval
,
1581 rate2str((8 * qs
->avg_bytes
) / interval
));
1587 switch (cs
->qtype
) {
1589 print_sfbstats(&cs
->sfb
);
1597 print_fairqstats(int slot
, struct fairq_classstats
*cs
, struct queue_stats
*qs
)
1599 printf(" %2d: [ pkts: %10llu bytes: %10llu "
1600 "dropped pkts: %6llu bytes: %6llu ]\n", slot
,
1601 (unsigned long long)cs
->xmit_cnt
.packets
,
1602 (unsigned long long)cs
->xmit_cnt
.bytes
,
1603 (unsigned long long)cs
->drop_cnt
.packets
,
1604 (unsigned long long)cs
->drop_cnt
.bytes
);
1605 printf(" [ qlength: %3d/%3d qalg: %11s service class: %5s ]]\n",
1606 cs
->qlength
, cs
->qlimit
, qtype2str(cs
->qtype
),
1607 qid2str(cs
->class_handle
));
1609 if (qs
->avgn
>= 2) {
1610 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1611 qs
->avg_packets
/ interval
,
1612 rate2str((8 * qs
->avg_bytes
) / interval
));
1618 switch (cs
->qtype
) {
1620 print_sfbstats(&cs
->sfb
);
1628 print_tcqstats(int slot
, struct tcq_classstats
*cs
, struct queue_stats
*qs
)
1635 qs
->handle
= cs
->class_handle
;
1638 for (n
= 0; n
< IFCQ_SC_MAX
; n
++) {
1639 if (&qstats
[n
] != qs
&& qstats
[n
].handle
== qs
->handle
)
1640 qstats
[n
].printed
++;
1643 printf("%5s: [ pkts: %10llu bytes: %10llu "
1644 "dropped pkts: %6llu bytes: %6llu ]\n", tcqslot2str(slot
),
1645 (unsigned long long)cs
->xmitcnt
.packets
,
1646 (unsigned long long)cs
->xmitcnt
.bytes
,
1647 (unsigned long long)cs
->dropcnt
.packets
,
1648 (unsigned long long)cs
->dropcnt
.bytes
);
1649 printf(" [ qlength: %3d/%3d qalg: %11s "
1650 "svc class: %9s %-13s ]\n", cs
->qlength
, cs
->qlimit
,
1651 qtype2str(cs
->qtype
), qid2str(cs
->class_handle
),
1652 qstate2str(cs
->qstate
));
1654 if (qs
->avgn
>= 2) {
1655 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1656 qs
->avg_packets
/ interval
,
1657 rate2str((8 * qs
->avg_bytes
) / interval
));
1663 switch (cs
->qtype
) {
1665 print_sfbstats(&cs
->sfb
);
1673 print_qfqstats(int slot
, struct qfq_classstats
*cs
, struct queue_stats
*qs
)
1675 printf(" %2d: [ pkts: %10llu bytes: %10llu "
1676 "dropped pkts: %6llu bytes: %6llu ]\n", slot
,
1677 (unsigned long long)cs
->xmitcnt
.packets
,
1678 (unsigned long long)cs
->xmitcnt
.bytes
,
1679 (unsigned long long)cs
->dropcnt
.packets
,
1680 (unsigned long long)cs
->dropcnt
.bytes
);
1681 printf(" [ qlength: %3d/%3d index: %10u weight: %12u "
1682 "lmax: %7u ]\n", cs
->qlength
, cs
->qlimit
, cs
->index
,
1683 cs
->weight
, cs
->lmax
);
1684 printf(" [ qalg: %10s svc class: %6s %-35s ]\n",
1685 qtype2str(cs
->qtype
), qid2str(cs
->class_handle
),
1686 qstate2str(cs
->qstate
));
1688 if (qs
->avgn
>= 2) {
1689 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1690 qs
->avg_packets
/ interval
,
1691 rate2str((8 * qs
->avg_bytes
) / interval
));
1697 switch (cs
->qtype
) {
1699 print_sfbstats(&cs
->sfb
);
1707 print_sfbstats(struct sfb_stats
*sfb
)
1709 struct sfbstats
*sp
= &sfb
->sfbstats
;
1710 int i
, j
, cur
= sfb
->current
;
1713 printf(" [ early drop: %12llu rlimit drop: %11llu "
1714 "marked: %11llu ]\n",
1715 sp
->drop_early
, sp
->drop_pbox
, sp
->marked_packets
);
1716 printf(" [ penalized: %13llu rehash cnt: %12llu "
1717 "current: %10u ]\n", sp
->pbox_packets
, sp
->num_rehash
, cur
);
1718 printf(" [ deque avg: %13s ", nsec_to_str(sp
->dequeue_avg
));
1719 printf("rehash intvl: %11s]\n", nsec_to_str(sp
->rehash_intval
));
1720 printf(" [ holdtime: %14s ", nsec_to_str(sp
->hold_time
));
1721 printf("pboxtime: %14s ]\n", nsec_to_str(sp
->pbox_time
));
1722 printf(" [ allocation: %12u drop thresh: %11u ]\n",
1723 sfb
->allocation
, sfb
->dropthresh
);
1724 printf(" [ flow controlled: %7llu adv feedback: %10llu ]\n",
1725 sp
->flow_controlled
, sp
->flow_feedback
);
1727 printf("\n\t\t\t\tCurrent bins (set %d)", cur
);
1728 for (i
= 0; i
< SFB_LEVELS
; ++i
) {
1732 printf("\n\tLevel: %d\n", i
);
1733 for (j
= 0; j
< SFB_BINS
; ++j
) {
1735 printf("\t%6d:\t", j
+ 1);
1736 p
= sfb
->binstats
[cur
].stats
[i
][j
].pmark
;
1737 q
= sfb
->binstats
[cur
].stats
[i
][j
].pkts
;
1739 p
/= (1 << SFB_FP_SHIFT
);
1740 printf("[%1.4f %4u]", p
, q
);
1744 if (j
> 0 && ((j
+ 1) % 4) == 0)
1750 printf("\n\t\t\t\tWarm up bins (set %d)", cur
);
1751 for (i
= 0; i
< SFB_LEVELS
; ++i
) {
1755 printf("\n\tLevel: %d\n", i
);
1756 for (j
= 0; j
< SFB_BINS
; ++j
) {
1758 printf("\t%6d:\t", j
+ 1);
1759 p
= sfb
->binstats
[cur
].stats
[i
][j
].pmark
;
1760 q
= sfb
->binstats
[cur
].stats
[i
][j
].pkts
;
1762 p
/= (1 << SFB_FP_SHIFT
);
1763 printf("[%1.4f %4u]", p
, q
);
1767 if (j
> 0 && ((j
+ 1) % 4) == 0)
1775 update_avg(struct if_ifclassq_stats
*ifcqs
, struct queue_stats
*qs
)
1782 switch (ifcqs
->ifqs_scheduler
) {
1784 b
= ifcqs
->ifqs_cbq_stats
.xmit_cnt
.bytes
;
1785 p
= ifcqs
->ifqs_cbq_stats
.xmit_cnt
.packets
;
1787 case PKTSCHEDT_PRIQ
:
1788 b
= ifcqs
->ifqs_priq_stats
.xmitcnt
.bytes
;
1789 p
= ifcqs
->ifqs_priq_stats
.xmitcnt
.packets
;
1791 case PKTSCHEDT_HFSC
:
1792 b
= ifcqs
->ifqs_hfsc_stats
.xmit_cnt
.bytes
;
1793 p
= ifcqs
->ifqs_hfsc_stats
.xmit_cnt
.packets
;
1795 case PKTSCHEDT_FAIRQ
:
1796 b
= ifcqs
->ifqs_fairq_stats
.xmit_cnt
.bytes
;
1797 p
= ifcqs
->ifqs_fairq_stats
.xmit_cnt
.packets
;
1800 b
= ifcqs
->ifqs_tcq_stats
.xmitcnt
.bytes
;
1801 p
= ifcqs
->ifqs_tcq_stats
.xmitcnt
.packets
;
1804 b
= ifcqs
->ifqs_qfq_stats
.xmitcnt
.bytes
;
1805 p
= ifcqs
->ifqs_qfq_stats
.xmitcnt
.packets
;
1815 qs
->prev_packets
= p
;
1820 if (b
>= qs
->prev_bytes
)
1821 qs
->avg_bytes
= ((qs
->avg_bytes
* (n
- 1)) +
1822 (b
- qs
->prev_bytes
)) / n
;
1824 if (p
>= qs
->prev_packets
)
1825 qs
->avg_packets
= ((qs
->avg_packets
* (n
- 1)) +
1826 (p
- qs
->prev_packets
)) / n
;
1829 qs
->prev_packets
= p
;
1835 qtype2str(classq_type_t t
)
1866 #define NSEC_PER_SEC 1000000000 /* nanoseconds per second */
1867 #define USEC_PER_SEC 1000000 /* nanoseconds per second */
1868 #define MSEC_PER_SEC 1000 /* nanoseconds per second */
1871 nsec_to_str(unsigned long long nsec
)
1873 static char buf
[32];
1875 long double n
= nsec
, t
;
1877 if (nsec
>= NSEC_PER_SEC
) {
1878 t
= n
/ NSEC_PER_SEC
;
1880 } else if (n
>= USEC_PER_SEC
) {
1881 t
= n
/ USEC_PER_SEC
;
1883 } else if (n
>= MSEC_PER_SEC
) {
1884 t
= n
/ MSEC_PER_SEC
;
1891 snprintf(buf
, sizeof (buf
), "%-4.2Lf %4s", t
, u
);
1896 sched2str(unsigned int s
)
1901 case PKTSCHEDT_NONE
:
1907 case PKTSCHEDT_HFSC
:
1910 case PKTSCHEDT_PRIQ
:
1913 case PKTSCHEDT_FAIRQ
:
1931 qid2str(unsigned int s
)
1975 tcqslot2str(unsigned int s
)
2007 qstate2str(unsigned int s
)
2027 #define RATESTR_MAX 16
2030 rate2str(long double rate
)
2033 static char r2sbuf
[R2S_BUFS
][RATESTR_MAX
]; /* ring bufer */
2036 static const char unit
[] = " KMG";
2038 buf
= r2sbuf
[idx
++];
2039 if (idx
== R2S_BUFS
)
2042 for (i
= 0; rate
>= 1000 && i
<= 3; i
++)
2045 if ((int)(rate
* 100) % 100)
2046 snprintf(buf
, RATESTR_MAX
, "%.2Lf%cb", rate
, unit
[i
]);
2048 snprintf(buf
, RATESTR_MAX
, "%lld%cb", (int64_t)rate
, unit
[i
]);
2056 struct ifmibdata_supplemental ifmsupp
;
2057 size_t miblen
= sizeof (ifmsupp
);
2058 struct itimerval timer_interval
;
2059 struct if_rxpoll_stats
*sp
;
2060 sigset_t sigset
, oldsigset
;
2061 unsigned int ifindex
;
2064 ifindex
= if_nametoindex(interface
);
2066 fprintf(stderr
, "Invalid interface name\n");
2070 bzero(&ifmsupp
, sizeof (struct ifmibdata_supplemental
));
2074 /* create a timer that fires repeatedly every interval seconds */
2075 timer_interval
.it_value
.tv_sec
= interval
;
2076 timer_interval
.it_value
.tv_usec
= 0;
2077 timer_interval
.it_interval
.tv_sec
= interval
;
2078 timer_interval
.it_interval
.tv_usec
= 0;
2079 (void) signal(SIGALRM
, catchalarm
);
2081 (void) setitimer(ITIMER_REAL
, &timer_interval
, NULL
);
2084 /* Common OID prefix */
2087 name
[2] = NETLINK_GENERIC
;
2088 name
[3] = IFMIB_IFDATA
;
2090 name
[5] = IFDATA_SUPPLEMENTAL
;
2091 if (sysctl(name
, 6, &ifmsupp
, &miblen
, NULL
, 0) == -1)
2092 err(1, "sysctl IFDATA_SUPPLEMENTAL");
2094 sp
= &ifmsupp
.ifmd_rxpoll_stats
;
2096 printf("%-4s [ poll on requests: %15u errors: %27u ]\n",
2097 interface
, sp
->ifi_poll_on_req
, sp
->ifi_poll_on_err
);
2098 printf(" [ poll off requests: %15u errors: %27u ]\n",
2099 sp
->ifi_poll_off_req
, sp
->ifi_poll_off_err
);
2100 printf(" [ polled packets: %18llu polled bytes: %21llu ]\n",
2101 sp
->ifi_poll_packets
, sp
->ifi_poll_bytes
);
2102 printf(" [ sampled packets avg/min/max: %12u / %12u / %12u ]\n",
2103 sp
->ifi_poll_packets_avg
, sp
->ifi_poll_packets_min
,
2104 sp
->ifi_poll_packets_max
);
2105 printf(" [ sampled bytes avg/min/max: %12u / %12u / %12u ]\n",
2106 sp
->ifi_poll_bytes_avg
, sp
->ifi_poll_bytes_min
,
2107 sp
->ifi_poll_bytes_max
);
2108 printf(" [ sampled wakeups avg: %12u ]\n",
2109 sp
->ifi_poll_wakeups_avg
);
2110 printf(" [ packets lowat/hiwat threshold: %10u / %10u ]\n",
2111 sp
->ifi_poll_packets_lowat
, sp
->ifi_poll_packets_hiwat
);
2112 printf(" [ bytes lowat/hiwat threshold: %10u / %10u ]\n",
2113 sp
->ifi_poll_bytes_lowat
, sp
->ifi_poll_bytes_hiwat
);
2114 printf(" [ wakeups lowat/hiwat threshold: %10u / %10u ]\n",
2115 sp
->ifi_poll_wakeups_lowat
, sp
->ifi_poll_wakeups_hiwat
);
2120 sigemptyset(&sigset
);
2121 sigaddset(&sigset
, SIGALRM
);
2122 (void) sigprocmask(SIG_BLOCK
, &sigset
, &oldsigset
);
2124 sigemptyset(&sigset
);
2125 sigsuspend(&sigset
);
2127 (void) sigprocmask(SIG_SETMASK
, &oldsigset
, NULL
);