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>
90 #include <tsol/label.h>
92 #include "statcommon.h"
94 extern void unixpr(kstat_ctl_t
*kc
);
98 #define V4MASK_TO_V6(v4, v6) ((v6)._S6_un._S6_u32[0] = 0xfffffffful, \
99 (v6)._S6_un._S6_u32[1] = 0xfffffffful, \
100 (v6)._S6_un._S6_u32[2] = 0xfffffffful, \
101 (v6)._S6_un._S6_u32[3] = (v4))
103 #define IN6_IS_V4MASK(v6) ((v6)._S6_un._S6_u32[0] == 0xfffffffful && \
104 (v6)._S6_un._S6_u32[1] == 0xfffffffful && \
105 (v6)._S6_un._S6_u32[2] == 0xfffffffful)
108 * This is used as a cushion in the buffer allocation directed by SIOCGLIFNUM.
109 * Because there's no locking between SIOCGLIFNUM and SIOCGLIFCONF, it's
110 * possible for an administrator to plumb new interfaces between those two
111 * calls, resulting in the failure of the latter. This addition makes that
114 #define LIFN_GUARD_VALUE 10
116 typedef struct mib_item_s
{
117 struct mib_item_s
*next_item
;
133 struct iflist
*next_if
;
134 char ifname
[LIFNAMSIZ
];
138 static mib_item_t
*mibget(int sd
);
139 static void mibfree(mib_item_t
*firstitem
);
140 static int mibopen(void);
141 static void mib_get_constants(mib_item_t
*item
);
142 static mib_item_t
*mib_item_dup(mib_item_t
*item
);
143 static mib_item_t
*mib_item_diff(mib_item_t
*item1
,
145 static void mib_item_destroy(mib_item_t
**item
);
147 static boolean_t
octetstrmatch(const Octet_t
*a
, const Octet_t
*b
);
148 static char *octetstr(const Octet_t
*op
, int code
,
149 char *dst
, uint_t dstlen
);
150 static char *pr_addr(uint_t addr
,
151 char *dst
, uint_t dstlen
);
152 static char *pr_addrnz(ipaddr_t addr
, char *dst
, uint_t dstlen
);
153 static char *pr_addr6(const in6_addr_t
*addr
,
154 char *dst
, uint_t dstlen
);
155 static char *pr_mask(uint_t addr
,
156 char *dst
, uint_t dstlen
);
157 static char *pr_prefix6(const struct in6_addr
*addr
,
158 uint_t prefixlen
, char *dst
, uint_t dstlen
);
159 static char *pr_ap(uint_t addr
, uint_t port
,
160 char *proto
, char *dst
, uint_t dstlen
);
161 static char *pr_ap6(const in6_addr_t
*addr
, uint_t port
,
162 char *proto
, char *dst
, uint_t dstlen
);
163 static char *pr_net(uint_t addr
, uint_t mask
,
164 char *dst
, uint_t dstlen
);
165 static char *pr_netaddr(uint_t addr
, uint_t mask
,
166 char *dst
, uint_t dstlen
);
167 static char *fmodestr(uint_t fmode
);
168 static char *portname(uint_t port
, char *proto
,
169 char *dst
, uint_t dstlen
);
171 static const char *mitcp_state(int code
,
172 const mib2_transportMLPEntry_t
*attr
);
173 static const char *miudp_state(int code
,
174 const mib2_transportMLPEntry_t
*attr
);
176 static void stat_report(mib_item_t
*item
);
177 static void mrt_stat_report(mib_item_t
*item
);
178 static void arp_report(mib_item_t
*item
);
179 static void ndp_report(mib_item_t
*item
);
180 static void mrt_report(mib_item_t
*item
);
181 static void if_stat_total(struct ifstat
*oldstats
,
182 struct ifstat
*newstats
, struct ifstat
*sumstats
);
183 static void if_report(mib_item_t
*item
, char *ifname
,
184 int Iflag_only
, boolean_t once_only
);
185 static void if_report_ip4(mib2_ipAddrEntry_t
*ap
,
186 char ifname
[], char logintname
[],
187 struct ifstat
*statptr
, boolean_t ksp_not_null
);
188 static void if_report_ip6(mib2_ipv6AddrEntry_t
*ap6
,
189 char ifname
[], char logintname
[],
190 struct ifstat
*statptr
, boolean_t ksp_not_null
);
191 static void ire_report(const mib_item_t
*item
);
192 static void tcp_report(const mib_item_t
*item
);
193 static void udp_report(const mib_item_t
*item
);
194 static void group_report(mib_item_t
*item
);
195 static void dce_report(mib_item_t
*item
);
196 static void print_ip_stats(mib2_ip_t
*ip
);
197 static void print_icmp_stats(mib2_icmp_t
*icmp
);
198 static void print_ip6_stats(mib2_ipv6IfStatsEntry_t
*ip6
);
199 static void print_icmp6_stats(mib2_ipv6IfIcmpEntry_t
*icmp6
);
200 static void print_sctp_stats(mib2_sctp_t
*tcp
);
201 static void print_tcp_stats(mib2_tcp_t
*tcp
);
202 static void print_udp_stats(mib2_udp_t
*udp
);
203 static void print_rawip_stats(mib2_rawip_t
*rawip
);
204 static void print_igmp_stats(struct igmpstat
*igps
);
205 static void print_mrt_stats(struct mrtstat
*mrts
);
206 static void sctp_report(const mib_item_t
*item
);
207 static void sum_ip6_stats(mib2_ipv6IfStatsEntry_t
*ip6
,
208 mib2_ipv6IfStatsEntry_t
*sum6
);
209 static void sum_icmp6_stats(mib2_ipv6IfIcmpEntry_t
*icmp6
,
210 mib2_ipv6IfIcmpEntry_t
*sum6
);
211 static void m_report(void);
212 static void dhcp_report(char *);
214 static uint64_t kstat_named_value(kstat_t
*, char *);
215 static kid_t
safe_kstat_read(kstat_ctl_t
*, kstat_t
*, void *);
216 static int isnum(char *);
217 static char *plural(int n
);
218 static char *pluraly(int n
);
219 static char *plurales(int n
);
220 static void process_filter(char *arg
);
221 static char *ifindex2str(uint_t
, char *);
222 static boolean_t
family_selected(int family
);
224 static void usage(char *);
225 static void fatal(int errcode
, char *str1
, ...);
227 #define PLURAL(n) plural((int)n)
228 #define PLURALY(n) pluraly((int)n)
229 #define PLURALES(n) plurales((int)n)
230 #define IFLAGMOD(flg, val1, val2) if (flg == val1) flg = val2
231 #define MDIFF(diff, elem2, elem1, member) (diff)->member = \
232 (elem2)->member - (elem1)->member
235 static boolean_t Aflag
= B_FALSE
; /* All sockets/ifs/rtng-tbls */
236 static boolean_t Dflag
= B_FALSE
; /* DCE info */
237 static boolean_t Iflag
= B_FALSE
; /* IP Traffic Interfaces */
238 static boolean_t Mflag
= B_FALSE
; /* STREAMS Memory Statistics */
239 static boolean_t Nflag
= B_FALSE
; /* Numeric Network Addresses */
240 static boolean_t Rflag
= B_FALSE
; /* Routing Tables */
241 static boolean_t RSECflag
= B_FALSE
; /* Security attributes */
242 static boolean_t Sflag
= B_FALSE
; /* Per-protocol Statistics */
243 static boolean_t Vflag
= B_FALSE
; /* Verbose */
244 static boolean_t Pflag
= B_FALSE
; /* Net to Media Tables */
245 static boolean_t Gflag
= B_FALSE
; /* Multicast group membership */
246 static boolean_t MMflag
= B_FALSE
; /* Multicast routing table */
247 static boolean_t DHCPflag
= B_FALSE
; /* DHCP statistics */
248 static boolean_t Xflag
= B_FALSE
; /* Debug Info */
250 static int v4compat
= 0; /* Compatible printing format for status */
252 static int proto
= IPPROTO_MAX
; /* all protocols */
253 kstat_ctl_t
*kc
= NULL
;
256 * Sizes of data structures extracted from the base mib.
257 * This allows the size of the tables entries to grow while preserving
258 * binary compatibility.
260 static int ipAddrEntrySize
;
261 static int ipRouteEntrySize
;
262 static int ipNetToMediaEntrySize
;
263 static int ipMemberEntrySize
;
264 static int ipGroupSourceEntrySize
;
265 static int ipRouteAttributeSize
;
266 static int vifctlSize
;
267 static int mfcctlSize
;
269 static int ipv6IfStatsEntrySize
;
270 static int ipv6IfIcmpEntrySize
;
271 static int ipv6AddrEntrySize
;
272 static int ipv6RouteEntrySize
;
273 static int ipv6NetToMediaEntrySize
;
274 static int ipv6MemberEntrySize
;
275 static int ipv6GroupSourceEntrySize
;
277 static int ipDestEntrySize
;
279 static int transportMLPSize
;
280 static int tcpConnEntrySize
;
281 static int tcp6ConnEntrySize
;
282 static int udpEntrySize
;
283 static int udp6EntrySize
;
284 static int sctpEntrySize
;
285 static int sctpLocalEntrySize
;
286 static int sctpRemoteEntrySize
;
288 #define protocol_selected(p) (proto == IPPROTO_MAX || proto == (p))
290 /* Machinery used for -f (filter) option */
291 enum { FK_AF
= 0, FK_OUTIF
, FK_DST
, FK_FLAGS
, NFILTERKEYS
};
293 static const char *filter_keys
[NFILTERKEYS
] = {
294 "af", "outif", "dst", "flags"
297 static m_label_t
*zone_security_label
= NULL
;
299 /* Flags on routes */
300 #define FLF_A 0x00000001
301 #define FLF_b 0x00000002
302 #define FLF_D 0x00000004
303 #define FLF_G 0x00000008
304 #define FLF_H 0x00000010
305 #define FLF_L 0x00000020
306 #define FLF_U 0x00000040
307 #define FLF_M 0x00000080
308 #define FLF_S 0x00000100
309 #define FLF_C 0x00000200 /* IRE_IF_CLONE */
310 #define FLF_I 0x00000400 /* RTF_INDIRECT */
311 #define FLF_R 0x00000800 /* RTF_REJECT */
312 #define FLF_B 0x00001000 /* RTF_BLACKHOLE */
313 #define FLF_Z 0x00100000 /* RTF_ZONE */
315 static const char flag_list
[] = "AbDGHLUMSCIRBZ";
317 typedef struct filter_rule filter_t
;
323 const char *f_ifname
;
325 struct hostent
*f_address
;
336 * The user-specified filters are linked into lists separated by
337 * keyword (type of filter). Thus, the matching algorithm is:
338 * For each non-empty filter list
339 * If no filters in the list match
340 * then stop here; route doesn't match
341 * If loop above completes, then route does match and will be
344 static filter_t
*filters
[NFILTERKEYS
];
346 static uint_t timestamp_fmt
= NODATE
;
348 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
349 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't */
353 main(int argc
, char **argv
)
356 mib_item_t
*item
= NULL
;
357 mib_item_t
*previtem
= NULL
;
360 int interval
= 0; /* Single time by default */
361 int count
= -1; /* Forever */
365 * Possible values of 'Iflag_only':
366 * -1, no feature-flags;
367 * 0, IFlag and other feature-flags enabled
368 * 1, IFlag is the only feature-flag enabled
369 * : trinary variable, modified using IFLAGMOD()
372 boolean_t once_only
= B_FALSE
; /* '-i' with count > 1 */
375 char *default_ip_str
= NULL
;
379 v4compat
= get_compat_flag(&default_ip_str
);
380 if (v4compat
== DEFAULT_PROT_BAD_VALUE
)
381 fatal(2, "%s: %s: Bad value for %s in %s\n", name
,
382 default_ip_str
, DEFAULT_IP
, INET_DEFAULT_FILE
);
383 free(default_ip_str
);
385 (void) setlocale(LC_ALL
, "");
386 (void) textdomain(TEXT_DOMAIN
);
388 while ((c
= getopt(argc
, argv
, "adimnrspMgvxf:P:I:DRT:")) != -1) {
390 case 'a': /* all connections */
394 case 'd': /* DCE info */
396 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
399 case 'i': /* interface (ill/ipif report) */
401 IFLAGMOD(Iflag_only
, -1, 1); /* '-i' exists */
404 case 'm': /* streams msg report */
406 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
409 case 'n': /* numeric format */
413 case 'r': /* route tables */
415 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
418 case 'R': /* security attributes */
420 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
423 case 's': /* per-protocol statistics */
425 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
428 case 'p': /* arp/ndp table */
430 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
433 case 'M': /* multicast routing tables */
435 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
438 case 'g': /* multicast group membership */
440 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
443 case 'v': /* verbose output format */
445 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
448 case 'x': /* turn on debugging */
453 process_filter(optarg
);
457 if (strcmp(optarg
, "ip") == 0) {
459 } else if (strcmp(optarg
, "ipv6") == 0 ||
460 strcmp(optarg
, "ip6") == 0) {
461 v4compat
= 0; /* Overridden */
462 proto
= IPPROTO_IPV6
;
463 } else if (strcmp(optarg
, "icmp") == 0) {
464 proto
= IPPROTO_ICMP
;
465 } else if (strcmp(optarg
, "icmpv6") == 0 ||
466 strcmp(optarg
, "icmp6") == 0) {
467 v4compat
= 0; /* Overridden */
468 proto
= IPPROTO_ICMPV6
;
469 } else if (strcmp(optarg
, "igmp") == 0) {
470 proto
= IPPROTO_IGMP
;
471 } else if (strcmp(optarg
, "udp") == 0) {
473 } else if (strcmp(optarg
, "tcp") == 0) {
475 } else if (strcmp(optarg
, "sctp") == 0) {
476 proto
= IPPROTO_SCTP
;
477 } else if (strcmp(optarg
, "raw") == 0 ||
478 strcmp(optarg
, "rawip") == 0) {
481 fatal(1, "%s: unknown protocol.\n", optarg
);
488 IFLAGMOD(Iflag_only
, -1, 1); /* see macro def'n */
499 timestamp_fmt
= UDATE
;
500 else if (*optarg
== 'd')
501 timestamp_fmt
= DDATE
;
516 * Make sure -R option is set only on a labeled system.
518 if (RSECflag
&& !is_system_labeled()) {
519 (void) fprintf(stderr
, "-R set but labeling is not enabled\n");
524 * Handle other arguments: find interval, count; the
525 * flags that accept 'interval' and 'count' are OR'd
526 * in the outermost 'if'; more flags may be added as
529 if (Iflag
|| Sflag
|| Mflag
) {
530 for (d
= optind
; d
< argc
; d
++) {
531 if (isnum(argv
[d
])) {
532 interval
= atoi(argv
[d
]);
534 isnum(argv
[d
+ 1])) {
535 count
= atoi(argv
[d
+ 1]);
539 if (interval
== 0 || count
== 0)
546 if (Iflag
&& isnum(argv
[optind
])) {
547 count
= atoi(argv
[optind
]);
554 (void) fprintf(stderr
,
555 "%s: extra arguments\n", name
);
559 setbuf(stdout
, NULL
);
562 dhcp_report(Iflag
? ifname
: NULL
);
567 * Get this process's security label if the -R switch is set.
568 * We use this label as the current zone's security label.
571 zone_security_label
= m_label_alloc(MAC_LABEL
);
572 if (zone_security_label
== NULL
)
573 fatal(errno
, "m_label_alloc() failed");
574 if (getplabel(zone_security_label
) < 0)
575 fatal(errno
, "getplabel() failed");
578 /* Get data structures: priming before iteration */
579 if (family_selected(AF_INET
) || family_selected(AF_INET6
)) {
582 fatal(1, "can't open mib stream\n");
583 if ((item
= mibget(sd
)) == NULL
) {
585 fatal(1, "mibget() failed\n");
587 /* Extract constant sizes - need do once only */
588 mib_get_constants(item
);
590 if ((kc
= kstat_open()) == NULL
) {
593 fail(1, "kstat_open(): can't open /dev/kstat");
602 mib_item_t
*curritem
= NULL
; /* only for -[M]s */
604 if (timestamp_fmt
!= NODATE
)
605 print_timestamp(timestamp_fmt
);
607 /* netstat: AF_INET[6] behaviour */
608 if (family_selected(AF_INET
) || family_selected(AF_INET6
)) {
610 curritem
= mib_item_diff(previtem
, item
);
611 if (curritem
== NULL
)
612 fatal(1, "can't process mib data, "
614 mib_item_destroy(&previtem
);
617 if (!(Dflag
|| Iflag
|| Rflag
|| Sflag
|| Mflag
||
618 MMflag
|| Pflag
|| Gflag
|| DHCPflag
)) {
619 if (protocol_selected(IPPROTO_UDP
))
621 if (protocol_selected(IPPROTO_TCP
))
623 if (protocol_selected(IPPROTO_SCTP
))
627 if_report(item
, ifname
, Iflag_only
, once_only
);
632 if (Sflag
&& MMflag
) {
633 mrt_stat_report(curritem
);
636 stat_report(curritem
);
643 if (family_selected(AF_INET
))
645 if (family_selected(AF_INET6
))
650 mib_item_destroy(&curritem
);
653 /* netstat: AF_UNIX behaviour */
654 if (family_selected(AF_UNIX
) &&
655 (!(Dflag
|| Iflag
|| Rflag
|| Sflag
|| Mflag
||
656 MMflag
|| Pflag
|| Gflag
)))
658 (void) kstat_close(kc
);
660 /* iteration handling code */
661 if (count
> 0 && --count
== 0)
663 (void) sleep(interval
);
665 /* re-populating of data structures */
666 if (family_selected(AF_INET
) || family_selected(AF_INET6
)) {
668 /* previtem is a cut-down list */
669 previtem
= mib_item_dup(item
);
670 if (previtem
== NULL
)
671 fatal(1, "can't process mib data, "
676 if ((sd
= mibopen()) == -1)
677 fatal(1, "can't open mib stream anymore\n");
678 if ((item
= mibget(sd
)) == NULL
) {
680 fatal(1, "mibget() failed\n");
683 if ((kc
= kstat_open()) == NULL
)
684 fail(1, "kstat_open(): can't open /dev/kstat");
686 } /* 'for' loop 1 ends */
689 if (zone_security_label
!= NULL
)
690 m_label_free(zone_security_label
);
703 for (i
= 0; i
< len
; i
++)
710 /* --------------------------------- MIBGET -------------------------------- */
716 * buf is an automatic for this function, so the
717 * compiler has complete control over its alignment;
718 * it is assumed this alignment is satisfactory for
719 * it to be casted to certain other struct pointers
720 * here, such as struct T_optmgmt_ack * .
722 uintptr_t buf
[512 / sizeof (uintptr_t)];
725 struct strbuf ctlbuf
, databuf
;
726 struct T_optmgmt_req
*tor
= (struct T_optmgmt_req
*)buf
;
727 struct T_optmgmt_ack
*toa
= (struct T_optmgmt_ack
*)buf
;
728 struct T_error_ack
*tea
= (struct T_error_ack
*)buf
;
730 mib_item_t
*first_item
= NULL
;
731 mib_item_t
*last_item
= NULL
;
734 tor
->PRIM_type
= T_SVR4_OPTMGMT_REQ
;
735 tor
->OPT_offset
= sizeof (struct T_optmgmt_req
);
736 tor
->OPT_length
= sizeof (struct opthdr
);
737 tor
->MGMT_flags
= T_CURRENT
;
741 * Note: we use the special level value below so that IP will return
742 * us information concerning IRE_MARK_TESTHIDDEN routes.
744 req
= (struct opthdr
*)&tor
[1];
745 req
->level
= EXPER_IP_AND_ALL_IRES
;
749 ctlbuf
.buf
= (char *)buf
;
750 ctlbuf
.len
= tor
->OPT_length
+ tor
->OPT_offset
;
752 if (putmsg(sd
, &ctlbuf
, (struct strbuf
*)0, flags
) == -1) {
753 perror("mibget: putmsg(ctl) failed");
758 * Each reply consists of a ctl part for one fixed structure
759 * or table, as defined in mib2.h. The format is a T_OPTMGMT_ACK,
760 * containing an opthdr structure. level/name identify the entry,
761 * len is the size of the data part of the message.
763 req
= (struct opthdr
*)&toa
[1];
764 ctlbuf
.maxlen
= sizeof (buf
);
768 getcode
= getmsg(sd
, &ctlbuf
, (struct strbuf
*)0, &flags
);
770 perror("mibget getmsg(ctl) failed");
772 (void) fputs("# level name len\n",
775 for (last_item
= first_item
; last_item
;
776 last_item
= last_item
->next_item
)
777 (void) printf("%d %4d %5d %d\n",
786 ctlbuf
.len
>= sizeof (struct T_optmgmt_ack
) &&
787 toa
->PRIM_type
== T_OPTMGMT_ACK
&&
788 toa
->MGMT_flags
== T_SUCCESS
&&
791 (void) printf("mibget getmsg() %d returned "
792 "EOD (level %ld, name %ld)\n",
793 j
, req
->level
, req
->name
);
794 return (first_item
); /* this is EOD msg */
797 if (ctlbuf
.len
>= sizeof (struct T_error_ack
) &&
798 tea
->PRIM_type
== T_ERROR_ACK
) {
799 (void) fprintf(stderr
,
800 "mibget %d gives T_ERROR_ACK: TLI_error = 0x%lx, "
801 "UNIX_error = 0x%lx\n",
802 j
, tea
->TLI_error
, tea
->UNIX_error
);
804 errno
= (tea
->TLI_error
== TSYSERR
) ?
805 tea
->UNIX_error
: EPROTO
;
809 if (getcode
!= MOREDATA
||
810 ctlbuf
.len
< sizeof (struct T_optmgmt_ack
) ||
811 toa
->PRIM_type
!= T_OPTMGMT_ACK
||
812 toa
->MGMT_flags
!= T_SUCCESS
) {
813 (void) printf("mibget getmsg(ctl) %d returned %d, "
814 "ctlbuf.len = %d, PRIM_type = %ld\n",
815 j
, getcode
, ctlbuf
.len
, toa
->PRIM_type
);
817 if (toa
->PRIM_type
== T_OPTMGMT_ACK
)
818 (void) printf("T_OPTMGMT_ACK: "
819 "MGMT_flags = 0x%lx, req->len = %ld\n",
820 toa
->MGMT_flags
, req
->len
);
825 temp
= (mib_item_t
*)malloc(sizeof (mib_item_t
));
827 perror("mibget malloc failed");
830 if (last_item
!= NULL
)
831 last_item
->next_item
= temp
;
835 last_item
->next_item
= NULL
;
836 last_item
->group
= req
->level
;
837 last_item
->mib_id
= req
->name
;
838 last_item
->length
= req
->len
;
839 last_item
->valp
= malloc((int)req
->len
);
840 if (last_item
->valp
== NULL
)
843 (void) printf("msg %d: group = %4d mib_id = %5d"
845 j
, last_item
->group
, last_item
->mib_id
,
848 databuf
.maxlen
= last_item
->length
;
849 databuf
.buf
= (char *)last_item
->valp
;
852 getcode
= getmsg(sd
, (struct strbuf
*)0, &databuf
, &flags
);
854 perror("mibget getmsg(data) failed");
856 } else if (getcode
!= 0) {
857 (void) printf("mibget getmsg(data) returned %d, "
858 "databuf.maxlen = %d, databuf.len = %d\n",
859 getcode
, databuf
.maxlen
, databuf
.len
);
872 * mibfree: frees a linked list of type (mib_item_t *)
873 * returned by mibget(); this is NOT THE SAME AS
874 * mib_item_destroy(), so should be used for objects
875 * returned by mibget() only
878 mibfree(mib_item_t
*firstitem
)
880 mib_item_t
*lastitem
;
882 while (firstitem
!= NULL
) {
883 lastitem
= firstitem
;
884 firstitem
= firstitem
->next_item
;
885 if (lastitem
->valp
!= NULL
)
886 free(lastitem
->valp
);
896 sd
= open("/dev/arp", O_RDWR
);
901 if (ioctl(sd
, I_PUSH
, "tcp") == -1) {
902 perror("tcp I_PUSH");
906 if (ioctl(sd
, I_PUSH
, "udp") == -1) {
907 perror("udp I_PUSH");
911 if (ioctl(sd
, I_PUSH
, "icmp") == -1) {
912 perror("icmp I_PUSH");
920 * mib_item_dup: returns a clean mib_item_t * linked
921 * list, so that for every element item->mib_id is 0;
922 * to deallocate this linked list, use mib_item_destroy
925 mib_item_dup(mib_item_t
*item
)
931 for (tempp
= item
; tempp
; tempp
= tempp
->next_item
)
932 if (tempp
->mib_id
== 0)
936 localp
= (mib_item_t
*)malloc(c
* sizeof (mib_item_t
));
940 for (; item
; item
= item
->next_item
) {
941 if (item
->mib_id
== 0) {
942 /* Replicate item in localp */
943 (localp
[c
]).next_item
= NULL
;
944 (localp
[c
]).group
= item
->group
;
945 (localp
[c
]).mib_id
= item
->mib_id
;
946 (localp
[c
]).length
= item
->length
;
947 (localp
[c
]).valp
= (uintptr_t *)malloc(
949 if ((localp
[c
]).valp
== NULL
) {
950 mib_item_destroy(&localp
);
953 (void *) memcpy((localp
[c
]).valp
,
956 tempp
= &(localp
[c
]);
958 (localp
[c
- 1]).next_item
= tempp
;
966 * mib_item_diff: takes two (mib_item_t *) linked lists
967 * item1 and item2 and computes the difference between
968 * differentiable values in item2 against item1 for every
969 * given member of item2; returns an mib_item_t * linked
970 * list of diff's, or a copy of item2 if item1 is NULL;
971 * will return NULL if system out of memory; works only
972 * for item->mib_id == 0
975 mib_item_diff(mib_item_t
*item1
, mib_item_t
*item2
) {
976 int nitems
= 0; /* no. of items in item2 */
977 mib_item_t
*tempp2
; /* walking copy of item2 */
978 mib_item_t
*tempp1
; /* walking copy of item1 */
980 mib_item_t
*diffptr
; /* walking copy of diffp */
981 mib_item_t
*prevp
= NULL
;
984 diffp
= mib_item_dup(item2
);
990 tempp2
= tempp2
->next_item
) {
991 if (tempp2
->mib_id
== 0)
992 switch (tempp2
->group
) {
994 * upon adding a case here, the same
995 * must also be added in the next
996 * switch statement, alongwith
1014 diffp
= mib_item_dup(item2
);
1018 diffp
= (mib_item_t
*)calloc(nitems
, sizeof (mib_item_t
));
1023 for (tempp2
= item2
; tempp2
!= NULL
; tempp2
= tempp2
->next_item
) {
1024 if (tempp2
->mib_id
!= 0)
1025 continue; /* 'for' loop 1 */
1027 for (tempp1
= item1
; tempp1
!= NULL
;
1028 tempp1
= tempp1
->next_item
) {
1029 if (!(tempp1
->mib_id
== 0 &&
1030 tempp1
->group
== tempp2
->group
&&
1031 tempp1
->mib_id
== tempp2
->mib_id
))
1032 continue; /* 'for' loop 2 */
1033 /* found comparable data sets */
1035 prevp
->next_item
= diffptr
;
1036 switch (tempp2
->group
) {
1038 * Indenting note: Because of long variable names
1039 * in cases MIB2_IP6 and MIB2_ICMP6, their contents
1040 * have been indented by one tab space only
1043 mib2_ip_t
*i2
= (mib2_ip_t
*)tempp2
->valp
;
1044 mib2_ip_t
*i1
= (mib2_ip_t
*)tempp1
->valp
;
1047 diffptr
->group
= tempp2
->group
;
1048 diffptr
->mib_id
= tempp2
->mib_id
;
1049 diffptr
->length
= tempp2
->length
;
1050 d
= (mib2_ip_t
*)calloc(tempp2
->length
, 1);
1052 goto mibdiff_out_of_memory
;
1054 d
->ipForwarding
= i2
->ipForwarding
;
1055 d
->ipDefaultTTL
= i2
->ipDefaultTTL
;
1056 MDIFF(d
, i2
, i1
, ipInReceives
);
1057 MDIFF(d
, i2
, i1
, ipInHdrErrors
);
1058 MDIFF(d
, i2
, i1
, ipInAddrErrors
);
1059 MDIFF(d
, i2
, i1
, ipInCksumErrs
);
1060 MDIFF(d
, i2
, i1
, ipForwDatagrams
);
1061 MDIFF(d
, i2
, i1
, ipForwProhibits
);
1062 MDIFF(d
, i2
, i1
, ipInUnknownProtos
);
1063 MDIFF(d
, i2
, i1
, ipInDiscards
);
1064 MDIFF(d
, i2
, i1
, ipInDelivers
);
1065 MDIFF(d
, i2
, i1
, ipOutRequests
);
1066 MDIFF(d
, i2
, i1
, ipOutDiscards
);
1067 MDIFF(d
, i2
, i1
, ipOutNoRoutes
);
1068 MDIFF(d
, i2
, i1
, ipReasmTimeout
);
1069 MDIFF(d
, i2
, i1
, ipReasmReqds
);
1070 MDIFF(d
, i2
, i1
, ipReasmOKs
);
1071 MDIFF(d
, i2
, i1
, ipReasmFails
);
1072 MDIFF(d
, i2
, i1
, ipReasmDuplicates
);
1073 MDIFF(d
, i2
, i1
, ipReasmPartDups
);
1074 MDIFF(d
, i2
, i1
, ipFragOKs
);
1075 MDIFF(d
, i2
, i1
, ipFragFails
);
1076 MDIFF(d
, i2
, i1
, ipFragCreates
);
1077 MDIFF(d
, i2
, i1
, ipRoutingDiscards
);
1078 MDIFF(d
, i2
, i1
, tcpInErrs
);
1079 MDIFF(d
, i2
, i1
, udpNoPorts
);
1080 MDIFF(d
, i2
, i1
, udpInCksumErrs
);
1081 MDIFF(d
, i2
, i1
, udpInOverflows
);
1082 MDIFF(d
, i2
, i1
, rawipInOverflows
);
1083 MDIFF(d
, i2
, i1
, ipsecInSucceeded
);
1084 MDIFF(d
, i2
, i1
, ipsecInFailed
);
1085 MDIFF(d
, i2
, i1
, ipInIPv6
);
1086 MDIFF(d
, i2
, i1
, ipOutIPv6
);
1087 MDIFF(d
, i2
, i1
, ipOutSwitchIPv6
);
1092 mib2_ipv6IfStatsEntry_t
*i2
;
1093 mib2_ipv6IfStatsEntry_t
*i1
;
1094 mib2_ipv6IfStatsEntry_t
*d
;
1096 i2
= (mib2_ipv6IfStatsEntry_t
*)tempp2
->valp
;
1097 i1
= (mib2_ipv6IfStatsEntry_t
*)tempp1
->valp
;
1098 diffptr
->group
= tempp2
->group
;
1099 diffptr
->mib_id
= tempp2
->mib_id
;
1100 diffptr
->length
= tempp2
->length
;
1101 d
= (mib2_ipv6IfStatsEntry_t
*)calloc(
1104 goto mibdiff_out_of_memory
;
1106 d
->ipv6Forwarding
= i2
->ipv6Forwarding
;
1107 d
->ipv6DefaultHopLimit
=
1108 i2
->ipv6DefaultHopLimit
;
1110 MDIFF(d
, i2
, i1
, ipv6InReceives
);
1111 MDIFF(d
, i2
, i1
, ipv6InHdrErrors
);
1112 MDIFF(d
, i2
, i1
, ipv6InTooBigErrors
);
1113 MDIFF(d
, i2
, i1
, ipv6InNoRoutes
);
1114 MDIFF(d
, i2
, i1
, ipv6InAddrErrors
);
1115 MDIFF(d
, i2
, i1
, ipv6InUnknownProtos
);
1116 MDIFF(d
, i2
, i1
, ipv6InTruncatedPkts
);
1117 MDIFF(d
, i2
, i1
, ipv6InDiscards
);
1118 MDIFF(d
, i2
, i1
, ipv6InDelivers
);
1119 MDIFF(d
, i2
, i1
, ipv6OutForwDatagrams
);
1120 MDIFF(d
, i2
, i1
, ipv6OutRequests
);
1121 MDIFF(d
, i2
, i1
, ipv6OutDiscards
);
1122 MDIFF(d
, i2
, i1
, ipv6OutNoRoutes
);
1123 MDIFF(d
, i2
, i1
, ipv6OutFragOKs
);
1124 MDIFF(d
, i2
, i1
, ipv6OutFragFails
);
1125 MDIFF(d
, i2
, i1
, ipv6OutFragCreates
);
1126 MDIFF(d
, i2
, i1
, ipv6ReasmReqds
);
1127 MDIFF(d
, i2
, i1
, ipv6ReasmOKs
);
1128 MDIFF(d
, i2
, i1
, ipv6ReasmFails
);
1129 MDIFF(d
, i2
, i1
, ipv6InMcastPkts
);
1130 MDIFF(d
, i2
, i1
, ipv6OutMcastPkts
);
1131 MDIFF(d
, i2
, i1
, ipv6ReasmDuplicates
);
1132 MDIFF(d
, i2
, i1
, ipv6ReasmPartDups
);
1133 MDIFF(d
, i2
, i1
, ipv6ForwProhibits
);
1134 MDIFF(d
, i2
, i1
, udpInCksumErrs
);
1135 MDIFF(d
, i2
, i1
, udpInOverflows
);
1136 MDIFF(d
, i2
, i1
, rawipInOverflows
);
1137 MDIFF(d
, i2
, i1
, ipv6InIPv4
);
1138 MDIFF(d
, i2
, i1
, ipv6OutIPv4
);
1139 MDIFF(d
, i2
, i1
, ipv6OutSwitchIPv4
);
1148 m2
= (struct mrtstat
*)tempp2
->valp
;
1149 m1
= (struct mrtstat
*)tempp1
->valp
;
1150 diffptr
->group
= tempp2
->group
;
1151 diffptr
->mib_id
= tempp2
->mib_id
;
1152 diffptr
->length
= tempp2
->length
;
1153 d
= (struct mrtstat
*)calloc(tempp2
->length
, 1);
1155 goto mibdiff_out_of_memory
;
1157 MDIFF(d
, m2
, m1
, mrts_mfc_hits
);
1158 MDIFF(d
, m2
, m1
, mrts_mfc_misses
);
1159 MDIFF(d
, m2
, m1
, mrts_fwd_in
);
1160 MDIFF(d
, m2
, m1
, mrts_fwd_out
);
1161 d
->mrts_upcalls
= m2
->mrts_upcalls
;
1162 MDIFF(d
, m2
, m1
, mrts_fwd_drop
);
1163 MDIFF(d
, m2
, m1
, mrts_bad_tunnel
);
1164 MDIFF(d
, m2
, m1
, mrts_cant_tunnel
);
1165 MDIFF(d
, m2
, m1
, mrts_wrong_if
);
1166 MDIFF(d
, m2
, m1
, mrts_upq_ovflw
);
1167 MDIFF(d
, m2
, m1
, mrts_cache_cleanups
);
1168 MDIFF(d
, m2
, m1
, mrts_drop_sel
);
1169 MDIFF(d
, m2
, m1
, mrts_q_overflow
);
1170 MDIFF(d
, m2
, m1
, mrts_pkt2large
);
1171 MDIFF(d
, m2
, m1
, mrts_pim_badversion
);
1172 MDIFF(d
, m2
, m1
, mrts_pim_rcv_badcsum
);
1173 MDIFF(d
, m2
, m1
, mrts_pim_badregisters
);
1174 MDIFF(d
, m2
, m1
, mrts_pim_regforwards
);
1175 MDIFF(d
, m2
, m1
, mrts_pim_regsend_drops
);
1176 MDIFF(d
, m2
, m1
, mrts_pim_malformed
);
1177 MDIFF(d
, m2
, m1
, mrts_pim_nomemory
);
1182 struct igmpstat
*i2
;
1183 struct igmpstat
*i1
;
1186 i2
= (struct igmpstat
*)tempp2
->valp
;
1187 i1
= (struct igmpstat
*)tempp1
->valp
;
1188 diffptr
->group
= tempp2
->group
;
1189 diffptr
->mib_id
= tempp2
->mib_id
;
1190 diffptr
->length
= tempp2
->length
;
1191 d
= (struct igmpstat
*)calloc(
1194 goto mibdiff_out_of_memory
;
1196 MDIFF(d
, i2
, i1
, igps_rcv_total
);
1197 MDIFF(d
, i2
, i1
, igps_rcv_tooshort
);
1198 MDIFF(d
, i2
, i1
, igps_rcv_badsum
);
1199 MDIFF(d
, i2
, i1
, igps_rcv_queries
);
1200 MDIFF(d
, i2
, i1
, igps_rcv_badqueries
);
1201 MDIFF(d
, i2
, i1
, igps_rcv_reports
);
1202 MDIFF(d
, i2
, i1
, igps_rcv_badreports
);
1203 MDIFF(d
, i2
, i1
, igps_rcv_ourreports
);
1204 MDIFF(d
, i2
, i1
, igps_snd_reports
);
1213 i2
= (mib2_icmp_t
*)tempp2
->valp
;
1214 i1
= (mib2_icmp_t
*)tempp1
->valp
;
1215 diffptr
->group
= tempp2
->group
;
1216 diffptr
->mib_id
= tempp2
->mib_id
;
1217 diffptr
->length
= tempp2
->length
;
1218 d
= (mib2_icmp_t
*)calloc(tempp2
->length
, 1);
1220 goto mibdiff_out_of_memory
;
1222 MDIFF(d
, i2
, i1
, icmpInMsgs
);
1223 MDIFF(d
, i2
, i1
, icmpInErrors
);
1224 MDIFF(d
, i2
, i1
, icmpInCksumErrs
);
1225 MDIFF(d
, i2
, i1
, icmpInUnknowns
);
1226 MDIFF(d
, i2
, i1
, icmpInDestUnreachs
);
1227 MDIFF(d
, i2
, i1
, icmpInTimeExcds
);
1228 MDIFF(d
, i2
, i1
, icmpInParmProbs
);
1229 MDIFF(d
, i2
, i1
, icmpInSrcQuenchs
);
1230 MDIFF(d
, i2
, i1
, icmpInRedirects
);
1231 MDIFF(d
, i2
, i1
, icmpInBadRedirects
);
1232 MDIFF(d
, i2
, i1
, icmpInEchos
);
1233 MDIFF(d
, i2
, i1
, icmpInEchoReps
);
1234 MDIFF(d
, i2
, i1
, icmpInTimestamps
);
1235 MDIFF(d
, i2
, i1
, icmpInAddrMasks
);
1236 MDIFF(d
, i2
, i1
, icmpInAddrMaskReps
);
1237 MDIFF(d
, i2
, i1
, icmpInFragNeeded
);
1238 MDIFF(d
, i2
, i1
, icmpOutMsgs
);
1239 MDIFF(d
, i2
, i1
, icmpOutDrops
);
1240 MDIFF(d
, i2
, i1
, icmpOutErrors
);
1241 MDIFF(d
, i2
, i1
, icmpOutDestUnreachs
);
1242 MDIFF(d
, i2
, i1
, icmpOutTimeExcds
);
1243 MDIFF(d
, i2
, i1
, icmpOutParmProbs
);
1244 MDIFF(d
, i2
, i1
, icmpOutSrcQuenchs
);
1245 MDIFF(d
, i2
, i1
, icmpOutRedirects
);
1246 MDIFF(d
, i2
, i1
, icmpOutEchos
);
1247 MDIFF(d
, i2
, i1
, icmpOutEchoReps
);
1248 MDIFF(d
, i2
, i1
, icmpOutTimestamps
);
1249 MDIFF(d
, i2
, i1
, icmpOutTimestampReps
);
1250 MDIFF(d
, i2
, i1
, icmpOutAddrMasks
);
1251 MDIFF(d
, i2
, i1
, icmpOutAddrMaskReps
);
1252 MDIFF(d
, i2
, i1
, icmpOutFragNeeded
);
1253 MDIFF(d
, i2
, i1
, icmpInOverflows
);
1258 mib2_ipv6IfIcmpEntry_t
*i2
;
1259 mib2_ipv6IfIcmpEntry_t
*i1
;
1260 mib2_ipv6IfIcmpEntry_t
*d
;
1262 i2
= (mib2_ipv6IfIcmpEntry_t
*)tempp2
->valp
;
1263 i1
= (mib2_ipv6IfIcmpEntry_t
*)tempp1
->valp
;
1264 diffptr
->group
= tempp2
->group
;
1265 diffptr
->mib_id
= tempp2
->mib_id
;
1266 diffptr
->length
= tempp2
->length
;
1267 d
= (mib2_ipv6IfIcmpEntry_t
*)calloc(tempp2
->length
, 1);
1269 goto mibdiff_out_of_memory
;
1271 MDIFF(d
, i2
, i1
, ipv6IfIcmpInMsgs
);
1272 MDIFF(d
, i2
, i1
, ipv6IfIcmpInErrors
);
1273 MDIFF(d
, i2
, i1
, ipv6IfIcmpInDestUnreachs
);
1274 MDIFF(d
, i2
, i1
, ipv6IfIcmpInAdminProhibs
);
1275 MDIFF(d
, i2
, i1
, ipv6IfIcmpInTimeExcds
);
1276 MDIFF(d
, i2
, i1
, ipv6IfIcmpInParmProblems
);
1277 MDIFF(d
, i2
, i1
, ipv6IfIcmpInPktTooBigs
);
1278 MDIFF(d
, i2
, i1
, ipv6IfIcmpInEchos
);
1279 MDIFF(d
, i2
, i1
, ipv6IfIcmpInEchoReplies
);
1280 MDIFF(d
, i2
, i1
, ipv6IfIcmpInRouterSolicits
);
1281 MDIFF(d
, i2
, i1
, ipv6IfIcmpInRouterAdvertisements
);
1282 MDIFF(d
, i2
, i1
, ipv6IfIcmpInNeighborSolicits
);
1283 MDIFF(d
, i2
, i1
, ipv6IfIcmpInNeighborAdvertisements
);
1284 MDIFF(d
, i2
, i1
, ipv6IfIcmpInRedirects
);
1285 MDIFF(d
, i2
, i1
, ipv6IfIcmpInBadRedirects
);
1286 MDIFF(d
, i2
, i1
, ipv6IfIcmpInGroupMembQueries
);
1287 MDIFF(d
, i2
, i1
, ipv6IfIcmpInGroupMembResponses
);
1288 MDIFF(d
, i2
, i1
, ipv6IfIcmpInGroupMembReductions
);
1289 MDIFF(d
, i2
, i1
, ipv6IfIcmpInOverflows
);
1290 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutMsgs
);
1291 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutErrors
);
1292 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutDestUnreachs
);
1293 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutAdminProhibs
);
1294 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutTimeExcds
);
1295 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutParmProblems
);
1296 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutPktTooBigs
);
1297 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutEchos
);
1298 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutEchoReplies
);
1299 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutRouterSolicits
);
1300 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutRouterAdvertisements
);
1301 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutNeighborSolicits
);
1302 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutNeighborAdvertisements
);
1303 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutRedirects
);
1304 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutGroupMembQueries
);
1305 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutGroupMembResponses
);
1306 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutGroupMembReductions
);
1315 t2
= (mib2_tcp_t
*)tempp2
->valp
;
1316 t1
= (mib2_tcp_t
*)tempp1
->valp
;
1317 diffptr
->group
= tempp2
->group
;
1318 diffptr
->mib_id
= tempp2
->mib_id
;
1319 diffptr
->length
= tempp2
->length
;
1320 d
= (mib2_tcp_t
*)calloc(tempp2
->length
, 1);
1322 goto mibdiff_out_of_memory
;
1324 d
->tcpRtoMin
= t2
->tcpRtoMin
;
1325 d
->tcpRtoMax
= t2
->tcpRtoMax
;
1326 d
->tcpMaxConn
= t2
->tcpMaxConn
;
1327 MDIFF(d
, t2
, t1
, tcpActiveOpens
);
1328 MDIFF(d
, t2
, t1
, tcpPassiveOpens
);
1329 MDIFF(d
, t2
, t1
, tcpAttemptFails
);
1330 MDIFF(d
, t2
, t1
, tcpEstabResets
);
1331 d
->tcpCurrEstab
= t2
->tcpCurrEstab
;
1332 MDIFF(d
, t2
, t1
, tcpHCOutSegs
);
1333 MDIFF(d
, t2
, t1
, tcpOutDataSegs
);
1334 MDIFF(d
, t2
, t1
, tcpOutDataBytes
);
1335 MDIFF(d
, t2
, t1
, tcpRetransSegs
);
1336 MDIFF(d
, t2
, t1
, tcpRetransBytes
);
1337 MDIFF(d
, t2
, t1
, tcpOutAck
);
1338 MDIFF(d
, t2
, t1
, tcpOutAckDelayed
);
1339 MDIFF(d
, t2
, t1
, tcpOutUrg
);
1340 MDIFF(d
, t2
, t1
, tcpOutWinUpdate
);
1341 MDIFF(d
, t2
, t1
, tcpOutWinProbe
);
1342 MDIFF(d
, t2
, t1
, tcpOutControl
);
1343 MDIFF(d
, t2
, t1
, tcpOutRsts
);
1344 MDIFF(d
, t2
, t1
, tcpOutFastRetrans
);
1345 MDIFF(d
, t2
, t1
, tcpHCInSegs
);
1346 MDIFF(d
, t2
, t1
, tcpInAckSegs
);
1347 MDIFF(d
, t2
, t1
, tcpInAckBytes
);
1348 MDIFF(d
, t2
, t1
, tcpInDupAck
);
1349 MDIFF(d
, t2
, t1
, tcpInAckUnsent
);
1350 MDIFF(d
, t2
, t1
, tcpInDataInorderSegs
);
1351 MDIFF(d
, t2
, t1
, tcpInDataInorderBytes
);
1352 MDIFF(d
, t2
, t1
, tcpInDataUnorderSegs
);
1353 MDIFF(d
, t2
, t1
, tcpInDataUnorderBytes
);
1354 MDIFF(d
, t2
, t1
, tcpInDataDupSegs
);
1355 MDIFF(d
, t2
, t1
, tcpInDataDupBytes
);
1356 MDIFF(d
, t2
, t1
, tcpInDataPartDupSegs
);
1357 MDIFF(d
, t2
, t1
, tcpInDataPartDupBytes
);
1358 MDIFF(d
, t2
, t1
, tcpInDataPastWinSegs
);
1359 MDIFF(d
, t2
, t1
, tcpInDataPastWinBytes
);
1360 MDIFF(d
, t2
, t1
, tcpInWinProbe
);
1361 MDIFF(d
, t2
, t1
, tcpInWinUpdate
);
1362 MDIFF(d
, t2
, t1
, tcpInClosed
);
1363 MDIFF(d
, t2
, t1
, tcpRttNoUpdate
);
1364 MDIFF(d
, t2
, t1
, tcpRttUpdate
);
1365 MDIFF(d
, t2
, t1
, tcpTimRetrans
);
1366 MDIFF(d
, t2
, t1
, tcpTimRetransDrop
);
1367 MDIFF(d
, t2
, t1
, tcpTimKeepalive
);
1368 MDIFF(d
, t2
, t1
, tcpTimKeepaliveProbe
);
1369 MDIFF(d
, t2
, t1
, tcpTimKeepaliveDrop
);
1370 MDIFF(d
, t2
, t1
, tcpListenDrop
);
1371 MDIFF(d
, t2
, t1
, tcpListenDropQ0
);
1372 MDIFF(d
, t2
, t1
, tcpHalfOpenDrop
);
1373 MDIFF(d
, t2
, t1
, tcpOutSackRetransSegs
);
1382 u2
= (mib2_udp_t
*)tempp2
->valp
;
1383 u1
= (mib2_udp_t
*)tempp1
->valp
;
1384 diffptr
->group
= tempp2
->group
;
1385 diffptr
->mib_id
= tempp2
->mib_id
;
1386 diffptr
->length
= tempp2
->length
;
1387 d
= (mib2_udp_t
*)calloc(tempp2
->length
, 1);
1389 goto mibdiff_out_of_memory
;
1391 MDIFF(d
, u2
, u1
, udpHCInDatagrams
);
1392 MDIFF(d
, u2
, u1
, udpInErrors
);
1393 MDIFF(d
, u2
, u1
, udpHCOutDatagrams
);
1394 MDIFF(d
, u2
, u1
, udpOutErrors
);
1403 s2
= (mib2_sctp_t
*)tempp2
->valp
;
1404 s1
= (mib2_sctp_t
*)tempp1
->valp
;
1405 diffptr
->group
= tempp2
->group
;
1406 diffptr
->mib_id
= tempp2
->mib_id
;
1407 diffptr
->length
= tempp2
->length
;
1408 d
= (mib2_sctp_t
*)calloc(tempp2
->length
, 1);
1410 goto mibdiff_out_of_memory
;
1412 d
->sctpRtoAlgorithm
= s2
->sctpRtoAlgorithm
;
1413 d
->sctpRtoMin
= s2
->sctpRtoMin
;
1414 d
->sctpRtoMax
= s2
->sctpRtoMax
;
1415 d
->sctpRtoInitial
= s2
->sctpRtoInitial
;
1416 d
->sctpMaxAssocs
= s2
->sctpMaxAssocs
;
1417 d
->sctpValCookieLife
= s2
->sctpValCookieLife
;
1418 d
->sctpMaxInitRetr
= s2
->sctpMaxInitRetr
;
1419 d
->sctpCurrEstab
= s2
->sctpCurrEstab
;
1420 MDIFF(d
, s2
, s1
, sctpActiveEstab
);
1421 MDIFF(d
, s2
, s1
, sctpPassiveEstab
);
1422 MDIFF(d
, s2
, s1
, sctpAborted
);
1423 MDIFF(d
, s2
, s1
, sctpShutdowns
);
1424 MDIFF(d
, s2
, s1
, sctpOutOfBlue
);
1425 MDIFF(d
, s2
, s1
, sctpChecksumError
);
1426 MDIFF(d
, s2
, s1
, sctpOutCtrlChunks
);
1427 MDIFF(d
, s2
, s1
, sctpOutOrderChunks
);
1428 MDIFF(d
, s2
, s1
, sctpOutUnorderChunks
);
1429 MDIFF(d
, s2
, s1
, sctpRetransChunks
);
1430 MDIFF(d
, s2
, s1
, sctpOutAck
);
1431 MDIFF(d
, s2
, s1
, sctpOutAckDelayed
);
1432 MDIFF(d
, s2
, s1
, sctpOutWinUpdate
);
1433 MDIFF(d
, s2
, s1
, sctpOutFastRetrans
);
1434 MDIFF(d
, s2
, s1
, sctpOutWinProbe
);
1435 MDIFF(d
, s2
, s1
, sctpInCtrlChunks
);
1436 MDIFF(d
, s2
, s1
, sctpInOrderChunks
);
1437 MDIFF(d
, s2
, s1
, sctpInUnorderChunks
);
1438 MDIFF(d
, s2
, s1
, sctpInAck
);
1439 MDIFF(d
, s2
, s1
, sctpInDupAck
);
1440 MDIFF(d
, s2
, s1
, sctpInAckUnsent
);
1441 MDIFF(d
, s2
, s1
, sctpFragUsrMsgs
);
1442 MDIFF(d
, s2
, s1
, sctpReasmUsrMsgs
);
1443 MDIFF(d
, s2
, s1
, sctpOutSCTPPkts
);
1444 MDIFF(d
, s2
, s1
, sctpInSCTPPkts
);
1445 MDIFF(d
, s2
, s1
, sctpInInvalidCookie
);
1446 MDIFF(d
, s2
, s1
, sctpTimRetrans
);
1447 MDIFF(d
, s2
, s1
, sctpTimRetransDrop
);
1448 MDIFF(d
, s2
, s1
, sctpTimHeartBeatProbe
);
1449 MDIFF(d
, s2
, s1
, sctpTimHeartBeatDrop
);
1450 MDIFF(d
, s2
, s1
, sctpListenDrop
);
1451 MDIFF(d
, s2
, s1
, sctpInClosed
);
1460 r2
= (mib2_rawip_t
*)tempp2
->valp
;
1461 r1
= (mib2_rawip_t
*)tempp1
->valp
;
1462 diffptr
->group
= tempp2
->group
;
1463 diffptr
->mib_id
= tempp2
->mib_id
;
1464 diffptr
->length
= tempp2
->length
;
1465 d
= (mib2_rawip_t
*)calloc(tempp2
->length
, 1);
1467 goto mibdiff_out_of_memory
;
1469 MDIFF(d
, r2
, r1
, rawipInDatagrams
);
1470 MDIFF(d
, r2
, r1
, rawipInErrors
);
1471 MDIFF(d
, r2
, r1
, rawipInCksumErrs
);
1472 MDIFF(d
, r2
, r1
, rawipOutDatagrams
);
1473 MDIFF(d
, r2
, r1
, rawipOutErrors
);
1478 * there are more "group" types but they aren't
1479 * required for the -s and -Ms options
1482 } /* 'for' loop 2 ends */
1484 } /* 'for' loop 1 ends */
1487 diffptr
->next_item
= NULL
;
1490 mibdiff_out_of_memory
:;
1491 mib_item_destroy(&diffp
);
1496 * mib_item_destroy: cleans up a mib_item_t *
1497 * that was created by calling mib_item_dup or
1501 mib_item_destroy(mib_item_t
**itemp
) {
1506 if (itemp
== NULL
|| *itemp
== NULL
)
1509 for (tempp
= *itemp
; tempp
!= NULL
; tempp
= tempp
->next_item
)
1510 if (tempp
->mib_id
== 0)
1513 return; /* cannot destroy! */
1516 return; /* cannot destroy! */
1518 for (c
= nitems
- 1; c
>= 0; c
--) {
1519 if ((itemp
[0][c
]).valp
!= NULL
)
1520 free((itemp
[0][c
]).valp
);
1527 /* Compare two Octet_ts. Return B_TRUE if they match, B_FALSE if not. */
1529 octetstrmatch(const Octet_t
*a
, const Octet_t
*b
)
1531 if (a
== NULL
|| b
== NULL
)
1534 if (a
->o_length
!= b
->o_length
)
1537 return (memcmp(a
->o_bytes
, b
->o_bytes
, a
->o_length
) == 0);
1540 /* If octetstr() changes make an appropriate change to STR_EXPAND */
1542 octetstr(const Octet_t
*op
, int code
, char *dst
, uint_t dstlen
)
1549 for (i
= 0; i
< op
->o_length
; i
++) {
1552 if (cp
- dst
+ 4 > dstlen
) {
1556 (void) snprintf(cp
, 5, "%d.",
1557 0xff & op
->o_bytes
[i
]);
1558 cp
= strchr(cp
, '\0');
1561 if (cp
- dst
+ 1 > dstlen
) {
1565 *cp
++ = op
->o_bytes
[i
];
1569 if (cp
- dst
+ 3 > dstlen
) {
1573 (void) snprintf(cp
, 4, "%02x:",
1574 0xff & op
->o_bytes
[i
]);
1580 if (code
!= 'a' && cp
!= dst
)
1587 mitcp_state(int state
, const mib2_transportMLPEntry_t
*attr
)
1589 static char tcpsbuf
[50];
1611 case TCPS_ESTABLISHED
:
1614 case TCPS_CLOSE_WAIT
:
1617 case TCPS_FIN_WAIT_1
:
1626 case TCPS_FIN_WAIT_2
:
1629 case TCPS_TIME_WAIT
:
1633 (void) snprintf(tcpsbuf
, sizeof (tcpsbuf
),
1634 "UnknownState(%d)", state
);
1639 if (RSECflag
&& attr
!= NULL
&& attr
->tme_flags
!= 0) {
1640 if (cp
!= tcpsbuf
) {
1641 (void) strlcpy(tcpsbuf
, cp
, sizeof (tcpsbuf
));
1644 if (attr
->tme_flags
& MIB2_TMEF_PRIVATE
)
1645 (void) strlcat(tcpsbuf
, " P", sizeof (tcpsbuf
));
1646 if (attr
->tme_flags
& MIB2_TMEF_SHARED
)
1647 (void) strlcat(tcpsbuf
, " S", sizeof (tcpsbuf
));
1654 miudp_state(int state
, const mib2_transportMLPEntry_t
*attr
)
1656 static char udpsbuf
[50];
1660 case MIB2_UDP_unbound
:
1666 case MIB2_UDP_connected
:
1670 (void) snprintf(udpsbuf
, sizeof (udpsbuf
),
1671 "Unknown State(%d)", state
);
1676 if (RSECflag
&& attr
!= NULL
&& attr
->tme_flags
!= 0) {
1677 if (cp
!= udpsbuf
) {
1678 (void) strlcpy(udpsbuf
, cp
, sizeof (udpsbuf
));
1681 if (attr
->tme_flags
& MIB2_TMEF_PRIVATE
)
1682 (void) strlcat(udpsbuf
, " P", sizeof (udpsbuf
));
1683 if (attr
->tme_flags
& MIB2_TMEF_SHARED
)
1684 (void) strlcat(udpsbuf
, " S", sizeof (udpsbuf
));
1699 prval(char *str
, Counter val
)
1701 (void) printf("\t%-20s=%6u", str
, val
);
1703 (void) putchar('\n');
1707 prval64(char *str
, Counter64 val
)
1709 (void) printf("\t%-20s=%6llu", str
, val
);
1711 (void) putchar('\n');
1715 pr_int_val(char *str
, int val
)
1717 (void) printf("\t%-20s=%6d", str
, val
);
1719 (void) putchar('\n');
1723 pr_sctp_rtoalgo(char *str
, int val
)
1725 (void) printf("\t%-20s=", str
);
1727 case MIB2_SCTP_RTOALGO_OTHER
:
1728 (void) printf("%6.6s", "other");
1731 case MIB2_SCTP_RTOALGO_VANJ
:
1732 (void) printf("%6.6s", "vanj");
1736 (void) printf("%6d", val
);
1740 (void) putchar('\n');
1747 (void) putchar('\n');
1750 /* Extract constant sizes */
1752 mib_get_constants(mib_item_t
*item
)
1755 for (; item
; item
= item
->next_item
) {
1756 if (item
->mib_id
!= 0)
1757 continue; /* 'for' loop 1 */
1759 switch (item
->group
) {
1761 mib2_ip_t
*ip
= (mib2_ip_t
*)item
->valp
;
1763 ipAddrEntrySize
= ip
->ipAddrEntrySize
;
1764 ipRouteEntrySize
= ip
->ipRouteEntrySize
;
1765 ipNetToMediaEntrySize
= ip
->ipNetToMediaEntrySize
;
1766 ipMemberEntrySize
= ip
->ipMemberEntrySize
;
1767 ipGroupSourceEntrySize
= ip
->ipGroupSourceEntrySize
;
1768 ipRouteAttributeSize
= ip
->ipRouteAttributeSize
;
1769 transportMLPSize
= ip
->transportMLPSize
;
1770 ipDestEntrySize
= ip
->ipDestEntrySize
;
1771 assert(IS_P2ALIGNED(ipAddrEntrySize
,
1772 sizeof (mib2_ipAddrEntry_t
*)));
1773 assert(IS_P2ALIGNED(ipRouteEntrySize
,
1774 sizeof (mib2_ipRouteEntry_t
*)));
1775 assert(IS_P2ALIGNED(ipNetToMediaEntrySize
,
1776 sizeof (mib2_ipNetToMediaEntry_t
*)));
1777 assert(IS_P2ALIGNED(ipMemberEntrySize
,
1778 sizeof (ip_member_t
*)));
1779 assert(IS_P2ALIGNED(ipGroupSourceEntrySize
,
1780 sizeof (ip_grpsrc_t
*)));
1781 assert(IS_P2ALIGNED(ipRouteAttributeSize
,
1782 sizeof (mib2_ipAttributeEntry_t
*)));
1783 assert(IS_P2ALIGNED(transportMLPSize
,
1784 sizeof (mib2_transportMLPEntry_t
*)));
1788 struct mrtstat
*mrts
= (struct mrtstat
*)item
->valp
;
1790 vifctlSize
= mrts
->mrts_vifctlSize
;
1791 mfcctlSize
= mrts
->mrts_mfcctlSize
;
1792 assert(IS_P2ALIGNED(vifctlSize
,
1793 sizeof (struct vifclt
*)));
1794 assert(IS_P2ALIGNED(mfcctlSize
,
1795 sizeof (struct mfcctl
*)));
1799 mib2_ipv6IfStatsEntry_t
*ip6
;
1800 /* Just use the first entry */
1802 ip6
= (mib2_ipv6IfStatsEntry_t
*)item
->valp
;
1803 ipv6IfStatsEntrySize
= ip6
->ipv6IfStatsEntrySize
;
1804 ipv6AddrEntrySize
= ip6
->ipv6AddrEntrySize
;
1805 ipv6RouteEntrySize
= ip6
->ipv6RouteEntrySize
;
1806 ipv6NetToMediaEntrySize
= ip6
->ipv6NetToMediaEntrySize
;
1807 ipv6MemberEntrySize
= ip6
->ipv6MemberEntrySize
;
1808 ipv6GroupSourceEntrySize
=
1809 ip6
->ipv6GroupSourceEntrySize
;
1810 assert(IS_P2ALIGNED(ipv6IfStatsEntrySize
,
1811 sizeof (mib2_ipv6IfStatsEntry_t
*)));
1812 assert(IS_P2ALIGNED(ipv6AddrEntrySize
,
1813 sizeof (mib2_ipv6AddrEntry_t
*)));
1814 assert(IS_P2ALIGNED(ipv6RouteEntrySize
,
1815 sizeof (mib2_ipv6RouteEntry_t
*)));
1816 assert(IS_P2ALIGNED(ipv6NetToMediaEntrySize
,
1817 sizeof (mib2_ipv6NetToMediaEntry_t
*)));
1818 assert(IS_P2ALIGNED(ipv6MemberEntrySize
,
1819 sizeof (ipv6_member_t
*)));
1820 assert(IS_P2ALIGNED(ipv6GroupSourceEntrySize
,
1821 sizeof (ipv6_grpsrc_t
*)));
1825 mib2_ipv6IfIcmpEntry_t
*icmp6
;
1826 /* Just use the first entry */
1828 icmp6
= (mib2_ipv6IfIcmpEntry_t
*)item
->valp
;
1829 ipv6IfIcmpEntrySize
= icmp6
->ipv6IfIcmpEntrySize
;
1830 assert(IS_P2ALIGNED(ipv6IfIcmpEntrySize
,
1831 sizeof (mib2_ipv6IfIcmpEntry_t
*)));
1835 mib2_tcp_t
*tcp
= (mib2_tcp_t
*)item
->valp
;
1837 tcpConnEntrySize
= tcp
->tcpConnTableSize
;
1838 tcp6ConnEntrySize
= tcp
->tcp6ConnTableSize
;
1839 assert(IS_P2ALIGNED(tcpConnEntrySize
,
1840 sizeof (mib2_tcpConnEntry_t
*)));
1841 assert(IS_P2ALIGNED(tcp6ConnEntrySize
,
1842 sizeof (mib2_tcp6ConnEntry_t
*)));
1846 mib2_udp_t
*udp
= (mib2_udp_t
*)item
->valp
;
1848 udpEntrySize
= udp
->udpEntrySize
;
1849 udp6EntrySize
= udp
->udp6EntrySize
;
1850 assert(IS_P2ALIGNED(udpEntrySize
,
1851 sizeof (mib2_udpEntry_t
*)));
1852 assert(IS_P2ALIGNED(udp6EntrySize
,
1853 sizeof (mib2_udp6Entry_t
*)));
1857 mib2_sctp_t
*sctp
= (mib2_sctp_t
*)item
->valp
;
1859 sctpEntrySize
= sctp
->sctpEntrySize
;
1860 sctpLocalEntrySize
= sctp
->sctpLocalEntrySize
;
1861 sctpRemoteEntrySize
= sctp
->sctpRemoteEntrySize
;
1865 } /* 'for' loop 1 ends */
1868 (void) puts("mib_get_constants:");
1869 (void) printf("\tipv6IfStatsEntrySize %d\n",
1870 ipv6IfStatsEntrySize
);
1871 (void) printf("\tipAddrEntrySize %d\n", ipAddrEntrySize
);
1872 (void) printf("\tipRouteEntrySize %d\n", ipRouteEntrySize
);
1873 (void) printf("\tipNetToMediaEntrySize %d\n",
1874 ipNetToMediaEntrySize
);
1875 (void) printf("\tipMemberEntrySize %d\n", ipMemberEntrySize
);
1876 (void) printf("\tipRouteAttributeSize %d\n",
1877 ipRouteAttributeSize
);
1878 (void) printf("\tvifctlSize %d\n", vifctlSize
);
1879 (void) printf("\tmfcctlSize %d\n", mfcctlSize
);
1881 (void) printf("\tipv6AddrEntrySize %d\n", ipv6AddrEntrySize
);
1882 (void) printf("\tipv6RouteEntrySize %d\n", ipv6RouteEntrySize
);
1883 (void) printf("\tipv6NetToMediaEntrySize %d\n",
1884 ipv6NetToMediaEntrySize
);
1885 (void) printf("\tipv6MemberEntrySize %d\n",
1886 ipv6MemberEntrySize
);
1887 (void) printf("\tipv6IfIcmpEntrySize %d\n",
1888 ipv6IfIcmpEntrySize
);
1889 (void) printf("\tipDestEntrySize %d\n", ipDestEntrySize
);
1890 (void) printf("\ttransportMLPSize %d\n", transportMLPSize
);
1891 (void) printf("\ttcpConnEntrySize %d\n", tcpConnEntrySize
);
1892 (void) printf("\ttcp6ConnEntrySize %d\n", tcp6ConnEntrySize
);
1893 (void) printf("\tudpEntrySize %d\n", udpEntrySize
);
1894 (void) printf("\tudp6EntrySize %d\n", udp6EntrySize
);
1895 (void) printf("\tsctpEntrySize %d\n", sctpEntrySize
);
1896 (void) printf("\tsctpLocalEntrySize %d\n", sctpLocalEntrySize
);
1897 (void) printf("\tsctpRemoteEntrySize %d\n",
1898 sctpRemoteEntrySize
);
1903 /* ----------------------------- STAT_REPORT ------------------------------- */
1906 stat_report(mib_item_t
*item
)
1909 char ifname
[LIFNAMSIZ
+ 1];
1912 for (; item
; item
= item
->next_item
) {
1914 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
1915 (void) printf("Group = %d, mib_id = %d, "
1916 "length = %d, valp = 0x%p\n",
1917 item
->group
, item
->mib_id
,
1918 item
->length
, item
->valp
);
1920 if (item
->mib_id
!= 0)
1921 continue; /* 'for' loop 1 */
1923 switch (item
->group
) {
1925 mib2_ip_t
*ip
= (mib2_ip_t
*)item
->valp
;
1927 if (protocol_selected(IPPROTO_IP
) &&
1928 family_selected(AF_INET
)) {
1929 (void) fputs(v4compat
? "\nIP" : "\nIPv4",
1937 (mib2_icmp_t
*)item
->valp
;
1939 if (protocol_selected(IPPROTO_ICMP
) &&
1940 family_selected(AF_INET
)) {
1941 (void) fputs(v4compat
? "\nICMP" : "\nICMPv4",
1943 print_icmp_stats(icmp
);
1948 mib2_ipv6IfStatsEntry_t
*ip6
;
1949 mib2_ipv6IfStatsEntry_t sum6
;
1951 if (!(protocol_selected(IPPROTO_IPV6
)) ||
1952 !(family_selected(AF_INET6
)))
1954 bzero(&sum6
, sizeof (sum6
));
1955 /* 'for' loop 2a: */
1956 for (ip6
= (mib2_ipv6IfStatsEntry_t
*)item
->valp
;
1957 (char *)ip6
< (char *)item
->valp
+ item
->length
;
1958 /* LINTED: (note 1) */
1959 ip6
= (mib2_ipv6IfStatsEntry_t
*)((char *)ip6
+
1960 ipv6IfStatsEntrySize
)) {
1961 if (ip6
->ipv6IfIndex
== 0) {
1963 * The "unknown interface" ip6
1964 * mib. Just add to the sum.
1966 sum_ip6_stats(ip6
, &sum6
);
1967 continue; /* 'for' loop 2a */
1970 (void) printf("\nIPv6 for %s\n",
1971 ifindex2str(ip6
->ipv6IfIndex
,
1973 print_ip6_stats(ip6
);
1975 sum_ip6_stats(ip6
, &sum6
);
1976 } /* 'for' loop 2a ends */
1977 (void) fputs("\nIPv6", stdout
);
1978 print_ip6_stats(&sum6
);
1982 mib2_ipv6IfIcmpEntry_t
*icmp6
;
1983 mib2_ipv6IfIcmpEntry_t sum6
;
1985 if (!(protocol_selected(IPPROTO_ICMPV6
)) ||
1986 !(family_selected(AF_INET6
)))
1988 bzero(&sum6
, sizeof (sum6
));
1989 /* 'for' loop 2b: */
1990 for (icmp6
= (mib2_ipv6IfIcmpEntry_t
*)item
->valp
;
1991 (char *)icmp6
< (char *)item
->valp
+ item
->length
;
1992 icmp6
= (void *)((char *)icmp6
+
1993 ipv6IfIcmpEntrySize
)) {
1994 if (icmp6
->ipv6IfIcmpIfIndex
== 0) {
1996 * The "unknown interface" icmp6
1997 * mib. Just add to the sum.
1999 sum_icmp6_stats(icmp6
, &sum6
);
2000 continue; /* 'for' loop 2b: */
2003 (void) printf("\nICMPv6 for %s\n",
2005 icmp6
->ipv6IfIcmpIfIndex
, ifname
));
2006 print_icmp6_stats(icmp6
);
2008 sum_icmp6_stats(icmp6
, &sum6
);
2009 } /* 'for' loop 2b ends */
2010 (void) fputs("\nICMPv6", stdout
);
2011 print_icmp6_stats(&sum6
);
2015 mib2_tcp_t
*tcp
= (mib2_tcp_t
*)item
->valp
;
2017 if (protocol_selected(IPPROTO_TCP
) &&
2018 (family_selected(AF_INET
) ||
2019 family_selected(AF_INET6
))) {
2020 (void) fputs("\nTCP", stdout
);
2021 print_tcp_stats(tcp
);
2026 mib2_udp_t
*udp
= (mib2_udp_t
*)item
->valp
;
2028 if (protocol_selected(IPPROTO_UDP
) &&
2029 (family_selected(AF_INET
) ||
2030 family_selected(AF_INET6
))) {
2031 (void) fputs("\nUDP", stdout
);
2032 print_udp_stats(udp
);
2037 mib2_sctp_t
*sctp
= (mib2_sctp_t
*)item
->valp
;
2039 if (protocol_selected(IPPROTO_SCTP
) &&
2040 (family_selected(AF_INET
) ||
2041 family_selected(AF_INET6
))) {
2042 (void) fputs("\nSCTP", stdout
);
2043 print_sctp_stats(sctp
);
2048 mib2_rawip_t
*rawip
=
2049 (mib2_rawip_t
*)item
->valp
;
2051 if (protocol_selected(IPPROTO_RAW
) &&
2052 (family_selected(AF_INET
) ||
2053 family_selected(AF_INET6
))) {
2054 (void) fputs("\nRAWIP", stdout
);
2055 print_rawip_stats(rawip
);
2060 struct igmpstat
*igps
=
2061 (struct igmpstat
*)item
->valp
;
2063 if (protocol_selected(IPPROTO_IGMP
) &&
2064 (family_selected(AF_INET
))) {
2065 (void) fputs("\nIGMP:\n", stdout
);
2066 print_igmp_stats(igps
);
2071 } /* 'for' loop 1 ends */
2072 (void) putchar('\n');
2073 (void) fflush(stdout
);
2077 print_ip_stats(mib2_ip_t
*ip
)
2080 pr_int_val("ipForwarding", ip
->ipForwarding
);
2081 pr_int_val("ipDefaultTTL", ip
->ipDefaultTTL
);
2082 prval("ipInReceives", ip
->ipInReceives
);
2083 prval("ipInHdrErrors", ip
->ipInHdrErrors
);
2084 prval("ipInAddrErrors", ip
->ipInAddrErrors
);
2085 prval("ipInCksumErrs", ip
->ipInCksumErrs
);
2086 prval("ipForwDatagrams", ip
->ipForwDatagrams
);
2087 prval("ipForwProhibits", ip
->ipForwProhibits
);
2088 prval("ipInUnknownProtos", ip
->ipInUnknownProtos
);
2089 prval("ipInDiscards", ip
->ipInDiscards
);
2090 prval("ipInDelivers", ip
->ipInDelivers
);
2091 prval("ipOutRequests", ip
->ipOutRequests
);
2092 prval("ipOutDiscards", ip
->ipOutDiscards
);
2093 prval("ipOutNoRoutes", ip
->ipOutNoRoutes
);
2094 pr_int_val("ipReasmTimeout", ip
->ipReasmTimeout
);
2095 prval("ipReasmReqds", ip
->ipReasmReqds
);
2096 prval("ipReasmOKs", ip
->ipReasmOKs
);
2097 prval("ipReasmFails", ip
->ipReasmFails
);
2098 prval("ipReasmDuplicates", ip
->ipReasmDuplicates
);
2099 prval("ipReasmPartDups", ip
->ipReasmPartDups
);
2100 prval("ipFragOKs", ip
->ipFragOKs
);
2101 prval("ipFragFails", ip
->ipFragFails
);
2102 prval("ipFragCreates", ip
->ipFragCreates
);
2103 prval("ipRoutingDiscards", ip
->ipRoutingDiscards
);
2105 prval("tcpInErrs", ip
->tcpInErrs
);
2106 prval("udpNoPorts", ip
->udpNoPorts
);
2107 prval("udpInCksumErrs", ip
->udpInCksumErrs
);
2108 prval("udpInOverflows", ip
->udpInOverflows
);
2109 prval("rawipInOverflows", ip
->rawipInOverflows
);
2110 prval("ipsecInSucceeded", ip
->ipsecInSucceeded
);
2111 prval("ipsecInFailed", ip
->ipsecInFailed
);
2112 prval("ipInIPv6", ip
->ipInIPv6
);
2113 prval("ipOutIPv6", ip
->ipOutIPv6
);
2114 prval("ipOutSwitchIPv6", ip
->ipOutSwitchIPv6
);
2119 print_icmp_stats(mib2_icmp_t
*icmp
)
2122 prval("icmpInMsgs", icmp
->icmpInMsgs
);
2123 prval("icmpInErrors", icmp
->icmpInErrors
);
2124 prval("icmpInCksumErrs", icmp
->icmpInCksumErrs
);
2125 prval("icmpInUnknowns", icmp
->icmpInUnknowns
);
2126 prval("icmpInDestUnreachs", icmp
->icmpInDestUnreachs
);
2127 prval("icmpInTimeExcds", icmp
->icmpInTimeExcds
);
2128 prval("icmpInParmProbs", icmp
->icmpInParmProbs
);
2129 prval("icmpInSrcQuenchs", icmp
->icmpInSrcQuenchs
);
2130 prval("icmpInRedirects", icmp
->icmpInRedirects
);
2131 prval("icmpInBadRedirects", icmp
->icmpInBadRedirects
);
2132 prval("icmpInEchos", icmp
->icmpInEchos
);
2133 prval("icmpInEchoReps", icmp
->icmpInEchoReps
);
2134 prval("icmpInTimestamps", icmp
->icmpInTimestamps
);
2135 prval("icmpInTimestampReps", icmp
->icmpInTimestampReps
);
2136 prval("icmpInAddrMasks", icmp
->icmpInAddrMasks
);
2137 prval("icmpInAddrMaskReps", icmp
->icmpInAddrMaskReps
);
2138 prval("icmpInFragNeeded", icmp
->icmpInFragNeeded
);
2139 prval("icmpOutMsgs", icmp
->icmpOutMsgs
);
2140 prval("icmpOutDrops", icmp
->icmpOutDrops
);
2141 prval("icmpOutErrors", icmp
->icmpOutErrors
);
2142 prval("icmpOutDestUnreachs", icmp
->icmpOutDestUnreachs
);
2143 prval("icmpOutTimeExcds", icmp
->icmpOutTimeExcds
);
2144 prval("icmpOutParmProbs", icmp
->icmpOutParmProbs
);
2145 prval("icmpOutSrcQuenchs", icmp
->icmpOutSrcQuenchs
);
2146 prval("icmpOutRedirects", icmp
->icmpOutRedirects
);
2147 prval("icmpOutEchos", icmp
->icmpOutEchos
);
2148 prval("icmpOutEchoReps", icmp
->icmpOutEchoReps
);
2149 prval("icmpOutTimestamps", icmp
->icmpOutTimestamps
);
2150 prval("icmpOutTimestampReps", icmp
->icmpOutTimestampReps
);
2151 prval("icmpOutAddrMasks", icmp
->icmpOutAddrMasks
);
2152 prval("icmpOutAddrMaskReps", icmp
->icmpOutAddrMaskReps
);
2153 prval("icmpOutFragNeeded", icmp
->icmpOutFragNeeded
);
2154 prval("icmpInOverflows", icmp
->icmpInOverflows
);
2159 print_ip6_stats(mib2_ipv6IfStatsEntry_t
*ip6
)
2162 prval("ipv6Forwarding", ip6
->ipv6Forwarding
);
2163 prval("ipv6DefaultHopLimit", ip6
->ipv6DefaultHopLimit
);
2165 prval("ipv6InReceives", ip6
->ipv6InReceives
);
2166 prval("ipv6InHdrErrors", ip6
->ipv6InHdrErrors
);
2167 prval("ipv6InTooBigErrors", ip6
->ipv6InTooBigErrors
);
2168 prval("ipv6InNoRoutes", ip6
->ipv6InNoRoutes
);
2169 prval("ipv6InAddrErrors", ip6
->ipv6InAddrErrors
);
2170 prval("ipv6InUnknownProtos", ip6
->ipv6InUnknownProtos
);
2171 prval("ipv6InTruncatedPkts", ip6
->ipv6InTruncatedPkts
);
2172 prval("ipv6InDiscards", ip6
->ipv6InDiscards
);
2173 prval("ipv6InDelivers", ip6
->ipv6InDelivers
);
2174 prval("ipv6OutForwDatagrams", ip6
->ipv6OutForwDatagrams
);
2175 prval("ipv6OutRequests", ip6
->ipv6OutRequests
);
2176 prval("ipv6OutDiscards", ip6
->ipv6OutDiscards
);
2177 prval("ipv6OutNoRoutes", ip6
->ipv6OutNoRoutes
);
2178 prval("ipv6OutFragOKs", ip6
->ipv6OutFragOKs
);
2179 prval("ipv6OutFragFails", ip6
->ipv6OutFragFails
);
2180 prval("ipv6OutFragCreates", ip6
->ipv6OutFragCreates
);
2181 prval("ipv6ReasmReqds", ip6
->ipv6ReasmReqds
);
2182 prval("ipv6ReasmOKs", ip6
->ipv6ReasmOKs
);
2183 prval("ipv6ReasmFails", ip6
->ipv6ReasmFails
);
2184 prval("ipv6InMcastPkts", ip6
->ipv6InMcastPkts
);
2185 prval("ipv6OutMcastPkts", ip6
->ipv6OutMcastPkts
);
2186 prval("ipv6ReasmDuplicates", ip6
->ipv6ReasmDuplicates
);
2187 prval("ipv6ReasmPartDups", ip6
->ipv6ReasmPartDups
);
2188 prval("ipv6ForwProhibits", ip6
->ipv6ForwProhibits
);
2189 prval("udpInCksumErrs", ip6
->udpInCksumErrs
);
2190 prval("udpInOverflows", ip6
->udpInOverflows
);
2191 prval("rawipInOverflows", ip6
->rawipInOverflows
);
2192 prval("ipv6InIPv4", ip6
->ipv6InIPv4
);
2193 prval("ipv6OutIPv4", ip6
->ipv6OutIPv4
);
2194 prval("ipv6OutSwitchIPv4", ip6
->ipv6OutSwitchIPv4
);
2199 print_icmp6_stats(mib2_ipv6IfIcmpEntry_t
*icmp6
)
2202 prval("icmp6InMsgs", icmp6
->ipv6IfIcmpInMsgs
);
2203 prval("icmp6InErrors", icmp6
->ipv6IfIcmpInErrors
);
2204 prval("icmp6InDestUnreachs", icmp6
->ipv6IfIcmpInDestUnreachs
);
2205 prval("icmp6InAdminProhibs", icmp6
->ipv6IfIcmpInAdminProhibs
);
2206 prval("icmp6InTimeExcds", icmp6
->ipv6IfIcmpInTimeExcds
);
2207 prval("icmp6InParmProblems", icmp6
->ipv6IfIcmpInParmProblems
);
2208 prval("icmp6InPktTooBigs", icmp6
->ipv6IfIcmpInPktTooBigs
);
2209 prval("icmp6InEchos", icmp6
->ipv6IfIcmpInEchos
);
2210 prval("icmp6InEchoReplies", icmp6
->ipv6IfIcmpInEchoReplies
);
2211 prval("icmp6InRouterSols", icmp6
->ipv6IfIcmpInRouterSolicits
);
2212 prval("icmp6InRouterAds",
2213 icmp6
->ipv6IfIcmpInRouterAdvertisements
);
2214 prval("icmp6InNeighborSols", icmp6
->ipv6IfIcmpInNeighborSolicits
);
2215 prval("icmp6InNeighborAds",
2216 icmp6
->ipv6IfIcmpInNeighborAdvertisements
);
2217 prval("icmp6InRedirects", icmp6
->ipv6IfIcmpInRedirects
);
2218 prval("icmp6InBadRedirects", icmp6
->ipv6IfIcmpInBadRedirects
);
2219 prval("icmp6InGroupQueries", icmp6
->ipv6IfIcmpInGroupMembQueries
);
2220 prval("icmp6InGroupResps", icmp6
->ipv6IfIcmpInGroupMembResponses
);
2221 prval("icmp6InGroupReds", icmp6
->ipv6IfIcmpInGroupMembReductions
);
2222 prval("icmp6InOverflows", icmp6
->ipv6IfIcmpInOverflows
);
2225 prval("icmp6OutMsgs", icmp6
->ipv6IfIcmpOutMsgs
);
2226 prval("icmp6OutErrors", icmp6
->ipv6IfIcmpOutErrors
);
2227 prval("icmp6OutDestUnreachs", icmp6
->ipv6IfIcmpOutDestUnreachs
);
2228 prval("icmp6OutAdminProhibs", icmp6
->ipv6IfIcmpOutAdminProhibs
);
2229 prval("icmp6OutTimeExcds", icmp6
->ipv6IfIcmpOutTimeExcds
);
2230 prval("icmp6OutParmProblems", icmp6
->ipv6IfIcmpOutParmProblems
);
2231 prval("icmp6OutPktTooBigs", icmp6
->ipv6IfIcmpOutPktTooBigs
);
2232 prval("icmp6OutEchos", icmp6
->ipv6IfIcmpOutEchos
);
2233 prval("icmp6OutEchoReplies", icmp6
->ipv6IfIcmpOutEchoReplies
);
2234 prval("icmp6OutRouterSols", icmp6
->ipv6IfIcmpOutRouterSolicits
);
2235 prval("icmp6OutRouterAds",
2236 icmp6
->ipv6IfIcmpOutRouterAdvertisements
);
2237 prval("icmp6OutNeighborSols", icmp6
->ipv6IfIcmpOutNeighborSolicits
);
2238 prval("icmp6OutNeighborAds",
2239 icmp6
->ipv6IfIcmpOutNeighborAdvertisements
);
2240 prval("icmp6OutRedirects", icmp6
->ipv6IfIcmpOutRedirects
);
2241 prval("icmp6OutGroupQueries", icmp6
->ipv6IfIcmpOutGroupMembQueries
);
2242 prval("icmp6OutGroupResps",
2243 icmp6
->ipv6IfIcmpOutGroupMembResponses
);
2244 prval("icmp6OutGroupReds",
2245 icmp6
->ipv6IfIcmpOutGroupMembReductions
);
2250 print_sctp_stats(mib2_sctp_t
*sctp
)
2253 pr_sctp_rtoalgo("sctpRtoAlgorithm", sctp
->sctpRtoAlgorithm
);
2254 prval("sctpRtoMin", sctp
->sctpRtoMin
);
2255 prval("sctpRtoMax", sctp
->sctpRtoMax
);
2256 prval("sctpRtoInitial", sctp
->sctpRtoInitial
);
2257 pr_int_val("sctpMaxAssocs", sctp
->sctpMaxAssocs
);
2258 prval("sctpValCookieLife", sctp
->sctpValCookieLife
);
2259 prval("sctpMaxInitRetr", sctp
->sctpMaxInitRetr
);
2260 prval("sctpCurrEstab", sctp
->sctpCurrEstab
);
2261 prval("sctpActiveEstab", sctp
->sctpActiveEstab
);
2262 prval("sctpPassiveEstab", sctp
->sctpPassiveEstab
);
2263 prval("sctpAborted", sctp
->sctpAborted
);
2264 prval("sctpShutdowns", sctp
->sctpShutdowns
);
2265 prval("sctpOutOfBlue", sctp
->sctpOutOfBlue
);
2266 prval("sctpChecksumError", sctp
->sctpChecksumError
);
2267 prval64("sctpOutCtrlChunks", sctp
->sctpOutCtrlChunks
);
2268 prval64("sctpOutOrderChunks", sctp
->sctpOutOrderChunks
);
2269 prval64("sctpOutUnorderChunks", sctp
->sctpOutUnorderChunks
);
2270 prval64("sctpRetransChunks", sctp
->sctpRetransChunks
);
2271 prval("sctpOutAck", sctp
->sctpOutAck
);
2272 prval("sctpOutAckDelayed", sctp
->sctpOutAckDelayed
);
2273 prval("sctpOutWinUpdate", sctp
->sctpOutWinUpdate
);
2274 prval("sctpOutFastRetrans", sctp
->sctpOutFastRetrans
);
2275 prval("sctpOutWinProbe", sctp
->sctpOutWinProbe
);
2276 prval64("sctpInCtrlChunks", sctp
->sctpInCtrlChunks
);
2277 prval64("sctpInOrderChunks", sctp
->sctpInOrderChunks
);
2278 prval64("sctpInUnorderChunks", sctp
->sctpInUnorderChunks
);
2279 prval("sctpInAck", sctp
->sctpInAck
);
2280 prval("sctpInDupAck", sctp
->sctpInDupAck
);
2281 prval("sctpInAckUnsent", sctp
->sctpInAckUnsent
);
2282 prval64("sctpFragUsrMsgs", sctp
->sctpFragUsrMsgs
);
2283 prval64("sctpReasmUsrMsgs", sctp
->sctpReasmUsrMsgs
);
2284 prval64("sctpOutSCTPPkts", sctp
->sctpOutSCTPPkts
);
2285 prval64("sctpInSCTPPkts", sctp
->sctpInSCTPPkts
);
2286 prval("sctpInInvalidCookie", sctp
->sctpInInvalidCookie
);
2287 prval("sctpTimRetrans", sctp
->sctpTimRetrans
);
2288 prval("sctpTimRetransDrop", sctp
->sctpTimRetransDrop
);
2289 prval("sctpTimHearBeatProbe", sctp
->sctpTimHeartBeatProbe
);
2290 prval("sctpTimHearBeatDrop", sctp
->sctpTimHeartBeatDrop
);
2291 prval("sctpListenDrop", sctp
->sctpListenDrop
);
2292 prval("sctpInClosed", sctp
->sctpInClosed
);
2297 print_tcp_stats(mib2_tcp_t
*tcp
)
2300 pr_int_val("tcpRtoAlgorithm", tcp
->tcpRtoAlgorithm
);
2301 pr_int_val("tcpRtoMin", tcp
->tcpRtoMin
);
2302 pr_int_val("tcpRtoMax", tcp
->tcpRtoMax
);
2303 pr_int_val("tcpMaxConn", tcp
->tcpMaxConn
);
2304 prval("tcpActiveOpens", tcp
->tcpActiveOpens
);
2305 prval("tcpPassiveOpens", tcp
->tcpPassiveOpens
);
2306 prval("tcpAttemptFails", tcp
->tcpAttemptFails
);
2307 prval("tcpEstabResets", tcp
->tcpEstabResets
);
2308 prval("tcpCurrEstab", tcp
->tcpCurrEstab
);
2309 prval64("tcpOutSegs", tcp
->tcpHCOutSegs
);
2310 prval("tcpOutDataSegs", tcp
->tcpOutDataSegs
);
2311 prval("tcpOutDataBytes", tcp
->tcpOutDataBytes
);
2312 prval("tcpRetransSegs", tcp
->tcpRetransSegs
);
2313 prval("tcpRetransBytes", tcp
->tcpRetransBytes
);
2314 prval("tcpOutAck", tcp
->tcpOutAck
);
2315 prval("tcpOutAckDelayed", tcp
->tcpOutAckDelayed
);
2316 prval("tcpOutUrg", tcp
->tcpOutUrg
);
2317 prval("tcpOutWinUpdate", tcp
->tcpOutWinUpdate
);
2318 prval("tcpOutWinProbe", tcp
->tcpOutWinProbe
);
2319 prval("tcpOutControl", tcp
->tcpOutControl
);
2320 prval("tcpOutRsts", tcp
->tcpOutRsts
);
2321 prval("tcpOutFastRetrans", tcp
->tcpOutFastRetrans
);
2322 prval64("tcpInSegs", tcp
->tcpHCInSegs
);
2324 prval("tcpInAckSegs", tcp
->tcpInAckSegs
);
2325 prval("tcpInAckBytes", tcp
->tcpInAckBytes
);
2326 prval("tcpInDupAck", tcp
->tcpInDupAck
);
2327 prval("tcpInAckUnsent", tcp
->tcpInAckUnsent
);
2328 prval("tcpInInorderSegs", tcp
->tcpInDataInorderSegs
);
2329 prval("tcpInInorderBytes", tcp
->tcpInDataInorderBytes
);
2330 prval("tcpInUnorderSegs", tcp
->tcpInDataUnorderSegs
);
2331 prval("tcpInUnorderBytes", tcp
->tcpInDataUnorderBytes
);
2332 prval("tcpInDupSegs", tcp
->tcpInDataDupSegs
);
2333 prval("tcpInDupBytes", tcp
->tcpInDataDupBytes
);
2334 prval("tcpInPartDupSegs", tcp
->tcpInDataPartDupSegs
);
2335 prval("tcpInPartDupBytes", tcp
->tcpInDataPartDupBytes
);
2336 prval("tcpInPastWinSegs", tcp
->tcpInDataPastWinSegs
);
2337 prval("tcpInPastWinBytes", tcp
->tcpInDataPastWinBytes
);
2338 prval("tcpInWinProbe", tcp
->tcpInWinProbe
);
2339 prval("tcpInWinUpdate", tcp
->tcpInWinUpdate
);
2340 prval("tcpInClosed", tcp
->tcpInClosed
);
2341 prval("tcpRttNoUpdate", tcp
->tcpRttNoUpdate
);
2342 prval("tcpRttUpdate", tcp
->tcpRttUpdate
);
2343 prval("tcpTimRetrans", tcp
->tcpTimRetrans
);
2344 prval("tcpTimRetransDrop", tcp
->tcpTimRetransDrop
);
2345 prval("tcpTimKeepalive", tcp
->tcpTimKeepalive
);
2346 prval("tcpTimKeepaliveProbe", tcp
->tcpTimKeepaliveProbe
);
2347 prval("tcpTimKeepaliveDrop", tcp
->tcpTimKeepaliveDrop
);
2348 prval("tcpListenDrop", tcp
->tcpListenDrop
);
2349 prval("tcpListenDropQ0", tcp
->tcpListenDropQ0
);
2350 prval("tcpHalfOpenDrop", tcp
->tcpHalfOpenDrop
);
2351 prval("tcpOutSackRetrans", tcp
->tcpOutSackRetransSegs
);
2357 print_udp_stats(mib2_udp_t
*udp
)
2360 prval64("udpInDatagrams", udp
->udpHCInDatagrams
);
2361 prval("udpInErrors", udp
->udpInErrors
);
2362 prval64("udpOutDatagrams", udp
->udpHCOutDatagrams
);
2363 prval("udpOutErrors", udp
->udpOutErrors
);
2368 print_rawip_stats(mib2_rawip_t
*rawip
)
2371 prval("rawipInDatagrams", rawip
->rawipInDatagrams
);
2372 prval("rawipInErrors", rawip
->rawipInErrors
);
2373 prval("rawipInCksumErrs", rawip
->rawipInCksumErrs
);
2374 prval("rawipOutDatagrams", rawip
->rawipOutDatagrams
);
2375 prval("rawipOutErrors", rawip
->rawipOutErrors
);
2380 print_igmp_stats(struct igmpstat
*igps
)
2382 (void) printf(" %10u message%s received\n",
2383 igps
->igps_rcv_total
, PLURAL(igps
->igps_rcv_total
));
2384 (void) printf(" %10u message%s received with too few bytes\n",
2385 igps
->igps_rcv_tooshort
, PLURAL(igps
->igps_rcv_tooshort
));
2386 (void) printf(" %10u message%s received with bad checksum\n",
2387 igps
->igps_rcv_badsum
, PLURAL(igps
->igps_rcv_badsum
));
2388 (void) printf(" %10u membership quer%s received\n",
2389 igps
->igps_rcv_queries
, PLURALY(igps
->igps_rcv_queries
));
2390 (void) printf(" %10u membership quer%s received with invalid "
2392 igps
->igps_rcv_badqueries
, PLURALY(igps
->igps_rcv_badqueries
));
2393 (void) printf(" %10u membership report%s received\n",
2394 igps
->igps_rcv_reports
, PLURAL(igps
->igps_rcv_reports
));
2395 (void) printf(" %10u membership report%s received with invalid "
2397 igps
->igps_rcv_badreports
, PLURAL(igps
->igps_rcv_badreports
));
2398 (void) printf(" %10u membership report%s received for groups to "
2399 "which we belong\n",
2400 igps
->igps_rcv_ourreports
, PLURAL(igps
->igps_rcv_ourreports
));
2401 (void) printf(" %10u membership report%s sent\n",
2402 igps
->igps_snd_reports
, PLURAL(igps
->igps_snd_reports
));
2406 print_mrt_stats(struct mrtstat
*mrts
)
2408 (void) puts("DVMRP multicast routing:");
2409 (void) printf(" %10u hit%s - kernel forwarding cache hits\n",
2410 mrts
->mrts_mfc_hits
, PLURAL(mrts
->mrts_mfc_hits
));
2411 (void) printf(" %10u miss%s - kernel forwarding cache misses\n",
2412 mrts
->mrts_mfc_misses
, PLURALES(mrts
->mrts_mfc_misses
));
2413 (void) printf(" %10u packet%s potentially forwarded\n",
2414 mrts
->mrts_fwd_in
, PLURAL(mrts
->mrts_fwd_in
));
2415 (void) printf(" %10u packet%s actually sent out\n",
2416 mrts
->mrts_fwd_out
, PLURAL(mrts
->mrts_fwd_out
));
2417 (void) printf(" %10u upcall%s - upcalls made to mrouted\n",
2418 mrts
->mrts_upcalls
, PLURAL(mrts
->mrts_upcalls
));
2419 (void) printf(" %10u packet%s not sent out due to lack of resources\n",
2420 mrts
->mrts_fwd_drop
, PLURAL(mrts
->mrts_fwd_drop
));
2421 (void) printf(" %10u datagram%s with malformed tunnel options\n",
2422 mrts
->mrts_bad_tunnel
, PLURAL(mrts
->mrts_bad_tunnel
));
2423 (void) printf(" %10u datagram%s with no room for tunnel options\n",
2424 mrts
->mrts_cant_tunnel
, PLURAL(mrts
->mrts_cant_tunnel
));
2425 (void) printf(" %10u datagram%s arrived on wrong interface\n",
2426 mrts
->mrts_wrong_if
, PLURAL(mrts
->mrts_wrong_if
));
2427 (void) printf(" %10u datagram%s dropped due to upcall Q overflow\n",
2428 mrts
->mrts_upq_ovflw
, PLURAL(mrts
->mrts_upq_ovflw
));
2429 (void) printf(" %10u datagram%s cleaned up by the cache\n",
2430 mrts
->mrts_cache_cleanups
, PLURAL(mrts
->mrts_cache_cleanups
));
2431 (void) printf(" %10u datagram%s dropped selectively by ratelimiter\n",
2432 mrts
->mrts_drop_sel
, PLURAL(mrts
->mrts_drop_sel
));
2433 (void) printf(" %10u datagram%s dropped - bucket Q overflow\n",
2434 mrts
->mrts_q_overflow
, PLURAL(mrts
->mrts_q_overflow
));
2435 (void) printf(" %10u datagram%s dropped - larger than bkt size\n",
2436 mrts
->mrts_pkt2large
, PLURAL(mrts
->mrts_pkt2large
));
2437 (void) printf("\nPIM multicast routing:\n");
2438 (void) printf(" %10u datagram%s dropped - bad version number\n",
2439 mrts
->mrts_pim_badversion
, PLURAL(mrts
->mrts_pim_badversion
));
2440 (void) printf(" %10u datagram%s dropped - bad checksum\n",
2441 mrts
->mrts_pim_rcv_badcsum
, PLURAL(mrts
->mrts_pim_rcv_badcsum
));
2442 (void) printf(" %10u datagram%s dropped - bad register packets\n",
2443 mrts
->mrts_pim_badregisters
, PLURAL(mrts
->mrts_pim_badregisters
));
2445 " %10u datagram%s potentially forwarded - register packets\n",
2446 mrts
->mrts_pim_regforwards
, PLURAL(mrts
->mrts_pim_regforwards
));
2447 (void) printf(" %10u datagram%s dropped - register send drops\n",
2448 mrts
->mrts_pim_regsend_drops
, PLURAL(mrts
->mrts_pim_regsend_drops
));
2449 (void) printf(" %10u datagram%s dropped - packet malformed\n",
2450 mrts
->mrts_pim_malformed
, PLURAL(mrts
->mrts_pim_malformed
));
2451 (void) printf(" %10u datagram%s dropped - no memory to forward\n",
2452 mrts
->mrts_pim_nomemory
, PLURAL(mrts
->mrts_pim_nomemory
));
2456 sum_ip6_stats(mib2_ipv6IfStatsEntry_t
*ip6
, mib2_ipv6IfStatsEntry_t
*sum6
)
2458 /* First few are not additive */
2459 sum6
->ipv6Forwarding
= ip6
->ipv6Forwarding
;
2460 sum6
->ipv6DefaultHopLimit
= ip6
->ipv6DefaultHopLimit
;
2462 sum6
->ipv6InReceives
+= ip6
->ipv6InReceives
;
2463 sum6
->ipv6InHdrErrors
+= ip6
->ipv6InHdrErrors
;
2464 sum6
->ipv6InTooBigErrors
+= ip6
->ipv6InTooBigErrors
;
2465 sum6
->ipv6InNoRoutes
+= ip6
->ipv6InNoRoutes
;
2466 sum6
->ipv6InAddrErrors
+= ip6
->ipv6InAddrErrors
;
2467 sum6
->ipv6InUnknownProtos
+= ip6
->ipv6InUnknownProtos
;
2468 sum6
->ipv6InTruncatedPkts
+= ip6
->ipv6InTruncatedPkts
;
2469 sum6
->ipv6InDiscards
+= ip6
->ipv6InDiscards
;
2470 sum6
->ipv6InDelivers
+= ip6
->ipv6InDelivers
;
2471 sum6
->ipv6OutForwDatagrams
+= ip6
->ipv6OutForwDatagrams
;
2472 sum6
->ipv6OutRequests
+= ip6
->ipv6OutRequests
;
2473 sum6
->ipv6OutDiscards
+= ip6
->ipv6OutDiscards
;
2474 sum6
->ipv6OutFragOKs
+= ip6
->ipv6OutFragOKs
;
2475 sum6
->ipv6OutFragFails
+= ip6
->ipv6OutFragFails
;
2476 sum6
->ipv6OutFragCreates
+= ip6
->ipv6OutFragCreates
;
2477 sum6
->ipv6ReasmReqds
+= ip6
->ipv6ReasmReqds
;
2478 sum6
->ipv6ReasmOKs
+= ip6
->ipv6ReasmOKs
;
2479 sum6
->ipv6ReasmFails
+= ip6
->ipv6ReasmFails
;
2480 sum6
->ipv6InMcastPkts
+= ip6
->ipv6InMcastPkts
;
2481 sum6
->ipv6OutMcastPkts
+= ip6
->ipv6OutMcastPkts
;
2482 sum6
->ipv6OutNoRoutes
+= ip6
->ipv6OutNoRoutes
;
2483 sum6
->ipv6ReasmDuplicates
+= ip6
->ipv6ReasmDuplicates
;
2484 sum6
->ipv6ReasmPartDups
+= ip6
->ipv6ReasmPartDups
;
2485 sum6
->ipv6ForwProhibits
+= ip6
->ipv6ForwProhibits
;
2486 sum6
->udpInCksumErrs
+= ip6
->udpInCksumErrs
;
2487 sum6
->udpInOverflows
+= ip6
->udpInOverflows
;
2488 sum6
->rawipInOverflows
+= ip6
->rawipInOverflows
;
2492 sum_icmp6_stats(mib2_ipv6IfIcmpEntry_t
*icmp6
, mib2_ipv6IfIcmpEntry_t
*sum6
)
2494 sum6
->ipv6IfIcmpInMsgs
+= icmp6
->ipv6IfIcmpInMsgs
;
2495 sum6
->ipv6IfIcmpInErrors
+= icmp6
->ipv6IfIcmpInErrors
;
2496 sum6
->ipv6IfIcmpInDestUnreachs
+= icmp6
->ipv6IfIcmpInDestUnreachs
;
2497 sum6
->ipv6IfIcmpInAdminProhibs
+= icmp6
->ipv6IfIcmpInAdminProhibs
;
2498 sum6
->ipv6IfIcmpInTimeExcds
+= icmp6
->ipv6IfIcmpInTimeExcds
;
2499 sum6
->ipv6IfIcmpInParmProblems
+= icmp6
->ipv6IfIcmpInParmProblems
;
2500 sum6
->ipv6IfIcmpInPktTooBigs
+= icmp6
->ipv6IfIcmpInPktTooBigs
;
2501 sum6
->ipv6IfIcmpInEchos
+= icmp6
->ipv6IfIcmpInEchos
;
2502 sum6
->ipv6IfIcmpInEchoReplies
+= icmp6
->ipv6IfIcmpInEchoReplies
;
2503 sum6
->ipv6IfIcmpInRouterSolicits
+= icmp6
->ipv6IfIcmpInRouterSolicits
;
2504 sum6
->ipv6IfIcmpInRouterAdvertisements
+=
2505 icmp6
->ipv6IfIcmpInRouterAdvertisements
;
2506 sum6
->ipv6IfIcmpInNeighborSolicits
+=
2507 icmp6
->ipv6IfIcmpInNeighborSolicits
;
2508 sum6
->ipv6IfIcmpInNeighborAdvertisements
+=
2509 icmp6
->ipv6IfIcmpInNeighborAdvertisements
;
2510 sum6
->ipv6IfIcmpInRedirects
+= icmp6
->ipv6IfIcmpInRedirects
;
2511 sum6
->ipv6IfIcmpInGroupMembQueries
+=
2512 icmp6
->ipv6IfIcmpInGroupMembQueries
;
2513 sum6
->ipv6IfIcmpInGroupMembResponses
+=
2514 icmp6
->ipv6IfIcmpInGroupMembResponses
;
2515 sum6
->ipv6IfIcmpInGroupMembReductions
+=
2516 icmp6
->ipv6IfIcmpInGroupMembReductions
;
2517 sum6
->ipv6IfIcmpOutMsgs
+= icmp6
->ipv6IfIcmpOutMsgs
;
2518 sum6
->ipv6IfIcmpOutErrors
+= icmp6
->ipv6IfIcmpOutErrors
;
2519 sum6
->ipv6IfIcmpOutDestUnreachs
+= icmp6
->ipv6IfIcmpOutDestUnreachs
;
2520 sum6
->ipv6IfIcmpOutAdminProhibs
+= icmp6
->ipv6IfIcmpOutAdminProhibs
;
2521 sum6
->ipv6IfIcmpOutTimeExcds
+= icmp6
->ipv6IfIcmpOutTimeExcds
;
2522 sum6
->ipv6IfIcmpOutParmProblems
+= icmp6
->ipv6IfIcmpOutParmProblems
;
2523 sum6
->ipv6IfIcmpOutPktTooBigs
+= icmp6
->ipv6IfIcmpOutPktTooBigs
;
2524 sum6
->ipv6IfIcmpOutEchos
+= icmp6
->ipv6IfIcmpOutEchos
;
2525 sum6
->ipv6IfIcmpOutEchoReplies
+= icmp6
->ipv6IfIcmpOutEchoReplies
;
2526 sum6
->ipv6IfIcmpOutRouterSolicits
+=
2527 icmp6
->ipv6IfIcmpOutRouterSolicits
;
2528 sum6
->ipv6IfIcmpOutRouterAdvertisements
+=
2529 icmp6
->ipv6IfIcmpOutRouterAdvertisements
;
2530 sum6
->ipv6IfIcmpOutNeighborSolicits
+=
2531 icmp6
->ipv6IfIcmpOutNeighborSolicits
;
2532 sum6
->ipv6IfIcmpOutNeighborAdvertisements
+=
2533 icmp6
->ipv6IfIcmpOutNeighborAdvertisements
;
2534 sum6
->ipv6IfIcmpOutRedirects
+= icmp6
->ipv6IfIcmpOutRedirects
;
2535 sum6
->ipv6IfIcmpOutGroupMembQueries
+=
2536 icmp6
->ipv6IfIcmpOutGroupMembQueries
;
2537 sum6
->ipv6IfIcmpOutGroupMembResponses
+=
2538 icmp6
->ipv6IfIcmpOutGroupMembResponses
;
2539 sum6
->ipv6IfIcmpOutGroupMembReductions
+=
2540 icmp6
->ipv6IfIcmpOutGroupMembReductions
;
2541 sum6
->ipv6IfIcmpInOverflows
+= icmp6
->ipv6IfIcmpInOverflows
;
2544 /* ----------------------------- MRT_STAT_REPORT --------------------------- */
2547 mrt_stat_report(mib_item_t
*curritem
)
2550 mib_item_t
*tempitem
;
2552 if (!(family_selected(AF_INET
)))
2555 (void) putchar('\n');
2557 for (tempitem
= curritem
;
2559 tempitem
= tempitem
->next_item
) {
2561 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
2562 (void) printf("Group = %d, mib_id = %d, "
2563 "length = %d, valp = 0x%p\n",
2564 tempitem
->group
, tempitem
->mib_id
,
2565 tempitem
->length
, tempitem
->valp
);
2568 if (tempitem
->mib_id
== 0) {
2569 switch (tempitem
->group
) {
2571 struct mrtstat
*mrts
;
2572 mrts
= (struct mrtstat
*)tempitem
->valp
;
2574 if (!(family_selected(AF_INET
)))
2575 continue; /* 'for' loop 1 */
2577 print_mrt_stats(mrts
);
2582 } /* 'for' loop 1 ends */
2583 (void) putchar('\n');
2584 (void) fflush(stdout
);
2588 * if_stat_total() - Computes totals for interface statistics
2589 * and returns result by updating sumstats.
2592 if_stat_total(struct ifstat
*oldstats
, struct ifstat
*newstats
,
2593 struct ifstat
*sumstats
)
2595 sumstats
->ipackets
+= newstats
->ipackets
- oldstats
->ipackets
;
2596 sumstats
->opackets
+= newstats
->opackets
- oldstats
->opackets
;
2597 sumstats
->ierrors
+= newstats
->ierrors
- oldstats
->ierrors
;
2598 sumstats
->oerrors
+= newstats
->oerrors
- oldstats
->oerrors
;
2599 sumstats
->collisions
+= newstats
->collisions
- oldstats
->collisions
;
2602 /* --------------------- IF_REPORT (netstat -i) -------------------------- */
2604 static struct ifstat zerostat
= {
2605 0LL, 0LL, 0LL, 0LL, 0LL
2609 if_report(mib_item_t
*item
, char *matchname
,
2610 int Iflag_only
, boolean_t once_only
)
2612 static boolean_t reentry
= B_FALSE
;
2613 boolean_t alreadydone
= B_FALSE
;
2615 uint32_t ifindex_v4
= 0;
2616 uint32_t ifindex_v6
= 0;
2617 boolean_t first_header
= B_TRUE
;
2620 for (; item
; item
= item
->next_item
) {
2622 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
2623 (void) printf("Group = %d, mib_id = %d, "
2624 "length = %d, valp = 0x%p\n",
2625 item
->group
, item
->mib_id
, item
->length
,
2629 switch (item
->group
) {
2631 if (item
->mib_id
!= MIB2_IP_ADDR
||
2632 !family_selected(AF_INET
))
2633 continue; /* 'for' loop 1 */
2635 static struct ifstat old
= {0L, 0L, 0L, 0L, 0L};
2636 static struct ifstat
new = {0L, 0L, 0L, 0L, 0L};
2638 struct iflist
*newlist
= NULL
;
2639 static struct iflist
*oldlist
= NULL
;
2643 char ifname
[LIFNAMSIZ
+ 1];
2644 char logintname
[LIFNAMSIZ
+ 1];
2645 mib2_ipAddrEntry_t
*ap
;
2646 struct ifstat stat
= {0L, 0L, 0L, 0L, 0L};
2647 boolean_t first
= B_TRUE
;
2648 uint32_t new_ifindex
;
2651 (void) printf("if_report: %d items\n",
2653 / sizeof (mib2_ipAddrEntry_t
));
2655 /* 'for' loop 2a: */
2656 for (ap
= (mib2_ipAddrEntry_t
*)item
->valp
;
2657 (char *)ap
< (char *)item
->valp
2660 (void) octetstr(&ap
->ipAdEntIfIndex
,
2662 sizeof (logintname
));
2663 (void) strcpy(ifname
, logintname
);
2664 (void) strtok(ifname
, ":");
2665 if (matchname
!= NULL
&&
2666 strcmp(matchname
, ifname
) != 0 &&
2667 strcmp(matchname
, logintname
) != 0)
2668 continue; /* 'for' loop 2a */
2670 if_nametoindex(logintname
);
2672 * First lookup the "link" kstats in
2673 * case the link is renamed. Then
2674 * fallback to the legacy kstats for
2675 * those non-GLDv3 links.
2677 if (new_ifindex
!= ifindex_v4
&&
2678 (((ksp
= kstat_lookup(kc
, "link", 0,
2679 ifname
)) != NULL
) ||
2680 ((ksp
= kstat_lookup(kc
, NULL
, -1,
2681 ifname
)) != NULL
))) {
2682 (void) safe_kstat_read(kc
, ksp
,
2685 kstat_named_value(ksp
,
2688 kstat_named_value(ksp
,
2691 kstat_named_value(ksp
,
2694 kstat_named_value(ksp
,
2697 kstat_named_value(ksp
,
2701 (void) putchar('\n');
2702 first_header
= B_FALSE
;
2704 "%-5.5s %-5.5s%-13.13s "
2705 "%-14.14s %-6.6s %-5.5s "
2706 "%-6.6s %-5.5s %-6.6s "
2708 "Name", "Mtu", "Net/Dest",
2710 "Ierrs", "Opkts", "Oerrs",
2715 if_report_ip4(ap
, ifname
,
2716 logintname
, &stat
, B_TRUE
);
2717 ifindex_v4
= new_ifindex
;
2719 if_report_ip4(ap
, ifname
,
2720 logintname
, &stat
, B_FALSE
);
2722 } /* 'for' loop 2a ends */
2723 } else if (!alreadydone
) {
2724 char ifname
[LIFNAMSIZ
+ 1];
2725 char buf
[LIFNAMSIZ
+ 1];
2726 mib2_ipAddrEntry_t
*ap
;
2728 struct iflist
*tlp
= NULL
;
2729 struct iflist
**nextnew
= &newlist
;
2730 struct iflist
*walkold
;
2731 struct iflist
*cleanlist
;
2732 boolean_t found_if
= B_FALSE
;
2734 alreadydone
= B_TRUE
; /* ignore other case */
2737 * Check if there is anything to do.
2740 sizeof (mib2_ipAddrEntry_t
)) {
2741 fail(0, "No compatible interfaces");
2745 * 'for' loop 2b: find the "right" entry:
2746 * If an interface name to match has been
2747 * supplied then try and find it, otherwise
2748 * match the first non-loopback interface found.
2749 * Use lo0 if all else fails.
2751 for (ap
= (mib2_ipAddrEntry_t
*)item
->valp
;
2752 (char *)ap
< (char *)item
->valp
2755 (void) octetstr(&ap
->ipAdEntIfIndex
,
2756 'a', ifname
, sizeof (ifname
));
2757 (void) strtok(ifname
, ":");
2760 if (strcmp(matchname
,
2766 } else if (strcmp(ifname
, "lo0") != 0)
2767 break; /* 'for' loop 2b */
2768 } /* 'for' loop 2b ends */
2770 if (matchname
== NULL
) {
2774 fail(0, "-I: %s no such "
2775 "interface.", matchname
);
2778 if (Iflag_only
== 0 || !reentry
) {
2779 (void) printf(" input %-6.6s "
2782 (void) printf(" input (Total) "
2784 (void) printf("%-7.7s %-5.5s %-7.7s "
2786 "packets", "errs", "packets",
2788 (void) printf("%-7.7s %-5.5s %-7.7s "
2790 "packets", "errs", "packets",
2796 /* 'for' loop 2c: */
2797 for (ap
= (mib2_ipAddrEntry_t
*)item
->valp
;
2798 (char *)ap
< (char *)item
->valp
2801 (void) octetstr(&ap
->ipAdEntIfIndex
,
2802 'a', buf
, sizeof (buf
));
2803 (void) strtok(buf
, ":");
2806 * We have reduced the IP interface
2807 * name, which could have been a
2808 * logical, down to a name suitable
2809 * for use with kstats.
2810 * We treat this name as unique and
2811 * only collate statistics for it once
2812 * per pass. This is to avoid falsely
2813 * amplifying these statistics by the
2814 * the number of logical instances.
2816 if ((tlp
!= NULL
) &&
2817 ((strcmp(buf
, tlp
->ifname
) == 0))) {
2822 * First lookup the "link" kstats in
2823 * case the link is renamed. Then
2824 * fallback to the legacy kstats for
2825 * those non-GLDv3 links.
2827 if (((ksp
= kstat_lookup(kc
, "link",
2829 (ksp
= kstat_lookup(kc
, NULL
, -1,
2830 buf
)) != NULL
) && (ksp
->ks_type
==
2831 KSTAT_TYPE_NAMED
)) {
2832 (void) safe_kstat_read(kc
, ksp
,
2836 t
.ipackets
= kstat_named_value(ksp
,
2838 t
.ierrors
= kstat_named_value(ksp
,
2840 t
.opackets
= kstat_named_value(ksp
,
2842 t
.oerrors
= kstat_named_value(ksp
,
2844 t
.collisions
= kstat_named_value(ksp
,
2847 if (strcmp(buf
, matchname
) == 0)
2850 /* Build the interface list */
2852 tlp
= malloc(sizeof (struct iflist
));
2853 (void) strlcpy(tlp
->ifname
, buf
,
2854 sizeof (tlp
->ifname
));
2857 nextnew
= &tlp
->next_if
;
2860 * First time through.
2861 * Just add up the interface stats.
2864 if (oldlist
== NULL
) {
2865 if_stat_total(&zerostat
,
2871 * Walk old list for the interface.
2873 * If found, add difference to total.
2875 * If not, an interface has been plumbed
2876 * up. In this case, we will simply
2877 * ignore the new interface until the
2878 * next interval; as there's no easy way
2879 * to acquire statistics between time
2880 * of the plumb and the next interval
2881 * boundary. This results in inaccurate
2882 * total values for current interval.
2884 * Note the case when an interface is
2885 * unplumbed; as similar problems exist.
2886 * The unplumbed interface is not in the
2887 * current list, and there's no easy way
2888 * to account for the statistics between
2889 * the previous interval and time of the
2890 * unplumb. Therefore, we (in a sense)
2891 * ignore the removed interface by only
2892 * involving "current" interfaces when
2893 * computing the total statistics.
2894 * Unfortunately, this also results in
2895 * inaccurate values for interval total.
2898 for (walkold
= oldlist
;
2900 walkold
= walkold
->next_if
) {
2901 if (strcmp(walkold
->ifname
,
2910 } /* 'for' loop 2c ends */
2914 (void) printf("%-7llu %-5llu %-7llu "
2916 new.ipackets
- old
.ipackets
,
2917 new.ierrors
- old
.ierrors
,
2918 new.opackets
- old
.opackets
,
2919 new.oerrors
- old
.oerrors
,
2920 new.collisions
- old
.collisions
);
2922 (void) printf("%-7llu %-5llu %-7llu "
2923 "%-5llu %-6llu\n", sum
.ipackets
,
2924 sum
.ierrors
, sum
.opackets
,
2925 sum
.oerrors
, sum
.collisions
);
2928 * Tidy things up once finished.
2932 cleanlist
= oldlist
;
2934 while (cleanlist
!= NULL
) {
2935 tlp
= cleanlist
->next_if
;
2943 if (item
->mib_id
!= MIB2_IP6_ADDR
||
2944 !family_selected(AF_INET6
))
2945 continue; /* 'for' loop 1 */
2947 static struct ifstat old6
= {0L, 0L, 0L, 0L, 0L};
2948 static struct ifstat new6
= {0L, 0L, 0L, 0L, 0L};
2950 struct iflist
*newlist6
= NULL
;
2951 static struct iflist
*oldlist6
= NULL
;
2955 char ifname
[LIFNAMSIZ
+ 1];
2956 char logintname
[LIFNAMSIZ
+ 1];
2957 mib2_ipv6AddrEntry_t
*ap6
;
2958 struct ifstat stat
= {0L, 0L, 0L, 0L, 0L};
2959 boolean_t first
= B_TRUE
;
2960 uint32_t new_ifindex
;
2963 (void) printf("if_report: %d items\n",
2965 / sizeof (mib2_ipv6AddrEntry_t
));
2966 /* 'for' loop 2d: */
2967 for (ap6
= (mib2_ipv6AddrEntry_t
*)item
->valp
;
2968 (char *)ap6
< (char *)item
->valp
2971 (void) octetstr(&ap6
->ipv6AddrIfIndex
,
2973 sizeof (logintname
));
2974 (void) strcpy(ifname
, logintname
);
2975 (void) strtok(ifname
, ":");
2976 if (matchname
!= NULL
&&
2977 strcmp(matchname
, ifname
) != 0 &&
2978 strcmp(matchname
, logintname
) != 0)
2979 continue; /* 'for' loop 2d */
2981 if_nametoindex(logintname
);
2984 * First lookup the "link" kstats in
2985 * case the link is renamed. Then
2986 * fallback to the legacy kstats for
2987 * those non-GLDv3 links.
2989 if (new_ifindex
!= ifindex_v6
&&
2990 ((ksp
= kstat_lookup(kc
, "link", 0,
2992 (ksp
= kstat_lookup(kc
, NULL
, -1,
2993 ifname
)) != NULL
)) {
2994 (void) safe_kstat_read(kc
, ksp
,
2997 kstat_named_value(ksp
,
3000 kstat_named_value(ksp
,
3003 kstat_named_value(ksp
,
3006 kstat_named_value(ksp
,
3009 kstat_named_value(ksp
,
3013 (void) putchar('\n');
3014 first_header
= B_FALSE
;
3028 if_report_ip6(ap6
, ifname
,
3029 logintname
, &stat
, B_TRUE
);
3030 ifindex_v6
= new_ifindex
;
3032 if_report_ip6(ap6
, ifname
,
3033 logintname
, &stat
, B_FALSE
);
3035 } /* 'for' loop 2d ends */
3036 } else if (!alreadydone
) {
3037 char ifname
[LIFNAMSIZ
+ 1];
3038 char buf
[IFNAMSIZ
+ 1];
3039 mib2_ipv6AddrEntry_t
*ap6
;
3041 struct iflist
*tlp
= NULL
;
3042 struct iflist
**nextnew
= &newlist6
;
3043 struct iflist
*walkold
;
3044 struct iflist
*cleanlist
;
3045 boolean_t found_if
= B_FALSE
;
3047 alreadydone
= B_TRUE
; /* ignore other case */
3050 * Check if there is anything to do.
3053 sizeof (mib2_ipv6AddrEntry_t
)) {
3054 fail(0, "No compatible interfaces");
3058 * 'for' loop 2e: find the "right" entry:
3059 * If an interface name to match has been
3060 * supplied then try and find it, otherwise
3061 * match the first non-loopback interface found.
3062 * Use lo0 if all else fails.
3064 for (ap6
= (mib2_ipv6AddrEntry_t
*)item
->valp
;
3065 (char *)ap6
< (char *)item
->valp
3068 (void) octetstr(&ap6
->ipv6AddrIfIndex
,
3069 'a', ifname
, sizeof (ifname
));
3070 (void) strtok(ifname
, ":");
3073 if (strcmp(matchname
,
3079 } else if (strcmp(ifname
, "lo0") != 0)
3080 break; /* 'for' loop 2e */
3081 } /* 'for' loop 2e ends */
3083 if (matchname
== NULL
) {
3087 fail(0, "-I: %s no such "
3088 "interface.", matchname
);
3091 if (Iflag_only
== 0 || !reentry
) {
3096 (void) printf(" input (Total)"
3098 (void) printf("%-7.7s %-5.5s %-7.7s "
3100 "packets", "errs", "packets",
3102 (void) printf("%-7.7s %-5.5s %-7.7s "
3104 "packets", "errs", "packets",
3110 /* 'for' loop 2f: */
3111 for (ap6
= (mib2_ipv6AddrEntry_t
*)item
->valp
;
3112 (char *)ap6
< (char *)item
->valp
3115 (void) octetstr(&ap6
->ipv6AddrIfIndex
,
3116 'a', buf
, sizeof (buf
));
3117 (void) strtok(buf
, ":");
3120 * We have reduced the IP interface
3121 * name, which could have been a
3122 * logical, down to a name suitable
3123 * for use with kstats.
3124 * We treat this name as unique and
3125 * only collate statistics for it once
3126 * per pass. This is to avoid falsely
3127 * amplifying these statistics by the
3128 * the number of logical instances.
3131 if ((tlp
!= NULL
) &&
3132 ((strcmp(buf
, tlp
->ifname
) == 0))) {
3137 * First lookup the "link" kstats in
3138 * case the link is renamed. Then
3139 * fallback to the legacy kstats for
3140 * those non-GLDv3 links.
3142 if (((ksp
= kstat_lookup(kc
, "link",
3144 (ksp
= kstat_lookup(kc
, NULL
, -1,
3145 buf
)) != NULL
) && (ksp
->ks_type
==
3146 KSTAT_TYPE_NAMED
)) {
3147 (void) safe_kstat_read(kc
,
3151 t
.ipackets
= kstat_named_value(ksp
,
3153 t
.ierrors
= kstat_named_value(ksp
,
3155 t
.opackets
= kstat_named_value(ksp
,
3157 t
.oerrors
= kstat_named_value(ksp
,
3159 t
.collisions
= kstat_named_value(ksp
,
3162 if (strcmp(buf
, matchname
) == 0)
3165 /* Build the interface list */
3167 tlp
= malloc(sizeof (struct iflist
));
3168 (void) strlcpy(tlp
->ifname
, buf
,
3169 sizeof (tlp
->ifname
));
3172 nextnew
= &tlp
->next_if
;
3175 * First time through.
3176 * Just add up the interface stats.
3179 if (oldlist6
== NULL
) {
3180 if_stat_total(&zerostat
,
3186 * Walk old list for the interface.
3188 * If found, add difference to total.
3190 * If not, an interface has been plumbed
3191 * up. In this case, we will simply
3192 * ignore the new interface until the
3193 * next interval; as there's no easy way
3194 * to acquire statistics between time
3195 * of the plumb and the next interval
3196 * boundary. This results in inaccurate
3197 * total values for current interval.
3199 * Note the case when an interface is
3200 * unplumbed; as similar problems exist.
3201 * The unplumbed interface is not in the
3202 * current list, and there's no easy way
3203 * to account for the statistics between
3204 * the previous interval and time of the
3205 * unplumb. Therefore, we (in a sense)
3206 * ignore the removed interface by only
3207 * involving "current" interfaces when
3208 * computing the total statistics.
3209 * Unfortunately, this also results in
3210 * inaccurate values for interval total.
3213 for (walkold
= oldlist6
;
3215 walkold
= walkold
->next_if
) {
3216 if (strcmp(walkold
->ifname
,
3225 } /* 'for' loop 2f ends */
3229 (void) printf("%-7llu %-5llu %-7llu "
3231 new6
.ipackets
- old6
.ipackets
,
3232 new6
.ierrors
- old6
.ierrors
,
3233 new6
.opackets
- old6
.opackets
,
3234 new6
.oerrors
- old6
.oerrors
,
3235 new6
.collisions
- old6
.collisions
);
3237 (void) printf("%-7llu %-5llu %-7llu "
3238 "%-5llu %-6llu\n", sum6
.ipackets
,
3239 sum6
.ierrors
, sum6
.opackets
,
3240 sum6
.oerrors
, sum6
.collisions
);
3243 * Tidy things up once finished.
3247 cleanlist
= oldlist6
;
3248 oldlist6
= newlist6
;
3249 while (cleanlist
!= NULL
) {
3250 tlp
= cleanlist
->next_if
;
3258 (void) fflush(stdout
);
3259 } /* 'for' loop 1 ends */
3260 if ((Iflag_only
== 0) && (!once_only
))
3261 (void) putchar('\n');
3266 if_report_ip4(mib2_ipAddrEntry_t
*ap
,
3267 char ifname
[], char logintname
[], struct ifstat
*statptr
,
3268 boolean_t ksp_not_null
) {
3270 char abuf
[MAXHOSTNAMELEN
+ 1];
3271 char dstbuf
[MAXHOSTNAMELEN
+ 1];
3274 (void) printf("%-5s %-4u ",
3275 ifname
, ap
->ipAdEntInfo
.ae_mtu
);
3276 if (ap
->ipAdEntInfo
.ae_flags
& IFF_POINTOPOINT
)
3277 (void) pr_addr(ap
->ipAdEntInfo
.ae_pp_dst_addr
,
3278 abuf
, sizeof (abuf
));
3280 (void) pr_netaddr(ap
->ipAdEntAddr
,
3281 ap
->ipAdEntNetMask
, abuf
, sizeof (abuf
));
3282 (void) printf("%-13s %-14s %-6llu %-5llu %-6llu %-5llu "
3284 abuf
, pr_addr(ap
->ipAdEntAddr
, dstbuf
, sizeof (dstbuf
)),
3285 statptr
->ipackets
, statptr
->ierrors
,
3286 statptr
->opackets
, statptr
->oerrors
,
3287 statptr
->collisions
, 0LL);
3290 * Print logical interface info if Aflag set (including logical unit 0)
3293 *statptr
= zerostat
;
3294 statptr
->ipackets
= ap
->ipAdEntInfo
.ae_ibcnt
;
3295 statptr
->opackets
= ap
->ipAdEntInfo
.ae_obcnt
;
3297 (void) printf("%-5s %-4u ", logintname
, ap
->ipAdEntInfo
.ae_mtu
);
3298 if (ap
->ipAdEntInfo
.ae_flags
& IFF_POINTOPOINT
)
3299 (void) pr_addr(ap
->ipAdEntInfo
.ae_pp_dst_addr
, abuf
,
3302 (void) pr_netaddr(ap
->ipAdEntAddr
, ap
->ipAdEntNetMask
,
3303 abuf
, sizeof (abuf
));
3305 (void) printf("%-13s %-14s %-6llu %-5s %-6s "
3306 "%-5s %-6s %-6llu\n", abuf
,
3307 pr_addr(ap
->ipAdEntAddr
, dstbuf
, sizeof (dstbuf
)),
3308 statptr
->ipackets
, "N/A", "N/A", "N/A", "N/A",
3314 if_report_ip6(mib2_ipv6AddrEntry_t
*ap6
,
3315 char ifname
[], char logintname
[], struct ifstat
*statptr
,
3316 boolean_t ksp_not_null
) {
3318 char abuf
[MAXHOSTNAMELEN
+ 1];
3319 char dstbuf
[MAXHOSTNAMELEN
+ 1];
3322 (void) printf("%-5s %-4u ", ifname
, ap6
->ipv6AddrInfo
.ae_mtu
);
3323 if (ap6
->ipv6AddrInfo
.ae_flags
&
3325 (void) pr_addr6(&ap6
->ipv6AddrInfo
.ae_pp_dst_addr
,
3326 abuf
, sizeof (abuf
));
3328 (void) pr_prefix6(&ap6
->ipv6AddrAddress
,
3329 ap6
->ipv6AddrPfxLength
, abuf
,
3332 (void) printf("%-27s %-27s %-6llu %-5llu "
3333 "%-6llu %-5llu %-6llu\n",
3334 abuf
, pr_addr6(&ap6
->ipv6AddrAddress
, dstbuf
,
3336 statptr
->ipackets
, statptr
->ierrors
, statptr
->opackets
,
3337 statptr
->oerrors
, statptr
->collisions
);
3340 * Print logical interface info if Aflag set (including logical unit 0)
3343 *statptr
= zerostat
;
3344 statptr
->ipackets
= ap6
->ipv6AddrInfo
.ae_ibcnt
;
3345 statptr
->opackets
= ap6
->ipv6AddrInfo
.ae_obcnt
;
3347 (void) printf("%-5s %-4u ", logintname
,
3348 ap6
->ipv6AddrInfo
.ae_mtu
);
3349 if (ap6
->ipv6AddrInfo
.ae_flags
& IFF_POINTOPOINT
)
3350 (void) pr_addr6(&ap6
->ipv6AddrInfo
.ae_pp_dst_addr
,
3351 abuf
, sizeof (abuf
));
3353 (void) pr_prefix6(&ap6
->ipv6AddrAddress
,
3354 ap6
->ipv6AddrPfxLength
, abuf
, sizeof (abuf
));
3355 (void) printf("%-27s %-27s %-6llu %-5s %-6s %-5s %-6s\n",
3356 abuf
, pr_addr6(&ap6
->ipv6AddrAddress
, dstbuf
,
3358 statptr
->ipackets
, "N/A", "N/A", "N/A", "N/A");
3362 /* --------------------- DHCP_REPORT (netstat -D) ------------------------- */
3365 dhcp_do_ipc(dhcp_ipc_type_t type
, const char *ifname
, boolean_t printed_one
)
3367 dhcp_ipc_request_t
*request
;
3368 dhcp_ipc_reply_t
*reply
;
3371 request
= dhcp_ipc_alloc_request(type
, ifname
, NULL
, 0, DHCP_TYPE_NONE
);
3372 if (request
== NULL
)
3373 fail(0, "dhcp_do_ipc: out of memory");
3375 error
= dhcp_ipc_make_request(request
, &reply
, DHCP_IPC_WAIT_DEFAULT
);
3378 fail(0, "dhcp_do_ipc: %s", dhcp_ipc_strerror(error
));
3382 error
= reply
->return_code
;
3383 if (error
== DHCP_IPC_E_UNKIF
) {
3385 return (printed_one
);
3389 fail(0, "dhcp_do_ipc: %s", dhcp_ipc_strerror(error
));
3392 if (timestamp_fmt
!= NODATE
)
3393 print_timestamp(timestamp_fmt
);
3396 (void) printf("%s", dhcp_status_hdr_string());
3398 (void) printf("%s", dhcp_status_reply_to_string(reply
));
3404 * dhcp_walk_interfaces: walk the list of interfaces for a given address
3405 * family (af). For each, print out the DHCP status using dhcp_do_ipc.
3408 dhcp_walk_interfaces(int af
, boolean_t printed_one
)
3411 struct lifconf lifc
;
3412 int n_ifs
, i
, sock_fd
;
3414 sock_fd
= socket(af
, SOCK_DGRAM
, 0);
3416 return (printed_one
);
3419 * SIOCGLIFNUM is just an estimate. If the ioctl fails, we don't care;
3420 * just drive on and use SIOCGLIFCONF with increasing buffer sizes, as
3423 (void) memset(&lifn
, 0, sizeof (lifn
));
3424 lifn
.lifn_family
= af
;
3425 lifn
.lifn_flags
= LIFC_ALLZONES
| LIFC_NOXMIT
| LIFC_UNDER_IPMP
;
3426 if (ioctl(sock_fd
, SIOCGLIFNUM
, &lifn
) == -1)
3427 n_ifs
= LIFN_GUARD_VALUE
;
3429 n_ifs
= lifn
.lifn_count
+ LIFN_GUARD_VALUE
;
3431 (void) memset(&lifc
, 0, sizeof (lifc
));
3432 lifc
.lifc_family
= af
;
3433 lifc
.lifc_flags
= lifn
.lifn_flags
;
3434 lifc
.lifc_len
= n_ifs
* sizeof (struct lifreq
);
3435 lifc
.lifc_buf
= malloc(lifc
.lifc_len
);
3436 if (lifc
.lifc_buf
!= NULL
) {
3438 if (ioctl(sock_fd
, SIOCGLIFCONF
, &lifc
) == -1) {
3439 (void) close(sock_fd
);
3440 free(lifc
.lifc_buf
);
3444 n_ifs
= lifc
.lifc_len
/ sizeof (struct lifreq
);
3446 for (i
= 0; i
< n_ifs
; i
++) {
3447 printed_one
= dhcp_do_ipc(DHCP_STATUS
|
3448 (af
== AF_INET6
? DHCP_V6
: 0),
3449 lifc
.lifc_req
[i
].lifr_name
, printed_one
);
3452 (void) close(sock_fd
);
3453 free(lifc
.lifc_buf
);
3454 return (printed_one
);
3458 dhcp_report(char *ifname
)
3460 boolean_t printed_one
;
3462 if (!family_selected(AF_INET
) && !family_selected(AF_INET6
))
3465 printed_one
= B_FALSE
;
3466 if (ifname
!= NULL
) {
3467 if (family_selected(AF_INET
)) {
3468 printed_one
= dhcp_do_ipc(DHCP_STATUS
, ifname
,
3471 if (family_selected(AF_INET6
)) {
3472 printed_one
= dhcp_do_ipc(DHCP_STATUS
| DHCP_V6
,
3473 ifname
, printed_one
);
3476 fail(0, "%s: %s", ifname
,
3477 dhcp_ipc_strerror(DHCP_IPC_E_UNKIF
));
3480 if (family_selected(AF_INET
)) {
3481 printed_one
= dhcp_walk_interfaces(AF_INET
,
3484 if (family_selected(AF_INET6
))
3485 (void) dhcp_walk_interfaces(AF_INET6
, printed_one
);
3489 /* --------------------- GROUP_REPORT (netstat -g) ------------------------- */
3492 group_report(mib_item_t
*item
)
3494 mib_item_t
*v4grp
= NULL
, *v4src
= NULL
;
3495 mib_item_t
*v6grp
= NULL
, *v6src
= NULL
;
3497 char ifname
[LIFNAMSIZ
+ 1];
3498 char abuf
[MAXHOSTNAMELEN
+ 1];
3501 ipv6_member_t
*ipmp6
;
3502 ipv6_grpsrc_t
*ips6
;
3503 boolean_t first
, first_src
;
3506 for (; item
; item
= item
->next_item
) {
3508 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
3509 (void) printf("Group = %d, mib_id = %d, "
3510 "length = %d, valp = 0x%p\n",
3511 item
->group
, item
->mib_id
, item
->length
,
3514 if (item
->group
== MIB2_IP
&& family_selected(AF_INET
)) {
3515 switch (item
->mib_id
) {
3516 case EXPER_IP_GROUP_MEMBERSHIP
:
3519 (void) printf("item is v4grp info\n");
3521 case EXPER_IP_GROUP_SOURCES
:
3524 (void) printf("item is v4src info\n");
3531 if (item
->group
== MIB2_IP6
&& family_selected(AF_INET6
)) {
3532 switch (item
->mib_id
) {
3533 case EXPER_IP6_GROUP_MEMBERSHIP
:
3536 (void) printf("item is v6grp info\n");
3538 case EXPER_IP6_GROUP_SOURCES
:
3541 (void) printf("item is v6src info\n");
3549 if (family_selected(AF_INET
) && v4grp
!= NULL
) {
3551 (void) printf("%u records for ipGroupMember:\n",
3552 v4grp
->length
/ sizeof (ip_member_t
));
3555 for (ipmp
= (ip_member_t
*)v4grp
->valp
;
3556 (char *)ipmp
< (char *)v4grp
->valp
+ v4grp
->length
;
3557 /* LINTED: (note 1) */
3558 ipmp
= (ip_member_t
*)((char *)ipmp
+ ipMemberEntrySize
)) {
3560 (void) puts(v4compat
?
3561 "Group Memberships" :
3562 "Group Memberships: IPv4");
3563 (void) puts("Interface "
3565 (void) puts("--------- "
3566 "-------------------- ------");
3570 (void) printf("%-9s %-20s %6u\n",
3571 octetstr(&ipmp
->ipGroupMemberIfIndex
, 'a',
3572 ifname
, sizeof (ifname
)),
3573 pr_addr(ipmp
->ipGroupMemberAddress
,
3574 abuf
, sizeof (abuf
)),
3575 ipmp
->ipGroupMemberRefCnt
);
3578 if (!Vflag
|| v4src
== NULL
)
3582 (void) printf("scanning %u ipGroupSource "
3584 v4src
->length
/sizeof (ip_grpsrc_t
));
3587 for (ips
= (ip_grpsrc_t
*)v4src
->valp
;
3588 (char *)ips
< (char *)v4src
->valp
+ v4src
->length
;
3589 /* LINTED: (note 1) */
3590 ips
= (ip_grpsrc_t
*)((char *)ips
+
3591 ipGroupSourceEntrySize
)) {
3593 * We assume that all source addrs for a given
3594 * interface/group pair are contiguous, so on
3595 * the first non-match after we've found at
3596 * least one, we bail.
3598 if ((ipmp
->ipGroupMemberAddress
!=
3599 ips
->ipGroupSourceGroup
) ||
3600 (!octetstrmatch(&ipmp
->ipGroupMemberIfIndex
,
3601 &ips
->ipGroupSourceIfIndex
))) {
3608 (void) printf("\t%s: %s\n",
3610 ipmp
->ipGroupMemberFilterMode
),
3611 pr_addr(ips
->ipGroupSourceAddress
,
3612 abuf
, sizeof (abuf
)));
3613 first_src
= B_FALSE
;
3617 (void) printf("\t %s\n",
3618 pr_addr(ips
->ipGroupSourceAddress
, abuf
,
3622 (void) putchar('\n');
3625 if (family_selected(AF_INET6
) && v6grp
!= NULL
) {
3627 (void) printf("%u records for ipv6GroupMember:\n",
3628 v6grp
->length
/ sizeof (ipv6_member_t
));
3631 for (ipmp6
= (ipv6_member_t
*)v6grp
->valp
;
3632 (char *)ipmp6
< (char *)v6grp
->valp
+ v6grp
->length
;
3633 /* LINTED: (note 1) */
3634 ipmp6
= (ipv6_member_t
*)((char *)ipmp6
+
3635 ipv6MemberEntrySize
)) {
3637 (void) puts("Group Memberships: "
3641 (void) puts("----- "
3642 "--------------------------- ------");
3646 (void) printf("%-5s %-27s %5u\n",
3647 ifindex2str(ipmp6
->ipv6GroupMemberIfIndex
, ifname
),
3648 pr_addr6(&ipmp6
->ipv6GroupMemberAddress
,
3649 abuf
, sizeof (abuf
)),
3650 ipmp6
->ipv6GroupMemberRefCnt
);
3652 if (!Vflag
|| v6src
== NULL
)
3656 (void) printf("scanning %u ipv6GroupSource "
3658 v6src
->length
/sizeof (ipv6_grpsrc_t
));
3661 for (ips6
= (ipv6_grpsrc_t
*)v6src
->valp
;
3662 (char *)ips6
< (char *)v6src
->valp
+ v6src
->length
;
3663 /* LINTED: (note 1) */
3664 ips6
= (ipv6_grpsrc_t
*)((char *)ips6
+
3665 ipv6GroupSourceEntrySize
)) {
3666 /* same assumption as in the v4 case above */
3667 if ((ipmp6
->ipv6GroupMemberIfIndex
!=
3668 ips6
->ipv6GroupSourceIfIndex
) ||
3669 (!IN6_ARE_ADDR_EQUAL(
3670 &ipmp6
->ipv6GroupMemberAddress
,
3671 &ips6
->ipv6GroupSourceGroup
))) {
3678 (void) printf("\t%s: %s\n",
3680 ipmp6
->ipv6GroupMemberFilterMode
),
3682 &ips6
->ipv6GroupSourceAddress
,
3683 abuf
, sizeof (abuf
)));
3684 first_src
= B_FALSE
;
3688 (void) printf("\t %s\n",
3689 pr_addr6(&ips6
->ipv6GroupSourceAddress
,
3690 abuf
, sizeof (abuf
)));
3693 (void) putchar('\n');
3696 (void) putchar('\n');
3697 (void) fflush(stdout
);
3700 /* --------------------- DCE_REPORT (netstat -d) ------------------------- */
3704 /* Assumes flbuf is at least 5 characters; callers use FLBUFSIZE */
3706 dceflags2str(uint32_t flags
, char *flbuf
)
3710 if (flags
& DCEF_DEFAULT
)
3712 if (flags
& DCEF_PMTU
)
3714 if (flags
& DCEF_UINFO
)
3716 if (flags
& DCEF_TOO_SMALL_PMTU
)
3723 dce_report(mib_item_t
*item
)
3725 mib_item_t
*v4dce
= NULL
;
3726 mib_item_t
*v6dce
= NULL
;
3728 char ifname
[LIFNAMSIZ
+ 1];
3729 char abuf
[MAXHOSTNAMELEN
+ 1];
3730 char flbuf
[FLBUFSIZE
];
3732 dest_cache_entry_t
*dce
;
3735 for (; item
; item
= item
->next_item
) {
3737 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
3738 (void) printf("Group = %d, mib_id = %d, "
3739 "length = %d, valp = 0x%p\n",
3740 item
->group
, item
->mib_id
, item
->length
,
3743 if (item
->group
== MIB2_IP
&& family_selected(AF_INET
) &&
3744 item
->mib_id
== EXPER_IP_DCE
) {
3747 (void) printf("item is v4dce info\n");
3749 if (item
->group
== MIB2_IP6
&& family_selected(AF_INET6
) &&
3750 item
->mib_id
== EXPER_IP_DCE
) {
3753 (void) printf("item is v6dce info\n");
3757 if (family_selected(AF_INET
) && v4dce
!= NULL
) {
3759 (void) printf("%u records for DestCacheEntry:\n",
3760 v4dce
->length
/ ipDestEntrySize
);
3763 for (dce
= (dest_cache_entry_t
*)v4dce
->valp
;
3764 (char *)dce
< (char *)v4dce
->valp
+ v4dce
->length
;
3765 /* LINTED: (note 1) */
3766 dce
= (dest_cache_entry_t
*)((char *)dce
+
3769 (void) putchar('\n');
3770 (void) puts("Destination Cache Entries: IPv4");
3772 "Address PMTU Age Flags");
3774 "-------------------- ------ ----- -----");
3778 (void) printf("%-20s %6u %5u %-5s\n",
3779 pr_addr(dce
->DestIpv4Address
, abuf
, sizeof (abuf
)),
3780 dce
->DestPmtu
, dce
->DestAge
,
3781 dceflags2str(dce
->DestFlags
, flbuf
));
3785 if (family_selected(AF_INET6
) && v6dce
!= NULL
) {
3787 (void) printf("%u records for DestCacheEntry:\n",
3788 v6dce
->length
/ ipDestEntrySize
);
3791 for (dce
= (dest_cache_entry_t
*)v6dce
->valp
;
3792 (char *)dce
< (char *)v6dce
->valp
+ v6dce
->length
;
3793 /* LINTED: (note 1) */
3794 dce
= (dest_cache_entry_t
*)((char *)dce
+
3797 (void) putchar('\n');
3798 (void) puts("Destination Cache Entries: IPv6");
3803 "--------------------------- ------ "
3808 (void) printf("%-27s %6u %5u %-5s %s\n",
3809 pr_addr6(&dce
->DestIpv6Address
, abuf
,
3811 dce
->DestPmtu
, dce
->DestAge
,
3812 dceflags2str(dce
->DestFlags
, flbuf
),
3813 dce
->DestIfindex
== 0 ? "" :
3814 ifindex2str(dce
->DestIfindex
, ifname
));
3817 (void) fflush(stdout
);
3820 /* --------------------- ARP_REPORT (netstat -p) -------------------------- */
3823 arp_report(mib_item_t
*item
)
3826 char ifname
[LIFNAMSIZ
+ 1];
3827 char abuf
[MAXHOSTNAMELEN
+ 1];
3828 char maskbuf
[STR_EXPAND
* OCTET_LENGTH
+ 1];
3829 char flbuf
[32]; /* ACE_F_ flags */
3830 char xbuf
[STR_EXPAND
* OCTET_LENGTH
+ 1];
3831 mib2_ipNetToMediaEntry_t
*np
;
3835 if (!(family_selected(AF_INET
)))
3839 for (; item
; item
= item
->next_item
) {
3841 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
3842 (void) printf("Group = %d, mib_id = %d, "
3843 "length = %d, valp = 0x%p\n",
3844 item
->group
, item
->mib_id
, item
->length
,
3847 if (!(item
->group
== MIB2_IP
&& item
->mib_id
== MIB2_IP_MEDIA
))
3848 continue; /* 'for' loop 1 */
3851 (void) printf("%u records for "
3852 "ipNetToMediaEntryTable:\n",
3853 item
->length
/sizeof (mib2_ipNetToMediaEntry_t
));
3857 for (np
= (mib2_ipNetToMediaEntry_t
*)item
->valp
;
3858 (char *)np
< (char *)item
->valp
+ item
->length
;
3859 /* LINTED: (note 1) */
3860 np
= (mib2_ipNetToMediaEntry_t
*)((char *)np
+
3861 ipNetToMediaEntrySize
)) {
3863 (void) puts(v4compat
?
3864 "Net to Media Table" :
3865 "Net to Media Table: IPv4");
3866 (void) puts("Device "
3869 (void) puts("------ "
3870 "-------------------- --------------- "
3871 "-------- ---------------");
3876 flags
= np
->ipNetToMediaInfo
.ntm_flags
;
3878 * Note that not all flags are possible at the same
3879 * time. Patterns: SPLAy DUo
3881 if (flags
& ACE_F_PERMANENT
)
3882 (void) strcat(flbuf
, "S");
3883 if (flags
& ACE_F_PUBLISH
)
3884 (void) strcat(flbuf
, "P");
3885 if (flags
& ACE_F_DYING
)
3886 (void) strcat(flbuf
, "D");
3887 if (!(flags
& ACE_F_RESOLVED
))
3888 (void) strcat(flbuf
, "U");
3889 if (flags
& ACE_F_MAPPING
)
3890 (void) strcat(flbuf
, "M");
3891 if (flags
& ACE_F_MYADDR
)
3892 (void) strcat(flbuf
, "L");
3893 if (flags
& ACE_F_UNVERIFIED
)
3894 (void) strcat(flbuf
, "d");
3895 if (flags
& ACE_F_AUTHORITY
)
3896 (void) strcat(flbuf
, "A");
3897 if (flags
& ACE_F_OLD
)
3898 (void) strcat(flbuf
, "o");
3899 if (flags
& ACE_F_DELAYED
)
3900 (void) strcat(flbuf
, "y");
3901 (void) printf("%-6s %-20s %-15s %-8s %s\n",
3902 octetstr(&np
->ipNetToMediaIfIndex
, 'a',
3903 ifname
, sizeof (ifname
)),
3904 pr_addr(np
->ipNetToMediaNetAddress
,
3905 abuf
, sizeof (abuf
)),
3906 octetstr(&np
->ipNetToMediaInfo
.ntm_mask
, 'd',
3907 maskbuf
, sizeof (maskbuf
)),
3909 octetstr(&np
->ipNetToMediaPhysAddress
, 'h',
3910 xbuf
, sizeof (xbuf
)));
3911 } /* 'for' loop 2 ends */
3912 } /* 'for' loop 1 ends */
3913 (void) fflush(stdout
);
3916 /* --------------------- NDP_REPORT (netstat -p) -------------------------- */
3919 ndp_report(mib_item_t
*item
)
3922 char abuf
[MAXHOSTNAMELEN
+ 1];
3925 char xbuf
[STR_EXPAND
* OCTET_LENGTH
+ 1];
3926 mib2_ipv6NetToMediaEntry_t
*np6
;
3927 char ifname
[LIFNAMSIZ
+ 1];
3930 if (!(family_selected(AF_INET6
)))
3934 for (; item
; item
= item
->next_item
) {
3936 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
3937 (void) printf("Group = %d, mib_id = %d, "
3938 "length = %d, valp = 0x%p\n",
3939 item
->group
, item
->mib_id
, item
->length
,
3942 if (!(item
->group
== MIB2_IP6
&&
3943 item
->mib_id
== MIB2_IP6_MEDIA
))
3944 continue; /* 'for' loop 1 */
3948 for (np6
= (mib2_ipv6NetToMediaEntry_t
*)item
->valp
;
3949 (char *)np6
< (char *)item
->valp
+ item
->length
;
3950 /* LINTED: (note 1) */
3951 np6
= (mib2_ipv6NetToMediaEntry_t
*)((char *)np6
+
3952 ipv6NetToMediaEntrySize
)) {
3954 (void) puts("\nNet to Media Table: IPv6");
3955 (void) puts(" If Physical Address "
3956 " Type State Destination/Mask");
3957 (void) puts("----- ----------------- "
3958 "------- ------------ "
3959 "---------------------------");
3963 switch (np6
->ipv6NetToMediaState
) {
3965 state
= "INCOMPLETE";
3968 state
= "REACHABLE";
3979 case ND_UNREACHABLE
:
3980 state
= "UNREACHABLE";
3986 switch (np6
->ipv6NetToMediaType
) {
4000 (void) printf("%-5s %-17s %-7s %-12s %-27s\n",
4001 ifindex2str(np6
->ipv6NetToMediaIfIndex
, ifname
),
4002 octetstr(&np6
->ipv6NetToMediaPhysAddress
, 'h',
4003 xbuf
, sizeof (xbuf
)),
4006 pr_addr6(&np6
->ipv6NetToMediaNetAddress
,
4007 abuf
, sizeof (abuf
)));
4008 } /* 'for' loop 2 ends */
4009 } /* 'for' loop 1 ends */
4010 (void) putchar('\n');
4011 (void) fflush(stdout
);
4014 /* ------------------------- ire_report (netstat -r) ------------------------ */
4016 typedef struct sec_attr_list_s
{
4017 struct sec_attr_list_s
*sal_next
;
4018 const mib2_ipAttributeEntry_t
*sal_attr
;
4021 static boolean_t
ire_report_item_v4(const mib2_ipRouteEntry_t
*, boolean_t
,
4022 const sec_attr_list_t
*);
4023 static boolean_t
ire_report_item_v6(const mib2_ipv6RouteEntry_t
*, boolean_t
,
4024 const sec_attr_list_t
*);
4025 static const char *pr_secattr(const sec_attr_list_t
*);
4028 ire_report(const mib_item_t
*item
)
4031 boolean_t print_hdr_once_v4
= B_TRUE
;
4032 boolean_t print_hdr_once_v6
= B_TRUE
;
4033 mib2_ipRouteEntry_t
*rp
;
4034 mib2_ipv6RouteEntry_t
*rp6
;
4035 sec_attr_list_t
**v4_attrs
, **v4a
;
4036 sec_attr_list_t
**v6_attrs
, **v6a
;
4037 sec_attr_list_t
*all_attrs
, *aptr
;
4038 const mib_item_t
*iptr
;
4039 int ipv4_route_count
, ipv6_route_count
;
4040 int route_attrs_count
;
4043 * Preparation pass: the kernel returns separate entries for IP routing
4044 * table entries and security attributes. We loop through the
4045 * attributes first and link them into lists.
4047 ipv4_route_count
= ipv6_route_count
= route_attrs_count
= 0;
4048 for (iptr
= item
; iptr
!= NULL
; iptr
= iptr
->next_item
) {
4049 if (iptr
->group
== MIB2_IP6
&& iptr
->mib_id
== MIB2_IP6_ROUTE
)
4050 ipv6_route_count
+= iptr
->length
/ ipv6RouteEntrySize
;
4051 if (iptr
->group
== MIB2_IP
&& iptr
->mib_id
== MIB2_IP_ROUTE
)
4052 ipv4_route_count
+= iptr
->length
/ ipRouteEntrySize
;
4053 if ((iptr
->group
== MIB2_IP
|| iptr
->group
== MIB2_IP6
) &&
4054 iptr
->mib_id
== EXPER_IP_RTATTR
)
4055 route_attrs_count
+= iptr
->length
/
4056 ipRouteAttributeSize
;
4058 v4_attrs
= v6_attrs
= NULL
;
4060 if (family_selected(AF_INET
) && ipv4_route_count
> 0) {
4061 v4_attrs
= calloc(ipv4_route_count
, sizeof (*v4_attrs
));
4062 if (v4_attrs
== NULL
) {
4063 perror("ire_report calloc v4_attrs failed");
4067 if (family_selected(AF_INET6
) && ipv6_route_count
> 0) {
4068 v6_attrs
= calloc(ipv6_route_count
, sizeof (*v6_attrs
));
4069 if (v6_attrs
== NULL
) {
4070 perror("ire_report calloc v6_attrs failed");
4071 goto ire_report_done
;
4074 if (route_attrs_count
> 0) {
4075 all_attrs
= malloc(route_attrs_count
* sizeof (*all_attrs
));
4076 if (all_attrs
== NULL
) {
4077 perror("ire_report malloc all_attrs failed");
4078 goto ire_report_done
;
4082 for (iptr
= item
; iptr
!= NULL
; iptr
= iptr
->next_item
) {
4083 mib2_ipAttributeEntry_t
*iae
;
4084 sec_attr_list_t
**alp
;
4086 if (v4_attrs
!= NULL
&& iptr
->group
== MIB2_IP
&&
4087 iptr
->mib_id
== EXPER_IP_RTATTR
) {
4089 } else if (v6_attrs
!= NULL
&& iptr
->group
== MIB2_IP6
&&
4090 iptr
->mib_id
== EXPER_IP_RTATTR
) {
4095 for (iae
= iptr
->valp
;
4096 (char *)iae
< (char *)iptr
->valp
+ iptr
->length
;
4097 /* LINTED: (note 1) */
4098 iae
= (mib2_ipAttributeEntry_t
*)((char *)iae
+
4099 ipRouteAttributeSize
)) {
4100 aptr
->sal_next
= alp
[iae
->iae_routeidx
];
4101 aptr
->sal_attr
= iae
;
4102 alp
[iae
->iae_routeidx
] = aptr
++;
4109 for (; item
!= NULL
; item
= item
->next_item
) {
4111 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
4112 (void) printf("Group = %d, mib_id = %d, "
4113 "length = %d, valp = 0x%p\n",
4114 item
->group
, item
->mib_id
,
4115 item
->length
, item
->valp
);
4117 if (!((item
->group
== MIB2_IP
&&
4118 item
->mib_id
== MIB2_IP_ROUTE
) ||
4119 (item
->group
== MIB2_IP6
&&
4120 item
->mib_id
== MIB2_IP6_ROUTE
)))
4121 continue; /* 'for' loop 1 */
4123 if (item
->group
== MIB2_IP
&& !family_selected(AF_INET
))
4124 continue; /* 'for' loop 1 */
4125 else if (item
->group
== MIB2_IP6
&& !family_selected(AF_INET6
))
4126 continue; /* 'for' loop 1 */
4129 if (item
->group
== MIB2_IP
) {
4130 (void) printf("%u records for "
4131 "ipRouteEntryTable:\n",
4132 item
->length
/sizeof (mib2_ipRouteEntry_t
));
4134 (void) printf("%u records for "
4135 "ipv6RouteEntryTable:\n",
4137 sizeof (mib2_ipv6RouteEntry_t
));
4141 if (item
->group
== MIB2_IP
) {
4142 for (rp
= (mib2_ipRouteEntry_t
*)item
->valp
;
4143 (char *)rp
< (char *)item
->valp
+ item
->length
;
4144 /* LINTED: (note 1) */
4145 rp
= (mib2_ipRouteEntry_t
*)((char *)rp
+
4146 ipRouteEntrySize
)) {
4147 aptr
= v4a
== NULL
? NULL
: *v4a
++;
4148 print_hdr_once_v4
= ire_report_item_v4(rp
,
4149 print_hdr_once_v4
, aptr
);
4152 for (rp6
= (mib2_ipv6RouteEntry_t
*)item
->valp
;
4153 (char *)rp6
< (char *)item
->valp
+ item
->length
;
4154 /* LINTED: (note 1) */
4155 rp6
= (mib2_ipv6RouteEntry_t
*)((char *)rp6
+
4156 ipv6RouteEntrySize
)) {
4157 aptr
= v6a
== NULL
? NULL
: *v6a
++;
4158 print_hdr_once_v6
= ire_report_item_v6(rp6
,
4159 print_hdr_once_v6
, aptr
);
4162 } /* 'for' loop 1 ends */
4163 (void) fflush(stdout
);
4165 if (v4_attrs
!= NULL
)
4167 if (v6_attrs
!= NULL
)
4169 if (all_attrs
!= NULL
)
4174 * Match a user-supplied device name. We do this by string because
4175 * the MIB2 interface gives us interface name strings rather than
4176 * ifIndex numbers. The "none" rule matches only routes with no
4177 * interface. The "any" rule matches routes with any non-blank
4178 * interface. A base name ("hme0") matches all aliases as well
4182 dev_name_match(const DeviceName
*devnam
, const char *ifname
)
4187 return (devnam
->o_length
== 0); /* "none" */
4188 if (*ifname
== '\0')
4189 return (devnam
->o_length
!= 0); /* "any" */
4190 iflen
= strlen(ifname
);
4191 /* The check for ':' here supports interface aliases. */
4192 if (iflen
> devnam
->o_length
||
4193 (iflen
< devnam
->o_length
&& devnam
->o_bytes
[iflen
] != ':'))
4195 return (strncmp(ifname
, devnam
->o_bytes
, iflen
) == 0);
4199 * Match a user-supplied IP address list. The "any" rule matches any
4200 * non-zero address. The "none" rule matches only the zero address.
4201 * IPv6 addresses supplied by the user are ignored. If the user
4202 * supplies a subnet mask, then match routes that are at least that
4203 * specific (use the user's mask). If the user supplies only an
4204 * address, then select any routes that would match (use the route's
4208 v4_addr_match(IpAddress addr
, IpAddress mask
, const filter_t
*fp
)
4212 in_addr_t faddr
, fmask
;
4214 if (fp
->u
.a
.f_address
== NULL
) {
4215 if (IN6_IS_ADDR_UNSPECIFIED(&fp
->u
.a
.f_mask
))
4216 return (addr
!= INADDR_ANY
); /* "any" */
4218 return (addr
== INADDR_ANY
); /* "none" */
4220 if (!IN6_IS_V4MASK(fp
->u
.a
.f_mask
))
4222 IN6_V4MAPPED_TO_IPADDR(&fp
->u
.a
.f_mask
, fmask
);
4223 if (fmask
!= IP_HOST_MASK
) {
4228 for (app
= fp
->u
.a
.f_address
->h_addr_list
; (aptr
= *app
) != NULL
; app
++)
4229 /* LINTED: (note 1) */
4230 if (IN6_IS_ADDR_V4MAPPED((in6_addr_t
*)aptr
)) {
4231 /* LINTED: (note 1) */
4232 IN6_V4MAPPED_TO_IPADDR((in6_addr_t
*)aptr
, faddr
);
4233 if (((faddr
^ addr
) & mask
) == 0)
4240 * Run through the filter list for an IPv4 MIB2 route entry. If all
4241 * filters of a given type fail to match, then the route is filtered
4242 * out (not displayed). If no filter is given or at least one filter
4243 * of each type matches, then display the route.
4246 ire_filter_match_v4(const mib2_ipRouteEntry_t
*rp
, uint_t flag_b
)
4252 for (idx
= 0; idx
< NFILTERKEYS
; idx
++)
4253 if ((fp
= filters
[idx
]) != NULL
) {
4255 for (; fp
!= NULL
; fp
= fp
->f_next
) {
4258 if (fp
->u
.f_family
!= AF_INET
)
4259 continue; /* 'for' loop 2 */
4262 if (!dev_name_match(&rp
->ipRouteIfIndex
,
4264 continue; /* 'for' loop 2 */
4267 if (!v4_addr_match(rp
->ipRouteDest
,
4268 rp
->ipRouteMask
, fp
))
4269 continue; /* 'for' loop 2 */
4272 if ((flag_b
& fp
->u
.f
.f_flagset
) !=
4273 fp
->u
.f
.f_flagset
||
4274 (flag_b
& fp
->u
.f
.f_flagclear
))
4275 continue; /* 'for' loop 2 */
4279 } /* 'for' loop 2 ends */
4283 /* 'for' loop 1 ends */
4288 * Given an IPv4 MIB2 route entry, form the list of flags for the
4292 form_v4_route_flags(const mib2_ipRouteEntry_t
*rp
, char *flags
)
4297 (void) strcpy(flags
, "U");
4298 /* RTF_INDIRECT wins over RTF_GATEWAY - don't display both */
4299 if (rp
->ipRouteInfo
.re_flags
& RTF_INDIRECT
) {
4300 (void) strcat(flags
, "I");
4302 } else if (rp
->ipRouteInfo
.re_ire_type
& IRE_OFFLINK
) {
4303 (void) strcat(flags
, "G");
4306 /* IRE_IF_CLONE wins over RTF_HOST - don't display both */
4307 if (rp
->ipRouteInfo
.re_ire_type
& IRE_IF_CLONE
) {
4308 (void) strcat(flags
, "C");
4310 } else if (rp
->ipRouteMask
== IP_HOST_MASK
) {
4311 (void) strcat(flags
, "H");
4314 if (rp
->ipRouteInfo
.re_flags
& RTF_DYNAMIC
) {
4315 (void) strcat(flags
, "D");
4318 if (rp
->ipRouteInfo
.re_ire_type
== IRE_BROADCAST
) { /* Broadcast */
4319 (void) strcat(flags
, "b");
4322 if (rp
->ipRouteInfo
.re_ire_type
== IRE_LOCAL
) { /* Local */
4323 (void) strcat(flags
, "L");
4326 if (rp
->ipRouteInfo
.re_flags
& RTF_MULTIRT
) {
4327 (void) strcat(flags
, "M"); /* Multiroute */
4330 if (rp
->ipRouteInfo
.re_flags
& RTF_SETSRC
) {
4331 (void) strcat(flags
, "S"); /* Setsrc */
4334 if (rp
->ipRouteInfo
.re_flags
& RTF_REJECT
) {
4335 (void) strcat(flags
, "R");
4338 if (rp
->ipRouteInfo
.re_flags
& RTF_BLACKHOLE
) {
4339 (void) strcat(flags
, "B");
4342 if (rp
->ipRouteInfo
.re_flags
& RTF_ZONE
) {
4343 (void) strcat(flags
, "Z");
4349 static const char ire_hdr_v4
[] =
4350 "\n%s Table: IPv4\n";
4351 static const char ire_hdr_v4_compat
[] =
4353 static const char ire_hdr_v4_verbose
[] =
4354 " Destination Mask Gateway Device "
4355 " MTU Ref Flg Out In/Fwd %s\n"
4356 "-------------------- --------------- -------------------- ------ "
4357 "----- --- --- ----- ------ %s\n";
4359 static const char ire_hdr_v4_normal
[] =
4360 " Destination Gateway Flags Ref Use Interface"
4361 " %s\n-------------------- -------------------- ----- ----- ---------- "
4365 ire_report_item_v4(const mib2_ipRouteEntry_t
*rp
, boolean_t first
,
4366 const sec_attr_list_t
*attrs
)
4368 char dstbuf
[MAXHOSTNAMELEN
+ 1];
4369 char maskbuf
[MAXHOSTNAMELEN
+ 1];
4370 char gwbuf
[MAXHOSTNAMELEN
+ 1];
4371 char ifname
[LIFNAMSIZ
+ 1];
4372 char flags
[10]; /* RTF_ flags */
4375 if (!(Aflag
|| (rp
->ipRouteInfo
.re_ire_type
!= IRE_IF_CLONE
&&
4376 rp
->ipRouteInfo
.re_ire_type
!= IRE_BROADCAST
&&
4377 rp
->ipRouteInfo
.re_ire_type
!= IRE_MULTICAST
&&
4378 rp
->ipRouteInfo
.re_ire_type
!= IRE_NOROUTE
&&
4379 rp
->ipRouteInfo
.re_ire_type
!= IRE_LOCAL
))) {
4383 flag_b
= form_v4_route_flags(rp
, flags
);
4385 if (!ire_filter_match_v4(rp
, flag_b
))
4389 (void) printf(v4compat
? ire_hdr_v4_compat
: ire_hdr_v4
,
4390 Vflag
? "IRE" : "Routing");
4391 (void) printf(Vflag
? ire_hdr_v4_verbose
: ire_hdr_v4_normal
,
4392 RSECflag
? " Gateway security attributes " : "",
4393 RSECflag
? "-------------------------------" : "");
4397 if (flag_b
& FLF_H
) {
4398 (void) pr_addr(rp
->ipRouteDest
, dstbuf
, sizeof (dstbuf
));
4400 (void) pr_net(rp
->ipRouteDest
, rp
->ipRouteMask
,
4401 dstbuf
, sizeof (dstbuf
));
4404 (void) printf("%-20s %-15s %-20s %-6s %5u %3u "
4407 pr_mask(rp
->ipRouteMask
, maskbuf
, sizeof (maskbuf
)),
4408 pr_addrnz(rp
->ipRouteNextHop
, gwbuf
, sizeof (gwbuf
)),
4409 octetstr(&rp
->ipRouteIfIndex
, 'a', ifname
, sizeof (ifname
)),
4410 rp
->ipRouteInfo
.re_max_frag
,
4411 rp
->ipRouteInfo
.re_ref
,
4413 rp
->ipRouteInfo
.re_obpkt
,
4414 rp
->ipRouteInfo
.re_ibpkt
,
4417 (void) printf("%-20s %-20s %-5s %4u %10u %-9s %s\n",
4419 pr_addrnz(rp
->ipRouteNextHop
, gwbuf
, sizeof (gwbuf
)),
4421 rp
->ipRouteInfo
.re_ref
,
4422 rp
->ipRouteInfo
.re_obpkt
+ rp
->ipRouteInfo
.re_ibpkt
,
4423 octetstr(&rp
->ipRouteIfIndex
, 'a',
4424 ifname
, sizeof (ifname
)),
4431 * Match a user-supplied IP address list against an IPv6 route entry.
4432 * If the user specified "any," then any non-zero address matches. If
4433 * the user specified "none," then only the zero address matches. If
4434 * the user specified a subnet mask length, then use that in matching
4435 * routes (select routes that are at least as specific). If the user
4436 * specified only an address, then use the route's mask (select routes
4437 * that would match that address). IPv4 addresses are ignored.
4440 v6_addr_match(const Ip6Address
*addr
, int masklen
, const filter_t
*fp
)
4446 const uint8_t *aptr
;
4448 if (fp
->u
.a
.f_address
== NULL
) {
4449 if (IN6_IS_ADDR_UNSPECIFIED(&fp
->u
.a
.f_mask
)) /* any */
4450 return (!IN6_IS_ADDR_UNSPECIFIED(addr
));
4451 return (IN6_IS_ADDR_UNSPECIFIED(addr
)); /* "none" */
4454 /* 'for' loop 1a: */
4455 for (ucp
= fp
->u
.a
.f_mask
.s6_addr
;
4456 ucp
< fp
->u
.a
.f_mask
.s6_addr
+ sizeof (fp
->u
.a
.f_mask
.s6_addr
);
4460 fmasklen
+= 9 - ffs(*ucp
);
4461 break; /* 'for' loop 1a */
4464 } /* 'for' loop 1a ends */
4465 if (fmasklen
!= IPV6_ABITS
) {
4466 if (fmasklen
> masklen
)
4470 /* 'for' loop 1b: */
4471 for (app
= fp
->u
.a
.f_address
->h_addr_list
;
4472 (aptr
= (uint8_t *)*app
) != NULL
; app
++) {
4473 /* LINTED: (note 1) */
4474 if (IN6_IS_ADDR_V4MAPPED((in6_addr_t
*)aptr
))
4475 continue; /* 'for' loop 1b */
4476 ucp
= addr
->s6_addr
;
4477 for (i
= masklen
; i
>= 8; i
-= 8)
4478 if (*ucp
++ != *aptr
++)
4479 break; /* 'for' loop 1b */
4481 (i
< 8 && ((*ucp
^ *aptr
) & ~(0xff >> i
)) == 0))
4483 } /* 'for' loop 1b ends */
4488 * Run through the filter list for an IPv6 MIB2 IRE. For a given
4489 * type, if there's at least one filter and all filters of that type
4490 * fail to match, then the route doesn't match and isn't displayed.
4491 * If at least one matches, or none are specified, for each of the
4492 * types, then the route is selected and displayed.
4495 ire_filter_match_v6(const mib2_ipv6RouteEntry_t
*rp6
, uint_t flag_b
)
4501 for (idx
= 0; idx
< NFILTERKEYS
; idx
++)
4502 if ((fp
= filters
[idx
]) != NULL
) {
4504 for (; fp
!= NULL
; fp
= fp
->f_next
) {
4507 if (fp
->u
.f_family
!= AF_INET6
)
4512 if (!dev_name_match(&rp6
->
4513 ipv6RouteIfIndex
, fp
->u
.f_ifname
))
4518 if (!v6_addr_match(&rp6
->ipv6RouteDest
,
4519 rp6
->ipv6RoutePfxLength
, fp
))
4524 if ((flag_b
& fp
->u
.f
.f_flagset
) !=
4525 fp
->u
.f
.f_flagset
||
4526 (flag_b
& fp
->u
.f
.f_flagclear
))
4532 } /* 'for' loop 2 ends */
4536 /* 'for' loop 1 ends */
4541 * Given an IPv6 MIB2 route entry, form the list of flags for the
4545 form_v6_route_flags(const mib2_ipv6RouteEntry_t
*rp6
, char *flags
)
4550 (void) strcpy(flags
, "U");
4551 /* RTF_INDIRECT wins over RTF_GATEWAY - don't display both */
4552 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_INDIRECT
) {
4553 (void) strcat(flags
, "I");
4555 } else if (rp6
->ipv6RouteInfo
.re_ire_type
& IRE_OFFLINK
) {
4556 (void) strcat(flags
, "G");
4560 /* IRE_IF_CLONE wins over RTF_HOST - don't display both */
4561 if (rp6
->ipv6RouteInfo
.re_ire_type
& IRE_IF_CLONE
) {
4562 (void) strcat(flags
, "C");
4564 } else if (rp6
->ipv6RoutePfxLength
== IPV6_ABITS
) {
4565 (void) strcat(flags
, "H");
4569 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_DYNAMIC
) {
4570 (void) strcat(flags
, "D");
4573 if (rp6
->ipv6RouteInfo
.re_ire_type
== IRE_LOCAL
) { /* Local */
4574 (void) strcat(flags
, "L");
4577 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_MULTIRT
) {
4578 (void) strcat(flags
, "M"); /* Multiroute */
4581 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_SETSRC
) {
4582 (void) strcat(flags
, "S"); /* Setsrc */
4585 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_REJECT
) {
4586 (void) strcat(flags
, "R");
4589 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_BLACKHOLE
) {
4590 (void) strcat(flags
, "B");
4593 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_ZONE
) {
4594 (void) strcat(flags
, "Z");
4600 static const char ire_hdr_v6
[] =
4601 "\n%s Table: IPv6\n";
4602 static const char ire_hdr_v6_verbose
[] =
4603 " Destination/Mask Gateway If MTU "
4604 "Ref Flags Out In/Fwd %s\n"
4605 "--------------------------- --------------------------- ----- ----- "
4606 "--- ----- ------ ------ %s\n";
4607 static const char ire_hdr_v6_normal
[] =
4608 " Destination/Mask Gateway Flags Ref Use "
4610 "--------------------------- --------------------------- ----- --- ------- "
4614 ire_report_item_v6(const mib2_ipv6RouteEntry_t
*rp6
, boolean_t first
,
4615 const sec_attr_list_t
*attrs
)
4617 char dstbuf
[MAXHOSTNAMELEN
+ 1];
4618 char gwbuf
[MAXHOSTNAMELEN
+ 1];
4619 char ifname
[LIFNAMSIZ
+ 1];
4620 char flags
[10]; /* RTF_ flags */
4623 if (!(Aflag
|| (rp6
->ipv6RouteInfo
.re_ire_type
!= IRE_IF_CLONE
&&
4624 rp6
->ipv6RouteInfo
.re_ire_type
!= IRE_MULTICAST
&&
4625 rp6
->ipv6RouteInfo
.re_ire_type
!= IRE_NOROUTE
&&
4626 rp6
->ipv6RouteInfo
.re_ire_type
!= IRE_LOCAL
))) {
4630 flag_b
= form_v6_route_flags(rp6
, flags
);
4632 if (!ire_filter_match_v6(rp6
, flag_b
))
4636 (void) printf(ire_hdr_v6
, Vflag
? "IRE" : "Routing");
4637 (void) printf(Vflag
? ire_hdr_v6_verbose
: ire_hdr_v6_normal
,
4638 RSECflag
? " Gateway security attributes " : "",
4639 RSECflag
? "-------------------------------" : "");
4644 (void) printf("%-27s %-27s %-5s %5u %3u "
4645 "%-5s %6u %6u %s\n",
4646 pr_prefix6(&rp6
->ipv6RouteDest
,
4647 rp6
->ipv6RoutePfxLength
, dstbuf
, sizeof (dstbuf
)),
4648 IN6_IS_ADDR_UNSPECIFIED(&rp6
->ipv6RouteNextHop
) ?
4650 pr_addr6(&rp6
->ipv6RouteNextHop
, gwbuf
, sizeof (gwbuf
)),
4651 octetstr(&rp6
->ipv6RouteIfIndex
, 'a',
4652 ifname
, sizeof (ifname
)),
4653 rp6
->ipv6RouteInfo
.re_max_frag
,
4654 rp6
->ipv6RouteInfo
.re_ref
,
4656 rp6
->ipv6RouteInfo
.re_obpkt
,
4657 rp6
->ipv6RouteInfo
.re_ibpkt
,
4660 (void) printf("%-27s %-27s %-5s %3u %7u %-5s %s\n",
4661 pr_prefix6(&rp6
->ipv6RouteDest
,
4662 rp6
->ipv6RoutePfxLength
, dstbuf
, sizeof (dstbuf
)),
4663 IN6_IS_ADDR_UNSPECIFIED(&rp6
->ipv6RouteNextHop
) ?
4665 pr_addr6(&rp6
->ipv6RouteNextHop
, gwbuf
, sizeof (gwbuf
)),
4667 rp6
->ipv6RouteInfo
.re_ref
,
4668 rp6
->ipv6RouteInfo
.re_obpkt
+ rp6
->ipv6RouteInfo
.re_ibpkt
,
4669 octetstr(&rp6
->ipv6RouteIfIndex
, 'a',
4670 ifname
, sizeof (ifname
)),
4677 * Common attribute-gathering routine for all transports.
4679 static mib2_transportMLPEntry_t
**
4680 gather_attrs(const mib_item_t
*item
, int group
, int mib_id
, int esize
)
4682 int transport_count
= 0;
4683 const mib_item_t
*iptr
;
4684 mib2_transportMLPEntry_t
**attrs
, *tme
;
4686 for (iptr
= item
; iptr
!= NULL
; iptr
= iptr
->next_item
) {
4687 if (iptr
->group
== group
&& iptr
->mib_id
== mib_id
)
4688 transport_count
+= iptr
->length
/ esize
;
4690 if (transport_count
<= 0)
4692 attrs
= calloc(transport_count
, sizeof (*attrs
));
4693 if (attrs
== NULL
) {
4694 perror("gather_attrs calloc failed");
4697 for (iptr
= item
; iptr
!= NULL
; iptr
= iptr
->next_item
) {
4698 if (iptr
->group
== group
&& iptr
->mib_id
== EXPER_XPORT_MLP
) {
4699 for (tme
= iptr
->valp
;
4700 (char *)tme
< (char *)iptr
->valp
+ iptr
->length
;
4701 /* LINTED: (note 1) */
4702 tme
= (mib2_transportMLPEntry_t
*)((char *)tme
+
4703 transportMLPSize
)) {
4704 attrs
[tme
->tme_connidx
] = tme
;
4712 print_transport_label(const mib2_transportMLPEntry_t
*attr
)
4714 if (!RSECflag
|| attr
== NULL
||
4715 !(attr
->tme_flags
& MIB2_TMEF_IS_LABELED
))
4718 if (bisinvalid(&attr
->tme_label
)) {
4719 (void) printf(" INVALID\n");
4720 } else if (!blequal(&attr
->tme_label
, zone_security_label
)) {
4723 sl_str
= sl_to_str(&attr
->tme_label
);
4724 (void) printf(" %s\n", sl_str
);
4729 /* ------------------------------ TCP_REPORT------------------------------- */
4731 static const char tcp_hdr_v4
[] =
4733 static const char tcp_hdr_v4_compat
[] =
4735 static const char tcp_hdr_v4_verbose
[] =
4736 "Local/Remote Address Swind Snext Suna Rwind Rnext Rack "
4738 "-------------------- ----- -------- -------- ----- -------- -------- "
4739 "----- ----- -----------\n";
4740 static const char tcp_hdr_v4_normal
[] =
4741 " Local Address Remote Address Swind Send-Q Rwind Recv-Q "
4743 "-------------------- -------------------- ----- ------ ----- ------ "
4746 static const char tcp_hdr_v6
[] =
4748 static const char tcp_hdr_v6_verbose
[] =
4749 "Local/Remote Address Swind Snext Suna Rwind Rnext "
4750 " Rack Rto Mss State If\n"
4751 "--------------------------------- ----- -------- -------- ----- -------- "
4752 "-------- ----- ----- ----------- -----\n";
4753 static const char tcp_hdr_v6_normal
[] =
4754 " Local Address Remote Address "
4755 "Swind Send-Q Rwind Recv-Q State If\n"
4756 "--------------------------------- --------------------------------- "
4757 "----- ------ ----- ------ ----------- -----\n";
4759 static boolean_t
tcp_report_item_v4(const mib2_tcpConnEntry_t
*,
4760 boolean_t first
, const mib2_transportMLPEntry_t
*);
4761 static boolean_t
tcp_report_item_v6(const mib2_tcp6ConnEntry_t
*,
4762 boolean_t first
, const mib2_transportMLPEntry_t
*);
4765 tcp_report(const mib_item_t
*item
)
4768 boolean_t print_hdr_once_v4
= B_TRUE
;
4769 boolean_t print_hdr_once_v6
= B_TRUE
;
4770 mib2_tcpConnEntry_t
*tp
;
4771 mib2_tcp6ConnEntry_t
*tp6
;
4772 mib2_transportMLPEntry_t
**v4_attrs
, **v6_attrs
;
4773 mib2_transportMLPEntry_t
**v4a
, **v6a
;
4774 mib2_transportMLPEntry_t
*aptr
;
4776 if (!protocol_selected(IPPROTO_TCP
))
4780 * Preparation pass: the kernel returns separate entries for TCP
4781 * connection table entries and Multilevel Port attributes. We loop
4782 * through the attributes first and set up an array for each address
4785 v4_attrs
= family_selected(AF_INET
) && RSECflag
?
4786 gather_attrs(item
, MIB2_TCP
, MIB2_TCP_CONN
, tcpConnEntrySize
) :
4788 v6_attrs
= family_selected(AF_INET6
) && RSECflag
?
4789 gather_attrs(item
, MIB2_TCP6
, MIB2_TCP6_CONN
, tcp6ConnEntrySize
) :
4795 for (; item
!= NULL
; item
= item
->next_item
) {
4797 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
4798 (void) printf("Group = %d, mib_id = %d, "
4799 "length = %d, valp = 0x%p\n",
4800 item
->group
, item
->mib_id
,
4801 item
->length
, item
->valp
);
4804 if (!((item
->group
== MIB2_TCP
&&
4805 item
->mib_id
== MIB2_TCP_CONN
) ||
4806 (item
->group
== MIB2_TCP6
&&
4807 item
->mib_id
== MIB2_TCP6_CONN
)))
4808 continue; /* 'for' loop 1 */
4810 if (item
->group
== MIB2_TCP
&& !family_selected(AF_INET
))
4811 continue; /* 'for' loop 1 */
4812 else if (item
->group
== MIB2_TCP6
&& !family_selected(AF_INET6
))
4813 continue; /* 'for' loop 1 */
4815 if (item
->group
== MIB2_TCP
) {
4816 for (tp
= (mib2_tcpConnEntry_t
*)item
->valp
;
4817 (char *)tp
< (char *)item
->valp
+ item
->length
;
4818 /* LINTED: (note 1) */
4819 tp
= (mib2_tcpConnEntry_t
*)((char *)tp
+
4820 tcpConnEntrySize
)) {
4821 aptr
= v4a
== NULL
? NULL
: *v4a
++;
4822 print_hdr_once_v4
= tcp_report_item_v4(tp
,
4823 print_hdr_once_v4
, aptr
);
4826 for (tp6
= (mib2_tcp6ConnEntry_t
*)item
->valp
;
4827 (char *)tp6
< (char *)item
->valp
+ item
->length
;
4828 /* LINTED: (note 1) */
4829 tp6
= (mib2_tcp6ConnEntry_t
*)((char *)tp6
+
4830 tcp6ConnEntrySize
)) {
4831 aptr
= v6a
== NULL
? NULL
: *v6a
++;
4832 print_hdr_once_v6
= tcp_report_item_v6(tp6
,
4833 print_hdr_once_v6
, aptr
);
4836 } /* 'for' loop 1 ends */
4837 (void) fflush(stdout
);
4839 if (v4_attrs
!= NULL
)
4841 if (v6_attrs
!= NULL
)
4846 tcp_report_item_v4(const mib2_tcpConnEntry_t
*tp
, boolean_t first
,
4847 const mib2_transportMLPEntry_t
*attr
)
4850 * lname and fname below are for the hostname as well as the portname
4851 * There is no limit on portname length so we assume MAXHOSTNAMELEN
4854 char lname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
4855 char fname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
4857 if (!(Aflag
|| tp
->tcpConnEntryInfo
.ce_state
>= TCPS_ESTABLISHED
))
4858 return (first
); /* Nothing to print */
4861 (void) printf(v4compat
? tcp_hdr_v4_compat
: tcp_hdr_v4
);
4862 (void) printf(Vflag
? tcp_hdr_v4_verbose
: tcp_hdr_v4_normal
);
4866 (void) printf("%-20s\n%-20s %5u %08x %08x %5u %08x %08x "
4868 pr_ap(tp
->tcpConnLocalAddress
,
4869 tp
->tcpConnLocalPort
, "tcp", lname
, sizeof (lname
)),
4870 pr_ap(tp
->tcpConnRemAddress
,
4871 tp
->tcpConnRemPort
, "tcp", fname
, sizeof (fname
)),
4872 tp
->tcpConnEntryInfo
.ce_swnd
,
4873 tp
->tcpConnEntryInfo
.ce_snxt
,
4874 tp
->tcpConnEntryInfo
.ce_suna
,
4875 tp
->tcpConnEntryInfo
.ce_rwnd
,
4876 tp
->tcpConnEntryInfo
.ce_rnxt
,
4877 tp
->tcpConnEntryInfo
.ce_rack
,
4878 tp
->tcpConnEntryInfo
.ce_rto
,
4879 tp
->tcpConnEntryInfo
.ce_mss
,
4880 mitcp_state(tp
->tcpConnEntryInfo
.ce_state
, attr
));
4882 int sq
= (int)tp
->tcpConnEntryInfo
.ce_snxt
-
4883 (int)tp
->tcpConnEntryInfo
.ce_suna
- 1;
4884 int rq
= (int)tp
->tcpConnEntryInfo
.ce_rnxt
-
4885 (int)tp
->tcpConnEntryInfo
.ce_rack
;
4887 (void) printf("%-20s %-20s %5u %6d %5u %6d %s\n",
4888 pr_ap(tp
->tcpConnLocalAddress
,
4889 tp
->tcpConnLocalPort
, "tcp", lname
, sizeof (lname
)),
4890 pr_ap(tp
->tcpConnRemAddress
,
4891 tp
->tcpConnRemPort
, "tcp", fname
, sizeof (fname
)),
4892 tp
->tcpConnEntryInfo
.ce_swnd
,
4894 tp
->tcpConnEntryInfo
.ce_rwnd
,
4896 mitcp_state(tp
->tcpConnEntryInfo
.ce_state
, attr
));
4899 print_transport_label(attr
);
4905 tcp_report_item_v6(const mib2_tcp6ConnEntry_t
*tp6
, boolean_t first
,
4906 const mib2_transportMLPEntry_t
*attr
)
4909 * lname and fname below are for the hostname as well as the portname
4910 * There is no limit on portname length so we assume MAXHOSTNAMELEN
4913 char lname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
4914 char fname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
4915 char ifname
[LIFNAMSIZ
+ 1];
4918 if (!(Aflag
|| tp6
->tcp6ConnEntryInfo
.ce_state
>= TCPS_ESTABLISHED
))
4919 return (first
); /* Nothing to print */
4922 (void) printf(tcp_hdr_v6
);
4923 (void) printf(Vflag
? tcp_hdr_v6_verbose
: tcp_hdr_v6_normal
);
4926 ifnamep
= (tp6
->tcp6ConnIfIndex
!= 0) ?
4927 if_indextoname(tp6
->tcp6ConnIfIndex
, ifname
) : NULL
;
4928 if (ifnamep
== NULL
)
4932 (void) printf("%-33s\n%-33s %5u %08x %08x %5u %08x %08x "
4933 "%5u %5u %-11s %s\n",
4934 pr_ap6(&tp6
->tcp6ConnLocalAddress
,
4935 tp6
->tcp6ConnLocalPort
, "tcp", lname
, sizeof (lname
)),
4936 pr_ap6(&tp6
->tcp6ConnRemAddress
,
4937 tp6
->tcp6ConnRemPort
, "tcp", fname
, sizeof (fname
)),
4938 tp6
->tcp6ConnEntryInfo
.ce_swnd
,
4939 tp6
->tcp6ConnEntryInfo
.ce_snxt
,
4940 tp6
->tcp6ConnEntryInfo
.ce_suna
,
4941 tp6
->tcp6ConnEntryInfo
.ce_rwnd
,
4942 tp6
->tcp6ConnEntryInfo
.ce_rnxt
,
4943 tp6
->tcp6ConnEntryInfo
.ce_rack
,
4944 tp6
->tcp6ConnEntryInfo
.ce_rto
,
4945 tp6
->tcp6ConnEntryInfo
.ce_mss
,
4946 mitcp_state(tp6
->tcp6ConnEntryInfo
.ce_state
, attr
),
4949 int sq
= (int)tp6
->tcp6ConnEntryInfo
.ce_snxt
-
4950 (int)tp6
->tcp6ConnEntryInfo
.ce_suna
- 1;
4951 int rq
= (int)tp6
->tcp6ConnEntryInfo
.ce_rnxt
-
4952 (int)tp6
->tcp6ConnEntryInfo
.ce_rack
;
4954 (void) printf("%-33s %-33s %5u %6d %5u %6d %-11s %s\n",
4955 pr_ap6(&tp6
->tcp6ConnLocalAddress
,
4956 tp6
->tcp6ConnLocalPort
, "tcp", lname
, sizeof (lname
)),
4957 pr_ap6(&tp6
->tcp6ConnRemAddress
,
4958 tp6
->tcp6ConnRemPort
, "tcp", fname
, sizeof (fname
)),
4959 tp6
->tcp6ConnEntryInfo
.ce_swnd
,
4961 tp6
->tcp6ConnEntryInfo
.ce_rwnd
,
4963 mitcp_state(tp6
->tcp6ConnEntryInfo
.ce_state
, attr
),
4967 print_transport_label(attr
);
4972 /* ------------------------------- UDP_REPORT------------------------------- */
4974 static boolean_t
udp_report_item_v4(const mib2_udpEntry_t
*ude
,
4975 boolean_t first
, const mib2_transportMLPEntry_t
*attr
);
4976 static boolean_t
udp_report_item_v6(const mib2_udp6Entry_t
*ude6
,
4977 boolean_t first
, const mib2_transportMLPEntry_t
*attr
);
4979 static const char udp_hdr_v4
[] =
4980 " Local Address Remote Address State\n"
4981 "-------------------- -------------------- ----------\n";
4983 static const char udp_hdr_v6
[] =
4984 " Local Address Remote Address "
4986 "--------------------------------- --------------------------------- "
4987 "---------- -----\n";
4990 udp_report(const mib_item_t
*item
)
4993 boolean_t print_hdr_once_v4
= B_TRUE
;
4994 boolean_t print_hdr_once_v6
= B_TRUE
;
4995 mib2_udpEntry_t
*ude
;
4996 mib2_udp6Entry_t
*ude6
;
4997 mib2_transportMLPEntry_t
**v4_attrs
, **v6_attrs
;
4998 mib2_transportMLPEntry_t
**v4a
, **v6a
;
4999 mib2_transportMLPEntry_t
*aptr
;
5001 if (!protocol_selected(IPPROTO_UDP
))
5005 * Preparation pass: the kernel returns separate entries for UDP
5006 * connection table entries and Multilevel Port attributes. We loop
5007 * through the attributes first and set up an array for each address
5010 v4_attrs
= family_selected(AF_INET
) && RSECflag
?
5011 gather_attrs(item
, MIB2_UDP
, MIB2_UDP_ENTRY
, udpEntrySize
) : NULL
;
5012 v6_attrs
= family_selected(AF_INET6
) && RSECflag
?
5013 gather_attrs(item
, MIB2_UDP6
, MIB2_UDP6_ENTRY
, udp6EntrySize
) :
5019 for (; item
; item
= item
->next_item
) {
5021 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
5022 (void) printf("Group = %d, mib_id = %d, "
5023 "length = %d, valp = 0x%p\n",
5024 item
->group
, item
->mib_id
,
5025 item
->length
, item
->valp
);
5027 if (!((item
->group
== MIB2_UDP
&&
5028 item
->mib_id
== MIB2_UDP_ENTRY
) ||
5029 (item
->group
== MIB2_UDP6
&&
5030 item
->mib_id
== MIB2_UDP6_ENTRY
)))
5031 continue; /* 'for' loop 1 */
5033 if (item
->group
== MIB2_UDP
&& !family_selected(AF_INET
))
5034 continue; /* 'for' loop 1 */
5035 else if (item
->group
== MIB2_UDP6
&& !family_selected(AF_INET6
))
5036 continue; /* 'for' loop 1 */
5038 /* xxx.xxx.xxx.xxx,pppp sss... */
5039 if (item
->group
== MIB2_UDP
) {
5040 for (ude
= (mib2_udpEntry_t
*)item
->valp
;
5041 (char *)ude
< (char *)item
->valp
+ item
->length
;
5042 /* LINTED: (note 1) */
5043 ude
= (mib2_udpEntry_t
*)((char *)ude
+
5045 aptr
= v4a
== NULL
? NULL
: *v4a
++;
5046 print_hdr_once_v4
= udp_report_item_v4(ude
,
5047 print_hdr_once_v4
, aptr
);
5050 for (ude6
= (mib2_udp6Entry_t
*)item
->valp
;
5051 (char *)ude6
< (char *)item
->valp
+ item
->length
;
5052 /* LINTED: (note 1) */
5053 ude6
= (mib2_udp6Entry_t
*)((char *)ude6
+
5055 aptr
= v6a
== NULL
? NULL
: *v6a
++;
5056 print_hdr_once_v6
= udp_report_item_v6(ude6
,
5057 print_hdr_once_v6
, aptr
);
5060 } /* 'for' loop 1 ends */
5061 (void) fflush(stdout
);
5063 if (v4_attrs
!= NULL
)
5065 if (v6_attrs
!= NULL
)
5070 udp_report_item_v4(const mib2_udpEntry_t
*ude
, boolean_t first
,
5071 const mib2_transportMLPEntry_t
*attr
)
5073 char lname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
5074 /* hostname + portname */
5076 if (!(Aflag
|| ude
->udpEntryInfo
.ue_state
>= MIB2_UDP_connected
))
5077 return (first
); /* Nothing to print */
5080 (void) printf(v4compat
? "\nUDP\n" : "\nUDP: IPv4\n");
5081 (void) printf(udp_hdr_v4
);
5085 (void) printf("%-20s ",
5086 pr_ap(ude
->udpLocalAddress
, ude
->udpLocalPort
, "udp",
5087 lname
, sizeof (lname
)));
5088 (void) printf("%-20s %s\n",
5089 ude
->udpEntryInfo
.ue_state
== MIB2_UDP_connected
?
5090 pr_ap(ude
->udpEntryInfo
.ue_RemoteAddress
,
5091 ude
->udpEntryInfo
.ue_RemotePort
, "udp", lname
, sizeof (lname
)) :
5093 miudp_state(ude
->udpEntryInfo
.ue_state
, attr
));
5095 print_transport_label(attr
);
5101 udp_report_item_v6(const mib2_udp6Entry_t
*ude6
, boolean_t first
,
5102 const mib2_transportMLPEntry_t
*attr
)
5104 char lname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
5105 /* hostname + portname */
5106 char ifname
[LIFNAMSIZ
+ 1];
5107 const char *ifnamep
;
5109 if (!(Aflag
|| ude6
->udp6EntryInfo
.ue_state
>= MIB2_UDP_connected
))
5110 return (first
); /* Nothing to print */
5113 (void) printf("\nUDP: IPv6\n");
5114 (void) printf(udp_hdr_v6
);
5118 ifnamep
= (ude6
->udp6IfIndex
!= 0) ?
5119 if_indextoname(ude6
->udp6IfIndex
, ifname
) : NULL
;
5121 (void) printf("%-33s ",
5122 pr_ap6(&ude6
->udp6LocalAddress
,
5123 ude6
->udp6LocalPort
, "udp", lname
, sizeof (lname
)));
5124 (void) printf("%-33s %-10s %s\n",
5125 ude6
->udp6EntryInfo
.ue_state
== MIB2_UDP_connected
?
5126 pr_ap6(&ude6
->udp6EntryInfo
.ue_RemoteAddress
,
5127 ude6
->udp6EntryInfo
.ue_RemotePort
, "udp", lname
, sizeof (lname
)) :
5129 miudp_state(ude6
->udp6EntryInfo
.ue_state
, attr
),
5130 ifnamep
== NULL
? "" : ifnamep
);
5132 print_transport_label(attr
);
5137 /* ------------------------------ SCTP_REPORT------------------------------- */
5139 static const char sctp_hdr
[] =
5141 static const char sctp_hdr_normal
[] =
5142 " Local Address Remote Address "
5143 "Swind Send-Q Rwind Recv-Q StrsI/O State\n"
5144 "------------------------------- ------------------------------- "
5145 "------ ------ ------ ------ ------- -----------";
5148 nssctp_state(int state
, const mib2_transportMLPEntry_t
*attr
)
5150 static char sctpsbuf
[50];
5154 case MIB2_SCTP_closed
:
5157 case MIB2_SCTP_cookieWait
:
5160 case MIB2_SCTP_cookieEchoed
:
5161 cp
= "COOKIE_ECHOED";
5163 case MIB2_SCTP_established
:
5166 case MIB2_SCTP_shutdownPending
:
5167 cp
= "SHUTDOWN_PENDING";
5169 case MIB2_SCTP_shutdownSent
:
5170 cp
= "SHUTDOWN_SENT";
5172 case MIB2_SCTP_shutdownReceived
:
5173 cp
= "SHUTDOWN_RECEIVED";
5175 case MIB2_SCTP_shutdownAckSent
:
5176 cp
= "SHUTDOWN_ACK_SENT";
5178 case MIB2_SCTP_listen
:
5182 (void) snprintf(sctpsbuf
, sizeof (sctpsbuf
),
5183 "UNKNOWN STATE(%d)", state
);
5188 if (RSECflag
&& attr
!= NULL
&& attr
->tme_flags
!= 0) {
5189 if (cp
!= sctpsbuf
) {
5190 (void) strlcpy(sctpsbuf
, cp
, sizeof (sctpsbuf
));
5193 if (attr
->tme_flags
& MIB2_TMEF_PRIVATE
)
5194 (void) strlcat(sctpsbuf
, " P", sizeof (sctpsbuf
));
5195 if (attr
->tme_flags
& MIB2_TMEF_SHARED
)
5196 (void) strlcat(sctpsbuf
, " S", sizeof (sctpsbuf
));
5202 static const mib2_sctpConnRemoteEntry_t
*
5203 sctp_getnext_rem(const mib_item_t
**itemp
,
5204 const mib2_sctpConnRemoteEntry_t
*current
, uint32_t associd
)
5206 const mib_item_t
*item
= *itemp
;
5207 const mib2_sctpConnRemoteEntry_t
*sre
;
5209 for (; item
!= NULL
; item
= item
->next_item
, current
= NULL
) {
5210 if (!(item
->group
== MIB2_SCTP
&&
5211 item
->mib_id
== MIB2_SCTP_CONN_REMOTE
)) {
5215 if (current
!= NULL
) {
5216 /* LINTED: (note 1) */
5217 sre
= (const mib2_sctpConnRemoteEntry_t
*)
5218 ((const char *)current
+ sctpRemoteEntrySize
);
5222 for (; (char *)sre
< (char *)item
->valp
+ item
->length
;
5223 /* LINTED: (note 1) */
5224 sre
= (const mib2_sctpConnRemoteEntry_t
*)
5225 ((const char *)sre
+ sctpRemoteEntrySize
)) {
5226 if (sre
->sctpAssocId
!= associd
) {
5237 static const mib2_sctpConnLocalEntry_t
*
5238 sctp_getnext_local(const mib_item_t
**itemp
,
5239 const mib2_sctpConnLocalEntry_t
*current
, uint32_t associd
)
5241 const mib_item_t
*item
= *itemp
;
5242 const mib2_sctpConnLocalEntry_t
*sle
;
5244 for (; item
!= NULL
; item
= item
->next_item
, current
= NULL
) {
5245 if (!(item
->group
== MIB2_SCTP
&&
5246 item
->mib_id
== MIB2_SCTP_CONN_LOCAL
)) {
5250 if (current
!= NULL
) {
5251 /* LINTED: (note 1) */
5252 sle
= (const mib2_sctpConnLocalEntry_t
*)
5253 ((const char *)current
+ sctpLocalEntrySize
);
5257 for (; (char *)sle
< (char *)item
->valp
+ item
->length
;
5258 /* LINTED: (note 1) */
5259 sle
= (const mib2_sctpConnLocalEntry_t
*)
5260 ((const char *)sle
+ sctpLocalEntrySize
)) {
5261 if (sle
->sctpAssocId
!= associd
) {
5273 sctp_pr_addr(int type
, char *name
, int namelen
, const in6_addr_t
*addr
,
5280 * Address is either a v4 mapped or v6 addr. If
5281 * it's a v4 mapped, convert to v4 before
5285 case MIB2_SCTP_ADDR_V4
:
5289 IN6_V4MAPPED_TO_IPADDR(&v6addr
, v4addr
);
5291 (void) pr_ap(v4addr
, port
, "sctp", name
, namelen
);
5293 (void) pr_addr(v4addr
, name
, namelen
);
5297 case MIB2_SCTP_ADDR_V6
:
5300 (void) pr_ap6(addr
, port
, "sctp", name
, namelen
);
5302 (void) pr_addr6(addr
, name
, namelen
);
5307 (void) snprintf(name
, namelen
, "<unknown addr type>");
5313 sctp_conn_report_item(const mib_item_t
*head
, const mib2_sctpConnEntry_t
*sp
,
5314 const mib2_transportMLPEntry_t
*attr
)
5316 char lname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
5317 char fname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
5318 const mib2_sctpConnRemoteEntry_t
*sre
= NULL
;
5319 const mib2_sctpConnLocalEntry_t
*sle
= NULL
;
5320 const mib_item_t
*local
= head
;
5321 const mib_item_t
*remote
= head
;
5322 uint32_t id
= sp
->sctpAssocId
;
5323 boolean_t printfirst
= B_TRUE
;
5325 sctp_pr_addr(sp
->sctpAssocRemPrimAddrType
, fname
, sizeof (fname
),
5326 &sp
->sctpAssocRemPrimAddr
, sp
->sctpAssocRemPort
);
5327 sctp_pr_addr(sp
->sctpAssocRemPrimAddrType
, lname
, sizeof (lname
),
5328 &sp
->sctpAssocLocPrimAddr
, sp
->sctpAssocLocalPort
);
5330 (void) printf("%-31s %-31s %6u %6d %6u %6d %3d/%-3d %s\n",
5332 sp
->sctpConnEntryInfo
.ce_swnd
,
5333 sp
->sctpConnEntryInfo
.ce_sendq
,
5334 sp
->sctpConnEntryInfo
.ce_rwnd
,
5335 sp
->sctpConnEntryInfo
.ce_recvq
,
5336 sp
->sctpAssocInStreams
, sp
->sctpAssocOutStreams
,
5337 nssctp_state(sp
->sctpAssocState
, attr
));
5339 print_transport_label(attr
);
5345 /* Print remote addresses/local addresses on following lines */
5346 while ((sre
= sctp_getnext_rem(&remote
, sre
, id
)) != NULL
) {
5347 if (!IN6_ARE_ADDR_EQUAL(&sre
->sctpAssocRemAddr
,
5348 &sp
->sctpAssocRemPrimAddr
)) {
5349 if (printfirst
== B_TRUE
) {
5350 (void) fputs("\t<Remote: ", stdout
);
5351 printfirst
= B_FALSE
;
5353 (void) fputs(", ", stdout
);
5355 sctp_pr_addr(sre
->sctpAssocRemAddrType
, fname
,
5356 sizeof (fname
), &sre
->sctpAssocRemAddr
, -1);
5357 if (sre
->sctpAssocRemAddrActive
== MIB2_SCTP_ACTIVE
) {
5358 (void) fputs(fname
, stdout
);
5360 (void) printf("(%s)", fname
);
5364 if (printfirst
== B_FALSE
) {
5366 printfirst
= B_TRUE
;
5368 while ((sle
= sctp_getnext_local(&local
, sle
, id
)) != NULL
) {
5369 if (!IN6_ARE_ADDR_EQUAL(&sle
->sctpAssocLocalAddr
,
5370 &sp
->sctpAssocLocPrimAddr
)) {
5371 if (printfirst
== B_TRUE
) {
5372 (void) fputs("\t<Local: ", stdout
);
5373 printfirst
= B_FALSE
;
5375 (void) fputs(", ", stdout
);
5377 sctp_pr_addr(sle
->sctpAssocLocalAddrType
, lname
,
5378 sizeof (lname
), &sle
->sctpAssocLocalAddr
, -1);
5379 (void) fputs(lname
, stdout
);
5382 if (printfirst
== B_FALSE
) {
5388 sctp_report(const mib_item_t
*item
)
5390 const mib_item_t
*head
;
5391 const mib2_sctpConnEntry_t
*sp
;
5392 boolean_t first
= B_TRUE
;
5393 mib2_transportMLPEntry_t
**attrs
, **aptr
;
5394 mib2_transportMLPEntry_t
*attr
;
5397 * Preparation pass: the kernel returns separate entries for SCTP
5398 * connection table entries and Multilevel Port attributes. We loop
5399 * through the attributes first and set up an array for each address
5403 gather_attrs(item
, MIB2_SCTP
, MIB2_SCTP_CONN
, sctpEntrySize
) :
5408 for (; item
!= NULL
; item
= item
->next_item
) {
5410 if (!(item
->group
== MIB2_SCTP
&&
5411 item
->mib_id
== MIB2_SCTP_CONN
))
5414 for (sp
= item
->valp
;
5415 (char *)sp
< (char *)item
->valp
+ item
->length
;
5416 /* LINTED: (note 1) */
5417 sp
= (mib2_sctpConnEntry_t
*)((char *)sp
+ sctpEntrySize
)) {
5418 attr
= aptr
== NULL
? NULL
: *aptr
++;
5420 sp
->sctpAssocState
>= MIB2_SCTP_established
) {
5421 if (first
== B_TRUE
) {
5422 (void) puts(sctp_hdr
);
5423 (void) puts(sctp_hdr_normal
);
5426 sctp_conn_report_item(head
, sp
, attr
);
5437 return (n
!= 1 ? "s" : "");
5443 return (n
!= 1 ? "ies" : "y");
5449 return (n
!= 1 ? "es" : "");
5461 } else if (n
< 1024 * 1024) {
5464 } else if (n
< 1024 * 1024 * 1024) {
5469 n
/= 1024 * 1024 * 1024;
5472 (void) snprintf(buf
, sizeof (buf
), "%4u%c", n
, t
);
5476 /* --------------------- mrt_report (netstat -m) -------------------------- */
5479 mrt_report(mib_item_t
*item
)
5484 struct mfcctl
*mfccp
;
5487 char abuf
[MAXHOSTNAMELEN
+ 1];
5489 if (!(family_selected(AF_INET
)))
5493 for (; item
; item
= item
->next_item
) {
5495 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
5496 (void) printf("Group = %d, mib_id = %d, "
5497 "length = %d, valp = 0x%p\n",
5498 item
->group
, item
->mib_id
, item
->length
,
5501 if (item
->group
!= EXPER_DVMRP
)
5502 continue; /* 'for' loop 1 */
5504 switch (item
->mib_id
) {
5506 case EXPER_DVMRP_VIF
:
5508 (void) printf("%u records for ipVifTable:\n",
5509 item
->length
/sizeof (struct vifctl
));
5510 if (item
->length
/sizeof (struct vifctl
) == 0) {
5511 (void) puts("\nVirtual Interface Table is "
5516 (void) puts("\nVirtual Interface Table\n"
5517 " Vif Threshold Rate_Limit Local-Address"
5518 " Remote-Address Pkt_in Pkt_out");
5521 for (vip
= (struct vifctl
*)item
->valp
;
5522 (char *)vip
< (char *)item
->valp
+ item
->length
;
5523 /* LINTED: (note 1) */
5524 vip
= (struct vifctl
*)((char *)vip
+
5526 if (vip
->vifc_lcl_addr
.s_addr
== 0)
5527 continue; /* 'for' loop 2 */
5528 /* numvifs = vip->vifc_vifi; */
5531 (void) printf(" %2u %3u "
5534 vip
->vifc_threshold
,
5535 vip
->vifc_rate_limit
,
5536 pr_addr(vip
->vifc_lcl_addr
.s_addr
,
5537 abuf
, sizeof (abuf
)));
5538 (void) printf(" %-15.15s %8u %8u\n",
5539 (vip
->vifc_flags
& VIFF_TUNNEL
) ?
5540 pr_addr(vip
->vifc_rmt_addr
.s_addr
,
5541 abuf
, sizeof (abuf
)) : "",
5544 } /* 'for' loop 2 ends */
5546 (void) printf("Numvifs: %d\n", numvifs
);
5549 case EXPER_DVMRP_MRT
:
5551 (void) printf("%u records for ipMfcTable:\n",
5552 item
->length
/sizeof (struct vifctl
));
5553 if (item
->length
/sizeof (struct vifctl
) == 0) {
5554 (void) puts("\nMulticast Forwarding Cache is "
5559 (void) puts("\nMulticast Forwarding Cache\n"
5560 " Origin-Subnet Mcastgroup "
5561 "# Pkts In-Vif Out-vifs/Forw-ttl");
5563 for (mfccp
= (struct mfcctl
*)item
->valp
;
5564 (char *)mfccp
< (char *)item
->valp
+ item
->length
;
5565 /* LINTED: (note 1) */
5566 mfccp
= (struct mfcctl
*)((char *)mfccp
+
5570 (void) printf(" %-30.15s",
5571 pr_addr(mfccp
->mfcc_origin
.s_addr
,
5572 abuf
, sizeof (abuf
)));
5573 (void) printf("%-15.15s %6s %3u ",
5574 pr_net(mfccp
->mfcc_mcastgrp
.s_addr
,
5575 mfccp
->mfcc_mcastgrp
.s_addr
,
5576 abuf
, sizeof (abuf
)),
5577 pktscale((int)mfccp
->mfcc_pkt_cnt
),
5578 mfccp
->mfcc_parent
);
5580 for (vifi
= 0; vifi
< MAXVIFS
; ++vifi
) {
5581 if (mfccp
->mfcc_ttls
[vifi
]) {
5582 (void) printf(" %u (%u)",
5584 mfccp
->mfcc_ttls
[vifi
]);
5588 (void) putchar('\n');
5590 (void) printf("\nTotal no. of entries in cache: %d\n",
5594 } /* 'for' loop 1 ends */
5595 (void) putchar('\n');
5596 (void) fflush(stdout
);
5600 * Get the stats for the cache named 'name'. If prefix != 0, then
5601 * interpret the name as a prefix, and sum up stats for all caches
5605 kmem_cache_stats(char *title
, char *name
, int prefix
, int64_t *total_bytes
)
5609 int64_t total_alloc
= 0;
5610 int alloc_fail
, total_alloc_fail
= 0;
5614 int buf_max
, total_buf_max
= 0;
5615 int buf_inuse
, total_buf_inuse
= 0;
5619 len
= prefix
? strlen(name
) : 256;
5622 for (ksp
= kc
->kc_chain
; ksp
!= NULL
; ksp
= ksp
->ks_next
) {
5624 if (strcmp(ksp
->ks_class
, "kmem_cache") != 0)
5625 continue; /* 'for' loop 1 */
5628 * Hack alert: because of the way streams messages are
5629 * allocated, every constructed free dblk has an associated
5630 * mblk. From the allocator's viewpoint those mblks are
5631 * allocated (because they haven't been freed), but from
5632 * our viewpoint they're actually free (because they're
5633 * not currently in use). To account for this caching
5634 * effect we subtract the total constructed free dblks
5635 * from the total allocated mblks to derive mblks in use.
5637 if (strcmp(name
, "streams_mblk") == 0 &&
5638 strncmp(ksp
->ks_name
, "streams_dblk", 12) == 0) {
5639 (void) safe_kstat_read(kc
, ksp
, NULL
);
5641 kstat_named_value(ksp
, "buf_constructed");
5642 continue; /* 'for' loop 1 */
5645 if (strncmp(ksp
->ks_name
, name
, len
) != 0)
5646 continue; /* 'for' loop 1 */
5648 (void) safe_kstat_read(kc
, ksp
, NULL
);
5650 alloc
= kstat_named_value(ksp
, "alloc");
5651 alloc_fail
= kstat_named_value(ksp
, "alloc_fail");
5652 buf_size
= kstat_named_value(ksp
, "buf_size");
5653 buf_avail
= kstat_named_value(ksp
, "buf_avail");
5654 buf_total
= kstat_named_value(ksp
, "buf_total");
5655 buf_max
= kstat_named_value(ksp
, "buf_max");
5656 buf_inuse
= buf_total
- buf_avail
;
5658 if (Vflag
&& prefix
) {
5659 (void) snprintf(buf
, sizeof (buf
), "%s%s", title
,
5660 ksp
->ks_name
+ len
);
5661 (void) printf(" %-18s %6u %9u %11u %11u\n",
5662 buf
, buf_inuse
, buf_max
, alloc
, alloc_fail
);
5665 total_alloc
+= alloc
;
5666 total_alloc_fail
+= alloc_fail
;
5667 total_buf_max
+= buf_max
;
5668 total_buf_inuse
+= buf_inuse
;
5669 *total_bytes
+= (int64_t)buf_inuse
* buf_size
;
5670 } /* 'for' loop 1 ends */
5672 if (buf_size
== 0) {
5673 (void) printf("%-22s [couldn't find statistics for %s]\n",
5678 if (Vflag
&& prefix
)
5679 (void) snprintf(buf
, sizeof (buf
), "%s_total", title
);
5681 (void) snprintf(buf
, sizeof (buf
), "%s", title
);
5683 (void) printf("%-22s %6d %9d %11lld %11d\n", buf
,
5684 total_buf_inuse
, total_buf_max
, total_alloc
, total_alloc_fail
);
5690 int64_t total_bytes
= 0;
5692 (void) puts("streams allocation:");
5693 (void) printf("%63s\n", "cumulative allocation");
5694 (void) printf("%63s\n",
5695 "current maximum total failures");
5697 kmem_cache_stats("streams",
5698 "stream_head_cache", 0, &total_bytes
);
5699 kmem_cache_stats("queues", "queue_cache", 0, &total_bytes
);
5700 kmem_cache_stats("mblk", "streams_mblk", 0, &total_bytes
);
5701 kmem_cache_stats("dblk", "streams_dblk", 1, &total_bytes
);
5702 kmem_cache_stats("linkblk", "linkinfo_cache", 0, &total_bytes
);
5703 kmem_cache_stats("syncq", "syncq_cache", 0, &total_bytes
);
5704 kmem_cache_stats("qband", "qband_cache", 0, &total_bytes
);
5706 (void) printf("\n%lld Kbytes allocated for streams data\n",
5707 total_bytes
/ 1024);
5709 (void) putchar('\n');
5710 (void) fflush(stdout
);
5713 /* --------------------------------- */
5716 * Print an IPv4 address. Remove the matching part of the domain name
5717 * from the returned name.
5720 pr_addr(uint_t addr
, char *dst
, uint_t dstlen
)
5723 struct hostent
*hp
= NULL
;
5724 static char domain
[MAXHOSTNAMELEN
+ 1];
5725 static boolean_t first
= B_TRUE
;
5730 if (sysinfo(SI_HOSTNAME
, domain
, MAXHOSTNAMELEN
) != -1 &&
5731 (cp
= strchr(domain
, '.'))) {
5732 (void) strncpy(domain
, cp
+ 1, sizeof (domain
));
5738 hp
= getipnodebyaddr((char *)&addr
, sizeof (uint_t
), AF_INET
,
5741 if ((cp
= strchr(hp
->h_name
, '.')) != NULL
&&
5742 strcasecmp(cp
+ 1, domain
) == 0)
5748 (void) strncpy(dst
, cp
, dstlen
);
5749 dst
[dstlen
- 1] = 0;
5751 (void) inet_ntop(AF_INET
, (char *)&addr
, dst
, dstlen
);
5759 * Print a non-zero IPv4 address. Print " --" if the address is zero.
5762 pr_addrnz(ipaddr_t addr
, char *dst
, uint_t dstlen
)
5764 if (addr
== INADDR_ANY
) {
5765 (void) strlcpy(dst
, " --", dstlen
);
5768 return (pr_addr(addr
, dst
, dstlen
));
5772 * Print an IPv6 address. Remove the matching part of the domain name
5773 * from the returned name.
5776 pr_addr6(const struct in6_addr
*addr
, char *dst
, uint_t dstlen
)
5779 struct hostent
*hp
= NULL
;
5780 static char domain
[MAXHOSTNAMELEN
+ 1];
5781 static boolean_t first
= B_TRUE
;
5786 if (sysinfo(SI_HOSTNAME
, domain
, MAXHOSTNAMELEN
) != -1 &&
5787 (cp
= strchr(domain
, '.'))) {
5788 (void) strncpy(domain
, cp
+ 1, sizeof (domain
));
5794 hp
= getipnodebyaddr((char *)addr
,
5795 sizeof (struct in6_addr
), AF_INET6
, &error_num
);
5797 if ((cp
= strchr(hp
->h_name
, '.')) != NULL
&&
5798 strcasecmp(cp
+ 1, domain
) == 0)
5804 (void) strncpy(dst
, cp
, dstlen
);
5805 dst
[dstlen
- 1] = 0;
5807 (void) inet_ntop(AF_INET6
, (void *)addr
, dst
, dstlen
);
5814 /* For IPv4 masks */
5816 pr_mask(uint_t addr
, char *dst
, uint_t dstlen
)
5818 uint8_t *ip_addr
= (uint8_t *)&addr
;
5820 (void) snprintf(dst
, dstlen
, "%d.%d.%d.%d",
5821 ip_addr
[0], ip_addr
[1], ip_addr
[2], ip_addr
[3]);
5826 * For ipv6 masks format is : dest/mask
5827 * Does not print /128 to save space in printout. H flag carries this notion.
5830 pr_prefix6(const struct in6_addr
*addr
, uint_t prefixlen
, char *dst
,
5835 if (IN6_IS_ADDR_UNSPECIFIED(addr
) && prefixlen
== 0) {
5836 (void) strncpy(dst
, "default", dstlen
);
5837 dst
[dstlen
- 1] = 0;
5841 (void) pr_addr6(addr
, dst
, dstlen
);
5842 if (prefixlen
!= IPV6_ABITS
) {
5843 /* How much room is left? */
5844 cp
= strchr(dst
, '\0');
5845 if (dst
+ dstlen
> cp
) {
5846 dstlen
-= (cp
- dst
);
5847 (void) snprintf(cp
, dstlen
, "/%d", prefixlen
);
5853 /* Print IPv4 address and port */
5855 pr_ap(uint_t addr
, uint_t port
, char *proto
,
5856 char *dst
, uint_t dstlen
)
5860 if (addr
== INADDR_ANY
) {
5861 (void) strncpy(dst
, " *", dstlen
);
5862 dst
[dstlen
- 1] = 0;
5864 (void) pr_addr(addr
, dst
, dstlen
);
5866 /* How much room is left? */
5867 cp
= strchr(dst
, '\0');
5868 if (dst
+ dstlen
> cp
+ 1) {
5870 dstlen
-= (cp
- dst
);
5872 (void) portname(port
, proto
, cp
, dstlen
);
5877 /* Print IPv6 address and port */
5879 pr_ap6(const in6_addr_t
*addr
, uint_t port
, char *proto
,
5880 char *dst
, uint_t dstlen
)
5884 if (IN6_IS_ADDR_UNSPECIFIED(addr
)) {
5885 (void) strncpy(dst
, " *", dstlen
);
5886 dst
[dstlen
- 1] = 0;
5888 (void) pr_addr6(addr
, dst
, dstlen
);
5890 /* How much room is left? */
5891 cp
= strchr(dst
, '\0');
5892 if (dst
+ dstlen
+ 1 > cp
) {
5894 dstlen
-= (cp
- dst
);
5896 (void) portname(port
, proto
, cp
, dstlen
);
5902 * Return the name of the network whose address is given. The address is
5903 * assumed to be that of a net or subnet, not a host.
5906 pr_net(uint_t addr
, uint_t mask
, char *dst
, uint_t dstlen
)
5909 struct netent
*np
= NULL
;
5910 struct hostent
*hp
= NULL
;
5915 if (addr
== INADDR_ANY
&& mask
== INADDR_ANY
) {
5916 (void) strncpy(dst
, "default", dstlen
);
5917 dst
[dstlen
- 1] = 0;
5921 if (!Nflag
&& addr
) {
5923 if (IN_CLASSA(addr
)) {
5924 mask
= (uint_t
)IN_CLASSA_NET
;
5926 } else if (IN_CLASSB(addr
)) {
5927 mask
= (uint_t
)IN_CLASSB_NET
;
5930 mask
= (uint_t
)IN_CLASSC_NET
;
5934 * If there are more bits than the standard mask
5935 * would suggest, subnets must be in use. Guess at
5936 * the subnet mask, assuming reasonable width subnet
5939 while (addr
& ~mask
)
5940 /* compiler doesn't sign extend! */
5941 mask
= (mask
| ((int)mask
>> subnetshift
));
5944 while ((mask
& 1) == 0)
5945 mask
>>= 1, net
>>= 1;
5946 np
= getnetbyaddr(net
, AF_INET
);
5947 if (np
&& np
->n_net
== net
)
5951 * Look for subnets in hosts map.
5953 hp
= getipnodebyaddr((char *)&addr
, sizeof (uint_t
),
5954 AF_INET
, &error_num
);
5960 (void) strncpy(dst
, cp
, dstlen
);
5961 dst
[dstlen
- 1] = 0;
5963 (void) inet_ntop(AF_INET
, (char *)&addr
, dst
, dstlen
);
5971 * Return the name of the network whose address is given.
5972 * The address is assumed to be a host address.
5975 pr_netaddr(uint_t addr
, uint_t mask
, char *dst
, uint_t dstlen
)
5978 struct netent
*np
= NULL
;
5979 struct hostent
*hp
= NULL
;
5985 uint_t nbo_addr
= addr
; /* network byte order */
5989 if (addr
== INADDR_ANY
&& mask
== INADDR_ANY
) {
5990 (void) strncpy(dst
, "default", dstlen
);
5991 dst
[dstlen
- 1] = 0;
5995 /* Figure out network portion of address (with host portion = 0) */
5997 /* Try figuring out mask if unknown (all 0s). */
5999 if (IN_CLASSA(addr
)) {
6000 mask
= (uint_t
)IN_CLASSA_NET
;
6002 } else if (IN_CLASSB(addr
)) {
6003 mask
= (uint_t
)IN_CLASSB_NET
;
6006 mask
= (uint_t
)IN_CLASSC_NET
;
6010 * If there are more bits than the standard mask
6011 * would suggest, subnets must be in use. Guess at
6012 * the subnet mask, assuming reasonable width subnet
6015 while (addr
& ~mask
)
6016 /* compiler doesn't sign extend! */
6017 mask
= (mask
| ((int)mask
>> subnetshift
));
6019 net
= netshifted
= addr
& mask
;
6020 while ((mask
& 1) == 0)
6021 mask
>>= 1, netshifted
>>= 1;
6024 net
= netshifted
= 0;
6026 /* Try looking up name unless -n was specified. */
6028 np
= getnetbyaddr(netshifted
, AF_INET
);
6029 if (np
&& np
->n_net
== netshifted
)
6033 * Look for subnets in hosts map.
6035 hp
= getipnodebyaddr((char *)&nbo_addr
, sizeof (uint_t
),
6036 AF_INET
, &error_num
);
6042 (void) strncpy(dst
, cp
, dstlen
);
6043 dst
[dstlen
- 1] = 0;
6049 * No name found for net: fallthru and return in decimal
6054 in
.s_addr
= htonl(net
);
6055 (void) inet_ntop(AF_INET
, (char *)&in
, dst
, dstlen
);
6062 * Return the filter mode as a string:
6065 * otherwise "<unknown>"
6068 fmodestr(uint_t fmode
)
6076 return ("<unknown>");
6080 #define MAX_STRING_SIZE 256
6083 pr_secattr(const sec_attr_list_t
*attrs
)
6086 char buf
[MAX_STRING_SIZE
+ 1], *cp
;
6088 static size_t sbuf_len
;
6090 const sec_attr_list_t
*aptr
;
6092 if (!RSECflag
|| attrs
== NULL
)
6095 for (aptr
= attrs
, i
= 1; aptr
!= NULL
; aptr
= aptr
->sal_next
)
6096 i
+= MAX_STRING_SIZE
;
6098 cp
= realloc(sbuf
, i
);
6100 perror("realloc security attribute buffer");
6108 while (attrs
!= NULL
) {
6109 const mib2_ipAttributeEntry_t
*iae
= attrs
->sal_attr
;
6111 /* note: effectively hard-coded in rtsa_keyword */
6112 rtsa
.rtsa_mask
= RTSA_CIPSO
| RTSA_SLRANGE
| RTSA_DOI
;
6113 rtsa
.rtsa_slrange
= iae
->iae_slrange
;
6114 rtsa
.rtsa_doi
= iae
->iae_doi
;
6116 (void) snprintf(cp
, MAX_STRING_SIZE
,
6117 "<%s>%s ", rtsa_to_str(&rtsa
, buf
, sizeof (buf
)),
6118 attrs
->sal_next
== NULL
? "" : ",");
6120 attrs
= attrs
->sal_next
;
6128 * Pretty print a port number. If the Nflag was
6129 * specified, use numbers instead of names.
6132 portname(uint_t port
, char *proto
, char *dst
, uint_t dstlen
)
6134 struct servent
*sp
= NULL
;
6137 sp
= getservbyport(htons(port
), proto
);
6138 if (sp
|| port
== 0)
6139 (void) snprintf(dst
, dstlen
, "%.*s", MAXHOSTNAMELEN
,
6140 sp
? sp
->s_name
: "*");
6142 (void) snprintf(dst
, dstlen
, "%d", port
);
6143 dst
[dstlen
- 1] = 0;
6149 fail(int do_perror
, char *message
, ...)
6153 va_start(args
, message
);
6154 (void) fputs("netstat: ", stderr
);
6155 (void) vfprintf(stderr
, message
, args
);
6158 (void) fprintf(stderr
, ": %s", strerror(errno
));
6159 (void) fputc('\n', stderr
);
6164 * Return value of named statistic for given kstat_named kstat;
6165 * return 0LL if named statistic is not in list (use "ll" as a
6166 * type qualifier when printing 64-bit int's with printf() )
6169 kstat_named_value(kstat_t
*ksp
, char *name
)
6177 knp
= kstat_data_lookup(ksp
, name
);
6181 switch (knp
->data_type
) {
6182 case KSTAT_DATA_INT32
:
6183 case KSTAT_DATA_UINT32
:
6184 value
= (uint64_t)(knp
->value
.ui32
);
6186 case KSTAT_DATA_INT64
:
6187 case KSTAT_DATA_UINT64
:
6188 value
= knp
->value
.ui64
;
6199 safe_kstat_read(kstat_ctl_t
*kc
, kstat_t
*ksp
, void *data
)
6201 kid_t kstat_chain_id
= kstat_read(kc
, ksp
, data
);
6203 if (kstat_chain_id
== -1)
6204 fail(1, "kstat_read(%p, '%s') failed", (void *)kc
,
6206 return (kstat_chain_id
);
6210 * Parse a list of IRE flag characters into a bit field.
6213 flag_bits(const char *arg
)
6219 fatal(1, "missing flag list\n");
6222 while (*arg
!= '\0') {
6223 if ((cp
= strchr(flag_list
, *arg
)) == NULL
)
6224 fatal(1, "%c: illegal flag\n", *arg
);
6225 val
|= 1 << (cp
- flag_list
);
6232 * Handle -f argument. Validate input format, sort by keyword, and
6233 * save off digested results.
6236 process_filter(char *arg
)
6248 /* Look up the keyword first */
6249 if (strchr(arg
, ':') == NULL
) {
6252 for (idx
= 0; idx
< NFILTERKEYS
; idx
++) {
6253 klen
= strlen(filter_keys
[idx
]);
6254 if (strncmp(filter_keys
[idx
], arg
, klen
) == 0 &&
6258 if (idx
>= NFILTERKEYS
)
6259 fatal(1, "%s: unknown filter keyword\n", arg
);
6261 /* Advance past keyword and separator. */
6265 if ((newf
= malloc(sizeof (*newf
))) == NULL
) {
6271 if (strcmp(arg
, "inet") == 0) {
6272 newf
->u
.f_family
= AF_INET
;
6273 } else if (strcmp(arg
, "inet6") == 0) {
6274 newf
->u
.f_family
= AF_INET6
;
6275 } else if (strcmp(arg
, "unix") == 0) {
6276 newf
->u
.f_family
= AF_UNIX
;
6278 newf
->u
.f_family
= strtol(arg
, &cp
, 0);
6279 if (arg
== cp
|| *cp
!= '\0')
6280 fatal(1, "%s: unknown address family.\n", arg
);
6285 if (strcmp(arg
, "none") == 0) {
6286 newf
->u
.f_ifname
= NULL
;
6289 if (strcmp(arg
, "any") == 0) {
6290 newf
->u
.f_ifname
= "";
6293 val
= strtol(arg
, &cp
, 0);
6294 if (val
<= 0 || arg
== cp
|| cp
[0] != '\0') {
6295 if ((val
= if_nametoindex(arg
)) == 0) {
6300 newf
->u
.f_ifname
= arg
;
6304 V4MASK_TO_V6(IP_HOST_MASK
, newf
->u
.a
.f_mask
);
6305 if (strcmp(arg
, "any") == 0) {
6306 /* Special semantics; any address *but* zero */
6307 newf
->u
.a
.f_address
= NULL
;
6308 (void) memset(&newf
->u
.a
.f_mask
, 0,
6309 sizeof (newf
->u
.a
.f_mask
));
6312 if (strcmp(arg
, "none") == 0) {
6313 newf
->u
.a
.f_address
= NULL
;
6316 if ((cp
= strrchr(arg
, '/')) != NULL
)
6318 hp
= getipnodebyname(arg
, AF_INET6
, AI_V4MAPPED
|AI_ALL
,
6321 fatal(1, "%s: invalid or unknown host address\n", arg
);
6322 newf
->u
.a
.f_address
= hp
;
6324 V4MASK_TO_V6(IP_HOST_MASK
, newf
->u
.a
.f_mask
);
6326 val
= strtol(cp
, &cp2
, 0);
6327 if (cp
!= cp2
&& cp2
[0] == '\0') {
6329 * If decode as "/n" works, then translate
6332 if (hp
->h_addr_list
[0] != NULL
&&
6333 /* LINTED: (note 1) */
6334 IN6_IS_ADDR_V4MAPPED((in6_addr_t
*)
6335 hp
->h_addr_list
[0])) {
6340 if (val
< 0 || val
>= maxv
)
6341 fatal(1, "%d: not in range 0 to %d\n",
6343 if (maxv
== IP_ABITS
)
6344 val
+= IPV6_ABITS
- IP_ABITS
;
6345 ucp
= newf
->u
.a
.f_mask
.s6_addr
;
6347 *ucp
++ = 0xff, val
-= 8;
6348 *ucp
++ = (0xff << (8 - val
)) & 0xff;
6349 while (ucp
< newf
->u
.a
.f_mask
.s6_addr
+
6350 sizeof (newf
->u
.a
.f_mask
.s6_addr
))
6352 /* Otherwise, try as numeric address */
6353 } else if (inet_pton(AF_INET6
,
6354 cp
, &newf
->u
.a
.f_mask
) <= 0) {
6355 fatal(1, "%s: illegal mask format\n", cp
);
6362 newf
->u
.f
.f_flagset
= flag_bits(arg
+ 1);
6363 newf
->u
.f
.f_flagclear
= 0;
6364 } else if (*arg
== '-') {
6365 newf
->u
.f
.f_flagset
= 0;
6366 newf
->u
.f
.f_flagclear
= flag_bits(arg
+ 1);
6368 newf
->u
.f
.f_flagset
= flag_bits(arg
);
6369 newf
->u
.f
.f_flagclear
= ~newf
->u
.f
.f_flagset
;
6376 newf
->f_next
= filters
[idx
];
6377 filters
[idx
] = newf
;
6380 /* Determine if user wants this address family printed. */
6382 family_selected(int family
)
6386 if (v4compat
&& family
== AF_INET6
)
6388 if ((fp
= filters
[FK_AF
]) == NULL
)
6390 while (fp
!= NULL
) {
6391 if (fp
->u
.f_family
== family
)
6399 * Convert the interface index to a string using the buffer `ifname', which
6400 * must be at least LIFNAMSIZ bytes. We first try to map it to name. If that
6401 * fails (e.g., because we're inside a zone and it does not have access to
6402 * interface for the index in question), just return "if#<num>".
6405 ifindex2str(uint_t ifindex
, char *ifname
)
6407 if (if_indextoname(ifindex
, ifname
) == NULL
)
6408 (void) snprintf(ifname
, LIFNAMSIZ
, "if#%d", ifindex
);
6414 * print the usage line
6417 usage(char *cmdname
)
6419 (void) fprintf(stderr
, "usage: %s [-anv] [-f address_family] "
6420 "[-T d|u]\n", cmdname
);
6421 (void) fprintf(stderr
, " %s [-n] [-f address_family] "
6422 "[-P protocol] [-T d|u] [-g | -p | -s [interval [count]]]\n",
6424 (void) fprintf(stderr
, " %s -m [-v] [-T d|u] "
6425 "[interval [count]]\n", cmdname
);
6426 (void) fprintf(stderr
, " %s -i [-I interface] [-an] "
6427 "[-f address_family] [-T d|u] [interval [count]]\n", cmdname
);
6428 (void) fprintf(stderr
, " %s -r [-anv] "
6429 "[-f address_family|filter] [-T d|u]\n", cmdname
);
6430 (void) fprintf(stderr
, " %s -M [-ns] [-f address_family] "
6431 "[-T d|u]\n", cmdname
);
6432 (void) fprintf(stderr
, " %s -D [-I interface] "
6433 "[-f address_family] [-T d|u]\n", cmdname
);
6438 * fatal: print error message to stderr and
6439 * call exit(errcode)
6443 fatal(int errcode
, char *format
, ...)
6450 va_start(argp
, format
);
6451 (void) vfprintf(stderr
, format
, argp
);