4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 1990 Mentat Inc.
24 * netstat.c 2.2, last change 9/9/91
25 * MROUTING Revision 3.5
29 * simple netstat based on snmp/mib-2 interface to the TCP/IP stack
32 * 1. A comment "LINTED: (note 1)" appears before certain lines where
33 * lint would have complained, "pointer cast may result in improper
34 * alignment". These are lines where lint had suspected potential
35 * improper alignment of a data structure; in each such situation
36 * we have relied on the kernel guaranteeing proper alignment.
37 * 2. Some 'for' loops have been commented as "'for' loop 1", etc
38 * because they have 'continue' or 'break' statements in their
39 * bodies. 'continue' statements have been used inside some loops
40 * where avoiding them would have led to deep levels of indentation.
43 * Add ability to request subsets from kernel (with level = MIB2_IP;
44 * name = 0 meaning everything for compatibility)
59 #include <sys/types.h>
60 #include <sys/stream.h>
62 #include <sys/strstat.h>
63 #include <sys/tihdr.h>
65 #include <sys/socket.h>
66 #include <sys/sockio.h>
67 #include <netinet/in.h>
69 #include <net/route.h>
71 #include <inet/mib2.h>
75 #include <netinet/igmp_var.h>
76 #include <netinet/ip_mroute.h>
78 #include <arpa/inet.h>
81 #include <sys/systeminfo.h>
82 #include <arpa/inet.h>
84 #include <netinet/dhcp.h>
85 #include <dhcpagent_ipc.h>
86 #include <dhcpagent_util.h>
89 #include "statcommon.h"
91 extern void unixpr(kstat_ctl_t
*kc
);
95 #define V4MASK_TO_V6(v4, v6) ((v6)._S6_un._S6_u32[0] = 0xfffffffful, \
96 (v6)._S6_un._S6_u32[1] = 0xfffffffful, \
97 (v6)._S6_un._S6_u32[2] = 0xfffffffful, \
98 (v6)._S6_un._S6_u32[3] = (v4))
100 #define IN6_IS_V4MASK(v6) ((v6)._S6_un._S6_u32[0] == 0xfffffffful && \
101 (v6)._S6_un._S6_u32[1] == 0xfffffffful && \
102 (v6)._S6_un._S6_u32[2] == 0xfffffffful)
105 * This is used as a cushion in the buffer allocation directed by SIOCGLIFNUM.
106 * Because there's no locking between SIOCGLIFNUM and SIOCGLIFCONF, it's
107 * possible for an administrator to plumb new interfaces between those two
108 * calls, resulting in the failure of the latter. This addition makes that
111 #define LIFN_GUARD_VALUE 10
113 typedef struct mib_item_s
{
114 struct mib_item_s
*next_item
;
130 struct iflist
*next_if
;
131 char ifname
[LIFNAMSIZ
];
135 static mib_item_t
*mibget(int sd
);
136 static void mibfree(mib_item_t
*firstitem
);
137 static int mibopen(void);
138 static void mib_get_constants(mib_item_t
*item
);
139 static mib_item_t
*mib_item_dup(mib_item_t
*item
);
140 static mib_item_t
*mib_item_diff(mib_item_t
*item1
,
142 static void mib_item_destroy(mib_item_t
**item
);
144 static boolean_t
octetstrmatch(const Octet_t
*a
, const Octet_t
*b
);
145 static char *octetstr(const Octet_t
*op
, int code
,
146 char *dst
, uint_t dstlen
);
147 static char *pr_addr(uint_t addr
,
148 char *dst
, uint_t dstlen
);
149 static char *pr_addrnz(ipaddr_t addr
, char *dst
, uint_t dstlen
);
150 static char *pr_addr6(const in6_addr_t
*addr
,
151 char *dst
, uint_t dstlen
);
152 static char *pr_mask(uint_t addr
,
153 char *dst
, uint_t dstlen
);
154 static char *pr_prefix6(const struct in6_addr
*addr
,
155 uint_t prefixlen
, char *dst
, uint_t dstlen
);
156 static char *pr_ap(uint_t addr
, uint_t port
,
157 char *proto
, char *dst
, uint_t dstlen
);
158 static char *pr_ap6(const in6_addr_t
*addr
, uint_t port
,
159 char *proto
, char *dst
, uint_t dstlen
);
160 static char *pr_net(uint_t addr
, uint_t mask
,
161 char *dst
, uint_t dstlen
);
162 static char *pr_netaddr(uint_t addr
, uint_t mask
,
163 char *dst
, uint_t dstlen
);
164 static char *fmodestr(uint_t fmode
);
165 static char *portname(uint_t port
, char *proto
,
166 char *dst
, uint_t dstlen
);
168 static const char *mitcp_state(int code
);
169 static const char *miudp_state(int code
);
171 static void stat_report(mib_item_t
*item
);
172 static void mrt_stat_report(mib_item_t
*item
);
173 static void arp_report(mib_item_t
*item
);
174 static void ndp_report(mib_item_t
*item
);
175 static void mrt_report(mib_item_t
*item
);
176 static void if_stat_total(struct ifstat
*oldstats
,
177 struct ifstat
*newstats
, struct ifstat
*sumstats
);
178 static void if_report(mib_item_t
*item
, char *ifname
,
179 int Iflag_only
, boolean_t once_only
);
180 static void if_report_ip4(mib2_ipAddrEntry_t
*ap
,
181 char ifname
[], char logintname
[],
182 struct ifstat
*statptr
, boolean_t ksp_not_null
);
183 static void if_report_ip6(mib2_ipv6AddrEntry_t
*ap6
,
184 char ifname
[], char logintname
[],
185 struct ifstat
*statptr
, boolean_t ksp_not_null
);
186 static void ire_report(const mib_item_t
*item
);
187 static void tcp_report(const mib_item_t
*item
);
188 static void udp_report(const mib_item_t
*item
);
189 static void group_report(mib_item_t
*item
);
190 static void dce_report(mib_item_t
*item
);
191 static void print_ip_stats(mib2_ip_t
*ip
);
192 static void print_icmp_stats(mib2_icmp_t
*icmp
);
193 static void print_ip6_stats(mib2_ipv6IfStatsEntry_t
*ip6
);
194 static void print_icmp6_stats(mib2_ipv6IfIcmpEntry_t
*icmp6
);
195 static void print_sctp_stats(mib2_sctp_t
*tcp
);
196 static void print_tcp_stats(mib2_tcp_t
*tcp
);
197 static void print_udp_stats(mib2_udp_t
*udp
);
198 static void print_rawip_stats(mib2_rawip_t
*rawip
);
199 static void print_igmp_stats(struct igmpstat
*igps
);
200 static void print_mrt_stats(struct mrtstat
*mrts
);
201 static void sctp_report(const mib_item_t
*item
);
202 static void sum_ip6_stats(mib2_ipv6IfStatsEntry_t
*ip6
,
203 mib2_ipv6IfStatsEntry_t
*sum6
);
204 static void sum_icmp6_stats(mib2_ipv6IfIcmpEntry_t
*icmp6
,
205 mib2_ipv6IfIcmpEntry_t
*sum6
);
206 static void m_report(void);
207 static void dhcp_report(char *);
209 static uint64_t kstat_named_value(kstat_t
*, char *);
210 static kid_t
safe_kstat_read(kstat_ctl_t
*, kstat_t
*, void *);
211 static int isnum(char *);
212 static char *plural(int n
);
213 static char *pluraly(int n
);
214 static char *plurales(int n
);
215 static void process_filter(char *arg
);
216 static char *ifindex2str(uint_t
, char *);
217 static boolean_t
family_selected(int family
);
219 static void usage(char *);
220 static void fatal(int errcode
, char *str1
, ...);
222 #define PLURAL(n) plural((int)n)
223 #define PLURALY(n) pluraly((int)n)
224 #define PLURALES(n) plurales((int)n)
225 #define IFLAGMOD(flg, val1, val2) if (flg == val1) flg = val2
226 #define MDIFF(diff, elem2, elem1, member) (diff)->member = \
227 (elem2)->member - (elem1)->member
230 static boolean_t Aflag
= B_FALSE
; /* All sockets/ifs/rtng-tbls */
231 static boolean_t Dflag
= B_FALSE
; /* DCE info */
232 static boolean_t Iflag
= B_FALSE
; /* IP Traffic Interfaces */
233 static boolean_t Mflag
= B_FALSE
; /* STREAMS Memory Statistics */
234 static boolean_t Nflag
= B_FALSE
; /* Numeric Network Addresses */
235 static boolean_t Rflag
= B_FALSE
; /* Routing Tables */
236 static boolean_t Sflag
= B_FALSE
; /* Per-protocol Statistics */
237 static boolean_t Vflag
= B_FALSE
; /* Verbose */
238 static boolean_t Pflag
= B_FALSE
; /* Net to Media Tables */
239 static boolean_t Gflag
= B_FALSE
; /* Multicast group membership */
240 static boolean_t MMflag
= B_FALSE
; /* Multicast routing table */
241 static boolean_t DHCPflag
= B_FALSE
; /* DHCP statistics */
242 static boolean_t Xflag
= B_FALSE
; /* Debug Info */
244 static int v4compat
= 0; /* Compatible printing format for status */
246 static int proto
= IPPROTO_MAX
; /* all protocols */
247 kstat_ctl_t
*kc
= NULL
;
250 * Sizes of data structures extracted from the base mib.
251 * This allows the size of the tables entries to grow while preserving
252 * binary compatibility.
254 static int ipAddrEntrySize
;
255 static int ipRouteEntrySize
;
256 static int ipNetToMediaEntrySize
;
257 static int ipMemberEntrySize
;
258 static int ipGroupSourceEntrySize
;
259 static int vifctlSize
;
260 static int mfcctlSize
;
262 static int ipv6IfStatsEntrySize
;
263 static int ipv6IfIcmpEntrySize
;
264 static int ipv6AddrEntrySize
;
265 static int ipv6RouteEntrySize
;
266 static int ipv6NetToMediaEntrySize
;
267 static int ipv6MemberEntrySize
;
268 static int ipv6GroupSourceEntrySize
;
270 static int ipDestEntrySize
;
272 static int tcpConnEntrySize
;
273 static int tcp6ConnEntrySize
;
274 static int udpEntrySize
;
275 static int udp6EntrySize
;
276 static int sctpEntrySize
;
277 static int sctpLocalEntrySize
;
278 static int sctpRemoteEntrySize
;
280 #define protocol_selected(p) (proto == IPPROTO_MAX || proto == (p))
282 /* Machinery used for -f (filter) option */
283 enum { FK_AF
= 0, FK_OUTIF
, FK_DST
, FK_FLAGS
, NFILTERKEYS
};
285 static const char *filter_keys
[NFILTERKEYS
] = {
286 "af", "outif", "dst", "flags"
289 /* Flags on routes */
290 #define FLF_A 0x00000001
291 #define FLF_b 0x00000002
292 #define FLF_D 0x00000004
293 #define FLF_G 0x00000008
294 #define FLF_H 0x00000010
295 #define FLF_L 0x00000020
296 #define FLF_U 0x00000040
297 #define FLF_S 0x00000100
298 #define FLF_C 0x00000200 /* IRE_IF_CLONE */
299 #define FLF_I 0x00000400 /* RTF_INDIRECT */
300 #define FLF_R 0x00000800 /* RTF_REJECT */
301 #define FLF_B 0x00001000 /* RTF_BLACKHOLE */
302 #define FLF_Z 0x00100000 /* RTF_ZONE */
304 static const char flag_list
[] = "AbDGHLUMSCIRBZ";
306 typedef struct filter_rule filter_t
;
312 const char *f_ifname
;
314 struct hostent
*f_address
;
325 * The user-specified filters are linked into lists separated by
326 * keyword (type of filter). Thus, the matching algorithm is:
327 * For each non-empty filter list
328 * If no filters in the list match
329 * then stop here; route doesn't match
330 * If loop above completes, then route does match and will be
333 static filter_t
*filters
[NFILTERKEYS
];
335 static uint_t timestamp_fmt
= NODATE
;
337 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
338 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't */
342 main(int argc
, char **argv
)
345 mib_item_t
*item
= NULL
;
346 mib_item_t
*previtem
= NULL
;
349 int interval
= 0; /* Single time by default */
350 int count
= -1; /* Forever */
354 * Possible values of 'Iflag_only':
355 * -1, no feature-flags;
356 * 0, IFlag and other feature-flags enabled
357 * 1, IFlag is the only feature-flag enabled
358 * : trinary variable, modified using IFLAGMOD()
361 boolean_t once_only
= B_FALSE
; /* '-i' with count > 1 */
364 char *default_ip_str
= NULL
;
368 v4compat
= get_compat_flag(&default_ip_str
);
369 if (v4compat
== DEFAULT_PROT_BAD_VALUE
)
370 fatal(2, "%s: %s: Bad value for %s in %s\n", name
,
371 default_ip_str
, DEFAULT_IP
, INET_DEFAULT_FILE
);
372 free(default_ip_str
);
374 (void) setlocale(LC_ALL
, "");
375 (void) textdomain(TEXT_DOMAIN
);
377 while ((c
= getopt(argc
, argv
, "adimnrspMgvxf:P:I:DT:")) != -1) {
379 case 'a': /* all connections */
383 case 'd': /* DCE info */
385 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
388 case 'i': /* interface (ill/ipif report) */
390 IFLAGMOD(Iflag_only
, -1, 1); /* '-i' exists */
393 case 'm': /* streams msg report */
395 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
398 case 'n': /* numeric format */
402 case 'r': /* route tables */
404 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
407 case 's': /* per-protocol statistics */
409 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
412 case 'p': /* arp/ndp table */
414 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
417 case 'M': /* multicast routing tables */
419 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
422 case 'g': /* multicast group membership */
424 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
427 case 'v': /* verbose output format */
429 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
432 case 'x': /* turn on debugging */
437 process_filter(optarg
);
441 if (strcmp(optarg
, "ip") == 0) {
443 } else if (strcmp(optarg
, "ipv6") == 0 ||
444 strcmp(optarg
, "ip6") == 0) {
445 v4compat
= 0; /* Overridden */
446 proto
= IPPROTO_IPV6
;
447 } else if (strcmp(optarg
, "icmp") == 0) {
448 proto
= IPPROTO_ICMP
;
449 } else if (strcmp(optarg
, "icmpv6") == 0 ||
450 strcmp(optarg
, "icmp6") == 0) {
451 v4compat
= 0; /* Overridden */
452 proto
= IPPROTO_ICMPV6
;
453 } else if (strcmp(optarg
, "igmp") == 0) {
454 proto
= IPPROTO_IGMP
;
455 } else if (strcmp(optarg
, "udp") == 0) {
457 } else if (strcmp(optarg
, "tcp") == 0) {
459 } else if (strcmp(optarg
, "sctp") == 0) {
460 proto
= IPPROTO_SCTP
;
461 } else if (strcmp(optarg
, "raw") == 0 ||
462 strcmp(optarg
, "rawip") == 0) {
465 fatal(1, "%s: unknown protocol.\n", optarg
);
472 IFLAGMOD(Iflag_only
, -1, 1); /* see macro def'n */
483 timestamp_fmt
= UDATE
;
484 else if (*optarg
== 'd')
485 timestamp_fmt
= DDATE
;
500 * Handle other arguments: find interval, count; the
501 * flags that accept 'interval' and 'count' are OR'd
502 * in the outermost 'if'; more flags may be added as
505 if (Iflag
|| Sflag
|| Mflag
) {
506 for (d
= optind
; d
< argc
; d
++) {
507 if (isnum(argv
[d
])) {
508 interval
= atoi(argv
[d
]);
510 isnum(argv
[d
+ 1])) {
511 count
= atoi(argv
[d
+ 1]);
515 if (interval
== 0 || count
== 0)
522 if (Iflag
&& isnum(argv
[optind
])) {
523 count
= atoi(argv
[optind
]);
530 (void) fprintf(stderr
,
531 "%s: extra arguments\n", name
);
535 setbuf(stdout
, NULL
);
538 dhcp_report(Iflag
? ifname
: NULL
);
542 /* Get data structures: priming before iteration */
543 if (family_selected(AF_INET
) || family_selected(AF_INET6
)) {
546 fatal(1, "can't open mib stream\n");
547 if ((item
= mibget(sd
)) == NULL
) {
549 fatal(1, "mibget() failed\n");
551 /* Extract constant sizes - need do once only */
552 mib_get_constants(item
);
554 if ((kc
= kstat_open()) == NULL
) {
557 fail(1, "kstat_open(): can't open /dev/kstat");
566 mib_item_t
*curritem
= NULL
; /* only for -[M]s */
568 if (timestamp_fmt
!= NODATE
)
569 print_timestamp(timestamp_fmt
);
571 /* netstat: AF_INET[6] behaviour */
572 if (family_selected(AF_INET
) || family_selected(AF_INET6
)) {
574 curritem
= mib_item_diff(previtem
, item
);
575 if (curritem
== NULL
)
576 fatal(1, "can't process mib data, "
578 mib_item_destroy(&previtem
);
581 if (!(Dflag
|| Iflag
|| Rflag
|| Sflag
|| Mflag
||
582 MMflag
|| Pflag
|| Gflag
|| DHCPflag
)) {
583 if (protocol_selected(IPPROTO_UDP
))
585 if (protocol_selected(IPPROTO_TCP
))
587 if (protocol_selected(IPPROTO_SCTP
))
591 if_report(item
, ifname
, Iflag_only
, once_only
);
596 if (Sflag
&& MMflag
) {
597 mrt_stat_report(curritem
);
600 stat_report(curritem
);
607 if (family_selected(AF_INET
))
609 if (family_selected(AF_INET6
))
614 mib_item_destroy(&curritem
);
617 /* netstat: AF_UNIX behaviour */
618 if (family_selected(AF_UNIX
) &&
619 (!(Dflag
|| Iflag
|| Rflag
|| Sflag
|| Mflag
||
620 MMflag
|| Pflag
|| Gflag
)))
622 (void) kstat_close(kc
);
624 /* iteration handling code */
625 if (count
> 0 && --count
== 0)
627 (void) sleep(interval
);
629 /* re-populating of data structures */
630 if (family_selected(AF_INET
) || family_selected(AF_INET6
)) {
632 /* previtem is a cut-down list */
633 previtem
= mib_item_dup(item
);
634 if (previtem
== NULL
)
635 fatal(1, "can't process mib data, "
640 if ((sd
= mibopen()) == -1)
641 fatal(1, "can't open mib stream anymore\n");
642 if ((item
= mibget(sd
)) == NULL
) {
644 fatal(1, "mibget() failed\n");
647 if ((kc
= kstat_open()) == NULL
)
648 fail(1, "kstat_open(): can't open /dev/kstat");
650 } /* 'for' loop 1 ends */
664 for (i
= 0; i
< len
; i
++)
671 /* --------------------------------- MIBGET -------------------------------- */
677 * buf is an automatic for this function, so the
678 * compiler has complete control over its alignment;
679 * it is assumed this alignment is satisfactory for
680 * it to be casted to certain other struct pointers
681 * here, such as struct T_optmgmt_ack * .
683 uintptr_t buf
[512 / sizeof (uintptr_t)];
686 struct strbuf ctlbuf
, databuf
;
687 struct T_optmgmt_req
*tor
= (struct T_optmgmt_req
*)buf
;
688 struct T_optmgmt_ack
*toa
= (struct T_optmgmt_ack
*)buf
;
689 struct T_error_ack
*tea
= (struct T_error_ack
*)buf
;
691 mib_item_t
*first_item
= NULL
;
692 mib_item_t
*last_item
= NULL
;
695 tor
->PRIM_type
= T_SVR4_OPTMGMT_REQ
;
696 tor
->OPT_offset
= sizeof (struct T_optmgmt_req
);
697 tor
->OPT_length
= sizeof (struct opthdr
);
698 tor
->MGMT_flags
= T_CURRENT
;
702 * Note: we use the special level value below so that IP will return
703 * us information concerning IRE_MARK_TESTHIDDEN routes.
705 req
= (struct opthdr
*)&tor
[1];
706 req
->level
= EXPER_IP_AND_ALL_IRES
;
710 ctlbuf
.buf
= (char *)buf
;
711 ctlbuf
.len
= tor
->OPT_length
+ tor
->OPT_offset
;
713 if (putmsg(sd
, &ctlbuf
, NULL
, flags
) == -1) {
714 perror("mibget: putmsg(ctl) failed");
719 * Each reply consists of a ctl part for one fixed structure
720 * or table, as defined in mib2.h. The format is a T_OPTMGMT_ACK,
721 * containing an opthdr structure. level/name identify the entry,
722 * len is the size of the data part of the message.
724 req
= (struct opthdr
*)&toa
[1];
725 ctlbuf
.maxlen
= sizeof (buf
);
729 getcode
= getmsg(sd
, &ctlbuf
, NULL
, &flags
);
731 perror("mibget getmsg(ctl) failed");
733 (void) fputs("# level name len\n",
736 for (last_item
= first_item
; last_item
;
737 last_item
= last_item
->next_item
)
738 (void) printf("%d %4d %5d %d\n",
747 ctlbuf
.len
>= sizeof (struct T_optmgmt_ack
) &&
748 toa
->PRIM_type
== T_OPTMGMT_ACK
&&
749 toa
->MGMT_flags
== T_SUCCESS
&&
752 (void) printf("mibget getmsg() %d returned "
753 "EOD (level %ld, name %ld)\n",
754 j
, req
->level
, req
->name
);
755 return (first_item
); /* this is EOD msg */
758 if (ctlbuf
.len
>= sizeof (struct T_error_ack
) &&
759 tea
->PRIM_type
== T_ERROR_ACK
) {
760 (void) fprintf(stderr
,
761 "mibget %d gives T_ERROR_ACK: TLI_error = 0x%lx, "
762 "UNIX_error = 0x%lx\n",
763 j
, tea
->TLI_error
, tea
->UNIX_error
);
765 errno
= (tea
->TLI_error
== TSYSERR
) ?
766 tea
->UNIX_error
: EPROTO
;
770 if (getcode
!= MOREDATA
||
771 ctlbuf
.len
< sizeof (struct T_optmgmt_ack
) ||
772 toa
->PRIM_type
!= T_OPTMGMT_ACK
||
773 toa
->MGMT_flags
!= T_SUCCESS
) {
774 (void) printf("mibget getmsg(ctl) %d returned %d, "
775 "ctlbuf.len = %d, PRIM_type = %ld\n",
776 j
, getcode
, ctlbuf
.len
, toa
->PRIM_type
);
778 if (toa
->PRIM_type
== T_OPTMGMT_ACK
)
779 (void) printf("T_OPTMGMT_ACK: "
780 "MGMT_flags = 0x%lx, req->len = %ld\n",
781 toa
->MGMT_flags
, req
->len
);
786 temp
= (mib_item_t
*)malloc(sizeof (mib_item_t
));
788 perror("mibget malloc failed");
791 if (last_item
!= NULL
)
792 last_item
->next_item
= temp
;
796 last_item
->next_item
= NULL
;
797 last_item
->group
= req
->level
;
798 last_item
->mib_id
= req
->name
;
799 last_item
->length
= req
->len
;
800 last_item
->valp
= malloc((int)req
->len
);
801 if (last_item
->valp
== NULL
)
804 (void) printf("msg %d: group = %4d mib_id = %5d"
806 j
, last_item
->group
, last_item
->mib_id
,
809 databuf
.maxlen
= last_item
->length
;
810 databuf
.buf
= (char *)last_item
->valp
;
813 getcode
= getmsg(sd
, NULL
, &databuf
, &flags
);
815 perror("mibget getmsg(data) failed");
817 } else if (getcode
!= 0) {
818 (void) printf("mibget getmsg(data) returned %d, "
819 "databuf.maxlen = %d, databuf.len = %d\n",
820 getcode
, databuf
.maxlen
, databuf
.len
);
833 * mibfree: frees a linked list of type (mib_item_t *)
834 * returned by mibget(); this is NOT THE SAME AS
835 * mib_item_destroy(), so should be used for objects
836 * returned by mibget() only
839 mibfree(mib_item_t
*firstitem
)
841 mib_item_t
*lastitem
;
843 while (firstitem
!= NULL
) {
844 lastitem
= firstitem
;
845 firstitem
= firstitem
->next_item
;
846 free(lastitem
->valp
);
856 sd
= open("/dev/arp", O_RDWR
);
861 if (ioctl(sd
, I_PUSH
, "tcp") == -1) {
862 perror("tcp I_PUSH");
866 if (ioctl(sd
, I_PUSH
, "udp") == -1) {
867 perror("udp I_PUSH");
871 if (ioctl(sd
, I_PUSH
, "icmp") == -1) {
872 perror("icmp I_PUSH");
880 * mib_item_dup: returns a clean mib_item_t * linked
881 * list, so that for every element item->mib_id is 0;
882 * to deallocate this linked list, use mib_item_destroy
885 mib_item_dup(mib_item_t
*item
)
891 for (tempp
= item
; tempp
; tempp
= tempp
->next_item
)
892 if (tempp
->mib_id
== 0)
896 localp
= (mib_item_t
*)malloc(c
* sizeof (mib_item_t
));
900 for (; item
; item
= item
->next_item
) {
901 if (item
->mib_id
== 0) {
902 /* Replicate item in localp */
903 (localp
[c
]).next_item
= NULL
;
904 (localp
[c
]).group
= item
->group
;
905 (localp
[c
]).mib_id
= item
->mib_id
;
906 (localp
[c
]).length
= item
->length
;
907 (localp
[c
]).valp
= (uintptr_t *)malloc(
909 if ((localp
[c
]).valp
== NULL
) {
910 mib_item_destroy(&localp
);
913 (void *) memcpy((localp
[c
]).valp
,
916 tempp
= &(localp
[c
]);
918 (localp
[c
- 1]).next_item
= tempp
;
926 * mib_item_diff: takes two (mib_item_t *) linked lists
927 * item1 and item2 and computes the difference between
928 * differentiable values in item2 against item1 for every
929 * given member of item2; returns an mib_item_t * linked
930 * list of diff's, or a copy of item2 if item1 is NULL;
931 * will return NULL if system out of memory; works only
932 * for item->mib_id == 0
935 mib_item_diff(mib_item_t
*item1
, mib_item_t
*item2
) {
936 int nitems
= 0; /* no. of items in item2 */
937 mib_item_t
*tempp2
; /* walking copy of item2 */
938 mib_item_t
*tempp1
; /* walking copy of item1 */
940 mib_item_t
*diffptr
; /* walking copy of diffp */
941 mib_item_t
*prevp
= NULL
;
944 diffp
= mib_item_dup(item2
);
950 tempp2
= tempp2
->next_item
) {
951 if (tempp2
->mib_id
== 0)
952 switch (tempp2
->group
) {
954 * upon adding a case here, the same
955 * must also be added in the next
956 * switch statement, alongwith
974 diffp
= mib_item_dup(item2
);
978 diffp
= (mib_item_t
*)calloc(nitems
, sizeof (mib_item_t
));
983 for (tempp2
= item2
; tempp2
!= NULL
; tempp2
= tempp2
->next_item
) {
984 if (tempp2
->mib_id
!= 0)
985 continue; /* 'for' loop 1 */
987 for (tempp1
= item1
; tempp1
!= NULL
;
988 tempp1
= tempp1
->next_item
) {
989 if (!(tempp1
->mib_id
== 0 &&
990 tempp1
->group
== tempp2
->group
&&
991 tempp1
->mib_id
== tempp2
->mib_id
))
992 continue; /* 'for' loop 2 */
993 /* found comparable data sets */
995 prevp
->next_item
= diffptr
;
996 switch (tempp2
->group
) {
998 * Indenting note: Because of long variable names
999 * in cases MIB2_IP6 and MIB2_ICMP6, their contents
1000 * have been indented by one tab space only
1003 mib2_ip_t
*i2
= (mib2_ip_t
*)tempp2
->valp
;
1004 mib2_ip_t
*i1
= (mib2_ip_t
*)tempp1
->valp
;
1007 diffptr
->group
= tempp2
->group
;
1008 diffptr
->mib_id
= tempp2
->mib_id
;
1009 diffptr
->length
= tempp2
->length
;
1010 d
= (mib2_ip_t
*)calloc(tempp2
->length
, 1);
1012 goto mibdiff_out_of_memory
;
1014 d
->ipForwarding
= i2
->ipForwarding
;
1015 d
->ipDefaultTTL
= i2
->ipDefaultTTL
;
1016 MDIFF(d
, i2
, i1
, ipInReceives
);
1017 MDIFF(d
, i2
, i1
, ipInHdrErrors
);
1018 MDIFF(d
, i2
, i1
, ipInAddrErrors
);
1019 MDIFF(d
, i2
, i1
, ipInCksumErrs
);
1020 MDIFF(d
, i2
, i1
, ipForwDatagrams
);
1021 MDIFF(d
, i2
, i1
, ipForwProhibits
);
1022 MDIFF(d
, i2
, i1
, ipInUnknownProtos
);
1023 MDIFF(d
, i2
, i1
, ipInDiscards
);
1024 MDIFF(d
, i2
, i1
, ipInDelivers
);
1025 MDIFF(d
, i2
, i1
, ipOutRequests
);
1026 MDIFF(d
, i2
, i1
, ipOutDiscards
);
1027 MDIFF(d
, i2
, i1
, ipOutNoRoutes
);
1028 MDIFF(d
, i2
, i1
, ipReasmTimeout
);
1029 MDIFF(d
, i2
, i1
, ipReasmReqds
);
1030 MDIFF(d
, i2
, i1
, ipReasmOKs
);
1031 MDIFF(d
, i2
, i1
, ipReasmFails
);
1032 MDIFF(d
, i2
, i1
, ipReasmDuplicates
);
1033 MDIFF(d
, i2
, i1
, ipReasmPartDups
);
1034 MDIFF(d
, i2
, i1
, ipFragOKs
);
1035 MDIFF(d
, i2
, i1
, ipFragFails
);
1036 MDIFF(d
, i2
, i1
, ipFragCreates
);
1037 MDIFF(d
, i2
, i1
, ipRoutingDiscards
);
1038 MDIFF(d
, i2
, i1
, tcpInErrs
);
1039 MDIFF(d
, i2
, i1
, udpNoPorts
);
1040 MDIFF(d
, i2
, i1
, udpInCksumErrs
);
1041 MDIFF(d
, i2
, i1
, udpInOverflows
);
1042 MDIFF(d
, i2
, i1
, rawipInOverflows
);
1043 MDIFF(d
, i2
, i1
, ipsecInSucceeded
);
1044 MDIFF(d
, i2
, i1
, ipsecInFailed
);
1045 MDIFF(d
, i2
, i1
, ipInIPv6
);
1046 MDIFF(d
, i2
, i1
, ipOutIPv6
);
1047 MDIFF(d
, i2
, i1
, ipOutSwitchIPv6
);
1052 mib2_ipv6IfStatsEntry_t
*i2
;
1053 mib2_ipv6IfStatsEntry_t
*i1
;
1054 mib2_ipv6IfStatsEntry_t
*d
;
1056 i2
= (mib2_ipv6IfStatsEntry_t
*)tempp2
->valp
;
1057 i1
= (mib2_ipv6IfStatsEntry_t
*)tempp1
->valp
;
1058 diffptr
->group
= tempp2
->group
;
1059 diffptr
->mib_id
= tempp2
->mib_id
;
1060 diffptr
->length
= tempp2
->length
;
1061 d
= (mib2_ipv6IfStatsEntry_t
*)calloc(
1064 goto mibdiff_out_of_memory
;
1066 d
->ipv6Forwarding
= i2
->ipv6Forwarding
;
1067 d
->ipv6DefaultHopLimit
=
1068 i2
->ipv6DefaultHopLimit
;
1070 MDIFF(d
, i2
, i1
, ipv6InReceives
);
1071 MDIFF(d
, i2
, i1
, ipv6InHdrErrors
);
1072 MDIFF(d
, i2
, i1
, ipv6InTooBigErrors
);
1073 MDIFF(d
, i2
, i1
, ipv6InNoRoutes
);
1074 MDIFF(d
, i2
, i1
, ipv6InAddrErrors
);
1075 MDIFF(d
, i2
, i1
, ipv6InUnknownProtos
);
1076 MDIFF(d
, i2
, i1
, ipv6InTruncatedPkts
);
1077 MDIFF(d
, i2
, i1
, ipv6InDiscards
);
1078 MDIFF(d
, i2
, i1
, ipv6InDelivers
);
1079 MDIFF(d
, i2
, i1
, ipv6OutForwDatagrams
);
1080 MDIFF(d
, i2
, i1
, ipv6OutRequests
);
1081 MDIFF(d
, i2
, i1
, ipv6OutDiscards
);
1082 MDIFF(d
, i2
, i1
, ipv6OutNoRoutes
);
1083 MDIFF(d
, i2
, i1
, ipv6OutFragOKs
);
1084 MDIFF(d
, i2
, i1
, ipv6OutFragFails
);
1085 MDIFF(d
, i2
, i1
, ipv6OutFragCreates
);
1086 MDIFF(d
, i2
, i1
, ipv6ReasmReqds
);
1087 MDIFF(d
, i2
, i1
, ipv6ReasmOKs
);
1088 MDIFF(d
, i2
, i1
, ipv6ReasmFails
);
1089 MDIFF(d
, i2
, i1
, ipv6InMcastPkts
);
1090 MDIFF(d
, i2
, i1
, ipv6OutMcastPkts
);
1091 MDIFF(d
, i2
, i1
, ipv6ReasmDuplicates
);
1092 MDIFF(d
, i2
, i1
, ipv6ReasmPartDups
);
1093 MDIFF(d
, i2
, i1
, ipv6ForwProhibits
);
1094 MDIFF(d
, i2
, i1
, udpInCksumErrs
);
1095 MDIFF(d
, i2
, i1
, udpInOverflows
);
1096 MDIFF(d
, i2
, i1
, rawipInOverflows
);
1097 MDIFF(d
, i2
, i1
, ipv6InIPv4
);
1098 MDIFF(d
, i2
, i1
, ipv6OutIPv4
);
1099 MDIFF(d
, i2
, i1
, ipv6OutSwitchIPv4
);
1108 m2
= (struct mrtstat
*)tempp2
->valp
;
1109 m1
= (struct mrtstat
*)tempp1
->valp
;
1110 diffptr
->group
= tempp2
->group
;
1111 diffptr
->mib_id
= tempp2
->mib_id
;
1112 diffptr
->length
= tempp2
->length
;
1113 d
= (struct mrtstat
*)calloc(tempp2
->length
, 1);
1115 goto mibdiff_out_of_memory
;
1117 MDIFF(d
, m2
, m1
, mrts_mfc_hits
);
1118 MDIFF(d
, m2
, m1
, mrts_mfc_misses
);
1119 MDIFF(d
, m2
, m1
, mrts_fwd_in
);
1120 MDIFF(d
, m2
, m1
, mrts_fwd_out
);
1121 d
->mrts_upcalls
= m2
->mrts_upcalls
;
1122 MDIFF(d
, m2
, m1
, mrts_fwd_drop
);
1123 MDIFF(d
, m2
, m1
, mrts_bad_tunnel
);
1124 MDIFF(d
, m2
, m1
, mrts_cant_tunnel
);
1125 MDIFF(d
, m2
, m1
, mrts_wrong_if
);
1126 MDIFF(d
, m2
, m1
, mrts_upq_ovflw
);
1127 MDIFF(d
, m2
, m1
, mrts_cache_cleanups
);
1128 MDIFF(d
, m2
, m1
, mrts_drop_sel
);
1129 MDIFF(d
, m2
, m1
, mrts_q_overflow
);
1130 MDIFF(d
, m2
, m1
, mrts_pkt2large
);
1131 MDIFF(d
, m2
, m1
, mrts_pim_badversion
);
1132 MDIFF(d
, m2
, m1
, mrts_pim_rcv_badcsum
);
1133 MDIFF(d
, m2
, m1
, mrts_pim_badregisters
);
1134 MDIFF(d
, m2
, m1
, mrts_pim_regforwards
);
1135 MDIFF(d
, m2
, m1
, mrts_pim_regsend_drops
);
1136 MDIFF(d
, m2
, m1
, mrts_pim_malformed
);
1137 MDIFF(d
, m2
, m1
, mrts_pim_nomemory
);
1142 struct igmpstat
*i2
;
1143 struct igmpstat
*i1
;
1146 i2
= (struct igmpstat
*)tempp2
->valp
;
1147 i1
= (struct igmpstat
*)tempp1
->valp
;
1148 diffptr
->group
= tempp2
->group
;
1149 diffptr
->mib_id
= tempp2
->mib_id
;
1150 diffptr
->length
= tempp2
->length
;
1151 d
= (struct igmpstat
*)calloc(
1154 goto mibdiff_out_of_memory
;
1156 MDIFF(d
, i2
, i1
, igps_rcv_total
);
1157 MDIFF(d
, i2
, i1
, igps_rcv_tooshort
);
1158 MDIFF(d
, i2
, i1
, igps_rcv_badsum
);
1159 MDIFF(d
, i2
, i1
, igps_rcv_queries
);
1160 MDIFF(d
, i2
, i1
, igps_rcv_badqueries
);
1161 MDIFF(d
, i2
, i1
, igps_rcv_reports
);
1162 MDIFF(d
, i2
, i1
, igps_rcv_badreports
);
1163 MDIFF(d
, i2
, i1
, igps_rcv_ourreports
);
1164 MDIFF(d
, i2
, i1
, igps_snd_reports
);
1173 i2
= (mib2_icmp_t
*)tempp2
->valp
;
1174 i1
= (mib2_icmp_t
*)tempp1
->valp
;
1175 diffptr
->group
= tempp2
->group
;
1176 diffptr
->mib_id
= tempp2
->mib_id
;
1177 diffptr
->length
= tempp2
->length
;
1178 d
= (mib2_icmp_t
*)calloc(tempp2
->length
, 1);
1180 goto mibdiff_out_of_memory
;
1182 MDIFF(d
, i2
, i1
, icmpInMsgs
);
1183 MDIFF(d
, i2
, i1
, icmpInErrors
);
1184 MDIFF(d
, i2
, i1
, icmpInCksumErrs
);
1185 MDIFF(d
, i2
, i1
, icmpInUnknowns
);
1186 MDIFF(d
, i2
, i1
, icmpInDestUnreachs
);
1187 MDIFF(d
, i2
, i1
, icmpInTimeExcds
);
1188 MDIFF(d
, i2
, i1
, icmpInParmProbs
);
1189 MDIFF(d
, i2
, i1
, icmpInSrcQuenchs
);
1190 MDIFF(d
, i2
, i1
, icmpInRedirects
);
1191 MDIFF(d
, i2
, i1
, icmpInBadRedirects
);
1192 MDIFF(d
, i2
, i1
, icmpInEchos
);
1193 MDIFF(d
, i2
, i1
, icmpInEchoReps
);
1194 MDIFF(d
, i2
, i1
, icmpInTimestamps
);
1195 MDIFF(d
, i2
, i1
, icmpInAddrMasks
);
1196 MDIFF(d
, i2
, i1
, icmpInAddrMaskReps
);
1197 MDIFF(d
, i2
, i1
, icmpInFragNeeded
);
1198 MDIFF(d
, i2
, i1
, icmpOutMsgs
);
1199 MDIFF(d
, i2
, i1
, icmpOutDrops
);
1200 MDIFF(d
, i2
, i1
, icmpOutErrors
);
1201 MDIFF(d
, i2
, i1
, icmpOutDestUnreachs
);
1202 MDIFF(d
, i2
, i1
, icmpOutTimeExcds
);
1203 MDIFF(d
, i2
, i1
, icmpOutParmProbs
);
1204 MDIFF(d
, i2
, i1
, icmpOutSrcQuenchs
);
1205 MDIFF(d
, i2
, i1
, icmpOutRedirects
);
1206 MDIFF(d
, i2
, i1
, icmpOutEchos
);
1207 MDIFF(d
, i2
, i1
, icmpOutEchoReps
);
1208 MDIFF(d
, i2
, i1
, icmpOutTimestamps
);
1209 MDIFF(d
, i2
, i1
, icmpOutTimestampReps
);
1210 MDIFF(d
, i2
, i1
, icmpOutAddrMasks
);
1211 MDIFF(d
, i2
, i1
, icmpOutAddrMaskReps
);
1212 MDIFF(d
, i2
, i1
, icmpOutFragNeeded
);
1213 MDIFF(d
, i2
, i1
, icmpInOverflows
);
1218 mib2_ipv6IfIcmpEntry_t
*i2
;
1219 mib2_ipv6IfIcmpEntry_t
*i1
;
1220 mib2_ipv6IfIcmpEntry_t
*d
;
1222 i2
= (mib2_ipv6IfIcmpEntry_t
*)tempp2
->valp
;
1223 i1
= (mib2_ipv6IfIcmpEntry_t
*)tempp1
->valp
;
1224 diffptr
->group
= tempp2
->group
;
1225 diffptr
->mib_id
= tempp2
->mib_id
;
1226 diffptr
->length
= tempp2
->length
;
1227 d
= (mib2_ipv6IfIcmpEntry_t
*)calloc(tempp2
->length
, 1);
1229 goto mibdiff_out_of_memory
;
1231 MDIFF(d
, i2
, i1
, ipv6IfIcmpInMsgs
);
1232 MDIFF(d
, i2
, i1
, ipv6IfIcmpInErrors
);
1233 MDIFF(d
, i2
, i1
, ipv6IfIcmpInDestUnreachs
);
1234 MDIFF(d
, i2
, i1
, ipv6IfIcmpInAdminProhibs
);
1235 MDIFF(d
, i2
, i1
, ipv6IfIcmpInTimeExcds
);
1236 MDIFF(d
, i2
, i1
, ipv6IfIcmpInParmProblems
);
1237 MDIFF(d
, i2
, i1
, ipv6IfIcmpInPktTooBigs
);
1238 MDIFF(d
, i2
, i1
, ipv6IfIcmpInEchos
);
1239 MDIFF(d
, i2
, i1
, ipv6IfIcmpInEchoReplies
);
1240 MDIFF(d
, i2
, i1
, ipv6IfIcmpInRouterSolicits
);
1241 MDIFF(d
, i2
, i1
, ipv6IfIcmpInRouterAdvertisements
);
1242 MDIFF(d
, i2
, i1
, ipv6IfIcmpInNeighborSolicits
);
1243 MDIFF(d
, i2
, i1
, ipv6IfIcmpInNeighborAdvertisements
);
1244 MDIFF(d
, i2
, i1
, ipv6IfIcmpInRedirects
);
1245 MDIFF(d
, i2
, i1
, ipv6IfIcmpInBadRedirects
);
1246 MDIFF(d
, i2
, i1
, ipv6IfIcmpInGroupMembQueries
);
1247 MDIFF(d
, i2
, i1
, ipv6IfIcmpInGroupMembResponses
);
1248 MDIFF(d
, i2
, i1
, ipv6IfIcmpInGroupMembReductions
);
1249 MDIFF(d
, i2
, i1
, ipv6IfIcmpInOverflows
);
1250 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutMsgs
);
1251 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutErrors
);
1252 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutDestUnreachs
);
1253 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutAdminProhibs
);
1254 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutTimeExcds
);
1255 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutParmProblems
);
1256 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutPktTooBigs
);
1257 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutEchos
);
1258 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutEchoReplies
);
1259 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutRouterSolicits
);
1260 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutRouterAdvertisements
);
1261 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutNeighborSolicits
);
1262 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutNeighborAdvertisements
);
1263 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutRedirects
);
1264 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutGroupMembQueries
);
1265 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutGroupMembResponses
);
1266 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutGroupMembReductions
);
1275 t2
= (mib2_tcp_t
*)tempp2
->valp
;
1276 t1
= (mib2_tcp_t
*)tempp1
->valp
;
1277 diffptr
->group
= tempp2
->group
;
1278 diffptr
->mib_id
= tempp2
->mib_id
;
1279 diffptr
->length
= tempp2
->length
;
1280 d
= (mib2_tcp_t
*)calloc(tempp2
->length
, 1);
1282 goto mibdiff_out_of_memory
;
1284 d
->tcpRtoMin
= t2
->tcpRtoMin
;
1285 d
->tcpRtoMax
= t2
->tcpRtoMax
;
1286 d
->tcpMaxConn
= t2
->tcpMaxConn
;
1287 MDIFF(d
, t2
, t1
, tcpActiveOpens
);
1288 MDIFF(d
, t2
, t1
, tcpPassiveOpens
);
1289 MDIFF(d
, t2
, t1
, tcpAttemptFails
);
1290 MDIFF(d
, t2
, t1
, tcpEstabResets
);
1291 d
->tcpCurrEstab
= t2
->tcpCurrEstab
;
1292 MDIFF(d
, t2
, t1
, tcpHCOutSegs
);
1293 MDIFF(d
, t2
, t1
, tcpOutDataSegs
);
1294 MDIFF(d
, t2
, t1
, tcpOutDataBytes
);
1295 MDIFF(d
, t2
, t1
, tcpRetransSegs
);
1296 MDIFF(d
, t2
, t1
, tcpRetransBytes
);
1297 MDIFF(d
, t2
, t1
, tcpOutAck
);
1298 MDIFF(d
, t2
, t1
, tcpOutAckDelayed
);
1299 MDIFF(d
, t2
, t1
, tcpOutUrg
);
1300 MDIFF(d
, t2
, t1
, tcpOutWinUpdate
);
1301 MDIFF(d
, t2
, t1
, tcpOutWinProbe
);
1302 MDIFF(d
, t2
, t1
, tcpOutControl
);
1303 MDIFF(d
, t2
, t1
, tcpOutRsts
);
1304 MDIFF(d
, t2
, t1
, tcpOutFastRetrans
);
1305 MDIFF(d
, t2
, t1
, tcpHCInSegs
);
1306 MDIFF(d
, t2
, t1
, tcpInAckSegs
);
1307 MDIFF(d
, t2
, t1
, tcpInAckBytes
);
1308 MDIFF(d
, t2
, t1
, tcpInDupAck
);
1309 MDIFF(d
, t2
, t1
, tcpInAckUnsent
);
1310 MDIFF(d
, t2
, t1
, tcpInDataInorderSegs
);
1311 MDIFF(d
, t2
, t1
, tcpInDataInorderBytes
);
1312 MDIFF(d
, t2
, t1
, tcpInDataUnorderSegs
);
1313 MDIFF(d
, t2
, t1
, tcpInDataUnorderBytes
);
1314 MDIFF(d
, t2
, t1
, tcpInDataDupSegs
);
1315 MDIFF(d
, t2
, t1
, tcpInDataDupBytes
);
1316 MDIFF(d
, t2
, t1
, tcpInDataPartDupSegs
);
1317 MDIFF(d
, t2
, t1
, tcpInDataPartDupBytes
);
1318 MDIFF(d
, t2
, t1
, tcpInDataPastWinSegs
);
1319 MDIFF(d
, t2
, t1
, tcpInDataPastWinBytes
);
1320 MDIFF(d
, t2
, t1
, tcpInWinProbe
);
1321 MDIFF(d
, t2
, t1
, tcpInWinUpdate
);
1322 MDIFF(d
, t2
, t1
, tcpInClosed
);
1323 MDIFF(d
, t2
, t1
, tcpRttNoUpdate
);
1324 MDIFF(d
, t2
, t1
, tcpRttUpdate
);
1325 MDIFF(d
, t2
, t1
, tcpTimRetrans
);
1326 MDIFF(d
, t2
, t1
, tcpTimRetransDrop
);
1327 MDIFF(d
, t2
, t1
, tcpTimKeepalive
);
1328 MDIFF(d
, t2
, t1
, tcpTimKeepaliveProbe
);
1329 MDIFF(d
, t2
, t1
, tcpTimKeepaliveDrop
);
1330 MDIFF(d
, t2
, t1
, tcpListenDrop
);
1331 MDIFF(d
, t2
, t1
, tcpListenDropQ0
);
1332 MDIFF(d
, t2
, t1
, tcpHalfOpenDrop
);
1333 MDIFF(d
, t2
, t1
, tcpOutSackRetransSegs
);
1342 u2
= (mib2_udp_t
*)tempp2
->valp
;
1343 u1
= (mib2_udp_t
*)tempp1
->valp
;
1344 diffptr
->group
= tempp2
->group
;
1345 diffptr
->mib_id
= tempp2
->mib_id
;
1346 diffptr
->length
= tempp2
->length
;
1347 d
= (mib2_udp_t
*)calloc(tempp2
->length
, 1);
1349 goto mibdiff_out_of_memory
;
1351 MDIFF(d
, u2
, u1
, udpHCInDatagrams
);
1352 MDIFF(d
, u2
, u1
, udpInErrors
);
1353 MDIFF(d
, u2
, u1
, udpHCOutDatagrams
);
1354 MDIFF(d
, u2
, u1
, udpOutErrors
);
1363 s2
= (mib2_sctp_t
*)tempp2
->valp
;
1364 s1
= (mib2_sctp_t
*)tempp1
->valp
;
1365 diffptr
->group
= tempp2
->group
;
1366 diffptr
->mib_id
= tempp2
->mib_id
;
1367 diffptr
->length
= tempp2
->length
;
1368 d
= (mib2_sctp_t
*)calloc(tempp2
->length
, 1);
1370 goto mibdiff_out_of_memory
;
1372 d
->sctpRtoAlgorithm
= s2
->sctpRtoAlgorithm
;
1373 d
->sctpRtoMin
= s2
->sctpRtoMin
;
1374 d
->sctpRtoMax
= s2
->sctpRtoMax
;
1375 d
->sctpRtoInitial
= s2
->sctpRtoInitial
;
1376 d
->sctpMaxAssocs
= s2
->sctpMaxAssocs
;
1377 d
->sctpValCookieLife
= s2
->sctpValCookieLife
;
1378 d
->sctpMaxInitRetr
= s2
->sctpMaxInitRetr
;
1379 d
->sctpCurrEstab
= s2
->sctpCurrEstab
;
1380 MDIFF(d
, s2
, s1
, sctpActiveEstab
);
1381 MDIFF(d
, s2
, s1
, sctpPassiveEstab
);
1382 MDIFF(d
, s2
, s1
, sctpAborted
);
1383 MDIFF(d
, s2
, s1
, sctpShutdowns
);
1384 MDIFF(d
, s2
, s1
, sctpOutOfBlue
);
1385 MDIFF(d
, s2
, s1
, sctpChecksumError
);
1386 MDIFF(d
, s2
, s1
, sctpOutCtrlChunks
);
1387 MDIFF(d
, s2
, s1
, sctpOutOrderChunks
);
1388 MDIFF(d
, s2
, s1
, sctpOutUnorderChunks
);
1389 MDIFF(d
, s2
, s1
, sctpRetransChunks
);
1390 MDIFF(d
, s2
, s1
, sctpOutAck
);
1391 MDIFF(d
, s2
, s1
, sctpOutAckDelayed
);
1392 MDIFF(d
, s2
, s1
, sctpOutWinUpdate
);
1393 MDIFF(d
, s2
, s1
, sctpOutFastRetrans
);
1394 MDIFF(d
, s2
, s1
, sctpOutWinProbe
);
1395 MDIFF(d
, s2
, s1
, sctpInCtrlChunks
);
1396 MDIFF(d
, s2
, s1
, sctpInOrderChunks
);
1397 MDIFF(d
, s2
, s1
, sctpInUnorderChunks
);
1398 MDIFF(d
, s2
, s1
, sctpInAck
);
1399 MDIFF(d
, s2
, s1
, sctpInDupAck
);
1400 MDIFF(d
, s2
, s1
, sctpInAckUnsent
);
1401 MDIFF(d
, s2
, s1
, sctpFragUsrMsgs
);
1402 MDIFF(d
, s2
, s1
, sctpReasmUsrMsgs
);
1403 MDIFF(d
, s2
, s1
, sctpOutSCTPPkts
);
1404 MDIFF(d
, s2
, s1
, sctpInSCTPPkts
);
1405 MDIFF(d
, s2
, s1
, sctpInInvalidCookie
);
1406 MDIFF(d
, s2
, s1
, sctpTimRetrans
);
1407 MDIFF(d
, s2
, s1
, sctpTimRetransDrop
);
1408 MDIFF(d
, s2
, s1
, sctpTimHeartBeatProbe
);
1409 MDIFF(d
, s2
, s1
, sctpTimHeartBeatDrop
);
1410 MDIFF(d
, s2
, s1
, sctpListenDrop
);
1411 MDIFF(d
, s2
, s1
, sctpInClosed
);
1420 r2
= (mib2_rawip_t
*)tempp2
->valp
;
1421 r1
= (mib2_rawip_t
*)tempp1
->valp
;
1422 diffptr
->group
= tempp2
->group
;
1423 diffptr
->mib_id
= tempp2
->mib_id
;
1424 diffptr
->length
= tempp2
->length
;
1425 d
= (mib2_rawip_t
*)calloc(tempp2
->length
, 1);
1427 goto mibdiff_out_of_memory
;
1429 MDIFF(d
, r2
, r1
, rawipInDatagrams
);
1430 MDIFF(d
, r2
, r1
, rawipInErrors
);
1431 MDIFF(d
, r2
, r1
, rawipInCksumErrs
);
1432 MDIFF(d
, r2
, r1
, rawipOutDatagrams
);
1433 MDIFF(d
, r2
, r1
, rawipOutErrors
);
1438 * there are more "group" types but they aren't
1439 * required for the -s and -Ms options
1442 } /* 'for' loop 2 ends */
1444 } /* 'for' loop 1 ends */
1447 diffptr
->next_item
= NULL
;
1450 mibdiff_out_of_memory
:;
1451 mib_item_destroy(&diffp
);
1456 * mib_item_destroy: cleans up a mib_item_t *
1457 * that was created by calling mib_item_dup or
1461 mib_item_destroy(mib_item_t
**itemp
) {
1466 if (itemp
== NULL
|| *itemp
== NULL
)
1469 for (tempp
= *itemp
; tempp
!= NULL
; tempp
= tempp
->next_item
)
1470 if (tempp
->mib_id
== 0)
1473 return; /* cannot destroy! */
1476 return; /* cannot destroy! */
1478 for (c
= nitems
- 1; c
>= 0; c
--) {
1479 free((itemp
[0][c
]).valp
);
1486 /* Compare two Octet_ts. Return B_TRUE if they match, B_FALSE if not. */
1488 octetstrmatch(const Octet_t
*a
, const Octet_t
*b
)
1490 if (a
== NULL
|| b
== NULL
)
1493 if (a
->o_length
!= b
->o_length
)
1496 return (memcmp(a
->o_bytes
, b
->o_bytes
, a
->o_length
) == 0);
1499 /* If octetstr() changes make an appropriate change to STR_EXPAND */
1501 octetstr(const Octet_t
*op
, int code
, char *dst
, uint_t dstlen
)
1508 for (i
= 0; i
< op
->o_length
; i
++) {
1511 if (cp
- dst
+ 4 > dstlen
) {
1515 (void) snprintf(cp
, 5, "%d.",
1516 0xff & op
->o_bytes
[i
]);
1517 cp
= strchr(cp
, '\0');
1520 if (cp
- dst
+ 1 > dstlen
) {
1524 *cp
++ = op
->o_bytes
[i
];
1528 if (cp
- dst
+ 3 > dstlen
) {
1532 (void) snprintf(cp
, 4, "%02x:",
1533 0xff & op
->o_bytes
[i
]);
1539 if (code
!= 'a' && cp
!= dst
)
1546 mitcp_state(int state
)
1548 static char tcpsbuf
[50];
1570 case TCPS_ESTABLISHED
:
1573 case TCPS_CLOSE_WAIT
:
1576 case TCPS_FIN_WAIT_1
:
1585 case TCPS_FIN_WAIT_2
:
1588 case TCPS_TIME_WAIT
:
1592 (void) snprintf(tcpsbuf
, sizeof (tcpsbuf
),
1593 "UnknownState(%d)", state
);
1602 miudp_state(int state
)
1604 static char udpsbuf
[50];
1608 case MIB2_UDP_unbound
:
1614 case MIB2_UDP_connected
:
1618 (void) snprintf(udpsbuf
, sizeof (udpsbuf
),
1619 "Unknown State(%d)", state
);
1636 prval(char *str
, Counter val
)
1638 (void) printf("\t%-20s=%6u", str
, val
);
1640 (void) putchar('\n');
1644 prval64(char *str
, Counter64 val
)
1646 (void) printf("\t%-20s=%6llu", str
, val
);
1648 (void) putchar('\n');
1652 pr_int_val(char *str
, int val
)
1654 (void) printf("\t%-20s=%6d", str
, val
);
1656 (void) putchar('\n');
1660 pr_sctp_rtoalgo(char *str
, int val
)
1662 (void) printf("\t%-20s=", str
);
1664 case MIB2_SCTP_RTOALGO_OTHER
:
1665 (void) printf("%6.6s", "other");
1668 case MIB2_SCTP_RTOALGO_VANJ
:
1669 (void) printf("%6.6s", "vanj");
1673 (void) printf("%6d", val
);
1677 (void) putchar('\n');
1684 (void) putchar('\n');
1687 /* Extract constant sizes */
1689 mib_get_constants(mib_item_t
*item
)
1692 for (; item
; item
= item
->next_item
) {
1693 if (item
->mib_id
!= 0)
1694 continue; /* 'for' loop 1 */
1696 switch (item
->group
) {
1698 mib2_ip_t
*ip
= (mib2_ip_t
*)item
->valp
;
1700 ipAddrEntrySize
= ip
->ipAddrEntrySize
;
1701 ipRouteEntrySize
= ip
->ipRouteEntrySize
;
1702 ipNetToMediaEntrySize
= ip
->ipNetToMediaEntrySize
;
1703 ipMemberEntrySize
= ip
->ipMemberEntrySize
;
1704 ipGroupSourceEntrySize
= ip
->ipGroupSourceEntrySize
;
1705 ipDestEntrySize
= ip
->ipDestEntrySize
;
1706 assert(IS_P2ALIGNED(ipAddrEntrySize
,
1707 sizeof (mib2_ipAddrEntry_t
*)));
1708 assert(IS_P2ALIGNED(ipRouteEntrySize
,
1709 sizeof (mib2_ipRouteEntry_t
*)));
1710 assert(IS_P2ALIGNED(ipNetToMediaEntrySize
,
1711 sizeof (mib2_ipNetToMediaEntry_t
*)));
1712 assert(IS_P2ALIGNED(ipMemberEntrySize
,
1713 sizeof (ip_member_t
*)));
1714 assert(IS_P2ALIGNED(ipGroupSourceEntrySize
,
1715 sizeof (ip_grpsrc_t
*)));
1719 struct mrtstat
*mrts
= (struct mrtstat
*)item
->valp
;
1721 vifctlSize
= mrts
->mrts_vifctlSize
;
1722 mfcctlSize
= mrts
->mrts_mfcctlSize
;
1723 assert(IS_P2ALIGNED(vifctlSize
,
1724 sizeof (struct vifclt
*)));
1725 assert(IS_P2ALIGNED(mfcctlSize
,
1726 sizeof (struct mfcctl
*)));
1730 mib2_ipv6IfStatsEntry_t
*ip6
;
1731 /* Just use the first entry */
1733 ip6
= (mib2_ipv6IfStatsEntry_t
*)item
->valp
;
1734 ipv6IfStatsEntrySize
= ip6
->ipv6IfStatsEntrySize
;
1735 ipv6AddrEntrySize
= ip6
->ipv6AddrEntrySize
;
1736 ipv6RouteEntrySize
= ip6
->ipv6RouteEntrySize
;
1737 ipv6NetToMediaEntrySize
= ip6
->ipv6NetToMediaEntrySize
;
1738 ipv6MemberEntrySize
= ip6
->ipv6MemberEntrySize
;
1739 ipv6GroupSourceEntrySize
=
1740 ip6
->ipv6GroupSourceEntrySize
;
1741 assert(IS_P2ALIGNED(ipv6IfStatsEntrySize
,
1742 sizeof (mib2_ipv6IfStatsEntry_t
*)));
1743 assert(IS_P2ALIGNED(ipv6AddrEntrySize
,
1744 sizeof (mib2_ipv6AddrEntry_t
*)));
1745 assert(IS_P2ALIGNED(ipv6RouteEntrySize
,
1746 sizeof (mib2_ipv6RouteEntry_t
*)));
1747 assert(IS_P2ALIGNED(ipv6NetToMediaEntrySize
,
1748 sizeof (mib2_ipv6NetToMediaEntry_t
*)));
1749 assert(IS_P2ALIGNED(ipv6MemberEntrySize
,
1750 sizeof (ipv6_member_t
*)));
1751 assert(IS_P2ALIGNED(ipv6GroupSourceEntrySize
,
1752 sizeof (ipv6_grpsrc_t
*)));
1756 mib2_ipv6IfIcmpEntry_t
*icmp6
;
1757 /* Just use the first entry */
1759 icmp6
= (mib2_ipv6IfIcmpEntry_t
*)item
->valp
;
1760 ipv6IfIcmpEntrySize
= icmp6
->ipv6IfIcmpEntrySize
;
1761 assert(IS_P2ALIGNED(ipv6IfIcmpEntrySize
,
1762 sizeof (mib2_ipv6IfIcmpEntry_t
*)));
1766 mib2_tcp_t
*tcp
= (mib2_tcp_t
*)item
->valp
;
1768 tcpConnEntrySize
= tcp
->tcpConnTableSize
;
1769 tcp6ConnEntrySize
= tcp
->tcp6ConnTableSize
;
1770 assert(IS_P2ALIGNED(tcpConnEntrySize
,
1771 sizeof (mib2_tcpConnEntry_t
*)));
1772 assert(IS_P2ALIGNED(tcp6ConnEntrySize
,
1773 sizeof (mib2_tcp6ConnEntry_t
*)));
1777 mib2_udp_t
*udp
= (mib2_udp_t
*)item
->valp
;
1779 udpEntrySize
= udp
->udpEntrySize
;
1780 udp6EntrySize
= udp
->udp6EntrySize
;
1781 assert(IS_P2ALIGNED(udpEntrySize
,
1782 sizeof (mib2_udpEntry_t
*)));
1783 assert(IS_P2ALIGNED(udp6EntrySize
,
1784 sizeof (mib2_udp6Entry_t
*)));
1788 mib2_sctp_t
*sctp
= (mib2_sctp_t
*)item
->valp
;
1790 sctpEntrySize
= sctp
->sctpEntrySize
;
1791 sctpLocalEntrySize
= sctp
->sctpLocalEntrySize
;
1792 sctpRemoteEntrySize
= sctp
->sctpRemoteEntrySize
;
1796 } /* 'for' loop 1 ends */
1799 (void) puts("mib_get_constants:");
1800 (void) printf("\tipv6IfStatsEntrySize %d\n",
1801 ipv6IfStatsEntrySize
);
1802 (void) printf("\tipAddrEntrySize %d\n", ipAddrEntrySize
);
1803 (void) printf("\tipRouteEntrySize %d\n", ipRouteEntrySize
);
1804 (void) printf("\tipNetToMediaEntrySize %d\n",
1805 ipNetToMediaEntrySize
);
1806 (void) printf("\tipMemberEntrySize %d\n", ipMemberEntrySize
);
1807 (void) printf("\tvifctlSize %d\n", vifctlSize
);
1808 (void) printf("\tmfcctlSize %d\n", mfcctlSize
);
1810 (void) printf("\tipv6AddrEntrySize %d\n", ipv6AddrEntrySize
);
1811 (void) printf("\tipv6RouteEntrySize %d\n", ipv6RouteEntrySize
);
1812 (void) printf("\tipv6NetToMediaEntrySize %d\n",
1813 ipv6NetToMediaEntrySize
);
1814 (void) printf("\tipv6MemberEntrySize %d\n",
1815 ipv6MemberEntrySize
);
1816 (void) printf("\tipv6IfIcmpEntrySize %d\n",
1817 ipv6IfIcmpEntrySize
);
1818 (void) printf("\tipDestEntrySize %d\n", ipDestEntrySize
);
1819 (void) printf("\ttcpConnEntrySize %d\n", tcpConnEntrySize
);
1820 (void) printf("\ttcp6ConnEntrySize %d\n", tcp6ConnEntrySize
);
1821 (void) printf("\tudpEntrySize %d\n", udpEntrySize
);
1822 (void) printf("\tudp6EntrySize %d\n", udp6EntrySize
);
1823 (void) printf("\tsctpEntrySize %d\n", sctpEntrySize
);
1824 (void) printf("\tsctpLocalEntrySize %d\n", sctpLocalEntrySize
);
1825 (void) printf("\tsctpRemoteEntrySize %d\n",
1826 sctpRemoteEntrySize
);
1831 /* ----------------------------- STAT_REPORT ------------------------------- */
1834 stat_report(mib_item_t
*item
)
1837 char ifname
[LIFNAMSIZ
+ 1];
1840 for (; item
; item
= item
->next_item
) {
1842 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
1843 (void) printf("Group = %d, mib_id = %d, "
1844 "length = %d, valp = 0x%p\n",
1845 item
->group
, item
->mib_id
,
1846 item
->length
, item
->valp
);
1848 if (item
->mib_id
!= 0)
1849 continue; /* 'for' loop 1 */
1851 switch (item
->group
) {
1853 mib2_ip_t
*ip
= (mib2_ip_t
*)item
->valp
;
1855 if (protocol_selected(IPPROTO_IP
) &&
1856 family_selected(AF_INET
)) {
1857 (void) fputs(v4compat
? "\nIP" : "\nIPv4",
1865 (mib2_icmp_t
*)item
->valp
;
1867 if (protocol_selected(IPPROTO_ICMP
) &&
1868 family_selected(AF_INET
)) {
1869 (void) fputs(v4compat
? "\nICMP" : "\nICMPv4",
1871 print_icmp_stats(icmp
);
1876 mib2_ipv6IfStatsEntry_t
*ip6
;
1877 mib2_ipv6IfStatsEntry_t sum6
;
1879 if (!(protocol_selected(IPPROTO_IPV6
)) ||
1880 !(family_selected(AF_INET6
)))
1882 bzero(&sum6
, sizeof (sum6
));
1883 /* 'for' loop 2a: */
1884 for (ip6
= (mib2_ipv6IfStatsEntry_t
*)item
->valp
;
1885 (char *)ip6
< (char *)item
->valp
+ item
->length
;
1886 /* LINTED: (note 1) */
1887 ip6
= (mib2_ipv6IfStatsEntry_t
*)((char *)ip6
+
1888 ipv6IfStatsEntrySize
)) {
1889 if (ip6
->ipv6IfIndex
== 0) {
1891 * The "unknown interface" ip6
1892 * mib. Just add to the sum.
1894 sum_ip6_stats(ip6
, &sum6
);
1895 continue; /* 'for' loop 2a */
1898 (void) printf("\nIPv6 for %s\n",
1899 ifindex2str(ip6
->ipv6IfIndex
,
1901 print_ip6_stats(ip6
);
1903 sum_ip6_stats(ip6
, &sum6
);
1904 } /* 'for' loop 2a ends */
1905 (void) fputs("\nIPv6", stdout
);
1906 print_ip6_stats(&sum6
);
1910 mib2_ipv6IfIcmpEntry_t
*icmp6
;
1911 mib2_ipv6IfIcmpEntry_t sum6
;
1913 if (!(protocol_selected(IPPROTO_ICMPV6
)) ||
1914 !(family_selected(AF_INET6
)))
1916 bzero(&sum6
, sizeof (sum6
));
1917 /* 'for' loop 2b: */
1918 for (icmp6
= (mib2_ipv6IfIcmpEntry_t
*)item
->valp
;
1919 (char *)icmp6
< (char *)item
->valp
+ item
->length
;
1920 icmp6
= (void *)((char *)icmp6
+
1921 ipv6IfIcmpEntrySize
)) {
1922 if (icmp6
->ipv6IfIcmpIfIndex
== 0) {
1924 * The "unknown interface" icmp6
1925 * mib. Just add to the sum.
1927 sum_icmp6_stats(icmp6
, &sum6
);
1928 continue; /* 'for' loop 2b: */
1931 (void) printf("\nICMPv6 for %s\n",
1933 icmp6
->ipv6IfIcmpIfIndex
, ifname
));
1934 print_icmp6_stats(icmp6
);
1936 sum_icmp6_stats(icmp6
, &sum6
);
1937 } /* 'for' loop 2b ends */
1938 (void) fputs("\nICMPv6", stdout
);
1939 print_icmp6_stats(&sum6
);
1943 mib2_tcp_t
*tcp
= (mib2_tcp_t
*)item
->valp
;
1945 if (protocol_selected(IPPROTO_TCP
) &&
1946 (family_selected(AF_INET
) ||
1947 family_selected(AF_INET6
))) {
1948 (void) fputs("\nTCP", stdout
);
1949 print_tcp_stats(tcp
);
1954 mib2_udp_t
*udp
= (mib2_udp_t
*)item
->valp
;
1956 if (protocol_selected(IPPROTO_UDP
) &&
1957 (family_selected(AF_INET
) ||
1958 family_selected(AF_INET6
))) {
1959 (void) fputs("\nUDP", stdout
);
1960 print_udp_stats(udp
);
1965 mib2_sctp_t
*sctp
= (mib2_sctp_t
*)item
->valp
;
1967 if (protocol_selected(IPPROTO_SCTP
) &&
1968 (family_selected(AF_INET
) ||
1969 family_selected(AF_INET6
))) {
1970 (void) fputs("\nSCTP", stdout
);
1971 print_sctp_stats(sctp
);
1976 mib2_rawip_t
*rawip
=
1977 (mib2_rawip_t
*)item
->valp
;
1979 if (protocol_selected(IPPROTO_RAW
) &&
1980 (family_selected(AF_INET
) ||
1981 family_selected(AF_INET6
))) {
1982 (void) fputs("\nRAWIP", stdout
);
1983 print_rawip_stats(rawip
);
1988 struct igmpstat
*igps
=
1989 (struct igmpstat
*)item
->valp
;
1991 if (protocol_selected(IPPROTO_IGMP
) &&
1992 (family_selected(AF_INET
))) {
1993 (void) fputs("\nIGMP:\n", stdout
);
1994 print_igmp_stats(igps
);
1999 } /* 'for' loop 1 ends */
2000 (void) putchar('\n');
2001 (void) fflush(stdout
);
2005 print_ip_stats(mib2_ip_t
*ip
)
2008 pr_int_val("ipForwarding", ip
->ipForwarding
);
2009 pr_int_val("ipDefaultTTL", ip
->ipDefaultTTL
);
2010 prval("ipInReceives", ip
->ipInReceives
);
2011 prval("ipInHdrErrors", ip
->ipInHdrErrors
);
2012 prval("ipInAddrErrors", ip
->ipInAddrErrors
);
2013 prval("ipInCksumErrs", ip
->ipInCksumErrs
);
2014 prval("ipForwDatagrams", ip
->ipForwDatagrams
);
2015 prval("ipForwProhibits", ip
->ipForwProhibits
);
2016 prval("ipInUnknownProtos", ip
->ipInUnknownProtos
);
2017 prval("ipInDiscards", ip
->ipInDiscards
);
2018 prval("ipInDelivers", ip
->ipInDelivers
);
2019 prval("ipOutRequests", ip
->ipOutRequests
);
2020 prval("ipOutDiscards", ip
->ipOutDiscards
);
2021 prval("ipOutNoRoutes", ip
->ipOutNoRoutes
);
2022 pr_int_val("ipReasmTimeout", ip
->ipReasmTimeout
);
2023 prval("ipReasmReqds", ip
->ipReasmReqds
);
2024 prval("ipReasmOKs", ip
->ipReasmOKs
);
2025 prval("ipReasmFails", ip
->ipReasmFails
);
2026 prval("ipReasmDuplicates", ip
->ipReasmDuplicates
);
2027 prval("ipReasmPartDups", ip
->ipReasmPartDups
);
2028 prval("ipFragOKs", ip
->ipFragOKs
);
2029 prval("ipFragFails", ip
->ipFragFails
);
2030 prval("ipFragCreates", ip
->ipFragCreates
);
2031 prval("ipRoutingDiscards", ip
->ipRoutingDiscards
);
2033 prval("tcpInErrs", ip
->tcpInErrs
);
2034 prval("udpNoPorts", ip
->udpNoPorts
);
2035 prval("udpInCksumErrs", ip
->udpInCksumErrs
);
2036 prval("udpInOverflows", ip
->udpInOverflows
);
2037 prval("rawipInOverflows", ip
->rawipInOverflows
);
2038 prval("ipsecInSucceeded", ip
->ipsecInSucceeded
);
2039 prval("ipsecInFailed", ip
->ipsecInFailed
);
2040 prval("ipInIPv6", ip
->ipInIPv6
);
2041 prval("ipOutIPv6", ip
->ipOutIPv6
);
2042 prval("ipOutSwitchIPv6", ip
->ipOutSwitchIPv6
);
2047 print_icmp_stats(mib2_icmp_t
*icmp
)
2050 prval("icmpInMsgs", icmp
->icmpInMsgs
);
2051 prval("icmpInErrors", icmp
->icmpInErrors
);
2052 prval("icmpInCksumErrs", icmp
->icmpInCksumErrs
);
2053 prval("icmpInUnknowns", icmp
->icmpInUnknowns
);
2054 prval("icmpInDestUnreachs", icmp
->icmpInDestUnreachs
);
2055 prval("icmpInTimeExcds", icmp
->icmpInTimeExcds
);
2056 prval("icmpInParmProbs", icmp
->icmpInParmProbs
);
2057 prval("icmpInSrcQuenchs", icmp
->icmpInSrcQuenchs
);
2058 prval("icmpInRedirects", icmp
->icmpInRedirects
);
2059 prval("icmpInBadRedirects", icmp
->icmpInBadRedirects
);
2060 prval("icmpInEchos", icmp
->icmpInEchos
);
2061 prval("icmpInEchoReps", icmp
->icmpInEchoReps
);
2062 prval("icmpInTimestamps", icmp
->icmpInTimestamps
);
2063 prval("icmpInTimestampReps", icmp
->icmpInTimestampReps
);
2064 prval("icmpInAddrMasks", icmp
->icmpInAddrMasks
);
2065 prval("icmpInAddrMaskReps", icmp
->icmpInAddrMaskReps
);
2066 prval("icmpInFragNeeded", icmp
->icmpInFragNeeded
);
2067 prval("icmpOutMsgs", icmp
->icmpOutMsgs
);
2068 prval("icmpOutDrops", icmp
->icmpOutDrops
);
2069 prval("icmpOutErrors", icmp
->icmpOutErrors
);
2070 prval("icmpOutDestUnreachs", icmp
->icmpOutDestUnreachs
);
2071 prval("icmpOutTimeExcds", icmp
->icmpOutTimeExcds
);
2072 prval("icmpOutParmProbs", icmp
->icmpOutParmProbs
);
2073 prval("icmpOutSrcQuenchs", icmp
->icmpOutSrcQuenchs
);
2074 prval("icmpOutRedirects", icmp
->icmpOutRedirects
);
2075 prval("icmpOutEchos", icmp
->icmpOutEchos
);
2076 prval("icmpOutEchoReps", icmp
->icmpOutEchoReps
);
2077 prval("icmpOutTimestamps", icmp
->icmpOutTimestamps
);
2078 prval("icmpOutTimestampReps", icmp
->icmpOutTimestampReps
);
2079 prval("icmpOutAddrMasks", icmp
->icmpOutAddrMasks
);
2080 prval("icmpOutAddrMaskReps", icmp
->icmpOutAddrMaskReps
);
2081 prval("icmpOutFragNeeded", icmp
->icmpOutFragNeeded
);
2082 prval("icmpInOverflows", icmp
->icmpInOverflows
);
2087 print_ip6_stats(mib2_ipv6IfStatsEntry_t
*ip6
)
2090 prval("ipv6Forwarding", ip6
->ipv6Forwarding
);
2091 prval("ipv6DefaultHopLimit", ip6
->ipv6DefaultHopLimit
);
2093 prval("ipv6InReceives", ip6
->ipv6InReceives
);
2094 prval("ipv6InHdrErrors", ip6
->ipv6InHdrErrors
);
2095 prval("ipv6InTooBigErrors", ip6
->ipv6InTooBigErrors
);
2096 prval("ipv6InNoRoutes", ip6
->ipv6InNoRoutes
);
2097 prval("ipv6InAddrErrors", ip6
->ipv6InAddrErrors
);
2098 prval("ipv6InUnknownProtos", ip6
->ipv6InUnknownProtos
);
2099 prval("ipv6InTruncatedPkts", ip6
->ipv6InTruncatedPkts
);
2100 prval("ipv6InDiscards", ip6
->ipv6InDiscards
);
2101 prval("ipv6InDelivers", ip6
->ipv6InDelivers
);
2102 prval("ipv6OutForwDatagrams", ip6
->ipv6OutForwDatagrams
);
2103 prval("ipv6OutRequests", ip6
->ipv6OutRequests
);
2104 prval("ipv6OutDiscards", ip6
->ipv6OutDiscards
);
2105 prval("ipv6OutNoRoutes", ip6
->ipv6OutNoRoutes
);
2106 prval("ipv6OutFragOKs", ip6
->ipv6OutFragOKs
);
2107 prval("ipv6OutFragFails", ip6
->ipv6OutFragFails
);
2108 prval("ipv6OutFragCreates", ip6
->ipv6OutFragCreates
);
2109 prval("ipv6ReasmReqds", ip6
->ipv6ReasmReqds
);
2110 prval("ipv6ReasmOKs", ip6
->ipv6ReasmOKs
);
2111 prval("ipv6ReasmFails", ip6
->ipv6ReasmFails
);
2112 prval("ipv6InMcastPkts", ip6
->ipv6InMcastPkts
);
2113 prval("ipv6OutMcastPkts", ip6
->ipv6OutMcastPkts
);
2114 prval("ipv6ReasmDuplicates", ip6
->ipv6ReasmDuplicates
);
2115 prval("ipv6ReasmPartDups", ip6
->ipv6ReasmPartDups
);
2116 prval("ipv6ForwProhibits", ip6
->ipv6ForwProhibits
);
2117 prval("udpInCksumErrs", ip6
->udpInCksumErrs
);
2118 prval("udpInOverflows", ip6
->udpInOverflows
);
2119 prval("rawipInOverflows", ip6
->rawipInOverflows
);
2120 prval("ipv6InIPv4", ip6
->ipv6InIPv4
);
2121 prval("ipv6OutIPv4", ip6
->ipv6OutIPv4
);
2122 prval("ipv6OutSwitchIPv4", ip6
->ipv6OutSwitchIPv4
);
2127 print_icmp6_stats(mib2_ipv6IfIcmpEntry_t
*icmp6
)
2130 prval("icmp6InMsgs", icmp6
->ipv6IfIcmpInMsgs
);
2131 prval("icmp6InErrors", icmp6
->ipv6IfIcmpInErrors
);
2132 prval("icmp6InDestUnreachs", icmp6
->ipv6IfIcmpInDestUnreachs
);
2133 prval("icmp6InAdminProhibs", icmp6
->ipv6IfIcmpInAdminProhibs
);
2134 prval("icmp6InTimeExcds", icmp6
->ipv6IfIcmpInTimeExcds
);
2135 prval("icmp6InParmProblems", icmp6
->ipv6IfIcmpInParmProblems
);
2136 prval("icmp6InPktTooBigs", icmp6
->ipv6IfIcmpInPktTooBigs
);
2137 prval("icmp6InEchos", icmp6
->ipv6IfIcmpInEchos
);
2138 prval("icmp6InEchoReplies", icmp6
->ipv6IfIcmpInEchoReplies
);
2139 prval("icmp6InRouterSols", icmp6
->ipv6IfIcmpInRouterSolicits
);
2140 prval("icmp6InRouterAds",
2141 icmp6
->ipv6IfIcmpInRouterAdvertisements
);
2142 prval("icmp6InNeighborSols", icmp6
->ipv6IfIcmpInNeighborSolicits
);
2143 prval("icmp6InNeighborAds",
2144 icmp6
->ipv6IfIcmpInNeighborAdvertisements
);
2145 prval("icmp6InRedirects", icmp6
->ipv6IfIcmpInRedirects
);
2146 prval("icmp6InBadRedirects", icmp6
->ipv6IfIcmpInBadRedirects
);
2147 prval("icmp6InGroupQueries", icmp6
->ipv6IfIcmpInGroupMembQueries
);
2148 prval("icmp6InGroupResps", icmp6
->ipv6IfIcmpInGroupMembResponses
);
2149 prval("icmp6InGroupReds", icmp6
->ipv6IfIcmpInGroupMembReductions
);
2150 prval("icmp6InOverflows", icmp6
->ipv6IfIcmpInOverflows
);
2153 prval("icmp6OutMsgs", icmp6
->ipv6IfIcmpOutMsgs
);
2154 prval("icmp6OutErrors", icmp6
->ipv6IfIcmpOutErrors
);
2155 prval("icmp6OutDestUnreachs", icmp6
->ipv6IfIcmpOutDestUnreachs
);
2156 prval("icmp6OutAdminProhibs", icmp6
->ipv6IfIcmpOutAdminProhibs
);
2157 prval("icmp6OutTimeExcds", icmp6
->ipv6IfIcmpOutTimeExcds
);
2158 prval("icmp6OutParmProblems", icmp6
->ipv6IfIcmpOutParmProblems
);
2159 prval("icmp6OutPktTooBigs", icmp6
->ipv6IfIcmpOutPktTooBigs
);
2160 prval("icmp6OutEchos", icmp6
->ipv6IfIcmpOutEchos
);
2161 prval("icmp6OutEchoReplies", icmp6
->ipv6IfIcmpOutEchoReplies
);
2162 prval("icmp6OutRouterSols", icmp6
->ipv6IfIcmpOutRouterSolicits
);
2163 prval("icmp6OutRouterAds",
2164 icmp6
->ipv6IfIcmpOutRouterAdvertisements
);
2165 prval("icmp6OutNeighborSols", icmp6
->ipv6IfIcmpOutNeighborSolicits
);
2166 prval("icmp6OutNeighborAds",
2167 icmp6
->ipv6IfIcmpOutNeighborAdvertisements
);
2168 prval("icmp6OutRedirects", icmp6
->ipv6IfIcmpOutRedirects
);
2169 prval("icmp6OutGroupQueries", icmp6
->ipv6IfIcmpOutGroupMembQueries
);
2170 prval("icmp6OutGroupResps",
2171 icmp6
->ipv6IfIcmpOutGroupMembResponses
);
2172 prval("icmp6OutGroupReds",
2173 icmp6
->ipv6IfIcmpOutGroupMembReductions
);
2178 print_sctp_stats(mib2_sctp_t
*sctp
)
2181 pr_sctp_rtoalgo("sctpRtoAlgorithm", sctp
->sctpRtoAlgorithm
);
2182 prval("sctpRtoMin", sctp
->sctpRtoMin
);
2183 prval("sctpRtoMax", sctp
->sctpRtoMax
);
2184 prval("sctpRtoInitial", sctp
->sctpRtoInitial
);
2185 pr_int_val("sctpMaxAssocs", sctp
->sctpMaxAssocs
);
2186 prval("sctpValCookieLife", sctp
->sctpValCookieLife
);
2187 prval("sctpMaxInitRetr", sctp
->sctpMaxInitRetr
);
2188 prval("sctpCurrEstab", sctp
->sctpCurrEstab
);
2189 prval("sctpActiveEstab", sctp
->sctpActiveEstab
);
2190 prval("sctpPassiveEstab", sctp
->sctpPassiveEstab
);
2191 prval("sctpAborted", sctp
->sctpAborted
);
2192 prval("sctpShutdowns", sctp
->sctpShutdowns
);
2193 prval("sctpOutOfBlue", sctp
->sctpOutOfBlue
);
2194 prval("sctpChecksumError", sctp
->sctpChecksumError
);
2195 prval64("sctpOutCtrlChunks", sctp
->sctpOutCtrlChunks
);
2196 prval64("sctpOutOrderChunks", sctp
->sctpOutOrderChunks
);
2197 prval64("sctpOutUnorderChunks", sctp
->sctpOutUnorderChunks
);
2198 prval64("sctpRetransChunks", sctp
->sctpRetransChunks
);
2199 prval("sctpOutAck", sctp
->sctpOutAck
);
2200 prval("sctpOutAckDelayed", sctp
->sctpOutAckDelayed
);
2201 prval("sctpOutWinUpdate", sctp
->sctpOutWinUpdate
);
2202 prval("sctpOutFastRetrans", sctp
->sctpOutFastRetrans
);
2203 prval("sctpOutWinProbe", sctp
->sctpOutWinProbe
);
2204 prval64("sctpInCtrlChunks", sctp
->sctpInCtrlChunks
);
2205 prval64("sctpInOrderChunks", sctp
->sctpInOrderChunks
);
2206 prval64("sctpInUnorderChunks", sctp
->sctpInUnorderChunks
);
2207 prval("sctpInAck", sctp
->sctpInAck
);
2208 prval("sctpInDupAck", sctp
->sctpInDupAck
);
2209 prval("sctpInAckUnsent", sctp
->sctpInAckUnsent
);
2210 prval64("sctpFragUsrMsgs", sctp
->sctpFragUsrMsgs
);
2211 prval64("sctpReasmUsrMsgs", sctp
->sctpReasmUsrMsgs
);
2212 prval64("sctpOutSCTPPkts", sctp
->sctpOutSCTPPkts
);
2213 prval64("sctpInSCTPPkts", sctp
->sctpInSCTPPkts
);
2214 prval("sctpInInvalidCookie", sctp
->sctpInInvalidCookie
);
2215 prval("sctpTimRetrans", sctp
->sctpTimRetrans
);
2216 prval("sctpTimRetransDrop", sctp
->sctpTimRetransDrop
);
2217 prval("sctpTimHearBeatProbe", sctp
->sctpTimHeartBeatProbe
);
2218 prval("sctpTimHearBeatDrop", sctp
->sctpTimHeartBeatDrop
);
2219 prval("sctpListenDrop", sctp
->sctpListenDrop
);
2220 prval("sctpInClosed", sctp
->sctpInClosed
);
2225 print_tcp_stats(mib2_tcp_t
*tcp
)
2228 pr_int_val("tcpRtoAlgorithm", tcp
->tcpRtoAlgorithm
);
2229 pr_int_val("tcpRtoMin", tcp
->tcpRtoMin
);
2230 pr_int_val("tcpRtoMax", tcp
->tcpRtoMax
);
2231 pr_int_val("tcpMaxConn", tcp
->tcpMaxConn
);
2232 prval("tcpActiveOpens", tcp
->tcpActiveOpens
);
2233 prval("tcpPassiveOpens", tcp
->tcpPassiveOpens
);
2234 prval("tcpAttemptFails", tcp
->tcpAttemptFails
);
2235 prval("tcpEstabResets", tcp
->tcpEstabResets
);
2236 prval("tcpCurrEstab", tcp
->tcpCurrEstab
);
2237 prval64("tcpOutSegs", tcp
->tcpHCOutSegs
);
2238 prval("tcpOutDataSegs", tcp
->tcpOutDataSegs
);
2239 prval("tcpOutDataBytes", tcp
->tcpOutDataBytes
);
2240 prval("tcpRetransSegs", tcp
->tcpRetransSegs
);
2241 prval("tcpRetransBytes", tcp
->tcpRetransBytes
);
2242 prval("tcpOutAck", tcp
->tcpOutAck
);
2243 prval("tcpOutAckDelayed", tcp
->tcpOutAckDelayed
);
2244 prval("tcpOutUrg", tcp
->tcpOutUrg
);
2245 prval("tcpOutWinUpdate", tcp
->tcpOutWinUpdate
);
2246 prval("tcpOutWinProbe", tcp
->tcpOutWinProbe
);
2247 prval("tcpOutControl", tcp
->tcpOutControl
);
2248 prval("tcpOutRsts", tcp
->tcpOutRsts
);
2249 prval("tcpOutFastRetrans", tcp
->tcpOutFastRetrans
);
2250 prval64("tcpInSegs", tcp
->tcpHCInSegs
);
2252 prval("tcpInAckSegs", tcp
->tcpInAckSegs
);
2253 prval("tcpInAckBytes", tcp
->tcpInAckBytes
);
2254 prval("tcpInDupAck", tcp
->tcpInDupAck
);
2255 prval("tcpInAckUnsent", tcp
->tcpInAckUnsent
);
2256 prval("tcpInInorderSegs", tcp
->tcpInDataInorderSegs
);
2257 prval("tcpInInorderBytes", tcp
->tcpInDataInorderBytes
);
2258 prval("tcpInUnorderSegs", tcp
->tcpInDataUnorderSegs
);
2259 prval("tcpInUnorderBytes", tcp
->tcpInDataUnorderBytes
);
2260 prval("tcpInDupSegs", tcp
->tcpInDataDupSegs
);
2261 prval("tcpInDupBytes", tcp
->tcpInDataDupBytes
);
2262 prval("tcpInPartDupSegs", tcp
->tcpInDataPartDupSegs
);
2263 prval("tcpInPartDupBytes", tcp
->tcpInDataPartDupBytes
);
2264 prval("tcpInPastWinSegs", tcp
->tcpInDataPastWinSegs
);
2265 prval("tcpInPastWinBytes", tcp
->tcpInDataPastWinBytes
);
2266 prval("tcpInWinProbe", tcp
->tcpInWinProbe
);
2267 prval("tcpInWinUpdate", tcp
->tcpInWinUpdate
);
2268 prval("tcpInClosed", tcp
->tcpInClosed
);
2269 prval("tcpRttNoUpdate", tcp
->tcpRttNoUpdate
);
2270 prval("tcpRttUpdate", tcp
->tcpRttUpdate
);
2271 prval("tcpTimRetrans", tcp
->tcpTimRetrans
);
2272 prval("tcpTimRetransDrop", tcp
->tcpTimRetransDrop
);
2273 prval("tcpTimKeepalive", tcp
->tcpTimKeepalive
);
2274 prval("tcpTimKeepaliveProbe", tcp
->tcpTimKeepaliveProbe
);
2275 prval("tcpTimKeepaliveDrop", tcp
->tcpTimKeepaliveDrop
);
2276 prval("tcpListenDrop", tcp
->tcpListenDrop
);
2277 prval("tcpListenDropQ0", tcp
->tcpListenDropQ0
);
2278 prval("tcpHalfOpenDrop", tcp
->tcpHalfOpenDrop
);
2279 prval("tcpOutSackRetrans", tcp
->tcpOutSackRetransSegs
);
2285 print_udp_stats(mib2_udp_t
*udp
)
2288 prval64("udpInDatagrams", udp
->udpHCInDatagrams
);
2289 prval("udpInErrors", udp
->udpInErrors
);
2290 prval64("udpOutDatagrams", udp
->udpHCOutDatagrams
);
2291 prval("udpOutErrors", udp
->udpOutErrors
);
2296 print_rawip_stats(mib2_rawip_t
*rawip
)
2299 prval("rawipInDatagrams", rawip
->rawipInDatagrams
);
2300 prval("rawipInErrors", rawip
->rawipInErrors
);
2301 prval("rawipInCksumErrs", rawip
->rawipInCksumErrs
);
2302 prval("rawipOutDatagrams", rawip
->rawipOutDatagrams
);
2303 prval("rawipOutErrors", rawip
->rawipOutErrors
);
2308 print_igmp_stats(struct igmpstat
*igps
)
2310 (void) printf(" %10u message%s received\n",
2311 igps
->igps_rcv_total
, PLURAL(igps
->igps_rcv_total
));
2312 (void) printf(" %10u message%s received with too few bytes\n",
2313 igps
->igps_rcv_tooshort
, PLURAL(igps
->igps_rcv_tooshort
));
2314 (void) printf(" %10u message%s received with bad checksum\n",
2315 igps
->igps_rcv_badsum
, PLURAL(igps
->igps_rcv_badsum
));
2316 (void) printf(" %10u membership quer%s received\n",
2317 igps
->igps_rcv_queries
, PLURALY(igps
->igps_rcv_queries
));
2318 (void) printf(" %10u membership quer%s received with invalid "
2320 igps
->igps_rcv_badqueries
, PLURALY(igps
->igps_rcv_badqueries
));
2321 (void) printf(" %10u membership report%s received\n",
2322 igps
->igps_rcv_reports
, PLURAL(igps
->igps_rcv_reports
));
2323 (void) printf(" %10u membership report%s received with invalid "
2325 igps
->igps_rcv_badreports
, PLURAL(igps
->igps_rcv_badreports
));
2326 (void) printf(" %10u membership report%s received for groups to "
2327 "which we belong\n",
2328 igps
->igps_rcv_ourreports
, PLURAL(igps
->igps_rcv_ourreports
));
2329 (void) printf(" %10u membership report%s sent\n",
2330 igps
->igps_snd_reports
, PLURAL(igps
->igps_snd_reports
));
2334 print_mrt_stats(struct mrtstat
*mrts
)
2336 (void) puts("DVMRP multicast routing:");
2337 (void) printf(" %10u hit%s - kernel forwarding cache hits\n",
2338 mrts
->mrts_mfc_hits
, PLURAL(mrts
->mrts_mfc_hits
));
2339 (void) printf(" %10u miss%s - kernel forwarding cache misses\n",
2340 mrts
->mrts_mfc_misses
, PLURALES(mrts
->mrts_mfc_misses
));
2341 (void) printf(" %10u packet%s potentially forwarded\n",
2342 mrts
->mrts_fwd_in
, PLURAL(mrts
->mrts_fwd_in
));
2343 (void) printf(" %10u packet%s actually sent out\n",
2344 mrts
->mrts_fwd_out
, PLURAL(mrts
->mrts_fwd_out
));
2345 (void) printf(" %10u upcall%s - upcalls made to mrouted\n",
2346 mrts
->mrts_upcalls
, PLURAL(mrts
->mrts_upcalls
));
2347 (void) printf(" %10u packet%s not sent out due to lack of resources\n",
2348 mrts
->mrts_fwd_drop
, PLURAL(mrts
->mrts_fwd_drop
));
2349 (void) printf(" %10u datagram%s with malformed tunnel options\n",
2350 mrts
->mrts_bad_tunnel
, PLURAL(mrts
->mrts_bad_tunnel
));
2351 (void) printf(" %10u datagram%s with no room for tunnel options\n",
2352 mrts
->mrts_cant_tunnel
, PLURAL(mrts
->mrts_cant_tunnel
));
2353 (void) printf(" %10u datagram%s arrived on wrong interface\n",
2354 mrts
->mrts_wrong_if
, PLURAL(mrts
->mrts_wrong_if
));
2355 (void) printf(" %10u datagram%s dropped due to upcall Q overflow\n",
2356 mrts
->mrts_upq_ovflw
, PLURAL(mrts
->mrts_upq_ovflw
));
2357 (void) printf(" %10u datagram%s cleaned up by the cache\n",
2358 mrts
->mrts_cache_cleanups
, PLURAL(mrts
->mrts_cache_cleanups
));
2359 (void) printf(" %10u datagram%s dropped selectively by ratelimiter\n",
2360 mrts
->mrts_drop_sel
, PLURAL(mrts
->mrts_drop_sel
));
2361 (void) printf(" %10u datagram%s dropped - bucket Q overflow\n",
2362 mrts
->mrts_q_overflow
, PLURAL(mrts
->mrts_q_overflow
));
2363 (void) printf(" %10u datagram%s dropped - larger than bkt size\n",
2364 mrts
->mrts_pkt2large
, PLURAL(mrts
->mrts_pkt2large
));
2365 (void) printf("\nPIM multicast routing:\n");
2366 (void) printf(" %10u datagram%s dropped - bad version number\n",
2367 mrts
->mrts_pim_badversion
, PLURAL(mrts
->mrts_pim_badversion
));
2368 (void) printf(" %10u datagram%s dropped - bad checksum\n",
2369 mrts
->mrts_pim_rcv_badcsum
, PLURAL(mrts
->mrts_pim_rcv_badcsum
));
2370 (void) printf(" %10u datagram%s dropped - bad register packets\n",
2371 mrts
->mrts_pim_badregisters
, PLURAL(mrts
->mrts_pim_badregisters
));
2373 " %10u datagram%s potentially forwarded - register packets\n",
2374 mrts
->mrts_pim_regforwards
, PLURAL(mrts
->mrts_pim_regforwards
));
2375 (void) printf(" %10u datagram%s dropped - register send drops\n",
2376 mrts
->mrts_pim_regsend_drops
, PLURAL(mrts
->mrts_pim_regsend_drops
));
2377 (void) printf(" %10u datagram%s dropped - packet malformed\n",
2378 mrts
->mrts_pim_malformed
, PLURAL(mrts
->mrts_pim_malformed
));
2379 (void) printf(" %10u datagram%s dropped - no memory to forward\n",
2380 mrts
->mrts_pim_nomemory
, PLURAL(mrts
->mrts_pim_nomemory
));
2384 sum_ip6_stats(mib2_ipv6IfStatsEntry_t
*ip6
, mib2_ipv6IfStatsEntry_t
*sum6
)
2386 /* First few are not additive */
2387 sum6
->ipv6Forwarding
= ip6
->ipv6Forwarding
;
2388 sum6
->ipv6DefaultHopLimit
= ip6
->ipv6DefaultHopLimit
;
2390 sum6
->ipv6InReceives
+= ip6
->ipv6InReceives
;
2391 sum6
->ipv6InHdrErrors
+= ip6
->ipv6InHdrErrors
;
2392 sum6
->ipv6InTooBigErrors
+= ip6
->ipv6InTooBigErrors
;
2393 sum6
->ipv6InNoRoutes
+= ip6
->ipv6InNoRoutes
;
2394 sum6
->ipv6InAddrErrors
+= ip6
->ipv6InAddrErrors
;
2395 sum6
->ipv6InUnknownProtos
+= ip6
->ipv6InUnknownProtos
;
2396 sum6
->ipv6InTruncatedPkts
+= ip6
->ipv6InTruncatedPkts
;
2397 sum6
->ipv6InDiscards
+= ip6
->ipv6InDiscards
;
2398 sum6
->ipv6InDelivers
+= ip6
->ipv6InDelivers
;
2399 sum6
->ipv6OutForwDatagrams
+= ip6
->ipv6OutForwDatagrams
;
2400 sum6
->ipv6OutRequests
+= ip6
->ipv6OutRequests
;
2401 sum6
->ipv6OutDiscards
+= ip6
->ipv6OutDiscards
;
2402 sum6
->ipv6OutFragOKs
+= ip6
->ipv6OutFragOKs
;
2403 sum6
->ipv6OutFragFails
+= ip6
->ipv6OutFragFails
;
2404 sum6
->ipv6OutFragCreates
+= ip6
->ipv6OutFragCreates
;
2405 sum6
->ipv6ReasmReqds
+= ip6
->ipv6ReasmReqds
;
2406 sum6
->ipv6ReasmOKs
+= ip6
->ipv6ReasmOKs
;
2407 sum6
->ipv6ReasmFails
+= ip6
->ipv6ReasmFails
;
2408 sum6
->ipv6InMcastPkts
+= ip6
->ipv6InMcastPkts
;
2409 sum6
->ipv6OutMcastPkts
+= ip6
->ipv6OutMcastPkts
;
2410 sum6
->ipv6OutNoRoutes
+= ip6
->ipv6OutNoRoutes
;
2411 sum6
->ipv6ReasmDuplicates
+= ip6
->ipv6ReasmDuplicates
;
2412 sum6
->ipv6ReasmPartDups
+= ip6
->ipv6ReasmPartDups
;
2413 sum6
->ipv6ForwProhibits
+= ip6
->ipv6ForwProhibits
;
2414 sum6
->udpInCksumErrs
+= ip6
->udpInCksumErrs
;
2415 sum6
->udpInOverflows
+= ip6
->udpInOverflows
;
2416 sum6
->rawipInOverflows
+= ip6
->rawipInOverflows
;
2420 sum_icmp6_stats(mib2_ipv6IfIcmpEntry_t
*icmp6
, mib2_ipv6IfIcmpEntry_t
*sum6
)
2422 sum6
->ipv6IfIcmpInMsgs
+= icmp6
->ipv6IfIcmpInMsgs
;
2423 sum6
->ipv6IfIcmpInErrors
+= icmp6
->ipv6IfIcmpInErrors
;
2424 sum6
->ipv6IfIcmpInDestUnreachs
+= icmp6
->ipv6IfIcmpInDestUnreachs
;
2425 sum6
->ipv6IfIcmpInAdminProhibs
+= icmp6
->ipv6IfIcmpInAdminProhibs
;
2426 sum6
->ipv6IfIcmpInTimeExcds
+= icmp6
->ipv6IfIcmpInTimeExcds
;
2427 sum6
->ipv6IfIcmpInParmProblems
+= icmp6
->ipv6IfIcmpInParmProblems
;
2428 sum6
->ipv6IfIcmpInPktTooBigs
+= icmp6
->ipv6IfIcmpInPktTooBigs
;
2429 sum6
->ipv6IfIcmpInEchos
+= icmp6
->ipv6IfIcmpInEchos
;
2430 sum6
->ipv6IfIcmpInEchoReplies
+= icmp6
->ipv6IfIcmpInEchoReplies
;
2431 sum6
->ipv6IfIcmpInRouterSolicits
+= icmp6
->ipv6IfIcmpInRouterSolicits
;
2432 sum6
->ipv6IfIcmpInRouterAdvertisements
+=
2433 icmp6
->ipv6IfIcmpInRouterAdvertisements
;
2434 sum6
->ipv6IfIcmpInNeighborSolicits
+=
2435 icmp6
->ipv6IfIcmpInNeighborSolicits
;
2436 sum6
->ipv6IfIcmpInNeighborAdvertisements
+=
2437 icmp6
->ipv6IfIcmpInNeighborAdvertisements
;
2438 sum6
->ipv6IfIcmpInRedirects
+= icmp6
->ipv6IfIcmpInRedirects
;
2439 sum6
->ipv6IfIcmpInGroupMembQueries
+=
2440 icmp6
->ipv6IfIcmpInGroupMembQueries
;
2441 sum6
->ipv6IfIcmpInGroupMembResponses
+=
2442 icmp6
->ipv6IfIcmpInGroupMembResponses
;
2443 sum6
->ipv6IfIcmpInGroupMembReductions
+=
2444 icmp6
->ipv6IfIcmpInGroupMembReductions
;
2445 sum6
->ipv6IfIcmpOutMsgs
+= icmp6
->ipv6IfIcmpOutMsgs
;
2446 sum6
->ipv6IfIcmpOutErrors
+= icmp6
->ipv6IfIcmpOutErrors
;
2447 sum6
->ipv6IfIcmpOutDestUnreachs
+= icmp6
->ipv6IfIcmpOutDestUnreachs
;
2448 sum6
->ipv6IfIcmpOutAdminProhibs
+= icmp6
->ipv6IfIcmpOutAdminProhibs
;
2449 sum6
->ipv6IfIcmpOutTimeExcds
+= icmp6
->ipv6IfIcmpOutTimeExcds
;
2450 sum6
->ipv6IfIcmpOutParmProblems
+= icmp6
->ipv6IfIcmpOutParmProblems
;
2451 sum6
->ipv6IfIcmpOutPktTooBigs
+= icmp6
->ipv6IfIcmpOutPktTooBigs
;
2452 sum6
->ipv6IfIcmpOutEchos
+= icmp6
->ipv6IfIcmpOutEchos
;
2453 sum6
->ipv6IfIcmpOutEchoReplies
+= icmp6
->ipv6IfIcmpOutEchoReplies
;
2454 sum6
->ipv6IfIcmpOutRouterSolicits
+=
2455 icmp6
->ipv6IfIcmpOutRouterSolicits
;
2456 sum6
->ipv6IfIcmpOutRouterAdvertisements
+=
2457 icmp6
->ipv6IfIcmpOutRouterAdvertisements
;
2458 sum6
->ipv6IfIcmpOutNeighborSolicits
+=
2459 icmp6
->ipv6IfIcmpOutNeighborSolicits
;
2460 sum6
->ipv6IfIcmpOutNeighborAdvertisements
+=
2461 icmp6
->ipv6IfIcmpOutNeighborAdvertisements
;
2462 sum6
->ipv6IfIcmpOutRedirects
+= icmp6
->ipv6IfIcmpOutRedirects
;
2463 sum6
->ipv6IfIcmpOutGroupMembQueries
+=
2464 icmp6
->ipv6IfIcmpOutGroupMembQueries
;
2465 sum6
->ipv6IfIcmpOutGroupMembResponses
+=
2466 icmp6
->ipv6IfIcmpOutGroupMembResponses
;
2467 sum6
->ipv6IfIcmpOutGroupMembReductions
+=
2468 icmp6
->ipv6IfIcmpOutGroupMembReductions
;
2469 sum6
->ipv6IfIcmpInOverflows
+= icmp6
->ipv6IfIcmpInOverflows
;
2472 /* ----------------------------- MRT_STAT_REPORT --------------------------- */
2475 mrt_stat_report(mib_item_t
*curritem
)
2478 mib_item_t
*tempitem
;
2480 if (!(family_selected(AF_INET
)))
2483 (void) putchar('\n');
2485 for (tempitem
= curritem
;
2487 tempitem
= tempitem
->next_item
) {
2489 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
2490 (void) printf("Group = %d, mib_id = %d, "
2491 "length = %d, valp = 0x%p\n",
2492 tempitem
->group
, tempitem
->mib_id
,
2493 tempitem
->length
, tempitem
->valp
);
2496 if (tempitem
->mib_id
== 0) {
2497 switch (tempitem
->group
) {
2499 struct mrtstat
*mrts
;
2500 mrts
= (struct mrtstat
*)tempitem
->valp
;
2502 if (!(family_selected(AF_INET
)))
2503 continue; /* 'for' loop 1 */
2505 print_mrt_stats(mrts
);
2510 } /* 'for' loop 1 ends */
2511 (void) putchar('\n');
2512 (void) fflush(stdout
);
2516 * if_stat_total() - Computes totals for interface statistics
2517 * and returns result by updating sumstats.
2520 if_stat_total(struct ifstat
*oldstats
, struct ifstat
*newstats
,
2521 struct ifstat
*sumstats
)
2523 sumstats
->ipackets
+= newstats
->ipackets
- oldstats
->ipackets
;
2524 sumstats
->opackets
+= newstats
->opackets
- oldstats
->opackets
;
2525 sumstats
->ierrors
+= newstats
->ierrors
- oldstats
->ierrors
;
2526 sumstats
->oerrors
+= newstats
->oerrors
- oldstats
->oerrors
;
2527 sumstats
->collisions
+= newstats
->collisions
- oldstats
->collisions
;
2530 /* --------------------- IF_REPORT (netstat -i) -------------------------- */
2532 static struct ifstat zerostat
= {
2533 0LL, 0LL, 0LL, 0LL, 0LL
2537 if_report(mib_item_t
*item
, char *matchname
,
2538 int Iflag_only
, boolean_t once_only
)
2540 static boolean_t reentry
= B_FALSE
;
2541 boolean_t alreadydone
= B_FALSE
;
2543 uint32_t ifindex_v4
= 0;
2544 uint32_t ifindex_v6
= 0;
2545 boolean_t first_header
= B_TRUE
;
2548 for (; item
; item
= item
->next_item
) {
2550 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
2551 (void) printf("Group = %d, mib_id = %d, "
2552 "length = %d, valp = 0x%p\n",
2553 item
->group
, item
->mib_id
, item
->length
,
2557 switch (item
->group
) {
2559 if (item
->mib_id
!= MIB2_IP_ADDR
||
2560 !family_selected(AF_INET
))
2561 continue; /* 'for' loop 1 */
2563 static struct ifstat old
= {0L, 0L, 0L, 0L, 0L};
2564 static struct ifstat
new = {0L, 0L, 0L, 0L, 0L};
2566 struct iflist
*newlist
= NULL
;
2567 static struct iflist
*oldlist
= NULL
;
2571 char ifname
[LIFNAMSIZ
+ 1];
2572 char logintname
[LIFNAMSIZ
+ 1];
2573 mib2_ipAddrEntry_t
*ap
;
2574 struct ifstat stat
= {0L, 0L, 0L, 0L, 0L};
2575 boolean_t first
= B_TRUE
;
2576 uint32_t new_ifindex
;
2579 (void) printf("if_report: %d items\n",
2581 / sizeof (mib2_ipAddrEntry_t
));
2583 /* 'for' loop 2a: */
2584 for (ap
= (mib2_ipAddrEntry_t
*)item
->valp
;
2585 (char *)ap
< (char *)item
->valp
2588 (void) octetstr(&ap
->ipAdEntIfIndex
,
2590 sizeof (logintname
));
2591 (void) strcpy(ifname
, logintname
);
2592 (void) strtok(ifname
, ":");
2593 if (matchname
!= NULL
&&
2594 strcmp(matchname
, ifname
) != 0 &&
2595 strcmp(matchname
, logintname
) != 0)
2596 continue; /* 'for' loop 2a */
2598 if_nametoindex(logintname
);
2600 * First lookup the "link" kstats in
2601 * case the link is renamed. Then
2602 * fallback to the legacy kstats for
2603 * those non-GLDv3 links.
2605 if (new_ifindex
!= ifindex_v4
&&
2606 (((ksp
= kstat_lookup(kc
, "link", 0,
2607 ifname
)) != NULL
) ||
2608 ((ksp
= kstat_lookup(kc
, NULL
, -1,
2609 ifname
)) != NULL
))) {
2610 (void) safe_kstat_read(kc
, ksp
,
2613 kstat_named_value(ksp
,
2616 kstat_named_value(ksp
,
2619 kstat_named_value(ksp
,
2622 kstat_named_value(ksp
,
2625 kstat_named_value(ksp
,
2629 (void) putchar('\n');
2630 first_header
= B_FALSE
;
2632 "%-5.5s %-5.5s%-13.13s "
2633 "%-14.14s %-6.6s %-5.5s "
2634 "%-6.6s %-5.5s %-6.6s "
2636 "Name", "Mtu", "Net/Dest",
2638 "Ierrs", "Opkts", "Oerrs",
2643 if_report_ip4(ap
, ifname
,
2644 logintname
, &stat
, B_TRUE
);
2645 ifindex_v4
= new_ifindex
;
2647 if_report_ip4(ap
, ifname
,
2648 logintname
, &stat
, B_FALSE
);
2650 } /* 'for' loop 2a ends */
2651 } else if (!alreadydone
) {
2652 char ifname
[LIFNAMSIZ
+ 1];
2653 char buf
[LIFNAMSIZ
+ 1];
2654 mib2_ipAddrEntry_t
*ap
;
2656 struct iflist
*tlp
= NULL
;
2657 struct iflist
**nextnew
= &newlist
;
2658 struct iflist
*walkold
;
2659 struct iflist
*cleanlist
;
2660 boolean_t found_if
= B_FALSE
;
2662 alreadydone
= B_TRUE
; /* ignore other case */
2665 * Check if there is anything to do.
2668 sizeof (mib2_ipAddrEntry_t
)) {
2669 fail(0, "No compatible interfaces");
2673 * 'for' loop 2b: find the "right" entry:
2674 * If an interface name to match has been
2675 * supplied then try and find it, otherwise
2676 * match the first non-loopback interface found.
2677 * Use lo0 if all else fails.
2679 for (ap
= (mib2_ipAddrEntry_t
*)item
->valp
;
2680 (char *)ap
< (char *)item
->valp
2683 (void) octetstr(&ap
->ipAdEntIfIndex
,
2684 'a', ifname
, sizeof (ifname
));
2685 (void) strtok(ifname
, ":");
2688 if (strcmp(matchname
,
2694 } else if (strcmp(ifname
, "lo0") != 0)
2695 break; /* 'for' loop 2b */
2696 } /* 'for' loop 2b ends */
2698 if (matchname
== NULL
) {
2702 fail(0, "-I: %s no such "
2703 "interface.", matchname
);
2706 if (Iflag_only
== 0 || !reentry
) {
2707 (void) printf(" input %-6.6s "
2710 (void) printf(" input (Total) "
2712 (void) printf("%-7.7s %-5.5s %-7.7s "
2714 "packets", "errs", "packets",
2716 (void) printf("%-7.7s %-5.5s %-7.7s "
2718 "packets", "errs", "packets",
2724 /* 'for' loop 2c: */
2725 for (ap
= (mib2_ipAddrEntry_t
*)item
->valp
;
2726 (char *)ap
< (char *)item
->valp
2729 (void) octetstr(&ap
->ipAdEntIfIndex
,
2730 'a', buf
, sizeof (buf
));
2731 (void) strtok(buf
, ":");
2734 * We have reduced the IP interface
2735 * name, which could have been a
2736 * logical, down to a name suitable
2737 * for use with kstats.
2738 * We treat this name as unique and
2739 * only collate statistics for it once
2740 * per pass. This is to avoid falsely
2741 * amplifying these statistics by the
2742 * the number of logical instances.
2744 if ((tlp
!= NULL
) &&
2745 ((strcmp(buf
, tlp
->ifname
) == 0))) {
2750 * First lookup the "link" kstats in
2751 * case the link is renamed. Then
2752 * fallback to the legacy kstats for
2753 * those non-GLDv3 links.
2755 if (((ksp
= kstat_lookup(kc
, "link",
2757 (ksp
= kstat_lookup(kc
, NULL
, -1,
2758 buf
)) != NULL
) && (ksp
->ks_type
==
2759 KSTAT_TYPE_NAMED
)) {
2760 (void) safe_kstat_read(kc
, ksp
,
2764 t
.ipackets
= kstat_named_value(ksp
,
2766 t
.ierrors
= kstat_named_value(ksp
,
2768 t
.opackets
= kstat_named_value(ksp
,
2770 t
.oerrors
= kstat_named_value(ksp
,
2772 t
.collisions
= kstat_named_value(ksp
,
2775 if (strcmp(buf
, matchname
) == 0)
2778 /* Build the interface list */
2780 tlp
= malloc(sizeof (struct iflist
));
2781 (void) strlcpy(tlp
->ifname
, buf
,
2782 sizeof (tlp
->ifname
));
2785 nextnew
= &tlp
->next_if
;
2788 * First time through.
2789 * Just add up the interface stats.
2792 if (oldlist
== NULL
) {
2793 if_stat_total(&zerostat
,
2799 * Walk old list for the interface.
2801 * If found, add difference to total.
2803 * If not, an interface has been plumbed
2804 * up. In this case, we will simply
2805 * ignore the new interface until the
2806 * next interval; as there's no easy way
2807 * to acquire statistics between time
2808 * of the plumb and the next interval
2809 * boundary. This results in inaccurate
2810 * total values for current interval.
2812 * Note the case when an interface is
2813 * unplumbed; as similar problems exist.
2814 * The unplumbed interface is not in the
2815 * current list, and there's no easy way
2816 * to account for the statistics between
2817 * the previous interval and time of the
2818 * unplumb. Therefore, we (in a sense)
2819 * ignore the removed interface by only
2820 * involving "current" interfaces when
2821 * computing the total statistics.
2822 * Unfortunately, this also results in
2823 * inaccurate values for interval total.
2826 for (walkold
= oldlist
;
2828 walkold
= walkold
->next_if
) {
2829 if (strcmp(walkold
->ifname
,
2838 } /* 'for' loop 2c ends */
2842 (void) printf("%-7llu %-5llu %-7llu "
2844 new.ipackets
- old
.ipackets
,
2845 new.ierrors
- old
.ierrors
,
2846 new.opackets
- old
.opackets
,
2847 new.oerrors
- old
.oerrors
,
2848 new.collisions
- old
.collisions
);
2850 (void) printf("%-7llu %-5llu %-7llu "
2851 "%-5llu %-6llu\n", sum
.ipackets
,
2852 sum
.ierrors
, sum
.opackets
,
2853 sum
.oerrors
, sum
.collisions
);
2856 * Tidy things up once finished.
2860 cleanlist
= oldlist
;
2862 while (cleanlist
!= NULL
) {
2863 tlp
= cleanlist
->next_if
;
2871 if (item
->mib_id
!= MIB2_IP6_ADDR
||
2872 !family_selected(AF_INET6
))
2873 continue; /* 'for' loop 1 */
2875 static struct ifstat old6
= {0L, 0L, 0L, 0L, 0L};
2876 static struct ifstat new6
= {0L, 0L, 0L, 0L, 0L};
2878 struct iflist
*newlist6
= NULL
;
2879 static struct iflist
*oldlist6
= NULL
;
2883 char ifname
[LIFNAMSIZ
+ 1];
2884 char logintname
[LIFNAMSIZ
+ 1];
2885 mib2_ipv6AddrEntry_t
*ap6
;
2886 struct ifstat stat
= {0L, 0L, 0L, 0L, 0L};
2887 boolean_t first
= B_TRUE
;
2888 uint32_t new_ifindex
;
2891 (void) printf("if_report: %d items\n",
2893 / sizeof (mib2_ipv6AddrEntry_t
));
2894 /* 'for' loop 2d: */
2895 for (ap6
= (mib2_ipv6AddrEntry_t
*)item
->valp
;
2896 (char *)ap6
< (char *)item
->valp
2899 (void) octetstr(&ap6
->ipv6AddrIfIndex
,
2901 sizeof (logintname
));
2902 (void) strcpy(ifname
, logintname
);
2903 (void) strtok(ifname
, ":");
2904 if (matchname
!= NULL
&&
2905 strcmp(matchname
, ifname
) != 0 &&
2906 strcmp(matchname
, logintname
) != 0)
2907 continue; /* 'for' loop 2d */
2909 if_nametoindex(logintname
);
2912 * First lookup the "link" kstats in
2913 * case the link is renamed. Then
2914 * fallback to the legacy kstats for
2915 * those non-GLDv3 links.
2917 if (new_ifindex
!= ifindex_v6
&&
2918 ((ksp
= kstat_lookup(kc
, "link", 0,
2920 (ksp
= kstat_lookup(kc
, NULL
, -1,
2921 ifname
)) != NULL
)) {
2922 (void) safe_kstat_read(kc
, ksp
,
2925 kstat_named_value(ksp
,
2928 kstat_named_value(ksp
,
2931 kstat_named_value(ksp
,
2934 kstat_named_value(ksp
,
2937 kstat_named_value(ksp
,
2941 (void) putchar('\n');
2942 first_header
= B_FALSE
;
2956 if_report_ip6(ap6
, ifname
,
2957 logintname
, &stat
, B_TRUE
);
2958 ifindex_v6
= new_ifindex
;
2960 if_report_ip6(ap6
, ifname
,
2961 logintname
, &stat
, B_FALSE
);
2963 } /* 'for' loop 2d ends */
2964 } else if (!alreadydone
) {
2965 char ifname
[LIFNAMSIZ
+ 1];
2966 char buf
[IFNAMSIZ
+ 1];
2967 mib2_ipv6AddrEntry_t
*ap6
;
2969 struct iflist
*tlp
= NULL
;
2970 struct iflist
**nextnew
= &newlist6
;
2971 struct iflist
*walkold
;
2972 struct iflist
*cleanlist
;
2973 boolean_t found_if
= B_FALSE
;
2975 alreadydone
= B_TRUE
; /* ignore other case */
2978 * Check if there is anything to do.
2981 sizeof (mib2_ipv6AddrEntry_t
)) {
2982 fail(0, "No compatible interfaces");
2986 * 'for' loop 2e: find the "right" entry:
2987 * If an interface name to match has been
2988 * supplied then try and find it, otherwise
2989 * match the first non-loopback interface found.
2990 * Use lo0 if all else fails.
2992 for (ap6
= (mib2_ipv6AddrEntry_t
*)item
->valp
;
2993 (char *)ap6
< (char *)item
->valp
2996 (void) octetstr(&ap6
->ipv6AddrIfIndex
,
2997 'a', ifname
, sizeof (ifname
));
2998 (void) strtok(ifname
, ":");
3001 if (strcmp(matchname
,
3007 } else if (strcmp(ifname
, "lo0") != 0)
3008 break; /* 'for' loop 2e */
3009 } /* 'for' loop 2e ends */
3011 if (matchname
== NULL
) {
3015 fail(0, "-I: %s no such "
3016 "interface.", matchname
);
3019 if (Iflag_only
== 0 || !reentry
) {
3024 (void) printf(" input (Total)"
3026 (void) printf("%-7.7s %-5.5s %-7.7s "
3028 "packets", "errs", "packets",
3030 (void) printf("%-7.7s %-5.5s %-7.7s "
3032 "packets", "errs", "packets",
3038 /* 'for' loop 2f: */
3039 for (ap6
= (mib2_ipv6AddrEntry_t
*)item
->valp
;
3040 (char *)ap6
< (char *)item
->valp
3043 (void) octetstr(&ap6
->ipv6AddrIfIndex
,
3044 'a', buf
, sizeof (buf
));
3045 (void) strtok(buf
, ":");
3048 * We have reduced the IP interface
3049 * name, which could have been a
3050 * logical, down to a name suitable
3051 * for use with kstats.
3052 * We treat this name as unique and
3053 * only collate statistics for it once
3054 * per pass. This is to avoid falsely
3055 * amplifying these statistics by the
3056 * the number of logical instances.
3059 if ((tlp
!= NULL
) &&
3060 ((strcmp(buf
, tlp
->ifname
) == 0))) {
3065 * First lookup the "link" kstats in
3066 * case the link is renamed. Then
3067 * fallback to the legacy kstats for
3068 * those non-GLDv3 links.
3070 if (((ksp
= kstat_lookup(kc
, "link",
3072 (ksp
= kstat_lookup(kc
, NULL
, -1,
3073 buf
)) != NULL
) && (ksp
->ks_type
==
3074 KSTAT_TYPE_NAMED
)) {
3075 (void) safe_kstat_read(kc
,
3079 t
.ipackets
= kstat_named_value(ksp
,
3081 t
.ierrors
= kstat_named_value(ksp
,
3083 t
.opackets
= kstat_named_value(ksp
,
3085 t
.oerrors
= kstat_named_value(ksp
,
3087 t
.collisions
= kstat_named_value(ksp
,
3090 if (strcmp(buf
, matchname
) == 0)
3093 /* Build the interface list */
3095 tlp
= malloc(sizeof (struct iflist
));
3096 (void) strlcpy(tlp
->ifname
, buf
,
3097 sizeof (tlp
->ifname
));
3100 nextnew
= &tlp
->next_if
;
3103 * First time through.
3104 * Just add up the interface stats.
3107 if (oldlist6
== NULL
) {
3108 if_stat_total(&zerostat
,
3114 * Walk old list for the interface.
3116 * If found, add difference to total.
3118 * If not, an interface has been plumbed
3119 * up. In this case, we will simply
3120 * ignore the new interface until the
3121 * next interval; as there's no easy way
3122 * to acquire statistics between time
3123 * of the plumb and the next interval
3124 * boundary. This results in inaccurate
3125 * total values for current interval.
3127 * Note the case when an interface is
3128 * unplumbed; as similar problems exist.
3129 * The unplumbed interface is not in the
3130 * current list, and there's no easy way
3131 * to account for the statistics between
3132 * the previous interval and time of the
3133 * unplumb. Therefore, we (in a sense)
3134 * ignore the removed interface by only
3135 * involving "current" interfaces when
3136 * computing the total statistics.
3137 * Unfortunately, this also results in
3138 * inaccurate values for interval total.
3141 for (walkold
= oldlist6
;
3143 walkold
= walkold
->next_if
) {
3144 if (strcmp(walkold
->ifname
,
3153 } /* 'for' loop 2f ends */
3157 (void) printf("%-7llu %-5llu %-7llu "
3159 new6
.ipackets
- old6
.ipackets
,
3160 new6
.ierrors
- old6
.ierrors
,
3161 new6
.opackets
- old6
.opackets
,
3162 new6
.oerrors
- old6
.oerrors
,
3163 new6
.collisions
- old6
.collisions
);
3165 (void) printf("%-7llu %-5llu %-7llu "
3166 "%-5llu %-6llu\n", sum6
.ipackets
,
3167 sum6
.ierrors
, sum6
.opackets
,
3168 sum6
.oerrors
, sum6
.collisions
);
3171 * Tidy things up once finished.
3175 cleanlist
= oldlist6
;
3176 oldlist6
= newlist6
;
3177 while (cleanlist
!= NULL
) {
3178 tlp
= cleanlist
->next_if
;
3186 (void) fflush(stdout
);
3187 } /* 'for' loop 1 ends */
3188 if ((Iflag_only
== 0) && (!once_only
))
3189 (void) putchar('\n');
3194 if_report_ip4(mib2_ipAddrEntry_t
*ap
,
3195 char ifname
[], char logintname
[], struct ifstat
*statptr
,
3196 boolean_t ksp_not_null
) {
3198 char abuf
[MAXHOSTNAMELEN
+ 1];
3199 char dstbuf
[MAXHOSTNAMELEN
+ 1];
3202 (void) printf("%-5s %-4u ",
3203 ifname
, ap
->ipAdEntInfo
.ae_mtu
);
3204 if (ap
->ipAdEntInfo
.ae_flags
& IFF_POINTOPOINT
)
3205 (void) pr_addr(ap
->ipAdEntInfo
.ae_pp_dst_addr
,
3206 abuf
, sizeof (abuf
));
3208 (void) pr_netaddr(ap
->ipAdEntAddr
,
3209 ap
->ipAdEntNetMask
, abuf
, sizeof (abuf
));
3210 (void) printf("%-13s %-14s %-6llu %-5llu %-6llu %-5llu "
3212 abuf
, pr_addr(ap
->ipAdEntAddr
, dstbuf
, sizeof (dstbuf
)),
3213 statptr
->ipackets
, statptr
->ierrors
,
3214 statptr
->opackets
, statptr
->oerrors
,
3215 statptr
->collisions
, 0LL);
3218 * Print logical interface info if Aflag set (including logical unit 0)
3221 *statptr
= zerostat
;
3222 statptr
->ipackets
= ap
->ipAdEntInfo
.ae_ibcnt
;
3223 statptr
->opackets
= ap
->ipAdEntInfo
.ae_obcnt
;
3225 (void) printf("%-5s %-4u ", logintname
, ap
->ipAdEntInfo
.ae_mtu
);
3226 if (ap
->ipAdEntInfo
.ae_flags
& IFF_POINTOPOINT
)
3227 (void) pr_addr(ap
->ipAdEntInfo
.ae_pp_dst_addr
, abuf
,
3230 (void) pr_netaddr(ap
->ipAdEntAddr
, ap
->ipAdEntNetMask
,
3231 abuf
, sizeof (abuf
));
3233 (void) printf("%-13s %-14s %-6llu %-5s %-6s "
3234 "%-5s %-6s %-6llu\n", abuf
,
3235 pr_addr(ap
->ipAdEntAddr
, dstbuf
, sizeof (dstbuf
)),
3236 statptr
->ipackets
, "N/A", "N/A", "N/A", "N/A",
3242 if_report_ip6(mib2_ipv6AddrEntry_t
*ap6
,
3243 char ifname
[], char logintname
[], struct ifstat
*statptr
,
3244 boolean_t ksp_not_null
) {
3246 char abuf
[MAXHOSTNAMELEN
+ 1];
3247 char dstbuf
[MAXHOSTNAMELEN
+ 1];
3250 (void) printf("%-5s %-4u ", ifname
, ap6
->ipv6AddrInfo
.ae_mtu
);
3251 if (ap6
->ipv6AddrInfo
.ae_flags
&
3253 (void) pr_addr6(&ap6
->ipv6AddrInfo
.ae_pp_dst_addr
,
3254 abuf
, sizeof (abuf
));
3256 (void) pr_prefix6(&ap6
->ipv6AddrAddress
,
3257 ap6
->ipv6AddrPfxLength
, abuf
,
3260 (void) printf("%-27s %-27s %-6llu %-5llu "
3261 "%-6llu %-5llu %-6llu\n",
3262 abuf
, pr_addr6(&ap6
->ipv6AddrAddress
, dstbuf
,
3264 statptr
->ipackets
, statptr
->ierrors
, statptr
->opackets
,
3265 statptr
->oerrors
, statptr
->collisions
);
3268 * Print logical interface info if Aflag set (including logical unit 0)
3271 *statptr
= zerostat
;
3272 statptr
->ipackets
= ap6
->ipv6AddrInfo
.ae_ibcnt
;
3273 statptr
->opackets
= ap6
->ipv6AddrInfo
.ae_obcnt
;
3275 (void) printf("%-5s %-4u ", logintname
,
3276 ap6
->ipv6AddrInfo
.ae_mtu
);
3277 if (ap6
->ipv6AddrInfo
.ae_flags
& IFF_POINTOPOINT
)
3278 (void) pr_addr6(&ap6
->ipv6AddrInfo
.ae_pp_dst_addr
,
3279 abuf
, sizeof (abuf
));
3281 (void) pr_prefix6(&ap6
->ipv6AddrAddress
,
3282 ap6
->ipv6AddrPfxLength
, abuf
, sizeof (abuf
));
3283 (void) printf("%-27s %-27s %-6llu %-5s %-6s %-5s %-6s\n",
3284 abuf
, pr_addr6(&ap6
->ipv6AddrAddress
, dstbuf
,
3286 statptr
->ipackets
, "N/A", "N/A", "N/A", "N/A");
3290 /* --------------------- DHCP_REPORT (netstat -D) ------------------------- */
3293 dhcp_do_ipc(dhcp_ipc_type_t type
, const char *ifname
, boolean_t printed_one
)
3295 dhcp_ipc_request_t
*request
;
3296 dhcp_ipc_reply_t
*reply
;
3299 request
= dhcp_ipc_alloc_request(type
, ifname
, NULL
, 0, DHCP_TYPE_NONE
);
3300 if (request
== NULL
)
3301 fail(0, "dhcp_do_ipc: out of memory");
3303 error
= dhcp_ipc_make_request(request
, &reply
, DHCP_IPC_WAIT_DEFAULT
);
3306 fail(0, "dhcp_do_ipc: %s", dhcp_ipc_strerror(error
));
3310 error
= reply
->return_code
;
3311 if (error
== DHCP_IPC_E_UNKIF
) {
3313 return (printed_one
);
3317 fail(0, "dhcp_do_ipc: %s", dhcp_ipc_strerror(error
));
3320 if (timestamp_fmt
!= NODATE
)
3321 print_timestamp(timestamp_fmt
);
3324 (void) printf("%s", dhcp_status_hdr_string());
3326 (void) printf("%s", dhcp_status_reply_to_string(reply
));
3332 * dhcp_walk_interfaces: walk the list of interfaces for a given address
3333 * family (af). For each, print out the DHCP status using dhcp_do_ipc.
3336 dhcp_walk_interfaces(int af
, boolean_t printed_one
)
3339 struct lifconf lifc
;
3340 int n_ifs
, i
, sock_fd
;
3342 sock_fd
= socket(af
, SOCK_DGRAM
, 0);
3344 return (printed_one
);
3347 * SIOCGLIFNUM is just an estimate. If the ioctl fails, we don't care;
3348 * just drive on and use SIOCGLIFCONF with increasing buffer sizes, as
3351 (void) memset(&lifn
, 0, sizeof (lifn
));
3352 lifn
.lifn_family
= af
;
3353 lifn
.lifn_flags
= LIFC_ALLZONES
| LIFC_NOXMIT
| LIFC_UNDER_IPMP
;
3354 if (ioctl(sock_fd
, SIOCGLIFNUM
, &lifn
) == -1)
3355 n_ifs
= LIFN_GUARD_VALUE
;
3357 n_ifs
= lifn
.lifn_count
+ LIFN_GUARD_VALUE
;
3359 (void) memset(&lifc
, 0, sizeof (lifc
));
3360 lifc
.lifc_family
= af
;
3361 lifc
.lifc_flags
= lifn
.lifn_flags
;
3362 lifc
.lifc_len
= n_ifs
* sizeof (struct lifreq
);
3363 lifc
.lifc_buf
= malloc(lifc
.lifc_len
);
3364 if (lifc
.lifc_buf
!= NULL
) {
3366 if (ioctl(sock_fd
, SIOCGLIFCONF
, &lifc
) == -1) {
3367 (void) close(sock_fd
);
3368 free(lifc
.lifc_buf
);
3372 n_ifs
= lifc
.lifc_len
/ sizeof (struct lifreq
);
3374 for (i
= 0; i
< n_ifs
; i
++) {
3375 printed_one
= dhcp_do_ipc(DHCP_STATUS
|
3376 (af
== AF_INET6
? DHCP_V6
: 0),
3377 lifc
.lifc_req
[i
].lifr_name
, printed_one
);
3380 (void) close(sock_fd
);
3381 free(lifc
.lifc_buf
);
3382 return (printed_one
);
3386 dhcp_report(char *ifname
)
3388 boolean_t printed_one
;
3390 if (!family_selected(AF_INET
) && !family_selected(AF_INET6
))
3393 printed_one
= B_FALSE
;
3394 if (ifname
!= NULL
) {
3395 if (family_selected(AF_INET
)) {
3396 printed_one
= dhcp_do_ipc(DHCP_STATUS
, ifname
,
3399 if (family_selected(AF_INET6
)) {
3400 printed_one
= dhcp_do_ipc(DHCP_STATUS
| DHCP_V6
,
3401 ifname
, printed_one
);
3404 fail(0, "%s: %s", ifname
,
3405 dhcp_ipc_strerror(DHCP_IPC_E_UNKIF
));
3408 if (family_selected(AF_INET
)) {
3409 printed_one
= dhcp_walk_interfaces(AF_INET
,
3412 if (family_selected(AF_INET6
))
3413 (void) dhcp_walk_interfaces(AF_INET6
, printed_one
);
3417 /* --------------------- GROUP_REPORT (netstat -g) ------------------------- */
3420 group_report(mib_item_t
*item
)
3422 mib_item_t
*v4grp
= NULL
, *v4src
= NULL
;
3423 mib_item_t
*v6grp
= NULL
, *v6src
= NULL
;
3425 char ifname
[LIFNAMSIZ
+ 1];
3426 char abuf
[MAXHOSTNAMELEN
+ 1];
3429 ipv6_member_t
*ipmp6
;
3430 ipv6_grpsrc_t
*ips6
;
3431 boolean_t first
, first_src
;
3434 for (; item
; item
= item
->next_item
) {
3436 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
3437 (void) printf("Group = %d, mib_id = %d, "
3438 "length = %d, valp = 0x%p\n",
3439 item
->group
, item
->mib_id
, item
->length
,
3442 if (item
->group
== MIB2_IP
&& family_selected(AF_INET
)) {
3443 switch (item
->mib_id
) {
3444 case EXPER_IP_GROUP_MEMBERSHIP
:
3447 (void) printf("item is v4grp info\n");
3449 case EXPER_IP_GROUP_SOURCES
:
3452 (void) printf("item is v4src info\n");
3459 if (item
->group
== MIB2_IP6
&& family_selected(AF_INET6
)) {
3460 switch (item
->mib_id
) {
3461 case EXPER_IP6_GROUP_MEMBERSHIP
:
3464 (void) printf("item is v6grp info\n");
3466 case EXPER_IP6_GROUP_SOURCES
:
3469 (void) printf("item is v6src info\n");
3477 if (family_selected(AF_INET
) && v4grp
!= NULL
) {
3479 (void) printf("%u records for ipGroupMember:\n",
3480 v4grp
->length
/ sizeof (ip_member_t
));
3483 for (ipmp
= (ip_member_t
*)v4grp
->valp
;
3484 (char *)ipmp
< (char *)v4grp
->valp
+ v4grp
->length
;
3485 /* LINTED: (note 1) */
3486 ipmp
= (ip_member_t
*)((char *)ipmp
+ ipMemberEntrySize
)) {
3488 (void) puts(v4compat
?
3489 "Group Memberships" :
3490 "Group Memberships: IPv4");
3491 (void) puts("Interface "
3493 (void) puts("--------- "
3494 "-------------------- ------");
3498 (void) printf("%-9s %-20s %6u\n",
3499 octetstr(&ipmp
->ipGroupMemberIfIndex
, 'a',
3500 ifname
, sizeof (ifname
)),
3501 pr_addr(ipmp
->ipGroupMemberAddress
,
3502 abuf
, sizeof (abuf
)),
3503 ipmp
->ipGroupMemberRefCnt
);
3506 if (!Vflag
|| v4src
== NULL
)
3510 (void) printf("scanning %u ipGroupSource "
3512 v4src
->length
/sizeof (ip_grpsrc_t
));
3515 for (ips
= (ip_grpsrc_t
*)v4src
->valp
;
3516 (char *)ips
< (char *)v4src
->valp
+ v4src
->length
;
3517 /* LINTED: (note 1) */
3518 ips
= (ip_grpsrc_t
*)((char *)ips
+
3519 ipGroupSourceEntrySize
)) {
3521 * We assume that all source addrs for a given
3522 * interface/group pair are contiguous, so on
3523 * the first non-match after we've found at
3524 * least one, we bail.
3526 if ((ipmp
->ipGroupMemberAddress
!=
3527 ips
->ipGroupSourceGroup
) ||
3528 (!octetstrmatch(&ipmp
->ipGroupMemberIfIndex
,
3529 &ips
->ipGroupSourceIfIndex
))) {
3536 (void) printf("\t%s: %s\n",
3538 ipmp
->ipGroupMemberFilterMode
),
3539 pr_addr(ips
->ipGroupSourceAddress
,
3540 abuf
, sizeof (abuf
)));
3541 first_src
= B_FALSE
;
3545 (void) printf("\t %s\n",
3546 pr_addr(ips
->ipGroupSourceAddress
, abuf
,
3550 (void) putchar('\n');
3553 if (family_selected(AF_INET6
) && v6grp
!= NULL
) {
3555 (void) printf("%u records for ipv6GroupMember:\n",
3556 v6grp
->length
/ sizeof (ipv6_member_t
));
3559 for (ipmp6
= (ipv6_member_t
*)v6grp
->valp
;
3560 (char *)ipmp6
< (char *)v6grp
->valp
+ v6grp
->length
;
3561 /* LINTED: (note 1) */
3562 ipmp6
= (ipv6_member_t
*)((char *)ipmp6
+
3563 ipv6MemberEntrySize
)) {
3565 (void) puts("Group Memberships: "
3569 (void) puts("----- "
3570 "--------------------------- ------");
3574 (void) printf("%-5s %-27s %5u\n",
3575 ifindex2str(ipmp6
->ipv6GroupMemberIfIndex
, ifname
),
3576 pr_addr6(&ipmp6
->ipv6GroupMemberAddress
,
3577 abuf
, sizeof (abuf
)),
3578 ipmp6
->ipv6GroupMemberRefCnt
);
3580 if (!Vflag
|| v6src
== NULL
)
3584 (void) printf("scanning %u ipv6GroupSource "
3586 v6src
->length
/sizeof (ipv6_grpsrc_t
));
3589 for (ips6
= (ipv6_grpsrc_t
*)v6src
->valp
;
3590 (char *)ips6
< (char *)v6src
->valp
+ v6src
->length
;
3591 /* LINTED: (note 1) */
3592 ips6
= (ipv6_grpsrc_t
*)((char *)ips6
+
3593 ipv6GroupSourceEntrySize
)) {
3594 /* same assumption as in the v4 case above */
3595 if ((ipmp6
->ipv6GroupMemberIfIndex
!=
3596 ips6
->ipv6GroupSourceIfIndex
) ||
3597 (!IN6_ARE_ADDR_EQUAL(
3598 &ipmp6
->ipv6GroupMemberAddress
,
3599 &ips6
->ipv6GroupSourceGroup
))) {
3606 (void) printf("\t%s: %s\n",
3608 ipmp6
->ipv6GroupMemberFilterMode
),
3610 &ips6
->ipv6GroupSourceAddress
,
3611 abuf
, sizeof (abuf
)));
3612 first_src
= B_FALSE
;
3616 (void) printf("\t %s\n",
3617 pr_addr6(&ips6
->ipv6GroupSourceAddress
,
3618 abuf
, sizeof (abuf
)));
3621 (void) putchar('\n');
3624 (void) putchar('\n');
3625 (void) fflush(stdout
);
3628 /* --------------------- DCE_REPORT (netstat -d) ------------------------- */
3632 /* Assumes flbuf is at least 5 characters; callers use FLBUFSIZE */
3634 dceflags2str(uint32_t flags
, char *flbuf
)
3638 if (flags
& DCEF_DEFAULT
)
3640 if (flags
& DCEF_PMTU
)
3642 if (flags
& DCEF_UINFO
)
3644 if (flags
& DCEF_TOO_SMALL_PMTU
)
3651 dce_report(mib_item_t
*item
)
3653 mib_item_t
*v4dce
= NULL
;
3654 mib_item_t
*v6dce
= NULL
;
3656 char ifname
[LIFNAMSIZ
+ 1];
3657 char abuf
[MAXHOSTNAMELEN
+ 1];
3658 char flbuf
[FLBUFSIZE
];
3660 dest_cache_entry_t
*dce
;
3663 for (; item
; item
= item
->next_item
) {
3665 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
3666 (void) printf("Group = %d, mib_id = %d, "
3667 "length = %d, valp = 0x%p\n",
3668 item
->group
, item
->mib_id
, item
->length
,
3671 if (item
->group
== MIB2_IP
&& family_selected(AF_INET
) &&
3672 item
->mib_id
== EXPER_IP_DCE
) {
3675 (void) printf("item is v4dce info\n");
3677 if (item
->group
== MIB2_IP6
&& family_selected(AF_INET6
) &&
3678 item
->mib_id
== EXPER_IP_DCE
) {
3681 (void) printf("item is v6dce info\n");
3685 if (family_selected(AF_INET
) && v4dce
!= NULL
) {
3687 (void) printf("%u records for DestCacheEntry:\n",
3688 v4dce
->length
/ ipDestEntrySize
);
3691 for (dce
= (dest_cache_entry_t
*)v4dce
->valp
;
3692 (char *)dce
< (char *)v4dce
->valp
+ v4dce
->length
;
3693 /* LINTED: (note 1) */
3694 dce
= (dest_cache_entry_t
*)((char *)dce
+
3697 (void) putchar('\n');
3698 (void) puts("Destination Cache Entries: IPv4");
3700 "Address PMTU Age Flags");
3702 "-------------------- ------ ----- -----");
3706 (void) printf("%-20s %6u %5u %-5s\n",
3707 pr_addr(dce
->DestIpv4Address
, abuf
, sizeof (abuf
)),
3708 dce
->DestPmtu
, dce
->DestAge
,
3709 dceflags2str(dce
->DestFlags
, flbuf
));
3713 if (family_selected(AF_INET6
) && v6dce
!= NULL
) {
3715 (void) printf("%u records for DestCacheEntry:\n",
3716 v6dce
->length
/ ipDestEntrySize
);
3719 for (dce
= (dest_cache_entry_t
*)v6dce
->valp
;
3720 (char *)dce
< (char *)v6dce
->valp
+ v6dce
->length
;
3721 /* LINTED: (note 1) */
3722 dce
= (dest_cache_entry_t
*)((char *)dce
+
3725 (void) putchar('\n');
3726 (void) puts("Destination Cache Entries: IPv6");
3731 "--------------------------- ------ "
3736 (void) printf("%-27s %6u %5u %-5s %s\n",
3737 pr_addr6(&dce
->DestIpv6Address
, abuf
,
3739 dce
->DestPmtu
, dce
->DestAge
,
3740 dceflags2str(dce
->DestFlags
, flbuf
),
3741 dce
->DestIfindex
== 0 ? "" :
3742 ifindex2str(dce
->DestIfindex
, ifname
));
3745 (void) fflush(stdout
);
3748 /* --------------------- ARP_REPORT (netstat -p) -------------------------- */
3751 arp_report(mib_item_t
*item
)
3754 char ifname
[LIFNAMSIZ
+ 1];
3755 char abuf
[MAXHOSTNAMELEN
+ 1];
3756 char maskbuf
[STR_EXPAND
* OCTET_LENGTH
+ 1];
3757 char flbuf
[32]; /* ACE_F_ flags */
3758 char xbuf
[STR_EXPAND
* OCTET_LENGTH
+ 1];
3759 mib2_ipNetToMediaEntry_t
*np
;
3763 if (!(family_selected(AF_INET
)))
3767 for (; item
; item
= item
->next_item
) {
3769 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
3770 (void) printf("Group = %d, mib_id = %d, "
3771 "length = %d, valp = 0x%p\n",
3772 item
->group
, item
->mib_id
, item
->length
,
3775 if (!(item
->group
== MIB2_IP
&& item
->mib_id
== MIB2_IP_MEDIA
))
3776 continue; /* 'for' loop 1 */
3779 (void) printf("%u records for "
3780 "ipNetToMediaEntryTable:\n",
3781 item
->length
/sizeof (mib2_ipNetToMediaEntry_t
));
3785 for (np
= (mib2_ipNetToMediaEntry_t
*)item
->valp
;
3786 (char *)np
< (char *)item
->valp
+ item
->length
;
3787 /* LINTED: (note 1) */
3788 np
= (mib2_ipNetToMediaEntry_t
*)((char *)np
+
3789 ipNetToMediaEntrySize
)) {
3791 (void) puts(v4compat
?
3792 "Net to Media Table" :
3793 "Net to Media Table: IPv4");
3794 (void) puts("Device "
3797 (void) puts("------ "
3798 "-------------------- --------------- "
3799 "-------- ---------------");
3804 flags
= np
->ipNetToMediaInfo
.ntm_flags
;
3806 * Note that not all flags are possible at the same
3807 * time. Patterns: SPLAy DUo
3809 if (flags
& ACE_F_PERMANENT
)
3810 (void) strcat(flbuf
, "S");
3811 if (flags
& ACE_F_PUBLISH
)
3812 (void) strcat(flbuf
, "P");
3813 if (flags
& ACE_F_DYING
)
3814 (void) strcat(flbuf
, "D");
3815 if (!(flags
& ACE_F_RESOLVED
))
3816 (void) strcat(flbuf
, "U");
3817 if (flags
& ACE_F_MAPPING
)
3818 (void) strcat(flbuf
, "M");
3819 if (flags
& ACE_F_MYADDR
)
3820 (void) strcat(flbuf
, "L");
3821 if (flags
& ACE_F_UNVERIFIED
)
3822 (void) strcat(flbuf
, "d");
3823 if (flags
& ACE_F_AUTHORITY
)
3824 (void) strcat(flbuf
, "A");
3825 if (flags
& ACE_F_OLD
)
3826 (void) strcat(flbuf
, "o");
3827 if (flags
& ACE_F_DELAYED
)
3828 (void) strcat(flbuf
, "y");
3829 (void) printf("%-6s %-20s %-15s %-8s %s\n",
3830 octetstr(&np
->ipNetToMediaIfIndex
, 'a',
3831 ifname
, sizeof (ifname
)),
3832 pr_addr(np
->ipNetToMediaNetAddress
,
3833 abuf
, sizeof (abuf
)),
3834 octetstr(&np
->ipNetToMediaInfo
.ntm_mask
, 'd',
3835 maskbuf
, sizeof (maskbuf
)),
3837 octetstr(&np
->ipNetToMediaPhysAddress
, 'h',
3838 xbuf
, sizeof (xbuf
)));
3839 } /* 'for' loop 2 ends */
3840 } /* 'for' loop 1 ends */
3841 (void) fflush(stdout
);
3844 /* --------------------- NDP_REPORT (netstat -p) -------------------------- */
3847 ndp_report(mib_item_t
*item
)
3850 char abuf
[MAXHOSTNAMELEN
+ 1];
3853 char xbuf
[STR_EXPAND
* OCTET_LENGTH
+ 1];
3854 mib2_ipv6NetToMediaEntry_t
*np6
;
3855 char ifname
[LIFNAMSIZ
+ 1];
3858 if (!(family_selected(AF_INET6
)))
3862 for (; item
; item
= item
->next_item
) {
3864 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
3865 (void) printf("Group = %d, mib_id = %d, "
3866 "length = %d, valp = 0x%p\n",
3867 item
->group
, item
->mib_id
, item
->length
,
3870 if (!(item
->group
== MIB2_IP6
&&
3871 item
->mib_id
== MIB2_IP6_MEDIA
))
3872 continue; /* 'for' loop 1 */
3876 for (np6
= (mib2_ipv6NetToMediaEntry_t
*)item
->valp
;
3877 (char *)np6
< (char *)item
->valp
+ item
->length
;
3878 /* LINTED: (note 1) */
3879 np6
= (mib2_ipv6NetToMediaEntry_t
*)((char *)np6
+
3880 ipv6NetToMediaEntrySize
)) {
3882 (void) puts("\nNet to Media Table: IPv6");
3883 (void) puts(" If Physical Address "
3884 " Type State Destination/Mask");
3885 (void) puts("----- ----------------- "
3886 "------- ------------ "
3887 "---------------------------");
3891 switch (np6
->ipv6NetToMediaState
) {
3893 state
= "INCOMPLETE";
3896 state
= "REACHABLE";
3907 case ND_UNREACHABLE
:
3908 state
= "UNREACHABLE";
3914 switch (np6
->ipv6NetToMediaType
) {
3928 (void) printf("%-5s %-17s %-7s %-12s %-27s\n",
3929 ifindex2str(np6
->ipv6NetToMediaIfIndex
, ifname
),
3930 octetstr(&np6
->ipv6NetToMediaPhysAddress
, 'h',
3931 xbuf
, sizeof (xbuf
)),
3934 pr_addr6(&np6
->ipv6NetToMediaNetAddress
,
3935 abuf
, sizeof (abuf
)));
3936 } /* 'for' loop 2 ends */
3937 } /* 'for' loop 1 ends */
3938 (void) putchar('\n');
3939 (void) fflush(stdout
);
3942 /* ------------------------- ire_report (netstat -r) ------------------------ */
3944 static boolean_t
ire_report_item_v4(const mib2_ipRouteEntry_t
*, boolean_t
);
3945 static boolean_t
ire_report_item_v6(const mib2_ipv6RouteEntry_t
*, boolean_t
);
3948 ire_report(const mib_item_t
*item
)
3951 boolean_t print_hdr_once_v4
= B_TRUE
;
3952 boolean_t print_hdr_once_v6
= B_TRUE
;
3953 mib2_ipRouteEntry_t
*rp
;
3954 mib2_ipv6RouteEntry_t
*rp6
;
3956 for (; item
!= NULL
; item
= item
->next_item
) {
3958 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
3959 (void) printf("Group = %d, mib_id = %d, "
3960 "length = %d, valp = 0x%p\n",
3961 item
->group
, item
->mib_id
,
3962 item
->length
, item
->valp
);
3964 if (!((item
->group
== MIB2_IP
&&
3965 item
->mib_id
== MIB2_IP_ROUTE
) ||
3966 (item
->group
== MIB2_IP6
&&
3967 item
->mib_id
== MIB2_IP6_ROUTE
)))
3968 continue; /* 'for' loop 1 */
3970 if (item
->group
== MIB2_IP
&& !family_selected(AF_INET
))
3971 continue; /* 'for' loop 1 */
3972 else if (item
->group
== MIB2_IP6
&& !family_selected(AF_INET6
))
3973 continue; /* 'for' loop 1 */
3976 if (item
->group
== MIB2_IP
) {
3977 (void) printf("%u records for "
3978 "ipRouteEntryTable:\n",
3979 item
->length
/sizeof (mib2_ipRouteEntry_t
));
3981 (void) printf("%u records for "
3982 "ipv6RouteEntryTable:\n",
3984 sizeof (mib2_ipv6RouteEntry_t
));
3988 if (item
->group
== MIB2_IP
) {
3989 for (rp
= (mib2_ipRouteEntry_t
*)item
->valp
;
3990 (char *)rp
< (char *)item
->valp
+ item
->length
;
3991 /* LINTED: (note 1) */
3992 rp
= (mib2_ipRouteEntry_t
*)((char *)rp
+
3993 ipRouteEntrySize
)) {
3994 print_hdr_once_v4
= ire_report_item_v4(rp
,
3998 for (rp6
= (mib2_ipv6RouteEntry_t
*)item
->valp
;
3999 (char *)rp6
< (char *)item
->valp
+ item
->length
;
4000 /* LINTED: (note 1) */
4001 rp6
= (mib2_ipv6RouteEntry_t
*)((char *)rp6
+
4002 ipv6RouteEntrySize
)) {
4003 print_hdr_once_v6
= ire_report_item_v6(rp6
,
4007 } /* 'for' loop 1 ends */
4008 (void) fflush(stdout
);
4012 * Match a user-supplied device name. We do this by string because
4013 * the MIB2 interface gives us interface name strings rather than
4014 * ifIndex numbers. The "none" rule matches only routes with no
4015 * interface. The "any" rule matches routes with any non-blank
4016 * interface. A base name ("hme0") matches all aliases as well
4020 dev_name_match(const DeviceName
*devnam
, const char *ifname
)
4025 return (devnam
->o_length
== 0); /* "none" */
4026 if (*ifname
== '\0')
4027 return (devnam
->o_length
!= 0); /* "any" */
4028 iflen
= strlen(ifname
);
4029 /* The check for ':' here supports interface aliases. */
4030 if (iflen
> devnam
->o_length
||
4031 (iflen
< devnam
->o_length
&& devnam
->o_bytes
[iflen
] != ':'))
4033 return (strncmp(ifname
, devnam
->o_bytes
, iflen
) == 0);
4037 * Match a user-supplied IP address list. The "any" rule matches any
4038 * non-zero address. The "none" rule matches only the zero address.
4039 * IPv6 addresses supplied by the user are ignored. If the user
4040 * supplies a subnet mask, then match routes that are at least that
4041 * specific (use the user's mask). If the user supplies only an
4042 * address, then select any routes that would match (use the route's
4046 v4_addr_match(IpAddress addr
, IpAddress mask
, const filter_t
*fp
)
4050 in_addr_t faddr
, fmask
;
4052 if (fp
->u
.a
.f_address
== NULL
) {
4053 if (IN6_IS_ADDR_UNSPECIFIED(&fp
->u
.a
.f_mask
))
4054 return (addr
!= INADDR_ANY
); /* "any" */
4056 return (addr
== INADDR_ANY
); /* "none" */
4058 if (!IN6_IS_V4MASK(fp
->u
.a
.f_mask
))
4060 IN6_V4MAPPED_TO_IPADDR(&fp
->u
.a
.f_mask
, fmask
);
4061 if (fmask
!= IP_HOST_MASK
) {
4066 for (app
= fp
->u
.a
.f_address
->h_addr_list
; (aptr
= *app
) != NULL
; app
++)
4067 /* LINTED: (note 1) */
4068 if (IN6_IS_ADDR_V4MAPPED((in6_addr_t
*)aptr
)) {
4069 /* LINTED: (note 1) */
4070 IN6_V4MAPPED_TO_IPADDR((in6_addr_t
*)aptr
, faddr
);
4071 if (((faddr
^ addr
) & mask
) == 0)
4078 * Run through the filter list for an IPv4 MIB2 route entry. If all
4079 * filters of a given type fail to match, then the route is filtered
4080 * out (not displayed). If no filter is given or at least one filter
4081 * of each type matches, then display the route.
4084 ire_filter_match_v4(const mib2_ipRouteEntry_t
*rp
, uint_t flag_b
)
4090 for (idx
= 0; idx
< NFILTERKEYS
; idx
++)
4091 if ((fp
= filters
[idx
]) != NULL
) {
4093 for (; fp
!= NULL
; fp
= fp
->f_next
) {
4096 if (fp
->u
.f_family
!= AF_INET
)
4097 continue; /* 'for' loop 2 */
4100 if (!dev_name_match(&rp
->ipRouteIfIndex
,
4102 continue; /* 'for' loop 2 */
4105 if (!v4_addr_match(rp
->ipRouteDest
,
4106 rp
->ipRouteMask
, fp
))
4107 continue; /* 'for' loop 2 */
4110 if ((flag_b
& fp
->u
.f
.f_flagset
) !=
4111 fp
->u
.f
.f_flagset
||
4112 (flag_b
& fp
->u
.f
.f_flagclear
))
4113 continue; /* 'for' loop 2 */
4117 } /* 'for' loop 2 ends */
4121 /* 'for' loop 1 ends */
4126 * Given an IPv4 MIB2 route entry, form the list of flags for the
4130 form_v4_route_flags(const mib2_ipRouteEntry_t
*rp
, char *flags
)
4135 (void) strcpy(flags
, "U");
4136 /* RTF_INDIRECT wins over RTF_GATEWAY - don't display both */
4137 if (rp
->ipRouteInfo
.re_flags
& RTF_INDIRECT
) {
4138 (void) strcat(flags
, "I");
4140 } else if (rp
->ipRouteInfo
.re_ire_type
& IRE_OFFLINK
) {
4141 (void) strcat(flags
, "G");
4144 /* IRE_IF_CLONE wins over RTF_HOST - don't display both */
4145 if (rp
->ipRouteInfo
.re_ire_type
& IRE_IF_CLONE
) {
4146 (void) strcat(flags
, "C");
4148 } else if (rp
->ipRouteMask
== IP_HOST_MASK
) {
4149 (void) strcat(flags
, "H");
4152 if (rp
->ipRouteInfo
.re_flags
& RTF_DYNAMIC
) {
4153 (void) strcat(flags
, "D");
4156 if (rp
->ipRouteInfo
.re_ire_type
== IRE_BROADCAST
) { /* Broadcast */
4157 (void) strcat(flags
, "b");
4160 if (rp
->ipRouteInfo
.re_ire_type
== IRE_LOCAL
) { /* Local */
4161 (void) strcat(flags
, "L");
4164 if (rp
->ipRouteInfo
.re_flags
& RTF_SETSRC
) {
4165 (void) strcat(flags
, "S"); /* Setsrc */
4168 if (rp
->ipRouteInfo
.re_flags
& RTF_REJECT
) {
4169 (void) strcat(flags
, "R");
4172 if (rp
->ipRouteInfo
.re_flags
& RTF_BLACKHOLE
) {
4173 (void) strcat(flags
, "B");
4176 if (rp
->ipRouteInfo
.re_flags
& RTF_ZONE
) {
4177 (void) strcat(flags
, "Z");
4183 static const char ire_hdr_v4
[] =
4184 "\n%s Table: IPv4\n";
4185 static const char ire_hdr_v4_compat
[] =
4187 static const char ire_hdr_v4_verbose
[] =
4188 " Destination Mask Gateway Device "
4189 " MTU Ref Flg Out In/Fwd\n"
4190 "-------------------- --------------- -------------------- ------ "
4191 "----- --- --- ----- ------\n";
4193 static const char ire_hdr_v4_normal
[] =
4194 " Destination Gateway Flags Ref Use Interface"
4195 "\n-------------------- -------------------- ----- ----- ---------- "
4199 ire_report_item_v4(const mib2_ipRouteEntry_t
*rp
, boolean_t first
)
4201 char dstbuf
[MAXHOSTNAMELEN
+ 1];
4202 char maskbuf
[MAXHOSTNAMELEN
+ 1];
4203 char gwbuf
[MAXHOSTNAMELEN
+ 1];
4204 char ifname
[LIFNAMSIZ
+ 1];
4205 char flags
[10]; /* RTF_ flags */
4208 if (!(Aflag
|| (rp
->ipRouteInfo
.re_ire_type
!= IRE_IF_CLONE
&&
4209 rp
->ipRouteInfo
.re_ire_type
!= IRE_BROADCAST
&&
4210 rp
->ipRouteInfo
.re_ire_type
!= IRE_MULTICAST
&&
4211 rp
->ipRouteInfo
.re_ire_type
!= IRE_NOROUTE
&&
4212 rp
->ipRouteInfo
.re_ire_type
!= IRE_LOCAL
))) {
4216 flag_b
= form_v4_route_flags(rp
, flags
);
4218 if (!ire_filter_match_v4(rp
, flag_b
))
4222 (void) printf(v4compat
? ire_hdr_v4_compat
: ire_hdr_v4
,
4223 Vflag
? "IRE" : "Routing");
4224 (void) printf(Vflag
? ire_hdr_v4_verbose
: ire_hdr_v4_normal
);
4228 if (flag_b
& FLF_H
) {
4229 (void) pr_addr(rp
->ipRouteDest
, dstbuf
, sizeof (dstbuf
));
4231 (void) pr_net(rp
->ipRouteDest
, rp
->ipRouteMask
,
4232 dstbuf
, sizeof (dstbuf
));
4235 (void) printf("%-20s %-15s %-20s %-6s %5u %3u "
4238 pr_mask(rp
->ipRouteMask
, maskbuf
, sizeof (maskbuf
)),
4239 pr_addrnz(rp
->ipRouteNextHop
, gwbuf
, sizeof (gwbuf
)),
4240 octetstr(&rp
->ipRouteIfIndex
, 'a', ifname
, sizeof (ifname
)),
4241 rp
->ipRouteInfo
.re_max_frag
,
4242 rp
->ipRouteInfo
.re_ref
,
4244 rp
->ipRouteInfo
.re_obpkt
,
4245 rp
->ipRouteInfo
.re_ibpkt
);
4247 (void) printf("%-20s %-20s %-5s %4u %10u %-9s\n",
4249 pr_addrnz(rp
->ipRouteNextHop
, gwbuf
, sizeof (gwbuf
)),
4251 rp
->ipRouteInfo
.re_ref
,
4252 rp
->ipRouteInfo
.re_obpkt
+ rp
->ipRouteInfo
.re_ibpkt
,
4253 octetstr(&rp
->ipRouteIfIndex
, 'a',
4254 ifname
, sizeof (ifname
)));
4260 * Match a user-supplied IP address list against an IPv6 route entry.
4261 * If the user specified "any," then any non-zero address matches. If
4262 * the user specified "none," then only the zero address matches. If
4263 * the user specified a subnet mask length, then use that in matching
4264 * routes (select routes that are at least as specific). If the user
4265 * specified only an address, then use the route's mask (select routes
4266 * that would match that address). IPv4 addresses are ignored.
4269 v6_addr_match(const Ip6Address
*addr
, int masklen
, const filter_t
*fp
)
4275 const uint8_t *aptr
;
4277 if (fp
->u
.a
.f_address
== NULL
) {
4278 if (IN6_IS_ADDR_UNSPECIFIED(&fp
->u
.a
.f_mask
)) /* any */
4279 return (!IN6_IS_ADDR_UNSPECIFIED(addr
));
4280 return (IN6_IS_ADDR_UNSPECIFIED(addr
)); /* "none" */
4283 /* 'for' loop 1a: */
4284 for (ucp
= fp
->u
.a
.f_mask
.s6_addr
;
4285 ucp
< fp
->u
.a
.f_mask
.s6_addr
+ sizeof (fp
->u
.a
.f_mask
.s6_addr
);
4289 fmasklen
+= 9 - ffs(*ucp
);
4290 break; /* 'for' loop 1a */
4293 } /* 'for' loop 1a ends */
4294 if (fmasklen
!= IPV6_ABITS
) {
4295 if (fmasklen
> masklen
)
4299 /* 'for' loop 1b: */
4300 for (app
= fp
->u
.a
.f_address
->h_addr_list
;
4301 (aptr
= (uint8_t *)*app
) != NULL
; app
++) {
4302 /* LINTED: (note 1) */
4303 if (IN6_IS_ADDR_V4MAPPED((in6_addr_t
*)aptr
))
4304 continue; /* 'for' loop 1b */
4305 ucp
= addr
->s6_addr
;
4306 for (i
= masklen
; i
>= 8; i
-= 8)
4307 if (*ucp
++ != *aptr
++)
4308 break; /* 'for' loop 1b */
4310 (i
< 8 && ((*ucp
^ *aptr
) & ~(0xff >> i
)) == 0))
4312 } /* 'for' loop 1b ends */
4317 * Run through the filter list for an IPv6 MIB2 IRE. For a given
4318 * type, if there's at least one filter and all filters of that type
4319 * fail to match, then the route doesn't match and isn't displayed.
4320 * If at least one matches, or none are specified, for each of the
4321 * types, then the route is selected and displayed.
4324 ire_filter_match_v6(const mib2_ipv6RouteEntry_t
*rp6
, uint_t flag_b
)
4330 for (idx
= 0; idx
< NFILTERKEYS
; idx
++)
4331 if ((fp
= filters
[idx
]) != NULL
) {
4333 for (; fp
!= NULL
; fp
= fp
->f_next
) {
4336 if (fp
->u
.f_family
!= AF_INET6
)
4341 if (!dev_name_match(&rp6
->
4342 ipv6RouteIfIndex
, fp
->u
.f_ifname
))
4347 if (!v6_addr_match(&rp6
->ipv6RouteDest
,
4348 rp6
->ipv6RoutePfxLength
, fp
))
4353 if ((flag_b
& fp
->u
.f
.f_flagset
) !=
4354 fp
->u
.f
.f_flagset
||
4355 (flag_b
& fp
->u
.f
.f_flagclear
))
4361 } /* 'for' loop 2 ends */
4365 /* 'for' loop 1 ends */
4370 * Given an IPv6 MIB2 route entry, form the list of flags for the
4374 form_v6_route_flags(const mib2_ipv6RouteEntry_t
*rp6
, char *flags
)
4379 (void) strcpy(flags
, "U");
4380 /* RTF_INDIRECT wins over RTF_GATEWAY - don't display both */
4381 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_INDIRECT
) {
4382 (void) strcat(flags
, "I");
4384 } else if (rp6
->ipv6RouteInfo
.re_ire_type
& IRE_OFFLINK
) {
4385 (void) strcat(flags
, "G");
4389 /* IRE_IF_CLONE wins over RTF_HOST - don't display both */
4390 if (rp6
->ipv6RouteInfo
.re_ire_type
& IRE_IF_CLONE
) {
4391 (void) strcat(flags
, "C");
4393 } else if (rp6
->ipv6RoutePfxLength
== IPV6_ABITS
) {
4394 (void) strcat(flags
, "H");
4398 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_DYNAMIC
) {
4399 (void) strcat(flags
, "D");
4402 if (rp6
->ipv6RouteInfo
.re_ire_type
== IRE_LOCAL
) { /* Local */
4403 (void) strcat(flags
, "L");
4406 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_SETSRC
) {
4407 (void) strcat(flags
, "S"); /* Setsrc */
4410 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_REJECT
) {
4411 (void) strcat(flags
, "R");
4414 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_BLACKHOLE
) {
4415 (void) strcat(flags
, "B");
4418 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_ZONE
) {
4419 (void) strcat(flags
, "Z");
4425 static const char ire_hdr_v6
[] =
4426 "\n%s Table: IPv6\n";
4427 static const char ire_hdr_v6_verbose
[] =
4428 " Destination/Mask Gateway If MTU "
4429 "Ref Flags Out In/Fwd\n"
4430 "--------------------------- --------------------------- ----- ----- "
4431 "--- ----- ------ ------\n";
4432 static const char ire_hdr_v6_normal
[] =
4433 " Destination/Mask Gateway Flags Ref Use "
4435 "--------------------------- --------------------------- ----- --- ------- "
4439 ire_report_item_v6(const mib2_ipv6RouteEntry_t
*rp6
, boolean_t first
)
4441 char dstbuf
[MAXHOSTNAMELEN
+ 1];
4442 char gwbuf
[MAXHOSTNAMELEN
+ 1];
4443 char ifname
[LIFNAMSIZ
+ 1];
4444 char flags
[10]; /* RTF_ flags */
4447 if (!(Aflag
|| (rp6
->ipv6RouteInfo
.re_ire_type
!= IRE_IF_CLONE
&&
4448 rp6
->ipv6RouteInfo
.re_ire_type
!= IRE_MULTICAST
&&
4449 rp6
->ipv6RouteInfo
.re_ire_type
!= IRE_NOROUTE
&&
4450 rp6
->ipv6RouteInfo
.re_ire_type
!= IRE_LOCAL
))) {
4454 flag_b
= form_v6_route_flags(rp6
, flags
);
4456 if (!ire_filter_match_v6(rp6
, flag_b
))
4460 (void) printf(ire_hdr_v6
, Vflag
? "IRE" : "Routing");
4461 (void) printf(Vflag
? ire_hdr_v6_verbose
: ire_hdr_v6_normal
);
4466 (void) printf("%-27s %-27s %-5s %5u %3u "
4468 pr_prefix6(&rp6
->ipv6RouteDest
,
4469 rp6
->ipv6RoutePfxLength
, dstbuf
, sizeof (dstbuf
)),
4470 IN6_IS_ADDR_UNSPECIFIED(&rp6
->ipv6RouteNextHop
) ?
4472 pr_addr6(&rp6
->ipv6RouteNextHop
, gwbuf
, sizeof (gwbuf
)),
4473 octetstr(&rp6
->ipv6RouteIfIndex
, 'a',
4474 ifname
, sizeof (ifname
)),
4475 rp6
->ipv6RouteInfo
.re_max_frag
,
4476 rp6
->ipv6RouteInfo
.re_ref
,
4478 rp6
->ipv6RouteInfo
.re_obpkt
,
4479 rp6
->ipv6RouteInfo
.re_ibpkt
);
4481 (void) printf("%-27s %-27s %-5s %3u %7u %-5s\n",
4482 pr_prefix6(&rp6
->ipv6RouteDest
,
4483 rp6
->ipv6RoutePfxLength
, dstbuf
, sizeof (dstbuf
)),
4484 IN6_IS_ADDR_UNSPECIFIED(&rp6
->ipv6RouteNextHop
) ?
4486 pr_addr6(&rp6
->ipv6RouteNextHop
, gwbuf
, sizeof (gwbuf
)),
4488 rp6
->ipv6RouteInfo
.re_ref
,
4489 rp6
->ipv6RouteInfo
.re_obpkt
+ rp6
->ipv6RouteInfo
.re_ibpkt
,
4490 octetstr(&rp6
->ipv6RouteIfIndex
, 'a',
4491 ifname
, sizeof (ifname
)));
4496 /* ------------------------------ TCP_REPORT------------------------------- */
4498 static const char tcp_hdr_v4
[] =
4500 static const char tcp_hdr_v4_compat
[] =
4502 static const char tcp_hdr_v4_verbose
[] =
4503 "Local/Remote Address Swind Snext Suna Rwind Rnext Rack "
4505 "-------------------- ----- -------- -------- ----- -------- -------- "
4506 "----- ----- -----------\n";
4507 static const char tcp_hdr_v4_normal
[] =
4508 " Local Address Remote Address Swind Send-Q Rwind Recv-Q "
4510 "-------------------- -------------------- ----- ------ ----- ------ "
4513 static const char tcp_hdr_v6
[] =
4515 static const char tcp_hdr_v6_verbose
[] =
4516 "Local/Remote Address Swind Snext Suna Rwind Rnext "
4517 " Rack Rto Mss State If\n"
4518 "--------------------------------- ----- -------- -------- ----- -------- "
4519 "-------- ----- ----- ----------- -----\n";
4520 static const char tcp_hdr_v6_normal
[] =
4521 " Local Address Remote Address "
4522 "Swind Send-Q Rwind Recv-Q State If\n"
4523 "--------------------------------- --------------------------------- "
4524 "----- ------ ----- ------ ----------- -----\n";
4526 static boolean_t
tcp_report_item_v4(const mib2_tcpConnEntry_t
*,
4528 static boolean_t
tcp_report_item_v6(const mib2_tcp6ConnEntry_t
*,
4532 tcp_report(const mib_item_t
*item
)
4535 boolean_t print_hdr_once_v4
= B_TRUE
;
4536 boolean_t print_hdr_once_v6
= B_TRUE
;
4537 mib2_tcpConnEntry_t
*tp
;
4538 mib2_tcp6ConnEntry_t
*tp6
;
4540 if (!protocol_selected(IPPROTO_TCP
))
4543 for (; item
!= NULL
; item
= item
->next_item
) {
4545 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
4546 (void) printf("Group = %d, mib_id = %d, "
4547 "length = %d, valp = 0x%p\n",
4548 item
->group
, item
->mib_id
,
4549 item
->length
, item
->valp
);
4552 if (!((item
->group
== MIB2_TCP
&&
4553 item
->mib_id
== MIB2_TCP_CONN
) ||
4554 (item
->group
== MIB2_TCP6
&&
4555 item
->mib_id
== MIB2_TCP6_CONN
)))
4556 continue; /* 'for' loop 1 */
4558 if (item
->group
== MIB2_TCP
&& !family_selected(AF_INET
))
4559 continue; /* 'for' loop 1 */
4560 else if (item
->group
== MIB2_TCP6
&& !family_selected(AF_INET6
))
4561 continue; /* 'for' loop 1 */
4563 if (item
->group
== MIB2_TCP
) {
4564 for (tp
= (mib2_tcpConnEntry_t
*)item
->valp
;
4565 (char *)tp
< (char *)item
->valp
+ item
->length
;
4566 /* LINTED: (note 1) */
4567 tp
= (mib2_tcpConnEntry_t
*)((char *)tp
+
4568 tcpConnEntrySize
)) {
4569 print_hdr_once_v4
= tcp_report_item_v4(tp
,
4573 for (tp6
= (mib2_tcp6ConnEntry_t
*)item
->valp
;
4574 (char *)tp6
< (char *)item
->valp
+ item
->length
;
4575 /* LINTED: (note 1) */
4576 tp6
= (mib2_tcp6ConnEntry_t
*)((char *)tp6
+
4577 tcp6ConnEntrySize
)) {
4578 print_hdr_once_v6
= tcp_report_item_v6(tp6
,
4582 } /* 'for' loop 1 ends */
4583 (void) fflush(stdout
);
4588 tcp_report_item_v4(const mib2_tcpConnEntry_t
*tp
, boolean_t first
)
4591 * lname and fname below are for the hostname as well as the portname
4592 * There is no limit on portname length so we assume MAXHOSTNAMELEN
4595 char lname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
4596 char fname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
4598 if (!(Aflag
|| tp
->tcpConnEntryInfo
.ce_state
>= TCPS_ESTABLISHED
))
4599 return (first
); /* Nothing to print */
4602 (void) printf(v4compat
? tcp_hdr_v4_compat
: tcp_hdr_v4
);
4603 (void) printf(Vflag
? tcp_hdr_v4_verbose
: tcp_hdr_v4_normal
);
4607 (void) printf("%-20s\n%-20s %5u %08x %08x %5u %08x %08x "
4609 pr_ap(tp
->tcpConnLocalAddress
,
4610 tp
->tcpConnLocalPort
, "tcp", lname
, sizeof (lname
)),
4611 pr_ap(tp
->tcpConnRemAddress
,
4612 tp
->tcpConnRemPort
, "tcp", fname
, sizeof (fname
)),
4613 tp
->tcpConnEntryInfo
.ce_swnd
,
4614 tp
->tcpConnEntryInfo
.ce_snxt
,
4615 tp
->tcpConnEntryInfo
.ce_suna
,
4616 tp
->tcpConnEntryInfo
.ce_rwnd
,
4617 tp
->tcpConnEntryInfo
.ce_rnxt
,
4618 tp
->tcpConnEntryInfo
.ce_rack
,
4619 tp
->tcpConnEntryInfo
.ce_rto
,
4620 tp
->tcpConnEntryInfo
.ce_mss
,
4621 mitcp_state(tp
->tcpConnEntryInfo
.ce_state
));
4623 int sq
= (int)tp
->tcpConnEntryInfo
.ce_snxt
-
4624 (int)tp
->tcpConnEntryInfo
.ce_suna
- 1;
4625 int rq
= (int)tp
->tcpConnEntryInfo
.ce_rnxt
-
4626 (int)tp
->tcpConnEntryInfo
.ce_rack
;
4628 (void) printf("%-20s %-20s %5u %6d %5u %6d\n",
4629 pr_ap(tp
->tcpConnLocalAddress
,
4630 tp
->tcpConnLocalPort
, "tcp", lname
, sizeof (lname
)),
4631 pr_ap(tp
->tcpConnRemAddress
,
4632 tp
->tcpConnRemPort
, "tcp", fname
, sizeof (fname
)),
4633 tp
->tcpConnEntryInfo
.ce_swnd
,
4635 tp
->tcpConnEntryInfo
.ce_rwnd
,
4637 mitcp_state(tp
->tcpConnEntryInfo
.ce_state
));
4644 tcp_report_item_v6(const mib2_tcp6ConnEntry_t
*tp6
, boolean_t first
)
4647 * lname and fname below are for the hostname as well as the portname
4648 * There is no limit on portname length so we assume MAXHOSTNAMELEN
4651 char lname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
4652 char fname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
4653 char ifname
[LIFNAMSIZ
+ 1];
4656 if (!(Aflag
|| tp6
->tcp6ConnEntryInfo
.ce_state
>= TCPS_ESTABLISHED
))
4657 return (first
); /* Nothing to print */
4660 (void) printf(tcp_hdr_v6
);
4661 (void) printf(Vflag
? tcp_hdr_v6_verbose
: tcp_hdr_v6_normal
);
4664 ifnamep
= (tp6
->tcp6ConnIfIndex
!= 0) ?
4665 if_indextoname(tp6
->tcp6ConnIfIndex
, ifname
) : NULL
;
4666 if (ifnamep
== NULL
)
4670 (void) printf("%-33s\n%-33s %5u %08x %08x %5u %08x %08x "
4671 "%5u %5u %-11s %s\n",
4672 pr_ap6(&tp6
->tcp6ConnLocalAddress
,
4673 tp6
->tcp6ConnLocalPort
, "tcp", lname
, sizeof (lname
)),
4674 pr_ap6(&tp6
->tcp6ConnRemAddress
,
4675 tp6
->tcp6ConnRemPort
, "tcp", fname
, sizeof (fname
)),
4676 tp6
->tcp6ConnEntryInfo
.ce_swnd
,
4677 tp6
->tcp6ConnEntryInfo
.ce_snxt
,
4678 tp6
->tcp6ConnEntryInfo
.ce_suna
,
4679 tp6
->tcp6ConnEntryInfo
.ce_rwnd
,
4680 tp6
->tcp6ConnEntryInfo
.ce_rnxt
,
4681 tp6
->tcp6ConnEntryInfo
.ce_rack
,
4682 tp6
->tcp6ConnEntryInfo
.ce_rto
,
4683 tp6
->tcp6ConnEntryInfo
.ce_mss
,
4684 mitcp_state(tp6
->tcp6ConnEntryInfo
.ce_state
),
4687 int sq
= (int)tp6
->tcp6ConnEntryInfo
.ce_snxt
-
4688 (int)tp6
->tcp6ConnEntryInfo
.ce_suna
- 1;
4689 int rq
= (int)tp6
->tcp6ConnEntryInfo
.ce_rnxt
-
4690 (int)tp6
->tcp6ConnEntryInfo
.ce_rack
;
4692 (void) printf("%-33s %-33s %5u %6d %5u %6d %-11s %s\n",
4693 pr_ap6(&tp6
->tcp6ConnLocalAddress
,
4694 tp6
->tcp6ConnLocalPort
, "tcp", lname
, sizeof (lname
)),
4695 pr_ap6(&tp6
->tcp6ConnRemAddress
,
4696 tp6
->tcp6ConnRemPort
, "tcp", fname
, sizeof (fname
)),
4697 tp6
->tcp6ConnEntryInfo
.ce_swnd
,
4699 tp6
->tcp6ConnEntryInfo
.ce_rwnd
,
4701 mitcp_state(tp6
->tcp6ConnEntryInfo
.ce_state
),
4708 /* ------------------------------- UDP_REPORT------------------------------- */
4710 static boolean_t
udp_report_item_v4(const mib2_udpEntry_t
*ude
,
4712 static boolean_t
udp_report_item_v6(const mib2_udp6Entry_t
*ude6
,
4715 static const char udp_hdr_v4
[] =
4716 " Local Address Remote Address State\n"
4717 "-------------------- -------------------- ----------\n";
4719 static const char udp_hdr_v6
[] =
4720 " Local Address Remote Address "
4722 "--------------------------------- --------------------------------- "
4723 "---------- -----\n";
4726 udp_report(const mib_item_t
*item
)
4729 boolean_t print_hdr_once_v4
= B_TRUE
;
4730 boolean_t print_hdr_once_v6
= B_TRUE
;
4731 mib2_udpEntry_t
*ude
;
4732 mib2_udp6Entry_t
*ude6
;
4734 if (!protocol_selected(IPPROTO_UDP
))
4738 for (; item
; item
= item
->next_item
) {
4740 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
4741 (void) printf("Group = %d, mib_id = %d, "
4742 "length = %d, valp = 0x%p\n",
4743 item
->group
, item
->mib_id
,
4744 item
->length
, item
->valp
);
4746 if (!((item
->group
== MIB2_UDP
&&
4747 item
->mib_id
== MIB2_UDP_ENTRY
) ||
4748 (item
->group
== MIB2_UDP6
&&
4749 item
->mib_id
== MIB2_UDP6_ENTRY
)))
4750 continue; /* 'for' loop 1 */
4752 if (item
->group
== MIB2_UDP
&& !family_selected(AF_INET
))
4753 continue; /* 'for' loop 1 */
4754 else if (item
->group
== MIB2_UDP6
&& !family_selected(AF_INET6
))
4755 continue; /* 'for' loop 1 */
4757 /* xxx.xxx.xxx.xxx,pppp sss... */
4758 if (item
->group
== MIB2_UDP
) {
4759 for (ude
= (mib2_udpEntry_t
*)item
->valp
;
4760 (char *)ude
< (char *)item
->valp
+ item
->length
;
4761 /* LINTED: (note 1) */
4762 ude
= (mib2_udpEntry_t
*)((char *)ude
+
4764 print_hdr_once_v4
= udp_report_item_v4(ude
,
4768 for (ude6
= (mib2_udp6Entry_t
*)item
->valp
;
4769 (char *)ude6
< (char *)item
->valp
+ item
->length
;
4770 /* LINTED: (note 1) */
4771 ude6
= (mib2_udp6Entry_t
*)((char *)ude6
+
4773 print_hdr_once_v6
= udp_report_item_v6(ude6
,
4777 } /* 'for' loop 1 ends */
4778 (void) fflush(stdout
);
4782 udp_report_item_v4(const mib2_udpEntry_t
*ude
, boolean_t first
)
4784 char lname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
4785 /* hostname + portname */
4787 if (!(Aflag
|| ude
->udpEntryInfo
.ue_state
>= MIB2_UDP_connected
))
4788 return (first
); /* Nothing to print */
4791 (void) printf(v4compat
? "\nUDP\n" : "\nUDP: IPv4\n");
4792 (void) printf(udp_hdr_v4
);
4796 (void) printf("%-20s ",
4797 pr_ap(ude
->udpLocalAddress
, ude
->udpLocalPort
, "udp",
4798 lname
, sizeof (lname
)));
4799 (void) printf("%-20s %s\n",
4800 ude
->udpEntryInfo
.ue_state
== MIB2_UDP_connected
?
4801 pr_ap(ude
->udpEntryInfo
.ue_RemoteAddress
,
4802 ude
->udpEntryInfo
.ue_RemotePort
, "udp", lname
, sizeof (lname
)) :
4804 miudp_state(ude
->udpEntryInfo
.ue_state
));
4810 udp_report_item_v6(const mib2_udp6Entry_t
*ude6
, boolean_t first
)
4812 char lname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
4813 /* hostname + portname */
4814 char ifname
[LIFNAMSIZ
+ 1];
4815 const char *ifnamep
;
4817 if (!(Aflag
|| ude6
->udp6EntryInfo
.ue_state
>= MIB2_UDP_connected
))
4818 return (first
); /* Nothing to print */
4821 (void) printf("\nUDP: IPv6\n");
4822 (void) printf(udp_hdr_v6
);
4826 ifnamep
= (ude6
->udp6IfIndex
!= 0) ?
4827 if_indextoname(ude6
->udp6IfIndex
, ifname
) : NULL
;
4829 (void) printf("%-33s ",
4830 pr_ap6(&ude6
->udp6LocalAddress
,
4831 ude6
->udp6LocalPort
, "udp", lname
, sizeof (lname
)));
4832 (void) printf("%-33s %-10s %s\n",
4833 ude6
->udp6EntryInfo
.ue_state
== MIB2_UDP_connected
?
4834 pr_ap6(&ude6
->udp6EntryInfo
.ue_RemoteAddress
,
4835 ude6
->udp6EntryInfo
.ue_RemotePort
, "udp", lname
, sizeof (lname
)) :
4837 miudp_state(ude6
->udp6EntryInfo
.ue_state
),
4838 ifnamep
== NULL
? "" : ifnamep
);
4843 /* ------------------------------ SCTP_REPORT------------------------------- */
4845 static const char sctp_hdr
[] =
4847 static const char sctp_hdr_normal
[] =
4848 " Local Address Remote Address "
4849 "Swind Send-Q Rwind Recv-Q StrsI/O State\n"
4850 "------------------------------- ------------------------------- "
4851 "------ ------ ------ ------ ------- -----------";
4854 nssctp_state(int state
)
4856 static char sctpsbuf
[50];
4860 case MIB2_SCTP_closed
:
4863 case MIB2_SCTP_cookieWait
:
4866 case MIB2_SCTP_cookieEchoed
:
4867 cp
= "COOKIE_ECHOED";
4869 case MIB2_SCTP_established
:
4872 case MIB2_SCTP_shutdownPending
:
4873 cp
= "SHUTDOWN_PENDING";
4875 case MIB2_SCTP_shutdownSent
:
4876 cp
= "SHUTDOWN_SENT";
4878 case MIB2_SCTP_shutdownReceived
:
4879 cp
= "SHUTDOWN_RECEIVED";
4881 case MIB2_SCTP_shutdownAckSent
:
4882 cp
= "SHUTDOWN_ACK_SENT";
4884 case MIB2_SCTP_listen
:
4888 (void) snprintf(sctpsbuf
, sizeof (sctpsbuf
),
4889 "UNKNOWN STATE(%d)", state
);
4897 static const mib2_sctpConnRemoteEntry_t
*
4898 sctp_getnext_rem(const mib_item_t
**itemp
,
4899 const mib2_sctpConnRemoteEntry_t
*current
, uint32_t associd
)
4901 const mib_item_t
*item
= *itemp
;
4902 const mib2_sctpConnRemoteEntry_t
*sre
;
4904 for (; item
!= NULL
; item
= item
->next_item
, current
= NULL
) {
4905 if (!(item
->group
== MIB2_SCTP
&&
4906 item
->mib_id
== MIB2_SCTP_CONN_REMOTE
)) {
4910 if (current
!= NULL
) {
4911 /* LINTED: (note 1) */
4912 sre
= (const mib2_sctpConnRemoteEntry_t
*)
4913 ((const char *)current
+ sctpRemoteEntrySize
);
4917 for (; (char *)sre
< (char *)item
->valp
+ item
->length
;
4918 /* LINTED: (note 1) */
4919 sre
= (const mib2_sctpConnRemoteEntry_t
*)
4920 ((const char *)sre
+ sctpRemoteEntrySize
)) {
4921 if (sre
->sctpAssocId
!= associd
) {
4932 static const mib2_sctpConnLocalEntry_t
*
4933 sctp_getnext_local(const mib_item_t
**itemp
,
4934 const mib2_sctpConnLocalEntry_t
*current
, uint32_t associd
)
4936 const mib_item_t
*item
= *itemp
;
4937 const mib2_sctpConnLocalEntry_t
*sle
;
4939 for (; item
!= NULL
; item
= item
->next_item
, current
= NULL
) {
4940 if (!(item
->group
== MIB2_SCTP
&&
4941 item
->mib_id
== MIB2_SCTP_CONN_LOCAL
)) {
4945 if (current
!= NULL
) {
4946 /* LINTED: (note 1) */
4947 sle
= (const mib2_sctpConnLocalEntry_t
*)
4948 ((const char *)current
+ sctpLocalEntrySize
);
4952 for (; (char *)sle
< (char *)item
->valp
+ item
->length
;
4953 /* LINTED: (note 1) */
4954 sle
= (const mib2_sctpConnLocalEntry_t
*)
4955 ((const char *)sle
+ sctpLocalEntrySize
)) {
4956 if (sle
->sctpAssocId
!= associd
) {
4968 sctp_pr_addr(int type
, char *name
, int namelen
, const in6_addr_t
*addr
,
4975 * Address is either a v4 mapped or v6 addr. If
4976 * it's a v4 mapped, convert to v4 before
4980 case MIB2_SCTP_ADDR_V4
:
4984 IN6_V4MAPPED_TO_IPADDR(&v6addr
, v4addr
);
4986 (void) pr_ap(v4addr
, port
, "sctp", name
, namelen
);
4988 (void) pr_addr(v4addr
, name
, namelen
);
4992 case MIB2_SCTP_ADDR_V6
:
4995 (void) pr_ap6(addr
, port
, "sctp", name
, namelen
);
4997 (void) pr_addr6(addr
, name
, namelen
);
5002 (void) snprintf(name
, namelen
, "<unknown addr type>");
5008 sctp_conn_report_item(const mib_item_t
*head
, const mib2_sctpConnEntry_t
*sp
)
5010 char lname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
5011 char fname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
5012 const mib2_sctpConnRemoteEntry_t
*sre
= NULL
;
5013 const mib2_sctpConnLocalEntry_t
*sle
= NULL
;
5014 const mib_item_t
*local
= head
;
5015 const mib_item_t
*remote
= head
;
5016 uint32_t id
= sp
->sctpAssocId
;
5017 boolean_t printfirst
= B_TRUE
;
5019 sctp_pr_addr(sp
->sctpAssocRemPrimAddrType
, fname
, sizeof (fname
),
5020 &sp
->sctpAssocRemPrimAddr
, sp
->sctpAssocRemPort
);
5021 sctp_pr_addr(sp
->sctpAssocRemPrimAddrType
, lname
, sizeof (lname
),
5022 &sp
->sctpAssocLocPrimAddr
, sp
->sctpAssocLocalPort
);
5024 (void) printf("%-31s %-31s %6u %6d %6u %6d %3d/%-3d %s\n",
5026 sp
->sctpConnEntryInfo
.ce_swnd
,
5027 sp
->sctpConnEntryInfo
.ce_sendq
,
5028 sp
->sctpConnEntryInfo
.ce_rwnd
,
5029 sp
->sctpConnEntryInfo
.ce_recvq
,
5030 sp
->sctpAssocInStreams
, sp
->sctpAssocOutStreams
,
5031 nssctp_state(sp
->sctpAssocState
));
5037 /* Print remote addresses/local addresses on following lines */
5038 while ((sre
= sctp_getnext_rem(&remote
, sre
, id
)) != NULL
) {
5039 if (!IN6_ARE_ADDR_EQUAL(&sre
->sctpAssocRemAddr
,
5040 &sp
->sctpAssocRemPrimAddr
)) {
5041 if (printfirst
== B_TRUE
) {
5042 (void) fputs("\t<Remote: ", stdout
);
5043 printfirst
= B_FALSE
;
5045 (void) fputs(", ", stdout
);
5047 sctp_pr_addr(sre
->sctpAssocRemAddrType
, fname
,
5048 sizeof (fname
), &sre
->sctpAssocRemAddr
, -1);
5049 if (sre
->sctpAssocRemAddrActive
== MIB2_SCTP_ACTIVE
) {
5050 (void) fputs(fname
, stdout
);
5052 (void) printf("(%s)", fname
);
5056 if (printfirst
== B_FALSE
) {
5058 printfirst
= B_TRUE
;
5060 while ((sle
= sctp_getnext_local(&local
, sle
, id
)) != NULL
) {
5061 if (!IN6_ARE_ADDR_EQUAL(&sle
->sctpAssocLocalAddr
,
5062 &sp
->sctpAssocLocPrimAddr
)) {
5063 if (printfirst
== B_TRUE
) {
5064 (void) fputs("\t<Local: ", stdout
);
5065 printfirst
= B_FALSE
;
5067 (void) fputs(", ", stdout
);
5069 sctp_pr_addr(sle
->sctpAssocLocalAddrType
, lname
,
5070 sizeof (lname
), &sle
->sctpAssocLocalAddr
, -1);
5071 (void) fputs(lname
, stdout
);
5074 if (printfirst
== B_FALSE
) {
5080 sctp_report(const mib_item_t
*item
)
5082 const mib_item_t
*head
;
5083 const mib2_sctpConnEntry_t
*sp
;
5084 boolean_t first
= B_TRUE
;
5087 for (; item
!= NULL
; item
= item
->next_item
) {
5089 if (!(item
->group
== MIB2_SCTP
&&
5090 item
->mib_id
== MIB2_SCTP_CONN
))
5093 for (sp
= item
->valp
;
5094 (char *)sp
< (char *)item
->valp
+ item
->length
;
5095 /* LINTED: (note 1) */
5096 sp
= (mib2_sctpConnEntry_t
*)((char *)sp
+ sctpEntrySize
)) {
5098 sp
->sctpAssocState
>= MIB2_SCTP_established
) {
5099 if (first
== B_TRUE
) {
5100 (void) puts(sctp_hdr
);
5101 (void) puts(sctp_hdr_normal
);
5104 sctp_conn_report_item(head
, sp
);
5113 return (n
!= 1 ? "s" : "");
5119 return (n
!= 1 ? "ies" : "y");
5125 return (n
!= 1 ? "es" : "");
5137 } else if (n
< 1024 * 1024) {
5140 } else if (n
< 1024 * 1024 * 1024) {
5145 n
/= 1024 * 1024 * 1024;
5148 (void) snprintf(buf
, sizeof (buf
), "%4u%c", n
, t
);
5152 /* --------------------- mrt_report (netstat -m) -------------------------- */
5155 mrt_report(mib_item_t
*item
)
5160 struct mfcctl
*mfccp
;
5163 char abuf
[MAXHOSTNAMELEN
+ 1];
5165 if (!(family_selected(AF_INET
)))
5169 for (; item
; item
= item
->next_item
) {
5171 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
5172 (void) printf("Group = %d, mib_id = %d, "
5173 "length = %d, valp = 0x%p\n",
5174 item
->group
, item
->mib_id
, item
->length
,
5177 if (item
->group
!= EXPER_DVMRP
)
5178 continue; /* 'for' loop 1 */
5180 switch (item
->mib_id
) {
5182 case EXPER_DVMRP_VIF
:
5184 (void) printf("%u records for ipVifTable:\n",
5185 item
->length
/sizeof (struct vifctl
));
5186 if (item
->length
/sizeof (struct vifctl
) == 0) {
5187 (void) puts("\nVirtual Interface Table is "
5192 (void) puts("\nVirtual Interface Table\n"
5193 " Vif Threshold Rate_Limit Local-Address"
5194 " Remote-Address Pkt_in Pkt_out");
5197 for (vip
= (struct vifctl
*)item
->valp
;
5198 (char *)vip
< (char *)item
->valp
+ item
->length
;
5199 /* LINTED: (note 1) */
5200 vip
= (struct vifctl
*)((char *)vip
+
5202 if (vip
->vifc_lcl_addr
.s_addr
== 0)
5203 continue; /* 'for' loop 2 */
5204 /* numvifs = vip->vifc_vifi; */
5207 (void) printf(" %2u %3u "
5210 vip
->vifc_threshold
,
5211 vip
->vifc_rate_limit
,
5212 pr_addr(vip
->vifc_lcl_addr
.s_addr
,
5213 abuf
, sizeof (abuf
)));
5214 (void) printf(" %-15.15s %8u %8u\n",
5215 (vip
->vifc_flags
& VIFF_TUNNEL
) ?
5216 pr_addr(vip
->vifc_rmt_addr
.s_addr
,
5217 abuf
, sizeof (abuf
)) : "",
5220 } /* 'for' loop 2 ends */
5222 (void) printf("Numvifs: %d\n", numvifs
);
5225 case EXPER_DVMRP_MRT
:
5227 (void) printf("%u records for ipMfcTable:\n",
5228 item
->length
/sizeof (struct vifctl
));
5229 if (item
->length
/sizeof (struct vifctl
) == 0) {
5230 (void) puts("\nMulticast Forwarding Cache is "
5235 (void) puts("\nMulticast Forwarding Cache\n"
5236 " Origin-Subnet Mcastgroup "
5237 "# Pkts In-Vif Out-vifs/Forw-ttl");
5239 for (mfccp
= (struct mfcctl
*)item
->valp
;
5240 (char *)mfccp
< (char *)item
->valp
+ item
->length
;
5241 /* LINTED: (note 1) */
5242 mfccp
= (struct mfcctl
*)((char *)mfccp
+
5246 (void) printf(" %-30.15s",
5247 pr_addr(mfccp
->mfcc_origin
.s_addr
,
5248 abuf
, sizeof (abuf
)));
5249 (void) printf("%-15.15s %6s %3u ",
5250 pr_net(mfccp
->mfcc_mcastgrp
.s_addr
,
5251 mfccp
->mfcc_mcastgrp
.s_addr
,
5252 abuf
, sizeof (abuf
)),
5253 pktscale((int)mfccp
->mfcc_pkt_cnt
),
5254 mfccp
->mfcc_parent
);
5256 for (vifi
= 0; vifi
< MAXVIFS
; ++vifi
) {
5257 if (mfccp
->mfcc_ttls
[vifi
]) {
5258 (void) printf(" %u (%u)",
5260 mfccp
->mfcc_ttls
[vifi
]);
5264 (void) putchar('\n');
5266 (void) printf("\nTotal no. of entries in cache: %d\n",
5270 } /* 'for' loop 1 ends */
5271 (void) putchar('\n');
5272 (void) fflush(stdout
);
5276 * Get the stats for the cache named 'name'. If prefix != 0, then
5277 * interpret the name as a prefix, and sum up stats for all caches
5281 kmem_cache_stats(char *title
, char *name
, int prefix
, int64_t *total_bytes
)
5285 int64_t total_alloc
= 0;
5286 int alloc_fail
, total_alloc_fail
= 0;
5290 int buf_max
, total_buf_max
= 0;
5291 int buf_inuse
, total_buf_inuse
= 0;
5295 len
= prefix
? strlen(name
) : 256;
5298 for (ksp
= kc
->kc_chain
; ksp
!= NULL
; ksp
= ksp
->ks_next
) {
5300 if (strcmp(ksp
->ks_class
, "kmem_cache") != 0)
5301 continue; /* 'for' loop 1 */
5304 * Hack alert: because of the way streams messages are
5305 * allocated, every constructed free dblk has an associated
5306 * mblk. From the allocator's viewpoint those mblks are
5307 * allocated (because they haven't been freed), but from
5308 * our viewpoint they're actually free (because they're
5309 * not currently in use). To account for this caching
5310 * effect we subtract the total constructed free dblks
5311 * from the total allocated mblks to derive mblks in use.
5313 if (strcmp(name
, "streams_mblk") == 0 &&
5314 strncmp(ksp
->ks_name
, "streams_dblk", 12) == 0) {
5315 (void) safe_kstat_read(kc
, ksp
, NULL
);
5317 kstat_named_value(ksp
, "buf_constructed");
5318 continue; /* 'for' loop 1 */
5321 if (strncmp(ksp
->ks_name
, name
, len
) != 0)
5322 continue; /* 'for' loop 1 */
5324 (void) safe_kstat_read(kc
, ksp
, NULL
);
5326 alloc
= kstat_named_value(ksp
, "alloc");
5327 alloc_fail
= kstat_named_value(ksp
, "alloc_fail");
5328 buf_size
= kstat_named_value(ksp
, "buf_size");
5329 buf_avail
= kstat_named_value(ksp
, "buf_avail");
5330 buf_total
= kstat_named_value(ksp
, "buf_total");
5331 buf_max
= kstat_named_value(ksp
, "buf_max");
5332 buf_inuse
= buf_total
- buf_avail
;
5334 if (Vflag
&& prefix
) {
5335 (void) snprintf(buf
, sizeof (buf
), "%s%s", title
,
5336 ksp
->ks_name
+ len
);
5337 (void) printf(" %-18s %6u %9u %11u %11u\n",
5338 buf
, buf_inuse
, buf_max
, alloc
, alloc_fail
);
5341 total_alloc
+= alloc
;
5342 total_alloc_fail
+= alloc_fail
;
5343 total_buf_max
+= buf_max
;
5344 total_buf_inuse
+= buf_inuse
;
5345 *total_bytes
+= (int64_t)buf_inuse
* buf_size
;
5346 } /* 'for' loop 1 ends */
5348 if (buf_size
== 0) {
5349 (void) printf("%-22s [couldn't find statistics for %s]\n",
5354 if (Vflag
&& prefix
)
5355 (void) snprintf(buf
, sizeof (buf
), "%s_total", title
);
5357 (void) snprintf(buf
, sizeof (buf
), "%s", title
);
5359 (void) printf("%-22s %6d %9d %11lld %11d\n", buf
,
5360 total_buf_inuse
, total_buf_max
, total_alloc
, total_alloc_fail
);
5366 int64_t total_bytes
= 0;
5368 (void) puts("streams allocation:");
5369 (void) printf("%63s\n", "cumulative allocation");
5370 (void) printf("%63s\n",
5371 "current maximum total failures");
5373 kmem_cache_stats("streams",
5374 "stream_head_cache", 0, &total_bytes
);
5375 kmem_cache_stats("queues", "queue_cache", 0, &total_bytes
);
5376 kmem_cache_stats("mblk", "streams_mblk", 0, &total_bytes
);
5377 kmem_cache_stats("dblk", "streams_dblk", 1, &total_bytes
);
5378 kmem_cache_stats("linkblk", "linkinfo_cache", 0, &total_bytes
);
5379 kmem_cache_stats("syncq", "syncq_cache", 0, &total_bytes
);
5380 kmem_cache_stats("qband", "qband_cache", 0, &total_bytes
);
5382 (void) printf("\n%lld Kbytes allocated for streams data\n",
5383 total_bytes
/ 1024);
5385 (void) putchar('\n');
5386 (void) fflush(stdout
);
5389 /* --------------------------------- */
5392 * Print an IPv4 address. Remove the matching part of the domain name
5393 * from the returned name.
5396 pr_addr(uint_t addr
, char *dst
, uint_t dstlen
)
5399 struct hostent
*hp
= NULL
;
5400 static char domain
[MAXHOSTNAMELEN
+ 1];
5401 static boolean_t first
= B_TRUE
;
5406 if (sysinfo(SI_HOSTNAME
, domain
, MAXHOSTNAMELEN
) != -1 &&
5407 (cp
= strchr(domain
, '.'))) {
5408 (void) strncpy(domain
, cp
+ 1, sizeof (domain
));
5414 hp
= getipnodebyaddr((char *)&addr
, sizeof (uint_t
), AF_INET
,
5417 if ((cp
= strchr(hp
->h_name
, '.')) != NULL
&&
5418 strcasecmp(cp
+ 1, domain
) == 0)
5424 (void) strncpy(dst
, cp
, dstlen
);
5425 dst
[dstlen
- 1] = 0;
5427 (void) inet_ntop(AF_INET
, (char *)&addr
, dst
, dstlen
);
5435 * Print a non-zero IPv4 address. Print " --" if the address is zero.
5438 pr_addrnz(ipaddr_t addr
, char *dst
, uint_t dstlen
)
5440 if (addr
== INADDR_ANY
) {
5441 (void) strlcpy(dst
, " --", dstlen
);
5444 return (pr_addr(addr
, dst
, dstlen
));
5448 * Print an IPv6 address. Remove the matching part of the domain name
5449 * from the returned name.
5452 pr_addr6(const struct in6_addr
*addr
, char *dst
, uint_t dstlen
)
5455 struct hostent
*hp
= NULL
;
5456 static char domain
[MAXHOSTNAMELEN
+ 1];
5457 static boolean_t first
= B_TRUE
;
5462 if (sysinfo(SI_HOSTNAME
, domain
, MAXHOSTNAMELEN
) != -1 &&
5463 (cp
= strchr(domain
, '.'))) {
5464 (void) strncpy(domain
, cp
+ 1, sizeof (domain
));
5470 hp
= getipnodebyaddr((char *)addr
,
5471 sizeof (struct in6_addr
), AF_INET6
, &error_num
);
5473 if ((cp
= strchr(hp
->h_name
, '.')) != NULL
&&
5474 strcasecmp(cp
+ 1, domain
) == 0)
5480 (void) strncpy(dst
, cp
, dstlen
);
5481 dst
[dstlen
- 1] = 0;
5483 (void) inet_ntop(AF_INET6
, (void *)addr
, dst
, dstlen
);
5490 /* For IPv4 masks */
5492 pr_mask(uint_t addr
, char *dst
, uint_t dstlen
)
5494 uint8_t *ip_addr
= (uint8_t *)&addr
;
5496 (void) snprintf(dst
, dstlen
, "%d.%d.%d.%d",
5497 ip_addr
[0], ip_addr
[1], ip_addr
[2], ip_addr
[3]);
5502 * For ipv6 masks format is : dest/mask
5503 * Does not print /128 to save space in printout. H flag carries this notion.
5506 pr_prefix6(const struct in6_addr
*addr
, uint_t prefixlen
, char *dst
,
5511 if (IN6_IS_ADDR_UNSPECIFIED(addr
) && prefixlen
== 0) {
5512 (void) strncpy(dst
, "default", dstlen
);
5513 dst
[dstlen
- 1] = 0;
5517 (void) pr_addr6(addr
, dst
, dstlen
);
5518 if (prefixlen
!= IPV6_ABITS
) {
5519 /* How much room is left? */
5520 cp
= strchr(dst
, '\0');
5521 if (dst
+ dstlen
> cp
) {
5522 dstlen
-= (cp
- dst
);
5523 (void) snprintf(cp
, dstlen
, "/%d", prefixlen
);
5529 /* Print IPv4 address and port */
5531 pr_ap(uint_t addr
, uint_t port
, char *proto
,
5532 char *dst
, uint_t dstlen
)
5536 if (addr
== INADDR_ANY
) {
5537 (void) strncpy(dst
, " *", dstlen
);
5538 dst
[dstlen
- 1] = 0;
5540 (void) pr_addr(addr
, dst
, dstlen
);
5542 /* How much room is left? */
5543 cp
= strchr(dst
, '\0');
5544 if (dst
+ dstlen
> cp
+ 1) {
5546 dstlen
-= (cp
- dst
);
5548 (void) portname(port
, proto
, cp
, dstlen
);
5553 /* Print IPv6 address and port */
5555 pr_ap6(const in6_addr_t
*addr
, uint_t port
, char *proto
,
5556 char *dst
, uint_t dstlen
)
5560 if (IN6_IS_ADDR_UNSPECIFIED(addr
)) {
5561 (void) strncpy(dst
, " *", dstlen
);
5562 dst
[dstlen
- 1] = 0;
5564 (void) pr_addr6(addr
, dst
, dstlen
);
5566 /* How much room is left? */
5567 cp
= strchr(dst
, '\0');
5568 if (dst
+ dstlen
+ 1 > cp
) {
5570 dstlen
-= (cp
- dst
);
5572 (void) portname(port
, proto
, cp
, dstlen
);
5578 * Return the name of the network whose address is given. The address is
5579 * assumed to be that of a net or subnet, not a host.
5582 pr_net(uint_t addr
, uint_t mask
, char *dst
, uint_t dstlen
)
5585 struct netent
*np
= NULL
;
5586 struct hostent
*hp
= NULL
;
5591 if (addr
== INADDR_ANY
&& mask
== INADDR_ANY
) {
5592 (void) strncpy(dst
, "default", dstlen
);
5593 dst
[dstlen
- 1] = 0;
5597 if (!Nflag
&& addr
) {
5599 if (IN_CLASSA(addr
)) {
5600 mask
= (uint_t
)IN_CLASSA_NET
;
5602 } else if (IN_CLASSB(addr
)) {
5603 mask
= (uint_t
)IN_CLASSB_NET
;
5606 mask
= (uint_t
)IN_CLASSC_NET
;
5610 * If there are more bits than the standard mask
5611 * would suggest, subnets must be in use. Guess at
5612 * the subnet mask, assuming reasonable width subnet
5615 while (addr
& ~mask
)
5616 /* compiler doesn't sign extend! */
5617 mask
= (mask
| ((int)mask
>> subnetshift
));
5620 while ((mask
& 1) == 0)
5621 mask
>>= 1, net
>>= 1;
5622 np
= getnetbyaddr(net
, AF_INET
);
5623 if (np
&& np
->n_net
== net
)
5627 * Look for subnets in hosts map.
5629 hp
= getipnodebyaddr((char *)&addr
, sizeof (uint_t
),
5630 AF_INET
, &error_num
);
5636 (void) strncpy(dst
, cp
, dstlen
);
5637 dst
[dstlen
- 1] = 0;
5639 (void) inet_ntop(AF_INET
, (char *)&addr
, dst
, dstlen
);
5647 * Return the name of the network whose address is given.
5648 * The address is assumed to be a host address.
5651 pr_netaddr(uint_t addr
, uint_t mask
, char *dst
, uint_t dstlen
)
5654 struct netent
*np
= NULL
;
5655 struct hostent
*hp
= NULL
;
5661 uint_t nbo_addr
= addr
; /* network byte order */
5665 if (addr
== INADDR_ANY
&& mask
== INADDR_ANY
) {
5666 (void) strncpy(dst
, "default", dstlen
);
5667 dst
[dstlen
- 1] = 0;
5671 /* Figure out network portion of address (with host portion = 0) */
5673 /* Try figuring out mask if unknown (all 0s). */
5675 if (IN_CLASSA(addr
)) {
5676 mask
= (uint_t
)IN_CLASSA_NET
;
5678 } else if (IN_CLASSB(addr
)) {
5679 mask
= (uint_t
)IN_CLASSB_NET
;
5682 mask
= (uint_t
)IN_CLASSC_NET
;
5686 * If there are more bits than the standard mask
5687 * would suggest, subnets must be in use. Guess at
5688 * the subnet mask, assuming reasonable width subnet
5691 while (addr
& ~mask
)
5692 /* compiler doesn't sign extend! */
5693 mask
= (mask
| ((int)mask
>> subnetshift
));
5695 net
= netshifted
= addr
& mask
;
5696 while ((mask
& 1) == 0)
5697 mask
>>= 1, netshifted
>>= 1;
5700 net
= netshifted
= 0;
5702 /* Try looking up name unless -n was specified. */
5704 np
= getnetbyaddr(netshifted
, AF_INET
);
5705 if (np
&& np
->n_net
== netshifted
)
5709 * Look for subnets in hosts map.
5711 hp
= getipnodebyaddr((char *)&nbo_addr
, sizeof (uint_t
),
5712 AF_INET
, &error_num
);
5718 (void) strncpy(dst
, cp
, dstlen
);
5719 dst
[dstlen
- 1] = 0;
5725 * No name found for net: fallthru and return in decimal
5730 in
.s_addr
= htonl(net
);
5731 (void) inet_ntop(AF_INET
, (char *)&in
, dst
, dstlen
);
5738 * Return the filter mode as a string:
5741 * otherwise "<unknown>"
5744 fmodestr(uint_t fmode
)
5752 return ("<unknown>");
5756 #define MAX_STRING_SIZE 256
5759 * Pretty print a port number. If the Nflag was
5760 * specified, use numbers instead of names.
5763 portname(uint_t port
, char *proto
, char *dst
, uint_t dstlen
)
5765 struct servent
*sp
= NULL
;
5768 sp
= getservbyport(htons(port
), proto
);
5769 if (sp
|| port
== 0)
5770 (void) snprintf(dst
, dstlen
, "%.*s", MAXHOSTNAMELEN
,
5771 sp
? sp
->s_name
: "*");
5773 (void) snprintf(dst
, dstlen
, "%d", port
);
5774 dst
[dstlen
- 1] = 0;
5780 fail(int do_perror
, char *message
, ...)
5784 va_start(args
, message
);
5785 (void) fputs("netstat: ", stderr
);
5786 (void) vfprintf(stderr
, message
, args
);
5789 (void) fprintf(stderr
, ": %s", strerror(errno
));
5790 (void) fputc('\n', stderr
);
5795 * Return value of named statistic for given kstat_named kstat;
5796 * return 0LL if named statistic is not in list (use "ll" as a
5797 * type qualifier when printing 64-bit int's with printf() )
5800 kstat_named_value(kstat_t
*ksp
, char *name
)
5808 knp
= kstat_data_lookup(ksp
, name
);
5812 switch (knp
->data_type
) {
5813 case KSTAT_DATA_INT32
:
5814 case KSTAT_DATA_UINT32
:
5815 value
= (uint64_t)(knp
->value
.ui32
);
5817 case KSTAT_DATA_INT64
:
5818 case KSTAT_DATA_UINT64
:
5819 value
= knp
->value
.ui64
;
5830 safe_kstat_read(kstat_ctl_t
*kc
, kstat_t
*ksp
, void *data
)
5832 kid_t kstat_chain_id
= kstat_read(kc
, ksp
, data
);
5834 if (kstat_chain_id
== -1)
5835 fail(1, "kstat_read(%p, '%s') failed", (void *)kc
,
5837 return (kstat_chain_id
);
5841 * Parse a list of IRE flag characters into a bit field.
5844 flag_bits(const char *arg
)
5850 fatal(1, "missing flag list\n");
5853 while (*arg
!= '\0') {
5854 if ((cp
= strchr(flag_list
, *arg
)) == NULL
)
5855 fatal(1, "%c: illegal flag\n", *arg
);
5856 val
|= 1 << (cp
- flag_list
);
5863 * Handle -f argument. Validate input format, sort by keyword, and
5864 * save off digested results.
5867 process_filter(char *arg
)
5879 /* Look up the keyword first */
5880 if (strchr(arg
, ':') == NULL
) {
5883 for (idx
= 0; idx
< NFILTERKEYS
; idx
++) {
5884 klen
= strlen(filter_keys
[idx
]);
5885 if (strncmp(filter_keys
[idx
], arg
, klen
) == 0 &&
5889 if (idx
>= NFILTERKEYS
)
5890 fatal(1, "%s: unknown filter keyword\n", arg
);
5892 /* Advance past keyword and separator. */
5896 if ((newf
= malloc(sizeof (*newf
))) == NULL
) {
5902 if (strcmp(arg
, "inet") == 0) {
5903 newf
->u
.f_family
= AF_INET
;
5904 } else if (strcmp(arg
, "inet6") == 0) {
5905 newf
->u
.f_family
= AF_INET6
;
5906 } else if (strcmp(arg
, "unix") == 0) {
5907 newf
->u
.f_family
= AF_UNIX
;
5909 newf
->u
.f_family
= strtol(arg
, &cp
, 0);
5910 if (arg
== cp
|| *cp
!= '\0')
5911 fatal(1, "%s: unknown address family.\n", arg
);
5916 if (strcmp(arg
, "none") == 0) {
5917 newf
->u
.f_ifname
= NULL
;
5920 if (strcmp(arg
, "any") == 0) {
5921 newf
->u
.f_ifname
= "";
5924 val
= strtol(arg
, &cp
, 0);
5925 if (val
<= 0 || arg
== cp
|| cp
[0] != '\0') {
5926 if ((val
= if_nametoindex(arg
)) == 0) {
5931 newf
->u
.f_ifname
= arg
;
5935 V4MASK_TO_V6(IP_HOST_MASK
, newf
->u
.a
.f_mask
);
5936 if (strcmp(arg
, "any") == 0) {
5937 /* Special semantics; any address *but* zero */
5938 newf
->u
.a
.f_address
= NULL
;
5939 (void) memset(&newf
->u
.a
.f_mask
, 0,
5940 sizeof (newf
->u
.a
.f_mask
));
5943 if (strcmp(arg
, "none") == 0) {
5944 newf
->u
.a
.f_address
= NULL
;
5947 if ((cp
= strrchr(arg
, '/')) != NULL
)
5949 hp
= getipnodebyname(arg
, AF_INET6
, AI_V4MAPPED
|AI_ALL
,
5952 fatal(1, "%s: invalid or unknown host address\n", arg
);
5953 newf
->u
.a
.f_address
= hp
;
5955 V4MASK_TO_V6(IP_HOST_MASK
, newf
->u
.a
.f_mask
);
5957 val
= strtol(cp
, &cp2
, 0);
5958 if (cp
!= cp2
&& cp2
[0] == '\0') {
5960 * If decode as "/n" works, then translate
5963 if (hp
->h_addr_list
[0] != NULL
&&
5964 /* LINTED: (note 1) */
5965 IN6_IS_ADDR_V4MAPPED((in6_addr_t
*)
5966 hp
->h_addr_list
[0])) {
5971 if (val
< 0 || val
>= maxv
)
5972 fatal(1, "%d: not in range 0 to %d\n",
5974 if (maxv
== IP_ABITS
)
5975 val
+= IPV6_ABITS
- IP_ABITS
;
5976 ucp
= newf
->u
.a
.f_mask
.s6_addr
;
5978 *ucp
++ = 0xff, val
-= 8;
5979 *ucp
++ = (0xff << (8 - val
)) & 0xff;
5980 while (ucp
< newf
->u
.a
.f_mask
.s6_addr
+
5981 sizeof (newf
->u
.a
.f_mask
.s6_addr
))
5983 /* Otherwise, try as numeric address */
5984 } else if (inet_pton(AF_INET6
,
5985 cp
, &newf
->u
.a
.f_mask
) <= 0) {
5986 fatal(1, "%s: illegal mask format\n", cp
);
5993 newf
->u
.f
.f_flagset
= flag_bits(arg
+ 1);
5994 newf
->u
.f
.f_flagclear
= 0;
5995 } else if (*arg
== '-') {
5996 newf
->u
.f
.f_flagset
= 0;
5997 newf
->u
.f
.f_flagclear
= flag_bits(arg
+ 1);
5999 newf
->u
.f
.f_flagset
= flag_bits(arg
);
6000 newf
->u
.f
.f_flagclear
= ~newf
->u
.f
.f_flagset
;
6007 newf
->f_next
= filters
[idx
];
6008 filters
[idx
] = newf
;
6011 /* Determine if user wants this address family printed. */
6013 family_selected(int family
)
6017 if (v4compat
&& family
== AF_INET6
)
6019 if ((fp
= filters
[FK_AF
]) == NULL
)
6021 while (fp
!= NULL
) {
6022 if (fp
->u
.f_family
== family
)
6030 * Convert the interface index to a string using the buffer `ifname', which
6031 * must be at least LIFNAMSIZ bytes. We first try to map it to name. If that
6032 * fails (e.g., because we're inside a zone and it does not have access to
6033 * interface for the index in question), just return "if#<num>".
6036 ifindex2str(uint_t ifindex
, char *ifname
)
6038 if (if_indextoname(ifindex
, ifname
) == NULL
)
6039 (void) snprintf(ifname
, LIFNAMSIZ
, "if#%d", ifindex
);
6045 * print the usage line
6048 usage(char *cmdname
)
6050 (void) fprintf(stderr
, "usage: %s [-anv] [-f address_family] "
6051 "[-T d|u]\n", cmdname
);
6052 (void) fprintf(stderr
, " %s [-n] [-f address_family] "
6053 "[-P protocol] [-T d|u] [-g | -p | -s [interval [count]]]\n",
6055 (void) fprintf(stderr
, " %s -m [-v] [-T d|u] "
6056 "[interval [count]]\n", cmdname
);
6057 (void) fprintf(stderr
, " %s -i [-I interface] [-an] "
6058 "[-f address_family] [-T d|u] [interval [count]]\n", cmdname
);
6059 (void) fprintf(stderr
, " %s -r [-anv] "
6060 "[-f address_family|filter] [-T d|u]\n", cmdname
);
6061 (void) fprintf(stderr
, " %s -M [-ns] [-f address_family] "
6062 "[-T d|u]\n", cmdname
);
6063 (void) fprintf(stderr
, " %s -D [-I interface] "
6064 "[-f address_family] [-T d|u]\n", cmdname
);
6069 * fatal: print error message to stderr and
6070 * call exit(errcode)
6074 fatal(int errcode
, char *format
, ...)
6081 va_start(argp
, format
);
6082 (void) vfprintf(stderr
, format
, argp
);