2 * Copyright (c) 2008-2012 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;
279 struct sockaddr
*sa
= NULL
;
284 char *buf
= NULL
, *lim
, *next
;
286 struct if_msghdr
*ifm
;
287 struct sockaddr
*rti_info
[RTAX_MAX
];
288 unsigned int ifindex
= 0;
296 ifindex
= if_nametoindex(interface
);
298 mib
[0] = CTL_NET
; // networking subsystem
299 mib
[1] = PF_ROUTE
; // type of information
300 mib
[2] = 0; // protocol (IPPROTO_xxx)
301 mib
[3] = 0; // address family
302 mib
[4] = NET_RT_IFLIST2
; // operation
304 if (sysctl(mib
, 6, NULL
, &len
, NULL
, 0) < 0)
306 if ((buf
= malloc(len
)) == NULL
) {
307 printf("malloc failed\n");
310 if (sysctl(mib
, 6, buf
, &len
, NULL
, 0) < 0) {
317 printf("%-5.5s %-5.5s %-13.13s %-15.15s %8.8s %5.5s",
318 "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs");
320 printf(" %8.8s %8.8s", "Itcpkts", "Ipvpkts");
322 printf(" %10.10s","Ibytes");
324 printf(" %8.8s %8.8s", "Itcbytes", "Ipvbytes");
326 printf(" %8.8s %5.5s", "Opkts", "Oerrs");
328 printf(" %8.8s %8.8s", "Otcpkts", "Opvpkts");
330 printf(" %10.10s","Obytes");
332 printf(" %8.8s %8.8s", "Otcbytes", "Opvbytes");
334 printf(" %5s", "Coll");
336 printf(" %s", "Time");
338 printf(" %s", "Drop");
342 for (next
= buf
; next
< lim
; ) {
345 struct ifmibdata_supplemental ifmsupp
;
346 u_int64_t ift_itcp
= 0; /* input tc packets */
347 u_int64_t ift_itcb
= 0; /* input tc bytes */
348 u_int64_t ift_otcp
= 0; /* output tc packets */
349 u_int64_t ift_otcb
= 0; /* output tc bytes */
350 u_int64_t ift_ipvp
= 0; /* input priv tc packets */
351 u_int64_t ift_ipvb
= 0; /* input priv tc bytes */
352 u_int64_t ift_opvp
= 0; /* output priv tc packets */
353 u_int64_t ift_opvb
= 0; /* output priv tc bytes */
355 bzero(&ifmsupp
, sizeof(struct ifmibdata_supplemental
));
359 ifm
= (struct if_msghdr
*)next
;
360 next
+= ifm
->ifm_msglen
;
362 if (ifm
->ifm_type
== RTM_IFINFO2
) {
363 struct if_msghdr2
*if2m
= (struct if_msghdr2
*)ifm
;
364 struct sockaddr_dl
*sdl
= (struct sockaddr_dl
*)(if2m
+ 1);
366 strncpy(name
, sdl
->sdl_data
, sdl
->sdl_nlen
);
367 name
[sdl
->sdl_nlen
] = 0;
368 if (interface
!= 0 && if2m
->ifm_index
!= ifindex
)
370 cp
= index(name
, '\0');
377 if ((if2m
->ifm_flags
& IFF_UP
) == 0)
382 * Get the interface stats. These may get
383 * overriden below on a per-interface basis.
385 opackets
= if2m
->ifm_data
.ifi_opackets
;
386 ipackets
= if2m
->ifm_data
.ifi_ipackets
;
387 obytes
= if2m
->ifm_data
.ifi_obytes
;
388 ibytes
= if2m
->ifm_data
.ifi_ibytes
;
389 oerrors
=if2m
->ifm_data
.ifi_oerrors
;
390 ierrors
= if2m
->ifm_data
.ifi_ierrors
;
391 collisions
= if2m
->ifm_data
.ifi_collisions
;
392 timer
= if2m
->ifm_timer
;
393 drops
= if2m
->ifm_snd_drops
;
394 mtu
= if2m
->ifm_data
.ifi_mtu
;
398 size_t miblen
= sizeof(struct ifmibdata_supplemental
);
400 /* Common OID prefix */
403 name
[2] = NETLINK_GENERIC
;
404 name
[3] = IFMIB_IFDATA
;
405 name
[4] = if2m
->ifm_index
;
406 name
[5] = IFDATA_SUPPLEMENTAL
;
407 if (sysctl(name
, 6, &ifmsupp
, &miblen
, (void *)0, 0) == -1)
408 err(1, "sysctl IFDATA_SUPPLEMENTAL");
412 ift_itcp
= ifmsupp
.ifmd_traffic_class
.ifi_ibepackets
;
413 ift_itcb
= ifmsupp
.ifmd_traffic_class
.ifi_ibebytes
;
414 ift_otcp
= ifmsupp
.ifmd_traffic_class
.ifi_obepackets
;
415 ift_otcb
= ifmsupp
.ifmd_traffic_class
.ifi_obebytes
;
418 ift_itcp
= ifmsupp
.ifmd_traffic_class
.ifi_ibkpackets
;
419 ift_itcb
= ifmsupp
.ifmd_traffic_class
.ifi_ibkbytes
;
420 ift_otcp
= ifmsupp
.ifmd_traffic_class
.ifi_obkpackets
;
421 ift_otcb
= ifmsupp
.ifmd_traffic_class
.ifi_obkbytes
;
424 ift_itcp
= ifmsupp
.ifmd_traffic_class
.ifi_ivipackets
;
425 ift_itcb
= ifmsupp
.ifmd_traffic_class
.ifi_ivibytes
;
426 ift_otcp
= ifmsupp
.ifmd_traffic_class
.ifi_ovipackets
;
427 ift_otcb
= ifmsupp
.ifmd_traffic_class
.ifi_ovibytes
;
430 ift_itcp
= ifmsupp
.ifmd_traffic_class
.ifi_ivopackets
;
431 ift_itcb
= ifmsupp
.ifmd_traffic_class
.ifi_ivobytes
;
432 ift_otcp
= ifmsupp
.ifmd_traffic_class
.ifi_ovopackets
;
433 ift_otcb
= ifmsupp
.ifmd_traffic_class
.ifi_ovobytes
;
446 ift_ipvp
= ifmsupp
.ifmd_traffic_class
.ifi_ipvpackets
;
447 ift_ipvb
= ifmsupp
.ifmd_traffic_class
.ifi_ipvbytes
;
448 ift_opvp
= ifmsupp
.ifmd_traffic_class
.ifi_opvpackets
;
449 ift_opvb
= ifmsupp
.ifmd_traffic_class
.ifi_opvbytes
;
452 get_rti_info(if2m
->ifm_addrs
, (struct sockaddr
*)(if2m
+ 1), rti_info
);
453 sa
= rti_info
[RTAX_IFP
];
454 } else if (ifm
->ifm_type
== RTM_NEWADDR
) {
455 struct ifa_msghdr
*ifam
= (struct ifa_msghdr
*)ifm
;
457 if (interface
!= 0 && ifam
->ifam_index
!= ifindex
)
459 get_rti_info(ifam
->ifam_addrs
, (struct sockaddr
*)(ifam
+ 1), rti_info
);
460 sa
= rti_info
[RTAX_IFA
];
464 printf("%-5.5s %-5u ", name
, mtu
);
467 printf("%-13.13s ", "none");
468 printf("%-15.15s ", "none");
470 switch (sa
->sa_family
) {
472 printf("%-13.13s ", "none");
473 printf("%-15.15s ", "none");
477 struct sockaddr_in
*sin
= (struct sockaddr_in
*)sa
;
478 struct sockaddr_in mask
;
480 mask
.sin_addr
.s_addr
= 0;
482 rti_info
[RTAX_NETMASK
],
483 ((struct sockaddr_in
*)rti_info
[RTAX_NETMASK
])->sin_len
);
486 netname(sin
->sin_addr
.s_addr
& mask
.sin_addr
.s_addr
,
487 ntohl(mask
.sin_addr
.s_addr
)));
490 routename(sin
->sin_addr
.s_addr
));
497 struct sockaddr_in6
*sin6
= (struct sockaddr_in6
*)sa
;
498 struct sockaddr
*mask
= (struct sockaddr
*)rti_info
[RTAX_NETMASK
];
504 (char *)inet_ntop(AF_INET6
,
506 ntop_buf
, sizeof(ntop_buf
)));
513 struct sockaddr_dl
*sdl
=
514 (struct sockaddr_dl
*)sa
;
516 cp
= (char *)LLADDR(sdl
);
518 snprintf(linknum
, sizeof(linknum
), "<Link#%d>", sdl
->sdl_index
);
519 m
= printf("%-11.11s ", linknum
);
524 m
= printf("(%d)", sa
->sa_family
);
525 for (cp
= sa
->sa_len
+ (char *)sa
;
526 --cp
> sa
->sa_data
&& (*cp
== 0);) {}
527 n
= cp
- sa
->sa_data
+ 1;
531 m
+= printf("%02x%c", *cp
++ & 0xff,
542 show_stat("llu", 8, ipackets
, link_layer
|network_layer
);
544 show_stat("llu", 5, ierrors
, link_layer
);
547 show_stat("llu", 8, ift_itcp
, link_layer
|network_layer
);
549 show_stat("llu", 8, ift_ipvp
, link_layer
|network_layer
);
553 show_stat("llu", 10, ibytes
, link_layer
|network_layer
);
556 show_stat("llu", 8, ift_itcb
, link_layer
|network_layer
);
558 show_stat("llu", 8, ift_ipvb
, link_layer
|network_layer
);
562 show_stat("llu", 8, opackets
, link_layer
|network_layer
);
564 show_stat("llu", 5, oerrors
, link_layer
);
567 show_stat("llu", 8, ift_otcp
, link_layer
|network_layer
);
569 show_stat("llu", 8, ift_opvp
, link_layer
|network_layer
);
573 show_stat("llu", 10, obytes
, link_layer
|network_layer
);
576 show_stat("llu", 8, ift_otcb
, link_layer
|network_layer
);
578 show_stat("llu", 8, ift_opvb
, link_layer
|network_layer
);
582 show_stat("llu", 5, collisions
, link_layer
);
585 show_stat("ll", 3, timer
, link_layer
);
589 show_stat("ll", 3, drops
, link_layer
);
594 multipr(sa
->sa_family
, next
, lim
);
600 SLIST_ENTRY(iftot
) chain
;
601 char ift_name
[16]; /* interface name */
602 u_int64_t ift_ip
; /* input packets */
603 u_int64_t ift_ie
; /* input errors */
604 u_int64_t ift_op
; /* output packets */
605 u_int64_t ift_oe
; /* output errors */
606 u_int64_t ift_co
; /* collisions */
607 u_int64_t ift_dr
; /* drops */
608 u_int64_t ift_ib
; /* input bytes */
609 u_int64_t ift_ob
; /* output bytes */
610 u_int64_t ift_itcp
; /* input tc packets */
611 u_int64_t ift_itcb
; /* input tc bytes */
612 u_int64_t ift_otcp
; /* output tc packets */
613 u_int64_t ift_otcb
; /* output tc bytes */
614 u_int64_t ift_ipvp
; /* input priv tc packets */
615 u_int64_t ift_ipvb
; /* input priv tc bytes */
616 u_int64_t ift_opvp
; /* output priv tc packets */
617 u_int64_t ift_opvb
; /* output priv tc bytes */
620 u_char signalled
; /* set if alarm goes off "early" */
623 * Print a running summary of interface statistics.
624 * Repeat display every interval seconds, showing statistics
625 * collected over that interval. Assumes that interval is non-zero.
626 * First line printed at top of screen is always cumulative.
627 * XXX - should be rewritten to use ifmib(4).
632 struct iftot
*total
, *sum
, *interesting
;
637 unsigned int ifcount
, i
;
638 struct ifmibdata
*ifmdall
= 0;
640 sigset_t sigset
, oldsigset
;
641 struct itimerval timer_interval
;
643 /* Common OID prefix */
646 name
[2] = NETLINK_GENERIC
;
649 name
[3] = IFMIB_SYSTEM
;
650 name
[4] = IFMIB_IFCOUNT
;
651 if (sysctl(name
, 5, &ifcount
, &len
, 0, 0) == 1)
652 err(1, "sysctl IFMIB_IFCOUNT");
654 len
= ifcount
* sizeof(struct ifmibdata
);
655 ifmdall
= malloc(len
);
657 err(1, "malloc failed");
658 name
[3] = IFMIB_IFALLDATA
;
660 name
[5] = IFDATA_GENERAL
;
661 if (sysctl(name
, 6, ifmdall
, &len
, (void *)0, 0) == -1)
662 err(1, "sysctl IFMIB_IFALLDATA");
666 for (i
= 0; i
< ifcount
; i
++) {
667 struct ifmibdata
*ifmd
= ifmdall
+ i
;
669 if (interface
&& strcmp(ifmd
->ifmd_name
, interface
) == 0) {
670 if ((interesting
= calloc(ifcount
, sizeof(struct iftot
))) == NULL
)
671 err(1, "malloc failed");
672 interesting_row
= if_nametoindex(interface
);
673 snprintf(interesting
->ift_name
, 16, "(%s)", ifmd
->ifmd_name
);;
676 if ((total
= calloc(1, sizeof(struct iftot
))) == NULL
)
677 err(1, "malloc failed");
679 if ((sum
= calloc(1, sizeof(struct iftot
))) == NULL
)
680 err(1, "malloc failed");
682 /* create a timer that fires repeatedly every interval seconds */
683 timer_interval
.it_value
.tv_sec
= interval
;
684 timer_interval
.it_value
.tv_usec
= 0;
685 timer_interval
.it_interval
.tv_sec
= interval
;
686 timer_interval
.it_interval
.tv_usec
= 0;
687 (void)signal(SIGALRM
, catchalarm
);
689 (void)setitimer(ITIMER_REAL
, &timer_interval
, NULL
);
693 printf("%39s %39s %36s", "input",
694 interesting
? interesting
->ift_name
: "(Total)", "output");
696 printf("%17s %14s %16s", "input",
697 interesting
? interesting
->ift_name
: "(Total)", "output");
699 printf("%10s %5s %10s ",
700 "packets", "errs", "bytes");
702 printf(" %10s %10s %10s %10s", "tcpkts", "tcbytes", "pvpkts", "pvbytes");
703 printf("%10s %5s %10s %5s",
704 "packets", "errs", "bytes", "colls");
706 printf(" %5.5s", "drops");
708 printf(" %10s %10s %10s %10s", "tcpkts", "tcbytes", "pvpkts", "pvbytes");
713 if (interesting
!= NULL
) {
714 struct ifmibdata ifmd
;
715 struct ifmibdata_supplemental ifmsupp
;
717 len
= sizeof(struct ifmibdata
);
718 name
[3] = IFMIB_IFDATA
;
719 name
[4] = interesting_row
;
720 name
[5] = IFDATA_GENERAL
;
721 if (sysctl(name
, 6, &ifmd
, &len
, (void *)0, 0) == -1)
722 err(1, "sysctl IFDATA_GENERAL %d", interesting_row
);
725 len
= sizeof(struct ifmibdata_supplemental
);
726 name
[3] = IFMIB_IFDATA
;
727 name
[4] = interesting_row
;
728 name
[5] = IFDATA_SUPPLEMENTAL
;
729 if (sysctl(name
, 6, &ifmsupp
, &len
, (void *)0, 0) == -1)
730 err(1, "sysctl IFDATA_SUPPLEMENTAL %d", interesting_row
);
734 printf("%10llu %5llu %10llu ",
735 ifmd
.ifmd_data
.ifi_ipackets
- interesting
->ift_ip
,
736 ifmd
.ifmd_data
.ifi_ierrors
- interesting
->ift_ie
,
737 ifmd
.ifmd_data
.ifi_ibytes
- interesting
->ift_ib
);
740 printf("%10llu %10llu ",
741 ifmsupp
.ifmd_traffic_class
.ifi_ibepackets
- interesting
->ift_itcp
,
742 ifmsupp
.ifmd_traffic_class
.ifi_ibebytes
- interesting
->ift_itcb
);
745 printf("%10llu %10llu ",
746 ifmsupp
.ifmd_traffic_class
.ifi_ibkpackets
- interesting
->ift_itcp
,
747 ifmsupp
.ifmd_traffic_class
.ifi_ibkbytes
- interesting
->ift_itcb
);
750 printf("%10llu %10llu ",
751 ifmsupp
.ifmd_traffic_class
.ifi_ivipackets
- interesting
->ift_itcp
,
752 ifmsupp
.ifmd_traffic_class
.ifi_ivibytes
- interesting
->ift_itcb
);
755 printf("%10llu %10llu ",
756 ifmsupp
.ifmd_traffic_class
.ifi_ivopackets
- interesting
->ift_itcp
,
757 ifmsupp
.ifmd_traffic_class
.ifi_ivobytes
- interesting
->ift_itcb
);
763 printf("%10llu %10llu ",
764 ifmsupp
.ifmd_traffic_class
.ifi_ipvpackets
- interesting
->ift_ipvp
,
765 ifmsupp
.ifmd_traffic_class
.ifi_ipvbytes
- interesting
->ift_ipvb
);
767 printf("%10llu %5llu %10llu %5llu",
768 ifmd
.ifmd_data
.ifi_opackets
- interesting
->ift_op
,
769 ifmd
.ifmd_data
.ifi_oerrors
- interesting
->ift_oe
,
770 ifmd
.ifmd_data
.ifi_obytes
- interesting
->ift_ob
,
771 ifmd
.ifmd_data
.ifi_collisions
- interesting
->ift_co
);
773 printf(" %5llu", ifmd
.ifmd_snd_drops
- interesting
->ift_dr
);
776 printf(" %10llu %10llu",
777 ifmsupp
.ifmd_traffic_class
.ifi_obepackets
- interesting
->ift_otcp
,
778 ifmsupp
.ifmd_traffic_class
.ifi_obebytes
- interesting
->ift_otcb
);
781 printf(" %10llu %10llu",
782 ifmsupp
.ifmd_traffic_class
.ifi_obkpackets
- interesting
->ift_otcp
,
783 ifmsupp
.ifmd_traffic_class
.ifi_obkbytes
- interesting
->ift_otcb
);
786 printf(" %10llu %10llu",
787 ifmsupp
.ifmd_traffic_class
.ifi_ovipackets
- interesting
->ift_otcp
,
788 ifmsupp
.ifmd_traffic_class
.ifi_ovibytes
- interesting
->ift_otcb
);
791 printf(" %10llu %10llu",
792 ifmsupp
.ifmd_traffic_class
.ifi_ovopackets
- interesting
->ift_otcp
,
793 ifmsupp
.ifmd_traffic_class
.ifi_ovobytes
- interesting
->ift_otcb
);
799 printf("%10llu %10llu ",
800 ifmsupp
.ifmd_traffic_class
.ifi_opvpackets
- interesting
->ift_opvp
,
801 ifmsupp
.ifmd_traffic_class
.ifi_opvbytes
- interesting
->ift_opvb
);
804 interesting
->ift_ip
= ifmd
.ifmd_data
.ifi_ipackets
;
805 interesting
->ift_ie
= ifmd
.ifmd_data
.ifi_ierrors
;
806 interesting
->ift_ib
= ifmd
.ifmd_data
.ifi_ibytes
;
807 interesting
->ift_op
= ifmd
.ifmd_data
.ifi_opackets
;
808 interesting
->ift_oe
= ifmd
.ifmd_data
.ifi_oerrors
;
809 interesting
->ift_ob
= ifmd
.ifmd_data
.ifi_obytes
;
810 interesting
->ift_co
= ifmd
.ifmd_data
.ifi_collisions
;
811 interesting
->ift_dr
= ifmd
.ifmd_snd_drops
;
812 /* private counters */
815 interesting
->ift_itcp
= ifmsupp
.ifmd_traffic_class
.ifi_ibepackets
;
816 interesting
->ift_itcb
= ifmsupp
.ifmd_traffic_class
.ifi_ibebytes
;
817 interesting
->ift_otcp
= ifmsupp
.ifmd_traffic_class
.ifi_obepackets
;
818 interesting
->ift_otcb
= ifmsupp
.ifmd_traffic_class
.ifi_obebytes
;
821 interesting
->ift_itcp
= ifmsupp
.ifmd_traffic_class
.ifi_ibkpackets
;
822 interesting
->ift_itcb
= ifmsupp
.ifmd_traffic_class
.ifi_ibkbytes
;
823 interesting
->ift_otcp
= ifmsupp
.ifmd_traffic_class
.ifi_obkpackets
;
824 interesting
->ift_otcb
= ifmsupp
.ifmd_traffic_class
.ifi_obkbytes
;
827 interesting
->ift_itcp
= ifmsupp
.ifmd_traffic_class
.ifi_ivipackets
;
828 interesting
->ift_itcb
= ifmsupp
.ifmd_traffic_class
.ifi_ivibytes
;
829 interesting
->ift_otcp
= ifmsupp
.ifmd_traffic_class
.ifi_ovipackets
;
830 interesting
->ift_otcb
= ifmsupp
.ifmd_traffic_class
.ifi_ovibytes
;
833 interesting
->ift_itcp
= ifmsupp
.ifmd_traffic_class
.ifi_ivopackets
;
834 interesting
->ift_itcb
= ifmsupp
.ifmd_traffic_class
.ifi_ivobytes
;
835 interesting
->ift_otcp
= ifmsupp
.ifmd_traffic_class
.ifi_ovopackets
;
836 interesting
->ift_otcb
= ifmsupp
.ifmd_traffic_class
.ifi_ovobytes
;
842 interesting
->ift_ipvp
= ifmsupp
.ifmd_traffic_class
.ifi_ipvpackets
;
843 interesting
->ift_ipvb
= ifmsupp
.ifmd_traffic_class
.ifi_ipvbytes
;
844 interesting
->ift_opvp
= ifmsupp
.ifmd_traffic_class
.ifi_opvpackets
;
845 interesting
->ift_opvb
= ifmsupp
.ifmd_traffic_class
.ifi_opvbytes
;
848 unsigned int latest_ifcount
;
849 struct ifmibdata_supplemental
*ifmsuppall
= NULL
;
852 name
[3] = IFMIB_SYSTEM
;
853 name
[4] = IFMIB_IFCOUNT
;
854 if (sysctl(name
, 5, &latest_ifcount
, &len
, 0, 0) == 1)
855 err(1, "sysctl IFMIB_IFCOUNT");
856 if (latest_ifcount
> ifcount
) {
857 ifcount
= latest_ifcount
;
858 len
= ifcount
* sizeof(struct ifmibdata
);
860 ifmdall
= malloc(len
);
862 err(1, "malloc ifmdall failed");
863 } else if (latest_ifcount
> ifcount
) {
864 ifcount
= latest_ifcount
;
865 len
= ifcount
* sizeof(struct ifmibdata
);
867 len
= ifcount
* sizeof(struct ifmibdata
);
868 name
[3] = IFMIB_IFALLDATA
;
870 name
[5] = IFDATA_GENERAL
;
871 if (sysctl(name
, 6, ifmdall
, &len
, (void *)0, 0) == -1)
872 err(1, "sysctl IFMIB_IFALLDATA");
874 len
= ifcount
* sizeof(struct ifmibdata_supplemental
);
875 ifmsuppall
= malloc(len
);
876 if (ifmsuppall
== NULL
)
877 err(1, "malloc ifmsuppall failed");
878 name
[3] = IFMIB_IFALLDATA
;
880 name
[5] = IFDATA_SUPPLEMENTAL
;
881 if (sysctl(name
, 6, ifmsuppall
, &len
, (void *)0, 0) == -1)
882 err(1, "sysctl IFMIB_IFALLDATA SUPPLEMENTAL");
900 for (i
= 0; i
< ifcount
; i
++) {
901 struct ifmibdata
*ifmd
= ifmdall
+ i
;
903 sum
->ift_ip
+= ifmd
->ifmd_data
.ifi_ipackets
;
904 sum
->ift_ie
+= ifmd
->ifmd_data
.ifi_ierrors
;
905 sum
->ift_ib
+= ifmd
->ifmd_data
.ifi_ibytes
;
906 sum
->ift_op
+= ifmd
->ifmd_data
.ifi_opackets
;
907 sum
->ift_oe
+= ifmd
->ifmd_data
.ifi_oerrors
;
908 sum
->ift_ob
+= ifmd
->ifmd_data
.ifi_obytes
;
909 sum
->ift_co
+= ifmd
->ifmd_data
.ifi_collisions
;
910 sum
->ift_dr
+= ifmd
->ifmd_snd_drops
;
911 /* private counters */
913 struct ifmibdata_supplemental
*ifmsupp
= ifmsuppall
+ i
;
916 sum
->ift_itcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ibepackets
;
917 sum
->ift_itcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ibebytes
;
918 sum
->ift_otcp
+= ifmsupp
->ifmd_traffic_class
.ifi_obepackets
;
919 sum
->ift_otcb
+= ifmsupp
->ifmd_traffic_class
.ifi_obebytes
;
922 sum
->ift_itcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ibkpackets
;
923 sum
->ift_itcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ibkbytes
;
924 sum
->ift_otcp
+= ifmsupp
->ifmd_traffic_class
.ifi_obkpackets
;
925 sum
->ift_otcb
+= ifmsupp
->ifmd_traffic_class
.ifi_obkbytes
;
928 sum
->ift_itcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ivipackets
;
929 sum
->ift_itcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ivibytes
;
930 sum
->ift_otcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ovipackets
;
931 sum
->ift_otcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ovibytes
;
934 sum
->ift_itcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ivopackets
;
935 sum
->ift_itcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ivobytes
;
936 sum
->ift_otcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ovopackets
;
937 sum
->ift_otcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ovobytes
;
942 sum
->ift_ipvp
+= ifmsupp
->ifmd_traffic_class
.ifi_ipvpackets
;
943 sum
->ift_ipvb
+= ifmsupp
->ifmd_traffic_class
.ifi_ipvbytes
;
944 sum
->ift_opvp
+= ifmsupp
->ifmd_traffic_class
.ifi_opvpackets
;
945 sum
->ift_opvb
+= ifmsupp
->ifmd_traffic_class
.ifi_opvbytes
;
949 printf("%10llu %5llu %10llu ",
950 sum
->ift_ip
- total
->ift_ip
,
951 sum
->ift_ie
- total
->ift_ie
,
952 sum
->ift_ib
- total
->ift_ib
);
954 printf(" %10llu %10llu %10llu %10llu",
955 sum
->ift_itcp
- total
->ift_itcp
,
956 sum
->ift_itcb
- total
->ift_itcb
,
957 sum
->ift_ipvp
- total
->ift_ipvp
,
958 sum
->ift_ipvb
- total
->ift_ipvb
);
959 printf("%10llu %5llu %10llu %5llu",
960 sum
->ift_op
- total
->ift_op
,
961 sum
->ift_oe
- total
->ift_oe
,
962 sum
->ift_ob
- total
->ift_ob
,
963 sum
->ift_co
- total
->ift_co
);
965 printf(" %5llu", sum
->ift_dr
- total
->ift_dr
);
967 printf(" %10llu %10llu %10llu %10llu",
968 sum
->ift_otcp
- total
->ift_otcp
,
969 sum
->ift_otcb
- total
->ift_otcb
,
970 sum
->ift_opvp
- total
->ift_opvp
,
971 sum
->ift_opvb
- total
->ift_opvb
);
978 sigemptyset(&sigset
);
979 sigaddset(&sigset
, SIGALRM
);
980 (void)sigprocmask(SIG_BLOCK
, &sigset
, &oldsigset
);
982 sigemptyset(&sigset
);
985 (void)sigprocmask(SIG_SETMASK
, &oldsigset
, NULL
);
998 intervalpr(void (*pr
)(uint32_t, char *, int), uint32_t off
, char *name
, int af
)
1000 struct itimerval timer_interval
;
1001 sigset_t sigset
, oldsigset
;
1003 /* create a timer that fires repeatedly every interval seconds */
1004 timer_interval
.it_value
.tv_sec
= interval
;
1005 timer_interval
.it_value
.tv_usec
= 0;
1006 timer_interval
.it_interval
.tv_sec
= interval
;
1007 timer_interval
.it_interval
.tv_usec
= 0;
1008 (void) signal(SIGALRM
, catchalarm
);
1010 (void) setitimer(ITIMER_REAL
, &timer_interval
, NULL
);
1016 sigemptyset(&sigset
);
1017 sigaddset(&sigset
, SIGALRM
);
1018 (void) sigprocmask(SIG_BLOCK
, &sigset
, &oldsigset
);
1020 sigemptyset(&sigset
);
1021 sigsuspend(&sigset
);
1023 (void) sigprocmask(SIG_SETMASK
, &oldsigset
, NULL
);
1029 * Called if an interval expires before sidewaysintpr has completed a loop.
1030 * Sets a flag to not wait for the alarm.
1033 catchalarm(int signo
)
1042 static char result
[256];
1043 int days
, hours
, mins
, secs
;
1047 days
= total
/ 3600 / 24;
1048 hours
= (total
/ 3600) % 24;
1049 mins
= (total
/ 60) % 60;
1054 p
+= snprintf(p
, sizeof(result
) - (p
- result
), "%dd", days
);
1056 if (!first
|| hours
) {
1058 p
+= snprintf(p
, sizeof(result
) - (p
- result
), "%dh", hours
);
1060 if (!first
|| mins
) {
1062 p
+= snprintf(p
, sizeof(result
) - (p
- result
), "%dm", mins
);
1064 snprintf(p
, sizeof(result
) - (p
- result
), "%ds", secs
);
1070 intpr_ri(void (*pfunc
)(char *))
1073 char *buf
= NULL
, *lim
, *next
;
1075 unsigned int ifindex
= 0;
1076 struct if_msghdr2
*if2m
;
1078 if (interface
!= 0) {
1079 ifindex
= if_nametoindex(interface
);
1081 printf("interface name is not valid: %s\n", interface
);
1086 mib
[0] = CTL_NET
; /* networking subsystem */
1087 mib
[1] = PF_ROUTE
; /* type of information */
1088 mib
[2] = 0; /* protocol (IPPROTO_xxx) */
1089 mib
[3] = 0; /* address family */
1090 mib
[4] = NET_RT_IFLIST2
; /* operation */
1092 if (sysctl(mib
, 6, NULL
, &len
, NULL
, 0) < 0)
1094 if ((buf
= malloc(len
)) == NULL
) {
1095 printf("malloc failed\n");
1098 if (sysctl(mib
, 6, buf
, &len
, NULL
, 0) < 0) {
1103 printf("%-6s %-17s %8.8s %-9.9s %4s %4s",
1104 "Proto", "Linklayer Address", "Netif", "Expire", "Refs",
1107 printf(" %7s %7s %7s", "RSSI", "LQM", "NPM");
1111 if2m
= (struct if_msghdr2
*)buf
;
1113 for (next
= buf
; next
< lim
; ) {
1114 if2m
= (struct if_msghdr2
*)next
;
1115 next
+= if2m
->ifm_msglen
;
1117 if (if2m
->ifm_type
!= RTM_IFINFO2
)
1119 else if (interface
!= 0 && if2m
->ifm_index
!= ifindex
)
1122 llreach_sysctl(if2m
->ifm_index
);
1128 llreach_sysctl(uint32_t ifindex
)
1130 #define MAX_SYSCTL_TRY 5
1131 int mib
[6], i
, ntry
= 0;
1132 size_t mibsize
, len
, needed
, cnt
;
1133 struct if_llreach_info
*lri
;
1134 struct timeval time
;
1136 char ifname
[IF_NAMESIZE
];
1138 bzero(&mib
, sizeof (mib
));
1139 mibsize
= sizeof (mib
) / sizeof (mib
[0]);
1140 if (sysctlnametomib("net.link.generic.system.llreach_info", mib
,
1142 perror("sysctlnametomib");
1149 mibsize
= sizeof (mib
) / sizeof (mib
[0]);
1151 if (sysctl(mib
, mibsize
, NULL
, &needed
, NULL
, 0) == -1) {
1152 perror("sysctl net.link.generic.system.llreach_info");
1155 if ((buf
= malloc(needed
)) == NULL
) {
1159 if (sysctl(mib
, mibsize
, buf
, &needed
, NULL
, 0) == -1) {
1160 if (errno
!= ENOMEM
|| ++ntry
>= MAX_SYSCTL_TRY
) {
1167 } while (buf
== NULL
);
1170 cnt
= len
/ sizeof (*lri
);
1171 lri
= (struct if_llreach_info
*)buf
;
1173 gettimeofday(&time
, 0);
1174 if (if_indextoname(ifindex
, ifname
) == NULL
)
1175 snprintf(ifname
, sizeof (ifname
), "%s", "?");
1177 for (i
= 0; i
< cnt
; i
++, lri
++) {
1178 printf("0x%-4x %-17s %8.8s ", lri
->lri_proto
,
1179 ether_ntoa((struct ether_addr
*)lri
->lri_addr
), ifname
);
1181 if (lri
->lri_expire
> time
.tv_sec
)
1182 printf("%-9.9s", sec2str(lri
->lri_expire
- time
.tv_sec
));
1183 else if (lri
->lri_expire
== 0)
1184 printf("%-9.9s", "permanent");
1186 printf("%-9.9s", "expired");
1188 printf(" %4d", lri
->lri_refcnt
);
1189 if (lri
->lri_probes
)
1190 printf(" %4d", lri
->lri_probes
);
1193 if (!lri
->lri_probes
)
1194 printf(" %-4.4s", "none");
1196 if (lri
->lri_rssi
!= IFNET_RSSI_UNKNOWN
)
1197 printf(" %7d", lri
->lri_rssi
);
1199 printf(" %-7.7s", "unknown");
1201 switch (lri
->lri_lqm
)
1203 case IFNET_LQM_THRESH_OFF
:
1204 printf(" %-7.7s", "off");
1206 case IFNET_LQM_THRESH_UNKNOWN
:
1207 printf(" %-7.7s", "unknown");
1209 case IFNET_LQM_THRESH_POOR
:
1210 printf(" %-7.7s", "poor");
1212 case IFNET_LQM_THRESH_GOOD
:
1213 printf(" %-7.7s", "good");
1216 printf(" %7d", lri
->lri_lqm
);
1220 switch (lri
->lri_npm
)
1222 case IFNET_NPM_THRESH_UNKNOWN
:
1223 printf(" %-7.7s", "unknown");
1225 case IFNET_NPM_THRESH_NEAR
:
1226 printf(" %-7.7s", "near");
1228 case IFNET_NPM_THRESH_GENERAL
:
1229 printf(" %-7.7s", "general");
1231 case IFNET_NPM_THRESH_FAR
:
1232 printf(" %-7.7s", "far");
1235 printf(" %7d", lri
->lri_npm
);
1241 len
-= sizeof (*lri
);
1245 fprintf(stderr
, "warning: %u trailing bytes from %s\n",
1246 (unsigned int)len
, "net.link.generic.system.llreach_info");
1251 #undef MAX_SYSCTL_TRY
1257 unsigned int ifindex
;
1258 struct itimerval timer_interval
;
1259 struct if_qstatsreq ifqr
;
1260 struct if_ifclassq_stats
*ifcqs
;
1261 sigset_t sigset
, oldsigset
;
1262 u_int32_t scheduler
;
1265 if (cq
< -1 || cq
>= IFCQ_SC_MAX
) {
1266 fprintf(stderr
, "Invalid classq index (range is 0-%d)\n",
1270 ifindex
= if_nametoindex(interface
);
1272 fprintf(stderr
, "Invalid interface name\n");
1276 ifcqs
= malloc(sizeof (*ifcqs
));
1277 if (ifcqs
== NULL
) {
1278 fprintf(stderr
, "Unable to allocate memory\n");
1282 if ((s
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) {
1283 perror("Warning: socket(AF_INET)");
1288 bzero(&ifqr
, sizeof (ifqr
));
1289 strlcpy(ifqr
.ifqr_name
, interface
, sizeof (ifqr
.ifqr_name
));
1290 ifqr
.ifqr_buf
= ifcqs
;
1291 ifqr
.ifqr_len
= sizeof (*ifcqs
);
1295 /* create a timer that fires repeatedly every interval seconds */
1296 timer_interval
.it_value
.tv_sec
= interval
;
1297 timer_interval
.it_value
.tv_usec
= 0;
1298 timer_interval
.it_interval
.tv_sec
= interval
;
1299 timer_interval
.it_interval
.tv_usec
= 0;
1300 (void) signal(SIGALRM
, catchalarm
);
1302 (void) setitimer(ITIMER_REAL
, &timer_interval
, NULL
);
1306 if (ioctl(s
, SIOCGIFQUEUESTATS
, (char *)&ifqr
) < 0) {
1307 if (errno
== ENXIO
) {
1308 printf("Queue statistics are not available on %s\n",
1311 perror("Warning: ioctl(SIOCGIFQUEUESTATS)");
1315 scheduler
= ifcqs
->ifqs_scheduler
;
1316 tcq
= (scheduler
== PKTSCHEDT_TCQ
);
1319 "%s [ sched: %9s %sqlength: %3d/%3d ]\n",
1320 interface
, tcq
? " " : "", sched2str(ifcqs
->ifqs_scheduler
),
1321 tcq
? "" : " ", ifcqs
->ifqs_len
, ifcqs
->ifqs_maxlen
);
1322 printf("%s [ pkts: %10llu %sbytes: %10llu "
1323 "%sdropped pkts: %6llu bytes: %6llu ]\n",
1324 (scheduler
!= PKTSCHEDT_TCQ
) ? "" : " ",
1325 ifcqs
->ifqs_xmitcnt
.packets
, tcq
? "" : " ",
1326 ifcqs
->ifqs_xmitcnt
.bytes
, tcq
? "" : " ",
1327 ifcqs
->ifqs_dropcnt
.packets
, ifcqs
->ifqs_dropcnt
.bytes
);
1329 for (n
= 0; n
< IFCQ_SC_MAX
; n
++) {
1330 qstats
[n
].printed
= 0;
1334 if (ioctl(s
, SIOCGIFQUEUESTATS
, (char *)&ifqr
) < 0) {
1335 perror("Warning: ioctl(SIOCGIFQUEUESTATS)");
1338 qstats
[n
].handle
= ifcqs
->ifqs_tcq_stats
.class_handle
;
1341 for (n
= 0; n
< IFCQ_SC_MAX
&& scheduler
!= PKTSCHEDT_NONE
; n
++) {
1342 if (cq
>= 0 && cq
!= n
)
1346 if (ioctl(s
, SIOCGIFQUEUESTATS
, (char *)&ifqr
) < 0) {
1347 perror("Warning: ioctl(SIOCGIFQUEUESTATS)");
1351 update_avg(ifcqs
, &qstats
[n
]);
1353 switch (scheduler
) {
1355 print_cbqstats(n
, &ifcqs
->ifqs_cbq_stats
,
1358 case PKTSCHEDT_HFSC
:
1359 print_hfscstats(n
, &ifcqs
->ifqs_hfsc_stats
,
1362 case PKTSCHEDT_PRIQ
:
1363 print_priqstats(n
, &ifcqs
->ifqs_priq_stats
,
1366 case PKTSCHEDT_FAIRQ
:
1367 print_fairqstats(n
, &ifcqs
->ifqs_fairq_stats
,
1371 print_tcqstats(n
, &ifcqs
->ifqs_tcq_stats
,
1375 print_qfqstats(n
, &ifcqs
->ifqs_qfq_stats
,
1378 case PKTSCHEDT_NONE
:
1387 sigemptyset(&sigset
);
1388 sigaddset(&sigset
, SIGALRM
);
1389 (void) sigprocmask(SIG_BLOCK
, &sigset
, &oldsigset
);
1391 sigemptyset(&sigset
);
1392 sigsuspend(&sigset
);
1394 (void) sigprocmask(SIG_SETMASK
, &oldsigset
, NULL
);
1406 print_cbqstats(int slot
, struct cbq_classstats
*cs
, struct queue_stats
*qs
)
1408 printf(" %2d: [ pkts: %10llu bytes: %10llu "
1409 "dropped pkts: %6llu bytes: %6llu ]\n", slot
,
1410 (unsigned long long)cs
->xmit_cnt
.packets
,
1411 (unsigned long long)cs
->xmit_cnt
.bytes
,
1412 (unsigned long long)cs
->drop_cnt
.packets
,
1413 (unsigned long long)cs
->drop_cnt
.bytes
);
1414 printf(" [ qlength: %3d/%3d borrows: %6u "
1415 "suspends: %6u qalg: %s ]\n", cs
->qcnt
, cs
->qmax
,
1416 cs
->borrows
, cs
->delays
, qtype2str(cs
->qtype
));
1417 printf(" [ service class: %5s ]\n", qid2str(cs
->handle
));
1419 if (qs
->avgn
>= 2) {
1420 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1421 qs
->avg_packets
/ interval
,
1422 rate2str((8 * qs
->avg_bytes
) / interval
));
1428 switch (cs
->qtype
) {
1430 print_sfbstats(&cs
->sfb
);
1438 print_priqstats(int slot
, struct priq_classstats
*cs
, struct queue_stats
*qs
)
1440 printf(" %2d: [ pkts: %10llu bytes: %10llu "
1441 "dropped pkts: %6llu bytes: %6llu ]\n", slot
,
1442 (unsigned long long)cs
->xmitcnt
.packets
,
1443 (unsigned long long)cs
->xmitcnt
.bytes
,
1444 (unsigned long long)cs
->dropcnt
.packets
,
1445 (unsigned long long)cs
->dropcnt
.bytes
);
1446 printf(" [ qlength: %3d/%3d qalg: %11s service class: %5s ]\n",
1447 cs
->qlength
, cs
->qlimit
, qtype2str(cs
->qtype
),
1448 qid2str(cs
->class_handle
));
1450 if (qs
->avgn
>= 2) {
1451 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1452 qs
->avg_packets
/ interval
,
1453 rate2str((8 * qs
->avg_bytes
) / interval
));
1459 switch (cs
->qtype
) {
1461 print_sfbstats(&cs
->sfb
);
1469 print_hfscstats(int slot
, struct hfsc_classstats
*cs
, struct queue_stats
*qs
)
1471 printf(" %2d: [ pkts: %10llu bytes: %10llu "
1472 "dropped pkts: %6llu bytes: %6llu ]\n", slot
,
1473 (unsigned long long)cs
->xmit_cnt
.packets
,
1474 (unsigned long long)cs
->xmit_cnt
.bytes
,
1475 (unsigned long long)cs
->drop_cnt
.packets
,
1476 (unsigned long long)cs
->drop_cnt
.bytes
);
1477 printf(" [ qlength: %3d/%3d qalg: %11s service class: %5s ]\n",
1478 cs
->qlength
, cs
->qlimit
, qtype2str(cs
->qtype
),
1479 qid2str(cs
->class_handle
));
1481 if (qs
->avgn
>= 2) {
1482 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1483 qs
->avg_packets
/ interval
,
1484 rate2str((8 * qs
->avg_bytes
) / interval
));
1490 switch (cs
->qtype
) {
1492 print_sfbstats(&cs
->sfb
);
1500 print_fairqstats(int slot
, struct fairq_classstats
*cs
, struct queue_stats
*qs
)
1502 printf(" %2d: [ pkts: %10llu bytes: %10llu "
1503 "dropped pkts: %6llu bytes: %6llu ]\n", slot
,
1504 (unsigned long long)cs
->xmit_cnt
.packets
,
1505 (unsigned long long)cs
->xmit_cnt
.bytes
,
1506 (unsigned long long)cs
->drop_cnt
.packets
,
1507 (unsigned long long)cs
->drop_cnt
.bytes
);
1508 printf(" [ qlength: %3d/%3d qalg: %11s service class: %5s ]]\n",
1509 cs
->qlength
, cs
->qlimit
, qtype2str(cs
->qtype
),
1510 qid2str(cs
->class_handle
));
1512 if (qs
->avgn
>= 2) {
1513 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1514 qs
->avg_packets
/ interval
,
1515 rate2str((8 * qs
->avg_bytes
) / interval
));
1521 switch (cs
->qtype
) {
1523 print_sfbstats(&cs
->sfb
);
1531 print_tcqstats(int slot
, struct tcq_classstats
*cs
, struct queue_stats
*qs
)
1538 qs
->handle
= cs
->class_handle
;
1541 for (n
= 0; n
< IFCQ_SC_MAX
; n
++) {
1542 if (&qstats
[n
] != qs
&& qstats
[n
].handle
== qs
->handle
)
1543 qstats
[n
].printed
++;
1546 printf("%5s: [ pkts: %10llu bytes: %10llu "
1547 "dropped pkts: %6llu bytes: %6llu ]\n", tcqslot2str(slot
),
1548 (unsigned long long)cs
->xmitcnt
.packets
,
1549 (unsigned long long)cs
->xmitcnt
.bytes
,
1550 (unsigned long long)cs
->dropcnt
.packets
,
1551 (unsigned long long)cs
->dropcnt
.bytes
);
1552 printf(" [ qlength: %3d/%3d qalg: %11s "
1553 "svc class: %9s %-13s ]\n", cs
->qlength
, cs
->qlimit
,
1554 qtype2str(cs
->qtype
), qid2str(cs
->class_handle
),
1555 qstate2str(cs
->qstate
));
1557 if (qs
->avgn
>= 2) {
1558 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1559 qs
->avg_packets
/ interval
,
1560 rate2str((8 * qs
->avg_bytes
) / interval
));
1566 switch (cs
->qtype
) {
1568 print_sfbstats(&cs
->sfb
);
1576 print_qfqstats(int slot
, struct qfq_classstats
*cs
, struct queue_stats
*qs
)
1578 printf(" %2d: [ pkts: %10llu bytes: %10llu "
1579 "dropped pkts: %6llu bytes: %6llu ]\n", slot
,
1580 (unsigned long long)cs
->xmitcnt
.packets
,
1581 (unsigned long long)cs
->xmitcnt
.bytes
,
1582 (unsigned long long)cs
->dropcnt
.packets
,
1583 (unsigned long long)cs
->dropcnt
.bytes
);
1584 printf(" [ qlength: %3d/%3d index: %10u weight: %12u "
1585 "lmax: %7u ]\n", cs
->qlength
, cs
->qlimit
, cs
->index
,
1586 cs
->weight
, cs
->lmax
);
1587 printf(" [ qalg: %10s svc class: %6s %-35s ]\n",
1588 qtype2str(cs
->qtype
), qid2str(cs
->class_handle
),
1589 qstate2str(cs
->qstate
));
1591 if (qs
->avgn
>= 2) {
1592 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1593 qs
->avg_packets
/ interval
,
1594 rate2str((8 * qs
->avg_bytes
) / interval
));
1600 switch (cs
->qtype
) {
1602 print_sfbstats(&cs
->sfb
);
1610 print_sfbstats(struct sfb_stats
*sfb
)
1612 struct sfbstats
*sp
= &sfb
->sfbstats
;
1613 int i
, j
, cur
= sfb
->current
;
1616 printf(" [ early drop: %12llu rlimit drop: %11llu "
1617 "marked: %11llu ]\n",
1618 sp
->drop_early
, sp
->drop_pbox
, sp
->marked_packets
);
1619 printf(" [ penalized: %13llu rehash cnt: %12llu "
1620 "current: %10u ]\n", sp
->pbox_packets
, sp
->num_rehash
, cur
);
1621 printf(" [ deque avg: %13s ", nsec_to_str(sp
->dequeue_avg
));
1622 printf("rehash intvl: %11s]\n", nsec_to_str(sp
->rehash_intval
));
1623 printf(" [ holdtime: %14s ", nsec_to_str(sp
->hold_time
));
1624 printf("pboxtime: %14s ]\n", nsec_to_str(sp
->pbox_time
));
1625 printf(" [ allocation: %12u drop thresh: %11u ]\n",
1626 sfb
->allocation
, sfb
->dropthresh
);
1627 printf(" [ flow controlled: %7llu adv feedback: %10llu ]\n",
1628 sp
->flow_controlled
, sp
->flow_feedback
);
1630 printf("\n\t\t\t\tCurrent bins (set %d)", cur
);
1631 for (i
= 0; i
< SFB_LEVELS
; ++i
) {
1635 printf("\n\tLevel: %d\n", i
);
1636 for (j
= 0; j
< SFB_BINS
; ++j
) {
1638 printf("\t%6d:\t", j
+ 1);
1639 p
= sfb
->binstats
[cur
].stats
[i
][j
].pmark
;
1640 q
= sfb
->binstats
[cur
].stats
[i
][j
].pkts
;
1642 p
/= (1 << SFB_FP_SHIFT
);
1643 printf("[%1.4f %4u]", p
, q
);
1647 if (j
> 0 && ((j
+ 1) % 4) == 0)
1653 printf("\n\t\t\t\tWarm up bins (set %d)", cur
);
1654 for (i
= 0; i
< SFB_LEVELS
; ++i
) {
1658 printf("\n\tLevel: %d\n", i
);
1659 for (j
= 0; j
< SFB_BINS
; ++j
) {
1661 printf("\t%6d:\t", j
+ 1);
1662 p
= sfb
->binstats
[cur
].stats
[i
][j
].pmark
;
1663 q
= sfb
->binstats
[cur
].stats
[i
][j
].pkts
;
1665 p
/= (1 << SFB_FP_SHIFT
);
1666 printf("[%1.4f %4u]", p
, q
);
1670 if (j
> 0 && ((j
+ 1) % 4) == 0)
1678 update_avg(struct if_ifclassq_stats
*ifcqs
, struct queue_stats
*qs
)
1685 switch (ifcqs
->ifqs_scheduler
) {
1687 b
= ifcqs
->ifqs_cbq_stats
.xmit_cnt
.bytes
;
1688 p
= ifcqs
->ifqs_cbq_stats
.xmit_cnt
.packets
;
1690 case PKTSCHEDT_PRIQ
:
1691 b
= ifcqs
->ifqs_priq_stats
.xmitcnt
.bytes
;
1692 p
= ifcqs
->ifqs_priq_stats
.xmitcnt
.packets
;
1694 case PKTSCHEDT_HFSC
:
1695 b
= ifcqs
->ifqs_hfsc_stats
.xmit_cnt
.bytes
;
1696 p
= ifcqs
->ifqs_hfsc_stats
.xmit_cnt
.packets
;
1698 case PKTSCHEDT_FAIRQ
:
1699 b
= ifcqs
->ifqs_fairq_stats
.xmit_cnt
.bytes
;
1700 p
= ifcqs
->ifqs_fairq_stats
.xmit_cnt
.packets
;
1703 b
= ifcqs
->ifqs_tcq_stats
.xmitcnt
.bytes
;
1704 p
= ifcqs
->ifqs_tcq_stats
.xmitcnt
.packets
;
1707 b
= ifcqs
->ifqs_qfq_stats
.xmitcnt
.bytes
;
1708 p
= ifcqs
->ifqs_qfq_stats
.xmitcnt
.packets
;
1718 qs
->prev_packets
= p
;
1723 if (b
>= qs
->prev_bytes
)
1724 qs
->avg_bytes
= ((qs
->avg_bytes
* (n
- 1)) +
1725 (b
- qs
->prev_bytes
)) / n
;
1727 if (p
>= qs
->prev_packets
)
1728 qs
->avg_packets
= ((qs
->avg_packets
* (n
- 1)) +
1729 (p
- qs
->prev_packets
)) / n
;
1732 qs
->prev_packets
= p
;
1738 qtype2str(classq_type_t t
)
1769 #define NSEC_PER_SEC 1000000000 /* nanoseconds per second */
1770 #define USEC_PER_SEC 1000000 /* nanoseconds per second */
1771 #define MSEC_PER_SEC 1000 /* nanoseconds per second */
1774 nsec_to_str(unsigned long long nsec
)
1776 static char buf
[32];
1778 long double n
= nsec
, t
;
1780 if (nsec
>= NSEC_PER_SEC
) {
1781 t
= n
/ NSEC_PER_SEC
;
1783 } else if (n
>= USEC_PER_SEC
) {
1784 t
= n
/ USEC_PER_SEC
;
1786 } else if (n
>= MSEC_PER_SEC
) {
1787 t
= n
/ MSEC_PER_SEC
;
1794 snprintf(buf
, sizeof (buf
), "%-4.2Lf %4s", t
, u
);
1799 sched2str(unsigned int s
)
1804 case PKTSCHEDT_NONE
:
1810 case PKTSCHEDT_HFSC
:
1813 case PKTSCHEDT_PRIQ
:
1816 case PKTSCHEDT_FAIRQ
:
1834 qid2str(unsigned int s
)
1878 tcqslot2str(unsigned int s
)
1910 qstate2str(unsigned int s
)
1930 #define RATESTR_MAX 16
1933 rate2str(long double rate
)
1936 static char r2sbuf
[R2S_BUFS
][RATESTR_MAX
]; /* ring bufer */
1939 static const char unit
[] = " KMG";
1941 buf
= r2sbuf
[idx
++];
1942 if (idx
== R2S_BUFS
)
1945 for (i
= 0; rate
>= 1000 && i
<= 3; i
++)
1948 if ((int)(rate
* 100) % 100)
1949 snprintf(buf
, RATESTR_MAX
, "%.2Lf%cb", rate
, unit
[i
]);
1951 snprintf(buf
, RATESTR_MAX
, "%lld%cb", (int64_t)rate
, unit
[i
]);
1959 struct ifmibdata_supplemental ifmsupp
;
1960 size_t miblen
= sizeof (ifmsupp
);
1961 struct itimerval timer_interval
;
1962 struct if_rxpoll_stats
*sp
;
1963 sigset_t sigset
, oldsigset
;
1964 unsigned int ifindex
;
1967 ifindex
= if_nametoindex(interface
);
1969 fprintf(stderr
, "Invalid interface name\n");
1973 bzero(&ifmsupp
, sizeof (struct ifmibdata_supplemental
));
1977 /* create a timer that fires repeatedly every interval seconds */
1978 timer_interval
.it_value
.tv_sec
= interval
;
1979 timer_interval
.it_value
.tv_usec
= 0;
1980 timer_interval
.it_interval
.tv_sec
= interval
;
1981 timer_interval
.it_interval
.tv_usec
= 0;
1982 (void) signal(SIGALRM
, catchalarm
);
1984 (void) setitimer(ITIMER_REAL
, &timer_interval
, NULL
);
1987 /* Common OID prefix */
1990 name
[2] = NETLINK_GENERIC
;
1991 name
[3] = IFMIB_IFDATA
;
1993 name
[5] = IFDATA_SUPPLEMENTAL
;
1994 if (sysctl(name
, 6, &ifmsupp
, &miblen
, NULL
, 0) == -1)
1995 err(1, "sysctl IFDATA_SUPPLEMENTAL");
1997 sp
= &ifmsupp
.ifmd_rxpoll_stats
;
1999 printf("%-4s [ poll on requests: %15u errors: %27u ]\n",
2000 interface
, sp
->ifi_poll_on_req
, sp
->ifi_poll_on_err
);
2001 printf(" [ poll off requests: %15u errors: %27u ]\n",
2002 sp
->ifi_poll_off_req
, sp
->ifi_poll_off_err
);
2003 printf(" [ polled packets: %18llu polled bytes: %21llu ]\n",
2004 sp
->ifi_poll_packets
, sp
->ifi_poll_bytes
);
2005 printf(" [ sampled packets avg/min/max: %12u / %12u / %12u ]\n",
2006 sp
->ifi_poll_packets_avg
, sp
->ifi_poll_packets_min
,
2007 sp
->ifi_poll_packets_max
);
2008 printf(" [ sampled bytes avg/min/max: %12u / %12u / %12u ]\n",
2009 sp
->ifi_poll_bytes_avg
, sp
->ifi_poll_bytes_min
,
2010 sp
->ifi_poll_bytes_max
);
2011 printf(" [ sampled wakeups avg: %12u ]\n",
2012 sp
->ifi_poll_wakeups_avg
);
2013 printf(" [ packets lowat/hiwat threshold: %10u / %10u ]\n",
2014 sp
->ifi_poll_packets_lowat
, sp
->ifi_poll_packets_hiwat
);
2015 printf(" [ bytes lowat/hiwat threshold: %10u / %10u ]\n",
2016 sp
->ifi_poll_bytes_lowat
, sp
->ifi_poll_bytes_hiwat
);
2017 printf(" [ wakeups lowat/hiwat threshold: %10u / %10u ]\n",
2018 sp
->ifi_poll_wakeups_lowat
, sp
->ifi_poll_wakeups_hiwat
);
2023 sigemptyset(&sigset
);
2024 sigaddset(&sigset
, SIGALRM
);
2025 (void) sigprocmask(SIG_BLOCK
, &sigset
, &oldsigset
);
2027 sigemptyset(&sigset
);
2028 sigsuspend(&sigset
);
2030 (void) sigprocmask(SIG_SETMASK
, &oldsigset
, NULL
);