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
61 #include <sys/types.h>
62 #include <sys/socket.h>
63 #include <sys/sysctl.h>
64 #include <sys/ioctl.h>
68 #include <net/if_var.h>
69 #include <net/if_dl.h>
70 #include <net/if_types.h>
71 #include <net/if_mib.h>
72 #include <net/if_llreach.h>
73 #include <net/ethernet.h>
74 #include <net/route.h>
76 #include <net/pktsched/pktsched.h>
77 #include <net/classq/if_classq.h>
79 #include <netinet/in.h>
80 #include <netinet/in_var.h>
82 #include <arpa/inet.h>
97 #define ROUNDUP(a, size) (((a) & ((size) - 1)) ? (1 + ((a)|(size - 1))) : (a))
99 #define NEXT_SA(p) (struct sockaddr *) \
100 ((caddr_t)p + (p->sa_len ? ROUNDUP(p->sa_len, sizeof(uint32_t)) : \
103 static void sidewaysintpr ();
104 static void catchalarm (int);
105 static char *sec2str(time_t);
106 static void llreach_sysctl(uint32_t);
107 static char *nsec_to_str(unsigned long long);
108 static char *qtype2str(classq_type_t
);
109 static char *sched2str(unsigned int);
110 static char *qid2str(unsigned int);
111 static char *qstate2str(unsigned int);
112 static char *tcqslot2str(unsigned int);
113 static char *rate2str(long double);
121 u_int64_t prev_bytes
;
122 u_int64_t prev_packets
;
123 unsigned int printed
;
127 static void print_cbqstats(int slot
, struct cbq_classstats
*,
128 struct queue_stats
*);
129 static void print_priqstats(int slot
, struct priq_classstats
*,
130 struct queue_stats
*);
131 static void print_hfscstats(int slot
, struct hfsc_classstats
*,
132 struct queue_stats
*);
133 static void print_fairqstats(int slot
, struct fairq_classstats
*,
134 struct queue_stats
*);
135 static void print_tcqstats(int slot
, struct tcq_classstats
*,
136 struct queue_stats
*);
137 static void print_qfqstats(int slot
, struct qfq_classstats
*,
138 struct queue_stats
*);
139 static void print_sfbstats(struct sfb_stats
*);
140 static void update_avg(struct if_ifclassq_stats
*, struct queue_stats
*);
142 struct queue_stats qstats
[IFCQ_SC_MAX
];
145 char *netname6 (struct sockaddr_in6
*, struct sockaddr
*);
146 static char ntop_buf
[INET6_ADDRSTRLEN
]; /* for inet_ntop() */
150 * Display a formatted value, or a '-' in the same space.
153 show_stat(const char *fmt
, int width
, u_int64_t value
, short showvalue
)
157 /* Construct the format string */
159 snprintf(newfmt
, sizeof(newfmt
), "%%%d%s", width
, fmt
);
160 printf(newfmt
, value
);
162 snprintf(newfmt
, sizeof(newfmt
), "%%%ds", width
);
168 get_rti_info(int addrs
, struct sockaddr
*sa
, struct sockaddr
**rti_info
)
173 for (i
= 0; i
< RTAX_MAX
; i
++) {
174 if (addrs
& (1 << i
)) {
176 if (sa
->sa_len
< sizeof(struct sockaddr
))
177 len
+= sizeof(struct sockaddr
);
189 multipr(int family
, char *buf
, char *lim
)
193 for (next
= buf
; next
< lim
; ) {
194 struct ifma_msghdr2
*ifmam
= (struct ifma_msghdr2
*)next
;
195 struct sockaddr
*rti_info
[RTAX_MAX
];
199 next
+= ifmam
->ifmam_msglen
;
200 if (ifmam
->ifmam_type
== RTM_IFINFO2
)
202 else if (ifmam
->ifmam_type
!= RTM_NEWMADDR2
)
204 get_rti_info(ifmam
->ifmam_addrs
, (struct sockaddr
*)(ifmam
+ 1), rti_info
);
205 sa
= rti_info
[RTAX_IFA
];
207 if (sa
->sa_family
!= family
)
209 switch (sa
->sa_family
) {
211 struct sockaddr_in
*sin
= (struct sockaddr_in
*)sa
;
213 fmt
= routename(sin
->sin_addr
.s_addr
);
218 struct sockaddr_in6 sin6
;
220 memcpy(&sin6
, sa
, sizeof(struct sockaddr_in6
));
222 if (IN6_IS_ADDR_LINKLOCAL(&sin6
.sin6_addr
) ||
223 IN6_IS_ADDR_MC_NODELOCAL(&sin6
.sin6_addr
) ||
224 IN6_IS_ADDR_MC_LINKLOCAL(&sin6
.sin6_addr
)) {
225 sin6
.sin6_scope_id
= ntohs(*(u_int16_t
*)&sin6
.sin6_addr
.s6_addr
[2]);
226 sin6
.sin6_addr
.s6_addr
[2] = 0;
227 sin6
.sin6_addr
.s6_addr
[3] = 0;
230 printf("%23s %-19.19s(refs: %d)\n", "",
231 inet_ntop(AF_INET6
, &sin6
.sin6_addr
,
232 ntop_buf
, sizeof(ntop_buf
)),
233 ifmam
->ifmam_refcount
);
238 struct sockaddr_dl
*sdl
= (struct sockaddr_dl
*)sa
;
240 switch (sdl
->sdl_type
) {
243 fmt
= ether_ntoa((struct ether_addr
*)
251 printf("%23s %s\n", "", fmt
);
256 * Print a description of the network interfaces.
259 intpr(void (*pfunc
)(char *))
261 u_int64_t opackets
= 0;
262 u_int64_t ipackets
= 0;
263 u_int64_t obytes
= 0;
264 u_int64_t ibytes
= 0;
265 u_int64_t oerrors
= 0;
266 u_int64_t ierrors
= 0;
267 u_int64_t collisions
= 0;
268 u_int64_t fpackets
= 0;
269 u_int64_t fbytes
= 0;
273 struct sockaddr
*sa
= NULL
;
278 char *buf
= NULL
, *lim
, *next
;
280 struct if_msghdr
*ifm
;
281 struct sockaddr
*rti_info
[RTAX_MAX
];
282 unsigned int ifindex
= 0;
290 ifindex
= if_nametoindex(interface
);
292 mib
[0] = CTL_NET
; // networking subsystem
293 mib
[1] = PF_ROUTE
; // type of information
294 mib
[2] = 0; // protocol (IPPROTO_xxx)
295 mib
[3] = 0; // address family
296 mib
[4] = NET_RT_IFLIST2
; // operation
298 if (sysctl(mib
, 6, NULL
, &len
, NULL
, 0) < 0)
300 if ((buf
= malloc(len
)) == NULL
) {
301 printf("malloc failed\n");
304 if (sysctl(mib
, 6, buf
, &len
, NULL
, 0) < 0) {
311 printf("%-5.5s %-5.5s %-13.13s %-15.15s %8.8s %5.5s",
312 "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs");
314 printf(" %8.8s %8.8s", "Itcpkts", "Ipvpkts");
316 printf(" %10.10s","Ibytes");
318 printf(" %8.8s %8.8s", "Itcbytes", "Ipvbytes");
320 printf(" %8.8s %5.5s", "Opkts", "Oerrs");
322 printf(" %8.8s %8.8s", "Otcpkts", "Opvpkts");
324 printf(" %10.10s","Obytes");
326 printf(" %8.8s %8.8s", "Otcbytes", "Opvbytes");
328 printf(" %5s", "Coll");
330 printf(" %s", "Time");
332 printf(" %s", "Drop");
334 printf(" %8.8s", "Fpkts");
336 printf(" %10.10s", "Fbytes");
341 for (next
= buf
; next
< lim
; ) {
344 struct ifmibdata_supplemental ifmsupp
;
345 u_int64_t ift_itcp
= 0; /* input tc packets */
346 u_int64_t ift_itcb
= 0; /* input tc bytes */
347 u_int64_t ift_otcp
= 0; /* output tc packets */
348 u_int64_t ift_otcb
= 0; /* output tc bytes */
349 u_int64_t ift_ipvp
= 0; /* input priv tc packets */
350 u_int64_t ift_ipvb
= 0; /* input priv tc bytes */
351 u_int64_t ift_opvp
= 0; /* output priv tc packets */
352 u_int64_t ift_opvb
= 0; /* output priv tc bytes */
354 bzero(&ifmsupp
, sizeof(struct ifmibdata_supplemental
));
358 ifm
= (struct if_msghdr
*)next
;
359 next
+= ifm
->ifm_msglen
;
361 if (ifm
->ifm_type
== RTM_IFINFO2
) {
362 struct if_msghdr2
*if2m
= (struct if_msghdr2
*)ifm
;
363 struct sockaddr_dl
*sdl
=
364 (struct sockaddr_dl
*)(if2m
+ 1);
366 size_t miblen
= sizeof(struct ifmibdata_supplemental
);
368 strncpy(name
, sdl
->sdl_data
, sdl
->sdl_nlen
);
369 name
[sdl
->sdl_nlen
] = 0;
370 if (interface
!= 0 && if2m
->ifm_index
!= ifindex
)
372 cp
= index(name
, '\0');
379 if ((if2m
->ifm_flags
& IFF_UP
) == 0)
384 * Get the interface stats. These may get
385 * overriden below on a per-interface basis.
387 opackets
= if2m
->ifm_data
.ifi_opackets
;
388 ipackets
= if2m
->ifm_data
.ifi_ipackets
;
389 obytes
= if2m
->ifm_data
.ifi_obytes
;
390 ibytes
= if2m
->ifm_data
.ifi_ibytes
;
391 oerrors
=if2m
->ifm_data
.ifi_oerrors
;
392 ierrors
= if2m
->ifm_data
.ifi_ierrors
;
393 collisions
= if2m
->ifm_data
.ifi_collisions
;
394 timer
= if2m
->ifm_timer
;
395 drops
= if2m
->ifm_snd_drops
;
396 mtu
= if2m
->ifm_data
.ifi_mtu
;
398 /* Common OID prefix */
399 mibname
[0] = CTL_NET
;
400 mibname
[1] = PF_LINK
;
401 mibname
[2] = NETLINK_GENERIC
;
402 mibname
[3] = IFMIB_IFDATA
;
403 mibname
[4] = if2m
->ifm_index
;
404 mibname
[5] = IFDATA_SUPPLEMENTAL
;
405 if (sysctl(mibname
, 6, &ifmsupp
, &miblen
, NULL
, 0) == -1)
406 err(1, "sysctl IFDATA_SUPPLEMENTAL");
408 fpackets
= ifmsupp
.ifmd_data_extended
.ifi_fpackets
;
409 fbytes
= ifmsupp
.ifmd_data_extended
.ifi_fbytes
;
414 ift_itcp
= ifmsupp
.ifmd_traffic_class
.ifi_ibepackets
;
415 ift_itcb
= ifmsupp
.ifmd_traffic_class
.ifi_ibebytes
;
416 ift_otcp
= ifmsupp
.ifmd_traffic_class
.ifi_obepackets
;
417 ift_otcb
= ifmsupp
.ifmd_traffic_class
.ifi_obebytes
;
420 ift_itcp
= ifmsupp
.ifmd_traffic_class
.ifi_ibkpackets
;
421 ift_itcb
= ifmsupp
.ifmd_traffic_class
.ifi_ibkbytes
;
422 ift_otcp
= ifmsupp
.ifmd_traffic_class
.ifi_obkpackets
;
423 ift_otcb
= ifmsupp
.ifmd_traffic_class
.ifi_obkbytes
;
426 ift_itcp
= ifmsupp
.ifmd_traffic_class
.ifi_ivipackets
;
427 ift_itcb
= ifmsupp
.ifmd_traffic_class
.ifi_ivibytes
;
428 ift_otcp
= ifmsupp
.ifmd_traffic_class
.ifi_ovipackets
;
429 ift_otcb
= ifmsupp
.ifmd_traffic_class
.ifi_ovibytes
;
432 ift_itcp
= ifmsupp
.ifmd_traffic_class
.ifi_ivopackets
;
433 ift_itcb
= ifmsupp
.ifmd_traffic_class
.ifi_ivobytes
;
434 ift_otcp
= ifmsupp
.ifmd_traffic_class
.ifi_ovopackets
;
435 ift_otcb
= ifmsupp
.ifmd_traffic_class
.ifi_ovobytes
;
448 ift_ipvp
= ifmsupp
.ifmd_traffic_class
.ifi_ipvpackets
;
449 ift_ipvb
= ifmsupp
.ifmd_traffic_class
.ifi_ipvbytes
;
450 ift_opvp
= ifmsupp
.ifmd_traffic_class
.ifi_opvpackets
;
451 ift_opvb
= ifmsupp
.ifmd_traffic_class
.ifi_opvbytes
;
454 get_rti_info(if2m
->ifm_addrs
,
455 (struct sockaddr
*)(if2m
+ 1), rti_info
);
456 sa
= rti_info
[RTAX_IFP
];
457 } else if (ifm
->ifm_type
== RTM_NEWADDR
) {
458 struct ifa_msghdr
*ifam
= (struct ifa_msghdr
*)ifm
;
460 if (interface
!= 0 && ifam
->ifam_index
!= ifindex
)
462 get_rti_info(ifam
->ifam_addrs
,
463 (struct sockaddr
*)(ifam
+ 1), rti_info
);
464 sa
= rti_info
[RTAX_IFA
];
468 printf("%-5.5s %-5u ", name
, mtu
);
471 printf("%-13.13s ", "none");
472 printf("%-15.15s ", "none");
474 switch (sa
->sa_family
) {
476 printf("%-13.13s ", "none");
477 printf("%-15.15s ", "none");
481 struct sockaddr_in
*sin
=
482 (struct sockaddr_in
*)sa
;
483 struct sockaddr_in mask
;
485 mask
.sin_addr
.s_addr
= 0;
486 memcpy(&mask
, rti_info
[RTAX_NETMASK
],
487 ((struct sockaddr_in
*)
488 rti_info
[RTAX_NETMASK
])->sin_len
);
491 netname(sin
->sin_addr
.s_addr
&
492 mask
.sin_addr
.s_addr
,
493 ntohl(mask
.sin_addr
.s_addr
)));
496 routename(sin
->sin_addr
.s_addr
));
503 struct sockaddr_in6
*sin6
=
504 (struct sockaddr_in6
*)sa
;
505 struct sockaddr
*mask
=
506 (struct sockaddr
*)rti_info
[RTAX_NETMASK
];
508 printf("%-11.11s ", netname6(sin6
, mask
));
509 printf("%-17.17s ", (char *)inet_ntop(AF_INET6
,
510 &sin6
->sin6_addr
, ntop_buf
,
518 struct sockaddr_dl
*sdl
=
519 (struct sockaddr_dl
*)sa
;
521 cp
= (char *)LLADDR(sdl
);
523 snprintf(linknum
, sizeof(linknum
),
524 "<Link#%d>", sdl
->sdl_index
);
525 m
= printf("%-11.11s ", linknum
);
530 m
= printf("(%d)", sa
->sa_family
);
531 for (cp
= sa
->sa_len
+ (char *)sa
;
532 --cp
> sa
->sa_data
&& (*cp
== 0);) {}
533 n
= cp
- sa
->sa_data
+ 1;
537 m
+= printf("%02x%c", *cp
++ & 0xff,
548 show_stat("llu", 8, ipackets
, link_layer
|network_layer
);
550 show_stat("llu", 5, ierrors
, link_layer
);
553 show_stat("llu", 8, ift_itcp
, link_layer
|network_layer
);
555 show_stat("llu", 8, ift_ipvp
, link_layer
|network_layer
);
559 show_stat("llu", 10, ibytes
, link_layer
|network_layer
);
562 show_stat("llu", 8, ift_itcb
, link_layer
|network_layer
);
564 show_stat("llu", 8, ift_ipvb
, link_layer
|network_layer
);
568 show_stat("llu", 8, opackets
, link_layer
|network_layer
);
570 show_stat("llu", 5, oerrors
, link_layer
);
573 show_stat("llu", 8, ift_otcp
, link_layer
|network_layer
);
575 show_stat("llu", 8, ift_opvp
, link_layer
|network_layer
);
579 show_stat("llu", 10, obytes
, link_layer
|network_layer
);
582 show_stat("llu", 8, ift_otcb
, link_layer
|network_layer
);
584 show_stat("llu", 8, ift_opvb
, link_layer
|network_layer
);
588 show_stat("llu", 5, collisions
, link_layer
);
591 show_stat("d", 3, timer
, link_layer
);
595 show_stat("d", 3, drops
, link_layer
);
599 show_stat("llu", 8, fpackets
, link_layer
|network_layer
);
602 show_stat("llu", 10, fbytes
,
603 link_layer
|network_layer
);
609 multipr(sa
->sa_family
, next
, lim
);
615 SLIST_ENTRY(iftot
) chain
;
616 char ift_name
[16]; /* interface name */
617 u_int64_t ift_ip
; /* input packets */
618 u_int64_t ift_ie
; /* input errors */
619 u_int64_t ift_op
; /* output packets */
620 u_int64_t ift_oe
; /* output errors */
621 u_int64_t ift_co
; /* collisions */
622 u_int64_t ift_dr
; /* drops */
623 u_int64_t ift_ib
; /* input bytes */
624 u_int64_t ift_ob
; /* output bytes */
625 u_int64_t ift_itcp
; /* input tc packets */
626 u_int64_t ift_itcb
; /* input tc bytes */
627 u_int64_t ift_otcp
; /* output tc packets */
628 u_int64_t ift_otcb
; /* output tc bytes */
629 u_int64_t ift_ipvp
; /* input priv tc packets */
630 u_int64_t ift_ipvb
; /* input priv tc bytes */
631 u_int64_t ift_opvp
; /* output priv tc packets */
632 u_int64_t ift_opvb
; /* output priv tc bytes */
633 u_int64_t ift_fp
; /* forwarded packets */
634 u_int64_t ift_fb
; /* forwarded bytes */
637 u_char signalled
; /* set if alarm goes off "early" */
640 * Print a running summary of interface statistics.
641 * Repeat display every interval seconds, showing statistics
642 * collected over that interval. Assumes that interval is non-zero.
643 * First line printed at top of screen is always cumulative.
644 * XXX - should be rewritten to use ifmib(4).
649 struct iftot
*total
, *sum
, *interesting
;
654 unsigned int ifcount
, i
;
655 struct ifmibdata
*ifmdall
= 0;
657 sigset_t sigset
, oldsigset
;
658 struct itimerval timer_interval
;
660 /* Common OID prefix */
663 name
[2] = NETLINK_GENERIC
;
666 name
[3] = IFMIB_SYSTEM
;
667 name
[4] = IFMIB_IFCOUNT
;
668 if (sysctl(name
, 5, &ifcount
, &len
, 0, 0) == 1)
669 err(1, "sysctl IFMIB_IFCOUNT");
671 len
= ifcount
* sizeof(struct ifmibdata
);
672 ifmdall
= malloc(len
);
674 err(1, "malloc failed");
675 name
[3] = IFMIB_IFALLDATA
;
677 name
[5] = IFDATA_GENERAL
;
678 if (sysctl(name
, 6, ifmdall
, &len
, (void *)0, 0) == -1)
679 err(1, "sysctl IFMIB_IFALLDATA");
683 for (i
= 0; i
< ifcount
; i
++) {
684 struct ifmibdata
*ifmd
= ifmdall
+ i
;
686 if (interface
&& strcmp(ifmd
->ifmd_name
, interface
) == 0) {
687 if ((interesting
= calloc(ifcount
,
688 sizeof(struct iftot
))) == NULL
)
689 err(1, "malloc failed");
690 interesting_row
= if_nametoindex(interface
);
691 snprintf(interesting
->ift_name
, 16, "(%s)",
695 if ((total
= calloc(1, sizeof(struct iftot
))) == NULL
)
696 err(1, "malloc failed");
698 if ((sum
= calloc(1, sizeof(struct iftot
))) == NULL
)
699 err(1, "malloc failed");
701 /* create a timer that fires repeatedly every interval seconds */
702 timer_interval
.it_value
.tv_sec
= interval
;
703 timer_interval
.it_value
.tv_usec
= 0;
704 timer_interval
.it_interval
.tv_sec
= interval
;
705 timer_interval
.it_interval
.tv_usec
= 0;
706 (void)signal(SIGALRM
, catchalarm
);
708 (void)setitimer(ITIMER_REAL
, &timer_interval
, NULL
);
715 printf("%39s %39s %36s", "input",
716 interesting
? interesting
->ift_name
: "(Total)", "output");
718 printf("%17s %14s %16s", "input",
719 interesting
? interesting
->ift_name
: "(Total)", "output");
725 printf("%10s %5s %10s ", "packets", "errs", "bytes");
727 printf(" %10s %10s %10s %10s",
728 "tcpkts", "tcbytes", "pvpkts", "pvbytes");
729 printf("%10s %5s %10s %5s", "packets", "errs", "bytes", "colls");
731 printf(" %5.5s", "drops");
733 printf(" %10s %10s %10s %10s",
734 "tcpkts", "tcbytes", "pvpkts", "pvbytes");
736 printf(" %10s %10s", "fpackets", "fbytes");
744 if (interesting
!= NULL
) {
745 struct ifmibdata ifmd
;
746 struct ifmibdata_supplemental ifmsupp
;
748 len
= sizeof(struct ifmibdata
);
749 name
[3] = IFMIB_IFDATA
;
750 name
[4] = interesting_row
;
751 name
[5] = IFDATA_GENERAL
;
752 if (sysctl(name
, 6, &ifmd
, &len
, (void *)0, 0) == -1)
753 err(1, "sysctl IFDATA_GENERAL %d", interesting_row
);
755 len
= sizeof(struct ifmibdata_supplemental
);
756 name
[3] = IFMIB_IFDATA
;
757 name
[4] = interesting_row
;
758 name
[5] = IFDATA_SUPPLEMENTAL
;
759 if (sysctl(name
, 6, &ifmsupp
, &len
, (void *)0, 0) == -1)
760 err(1, "sysctl IFDATA_SUPPLEMENTAL %d",
764 printf("%10llu %5llu %10llu ",
765 ifmd
.ifmd_data
.ifi_ipackets
- interesting
->ift_ip
,
766 ifmd
.ifmd_data
.ifi_ierrors
- interesting
->ift_ie
,
767 ifmd
.ifmd_data
.ifi_ibytes
- interesting
->ift_ib
);
770 printf("%10llu %10llu ",
771 ifmsupp
.ifmd_traffic_class
.ifi_ibepackets
-
772 interesting
->ift_itcp
,
773 ifmsupp
.ifmd_traffic_class
.ifi_ibebytes
-
774 interesting
->ift_itcb
);
777 printf("%10llu %10llu ",
778 ifmsupp
.ifmd_traffic_class
.ifi_ibkpackets
-
779 interesting
->ift_itcp
,
780 ifmsupp
.ifmd_traffic_class
.ifi_ibkbytes
-
781 interesting
->ift_itcb
);
784 printf("%10llu %10llu ",
785 ifmsupp
.ifmd_traffic_class
.ifi_ivipackets
-
786 interesting
->ift_itcp
,
787 ifmsupp
.ifmd_traffic_class
.ifi_ivibytes
-
788 interesting
->ift_itcb
);
791 printf("%10llu %10llu ",
792 ifmsupp
.ifmd_traffic_class
.ifi_ivopackets
-
793 interesting
->ift_itcp
,
794 ifmsupp
.ifmd_traffic_class
.ifi_ivobytes
-
795 interesting
->ift_itcb
);
801 printf("%10llu %10llu ",
802 ifmsupp
.ifmd_traffic_class
.ifi_ipvpackets
-
803 interesting
->ift_ipvp
,
804 ifmsupp
.ifmd_traffic_class
.ifi_ipvbytes
-
805 interesting
->ift_ipvb
);
807 printf("%10llu %5llu %10llu %5llu",
808 ifmd
.ifmd_data
.ifi_opackets
- interesting
->ift_op
,
809 ifmd
.ifmd_data
.ifi_oerrors
- interesting
->ift_oe
,
810 ifmd
.ifmd_data
.ifi_obytes
- interesting
->ift_ob
,
811 ifmd
.ifmd_data
.ifi_collisions
- interesting
->ift_co
);
814 ifmd
.ifmd_snd_drops
- interesting
->ift_dr
);
817 printf(" %10llu %10llu",
818 ifmsupp
.ifmd_traffic_class
.ifi_obepackets
-
819 interesting
->ift_otcp
,
820 ifmsupp
.ifmd_traffic_class
.ifi_obebytes
-
821 interesting
->ift_otcb
);
824 printf(" %10llu %10llu",
825 ifmsupp
.ifmd_traffic_class
.ifi_obkpackets
-
826 interesting
->ift_otcp
,
827 ifmsupp
.ifmd_traffic_class
.ifi_obkbytes
-
828 interesting
->ift_otcb
);
831 printf(" %10llu %10llu",
832 ifmsupp
.ifmd_traffic_class
.ifi_ovipackets
-
833 interesting
->ift_otcp
,
834 ifmsupp
.ifmd_traffic_class
.ifi_ovibytes
-
835 interesting
->ift_otcb
);
838 printf(" %10llu %10llu",
839 ifmsupp
.ifmd_traffic_class
.ifi_ovopackets
-
840 interesting
->ift_otcp
,
841 ifmsupp
.ifmd_traffic_class
.ifi_ovobytes
-
842 interesting
->ift_otcb
);
848 printf("%10llu %10llu ",
849 ifmsupp
.ifmd_traffic_class
.ifi_opvpackets
-
850 interesting
->ift_opvp
,
851 ifmsupp
.ifmd_traffic_class
.ifi_opvbytes
-
852 interesting
->ift_opvb
);
855 printf("%10llu %10llu",
856 ifmsupp
.ifmd_data_extended
.ifi_fpackets
-
858 ifmsupp
.ifmd_data_extended
.ifi_fbytes
-
859 interesting
->ift_fb
);
862 interesting
->ift_ip
= ifmd
.ifmd_data
.ifi_ipackets
;
863 interesting
->ift_ie
= ifmd
.ifmd_data
.ifi_ierrors
;
864 interesting
->ift_ib
= ifmd
.ifmd_data
.ifi_ibytes
;
865 interesting
->ift_op
= ifmd
.ifmd_data
.ifi_opackets
;
866 interesting
->ift_oe
= ifmd
.ifmd_data
.ifi_oerrors
;
867 interesting
->ift_ob
= ifmd
.ifmd_data
.ifi_obytes
;
868 interesting
->ift_co
= ifmd
.ifmd_data
.ifi_collisions
;
869 interesting
->ift_dr
= ifmd
.ifmd_snd_drops
;
871 /* private counters */
874 interesting
->ift_itcp
=
875 ifmsupp
.ifmd_traffic_class
.ifi_ibepackets
;
876 interesting
->ift_itcb
=
877 ifmsupp
.ifmd_traffic_class
.ifi_ibebytes
;
878 interesting
->ift_otcp
=
879 ifmsupp
.ifmd_traffic_class
.ifi_obepackets
;
880 interesting
->ift_otcb
=
881 ifmsupp
.ifmd_traffic_class
.ifi_obebytes
;
884 interesting
->ift_itcp
=
885 ifmsupp
.ifmd_traffic_class
.ifi_ibkpackets
;
886 interesting
->ift_itcb
=
887 ifmsupp
.ifmd_traffic_class
.ifi_ibkbytes
;
888 interesting
->ift_otcp
=
889 ifmsupp
.ifmd_traffic_class
.ifi_obkpackets
;
890 interesting
->ift_otcb
=
891 ifmsupp
.ifmd_traffic_class
.ifi_obkbytes
;
894 interesting
->ift_itcp
=
895 ifmsupp
.ifmd_traffic_class
.ifi_ivipackets
;
896 interesting
->ift_itcb
=
897 ifmsupp
.ifmd_traffic_class
.ifi_ivibytes
;
898 interesting
->ift_otcp
=
899 ifmsupp
.ifmd_traffic_class
.ifi_ovipackets
;
900 interesting
->ift_otcb
=
901 ifmsupp
.ifmd_traffic_class
.ifi_ovibytes
;
904 interesting
->ift_itcp
=
905 ifmsupp
.ifmd_traffic_class
.ifi_ivopackets
;
906 interesting
->ift_itcb
=
907 ifmsupp
.ifmd_traffic_class
.ifi_ivobytes
;
908 interesting
->ift_otcp
=
909 ifmsupp
.ifmd_traffic_class
.ifi_ovopackets
;
910 interesting
->ift_otcb
=
911 ifmsupp
.ifmd_traffic_class
.ifi_ovobytes
;
917 interesting
->ift_ipvp
=
918 ifmsupp
.ifmd_traffic_class
.ifi_ipvpackets
;
919 interesting
->ift_ipvb
=
920 ifmsupp
.ifmd_traffic_class
.ifi_ipvbytes
;
921 interesting
->ift_opvp
=
922 ifmsupp
.ifmd_traffic_class
.ifi_opvpackets
;
923 interesting
->ift_opvb
=
924 ifmsupp
.ifmd_traffic_class
.ifi_opvbytes
;
926 interesting
->ift_fp
= ifmsupp
.ifmd_data_extended
.ifi_fpackets
;
927 interesting
->ift_fb
= ifmsupp
.ifmd_data_extended
.ifi_fbytes
;
929 unsigned int latest_ifcount
;
930 struct ifmibdata_supplemental
*ifmsuppall
= NULL
;
933 name
[3] = IFMIB_SYSTEM
;
934 name
[4] = IFMIB_IFCOUNT
;
935 if (sysctl(name
, 5, &latest_ifcount
, &len
, 0, 0) == 1)
936 err(1, "sysctl IFMIB_IFCOUNT");
937 if (latest_ifcount
> ifcount
) {
938 ifcount
= latest_ifcount
;
939 len
= ifcount
* sizeof(struct ifmibdata
);
941 ifmdall
= malloc(len
);
943 err(1, "malloc ifmdall failed");
944 } else if (latest_ifcount
> ifcount
) {
945 ifcount
= latest_ifcount
;
946 len
= ifcount
* sizeof(struct ifmibdata
);
948 len
= ifcount
* sizeof(struct ifmibdata
);
949 name
[3] = IFMIB_IFALLDATA
;
951 name
[5] = IFDATA_GENERAL
;
952 if (sysctl(name
, 6, ifmdall
, &len
, (void *)0, 0) == -1)
953 err(1, "sysctl IFMIB_IFALLDATA");
955 len
= ifcount
* sizeof(struct ifmibdata_supplemental
);
956 ifmsuppall
= malloc(len
);
957 if (ifmsuppall
== NULL
)
958 err(1, "malloc ifmsuppall failed");
959 name
[3] = IFMIB_IFALLDATA
;
961 name
[5] = IFDATA_SUPPLEMENTAL
;
962 if (sysctl(name
, 6, ifmsuppall
, &len
, (void *)0, 0) == -1)
963 err(1, "sysctl IFMIB_IFALLDATA SUPPLEMENTAL");
983 for (i
= 0; i
< ifcount
; i
++) {
984 struct ifmibdata
*ifmd
= ifmdall
+ i
;
985 struct ifmibdata_supplemental
*ifmsupp
= ifmsuppall
+ i
;
987 sum
->ift_ip
+= ifmd
->ifmd_data
.ifi_ipackets
;
988 sum
->ift_ie
+= ifmd
->ifmd_data
.ifi_ierrors
;
989 sum
->ift_ib
+= ifmd
->ifmd_data
.ifi_ibytes
;
990 sum
->ift_op
+= ifmd
->ifmd_data
.ifi_opackets
;
991 sum
->ift_oe
+= ifmd
->ifmd_data
.ifi_oerrors
;
992 sum
->ift_ob
+= ifmd
->ifmd_data
.ifi_obytes
;
993 sum
->ift_co
+= ifmd
->ifmd_data
.ifi_collisions
;
994 sum
->ift_dr
+= ifmd
->ifmd_snd_drops
;
995 /* private counters */
999 sum
->ift_itcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ibepackets
;
1000 sum
->ift_itcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ibebytes
;
1001 sum
->ift_otcp
+= ifmsupp
->ifmd_traffic_class
.ifi_obepackets
;
1002 sum
->ift_otcb
+= ifmsupp
->ifmd_traffic_class
.ifi_obebytes
;
1005 sum
->ift_itcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ibkpackets
;
1006 sum
->ift_itcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ibkbytes
;
1007 sum
->ift_otcp
+= ifmsupp
->ifmd_traffic_class
.ifi_obkpackets
;
1008 sum
->ift_otcb
+= ifmsupp
->ifmd_traffic_class
.ifi_obkbytes
;
1011 sum
->ift_itcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ivipackets
;
1012 sum
->ift_itcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ivibytes
;
1013 sum
->ift_otcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ovipackets
;
1014 sum
->ift_otcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ovibytes
;
1017 sum
->ift_itcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ivopackets
;
1018 sum
->ift_itcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ivobytes
;
1019 sum
->ift_otcp
+= ifmsupp
->ifmd_traffic_class
.ifi_ovopackets
;
1020 sum
->ift_otcb
+= ifmsupp
->ifmd_traffic_class
.ifi_ovobytes
;
1025 sum
->ift_ipvp
+= ifmsupp
->ifmd_traffic_class
.ifi_ipvpackets
;
1026 sum
->ift_ipvb
+= ifmsupp
->ifmd_traffic_class
.ifi_ipvbytes
;
1027 sum
->ift_opvp
+= ifmsupp
->ifmd_traffic_class
.ifi_opvpackets
;
1028 sum
->ift_opvb
+= ifmsupp
->ifmd_traffic_class
.ifi_opvbytes
;
1030 sum
->ift_fp
+= ifmsupp
->ifmd_data_extended
.ifi_fpackets
;
1031 sum
->ift_fb
+= ifmsupp
->ifmd_data_extended
.ifi_fbytes
;
1034 printf("%10llu %5llu %10llu ",
1035 sum
->ift_ip
- total
->ift_ip
,
1036 sum
->ift_ie
- total
->ift_ie
,
1037 sum
->ift_ib
- total
->ift_ib
);
1039 printf(" %10llu %10llu %10llu %10llu",
1040 sum
->ift_itcp
- total
->ift_itcp
,
1041 sum
->ift_itcb
- total
->ift_itcb
,
1042 sum
->ift_ipvp
- total
->ift_ipvp
,
1043 sum
->ift_ipvb
- total
->ift_ipvb
);
1044 printf("%10llu %5llu %10llu %5llu",
1045 sum
->ift_op
- total
->ift_op
,
1046 sum
->ift_oe
- total
->ift_oe
,
1047 sum
->ift_ob
- total
->ift_ob
,
1048 sum
->ift_co
- total
->ift_co
);
1050 printf(" %5llu", sum
->ift_dr
- total
->ift_dr
);
1052 printf(" %10llu %10llu %10llu %10llu",
1053 sum
->ift_otcp
- total
->ift_otcp
,
1054 sum
->ift_otcb
- total
->ift_otcb
,
1055 sum
->ift_opvp
- total
->ift_opvp
,
1056 sum
->ift_opvb
- total
->ift_opvb
);
1058 printf(" %10llu %10llu",
1059 sum
->ift_fp
- total
->ift_fp
,
1060 sum
->ift_fb
- total
->ift_fb
);
1067 sigemptyset(&sigset
);
1068 sigaddset(&sigset
, SIGALRM
);
1069 (void)sigprocmask(SIG_BLOCK
, &sigset
, &oldsigset
);
1071 sigemptyset(&sigset
);
1072 sigsuspend(&sigset
);
1074 (void)sigprocmask(SIG_SETMASK
, &oldsigset
, NULL
);
1087 intervalpr(void (*pr
)(uint32_t, char *, int), uint32_t off
, char *name
, int af
)
1089 struct itimerval timer_interval
;
1090 sigset_t sigset
, oldsigset
;
1092 /* create a timer that fires repeatedly every interval seconds */
1093 timer_interval
.it_value
.tv_sec
= interval
;
1094 timer_interval
.it_value
.tv_usec
= 0;
1095 timer_interval
.it_interval
.tv_sec
= interval
;
1096 timer_interval
.it_interval
.tv_usec
= 0;
1097 (void) signal(SIGALRM
, catchalarm
);
1099 (void) setitimer(ITIMER_REAL
, &timer_interval
, NULL
);
1105 sigemptyset(&sigset
);
1106 sigaddset(&sigset
, SIGALRM
);
1107 (void) sigprocmask(SIG_BLOCK
, &sigset
, &oldsigset
);
1109 sigemptyset(&sigset
);
1110 sigsuspend(&sigset
);
1112 (void) sigprocmask(SIG_SETMASK
, &oldsigset
, NULL
);
1118 * Called if an interval expires before sidewaysintpr has completed a loop.
1119 * Sets a flag to not wait for the alarm.
1122 catchalarm(int signo
)
1131 static char result
[256];
1132 int days
, hours
, mins
, secs
;
1136 days
= total
/ 3600 / 24;
1137 hours
= (total
/ 3600) % 24;
1138 mins
= (total
/ 60) % 60;
1143 p
+= snprintf(p
, sizeof(result
) - (p
- result
), "%dd", days
);
1145 if (!first
|| hours
) {
1147 p
+= snprintf(p
, sizeof(result
) - (p
- result
), "%dh", hours
);
1149 if (!first
|| mins
) {
1151 p
+= snprintf(p
, sizeof(result
) - (p
- result
), "%dm", mins
);
1153 snprintf(p
, sizeof(result
) - (p
- result
), "%ds", secs
);
1159 intpr_ri(void (*pfunc
)(char *))
1162 char *buf
= NULL
, *lim
, *next
;
1164 unsigned int ifindex
= 0;
1165 struct if_msghdr2
*if2m
;
1167 if (interface
!= 0) {
1168 ifindex
= if_nametoindex(interface
);
1170 printf("interface name is not valid: %s\n", interface
);
1175 mib
[0] = CTL_NET
; /* networking subsystem */
1176 mib
[1] = PF_ROUTE
; /* type of information */
1177 mib
[2] = 0; /* protocol (IPPROTO_xxx) */
1178 mib
[3] = 0; /* address family */
1179 mib
[4] = NET_RT_IFLIST2
; /* operation */
1181 if (sysctl(mib
, 6, NULL
, &len
, NULL
, 0) < 0)
1183 if ((buf
= malloc(len
)) == NULL
) {
1184 printf("malloc failed\n");
1187 if (sysctl(mib
, 6, buf
, &len
, NULL
, 0) < 0) {
1192 printf("%-6s %-17s %8.8s %-9.9s %4s %4s",
1193 "Proto", "Linklayer Address", "Netif", "Expire", "Refs",
1196 printf(" %7s %7s %7s", "RSSI", "LQM", "NPM");
1200 if2m
= (struct if_msghdr2
*)buf
;
1202 for (next
= buf
; next
< lim
; ) {
1203 if2m
= (struct if_msghdr2
*)next
;
1204 next
+= if2m
->ifm_msglen
;
1206 if (if2m
->ifm_type
!= RTM_IFINFO2
)
1208 else if (interface
!= 0 && if2m
->ifm_index
!= ifindex
)
1211 llreach_sysctl(if2m
->ifm_index
);
1217 llreach_sysctl(uint32_t ifindex
)
1219 #define MAX_SYSCTL_TRY 5
1220 int mib
[6], i
, ntry
= 0;
1221 size_t mibsize
, len
, needed
, cnt
;
1222 struct if_llreach_info
*lri
;
1223 struct timeval time
;
1225 char ifname
[IF_NAMESIZE
];
1227 bzero(&mib
, sizeof (mib
));
1228 mibsize
= sizeof (mib
) / sizeof (mib
[0]);
1229 if (sysctlnametomib("net.link.generic.system.llreach_info", mib
,
1231 perror("sysctlnametomib");
1238 mibsize
= sizeof (mib
) / sizeof (mib
[0]);
1240 if (sysctl(mib
, mibsize
, NULL
, &needed
, NULL
, 0) == -1) {
1241 perror("sysctl net.link.generic.system.llreach_info");
1244 if ((buf
= malloc(needed
)) == NULL
) {
1248 if (sysctl(mib
, mibsize
, buf
, &needed
, NULL
, 0) == -1) {
1249 if (errno
!= ENOMEM
|| ++ntry
>= MAX_SYSCTL_TRY
) {
1256 } while (buf
== NULL
);
1259 cnt
= len
/ sizeof (*lri
);
1260 lri
= (struct if_llreach_info
*)buf
;
1262 gettimeofday(&time
, 0);
1263 if (if_indextoname(ifindex
, ifname
) == NULL
)
1264 snprintf(ifname
, sizeof (ifname
), "%s", "?");
1266 for (i
= 0; i
< cnt
; i
++, lri
++) {
1267 printf("0x%-4x %-17s %8.8s ", lri
->lri_proto
,
1268 ether_ntoa((struct ether_addr
*)lri
->lri_addr
), ifname
);
1270 if (lri
->lri_expire
> time
.tv_sec
)
1271 printf("%-9.9s", sec2str(lri
->lri_expire
- time
.tv_sec
));
1272 else if (lri
->lri_expire
== 0)
1273 printf("%-9.9s", "permanent");
1275 printf("%-9.9s", "expired");
1277 printf(" %4d", lri
->lri_refcnt
);
1278 if (lri
->lri_probes
)
1279 printf(" %4d", lri
->lri_probes
);
1282 if (!lri
->lri_probes
)
1283 printf(" %-4.4s", "none");
1285 if (lri
->lri_rssi
!= IFNET_RSSI_UNKNOWN
)
1286 printf(" %7d", lri
->lri_rssi
);
1288 printf(" %-7.7s", "unknown");
1290 switch (lri
->lri_lqm
)
1292 case IFNET_LQM_THRESH_OFF
:
1293 printf(" %-7.7s", "off");
1295 case IFNET_LQM_THRESH_UNKNOWN
:
1296 printf(" %-7.7s", "unknown");
1298 case IFNET_LQM_THRESH_POOR
:
1299 printf(" %-7.7s", "poor");
1301 case IFNET_LQM_THRESH_GOOD
:
1302 printf(" %-7.7s", "good");
1305 printf(" %7d", lri
->lri_lqm
);
1309 switch (lri
->lri_npm
)
1311 case IFNET_NPM_THRESH_UNKNOWN
:
1312 printf(" %-7.7s", "unknown");
1314 case IFNET_NPM_THRESH_NEAR
:
1315 printf(" %-7.7s", "near");
1317 case IFNET_NPM_THRESH_GENERAL
:
1318 printf(" %-7.7s", "general");
1320 case IFNET_NPM_THRESH_FAR
:
1321 printf(" %-7.7s", "far");
1324 printf(" %7d", lri
->lri_npm
);
1330 len
-= sizeof (*lri
);
1334 fprintf(stderr
, "warning: %u trailing bytes from %s\n",
1335 (unsigned int)len
, "net.link.generic.system.llreach_info");
1340 #undef MAX_SYSCTL_TRY
1346 unsigned int ifindex
;
1347 struct itimerval timer_interval
;
1348 struct if_qstatsreq ifqr
;
1349 struct if_ifclassq_stats
*ifcqs
;
1350 sigset_t sigset
, oldsigset
;
1351 u_int32_t scheduler
;
1354 if (cq
< -1 || cq
>= IFCQ_SC_MAX
) {
1355 fprintf(stderr
, "Invalid classq index (range is 0-%d)\n",
1359 ifindex
= if_nametoindex(interface
);
1361 fprintf(stderr
, "Invalid interface name\n");
1365 ifcqs
= malloc(sizeof (*ifcqs
));
1366 if (ifcqs
== NULL
) {
1367 fprintf(stderr
, "Unable to allocate memory\n");
1371 if ((s
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0) {
1372 perror("Warning: socket(AF_INET)");
1377 bzero(&ifqr
, sizeof (ifqr
));
1378 strlcpy(ifqr
.ifqr_name
, interface
, sizeof (ifqr
.ifqr_name
));
1379 ifqr
.ifqr_buf
= ifcqs
;
1380 ifqr
.ifqr_len
= sizeof (*ifcqs
);
1384 /* create a timer that fires repeatedly every interval seconds */
1385 timer_interval
.it_value
.tv_sec
= interval
;
1386 timer_interval
.it_value
.tv_usec
= 0;
1387 timer_interval
.it_interval
.tv_sec
= interval
;
1388 timer_interval
.it_interval
.tv_usec
= 0;
1389 (void) signal(SIGALRM
, catchalarm
);
1391 (void) setitimer(ITIMER_REAL
, &timer_interval
, NULL
);
1395 if (ioctl(s
, SIOCGIFQUEUESTATS
, (char *)&ifqr
) < 0) {
1396 if (errno
== ENXIO
) {
1397 printf("Queue statistics are not available on %s\n",
1400 perror("Warning: ioctl(SIOCGIFQUEUESTATS)");
1404 scheduler
= ifcqs
->ifqs_scheduler
;
1405 tcq
= (scheduler
== PKTSCHEDT_TCQ
);
1408 "%s [ sched: %9s %sqlength: %3d/%3d ]\n",
1409 interface
, tcq
? " " : "", sched2str(ifcqs
->ifqs_scheduler
),
1410 tcq
? "" : " ", ifcqs
->ifqs_len
, ifcqs
->ifqs_maxlen
);
1411 printf("%s [ pkts: %10llu %sbytes: %10llu "
1412 "%sdropped pkts: %6llu bytes: %6llu ]\n",
1413 (scheduler
!= PKTSCHEDT_TCQ
) ? "" : " ",
1414 ifcqs
->ifqs_xmitcnt
.packets
, tcq
? "" : " ",
1415 ifcqs
->ifqs_xmitcnt
.bytes
, tcq
? "" : " ",
1416 ifcqs
->ifqs_dropcnt
.packets
, ifcqs
->ifqs_dropcnt
.bytes
);
1418 for (n
= 0; n
< IFCQ_SC_MAX
; n
++) {
1419 qstats
[n
].printed
= 0;
1423 if (ioctl(s
, SIOCGIFQUEUESTATS
, (char *)&ifqr
) < 0) {
1424 perror("Warning: ioctl(SIOCGIFQUEUESTATS)");
1427 qstats
[n
].handle
= ifcqs
->ifqs_tcq_stats
.class_handle
;
1430 for (n
= 0; n
< IFCQ_SC_MAX
&& scheduler
!= PKTSCHEDT_NONE
; n
++) {
1431 if (cq
>= 0 && cq
!= n
)
1435 if (ioctl(s
, SIOCGIFQUEUESTATS
, (char *)&ifqr
) < 0) {
1436 perror("Warning: ioctl(SIOCGIFQUEUESTATS)");
1440 update_avg(ifcqs
, &qstats
[n
]);
1442 switch (scheduler
) {
1444 print_cbqstats(n
, &ifcqs
->ifqs_cbq_stats
,
1447 case PKTSCHEDT_HFSC
:
1448 print_hfscstats(n
, &ifcqs
->ifqs_hfsc_stats
,
1451 case PKTSCHEDT_PRIQ
:
1452 print_priqstats(n
, &ifcqs
->ifqs_priq_stats
,
1455 case PKTSCHEDT_FAIRQ
:
1456 print_fairqstats(n
, &ifcqs
->ifqs_fairq_stats
,
1460 print_tcqstats(n
, &ifcqs
->ifqs_tcq_stats
,
1464 print_qfqstats(n
, &ifcqs
->ifqs_qfq_stats
,
1467 case PKTSCHEDT_NONE
:
1476 sigemptyset(&sigset
);
1477 sigaddset(&sigset
, SIGALRM
);
1478 (void) sigprocmask(SIG_BLOCK
, &sigset
, &oldsigset
);
1480 sigemptyset(&sigset
);
1481 sigsuspend(&sigset
);
1483 (void) sigprocmask(SIG_SETMASK
, &oldsigset
, NULL
);
1495 print_cbqstats(int slot
, struct cbq_classstats
*cs
, struct queue_stats
*qs
)
1497 printf(" %2d: [ pkts: %10llu bytes: %10llu "
1498 "dropped pkts: %6llu bytes: %6llu ]\n", slot
,
1499 (unsigned long long)cs
->xmit_cnt
.packets
,
1500 (unsigned long long)cs
->xmit_cnt
.bytes
,
1501 (unsigned long long)cs
->drop_cnt
.packets
,
1502 (unsigned long long)cs
->drop_cnt
.bytes
);
1503 printf(" [ qlength: %3d/%3d borrows: %6u "
1504 "suspends: %6u qalg: %s ]\n", cs
->qcnt
, cs
->qmax
,
1505 cs
->borrows
, cs
->delays
, qtype2str(cs
->qtype
));
1506 printf(" [ service class: %5s ]\n", qid2str(cs
->handle
));
1508 if (qs
->avgn
>= 2) {
1509 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1510 qs
->avg_packets
/ interval
,
1511 rate2str((8 * qs
->avg_bytes
) / interval
));
1517 switch (cs
->qtype
) {
1519 print_sfbstats(&cs
->sfb
);
1527 print_priqstats(int slot
, struct priq_classstats
*cs
, struct queue_stats
*qs
)
1529 printf(" %2d: [ pkts: %10llu bytes: %10llu "
1530 "dropped pkts: %6llu bytes: %6llu ]\n", slot
,
1531 (unsigned long long)cs
->xmitcnt
.packets
,
1532 (unsigned long long)cs
->xmitcnt
.bytes
,
1533 (unsigned long long)cs
->dropcnt
.packets
,
1534 (unsigned long long)cs
->dropcnt
.bytes
);
1535 printf(" [ qlength: %3d/%3d qalg: %11s service class: %5s ]\n",
1536 cs
->qlength
, cs
->qlimit
, qtype2str(cs
->qtype
),
1537 qid2str(cs
->class_handle
));
1539 if (qs
->avgn
>= 2) {
1540 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1541 qs
->avg_packets
/ interval
,
1542 rate2str((8 * qs
->avg_bytes
) / interval
));
1548 switch (cs
->qtype
) {
1550 print_sfbstats(&cs
->sfb
);
1558 print_hfscstats(int slot
, struct hfsc_classstats
*cs
, struct queue_stats
*qs
)
1560 printf(" %2d: [ pkts: %10llu bytes: %10llu "
1561 "dropped pkts: %6llu bytes: %6llu ]\n", slot
,
1562 (unsigned long long)cs
->xmit_cnt
.packets
,
1563 (unsigned long long)cs
->xmit_cnt
.bytes
,
1564 (unsigned long long)cs
->drop_cnt
.packets
,
1565 (unsigned long long)cs
->drop_cnt
.bytes
);
1566 printf(" [ qlength: %3d/%3d qalg: %11s service class: %5s ]\n",
1567 cs
->qlength
, cs
->qlimit
, qtype2str(cs
->qtype
),
1568 qid2str(cs
->class_handle
));
1570 if (qs
->avgn
>= 2) {
1571 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1572 qs
->avg_packets
/ interval
,
1573 rate2str((8 * qs
->avg_bytes
) / interval
));
1579 switch (cs
->qtype
) {
1581 print_sfbstats(&cs
->sfb
);
1589 print_fairqstats(int slot
, struct fairq_classstats
*cs
, struct queue_stats
*qs
)
1591 printf(" %2d: [ pkts: %10llu bytes: %10llu "
1592 "dropped pkts: %6llu bytes: %6llu ]\n", slot
,
1593 (unsigned long long)cs
->xmit_cnt
.packets
,
1594 (unsigned long long)cs
->xmit_cnt
.bytes
,
1595 (unsigned long long)cs
->drop_cnt
.packets
,
1596 (unsigned long long)cs
->drop_cnt
.bytes
);
1597 printf(" [ qlength: %3d/%3d qalg: %11s service class: %5s ]]\n",
1598 cs
->qlength
, cs
->qlimit
, qtype2str(cs
->qtype
),
1599 qid2str(cs
->class_handle
));
1601 if (qs
->avgn
>= 2) {
1602 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1603 qs
->avg_packets
/ interval
,
1604 rate2str((8 * qs
->avg_bytes
) / interval
));
1610 switch (cs
->qtype
) {
1612 print_sfbstats(&cs
->sfb
);
1620 print_tcqstats(int slot
, struct tcq_classstats
*cs
, struct queue_stats
*qs
)
1627 qs
->handle
= cs
->class_handle
;
1630 for (n
= 0; n
< IFCQ_SC_MAX
; n
++) {
1631 if (&qstats
[n
] != qs
&& qstats
[n
].handle
== qs
->handle
)
1632 qstats
[n
].printed
++;
1635 printf("%5s: [ pkts: %10llu bytes: %10llu "
1636 "dropped pkts: %6llu bytes: %6llu ]\n", tcqslot2str(slot
),
1637 (unsigned long long)cs
->xmitcnt
.packets
,
1638 (unsigned long long)cs
->xmitcnt
.bytes
,
1639 (unsigned long long)cs
->dropcnt
.packets
,
1640 (unsigned long long)cs
->dropcnt
.bytes
);
1641 printf(" [ qlength: %3d/%3d qalg: %11s "
1642 "svc class: %9s %-13s ]\n", cs
->qlength
, cs
->qlimit
,
1643 qtype2str(cs
->qtype
), qid2str(cs
->class_handle
),
1644 qstate2str(cs
->qstate
));
1646 if (qs
->avgn
>= 2) {
1647 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1648 qs
->avg_packets
/ interval
,
1649 rate2str((8 * qs
->avg_bytes
) / interval
));
1655 switch (cs
->qtype
) {
1657 print_sfbstats(&cs
->sfb
);
1665 print_qfqstats(int slot
, struct qfq_classstats
*cs
, struct queue_stats
*qs
)
1667 printf(" %2d: [ pkts: %10llu bytes: %10llu "
1668 "dropped pkts: %6llu bytes: %6llu ]\n", slot
,
1669 (unsigned long long)cs
->xmitcnt
.packets
,
1670 (unsigned long long)cs
->xmitcnt
.bytes
,
1671 (unsigned long long)cs
->dropcnt
.packets
,
1672 (unsigned long long)cs
->dropcnt
.bytes
);
1673 printf(" [ qlength: %3d/%3d index: %10u weight: %12u "
1674 "lmax: %7u ]\n", cs
->qlength
, cs
->qlimit
, cs
->index
,
1675 cs
->weight
, cs
->lmax
);
1676 printf(" [ qalg: %10s svc class: %6s %-35s ]\n",
1677 qtype2str(cs
->qtype
), qid2str(cs
->class_handle
),
1678 qstate2str(cs
->qstate
));
1680 if (qs
->avgn
>= 2) {
1681 printf(" [ measured: %7.1f packets/s, %s/s ]\n",
1682 qs
->avg_packets
/ interval
,
1683 rate2str((8 * qs
->avg_bytes
) / interval
));
1689 switch (cs
->qtype
) {
1691 print_sfbstats(&cs
->sfb
);
1699 print_sfbstats(struct sfb_stats
*sfb
)
1701 struct sfbstats
*sp
= &sfb
->sfbstats
;
1702 int i
, j
, cur
= sfb
->current
;
1705 printf(" [target delay: %14s ",
1706 nsec_to_str(sfb
->target_qdelay
));
1707 printf("update interval: %14s]\n",
1708 nsec_to_str(sfb
->update_interval
));
1709 printf(" [ early drop: %12llu rlimit drop: %11llu "
1710 "marked: %11llu ]\n",
1711 sp
->drop_early
, sp
->drop_pbox
, sp
->marked_packets
);
1712 printf(" [ penalized: %13llu rehash cnt: %12llu "
1713 "current: %10u ]\n", sp
->pbox_packets
, sp
->num_rehash
, cur
);
1714 printf(" [ deque avg: %13s ", nsec_to_str(sp
->dequeue_avg
));
1715 printf("rehash intvl: %11s]\n", nsec_to_str(sp
->rehash_intval
));
1716 printf(" [ holdtime: %14s ", nsec_to_str(sp
->hold_time
));
1717 printf("pboxtime: %14s ]\n", nsec_to_str(sp
->pbox_time
));
1718 printf(" [ allocation: %12u drop thresh: %11u ]\n",
1719 sfb
->allocation
, sfb
->dropthresh
);
1720 printf(" [ flow controlled: %7llu adv feedback: %10llu ]\n",
1721 sp
->flow_controlled
, sp
->flow_feedback
);
1722 printf(" [ min queue delay: %10s delay_fcthreshold: %12llu]\n "
1723 " [stalls: %12lu]\n",
1724 nsec_to_str(sfb
->min_estdelay
), sfb
->delay_fcthreshold
,
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
);