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
26 * Copyright 2018, Joyent, Inc.
30 * simple netstat based on snmp/mib-2 interface to the TCP/IP stack
33 * 1. A comment "LINTED: (note 1)" appears before certain lines where
34 * lint would have complained, "pointer cast may result in improper
35 * alignment". These are lines where lint had suspected potential
36 * improper alignment of a data structure; in each such situation
37 * we have relied on the kernel guaranteeing proper alignment.
38 * 2. Some 'for' loops have been commented as "'for' loop 1", etc
39 * because they have 'continue' or 'break' statements in their
40 * bodies. 'continue' statements have been used inside some loops
41 * where avoiding them would have led to deep levels of indentation.
44 * Add ability to request subsets from kernel (with level = MIB2_IP;
45 * name = 0 meaning everything for compatibility)
62 #include <sys/types.h>
63 #include <sys/stream.h>
65 #include <sys/strstat.h>
66 #include <sys/tihdr.h>
68 #include <sys/socket.h>
69 #include <sys/sockio.h>
70 #include <netinet/in.h>
72 #include <net/route.h>
74 #include <inet/mib2.h>
78 #include <netinet/igmp_var.h>
79 #include <netinet/ip_mroute.h>
81 #include <arpa/inet.h>
84 #include <sys/systeminfo.h>
85 #include <arpa/inet.h>
87 #include <netinet/dhcp.h>
88 #include <dhcpagent_ipc.h>
89 #include <dhcpagent_util.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 static const char *miudp_state(int code
);
174 static void stat_report(mib_item_t
*item
);
175 static void mrt_stat_report(mib_item_t
*item
);
176 static void arp_report(mib_item_t
*item
);
177 static void ndp_report(mib_item_t
*item
);
178 static void mrt_report(mib_item_t
*item
);
179 static void if_stat_total(struct ifstat
*oldstats
,
180 struct ifstat
*newstats
, struct ifstat
*sumstats
);
181 static void if_report(mib_item_t
*item
, char *ifname
,
182 int Iflag_only
, boolean_t once_only
);
183 static void if_report_ip4(mib2_ipAddrEntry_t
*ap
,
184 char ifname
[], char logintname
[],
185 struct ifstat
*statptr
, boolean_t ksp_not_null
);
186 static void if_report_ip6(mib2_ipv6AddrEntry_t
*ap6
,
187 char ifname
[], char logintname
[],
188 struct ifstat
*statptr
, boolean_t ksp_not_null
);
189 static void ire_report(const mib_item_t
*item
);
190 static void tcp_report(const mib_item_t
*item
);
191 static void udp_report(const mib_item_t
*item
);
192 static void group_report(mib_item_t
*item
);
193 static void dce_report(mib_item_t
*item
);
194 static void print_ip_stats(mib2_ip_t
*ip
);
195 static void print_icmp_stats(mib2_icmp_t
*icmp
);
196 static void print_ip6_stats(mib2_ipv6IfStatsEntry_t
*ip6
);
197 static void print_icmp6_stats(mib2_ipv6IfIcmpEntry_t
*icmp6
);
198 static void print_sctp_stats(mib2_sctp_t
*tcp
);
199 static void print_tcp_stats(mib2_tcp_t
*tcp
);
200 static void print_udp_stats(mib2_udp_t
*udp
);
201 static void print_rawip_stats(mib2_rawip_t
*rawip
);
202 static void print_igmp_stats(struct igmpstat
*igps
);
203 static void print_mrt_stats(struct mrtstat
*mrts
);
204 static void sctp_report(const mib_item_t
*item
);
205 static void sum_ip6_stats(mib2_ipv6IfStatsEntry_t
*ip6
,
206 mib2_ipv6IfStatsEntry_t
*sum6
);
207 static void sum_icmp6_stats(mib2_ipv6IfIcmpEntry_t
*icmp6
,
208 mib2_ipv6IfIcmpEntry_t
*sum6
);
209 static void m_report(void);
210 static void dhcp_report(char *);
212 static uint64_t kstat_named_value(kstat_t
*, char *);
213 static kid_t
safe_kstat_read(kstat_ctl_t
*, kstat_t
*, void *);
214 static int isnum(char *);
215 static char *plural(int n
);
216 static char *pluraly(int n
);
217 static char *plurales(int n
);
218 static void process_filter(char *arg
);
219 static char *ifindex2str(uint_t
, char *);
220 static boolean_t
family_selected(int family
);
222 static void usage(char *);
223 static void fatal(int errcode
, char *str1
, ...);
225 #define PLURAL(n) plural((int)n)
226 #define PLURALY(n) pluraly((int)n)
227 #define PLURALES(n) plurales((int)n)
228 #define IFLAGMOD(flg, val1, val2) if (flg == val1) flg = val2
229 #define MDIFF(diff, elem2, elem1, member) (diff)->member = \
230 (elem2)->member - (elem1)->member
233 static boolean_t Aflag
= B_FALSE
; /* All sockets/ifs/rtng-tbls */
234 static boolean_t CIDRflag
= B_FALSE
; /* CIDR for IPv4 -i/-r addrs */
235 static boolean_t Dflag
= B_FALSE
; /* DCE info */
236 static boolean_t Iflag
= B_FALSE
; /* IP Traffic Interfaces */
237 static boolean_t Mflag
= B_FALSE
; /* STREAMS Memory Statistics */
238 static boolean_t Nflag
= B_FALSE
; /* Numeric Network Addresses */
239 static boolean_t Rflag
= B_FALSE
; /* Routing Tables */
240 static boolean_t Sflag
= B_FALSE
; /* Per-protocol Statistics */
241 static boolean_t Vflag
= B_FALSE
; /* Verbose */
242 static boolean_t Pflag
= B_FALSE
; /* Net to Media Tables */
243 static boolean_t Gflag
= B_FALSE
; /* Multicast group membership */
244 static boolean_t MMflag
= B_FALSE
; /* Multicast routing table */
245 static boolean_t DHCPflag
= B_FALSE
; /* DHCP statistics */
246 static boolean_t Xflag
= B_FALSE
; /* Debug Info */
248 static int v4compat
= 0; /* Compatible printing format for status */
250 static int proto
= IPPROTO_MAX
; /* all protocols */
251 kstat_ctl_t
*kc
= NULL
;
254 * Name service timeout detection constants.
256 static mutex_t ns_lock
= ERRORCHECKMUTEX
;
257 static boolean_t ns_active
= B_FALSE
; /* Is a lookup ongoing? */
258 static hrtime_t ns_starttime
; /* Time the lookup started */
259 static int ns_sleeptime
= 2; /* Time in seconds between checks */
260 static int ns_warntime
= 2; /* Time in seconds before warning */
263 * Sizes of data structures extracted from the base mib.
264 * This allows the size of the tables entries to grow while preserving
265 * binary compatibility.
267 static int ipAddrEntrySize
;
268 static int ipRouteEntrySize
;
269 static int ipNetToMediaEntrySize
;
270 static int ipMemberEntrySize
;
271 static int ipGroupSourceEntrySize
;
272 static int vifctlSize
;
273 static int mfcctlSize
;
275 static int ipv6IfStatsEntrySize
;
276 static int ipv6IfIcmpEntrySize
;
277 static int ipv6AddrEntrySize
;
278 static int ipv6RouteEntrySize
;
279 static int ipv6NetToMediaEntrySize
;
280 static int ipv6MemberEntrySize
;
281 static int ipv6GroupSourceEntrySize
;
283 static int ipDestEntrySize
;
285 static int tcpConnEntrySize
;
286 static int tcp6ConnEntrySize
;
287 static int udpEntrySize
;
288 static int udp6EntrySize
;
289 static int sctpEntrySize
;
290 static int sctpLocalEntrySize
;
291 static int sctpRemoteEntrySize
;
293 #define protocol_selected(p) (proto == IPPROTO_MAX || proto == (p))
295 /* Machinery used for -f (filter) option */
296 enum { FK_AF
= 0, FK_OUTIF
, FK_DST
, FK_FLAGS
, NFILTERKEYS
};
298 static const char *filter_keys
[NFILTERKEYS
] = {
299 "af", "outif", "dst", "flags"
302 /* Flags on routes */
303 #define FLF_A 0x00000001
304 #define FLF_b 0x00000002
305 #define FLF_D 0x00000004
306 #define FLF_G 0x00000008
307 #define FLF_H 0x00000010
308 #define FLF_L 0x00000020
309 #define FLF_U 0x00000040
310 #define FLF_S 0x00000100
311 #define FLF_C 0x00000200 /* IRE_IF_CLONE */
312 #define FLF_I 0x00000400 /* RTF_INDIRECT */
313 #define FLF_R 0x00000800 /* RTF_REJECT */
314 #define FLF_B 0x00001000 /* RTF_BLACKHOLE */
315 #define FLF_Z 0x00100000 /* RTF_ZONE */
317 static const char flag_list
[] = "AbDGHLUMSCIRBZ";
319 typedef struct filter_rule filter_t
;
325 const char *f_ifname
;
327 struct hostent
*f_address
;
338 * The user-specified filters are linked into lists separated by
339 * keyword (type of filter). Thus, the matching algorithm is:
340 * For each non-empty filter list
341 * If no filters in the list match
342 * then stop here; route doesn't match
343 * If loop above completes, then route does match and will be
346 static filter_t
*filters
[NFILTERKEYS
];
348 static uint_t timestamp_fmt
= NODATE
;
350 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
351 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't */
355 ns_lookup_start(void)
357 mutex_enter(&ns_lock
);
359 ns_starttime
= gethrtime();
360 mutex_exit(&ns_lock
);
366 mutex_enter(&ns_lock
);
368 mutex_exit(&ns_lock
);
372 * When name services are not functioning, this program appears to hang to the
373 * user. To try and give the user a chance of figuring out that this might be
374 * the case, we end up warning them and suggest that they may want to use the -n
379 ns_warning_thr(void *unsued
)
384 (void) sleep(ns_sleeptime
);
386 mutex_enter(&ns_lock
);
387 if (ns_active
&& now
- ns_starttime
>= ns_warntime
* NANOSEC
) {
388 (void) fprintf(stderr
, "warning: data "
389 "available, but name service lookups are "
390 "taking a while. Use the -n option to "
391 "disable name service lookups.\n");
392 mutex_exit(&ns_lock
);
395 mutex_exit(&ns_lock
);
398 /* LINTED: E_STMT_NOT_REACHED */
404 main(int argc
, char **argv
)
407 mib_item_t
*item
= NULL
;
408 mib_item_t
*previtem
= NULL
;
411 int interval
= 0; /* Single time by default */
412 int count
= -1; /* Forever */
416 * Possible values of 'Iflag_only':
417 * -1, no feature-flags;
418 * 0, IFlag and other feature-flags enabled
419 * 1, IFlag is the only feature-flag enabled
420 * : trinary variable, modified using IFLAGMOD()
423 boolean_t once_only
= B_FALSE
; /* '-i' with count > 1 */
426 char *default_ip_str
= NULL
;
430 v4compat
= get_compat_flag(&default_ip_str
);
431 if (v4compat
== DEFAULT_PROT_BAD_VALUE
)
432 fatal(2, "%s: %s: Bad value for %s in %s\n", name
,
433 default_ip_str
, DEFAULT_IP
, INET_DEFAULT_FILE
);
434 free(default_ip_str
);
436 (void) setlocale(LC_ALL
, "");
437 (void) textdomain(TEXT_DOMAIN
);
439 while ((c
= getopt(argc
, argv
, "acdimnrspMgvxf:P:I:DT:")) != -1) {
441 case 'a': /* all connections */
449 case 'd': /* DCE info */
451 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
454 case 'i': /* interface (ill/ipif report) */
456 IFLAGMOD(Iflag_only
, -1, 1); /* '-i' exists */
459 case 'm': /* streams msg report */
461 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
464 case 'n': /* numeric format */
468 case 'r': /* route tables */
470 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
473 case 's': /* per-protocol statistics */
475 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
478 case 'p': /* arp/ndp table */
480 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
483 case 'M': /* multicast routing tables */
485 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
488 case 'g': /* multicast group membership */
490 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
493 case 'v': /* verbose output format */
495 IFLAGMOD(Iflag_only
, 1, 0); /* see macro def'n */
498 case 'x': /* turn on debugging */
503 process_filter(optarg
);
507 if (strcmp(optarg
, "ip") == 0) {
509 } else if (strcmp(optarg
, "ipv6") == 0 ||
510 strcmp(optarg
, "ip6") == 0) {
511 v4compat
= 0; /* Overridden */
512 proto
= IPPROTO_IPV6
;
513 } else if (strcmp(optarg
, "icmp") == 0) {
514 proto
= IPPROTO_ICMP
;
515 } else if (strcmp(optarg
, "icmpv6") == 0 ||
516 strcmp(optarg
, "icmp6") == 0) {
517 v4compat
= 0; /* Overridden */
518 proto
= IPPROTO_ICMPV6
;
519 } else if (strcmp(optarg
, "igmp") == 0) {
520 proto
= IPPROTO_IGMP
;
521 } else if (strcmp(optarg
, "udp") == 0) {
523 } else if (strcmp(optarg
, "tcp") == 0) {
525 } else if (strcmp(optarg
, "sctp") == 0) {
526 proto
= IPPROTO_SCTP
;
527 } else if (strcmp(optarg
, "raw") == 0 ||
528 strcmp(optarg
, "rawip") == 0) {
531 fatal(1, "%s: unknown protocol.\n", optarg
);
538 IFLAGMOD(Iflag_only
, -1, 1); /* see macro def'n */
549 timestamp_fmt
= UDATE
;
550 else if (*optarg
== 'd')
551 timestamp_fmt
= DDATE
;
566 * Handle other arguments: find interval, count; the
567 * flags that accept 'interval' and 'count' are OR'd
568 * in the outermost 'if'; more flags may be added as
571 if (Iflag
|| Sflag
|| Mflag
) {
572 for (d
= optind
; d
< argc
; d
++) {
573 if (isnum(argv
[d
])) {
574 interval
= atoi(argv
[d
]);
576 isnum(argv
[d
+ 1])) {
577 count
= atoi(argv
[d
+ 1]);
581 if (interval
== 0 || count
== 0)
588 if (Iflag
&& isnum(argv
[optind
])) {
589 count
= atoi(argv
[optind
]);
596 (void) fprintf(stderr
,
597 "%s: extra arguments\n", name
);
601 setbuf(stdout
, NULL
);
604 * Start up the thread to check for name services warnings.
606 if (thr_create(NULL
, 0, ns_warning_thr
, NULL
,
607 THR_DETACHED
| THR_DAEMON
, NULL
) != 0) {
608 fatal(1, "%s: failed to create name services "
609 "thread: %s\n", name
, strerror(errno
));
613 dhcp_report(Iflag
? ifname
: NULL
);
617 /* Get data structures: priming before iteration */
618 if (family_selected(AF_INET
) || family_selected(AF_INET6
)) {
621 fatal(1, "can't open mib stream\n");
622 if ((item
= mibget(sd
)) == NULL
) {
624 fatal(1, "mibget() failed\n");
626 /* Extract constant sizes - need do once only */
627 mib_get_constants(item
);
629 if ((kc
= kstat_open()) == NULL
) {
632 fail(1, "kstat_open(): can't open /dev/kstat");
641 mib_item_t
*curritem
= NULL
; /* only for -[M]s */
643 if (timestamp_fmt
!= NODATE
)
644 print_timestamp(timestamp_fmt
);
646 /* netstat: AF_INET[6] behaviour */
647 if (family_selected(AF_INET
) || family_selected(AF_INET6
)) {
649 curritem
= mib_item_diff(previtem
, item
);
650 if (curritem
== NULL
)
651 fatal(1, "can't process mib data, "
653 mib_item_destroy(&previtem
);
656 if (!(Dflag
|| Iflag
|| Rflag
|| Sflag
|| Mflag
||
657 MMflag
|| Pflag
|| Gflag
|| DHCPflag
)) {
658 if (protocol_selected(IPPROTO_UDP
))
660 if (protocol_selected(IPPROTO_TCP
))
662 if (protocol_selected(IPPROTO_SCTP
))
666 if_report(item
, ifname
, Iflag_only
, once_only
);
671 if (Sflag
&& MMflag
) {
672 mrt_stat_report(curritem
);
675 stat_report(curritem
);
682 if (family_selected(AF_INET
))
684 if (family_selected(AF_INET6
))
689 mib_item_destroy(&curritem
);
692 /* netstat: AF_UNIX behaviour */
693 if (family_selected(AF_UNIX
) &&
694 (!(Dflag
|| Iflag
|| Rflag
|| Sflag
|| Mflag
||
695 MMflag
|| Pflag
|| Gflag
)))
697 (void) kstat_close(kc
);
699 /* iteration handling code */
700 if (count
> 0 && --count
== 0)
702 (void) sleep(interval
);
704 /* re-populating of data structures */
705 if (family_selected(AF_INET
) || family_selected(AF_INET6
)) {
707 /* previtem is a cut-down list */
708 previtem
= mib_item_dup(item
);
709 if (previtem
== NULL
)
710 fatal(1, "can't process mib data, "
715 if ((sd
= mibopen()) == -1)
716 fatal(1, "can't open mib stream anymore\n");
717 if ((item
= mibget(sd
)) == NULL
) {
719 fatal(1, "mibget() failed\n");
722 if ((kc
= kstat_open()) == NULL
)
723 fail(1, "kstat_open(): can't open /dev/kstat");
725 } /* 'for' loop 1 ends */
739 for (i
= 0; i
< len
; i
++)
746 /* --------------------------------- MIBGET -------------------------------- */
752 * buf is an automatic for this function, so the
753 * compiler has complete control over its alignment;
754 * it is assumed this alignment is satisfactory for
755 * it to be casted to certain other struct pointers
756 * here, such as struct T_optmgmt_ack * .
758 uintptr_t buf
[512 / sizeof (uintptr_t)];
761 struct strbuf ctlbuf
, databuf
;
762 struct T_optmgmt_req
*tor
= (struct T_optmgmt_req
*)buf
;
763 struct T_optmgmt_ack
*toa
= (struct T_optmgmt_ack
*)buf
;
764 struct T_error_ack
*tea
= (struct T_error_ack
*)buf
;
766 mib_item_t
*first_item
= NULL
;
767 mib_item_t
*last_item
= NULL
;
770 tor
->PRIM_type
= T_SVR4_OPTMGMT_REQ
;
771 tor
->OPT_offset
= sizeof (struct T_optmgmt_req
);
772 tor
->OPT_length
= sizeof (struct opthdr
);
773 tor
->MGMT_flags
= T_CURRENT
;
777 * Note: we use the special level value below so that IP will return
778 * us information concerning IRE_MARK_TESTHIDDEN routes.
780 req
= (struct opthdr
*)&tor
[1];
781 req
->level
= EXPER_IP_AND_ALL_IRES
;
785 ctlbuf
.buf
= (char *)buf
;
786 ctlbuf
.len
= tor
->OPT_length
+ tor
->OPT_offset
;
788 if (putmsg(sd
, &ctlbuf
, NULL
, flags
) == -1) {
789 perror("mibget: putmsg(ctl) failed");
794 * Each reply consists of a ctl part for one fixed structure
795 * or table, as defined in mib2.h. The format is a T_OPTMGMT_ACK,
796 * containing an opthdr structure. level/name identify the entry,
797 * len is the size of the data part of the message.
799 req
= (struct opthdr
*)&toa
[1];
800 ctlbuf
.maxlen
= sizeof (buf
);
804 getcode
= getmsg(sd
, &ctlbuf
, NULL
, &flags
);
806 perror("mibget getmsg(ctl) failed");
808 (void) fputs("# level name len\n",
811 for (last_item
= first_item
; last_item
;
812 last_item
= last_item
->next_item
)
813 (void) printf("%d %4d %5d %d\n",
822 ctlbuf
.len
>= sizeof (struct T_optmgmt_ack
) &&
823 toa
->PRIM_type
== T_OPTMGMT_ACK
&&
824 toa
->MGMT_flags
== T_SUCCESS
&&
827 (void) printf("mibget getmsg() %d returned "
828 "EOD (level %ld, name %ld)\n",
829 j
, req
->level
, req
->name
);
830 return (first_item
); /* this is EOD msg */
833 if (ctlbuf
.len
>= sizeof (struct T_error_ack
) &&
834 tea
->PRIM_type
== T_ERROR_ACK
) {
835 (void) fprintf(stderr
,
836 "mibget %d gives T_ERROR_ACK: TLI_error = 0x%lx, "
837 "UNIX_error = 0x%lx\n",
838 j
, tea
->TLI_error
, tea
->UNIX_error
);
840 errno
= (tea
->TLI_error
== TSYSERR
) ?
841 tea
->UNIX_error
: EPROTO
;
845 if (getcode
!= MOREDATA
||
846 ctlbuf
.len
< sizeof (struct T_optmgmt_ack
) ||
847 toa
->PRIM_type
!= T_OPTMGMT_ACK
||
848 toa
->MGMT_flags
!= T_SUCCESS
) {
849 (void) printf("mibget getmsg(ctl) %d returned %d, "
850 "ctlbuf.len = %d, PRIM_type = %ld\n",
851 j
, getcode
, ctlbuf
.len
, toa
->PRIM_type
);
853 if (toa
->PRIM_type
== T_OPTMGMT_ACK
)
854 (void) printf("T_OPTMGMT_ACK: "
855 "MGMT_flags = 0x%lx, req->len = %ld\n",
856 toa
->MGMT_flags
, req
->len
);
861 temp
= (mib_item_t
*)malloc(sizeof (mib_item_t
));
863 perror("mibget malloc failed");
866 if (last_item
!= NULL
)
867 last_item
->next_item
= temp
;
871 last_item
->next_item
= NULL
;
872 last_item
->group
= req
->level
;
873 last_item
->mib_id
= req
->name
;
874 last_item
->length
= req
->len
;
875 last_item
->valp
= malloc((int)req
->len
);
876 if (last_item
->valp
== NULL
)
879 (void) printf("msg %d: group = %4d mib_id = %5d"
881 j
, last_item
->group
, last_item
->mib_id
,
884 databuf
.maxlen
= last_item
->length
;
885 databuf
.buf
= (char *)last_item
->valp
;
888 getcode
= getmsg(sd
, NULL
, &databuf
, &flags
);
890 perror("mibget getmsg(data) failed");
892 } else if (getcode
!= 0) {
893 (void) printf("mibget getmsg(data) returned %d, "
894 "databuf.maxlen = %d, databuf.len = %d\n",
895 getcode
, databuf
.maxlen
, databuf
.len
);
908 * mibfree: frees a linked list of type (mib_item_t *)
909 * returned by mibget(); this is NOT THE SAME AS
910 * mib_item_destroy(), so should be used for objects
911 * returned by mibget() only
914 mibfree(mib_item_t
*firstitem
)
916 mib_item_t
*lastitem
;
918 while (firstitem
!= NULL
) {
919 lastitem
= firstitem
;
920 firstitem
= firstitem
->next_item
;
921 free(lastitem
->valp
);
931 sd
= open("/dev/arp", O_RDWR
);
936 if (ioctl(sd
, I_PUSH
, "tcp") == -1) {
937 perror("tcp I_PUSH");
941 if (ioctl(sd
, I_PUSH
, "udp") == -1) {
942 perror("udp I_PUSH");
946 if (ioctl(sd
, I_PUSH
, "icmp") == -1) {
947 perror("icmp I_PUSH");
955 * mib_item_dup: returns a clean mib_item_t * linked
956 * list, so that for every element item->mib_id is 0;
957 * to deallocate this linked list, use mib_item_destroy
960 mib_item_dup(mib_item_t
*item
)
966 for (tempp
= item
; tempp
; tempp
= tempp
->next_item
)
967 if (tempp
->mib_id
== 0)
971 localp
= (mib_item_t
*)malloc(c
* sizeof (mib_item_t
));
975 for (; item
; item
= item
->next_item
) {
976 if (item
->mib_id
== 0) {
977 /* Replicate item in localp */
978 (localp
[c
]).next_item
= NULL
;
979 (localp
[c
]).group
= item
->group
;
980 (localp
[c
]).mib_id
= item
->mib_id
;
981 (localp
[c
]).length
= item
->length
;
982 (localp
[c
]).valp
= (uintptr_t *)malloc(
984 if ((localp
[c
]).valp
== NULL
) {
985 mib_item_destroy(&localp
);
988 (void *) memcpy((localp
[c
]).valp
,
991 tempp
= &(localp
[c
]);
993 (localp
[c
- 1]).next_item
= tempp
;
1001 * mib_item_diff: takes two (mib_item_t *) linked lists
1002 * item1 and item2 and computes the difference between
1003 * differentiable values in item2 against item1 for every
1004 * given member of item2; returns an mib_item_t * linked
1005 * list of diff's, or a copy of item2 if item1 is NULL;
1006 * will return NULL if system out of memory; works only
1007 * for item->mib_id == 0
1010 mib_item_diff(mib_item_t
*item1
, mib_item_t
*item2
)
1012 int nitems
= 0; /* no. of items in item2 */
1013 mib_item_t
*tempp2
; /* walking copy of item2 */
1014 mib_item_t
*tempp1
; /* walking copy of item1 */
1016 mib_item_t
*diffptr
; /* walking copy of diffp */
1017 mib_item_t
*prevp
= NULL
;
1019 if (item1
== NULL
) {
1020 diffp
= mib_item_dup(item2
);
1024 for (tempp2
= item2
;
1026 tempp2
= tempp2
->next_item
) {
1027 if (tempp2
->mib_id
== 0)
1028 switch (tempp2
->group
) {
1030 * upon adding a case here, the same
1031 * must also be added in the next
1032 * switch statement, alongwith
1050 diffp
= mib_item_dup(item2
);
1054 diffp
= (mib_item_t
*)calloc(nitems
, sizeof (mib_item_t
));
1059 for (tempp2
= item2
; tempp2
!= NULL
; tempp2
= tempp2
->next_item
) {
1060 if (tempp2
->mib_id
!= 0)
1061 continue; /* 'for' loop 1 */
1063 for (tempp1
= item1
; tempp1
!= NULL
;
1064 tempp1
= tempp1
->next_item
) {
1065 if (!(tempp1
->mib_id
== 0 &&
1066 tempp1
->group
== tempp2
->group
&&
1067 tempp1
->mib_id
== tempp2
->mib_id
))
1068 continue; /* 'for' loop 2 */
1069 /* found comparable data sets */
1071 prevp
->next_item
= diffptr
;
1072 switch (tempp2
->group
) {
1074 * Indenting note: Because of long variable names
1075 * in cases MIB2_IP6 and MIB2_ICMP6, their contents
1076 * have been indented by one tab space only
1079 mib2_ip_t
*i2
= (mib2_ip_t
*)tempp2
->valp
;
1080 mib2_ip_t
*i1
= (mib2_ip_t
*)tempp1
->valp
;
1083 diffptr
->group
= tempp2
->group
;
1084 diffptr
->mib_id
= tempp2
->mib_id
;
1085 diffptr
->length
= tempp2
->length
;
1086 d
= (mib2_ip_t
*)calloc(tempp2
->length
, 1);
1088 goto mibdiff_out_of_memory
;
1090 d
->ipForwarding
= i2
->ipForwarding
;
1091 d
->ipDefaultTTL
= i2
->ipDefaultTTL
;
1092 MDIFF(d
, i2
, i1
, ipInReceives
);
1093 MDIFF(d
, i2
, i1
, ipInHdrErrors
);
1094 MDIFF(d
, i2
, i1
, ipInAddrErrors
);
1095 MDIFF(d
, i2
, i1
, ipInCksumErrs
);
1096 MDIFF(d
, i2
, i1
, ipForwDatagrams
);
1097 MDIFF(d
, i2
, i1
, ipForwProhibits
);
1098 MDIFF(d
, i2
, i1
, ipInUnknownProtos
);
1099 MDIFF(d
, i2
, i1
, ipInDiscards
);
1100 MDIFF(d
, i2
, i1
, ipInDelivers
);
1101 MDIFF(d
, i2
, i1
, ipOutRequests
);
1102 MDIFF(d
, i2
, i1
, ipOutDiscards
);
1103 MDIFF(d
, i2
, i1
, ipOutNoRoutes
);
1104 MDIFF(d
, i2
, i1
, ipReasmTimeout
);
1105 MDIFF(d
, i2
, i1
, ipReasmReqds
);
1106 MDIFF(d
, i2
, i1
, ipReasmOKs
);
1107 MDIFF(d
, i2
, i1
, ipReasmFails
);
1108 MDIFF(d
, i2
, i1
, ipReasmDuplicates
);
1109 MDIFF(d
, i2
, i1
, ipReasmPartDups
);
1110 MDIFF(d
, i2
, i1
, ipFragOKs
);
1111 MDIFF(d
, i2
, i1
, ipFragFails
);
1112 MDIFF(d
, i2
, i1
, ipFragCreates
);
1113 MDIFF(d
, i2
, i1
, ipRoutingDiscards
);
1114 MDIFF(d
, i2
, i1
, tcpInErrs
);
1115 MDIFF(d
, i2
, i1
, udpNoPorts
);
1116 MDIFF(d
, i2
, i1
, udpInCksumErrs
);
1117 MDIFF(d
, i2
, i1
, udpInOverflows
);
1118 MDIFF(d
, i2
, i1
, rawipInOverflows
);
1119 MDIFF(d
, i2
, i1
, ipsecInSucceeded
);
1120 MDIFF(d
, i2
, i1
, ipsecInFailed
);
1121 MDIFF(d
, i2
, i1
, ipInIPv6
);
1122 MDIFF(d
, i2
, i1
, ipOutIPv6
);
1123 MDIFF(d
, i2
, i1
, ipOutSwitchIPv6
);
1128 mib2_ipv6IfStatsEntry_t
*i2
;
1129 mib2_ipv6IfStatsEntry_t
*i1
;
1130 mib2_ipv6IfStatsEntry_t
*d
;
1132 i2
= (mib2_ipv6IfStatsEntry_t
*)tempp2
->valp
;
1133 i1
= (mib2_ipv6IfStatsEntry_t
*)tempp1
->valp
;
1134 diffptr
->group
= tempp2
->group
;
1135 diffptr
->mib_id
= tempp2
->mib_id
;
1136 diffptr
->length
= tempp2
->length
;
1137 d
= (mib2_ipv6IfStatsEntry_t
*)calloc(
1140 goto mibdiff_out_of_memory
;
1142 d
->ipv6Forwarding
= i2
->ipv6Forwarding
;
1143 d
->ipv6DefaultHopLimit
=
1144 i2
->ipv6DefaultHopLimit
;
1146 MDIFF(d
, i2
, i1
, ipv6InReceives
);
1147 MDIFF(d
, i2
, i1
, ipv6InHdrErrors
);
1148 MDIFF(d
, i2
, i1
, ipv6InTooBigErrors
);
1149 MDIFF(d
, i2
, i1
, ipv6InNoRoutes
);
1150 MDIFF(d
, i2
, i1
, ipv6InAddrErrors
);
1151 MDIFF(d
, i2
, i1
, ipv6InUnknownProtos
);
1152 MDIFF(d
, i2
, i1
, ipv6InTruncatedPkts
);
1153 MDIFF(d
, i2
, i1
, ipv6InDiscards
);
1154 MDIFF(d
, i2
, i1
, ipv6InDelivers
);
1155 MDIFF(d
, i2
, i1
, ipv6OutForwDatagrams
);
1156 MDIFF(d
, i2
, i1
, ipv6OutRequests
);
1157 MDIFF(d
, i2
, i1
, ipv6OutDiscards
);
1158 MDIFF(d
, i2
, i1
, ipv6OutNoRoutes
);
1159 MDIFF(d
, i2
, i1
, ipv6OutFragOKs
);
1160 MDIFF(d
, i2
, i1
, ipv6OutFragFails
);
1161 MDIFF(d
, i2
, i1
, ipv6OutFragCreates
);
1162 MDIFF(d
, i2
, i1
, ipv6ReasmReqds
);
1163 MDIFF(d
, i2
, i1
, ipv6ReasmOKs
);
1164 MDIFF(d
, i2
, i1
, ipv6ReasmFails
);
1165 MDIFF(d
, i2
, i1
, ipv6InMcastPkts
);
1166 MDIFF(d
, i2
, i1
, ipv6OutMcastPkts
);
1167 MDIFF(d
, i2
, i1
, ipv6ReasmDuplicates
);
1168 MDIFF(d
, i2
, i1
, ipv6ReasmPartDups
);
1169 MDIFF(d
, i2
, i1
, ipv6ForwProhibits
);
1170 MDIFF(d
, i2
, i1
, udpInCksumErrs
);
1171 MDIFF(d
, i2
, i1
, udpInOverflows
);
1172 MDIFF(d
, i2
, i1
, rawipInOverflows
);
1173 MDIFF(d
, i2
, i1
, ipv6InIPv4
);
1174 MDIFF(d
, i2
, i1
, ipv6OutIPv4
);
1175 MDIFF(d
, i2
, i1
, ipv6OutSwitchIPv4
);
1184 m2
= (struct mrtstat
*)tempp2
->valp
;
1185 m1
= (struct mrtstat
*)tempp1
->valp
;
1186 diffptr
->group
= tempp2
->group
;
1187 diffptr
->mib_id
= tempp2
->mib_id
;
1188 diffptr
->length
= tempp2
->length
;
1189 d
= (struct mrtstat
*)calloc(tempp2
->length
, 1);
1191 goto mibdiff_out_of_memory
;
1193 MDIFF(d
, m2
, m1
, mrts_mfc_hits
);
1194 MDIFF(d
, m2
, m1
, mrts_mfc_misses
);
1195 MDIFF(d
, m2
, m1
, mrts_fwd_in
);
1196 MDIFF(d
, m2
, m1
, mrts_fwd_out
);
1197 d
->mrts_upcalls
= m2
->mrts_upcalls
;
1198 MDIFF(d
, m2
, m1
, mrts_fwd_drop
);
1199 MDIFF(d
, m2
, m1
, mrts_bad_tunnel
);
1200 MDIFF(d
, m2
, m1
, mrts_cant_tunnel
);
1201 MDIFF(d
, m2
, m1
, mrts_wrong_if
);
1202 MDIFF(d
, m2
, m1
, mrts_upq_ovflw
);
1203 MDIFF(d
, m2
, m1
, mrts_cache_cleanups
);
1204 MDIFF(d
, m2
, m1
, mrts_drop_sel
);
1205 MDIFF(d
, m2
, m1
, mrts_q_overflow
);
1206 MDIFF(d
, m2
, m1
, mrts_pkt2large
);
1207 MDIFF(d
, m2
, m1
, mrts_pim_badversion
);
1208 MDIFF(d
, m2
, m1
, mrts_pim_rcv_badcsum
);
1209 MDIFF(d
, m2
, m1
, mrts_pim_badregisters
);
1210 MDIFF(d
, m2
, m1
, mrts_pim_regforwards
);
1211 MDIFF(d
, m2
, m1
, mrts_pim_regsend_drops
);
1212 MDIFF(d
, m2
, m1
, mrts_pim_malformed
);
1213 MDIFF(d
, m2
, m1
, mrts_pim_nomemory
);
1218 struct igmpstat
*i2
;
1219 struct igmpstat
*i1
;
1222 i2
= (struct igmpstat
*)tempp2
->valp
;
1223 i1
= (struct igmpstat
*)tempp1
->valp
;
1224 diffptr
->group
= tempp2
->group
;
1225 diffptr
->mib_id
= tempp2
->mib_id
;
1226 diffptr
->length
= tempp2
->length
;
1227 d
= (struct igmpstat
*)calloc(
1230 goto mibdiff_out_of_memory
;
1232 MDIFF(d
, i2
, i1
, igps_rcv_total
);
1233 MDIFF(d
, i2
, i1
, igps_rcv_tooshort
);
1234 MDIFF(d
, i2
, i1
, igps_rcv_badsum
);
1235 MDIFF(d
, i2
, i1
, igps_rcv_queries
);
1236 MDIFF(d
, i2
, i1
, igps_rcv_badqueries
);
1237 MDIFF(d
, i2
, i1
, igps_rcv_reports
);
1238 MDIFF(d
, i2
, i1
, igps_rcv_badreports
);
1239 MDIFF(d
, i2
, i1
, igps_rcv_ourreports
);
1240 MDIFF(d
, i2
, i1
, igps_snd_reports
);
1249 i2
= (mib2_icmp_t
*)tempp2
->valp
;
1250 i1
= (mib2_icmp_t
*)tempp1
->valp
;
1251 diffptr
->group
= tempp2
->group
;
1252 diffptr
->mib_id
= tempp2
->mib_id
;
1253 diffptr
->length
= tempp2
->length
;
1254 d
= (mib2_icmp_t
*)calloc(tempp2
->length
, 1);
1256 goto mibdiff_out_of_memory
;
1258 MDIFF(d
, i2
, i1
, icmpInMsgs
);
1259 MDIFF(d
, i2
, i1
, icmpInErrors
);
1260 MDIFF(d
, i2
, i1
, icmpInCksumErrs
);
1261 MDIFF(d
, i2
, i1
, icmpInUnknowns
);
1262 MDIFF(d
, i2
, i1
, icmpInDestUnreachs
);
1263 MDIFF(d
, i2
, i1
, icmpInTimeExcds
);
1264 MDIFF(d
, i2
, i1
, icmpInParmProbs
);
1265 MDIFF(d
, i2
, i1
, icmpInSrcQuenchs
);
1266 MDIFF(d
, i2
, i1
, icmpInRedirects
);
1267 MDIFF(d
, i2
, i1
, icmpInBadRedirects
);
1268 MDIFF(d
, i2
, i1
, icmpInEchos
);
1269 MDIFF(d
, i2
, i1
, icmpInEchoReps
);
1270 MDIFF(d
, i2
, i1
, icmpInTimestamps
);
1271 MDIFF(d
, i2
, i1
, icmpInAddrMasks
);
1272 MDIFF(d
, i2
, i1
, icmpInAddrMaskReps
);
1273 MDIFF(d
, i2
, i1
, icmpInFragNeeded
);
1274 MDIFF(d
, i2
, i1
, icmpOutMsgs
);
1275 MDIFF(d
, i2
, i1
, icmpOutDrops
);
1276 MDIFF(d
, i2
, i1
, icmpOutErrors
);
1277 MDIFF(d
, i2
, i1
, icmpOutDestUnreachs
);
1278 MDIFF(d
, i2
, i1
, icmpOutTimeExcds
);
1279 MDIFF(d
, i2
, i1
, icmpOutParmProbs
);
1280 MDIFF(d
, i2
, i1
, icmpOutSrcQuenchs
);
1281 MDIFF(d
, i2
, i1
, icmpOutRedirects
);
1282 MDIFF(d
, i2
, i1
, icmpOutEchos
);
1283 MDIFF(d
, i2
, i1
, icmpOutEchoReps
);
1284 MDIFF(d
, i2
, i1
, icmpOutTimestamps
);
1285 MDIFF(d
, i2
, i1
, icmpOutTimestampReps
);
1286 MDIFF(d
, i2
, i1
, icmpOutAddrMasks
);
1287 MDIFF(d
, i2
, i1
, icmpOutAddrMaskReps
);
1288 MDIFF(d
, i2
, i1
, icmpOutFragNeeded
);
1289 MDIFF(d
, i2
, i1
, icmpInOverflows
);
1294 mib2_ipv6IfIcmpEntry_t
*i2
;
1295 mib2_ipv6IfIcmpEntry_t
*i1
;
1296 mib2_ipv6IfIcmpEntry_t
*d
;
1298 i2
= (mib2_ipv6IfIcmpEntry_t
*)tempp2
->valp
;
1299 i1
= (mib2_ipv6IfIcmpEntry_t
*)tempp1
->valp
;
1300 diffptr
->group
= tempp2
->group
;
1301 diffptr
->mib_id
= tempp2
->mib_id
;
1302 diffptr
->length
= tempp2
->length
;
1303 d
= (mib2_ipv6IfIcmpEntry_t
*)calloc(tempp2
->length
, 1);
1305 goto mibdiff_out_of_memory
;
1307 MDIFF(d
, i2
, i1
, ipv6IfIcmpInMsgs
);
1308 MDIFF(d
, i2
, i1
, ipv6IfIcmpInErrors
);
1309 MDIFF(d
, i2
, i1
, ipv6IfIcmpInDestUnreachs
);
1310 MDIFF(d
, i2
, i1
, ipv6IfIcmpInAdminProhibs
);
1311 MDIFF(d
, i2
, i1
, ipv6IfIcmpInTimeExcds
);
1312 MDIFF(d
, i2
, i1
, ipv6IfIcmpInParmProblems
);
1313 MDIFF(d
, i2
, i1
, ipv6IfIcmpInPktTooBigs
);
1314 MDIFF(d
, i2
, i1
, ipv6IfIcmpInEchos
);
1315 MDIFF(d
, i2
, i1
, ipv6IfIcmpInEchoReplies
);
1316 MDIFF(d
, i2
, i1
, ipv6IfIcmpInRouterSolicits
);
1317 MDIFF(d
, i2
, i1
, ipv6IfIcmpInRouterAdvertisements
);
1318 MDIFF(d
, i2
, i1
, ipv6IfIcmpInNeighborSolicits
);
1319 MDIFF(d
, i2
, i1
, ipv6IfIcmpInNeighborAdvertisements
);
1320 MDIFF(d
, i2
, i1
, ipv6IfIcmpInRedirects
);
1321 MDIFF(d
, i2
, i1
, ipv6IfIcmpInBadRedirects
);
1322 MDIFF(d
, i2
, i1
, ipv6IfIcmpInGroupMembQueries
);
1323 MDIFF(d
, i2
, i1
, ipv6IfIcmpInGroupMembResponses
);
1324 MDIFF(d
, i2
, i1
, ipv6IfIcmpInGroupMembReductions
);
1325 MDIFF(d
, i2
, i1
, ipv6IfIcmpInOverflows
);
1326 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutMsgs
);
1327 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutErrors
);
1328 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutDestUnreachs
);
1329 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutAdminProhibs
);
1330 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutTimeExcds
);
1331 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutParmProblems
);
1332 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutPktTooBigs
);
1333 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutEchos
);
1334 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutEchoReplies
);
1335 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutRouterSolicits
);
1336 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutRouterAdvertisements
);
1337 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutNeighborSolicits
);
1338 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutNeighborAdvertisements
);
1339 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutRedirects
);
1340 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutGroupMembQueries
);
1341 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutGroupMembResponses
);
1342 MDIFF(d
, i2
, i1
, ipv6IfIcmpOutGroupMembReductions
);
1351 t2
= (mib2_tcp_t
*)tempp2
->valp
;
1352 t1
= (mib2_tcp_t
*)tempp1
->valp
;
1353 diffptr
->group
= tempp2
->group
;
1354 diffptr
->mib_id
= tempp2
->mib_id
;
1355 diffptr
->length
= tempp2
->length
;
1356 d
= (mib2_tcp_t
*)calloc(tempp2
->length
, 1);
1358 goto mibdiff_out_of_memory
;
1360 d
->tcpRtoMin
= t2
->tcpRtoMin
;
1361 d
->tcpRtoMax
= t2
->tcpRtoMax
;
1362 d
->tcpMaxConn
= t2
->tcpMaxConn
;
1363 MDIFF(d
, t2
, t1
, tcpActiveOpens
);
1364 MDIFF(d
, t2
, t1
, tcpPassiveOpens
);
1365 MDIFF(d
, t2
, t1
, tcpAttemptFails
);
1366 MDIFF(d
, t2
, t1
, tcpEstabResets
);
1367 d
->tcpCurrEstab
= t2
->tcpCurrEstab
;
1368 MDIFF(d
, t2
, t1
, tcpHCOutSegs
);
1369 MDIFF(d
, t2
, t1
, tcpOutDataSegs
);
1370 MDIFF(d
, t2
, t1
, tcpOutDataBytes
);
1371 MDIFF(d
, t2
, t1
, tcpRetransSegs
);
1372 MDIFF(d
, t2
, t1
, tcpRetransBytes
);
1373 MDIFF(d
, t2
, t1
, tcpOutAck
);
1374 MDIFF(d
, t2
, t1
, tcpOutAckDelayed
);
1375 MDIFF(d
, t2
, t1
, tcpOutUrg
);
1376 MDIFF(d
, t2
, t1
, tcpOutWinUpdate
);
1377 MDIFF(d
, t2
, t1
, tcpOutWinProbe
);
1378 MDIFF(d
, t2
, t1
, tcpOutControl
);
1379 MDIFF(d
, t2
, t1
, tcpOutRsts
);
1380 MDIFF(d
, t2
, t1
, tcpOutFastRetrans
);
1381 MDIFF(d
, t2
, t1
, tcpHCInSegs
);
1382 MDIFF(d
, t2
, t1
, tcpInAckSegs
);
1383 MDIFF(d
, t2
, t1
, tcpInAckBytes
);
1384 MDIFF(d
, t2
, t1
, tcpInDupAck
);
1385 MDIFF(d
, t2
, t1
, tcpInAckUnsent
);
1386 MDIFF(d
, t2
, t1
, tcpInDataInorderSegs
);
1387 MDIFF(d
, t2
, t1
, tcpInDataInorderBytes
);
1388 MDIFF(d
, t2
, t1
, tcpInDataUnorderSegs
);
1389 MDIFF(d
, t2
, t1
, tcpInDataUnorderBytes
);
1390 MDIFF(d
, t2
, t1
, tcpInDataDupSegs
);
1391 MDIFF(d
, t2
, t1
, tcpInDataDupBytes
);
1392 MDIFF(d
, t2
, t1
, tcpInDataPartDupSegs
);
1393 MDIFF(d
, t2
, t1
, tcpInDataPartDupBytes
);
1394 MDIFF(d
, t2
, t1
, tcpInDataPastWinSegs
);
1395 MDIFF(d
, t2
, t1
, tcpInDataPastWinBytes
);
1396 MDIFF(d
, t2
, t1
, tcpInWinProbe
);
1397 MDIFF(d
, t2
, t1
, tcpInWinUpdate
);
1398 MDIFF(d
, t2
, t1
, tcpInClosed
);
1399 MDIFF(d
, t2
, t1
, tcpRttNoUpdate
);
1400 MDIFF(d
, t2
, t1
, tcpRttUpdate
);
1401 MDIFF(d
, t2
, t1
, tcpTimRetrans
);
1402 MDIFF(d
, t2
, t1
, tcpTimRetransDrop
);
1403 MDIFF(d
, t2
, t1
, tcpTimKeepalive
);
1404 MDIFF(d
, t2
, t1
, tcpTimKeepaliveProbe
);
1405 MDIFF(d
, t2
, t1
, tcpTimKeepaliveDrop
);
1406 MDIFF(d
, t2
, t1
, tcpListenDrop
);
1407 MDIFF(d
, t2
, t1
, tcpListenDropQ0
);
1408 MDIFF(d
, t2
, t1
, tcpHalfOpenDrop
);
1409 MDIFF(d
, t2
, t1
, tcpOutSackRetransSegs
);
1418 u2
= (mib2_udp_t
*)tempp2
->valp
;
1419 u1
= (mib2_udp_t
*)tempp1
->valp
;
1420 diffptr
->group
= tempp2
->group
;
1421 diffptr
->mib_id
= tempp2
->mib_id
;
1422 diffptr
->length
= tempp2
->length
;
1423 d
= (mib2_udp_t
*)calloc(tempp2
->length
, 1);
1425 goto mibdiff_out_of_memory
;
1427 MDIFF(d
, u2
, u1
, udpHCInDatagrams
);
1428 MDIFF(d
, u2
, u1
, udpInErrors
);
1429 MDIFF(d
, u2
, u1
, udpHCOutDatagrams
);
1430 MDIFF(d
, u2
, u1
, udpOutErrors
);
1439 s2
= (mib2_sctp_t
*)tempp2
->valp
;
1440 s1
= (mib2_sctp_t
*)tempp1
->valp
;
1441 diffptr
->group
= tempp2
->group
;
1442 diffptr
->mib_id
= tempp2
->mib_id
;
1443 diffptr
->length
= tempp2
->length
;
1444 d
= (mib2_sctp_t
*)calloc(tempp2
->length
, 1);
1446 goto mibdiff_out_of_memory
;
1448 d
->sctpRtoAlgorithm
= s2
->sctpRtoAlgorithm
;
1449 d
->sctpRtoMin
= s2
->sctpRtoMin
;
1450 d
->sctpRtoMax
= s2
->sctpRtoMax
;
1451 d
->sctpRtoInitial
= s2
->sctpRtoInitial
;
1452 d
->sctpMaxAssocs
= s2
->sctpMaxAssocs
;
1453 d
->sctpValCookieLife
= s2
->sctpValCookieLife
;
1454 d
->sctpMaxInitRetr
= s2
->sctpMaxInitRetr
;
1455 d
->sctpCurrEstab
= s2
->sctpCurrEstab
;
1456 MDIFF(d
, s2
, s1
, sctpActiveEstab
);
1457 MDIFF(d
, s2
, s1
, sctpPassiveEstab
);
1458 MDIFF(d
, s2
, s1
, sctpAborted
);
1459 MDIFF(d
, s2
, s1
, sctpShutdowns
);
1460 MDIFF(d
, s2
, s1
, sctpOutOfBlue
);
1461 MDIFF(d
, s2
, s1
, sctpChecksumError
);
1462 MDIFF(d
, s2
, s1
, sctpOutCtrlChunks
);
1463 MDIFF(d
, s2
, s1
, sctpOutOrderChunks
);
1464 MDIFF(d
, s2
, s1
, sctpOutUnorderChunks
);
1465 MDIFF(d
, s2
, s1
, sctpRetransChunks
);
1466 MDIFF(d
, s2
, s1
, sctpOutAck
);
1467 MDIFF(d
, s2
, s1
, sctpOutAckDelayed
);
1468 MDIFF(d
, s2
, s1
, sctpOutWinUpdate
);
1469 MDIFF(d
, s2
, s1
, sctpOutFastRetrans
);
1470 MDIFF(d
, s2
, s1
, sctpOutWinProbe
);
1471 MDIFF(d
, s2
, s1
, sctpInCtrlChunks
);
1472 MDIFF(d
, s2
, s1
, sctpInOrderChunks
);
1473 MDIFF(d
, s2
, s1
, sctpInUnorderChunks
);
1474 MDIFF(d
, s2
, s1
, sctpInAck
);
1475 MDIFF(d
, s2
, s1
, sctpInDupAck
);
1476 MDIFF(d
, s2
, s1
, sctpInAckUnsent
);
1477 MDIFF(d
, s2
, s1
, sctpFragUsrMsgs
);
1478 MDIFF(d
, s2
, s1
, sctpReasmUsrMsgs
);
1479 MDIFF(d
, s2
, s1
, sctpOutSCTPPkts
);
1480 MDIFF(d
, s2
, s1
, sctpInSCTPPkts
);
1481 MDIFF(d
, s2
, s1
, sctpInInvalidCookie
);
1482 MDIFF(d
, s2
, s1
, sctpTimRetrans
);
1483 MDIFF(d
, s2
, s1
, sctpTimRetransDrop
);
1484 MDIFF(d
, s2
, s1
, sctpTimHeartBeatProbe
);
1485 MDIFF(d
, s2
, s1
, sctpTimHeartBeatDrop
);
1486 MDIFF(d
, s2
, s1
, sctpListenDrop
);
1487 MDIFF(d
, s2
, s1
, sctpInClosed
);
1496 r2
= (mib2_rawip_t
*)tempp2
->valp
;
1497 r1
= (mib2_rawip_t
*)tempp1
->valp
;
1498 diffptr
->group
= tempp2
->group
;
1499 diffptr
->mib_id
= tempp2
->mib_id
;
1500 diffptr
->length
= tempp2
->length
;
1501 d
= (mib2_rawip_t
*)calloc(tempp2
->length
, 1);
1503 goto mibdiff_out_of_memory
;
1505 MDIFF(d
, r2
, r1
, rawipInDatagrams
);
1506 MDIFF(d
, r2
, r1
, rawipInErrors
);
1507 MDIFF(d
, r2
, r1
, rawipInCksumErrs
);
1508 MDIFF(d
, r2
, r1
, rawipOutDatagrams
);
1509 MDIFF(d
, r2
, r1
, rawipOutErrors
);
1514 * there are more "group" types but they aren't
1515 * required for the -s and -Ms options
1518 } /* 'for' loop 2 ends */
1520 } /* 'for' loop 1 ends */
1523 diffptr
->next_item
= NULL
;
1526 mibdiff_out_of_memory
:;
1527 mib_item_destroy(&diffp
);
1532 * mib_item_destroy: cleans up a mib_item_t *
1533 * that was created by calling mib_item_dup or
1537 mib_item_destroy(mib_item_t
**itemp
)
1543 if (itemp
== NULL
|| *itemp
== NULL
)
1546 for (tempp
= *itemp
; tempp
!= NULL
; tempp
= tempp
->next_item
)
1547 if (tempp
->mib_id
== 0)
1550 return; /* cannot destroy! */
1553 return; /* cannot destroy! */
1555 for (c
= nitems
- 1; c
>= 0; c
--) {
1556 free((itemp
[0][c
]).valp
);
1563 /* Compare two Octet_ts. Return B_TRUE if they match, B_FALSE if not. */
1565 octetstrmatch(const Octet_t
*a
, const Octet_t
*b
)
1567 if (a
== NULL
|| b
== NULL
)
1570 if (a
->o_length
!= b
->o_length
)
1573 return (memcmp(a
->o_bytes
, b
->o_bytes
, a
->o_length
) == 0);
1576 /* If octetstr() changes make an appropriate change to STR_EXPAND */
1578 octetstr(const Octet_t
*op
, int code
, char *dst
, uint_t dstlen
)
1585 for (i
= 0; i
< op
->o_length
; i
++) {
1588 if (cp
- dst
+ 4 > dstlen
) {
1592 (void) snprintf(cp
, 5, "%d.",
1593 0xff & op
->o_bytes
[i
]);
1594 cp
= strchr(cp
, '\0');
1597 if (cp
- dst
+ 1 > dstlen
) {
1601 *cp
++ = op
->o_bytes
[i
];
1605 if (cp
- dst
+ 3 > dstlen
) {
1609 (void) snprintf(cp
, 4, "%02x:",
1610 0xff & op
->o_bytes
[i
]);
1616 if (code
!= 'a' && cp
!= dst
)
1623 mitcp_state(int state
)
1625 static char tcpsbuf
[50];
1647 case TCPS_ESTABLISHED
:
1650 case TCPS_CLOSE_WAIT
:
1653 case TCPS_FIN_WAIT_1
:
1662 case TCPS_FIN_WAIT_2
:
1665 case TCPS_TIME_WAIT
:
1669 (void) snprintf(tcpsbuf
, sizeof (tcpsbuf
),
1670 "UnknownState(%d)", state
);
1679 miudp_state(int state
)
1681 static char udpsbuf
[50];
1685 case MIB2_UDP_unbound
:
1691 case MIB2_UDP_connected
:
1695 (void) snprintf(udpsbuf
, sizeof (udpsbuf
),
1696 "Unknown State(%d)", state
);
1713 prval(char *str
, Counter val
)
1715 (void) printf("\t%-20s=%6u", str
, val
);
1717 (void) putchar('\n');
1721 prval64(char *str
, Counter64 val
)
1723 (void) printf("\t%-20s=%6llu", str
, val
);
1725 (void) putchar('\n');
1729 pr_int_val(char *str
, int val
)
1731 (void) printf("\t%-20s=%6d", str
, val
);
1733 (void) putchar('\n');
1737 pr_sctp_rtoalgo(char *str
, int val
)
1739 (void) printf("\t%-20s=", str
);
1741 case MIB2_SCTP_RTOALGO_OTHER
:
1742 (void) printf("%6.6s", "other");
1745 case MIB2_SCTP_RTOALGO_VANJ
:
1746 (void) printf("%6.6s", "vanj");
1750 (void) printf("%6d", val
);
1754 (void) putchar('\n');
1761 (void) putchar('\n');
1764 /* Extract constant sizes */
1766 mib_get_constants(mib_item_t
*item
)
1769 for (; item
; item
= item
->next_item
) {
1770 if (item
->mib_id
!= 0)
1771 continue; /* 'for' loop 1 */
1773 switch (item
->group
) {
1775 mib2_ip_t
*ip
= (mib2_ip_t
*)item
->valp
;
1777 ipAddrEntrySize
= ip
->ipAddrEntrySize
;
1778 ipRouteEntrySize
= ip
->ipRouteEntrySize
;
1779 ipNetToMediaEntrySize
= ip
->ipNetToMediaEntrySize
;
1780 ipMemberEntrySize
= ip
->ipMemberEntrySize
;
1781 ipGroupSourceEntrySize
= ip
->ipGroupSourceEntrySize
;
1782 ipDestEntrySize
= ip
->ipDestEntrySize
;
1783 assert(IS_P2ALIGNED(ipAddrEntrySize
,
1784 sizeof (mib2_ipAddrEntry_t
*)));
1785 assert(IS_P2ALIGNED(ipRouteEntrySize
,
1786 sizeof (mib2_ipRouteEntry_t
*)));
1787 assert(IS_P2ALIGNED(ipNetToMediaEntrySize
,
1788 sizeof (mib2_ipNetToMediaEntry_t
*)));
1789 assert(IS_P2ALIGNED(ipMemberEntrySize
,
1790 sizeof (ip_member_t
*)));
1791 assert(IS_P2ALIGNED(ipGroupSourceEntrySize
,
1792 sizeof (ip_grpsrc_t
*)));
1796 struct mrtstat
*mrts
= (struct mrtstat
*)item
->valp
;
1798 vifctlSize
= mrts
->mrts_vifctlSize
;
1799 mfcctlSize
= mrts
->mrts_mfcctlSize
;
1800 assert(IS_P2ALIGNED(vifctlSize
,
1801 sizeof (struct vifclt
*)));
1802 assert(IS_P2ALIGNED(mfcctlSize
,
1803 sizeof (struct mfcctl
*)));
1807 mib2_ipv6IfStatsEntry_t
*ip6
;
1808 /* Just use the first entry */
1810 ip6
= (mib2_ipv6IfStatsEntry_t
*)item
->valp
;
1811 ipv6IfStatsEntrySize
= ip6
->ipv6IfStatsEntrySize
;
1812 ipv6AddrEntrySize
= ip6
->ipv6AddrEntrySize
;
1813 ipv6RouteEntrySize
= ip6
->ipv6RouteEntrySize
;
1814 ipv6NetToMediaEntrySize
= ip6
->ipv6NetToMediaEntrySize
;
1815 ipv6MemberEntrySize
= ip6
->ipv6MemberEntrySize
;
1816 ipv6GroupSourceEntrySize
=
1817 ip6
->ipv6GroupSourceEntrySize
;
1818 assert(IS_P2ALIGNED(ipv6IfStatsEntrySize
,
1819 sizeof (mib2_ipv6IfStatsEntry_t
*)));
1820 assert(IS_P2ALIGNED(ipv6AddrEntrySize
,
1821 sizeof (mib2_ipv6AddrEntry_t
*)));
1822 assert(IS_P2ALIGNED(ipv6RouteEntrySize
,
1823 sizeof (mib2_ipv6RouteEntry_t
*)));
1824 assert(IS_P2ALIGNED(ipv6NetToMediaEntrySize
,
1825 sizeof (mib2_ipv6NetToMediaEntry_t
*)));
1826 assert(IS_P2ALIGNED(ipv6MemberEntrySize
,
1827 sizeof (ipv6_member_t
*)));
1828 assert(IS_P2ALIGNED(ipv6GroupSourceEntrySize
,
1829 sizeof (ipv6_grpsrc_t
*)));
1833 mib2_ipv6IfIcmpEntry_t
*icmp6
;
1834 /* Just use the first entry */
1836 icmp6
= (mib2_ipv6IfIcmpEntry_t
*)item
->valp
;
1837 ipv6IfIcmpEntrySize
= icmp6
->ipv6IfIcmpEntrySize
;
1838 assert(IS_P2ALIGNED(ipv6IfIcmpEntrySize
,
1839 sizeof (mib2_ipv6IfIcmpEntry_t
*)));
1843 mib2_tcp_t
*tcp
= (mib2_tcp_t
*)item
->valp
;
1845 tcpConnEntrySize
= tcp
->tcpConnTableSize
;
1846 tcp6ConnEntrySize
= tcp
->tcp6ConnTableSize
;
1847 assert(IS_P2ALIGNED(tcpConnEntrySize
,
1848 sizeof (mib2_tcpConnEntry_t
*)));
1849 assert(IS_P2ALIGNED(tcp6ConnEntrySize
,
1850 sizeof (mib2_tcp6ConnEntry_t
*)));
1854 mib2_udp_t
*udp
= (mib2_udp_t
*)item
->valp
;
1856 udpEntrySize
= udp
->udpEntrySize
;
1857 udp6EntrySize
= udp
->udp6EntrySize
;
1858 assert(IS_P2ALIGNED(udpEntrySize
,
1859 sizeof (mib2_udpEntry_t
*)));
1860 assert(IS_P2ALIGNED(udp6EntrySize
,
1861 sizeof (mib2_udp6Entry_t
*)));
1865 mib2_sctp_t
*sctp
= (mib2_sctp_t
*)item
->valp
;
1867 sctpEntrySize
= sctp
->sctpEntrySize
;
1868 sctpLocalEntrySize
= sctp
->sctpLocalEntrySize
;
1869 sctpRemoteEntrySize
= sctp
->sctpRemoteEntrySize
;
1873 } /* 'for' loop 1 ends */
1876 (void) puts("mib_get_constants:");
1877 (void) printf("\tipv6IfStatsEntrySize %d\n",
1878 ipv6IfStatsEntrySize
);
1879 (void) printf("\tipAddrEntrySize %d\n", ipAddrEntrySize
);
1880 (void) printf("\tipRouteEntrySize %d\n", ipRouteEntrySize
);
1881 (void) printf("\tipNetToMediaEntrySize %d\n",
1882 ipNetToMediaEntrySize
);
1883 (void) printf("\tipMemberEntrySize %d\n", ipMemberEntrySize
);
1884 (void) printf("\tvifctlSize %d\n", vifctlSize
);
1885 (void) printf("\tmfcctlSize %d\n", mfcctlSize
);
1887 (void) printf("\tipv6AddrEntrySize %d\n", ipv6AddrEntrySize
);
1888 (void) printf("\tipv6RouteEntrySize %d\n", ipv6RouteEntrySize
);
1889 (void) printf("\tipv6NetToMediaEntrySize %d\n",
1890 ipv6NetToMediaEntrySize
);
1891 (void) printf("\tipv6MemberEntrySize %d\n",
1892 ipv6MemberEntrySize
);
1893 (void) printf("\tipv6IfIcmpEntrySize %d\n",
1894 ipv6IfIcmpEntrySize
);
1895 (void) printf("\tipDestEntrySize %d\n", ipDestEntrySize
);
1896 (void) printf("\ttcpConnEntrySize %d\n", tcpConnEntrySize
);
1897 (void) printf("\ttcp6ConnEntrySize %d\n", tcp6ConnEntrySize
);
1898 (void) printf("\tudpEntrySize %d\n", udpEntrySize
);
1899 (void) printf("\tudp6EntrySize %d\n", udp6EntrySize
);
1900 (void) printf("\tsctpEntrySize %d\n", sctpEntrySize
);
1901 (void) printf("\tsctpLocalEntrySize %d\n", sctpLocalEntrySize
);
1902 (void) printf("\tsctpRemoteEntrySize %d\n",
1903 sctpRemoteEntrySize
);
1908 /* ----------------------------- STAT_REPORT ------------------------------- */
1911 stat_report(mib_item_t
*item
)
1914 char ifname
[LIFNAMSIZ
+ 1];
1917 for (; item
; item
= item
->next_item
) {
1919 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
1920 (void) printf("Group = %d, mib_id = %d, "
1921 "length = %d, valp = 0x%p\n",
1922 item
->group
, item
->mib_id
,
1923 item
->length
, item
->valp
);
1925 if (item
->mib_id
!= 0)
1926 continue; /* 'for' loop 1 */
1928 switch (item
->group
) {
1930 mib2_ip_t
*ip
= (mib2_ip_t
*)item
->valp
;
1932 if (protocol_selected(IPPROTO_IP
) &&
1933 family_selected(AF_INET
)) {
1934 (void) fputs(v4compat
? "\nIP" : "\nIPv4",
1942 (mib2_icmp_t
*)item
->valp
;
1944 if (protocol_selected(IPPROTO_ICMP
) &&
1945 family_selected(AF_INET
)) {
1946 (void) fputs(v4compat
? "\nICMP" : "\nICMPv4",
1948 print_icmp_stats(icmp
);
1953 mib2_ipv6IfStatsEntry_t
*ip6
;
1954 mib2_ipv6IfStatsEntry_t sum6
;
1956 if (!(protocol_selected(IPPROTO_IPV6
)) ||
1957 !(family_selected(AF_INET6
)))
1959 bzero(&sum6
, sizeof (sum6
));
1960 /* 'for' loop 2a: */
1961 for (ip6
= (mib2_ipv6IfStatsEntry_t
*)item
->valp
;
1962 (char *)ip6
< (char *)item
->valp
+ item
->length
;
1963 /* LINTED: (note 1) */
1964 ip6
= (mib2_ipv6IfStatsEntry_t
*)((char *)ip6
+
1965 ipv6IfStatsEntrySize
)) {
1966 if (ip6
->ipv6IfIndex
== 0) {
1968 * The "unknown interface" ip6
1969 * mib. Just add to the sum.
1971 sum_ip6_stats(ip6
, &sum6
);
1972 continue; /* 'for' loop 2a */
1975 (void) printf("\nIPv6 for %s\n",
1976 ifindex2str(ip6
->ipv6IfIndex
,
1978 print_ip6_stats(ip6
);
1980 sum_ip6_stats(ip6
, &sum6
);
1981 } /* 'for' loop 2a ends */
1982 (void) fputs("\nIPv6", stdout
);
1983 print_ip6_stats(&sum6
);
1987 mib2_ipv6IfIcmpEntry_t
*icmp6
;
1988 mib2_ipv6IfIcmpEntry_t sum6
;
1990 if (!(protocol_selected(IPPROTO_ICMPV6
)) ||
1991 !(family_selected(AF_INET6
)))
1993 bzero(&sum6
, sizeof (sum6
));
1994 /* 'for' loop 2b: */
1995 for (icmp6
= (mib2_ipv6IfIcmpEntry_t
*)item
->valp
;
1996 (char *)icmp6
< (char *)item
->valp
+ item
->length
;
1997 icmp6
= (void *)((char *)icmp6
+
1998 ipv6IfIcmpEntrySize
)) {
1999 if (icmp6
->ipv6IfIcmpIfIndex
== 0) {
2001 * The "unknown interface" icmp6
2002 * mib. Just add to the sum.
2004 sum_icmp6_stats(icmp6
, &sum6
);
2005 continue; /* 'for' loop 2b: */
2008 (void) printf("\nICMPv6 for %s\n",
2010 icmp6
->ipv6IfIcmpIfIndex
, ifname
));
2011 print_icmp6_stats(icmp6
);
2013 sum_icmp6_stats(icmp6
, &sum6
);
2014 } /* 'for' loop 2b ends */
2015 (void) fputs("\nICMPv6", stdout
);
2016 print_icmp6_stats(&sum6
);
2020 mib2_tcp_t
*tcp
= (mib2_tcp_t
*)item
->valp
;
2022 if (protocol_selected(IPPROTO_TCP
) &&
2023 (family_selected(AF_INET
) ||
2024 family_selected(AF_INET6
))) {
2025 (void) fputs("\nTCP", stdout
);
2026 print_tcp_stats(tcp
);
2031 mib2_udp_t
*udp
= (mib2_udp_t
*)item
->valp
;
2033 if (protocol_selected(IPPROTO_UDP
) &&
2034 (family_selected(AF_INET
) ||
2035 family_selected(AF_INET6
))) {
2036 (void) fputs("\nUDP", stdout
);
2037 print_udp_stats(udp
);
2042 mib2_sctp_t
*sctp
= (mib2_sctp_t
*)item
->valp
;
2044 if (protocol_selected(IPPROTO_SCTP
) &&
2045 (family_selected(AF_INET
) ||
2046 family_selected(AF_INET6
))) {
2047 (void) fputs("\nSCTP", stdout
);
2048 print_sctp_stats(sctp
);
2053 mib2_rawip_t
*rawip
=
2054 (mib2_rawip_t
*)item
->valp
;
2056 if (protocol_selected(IPPROTO_RAW
) &&
2057 (family_selected(AF_INET
) ||
2058 family_selected(AF_INET6
))) {
2059 (void) fputs("\nRAWIP", stdout
);
2060 print_rawip_stats(rawip
);
2065 struct igmpstat
*igps
=
2066 (struct igmpstat
*)item
->valp
;
2068 if (protocol_selected(IPPROTO_IGMP
) &&
2069 (family_selected(AF_INET
))) {
2070 (void) fputs("\nIGMP:\n", stdout
);
2071 print_igmp_stats(igps
);
2076 } /* 'for' loop 1 ends */
2077 (void) putchar('\n');
2078 (void) fflush(stdout
);
2082 print_ip_stats(mib2_ip_t
*ip
)
2085 pr_int_val("ipForwarding", ip
->ipForwarding
);
2086 pr_int_val("ipDefaultTTL", ip
->ipDefaultTTL
);
2087 prval("ipInReceives", ip
->ipInReceives
);
2088 prval("ipInHdrErrors", ip
->ipInHdrErrors
);
2089 prval("ipInAddrErrors", ip
->ipInAddrErrors
);
2090 prval("ipInCksumErrs", ip
->ipInCksumErrs
);
2091 prval("ipForwDatagrams", ip
->ipForwDatagrams
);
2092 prval("ipForwProhibits", ip
->ipForwProhibits
);
2093 prval("ipInUnknownProtos", ip
->ipInUnknownProtos
);
2094 prval("ipInDiscards", ip
->ipInDiscards
);
2095 prval("ipInDelivers", ip
->ipInDelivers
);
2096 prval("ipOutRequests", ip
->ipOutRequests
);
2097 prval("ipOutDiscards", ip
->ipOutDiscards
);
2098 prval("ipOutNoRoutes", ip
->ipOutNoRoutes
);
2099 pr_int_val("ipReasmTimeout", ip
->ipReasmTimeout
);
2100 prval("ipReasmReqds", ip
->ipReasmReqds
);
2101 prval("ipReasmOKs", ip
->ipReasmOKs
);
2102 prval("ipReasmFails", ip
->ipReasmFails
);
2103 prval("ipReasmDuplicates", ip
->ipReasmDuplicates
);
2104 prval("ipReasmPartDups", ip
->ipReasmPartDups
);
2105 prval("ipFragOKs", ip
->ipFragOKs
);
2106 prval("ipFragFails", ip
->ipFragFails
);
2107 prval("ipFragCreates", ip
->ipFragCreates
);
2108 prval("ipRoutingDiscards", ip
->ipRoutingDiscards
);
2110 prval("tcpInErrs", ip
->tcpInErrs
);
2111 prval("udpNoPorts", ip
->udpNoPorts
);
2112 prval("udpInCksumErrs", ip
->udpInCksumErrs
);
2113 prval("udpInOverflows", ip
->udpInOverflows
);
2114 prval("rawipInOverflows", ip
->rawipInOverflows
);
2115 prval("ipsecInSucceeded", ip
->ipsecInSucceeded
);
2116 prval("ipsecInFailed", ip
->ipsecInFailed
);
2117 prval("ipInIPv6", ip
->ipInIPv6
);
2118 prval("ipOutIPv6", ip
->ipOutIPv6
);
2119 prval("ipOutSwitchIPv6", ip
->ipOutSwitchIPv6
);
2124 print_icmp_stats(mib2_icmp_t
*icmp
)
2127 prval("icmpInMsgs", icmp
->icmpInMsgs
);
2128 prval("icmpInErrors", icmp
->icmpInErrors
);
2129 prval("icmpInCksumErrs", icmp
->icmpInCksumErrs
);
2130 prval("icmpInUnknowns", icmp
->icmpInUnknowns
);
2131 prval("icmpInDestUnreachs", icmp
->icmpInDestUnreachs
);
2132 prval("icmpInTimeExcds", icmp
->icmpInTimeExcds
);
2133 prval("icmpInParmProbs", icmp
->icmpInParmProbs
);
2134 prval("icmpInSrcQuenchs", icmp
->icmpInSrcQuenchs
);
2135 prval("icmpInRedirects", icmp
->icmpInRedirects
);
2136 prval("icmpInBadRedirects", icmp
->icmpInBadRedirects
);
2137 prval("icmpInEchos", icmp
->icmpInEchos
);
2138 prval("icmpInEchoReps", icmp
->icmpInEchoReps
);
2139 prval("icmpInTimestamps", icmp
->icmpInTimestamps
);
2140 prval("icmpInTimestampReps", icmp
->icmpInTimestampReps
);
2141 prval("icmpInAddrMasks", icmp
->icmpInAddrMasks
);
2142 prval("icmpInAddrMaskReps", icmp
->icmpInAddrMaskReps
);
2143 prval("icmpInFragNeeded", icmp
->icmpInFragNeeded
);
2144 prval("icmpOutMsgs", icmp
->icmpOutMsgs
);
2145 prval("icmpOutDrops", icmp
->icmpOutDrops
);
2146 prval("icmpOutErrors", icmp
->icmpOutErrors
);
2147 prval("icmpOutDestUnreachs", icmp
->icmpOutDestUnreachs
);
2148 prval("icmpOutTimeExcds", icmp
->icmpOutTimeExcds
);
2149 prval("icmpOutParmProbs", icmp
->icmpOutParmProbs
);
2150 prval("icmpOutSrcQuenchs", icmp
->icmpOutSrcQuenchs
);
2151 prval("icmpOutRedirects", icmp
->icmpOutRedirects
);
2152 prval("icmpOutEchos", icmp
->icmpOutEchos
);
2153 prval("icmpOutEchoReps", icmp
->icmpOutEchoReps
);
2154 prval("icmpOutTimestamps", icmp
->icmpOutTimestamps
);
2155 prval("icmpOutTimestampReps", icmp
->icmpOutTimestampReps
);
2156 prval("icmpOutAddrMasks", icmp
->icmpOutAddrMasks
);
2157 prval("icmpOutAddrMaskReps", icmp
->icmpOutAddrMaskReps
);
2158 prval("icmpOutFragNeeded", icmp
->icmpOutFragNeeded
);
2159 prval("icmpInOverflows", icmp
->icmpInOverflows
);
2164 print_ip6_stats(mib2_ipv6IfStatsEntry_t
*ip6
)
2167 prval("ipv6Forwarding", ip6
->ipv6Forwarding
);
2168 prval("ipv6DefaultHopLimit", ip6
->ipv6DefaultHopLimit
);
2170 prval("ipv6InReceives", ip6
->ipv6InReceives
);
2171 prval("ipv6InHdrErrors", ip6
->ipv6InHdrErrors
);
2172 prval("ipv6InTooBigErrors", ip6
->ipv6InTooBigErrors
);
2173 prval("ipv6InNoRoutes", ip6
->ipv6InNoRoutes
);
2174 prval("ipv6InAddrErrors", ip6
->ipv6InAddrErrors
);
2175 prval("ipv6InUnknownProtos", ip6
->ipv6InUnknownProtos
);
2176 prval("ipv6InTruncatedPkts", ip6
->ipv6InTruncatedPkts
);
2177 prval("ipv6InDiscards", ip6
->ipv6InDiscards
);
2178 prval("ipv6InDelivers", ip6
->ipv6InDelivers
);
2179 prval("ipv6OutForwDatagrams", ip6
->ipv6OutForwDatagrams
);
2180 prval("ipv6OutRequests", ip6
->ipv6OutRequests
);
2181 prval("ipv6OutDiscards", ip6
->ipv6OutDiscards
);
2182 prval("ipv6OutNoRoutes", ip6
->ipv6OutNoRoutes
);
2183 prval("ipv6OutFragOKs", ip6
->ipv6OutFragOKs
);
2184 prval("ipv6OutFragFails", ip6
->ipv6OutFragFails
);
2185 prval("ipv6OutFragCreates", ip6
->ipv6OutFragCreates
);
2186 prval("ipv6ReasmReqds", ip6
->ipv6ReasmReqds
);
2187 prval("ipv6ReasmOKs", ip6
->ipv6ReasmOKs
);
2188 prval("ipv6ReasmFails", ip6
->ipv6ReasmFails
);
2189 prval("ipv6InMcastPkts", ip6
->ipv6InMcastPkts
);
2190 prval("ipv6OutMcastPkts", ip6
->ipv6OutMcastPkts
);
2191 prval("ipv6ReasmDuplicates", ip6
->ipv6ReasmDuplicates
);
2192 prval("ipv6ReasmPartDups", ip6
->ipv6ReasmPartDups
);
2193 prval("ipv6ForwProhibits", ip6
->ipv6ForwProhibits
);
2194 prval("udpInCksumErrs", ip6
->udpInCksumErrs
);
2195 prval("udpInOverflows", ip6
->udpInOverflows
);
2196 prval("rawipInOverflows", ip6
->rawipInOverflows
);
2197 prval("ipv6InIPv4", ip6
->ipv6InIPv4
);
2198 prval("ipv6OutIPv4", ip6
->ipv6OutIPv4
);
2199 prval("ipv6OutSwitchIPv4", ip6
->ipv6OutSwitchIPv4
);
2204 print_icmp6_stats(mib2_ipv6IfIcmpEntry_t
*icmp6
)
2207 prval("icmp6InMsgs", icmp6
->ipv6IfIcmpInMsgs
);
2208 prval("icmp6InErrors", icmp6
->ipv6IfIcmpInErrors
);
2209 prval("icmp6InDestUnreachs", icmp6
->ipv6IfIcmpInDestUnreachs
);
2210 prval("icmp6InAdminProhibs", icmp6
->ipv6IfIcmpInAdminProhibs
);
2211 prval("icmp6InTimeExcds", icmp6
->ipv6IfIcmpInTimeExcds
);
2212 prval("icmp6InParmProblems", icmp6
->ipv6IfIcmpInParmProblems
);
2213 prval("icmp6InPktTooBigs", icmp6
->ipv6IfIcmpInPktTooBigs
);
2214 prval("icmp6InEchos", icmp6
->ipv6IfIcmpInEchos
);
2215 prval("icmp6InEchoReplies", icmp6
->ipv6IfIcmpInEchoReplies
);
2216 prval("icmp6InRouterSols", icmp6
->ipv6IfIcmpInRouterSolicits
);
2217 prval("icmp6InRouterAds",
2218 icmp6
->ipv6IfIcmpInRouterAdvertisements
);
2219 prval("icmp6InNeighborSols", icmp6
->ipv6IfIcmpInNeighborSolicits
);
2220 prval("icmp6InNeighborAds",
2221 icmp6
->ipv6IfIcmpInNeighborAdvertisements
);
2222 prval("icmp6InRedirects", icmp6
->ipv6IfIcmpInRedirects
);
2223 prval("icmp6InBadRedirects", icmp6
->ipv6IfIcmpInBadRedirects
);
2224 prval("icmp6InGroupQueries", icmp6
->ipv6IfIcmpInGroupMembQueries
);
2225 prval("icmp6InGroupResps", icmp6
->ipv6IfIcmpInGroupMembResponses
);
2226 prval("icmp6InGroupReds", icmp6
->ipv6IfIcmpInGroupMembReductions
);
2227 prval("icmp6InOverflows", icmp6
->ipv6IfIcmpInOverflows
);
2230 prval("icmp6OutMsgs", icmp6
->ipv6IfIcmpOutMsgs
);
2231 prval("icmp6OutErrors", icmp6
->ipv6IfIcmpOutErrors
);
2232 prval("icmp6OutDestUnreachs", icmp6
->ipv6IfIcmpOutDestUnreachs
);
2233 prval("icmp6OutAdminProhibs", icmp6
->ipv6IfIcmpOutAdminProhibs
);
2234 prval("icmp6OutTimeExcds", icmp6
->ipv6IfIcmpOutTimeExcds
);
2235 prval("icmp6OutParmProblems", icmp6
->ipv6IfIcmpOutParmProblems
);
2236 prval("icmp6OutPktTooBigs", icmp6
->ipv6IfIcmpOutPktTooBigs
);
2237 prval("icmp6OutEchos", icmp6
->ipv6IfIcmpOutEchos
);
2238 prval("icmp6OutEchoReplies", icmp6
->ipv6IfIcmpOutEchoReplies
);
2239 prval("icmp6OutRouterSols", icmp6
->ipv6IfIcmpOutRouterSolicits
);
2240 prval("icmp6OutRouterAds",
2241 icmp6
->ipv6IfIcmpOutRouterAdvertisements
);
2242 prval("icmp6OutNeighborSols", icmp6
->ipv6IfIcmpOutNeighborSolicits
);
2243 prval("icmp6OutNeighborAds",
2244 icmp6
->ipv6IfIcmpOutNeighborAdvertisements
);
2245 prval("icmp6OutRedirects", icmp6
->ipv6IfIcmpOutRedirects
);
2246 prval("icmp6OutGroupQueries", icmp6
->ipv6IfIcmpOutGroupMembQueries
);
2247 prval("icmp6OutGroupResps",
2248 icmp6
->ipv6IfIcmpOutGroupMembResponses
);
2249 prval("icmp6OutGroupReds",
2250 icmp6
->ipv6IfIcmpOutGroupMembReductions
);
2255 print_sctp_stats(mib2_sctp_t
*sctp
)
2258 pr_sctp_rtoalgo("sctpRtoAlgorithm", sctp
->sctpRtoAlgorithm
);
2259 prval("sctpRtoMin", sctp
->sctpRtoMin
);
2260 prval("sctpRtoMax", sctp
->sctpRtoMax
);
2261 prval("sctpRtoInitial", sctp
->sctpRtoInitial
);
2262 pr_int_val("sctpMaxAssocs", sctp
->sctpMaxAssocs
);
2263 prval("sctpValCookieLife", sctp
->sctpValCookieLife
);
2264 prval("sctpMaxInitRetr", sctp
->sctpMaxInitRetr
);
2265 prval("sctpCurrEstab", sctp
->sctpCurrEstab
);
2266 prval("sctpActiveEstab", sctp
->sctpActiveEstab
);
2267 prval("sctpPassiveEstab", sctp
->sctpPassiveEstab
);
2268 prval("sctpAborted", sctp
->sctpAborted
);
2269 prval("sctpShutdowns", sctp
->sctpShutdowns
);
2270 prval("sctpOutOfBlue", sctp
->sctpOutOfBlue
);
2271 prval("sctpChecksumError", sctp
->sctpChecksumError
);
2272 prval64("sctpOutCtrlChunks", sctp
->sctpOutCtrlChunks
);
2273 prval64("sctpOutOrderChunks", sctp
->sctpOutOrderChunks
);
2274 prval64("sctpOutUnorderChunks", sctp
->sctpOutUnorderChunks
);
2275 prval64("sctpRetransChunks", sctp
->sctpRetransChunks
);
2276 prval("sctpOutAck", sctp
->sctpOutAck
);
2277 prval("sctpOutAckDelayed", sctp
->sctpOutAckDelayed
);
2278 prval("sctpOutWinUpdate", sctp
->sctpOutWinUpdate
);
2279 prval("sctpOutFastRetrans", sctp
->sctpOutFastRetrans
);
2280 prval("sctpOutWinProbe", sctp
->sctpOutWinProbe
);
2281 prval64("sctpInCtrlChunks", sctp
->sctpInCtrlChunks
);
2282 prval64("sctpInOrderChunks", sctp
->sctpInOrderChunks
);
2283 prval64("sctpInUnorderChunks", sctp
->sctpInUnorderChunks
);
2284 prval("sctpInAck", sctp
->sctpInAck
);
2285 prval("sctpInDupAck", sctp
->sctpInDupAck
);
2286 prval("sctpInAckUnsent", sctp
->sctpInAckUnsent
);
2287 prval64("sctpFragUsrMsgs", sctp
->sctpFragUsrMsgs
);
2288 prval64("sctpReasmUsrMsgs", sctp
->sctpReasmUsrMsgs
);
2289 prval64("sctpOutSCTPPkts", sctp
->sctpOutSCTPPkts
);
2290 prval64("sctpInSCTPPkts", sctp
->sctpInSCTPPkts
);
2291 prval("sctpInInvalidCookie", sctp
->sctpInInvalidCookie
);
2292 prval("sctpTimRetrans", sctp
->sctpTimRetrans
);
2293 prval("sctpTimRetransDrop", sctp
->sctpTimRetransDrop
);
2294 prval("sctpTimHearBeatProbe", sctp
->sctpTimHeartBeatProbe
);
2295 prval("sctpTimHearBeatDrop", sctp
->sctpTimHeartBeatDrop
);
2296 prval("sctpListenDrop", sctp
->sctpListenDrop
);
2297 prval("sctpInClosed", sctp
->sctpInClosed
);
2302 print_tcp_stats(mib2_tcp_t
*tcp
)
2305 pr_int_val("tcpRtoAlgorithm", tcp
->tcpRtoAlgorithm
);
2306 pr_int_val("tcpRtoMin", tcp
->tcpRtoMin
);
2307 pr_int_val("tcpRtoMax", tcp
->tcpRtoMax
);
2308 pr_int_val("tcpMaxConn", tcp
->tcpMaxConn
);
2309 prval("tcpActiveOpens", tcp
->tcpActiveOpens
);
2310 prval("tcpPassiveOpens", tcp
->tcpPassiveOpens
);
2311 prval("tcpAttemptFails", tcp
->tcpAttemptFails
);
2312 prval("tcpEstabResets", tcp
->tcpEstabResets
);
2313 prval("tcpCurrEstab", tcp
->tcpCurrEstab
);
2314 prval64("tcpOutSegs", tcp
->tcpHCOutSegs
);
2315 prval("tcpOutDataSegs", tcp
->tcpOutDataSegs
);
2316 prval("tcpOutDataBytes", tcp
->tcpOutDataBytes
);
2317 prval("tcpRetransSegs", tcp
->tcpRetransSegs
);
2318 prval("tcpRetransBytes", tcp
->tcpRetransBytes
);
2319 prval("tcpOutAck", tcp
->tcpOutAck
);
2320 prval("tcpOutAckDelayed", tcp
->tcpOutAckDelayed
);
2321 prval("tcpOutUrg", tcp
->tcpOutUrg
);
2322 prval("tcpOutWinUpdate", tcp
->tcpOutWinUpdate
);
2323 prval("tcpOutWinProbe", tcp
->tcpOutWinProbe
);
2324 prval("tcpOutControl", tcp
->tcpOutControl
);
2325 prval("tcpOutRsts", tcp
->tcpOutRsts
);
2326 prval("tcpOutFastRetrans", tcp
->tcpOutFastRetrans
);
2327 prval64("tcpInSegs", tcp
->tcpHCInSegs
);
2329 prval("tcpInAckSegs", tcp
->tcpInAckSegs
);
2330 prval("tcpInAckBytes", tcp
->tcpInAckBytes
);
2331 prval("tcpInDupAck", tcp
->tcpInDupAck
);
2332 prval("tcpInAckUnsent", tcp
->tcpInAckUnsent
);
2333 prval("tcpInInorderSegs", tcp
->tcpInDataInorderSegs
);
2334 prval("tcpInInorderBytes", tcp
->tcpInDataInorderBytes
);
2335 prval("tcpInUnorderSegs", tcp
->tcpInDataUnorderSegs
);
2336 prval("tcpInUnorderBytes", tcp
->tcpInDataUnorderBytes
);
2337 prval("tcpInDupSegs", tcp
->tcpInDataDupSegs
);
2338 prval("tcpInDupBytes", tcp
->tcpInDataDupBytes
);
2339 prval("tcpInPartDupSegs", tcp
->tcpInDataPartDupSegs
);
2340 prval("tcpInPartDupBytes", tcp
->tcpInDataPartDupBytes
);
2341 prval("tcpInPastWinSegs", tcp
->tcpInDataPastWinSegs
);
2342 prval("tcpInPastWinBytes", tcp
->tcpInDataPastWinBytes
);
2343 prval("tcpInWinProbe", tcp
->tcpInWinProbe
);
2344 prval("tcpInWinUpdate", tcp
->tcpInWinUpdate
);
2345 prval("tcpInClosed", tcp
->tcpInClosed
);
2346 prval("tcpRttNoUpdate", tcp
->tcpRttNoUpdate
);
2347 prval("tcpRttUpdate", tcp
->tcpRttUpdate
);
2348 prval("tcpTimRetrans", tcp
->tcpTimRetrans
);
2349 prval("tcpTimRetransDrop", tcp
->tcpTimRetransDrop
);
2350 prval("tcpTimKeepalive", tcp
->tcpTimKeepalive
);
2351 prval("tcpTimKeepaliveProbe", tcp
->tcpTimKeepaliveProbe
);
2352 prval("tcpTimKeepaliveDrop", tcp
->tcpTimKeepaliveDrop
);
2353 prval("tcpListenDrop", tcp
->tcpListenDrop
);
2354 prval("tcpListenDropQ0", tcp
->tcpListenDropQ0
);
2355 prval("tcpHalfOpenDrop", tcp
->tcpHalfOpenDrop
);
2356 prval("tcpOutSackRetrans", tcp
->tcpOutSackRetransSegs
);
2362 print_udp_stats(mib2_udp_t
*udp
)
2365 prval64("udpInDatagrams", udp
->udpHCInDatagrams
);
2366 prval("udpInErrors", udp
->udpInErrors
);
2367 prval64("udpOutDatagrams", udp
->udpHCOutDatagrams
);
2368 prval("udpOutErrors", udp
->udpOutErrors
);
2373 print_rawip_stats(mib2_rawip_t
*rawip
)
2376 prval("rawipInDatagrams", rawip
->rawipInDatagrams
);
2377 prval("rawipInErrors", rawip
->rawipInErrors
);
2378 prval("rawipInCksumErrs", rawip
->rawipInCksumErrs
);
2379 prval("rawipOutDatagrams", rawip
->rawipOutDatagrams
);
2380 prval("rawipOutErrors", rawip
->rawipOutErrors
);
2385 print_igmp_stats(struct igmpstat
*igps
)
2387 (void) printf(" %10u message%s received\n",
2388 igps
->igps_rcv_total
, PLURAL(igps
->igps_rcv_total
));
2389 (void) printf(" %10u message%s received with too few bytes\n",
2390 igps
->igps_rcv_tooshort
, PLURAL(igps
->igps_rcv_tooshort
));
2391 (void) printf(" %10u message%s received with bad checksum\n",
2392 igps
->igps_rcv_badsum
, PLURAL(igps
->igps_rcv_badsum
));
2393 (void) printf(" %10u membership quer%s received\n",
2394 igps
->igps_rcv_queries
, PLURALY(igps
->igps_rcv_queries
));
2395 (void) printf(" %10u membership quer%s received with invalid "
2397 igps
->igps_rcv_badqueries
, PLURALY(igps
->igps_rcv_badqueries
));
2398 (void) printf(" %10u membership report%s received\n",
2399 igps
->igps_rcv_reports
, PLURAL(igps
->igps_rcv_reports
));
2400 (void) printf(" %10u membership report%s received with invalid "
2402 igps
->igps_rcv_badreports
, PLURAL(igps
->igps_rcv_badreports
));
2403 (void) printf(" %10u membership report%s received for groups to "
2404 "which we belong\n",
2405 igps
->igps_rcv_ourreports
, PLURAL(igps
->igps_rcv_ourreports
));
2406 (void) printf(" %10u membership report%s sent\n",
2407 igps
->igps_snd_reports
, PLURAL(igps
->igps_snd_reports
));
2411 print_mrt_stats(struct mrtstat
*mrts
)
2413 (void) puts("DVMRP multicast routing:");
2414 (void) printf(" %10u hit%s - kernel forwarding cache hits\n",
2415 mrts
->mrts_mfc_hits
, PLURAL(mrts
->mrts_mfc_hits
));
2416 (void) printf(" %10u miss%s - kernel forwarding cache misses\n",
2417 mrts
->mrts_mfc_misses
, PLURALES(mrts
->mrts_mfc_misses
));
2418 (void) printf(" %10u packet%s potentially forwarded\n",
2419 mrts
->mrts_fwd_in
, PLURAL(mrts
->mrts_fwd_in
));
2420 (void) printf(" %10u packet%s actually sent out\n",
2421 mrts
->mrts_fwd_out
, PLURAL(mrts
->mrts_fwd_out
));
2422 (void) printf(" %10u upcall%s - upcalls made to mrouted\n",
2423 mrts
->mrts_upcalls
, PLURAL(mrts
->mrts_upcalls
));
2424 (void) printf(" %10u packet%s not sent out due to lack of resources\n",
2425 mrts
->mrts_fwd_drop
, PLURAL(mrts
->mrts_fwd_drop
));
2426 (void) printf(" %10u datagram%s with malformed tunnel options\n",
2427 mrts
->mrts_bad_tunnel
, PLURAL(mrts
->mrts_bad_tunnel
));
2428 (void) printf(" %10u datagram%s with no room for tunnel options\n",
2429 mrts
->mrts_cant_tunnel
, PLURAL(mrts
->mrts_cant_tunnel
));
2430 (void) printf(" %10u datagram%s arrived on wrong interface\n",
2431 mrts
->mrts_wrong_if
, PLURAL(mrts
->mrts_wrong_if
));
2432 (void) printf(" %10u datagram%s dropped due to upcall Q overflow\n",
2433 mrts
->mrts_upq_ovflw
, PLURAL(mrts
->mrts_upq_ovflw
));
2434 (void) printf(" %10u datagram%s cleaned up by the cache\n",
2435 mrts
->mrts_cache_cleanups
, PLURAL(mrts
->mrts_cache_cleanups
));
2436 (void) printf(" %10u datagram%s dropped selectively by ratelimiter\n",
2437 mrts
->mrts_drop_sel
, PLURAL(mrts
->mrts_drop_sel
));
2438 (void) printf(" %10u datagram%s dropped - bucket Q overflow\n",
2439 mrts
->mrts_q_overflow
, PLURAL(mrts
->mrts_q_overflow
));
2440 (void) printf(" %10u datagram%s dropped - larger than bkt size\n",
2441 mrts
->mrts_pkt2large
, PLURAL(mrts
->mrts_pkt2large
));
2442 (void) printf("\nPIM multicast routing:\n");
2443 (void) printf(" %10u datagram%s dropped - bad version number\n",
2444 mrts
->mrts_pim_badversion
, PLURAL(mrts
->mrts_pim_badversion
));
2445 (void) printf(" %10u datagram%s dropped - bad checksum\n",
2446 mrts
->mrts_pim_rcv_badcsum
, PLURAL(mrts
->mrts_pim_rcv_badcsum
));
2447 (void) printf(" %10u datagram%s dropped - bad register packets\n",
2448 mrts
->mrts_pim_badregisters
, PLURAL(mrts
->mrts_pim_badregisters
));
2450 " %10u datagram%s potentially forwarded - register packets\n",
2451 mrts
->mrts_pim_regforwards
, PLURAL(mrts
->mrts_pim_regforwards
));
2452 (void) printf(" %10u datagram%s dropped - register send drops\n",
2453 mrts
->mrts_pim_regsend_drops
, PLURAL(mrts
->mrts_pim_regsend_drops
));
2454 (void) printf(" %10u datagram%s dropped - packet malformed\n",
2455 mrts
->mrts_pim_malformed
, PLURAL(mrts
->mrts_pim_malformed
));
2456 (void) printf(" %10u datagram%s dropped - no memory to forward\n",
2457 mrts
->mrts_pim_nomemory
, PLURAL(mrts
->mrts_pim_nomemory
));
2461 sum_ip6_stats(mib2_ipv6IfStatsEntry_t
*ip6
, mib2_ipv6IfStatsEntry_t
*sum6
)
2463 /* First few are not additive */
2464 sum6
->ipv6Forwarding
= ip6
->ipv6Forwarding
;
2465 sum6
->ipv6DefaultHopLimit
= ip6
->ipv6DefaultHopLimit
;
2467 sum6
->ipv6InReceives
+= ip6
->ipv6InReceives
;
2468 sum6
->ipv6InHdrErrors
+= ip6
->ipv6InHdrErrors
;
2469 sum6
->ipv6InTooBigErrors
+= ip6
->ipv6InTooBigErrors
;
2470 sum6
->ipv6InNoRoutes
+= ip6
->ipv6InNoRoutes
;
2471 sum6
->ipv6InAddrErrors
+= ip6
->ipv6InAddrErrors
;
2472 sum6
->ipv6InUnknownProtos
+= ip6
->ipv6InUnknownProtos
;
2473 sum6
->ipv6InTruncatedPkts
+= ip6
->ipv6InTruncatedPkts
;
2474 sum6
->ipv6InDiscards
+= ip6
->ipv6InDiscards
;
2475 sum6
->ipv6InDelivers
+= ip6
->ipv6InDelivers
;
2476 sum6
->ipv6OutForwDatagrams
+= ip6
->ipv6OutForwDatagrams
;
2477 sum6
->ipv6OutRequests
+= ip6
->ipv6OutRequests
;
2478 sum6
->ipv6OutDiscards
+= ip6
->ipv6OutDiscards
;
2479 sum6
->ipv6OutFragOKs
+= ip6
->ipv6OutFragOKs
;
2480 sum6
->ipv6OutFragFails
+= ip6
->ipv6OutFragFails
;
2481 sum6
->ipv6OutFragCreates
+= ip6
->ipv6OutFragCreates
;
2482 sum6
->ipv6ReasmReqds
+= ip6
->ipv6ReasmReqds
;
2483 sum6
->ipv6ReasmOKs
+= ip6
->ipv6ReasmOKs
;
2484 sum6
->ipv6ReasmFails
+= ip6
->ipv6ReasmFails
;
2485 sum6
->ipv6InMcastPkts
+= ip6
->ipv6InMcastPkts
;
2486 sum6
->ipv6OutMcastPkts
+= ip6
->ipv6OutMcastPkts
;
2487 sum6
->ipv6OutNoRoutes
+= ip6
->ipv6OutNoRoutes
;
2488 sum6
->ipv6ReasmDuplicates
+= ip6
->ipv6ReasmDuplicates
;
2489 sum6
->ipv6ReasmPartDups
+= ip6
->ipv6ReasmPartDups
;
2490 sum6
->ipv6ForwProhibits
+= ip6
->ipv6ForwProhibits
;
2491 sum6
->udpInCksumErrs
+= ip6
->udpInCksumErrs
;
2492 sum6
->udpInOverflows
+= ip6
->udpInOverflows
;
2493 sum6
->rawipInOverflows
+= ip6
->rawipInOverflows
;
2497 sum_icmp6_stats(mib2_ipv6IfIcmpEntry_t
*icmp6
, mib2_ipv6IfIcmpEntry_t
*sum6
)
2499 sum6
->ipv6IfIcmpInMsgs
+= icmp6
->ipv6IfIcmpInMsgs
;
2500 sum6
->ipv6IfIcmpInErrors
+= icmp6
->ipv6IfIcmpInErrors
;
2501 sum6
->ipv6IfIcmpInDestUnreachs
+= icmp6
->ipv6IfIcmpInDestUnreachs
;
2502 sum6
->ipv6IfIcmpInAdminProhibs
+= icmp6
->ipv6IfIcmpInAdminProhibs
;
2503 sum6
->ipv6IfIcmpInTimeExcds
+= icmp6
->ipv6IfIcmpInTimeExcds
;
2504 sum6
->ipv6IfIcmpInParmProblems
+= icmp6
->ipv6IfIcmpInParmProblems
;
2505 sum6
->ipv6IfIcmpInPktTooBigs
+= icmp6
->ipv6IfIcmpInPktTooBigs
;
2506 sum6
->ipv6IfIcmpInEchos
+= icmp6
->ipv6IfIcmpInEchos
;
2507 sum6
->ipv6IfIcmpInEchoReplies
+= icmp6
->ipv6IfIcmpInEchoReplies
;
2508 sum6
->ipv6IfIcmpInRouterSolicits
+= icmp6
->ipv6IfIcmpInRouterSolicits
;
2509 sum6
->ipv6IfIcmpInRouterAdvertisements
+=
2510 icmp6
->ipv6IfIcmpInRouterAdvertisements
;
2511 sum6
->ipv6IfIcmpInNeighborSolicits
+=
2512 icmp6
->ipv6IfIcmpInNeighborSolicits
;
2513 sum6
->ipv6IfIcmpInNeighborAdvertisements
+=
2514 icmp6
->ipv6IfIcmpInNeighborAdvertisements
;
2515 sum6
->ipv6IfIcmpInRedirects
+= icmp6
->ipv6IfIcmpInRedirects
;
2516 sum6
->ipv6IfIcmpInGroupMembQueries
+=
2517 icmp6
->ipv6IfIcmpInGroupMembQueries
;
2518 sum6
->ipv6IfIcmpInGroupMembResponses
+=
2519 icmp6
->ipv6IfIcmpInGroupMembResponses
;
2520 sum6
->ipv6IfIcmpInGroupMembReductions
+=
2521 icmp6
->ipv6IfIcmpInGroupMembReductions
;
2522 sum6
->ipv6IfIcmpOutMsgs
+= icmp6
->ipv6IfIcmpOutMsgs
;
2523 sum6
->ipv6IfIcmpOutErrors
+= icmp6
->ipv6IfIcmpOutErrors
;
2524 sum6
->ipv6IfIcmpOutDestUnreachs
+= icmp6
->ipv6IfIcmpOutDestUnreachs
;
2525 sum6
->ipv6IfIcmpOutAdminProhibs
+= icmp6
->ipv6IfIcmpOutAdminProhibs
;
2526 sum6
->ipv6IfIcmpOutTimeExcds
+= icmp6
->ipv6IfIcmpOutTimeExcds
;
2527 sum6
->ipv6IfIcmpOutParmProblems
+= icmp6
->ipv6IfIcmpOutParmProblems
;
2528 sum6
->ipv6IfIcmpOutPktTooBigs
+= icmp6
->ipv6IfIcmpOutPktTooBigs
;
2529 sum6
->ipv6IfIcmpOutEchos
+= icmp6
->ipv6IfIcmpOutEchos
;
2530 sum6
->ipv6IfIcmpOutEchoReplies
+= icmp6
->ipv6IfIcmpOutEchoReplies
;
2531 sum6
->ipv6IfIcmpOutRouterSolicits
+=
2532 icmp6
->ipv6IfIcmpOutRouterSolicits
;
2533 sum6
->ipv6IfIcmpOutRouterAdvertisements
+=
2534 icmp6
->ipv6IfIcmpOutRouterAdvertisements
;
2535 sum6
->ipv6IfIcmpOutNeighborSolicits
+=
2536 icmp6
->ipv6IfIcmpOutNeighborSolicits
;
2537 sum6
->ipv6IfIcmpOutNeighborAdvertisements
+=
2538 icmp6
->ipv6IfIcmpOutNeighborAdvertisements
;
2539 sum6
->ipv6IfIcmpOutRedirects
+= icmp6
->ipv6IfIcmpOutRedirects
;
2540 sum6
->ipv6IfIcmpOutGroupMembQueries
+=
2541 icmp6
->ipv6IfIcmpOutGroupMembQueries
;
2542 sum6
->ipv6IfIcmpOutGroupMembResponses
+=
2543 icmp6
->ipv6IfIcmpOutGroupMembResponses
;
2544 sum6
->ipv6IfIcmpOutGroupMembReductions
+=
2545 icmp6
->ipv6IfIcmpOutGroupMembReductions
;
2546 sum6
->ipv6IfIcmpInOverflows
+= icmp6
->ipv6IfIcmpInOverflows
;
2549 /* ----------------------------- MRT_STAT_REPORT --------------------------- */
2552 mrt_stat_report(mib_item_t
*curritem
)
2555 mib_item_t
*tempitem
;
2557 if (!(family_selected(AF_INET
)))
2560 (void) putchar('\n');
2562 for (tempitem
= curritem
;
2564 tempitem
= tempitem
->next_item
) {
2566 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
2567 (void) printf("Group = %d, mib_id = %d, "
2568 "length = %d, valp = 0x%p\n",
2569 tempitem
->group
, tempitem
->mib_id
,
2570 tempitem
->length
, tempitem
->valp
);
2573 if (tempitem
->mib_id
== 0) {
2574 switch (tempitem
->group
) {
2576 struct mrtstat
*mrts
;
2577 mrts
= (struct mrtstat
*)tempitem
->valp
;
2579 if (!(family_selected(AF_INET
)))
2580 continue; /* 'for' loop 1 */
2582 print_mrt_stats(mrts
);
2587 } /* 'for' loop 1 ends */
2588 (void) putchar('\n');
2589 (void) fflush(stdout
);
2593 * if_stat_total() - Computes totals for interface statistics
2594 * and returns result by updating sumstats.
2597 if_stat_total(struct ifstat
*oldstats
, struct ifstat
*newstats
,
2598 struct ifstat
*sumstats
)
2600 sumstats
->ipackets
+= newstats
->ipackets
- oldstats
->ipackets
;
2601 sumstats
->opackets
+= newstats
->opackets
- oldstats
->opackets
;
2602 sumstats
->ierrors
+= newstats
->ierrors
- oldstats
->ierrors
;
2603 sumstats
->oerrors
+= newstats
->oerrors
- oldstats
->oerrors
;
2604 sumstats
->collisions
+= newstats
->collisions
- oldstats
->collisions
;
2607 /* --------------------- IF_REPORT (netstat -i) -------------------------- */
2609 static struct ifstat zerostat
= {
2610 0LL, 0LL, 0LL, 0LL, 0LL
2614 if_report(mib_item_t
*item
, char *matchname
,
2615 int Iflag_only
, boolean_t once_only
)
2617 static boolean_t reentry
= B_FALSE
;
2618 boolean_t alreadydone
= B_FALSE
;
2620 uint32_t ifindex_v4
= 0;
2621 uint32_t ifindex_v6
= 0;
2622 boolean_t first_header
= B_TRUE
;
2625 for (; item
; item
= item
->next_item
) {
2627 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
2628 (void) printf("Group = %d, mib_id = %d, "
2629 "length = %d, valp = 0x%p\n",
2630 item
->group
, item
->mib_id
, item
->length
,
2634 switch (item
->group
) {
2636 if (item
->mib_id
!= MIB2_IP_ADDR
||
2637 !family_selected(AF_INET
))
2638 continue; /* 'for' loop 1 */
2640 static struct ifstat old
= {0L, 0L, 0L, 0L, 0L};
2641 static struct ifstat
new = {0L, 0L, 0L, 0L, 0L};
2643 struct iflist
*newlist
= NULL
;
2644 static struct iflist
*oldlist
= NULL
;
2648 char ifname
[LIFNAMSIZ
+ 1];
2649 char logintname
[LIFNAMSIZ
+ 1];
2650 mib2_ipAddrEntry_t
*ap
;
2651 struct ifstat stat
= {0L, 0L, 0L, 0L, 0L};
2652 boolean_t first
= B_TRUE
;
2653 uint32_t new_ifindex
;
2656 (void) printf("if_report: %d items\n",
2658 / sizeof (mib2_ipAddrEntry_t
));
2660 /* 'for' loop 2a: */
2661 for (ap
= (mib2_ipAddrEntry_t
*)item
->valp
;
2662 (char *)ap
< (char *)item
->valp
2665 (void) octetstr(&ap
->ipAdEntIfIndex
,
2667 sizeof (logintname
));
2668 (void) strcpy(ifname
, logintname
);
2669 (void) strtok(ifname
, ":");
2670 if (matchname
!= NULL
&&
2671 strcmp(matchname
, ifname
) != 0 &&
2672 strcmp(matchname
, logintname
) != 0)
2673 continue; /* 'for' loop 2a */
2675 if_nametoindex(logintname
);
2677 * First lookup the "link" kstats in
2678 * case the link is renamed. Then
2679 * fallback to the legacy kstats for
2680 * those non-GLDv3 links.
2682 if (new_ifindex
!= ifindex_v4
&&
2683 (((ksp
= kstat_lookup(kc
, "link", 0,
2684 ifname
)) != NULL
) ||
2685 ((ksp
= kstat_lookup(kc
, NULL
, -1,
2686 ifname
)) != NULL
))) {
2687 (void) safe_kstat_read(kc
, ksp
,
2690 kstat_named_value(ksp
,
2693 kstat_named_value(ksp
,
2696 kstat_named_value(ksp
,
2699 kstat_named_value(ksp
,
2702 kstat_named_value(ksp
,
2706 (void) putchar('\n');
2707 first_header
= B_FALSE
;
2709 "%-5.5s %-5.5s%-13.13s "
2710 "%-14.14s %-6.6s %-5.5s "
2711 "%-6.6s %-5.5s %-6.6s "
2713 "Name", "Mtu", "Net/Dest",
2715 "Ierrs", "Opkts", "Oerrs",
2720 if_report_ip4(ap
, ifname
,
2721 logintname
, &stat
, B_TRUE
);
2722 ifindex_v4
= new_ifindex
;
2724 if_report_ip4(ap
, ifname
,
2725 logintname
, &stat
, B_FALSE
);
2727 } /* 'for' loop 2a ends */
2728 } else if (!alreadydone
) {
2729 char ifname
[LIFNAMSIZ
+ 1];
2730 char buf
[LIFNAMSIZ
+ 1];
2731 mib2_ipAddrEntry_t
*ap
;
2733 struct iflist
*tlp
= NULL
;
2734 struct iflist
**nextnew
= &newlist
;
2735 struct iflist
*walkold
;
2736 struct iflist
*cleanlist
;
2737 boolean_t found_if
= B_FALSE
;
2739 alreadydone
= B_TRUE
; /* ignore other case */
2742 * Check if there is anything to do.
2745 sizeof (mib2_ipAddrEntry_t
)) {
2746 fail(0, "No compatible interfaces");
2750 * 'for' loop 2b: find the "right" entry:
2751 * If an interface name to match has been
2752 * supplied then try and find it, otherwise
2753 * match the first non-loopback interface found.
2754 * Use lo0 if all else fails.
2756 for (ap
= (mib2_ipAddrEntry_t
*)item
->valp
;
2757 (char *)ap
< (char *)item
->valp
2760 (void) octetstr(&ap
->ipAdEntIfIndex
,
2761 'a', ifname
, sizeof (ifname
));
2762 (void) strtok(ifname
, ":");
2765 if (strcmp(matchname
,
2771 } else if (strcmp(ifname
, "lo0") != 0)
2772 break; /* 'for' loop 2b */
2773 } /* 'for' loop 2b ends */
2775 if (matchname
== NULL
) {
2779 fail(0, "-I: %s no such "
2780 "interface.", matchname
);
2783 if (Iflag_only
== 0 || !reentry
) {
2784 (void) printf(" input %-6.6s "
2787 (void) printf(" input (Total) "
2789 (void) printf("%-7.7s %-5.5s %-7.7s "
2791 "packets", "errs", "packets",
2793 (void) printf("%-7.7s %-5.5s %-7.7s "
2795 "packets", "errs", "packets",
2801 /* 'for' loop 2c: */
2802 for (ap
= (mib2_ipAddrEntry_t
*)item
->valp
;
2803 (char *)ap
< (char *)item
->valp
2806 (void) octetstr(&ap
->ipAdEntIfIndex
,
2807 'a', buf
, sizeof (buf
));
2808 (void) strtok(buf
, ":");
2811 * We have reduced the IP interface
2812 * name, which could have been a
2813 * logical, down to a name suitable
2814 * for use with kstats.
2815 * We treat this name as unique and
2816 * only collate statistics for it once
2817 * per pass. This is to avoid falsely
2818 * amplifying these statistics by the
2819 * the number of logical instances.
2821 if ((tlp
!= NULL
) &&
2822 ((strcmp(buf
, tlp
->ifname
) == 0))) {
2827 * First lookup the "link" kstats in
2828 * case the link is renamed. Then
2829 * fallback to the legacy kstats for
2830 * those non-GLDv3 links.
2832 if (((ksp
= kstat_lookup(kc
, "link",
2834 (ksp
= kstat_lookup(kc
, NULL
, -1,
2835 buf
)) != NULL
) && (ksp
->ks_type
==
2836 KSTAT_TYPE_NAMED
)) {
2837 (void) safe_kstat_read(kc
, ksp
,
2841 t
.ipackets
= kstat_named_value(ksp
,
2843 t
.ierrors
= kstat_named_value(ksp
,
2845 t
.opackets
= kstat_named_value(ksp
,
2847 t
.oerrors
= kstat_named_value(ksp
,
2849 t
.collisions
= kstat_named_value(ksp
,
2852 if (strcmp(buf
, matchname
) == 0)
2855 /* Build the interface list */
2857 tlp
= malloc(sizeof (struct iflist
));
2858 (void) strlcpy(tlp
->ifname
, buf
,
2859 sizeof (tlp
->ifname
));
2862 nextnew
= &tlp
->next_if
;
2865 * First time through.
2866 * Just add up the interface stats.
2869 if (oldlist
== NULL
) {
2870 if_stat_total(&zerostat
,
2876 * Walk old list for the interface.
2878 * If found, add difference to total.
2880 * If not, an interface has been plumbed
2881 * up. In this case, we will simply
2882 * ignore the new interface until the
2883 * next interval; as there's no easy way
2884 * to acquire statistics between time
2885 * of the plumb and the next interval
2886 * boundary. This results in inaccurate
2887 * total values for current interval.
2889 * Note the case when an interface is
2890 * unplumbed; as similar problems exist.
2891 * The unplumbed interface is not in the
2892 * current list, and there's no easy way
2893 * to account for the statistics between
2894 * the previous interval and time of the
2895 * unplumb. Therefore, we (in a sense)
2896 * ignore the removed interface by only
2897 * involving "current" interfaces when
2898 * computing the total statistics.
2899 * Unfortunately, this also results in
2900 * inaccurate values for interval total.
2903 for (walkold
= oldlist
;
2905 walkold
= walkold
->next_if
) {
2906 if (strcmp(walkold
->ifname
,
2915 } /* 'for' loop 2c ends */
2919 (void) printf("%-7llu %-5llu %-7llu "
2921 new.ipackets
- old
.ipackets
,
2922 new.ierrors
- old
.ierrors
,
2923 new.opackets
- old
.opackets
,
2924 new.oerrors
- old
.oerrors
,
2925 new.collisions
- old
.collisions
);
2927 (void) printf("%-7llu %-5llu %-7llu "
2928 "%-5llu %-6llu\n", sum
.ipackets
,
2929 sum
.ierrors
, sum
.opackets
,
2930 sum
.oerrors
, sum
.collisions
);
2933 * Tidy things up once finished.
2937 cleanlist
= oldlist
;
2939 while (cleanlist
!= NULL
) {
2940 tlp
= cleanlist
->next_if
;
2948 if (item
->mib_id
!= MIB2_IP6_ADDR
||
2949 !family_selected(AF_INET6
))
2950 continue; /* 'for' loop 1 */
2952 static struct ifstat old6
= {0L, 0L, 0L, 0L, 0L};
2953 static struct ifstat new6
= {0L, 0L, 0L, 0L, 0L};
2955 struct iflist
*newlist6
= NULL
;
2956 static struct iflist
*oldlist6
= NULL
;
2960 char ifname
[LIFNAMSIZ
+ 1];
2961 char logintname
[LIFNAMSIZ
+ 1];
2962 mib2_ipv6AddrEntry_t
*ap6
;
2963 struct ifstat stat
= {0L, 0L, 0L, 0L, 0L};
2964 boolean_t first
= B_TRUE
;
2965 uint32_t new_ifindex
;
2968 (void) printf("if_report: %d items\n",
2970 / sizeof (mib2_ipv6AddrEntry_t
));
2971 /* 'for' loop 2d: */
2972 for (ap6
= (mib2_ipv6AddrEntry_t
*)item
->valp
;
2973 (char *)ap6
< (char *)item
->valp
2976 (void) octetstr(&ap6
->ipv6AddrIfIndex
,
2978 sizeof (logintname
));
2979 (void) strcpy(ifname
, logintname
);
2980 (void) strtok(ifname
, ":");
2981 if (matchname
!= NULL
&&
2982 strcmp(matchname
, ifname
) != 0 &&
2983 strcmp(matchname
, logintname
) != 0)
2984 continue; /* 'for' loop 2d */
2986 if_nametoindex(logintname
);
2989 * First lookup the "link" kstats in
2990 * case the link is renamed. Then
2991 * fallback to the legacy kstats for
2992 * those non-GLDv3 links.
2994 if (new_ifindex
!= ifindex_v6
&&
2995 ((ksp
= kstat_lookup(kc
, "link", 0,
2997 (ksp
= kstat_lookup(kc
, NULL
, -1,
2998 ifname
)) != NULL
)) {
2999 (void) safe_kstat_read(kc
, ksp
,
3002 kstat_named_value(ksp
,
3005 kstat_named_value(ksp
,
3008 kstat_named_value(ksp
,
3011 kstat_named_value(ksp
,
3014 kstat_named_value(ksp
,
3018 (void) putchar('\n');
3019 first_header
= B_FALSE
;
3033 if_report_ip6(ap6
, ifname
,
3034 logintname
, &stat
, B_TRUE
);
3035 ifindex_v6
= new_ifindex
;
3037 if_report_ip6(ap6
, ifname
,
3038 logintname
, &stat
, B_FALSE
);
3040 } /* 'for' loop 2d ends */
3041 } else if (!alreadydone
) {
3042 char ifname
[LIFNAMSIZ
+ 1];
3043 char buf
[IFNAMSIZ
+ 1];
3044 mib2_ipv6AddrEntry_t
*ap6
;
3046 struct iflist
*tlp
= NULL
;
3047 struct iflist
**nextnew
= &newlist6
;
3048 struct iflist
*walkold
;
3049 struct iflist
*cleanlist
;
3050 boolean_t found_if
= B_FALSE
;
3052 alreadydone
= B_TRUE
; /* ignore other case */
3055 * Check if there is anything to do.
3058 sizeof (mib2_ipv6AddrEntry_t
)) {
3059 fail(0, "No compatible interfaces");
3063 * 'for' loop 2e: find the "right" entry:
3064 * If an interface name to match has been
3065 * supplied then try and find it, otherwise
3066 * match the first non-loopback interface found.
3067 * Use lo0 if all else fails.
3069 for (ap6
= (mib2_ipv6AddrEntry_t
*)item
->valp
;
3070 (char *)ap6
< (char *)item
->valp
3073 (void) octetstr(&ap6
->ipv6AddrIfIndex
,
3074 'a', ifname
, sizeof (ifname
));
3075 (void) strtok(ifname
, ":");
3078 if (strcmp(matchname
,
3084 } else if (strcmp(ifname
, "lo0") != 0)
3085 break; /* 'for' loop 2e */
3086 } /* 'for' loop 2e ends */
3088 if (matchname
== NULL
) {
3092 fail(0, "-I: %s no such "
3093 "interface.", matchname
);
3096 if (Iflag_only
== 0 || !reentry
) {
3101 (void) printf(" input (Total)"
3103 (void) printf("%-7.7s %-5.5s %-7.7s "
3105 "packets", "errs", "packets",
3107 (void) printf("%-7.7s %-5.5s %-7.7s "
3109 "packets", "errs", "packets",
3115 /* 'for' loop 2f: */
3116 for (ap6
= (mib2_ipv6AddrEntry_t
*)item
->valp
;
3117 (char *)ap6
< (char *)item
->valp
3120 (void) octetstr(&ap6
->ipv6AddrIfIndex
,
3121 'a', buf
, sizeof (buf
));
3122 (void) strtok(buf
, ":");
3125 * We have reduced the IP interface
3126 * name, which could have been a
3127 * logical, down to a name suitable
3128 * for use with kstats.
3129 * We treat this name as unique and
3130 * only collate statistics for it once
3131 * per pass. This is to avoid falsely
3132 * amplifying these statistics by the
3133 * the number of logical instances.
3136 if ((tlp
!= NULL
) &&
3137 ((strcmp(buf
, tlp
->ifname
) == 0))) {
3142 * First lookup the "link" kstats in
3143 * case the link is renamed. Then
3144 * fallback to the legacy kstats for
3145 * those non-GLDv3 links.
3147 if (((ksp
= kstat_lookup(kc
, "link",
3149 (ksp
= kstat_lookup(kc
, NULL
, -1,
3150 buf
)) != NULL
) && (ksp
->ks_type
==
3151 KSTAT_TYPE_NAMED
)) {
3152 (void) safe_kstat_read(kc
,
3156 t
.ipackets
= kstat_named_value(ksp
,
3158 t
.ierrors
= kstat_named_value(ksp
,
3160 t
.opackets
= kstat_named_value(ksp
,
3162 t
.oerrors
= kstat_named_value(ksp
,
3164 t
.collisions
= kstat_named_value(ksp
,
3167 if (strcmp(buf
, matchname
) == 0)
3170 /* Build the interface list */
3172 tlp
= malloc(sizeof (struct iflist
));
3173 (void) strlcpy(tlp
->ifname
, buf
,
3174 sizeof (tlp
->ifname
));
3177 nextnew
= &tlp
->next_if
;
3180 * First time through.
3181 * Just add up the interface stats.
3184 if (oldlist6
== NULL
) {
3185 if_stat_total(&zerostat
,
3191 * Walk old list for the interface.
3193 * If found, add difference to total.
3195 * If not, an interface has been plumbed
3196 * up. In this case, we will simply
3197 * ignore the new interface until the
3198 * next interval; as there's no easy way
3199 * to acquire statistics between time
3200 * of the plumb and the next interval
3201 * boundary. This results in inaccurate
3202 * total values for current interval.
3204 * Note the case when an interface is
3205 * unplumbed; as similar problems exist.
3206 * The unplumbed interface is not in the
3207 * current list, and there's no easy way
3208 * to account for the statistics between
3209 * the previous interval and time of the
3210 * unplumb. Therefore, we (in a sense)
3211 * ignore the removed interface by only
3212 * involving "current" interfaces when
3213 * computing the total statistics.
3214 * Unfortunately, this also results in
3215 * inaccurate values for interval total.
3218 for (walkold
= oldlist6
;
3220 walkold
= walkold
->next_if
) {
3221 if (strcmp(walkold
->ifname
,
3230 } /* 'for' loop 2f ends */
3234 (void) printf("%-7llu %-5llu %-7llu "
3236 new6
.ipackets
- old6
.ipackets
,
3237 new6
.ierrors
- old6
.ierrors
,
3238 new6
.opackets
- old6
.opackets
,
3239 new6
.oerrors
- old6
.oerrors
,
3240 new6
.collisions
- old6
.collisions
);
3242 (void) printf("%-7llu %-5llu %-7llu "
3243 "%-5llu %-6llu\n", sum6
.ipackets
,
3244 sum6
.ierrors
, sum6
.opackets
,
3245 sum6
.oerrors
, sum6
.collisions
);
3248 * Tidy things up once finished.
3252 cleanlist
= oldlist6
;
3253 oldlist6
= newlist6
;
3254 while (cleanlist
!= NULL
) {
3255 tlp
= cleanlist
->next_if
;
3263 (void) fflush(stdout
);
3264 } /* 'for' loop 1 ends */
3265 if ((Iflag_only
== 0) && (!once_only
))
3266 (void) putchar('\n');
3271 if_report_ip4(mib2_ipAddrEntry_t
*ap
,
3272 char ifname
[], char logintname
[], struct ifstat
*statptr
,
3273 boolean_t ksp_not_null
)
3276 char abuf
[MAXHOSTNAMELEN
+ 4]; /* Include /<num> for CIDR-printing. */
3277 char dstbuf
[MAXHOSTNAMELEN
+ 1];
3280 (void) printf("%-5s %-4u ",
3281 ifname
, ap
->ipAdEntInfo
.ae_mtu
);
3282 if (ap
->ipAdEntInfo
.ae_flags
& IFF_POINTOPOINT
)
3283 (void) pr_addr(ap
->ipAdEntInfo
.ae_pp_dst_addr
,
3284 abuf
, sizeof (abuf
));
3286 (void) pr_netaddr(ap
->ipAdEntAddr
,
3287 ap
->ipAdEntNetMask
, abuf
, sizeof (abuf
));
3288 (void) printf("%-13s %-14s %-6llu %-5llu %-6llu %-5llu "
3290 abuf
, pr_addr(ap
->ipAdEntAddr
, dstbuf
, sizeof (dstbuf
)),
3291 statptr
->ipackets
, statptr
->ierrors
,
3292 statptr
->opackets
, statptr
->oerrors
,
3293 statptr
->collisions
, 0LL);
3296 * Print logical interface info if Aflag set (including logical unit 0)
3299 *statptr
= zerostat
;
3300 statptr
->ipackets
= ap
->ipAdEntInfo
.ae_ibcnt
;
3301 statptr
->opackets
= ap
->ipAdEntInfo
.ae_obcnt
;
3303 (void) printf("%-5s %-4u ", logintname
, ap
->ipAdEntInfo
.ae_mtu
);
3304 if (ap
->ipAdEntInfo
.ae_flags
& IFF_POINTOPOINT
)
3305 (void) pr_addr(ap
->ipAdEntInfo
.ae_pp_dst_addr
, abuf
,
3308 (void) pr_netaddr(ap
->ipAdEntAddr
, ap
->ipAdEntNetMask
,
3309 abuf
, sizeof (abuf
));
3311 (void) printf("%-13s %-14s %-6llu %-5s %-6s "
3312 "%-5s %-6s %-6llu\n", abuf
,
3313 pr_addr(ap
->ipAdEntAddr
, dstbuf
, sizeof (dstbuf
)),
3314 statptr
->ipackets
, "N/A", "N/A", "N/A", "N/A",
3320 if_report_ip6(mib2_ipv6AddrEntry_t
*ap6
,
3321 char ifname
[], char logintname
[], struct ifstat
*statptr
,
3322 boolean_t ksp_not_null
)
3325 char abuf
[MAXHOSTNAMELEN
+ 1];
3326 char dstbuf
[MAXHOSTNAMELEN
+ 1];
3329 (void) printf("%-5s %-4u ", ifname
, ap6
->ipv6AddrInfo
.ae_mtu
);
3330 if (ap6
->ipv6AddrInfo
.ae_flags
&
3332 (void) pr_addr6(&ap6
->ipv6AddrInfo
.ae_pp_dst_addr
,
3333 abuf
, sizeof (abuf
));
3335 (void) pr_prefix6(&ap6
->ipv6AddrAddress
,
3336 ap6
->ipv6AddrPfxLength
, abuf
,
3339 (void) printf("%-27s %-27s %-6llu %-5llu "
3340 "%-6llu %-5llu %-6llu\n",
3341 abuf
, pr_addr6(&ap6
->ipv6AddrAddress
, dstbuf
,
3343 statptr
->ipackets
, statptr
->ierrors
, statptr
->opackets
,
3344 statptr
->oerrors
, statptr
->collisions
);
3347 * Print logical interface info if Aflag set (including logical unit 0)
3350 *statptr
= zerostat
;
3351 statptr
->ipackets
= ap6
->ipv6AddrInfo
.ae_ibcnt
;
3352 statptr
->opackets
= ap6
->ipv6AddrInfo
.ae_obcnt
;
3354 (void) printf("%-5s %-4u ", logintname
,
3355 ap6
->ipv6AddrInfo
.ae_mtu
);
3356 if (ap6
->ipv6AddrInfo
.ae_flags
& IFF_POINTOPOINT
)
3357 (void) pr_addr6(&ap6
->ipv6AddrInfo
.ae_pp_dst_addr
,
3358 abuf
, sizeof (abuf
));
3360 (void) pr_prefix6(&ap6
->ipv6AddrAddress
,
3361 ap6
->ipv6AddrPfxLength
, abuf
, sizeof (abuf
));
3362 (void) printf("%-27s %-27s %-6llu %-5s %-6s %-5s %-6s\n",
3363 abuf
, pr_addr6(&ap6
->ipv6AddrAddress
, dstbuf
,
3365 statptr
->ipackets
, "N/A", "N/A", "N/A", "N/A");
3369 /* --------------------- DHCP_REPORT (netstat -D) ------------------------- */
3372 dhcp_do_ipc(dhcp_ipc_type_t type
, const char *ifname
, boolean_t printed_one
)
3374 dhcp_ipc_request_t
*request
;
3375 dhcp_ipc_reply_t
*reply
;
3378 request
= dhcp_ipc_alloc_request(type
, ifname
, NULL
, 0, DHCP_TYPE_NONE
);
3379 if (request
== NULL
)
3380 fail(0, "dhcp_do_ipc: out of memory");
3382 error
= dhcp_ipc_make_request(request
, &reply
, DHCP_IPC_WAIT_DEFAULT
);
3385 fail(0, "dhcp_do_ipc: %s", dhcp_ipc_strerror(error
));
3389 error
= reply
->return_code
;
3390 if (error
== DHCP_IPC_E_UNKIF
) {
3392 return (printed_one
);
3396 fail(0, "dhcp_do_ipc: %s", dhcp_ipc_strerror(error
));
3399 if (timestamp_fmt
!= NODATE
)
3400 print_timestamp(timestamp_fmt
);
3403 (void) printf("%s", dhcp_status_hdr_string());
3405 (void) printf("%s", dhcp_status_reply_to_string(reply
));
3411 * dhcp_walk_interfaces: walk the list of interfaces for a given address
3412 * family (af). For each, print out the DHCP status using dhcp_do_ipc.
3415 dhcp_walk_interfaces(int af
, boolean_t printed_one
)
3418 struct lifconf lifc
;
3419 int n_ifs
, i
, sock_fd
;
3421 sock_fd
= socket(af
, SOCK_DGRAM
, 0);
3423 return (printed_one
);
3426 * SIOCGLIFNUM is just an estimate. If the ioctl fails, we don't care;
3427 * just drive on and use SIOCGLIFCONF with increasing buffer sizes, as
3430 (void) memset(&lifn
, 0, sizeof (lifn
));
3431 lifn
.lifn_family
= af
;
3432 lifn
.lifn_flags
= LIFC_ALLZONES
| LIFC_NOXMIT
| LIFC_UNDER_IPMP
;
3433 if (ioctl(sock_fd
, SIOCGLIFNUM
, &lifn
) == -1)
3434 n_ifs
= LIFN_GUARD_VALUE
;
3436 n_ifs
= lifn
.lifn_count
+ LIFN_GUARD_VALUE
;
3438 (void) memset(&lifc
, 0, sizeof (lifc
));
3439 lifc
.lifc_family
= af
;
3440 lifc
.lifc_flags
= lifn
.lifn_flags
;
3441 lifc
.lifc_len
= n_ifs
* sizeof (struct lifreq
);
3442 lifc
.lifc_buf
= malloc(lifc
.lifc_len
);
3443 if (lifc
.lifc_buf
!= NULL
) {
3445 if (ioctl(sock_fd
, SIOCGLIFCONF
, &lifc
) == -1) {
3446 (void) close(sock_fd
);
3447 free(lifc
.lifc_buf
);
3451 n_ifs
= lifc
.lifc_len
/ sizeof (struct lifreq
);
3453 for (i
= 0; i
< n_ifs
; i
++) {
3454 printed_one
= dhcp_do_ipc(DHCP_STATUS
|
3455 (af
== AF_INET6
? DHCP_V6
: 0),
3456 lifc
.lifc_req
[i
].lifr_name
, printed_one
);
3459 (void) close(sock_fd
);
3460 free(lifc
.lifc_buf
);
3461 return (printed_one
);
3465 dhcp_report(char *ifname
)
3467 boolean_t printed_one
;
3469 if (!family_selected(AF_INET
) && !family_selected(AF_INET6
))
3472 printed_one
= B_FALSE
;
3473 if (ifname
!= NULL
) {
3474 if (family_selected(AF_INET
)) {
3475 printed_one
= dhcp_do_ipc(DHCP_STATUS
, ifname
,
3478 if (family_selected(AF_INET6
)) {
3479 printed_one
= dhcp_do_ipc(DHCP_STATUS
| DHCP_V6
,
3480 ifname
, printed_one
);
3483 fail(0, "%s: %s", ifname
,
3484 dhcp_ipc_strerror(DHCP_IPC_E_UNKIF
));
3487 if (family_selected(AF_INET
)) {
3488 printed_one
= dhcp_walk_interfaces(AF_INET
,
3491 if (family_selected(AF_INET6
))
3492 (void) dhcp_walk_interfaces(AF_INET6
, printed_one
);
3496 /* --------------------- GROUP_REPORT (netstat -g) ------------------------- */
3499 group_report(mib_item_t
*item
)
3501 mib_item_t
*v4grp
= NULL
, *v4src
= NULL
;
3502 mib_item_t
*v6grp
= NULL
, *v6src
= NULL
;
3504 char ifname
[LIFNAMSIZ
+ 1];
3505 char abuf
[MAXHOSTNAMELEN
+ 1];
3508 ipv6_member_t
*ipmp6
;
3509 ipv6_grpsrc_t
*ips6
;
3510 boolean_t first
, first_src
;
3513 for (; item
; item
= item
->next_item
) {
3515 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
3516 (void) printf("Group = %d, mib_id = %d, "
3517 "length = %d, valp = 0x%p\n",
3518 item
->group
, item
->mib_id
, item
->length
,
3521 if (item
->group
== MIB2_IP
&& family_selected(AF_INET
)) {
3522 switch (item
->mib_id
) {
3523 case EXPER_IP_GROUP_MEMBERSHIP
:
3526 (void) printf("item is v4grp info\n");
3528 case EXPER_IP_GROUP_SOURCES
:
3531 (void) printf("item is v4src info\n");
3538 if (item
->group
== MIB2_IP6
&& family_selected(AF_INET6
)) {
3539 switch (item
->mib_id
) {
3540 case EXPER_IP6_GROUP_MEMBERSHIP
:
3543 (void) printf("item is v6grp info\n");
3545 case EXPER_IP6_GROUP_SOURCES
:
3548 (void) printf("item is v6src info\n");
3556 if (family_selected(AF_INET
) && v4grp
!= NULL
) {
3558 (void) printf("%u records for ipGroupMember:\n",
3559 v4grp
->length
/ sizeof (ip_member_t
));
3562 for (ipmp
= (ip_member_t
*)v4grp
->valp
;
3563 (char *)ipmp
< (char *)v4grp
->valp
+ v4grp
->length
;
3564 /* LINTED: (note 1) */
3565 ipmp
= (ip_member_t
*)((char *)ipmp
+ ipMemberEntrySize
)) {
3567 (void) puts(v4compat
?
3568 "Group Memberships" :
3569 "Group Memberships: IPv4");
3570 (void) puts("Interface "
3572 (void) puts("--------- "
3573 "-------------------- ------");
3577 (void) printf("%-9s %-20s %6u\n",
3578 octetstr(&ipmp
->ipGroupMemberIfIndex
, 'a',
3579 ifname
, sizeof (ifname
)),
3580 pr_addr(ipmp
->ipGroupMemberAddress
,
3581 abuf
, sizeof (abuf
)),
3582 ipmp
->ipGroupMemberRefCnt
);
3585 if (!Vflag
|| v4src
== NULL
)
3589 (void) printf("scanning %u ipGroupSource "
3591 v4src
->length
/sizeof (ip_grpsrc_t
));
3594 for (ips
= (ip_grpsrc_t
*)v4src
->valp
;
3595 (char *)ips
< (char *)v4src
->valp
+ v4src
->length
;
3596 /* LINTED: (note 1) */
3597 ips
= (ip_grpsrc_t
*)((char *)ips
+
3598 ipGroupSourceEntrySize
)) {
3600 * We assume that all source addrs for a given
3601 * interface/group pair are contiguous, so on
3602 * the first non-match after we've found at
3603 * least one, we bail.
3605 if ((ipmp
->ipGroupMemberAddress
!=
3606 ips
->ipGroupSourceGroup
) ||
3607 (!octetstrmatch(&ipmp
->ipGroupMemberIfIndex
,
3608 &ips
->ipGroupSourceIfIndex
))) {
3615 (void) printf("\t%s: %s\n",
3617 ipmp
->ipGroupMemberFilterMode
),
3618 pr_addr(ips
->ipGroupSourceAddress
,
3619 abuf
, sizeof (abuf
)));
3620 first_src
= B_FALSE
;
3624 (void) printf("\t %s\n",
3625 pr_addr(ips
->ipGroupSourceAddress
, abuf
,
3629 (void) putchar('\n');
3632 if (family_selected(AF_INET6
) && v6grp
!= NULL
) {
3634 (void) printf("%u records for ipv6GroupMember:\n",
3635 v6grp
->length
/ sizeof (ipv6_member_t
));
3638 for (ipmp6
= (ipv6_member_t
*)v6grp
->valp
;
3639 (char *)ipmp6
< (char *)v6grp
->valp
+ v6grp
->length
;
3640 /* LINTED: (note 1) */
3641 ipmp6
= (ipv6_member_t
*)((char *)ipmp6
+
3642 ipv6MemberEntrySize
)) {
3644 (void) puts("Group Memberships: "
3648 (void) puts("----- "
3649 "--------------------------- ------");
3653 (void) printf("%-5s %-27s %5u\n",
3654 ifindex2str(ipmp6
->ipv6GroupMemberIfIndex
, ifname
),
3655 pr_addr6(&ipmp6
->ipv6GroupMemberAddress
,
3656 abuf
, sizeof (abuf
)),
3657 ipmp6
->ipv6GroupMemberRefCnt
);
3659 if (!Vflag
|| v6src
== NULL
)
3663 (void) printf("scanning %u ipv6GroupSource "
3665 v6src
->length
/sizeof (ipv6_grpsrc_t
));
3668 for (ips6
= (ipv6_grpsrc_t
*)v6src
->valp
;
3669 (char *)ips6
< (char *)v6src
->valp
+ v6src
->length
;
3670 /* LINTED: (note 1) */
3671 ips6
= (ipv6_grpsrc_t
*)((char *)ips6
+
3672 ipv6GroupSourceEntrySize
)) {
3673 /* same assumption as in the v4 case above */
3674 if ((ipmp6
->ipv6GroupMemberIfIndex
!=
3675 ips6
->ipv6GroupSourceIfIndex
) ||
3676 (!IN6_ARE_ADDR_EQUAL(
3677 &ipmp6
->ipv6GroupMemberAddress
,
3678 &ips6
->ipv6GroupSourceGroup
))) {
3685 (void) printf("\t%s: %s\n",
3687 ipmp6
->ipv6GroupMemberFilterMode
),
3689 &ips6
->ipv6GroupSourceAddress
,
3690 abuf
, sizeof (abuf
)));
3691 first_src
= B_FALSE
;
3695 (void) printf("\t %s\n",
3696 pr_addr6(&ips6
->ipv6GroupSourceAddress
,
3697 abuf
, sizeof (abuf
)));
3700 (void) putchar('\n');
3703 (void) putchar('\n');
3704 (void) fflush(stdout
);
3707 /* --------------------- DCE_REPORT (netstat -d) ------------------------- */
3711 /* Assumes flbuf is at least 5 characters; callers use FLBUFSIZE */
3713 dceflags2str(uint32_t flags
, char *flbuf
)
3717 if (flags
& DCEF_DEFAULT
)
3719 if (flags
& DCEF_PMTU
)
3721 if (flags
& DCEF_UINFO
)
3723 if (flags
& DCEF_TOO_SMALL_PMTU
)
3730 dce_report(mib_item_t
*item
)
3732 mib_item_t
*v4dce
= NULL
;
3733 mib_item_t
*v6dce
= NULL
;
3735 char ifname
[LIFNAMSIZ
+ 1];
3736 char abuf
[MAXHOSTNAMELEN
+ 1];
3737 char flbuf
[FLBUFSIZE
];
3739 dest_cache_entry_t
*dce
;
3742 for (; item
; item
= item
->next_item
) {
3744 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
3745 (void) printf("Group = %d, mib_id = %d, "
3746 "length = %d, valp = 0x%p\n",
3747 item
->group
, item
->mib_id
, item
->length
,
3750 if (item
->group
== MIB2_IP
&& family_selected(AF_INET
) &&
3751 item
->mib_id
== EXPER_IP_DCE
) {
3754 (void) printf("item is v4dce info\n");
3756 if (item
->group
== MIB2_IP6
&& family_selected(AF_INET6
) &&
3757 item
->mib_id
== EXPER_IP_DCE
) {
3760 (void) printf("item is v6dce info\n");
3764 if (family_selected(AF_INET
) && v4dce
!= NULL
) {
3766 (void) printf("%u records for DestCacheEntry:\n",
3767 v4dce
->length
/ ipDestEntrySize
);
3770 for (dce
= (dest_cache_entry_t
*)v4dce
->valp
;
3771 (char *)dce
< (char *)v4dce
->valp
+ v4dce
->length
;
3772 /* LINTED: (note 1) */
3773 dce
= (dest_cache_entry_t
*)((char *)dce
+
3776 (void) putchar('\n');
3777 (void) puts("Destination Cache Entries: IPv4");
3779 "Address PMTU Age Flags");
3781 "-------------------- ------ ----- -----");
3785 (void) printf("%-20s %6u %5u %-5s\n",
3786 pr_addr(dce
->DestIpv4Address
, abuf
, sizeof (abuf
)),
3787 dce
->DestPmtu
, dce
->DestAge
,
3788 dceflags2str(dce
->DestFlags
, flbuf
));
3792 if (family_selected(AF_INET6
) && v6dce
!= NULL
) {
3794 (void) printf("%u records for DestCacheEntry:\n",
3795 v6dce
->length
/ ipDestEntrySize
);
3798 for (dce
= (dest_cache_entry_t
*)v6dce
->valp
;
3799 (char *)dce
< (char *)v6dce
->valp
+ v6dce
->length
;
3800 /* LINTED: (note 1) */
3801 dce
= (dest_cache_entry_t
*)((char *)dce
+
3804 (void) putchar('\n');
3805 (void) puts("Destination Cache Entries: IPv6");
3810 "--------------------------- ------ "
3815 (void) printf("%-27s %6u %5u %-5s %s\n",
3816 pr_addr6(&dce
->DestIpv6Address
, abuf
,
3818 dce
->DestPmtu
, dce
->DestAge
,
3819 dceflags2str(dce
->DestFlags
, flbuf
),
3820 dce
->DestIfindex
== 0 ? "" :
3821 ifindex2str(dce
->DestIfindex
, ifname
));
3824 (void) fflush(stdout
);
3827 /* --------------------- ARP_REPORT (netstat -p) -------------------------- */
3830 arp_report(mib_item_t
*item
)
3833 char ifname
[LIFNAMSIZ
+ 1];
3834 char abuf
[MAXHOSTNAMELEN
+ 1];
3835 char maskbuf
[STR_EXPAND
* OCTET_LENGTH
+ 1];
3836 char flbuf
[32]; /* ACE_F_ flags */
3837 char xbuf
[STR_EXPAND
* OCTET_LENGTH
+ 1];
3838 mib2_ipNetToMediaEntry_t
*np
;
3842 if (!(family_selected(AF_INET
)))
3846 for (; item
; item
= item
->next_item
) {
3848 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
3849 (void) printf("Group = %d, mib_id = %d, "
3850 "length = %d, valp = 0x%p\n",
3851 item
->group
, item
->mib_id
, item
->length
,
3854 if (!(item
->group
== MIB2_IP
&& item
->mib_id
== MIB2_IP_MEDIA
))
3855 continue; /* 'for' loop 1 */
3858 (void) printf("%u records for "
3859 "ipNetToMediaEntryTable:\n",
3860 item
->length
/sizeof (mib2_ipNetToMediaEntry_t
));
3864 for (np
= (mib2_ipNetToMediaEntry_t
*)item
->valp
;
3865 (char *)np
< (char *)item
->valp
+ item
->length
;
3866 /* LINTED: (note 1) */
3867 np
= (mib2_ipNetToMediaEntry_t
*)((char *)np
+
3868 ipNetToMediaEntrySize
)) {
3870 (void) puts(v4compat
?
3871 "Net to Media Table" :
3872 "Net to Media Table: IPv4");
3873 (void) puts("Device "
3876 (void) puts("------ "
3877 "-------------------- --------------- "
3878 "-------- ---------------");
3883 flags
= np
->ipNetToMediaInfo
.ntm_flags
;
3885 * Note that not all flags are possible at the same
3886 * time. Patterns: SPLAy DUo
3888 if (flags
& ACE_F_PERMANENT
)
3889 (void) strcat(flbuf
, "S");
3890 if (flags
& ACE_F_PUBLISH
)
3891 (void) strcat(flbuf
, "P");
3892 if (flags
& ACE_F_DYING
)
3893 (void) strcat(flbuf
, "D");
3894 if (!(flags
& ACE_F_RESOLVED
))
3895 (void) strcat(flbuf
, "U");
3896 if (flags
& ACE_F_MAPPING
)
3897 (void) strcat(flbuf
, "M");
3898 if (flags
& ACE_F_MYADDR
)
3899 (void) strcat(flbuf
, "L");
3900 if (flags
& ACE_F_UNVERIFIED
)
3901 (void) strcat(flbuf
, "d");
3902 if (flags
& ACE_F_AUTHORITY
)
3903 (void) strcat(flbuf
, "A");
3904 if (flags
& ACE_F_OLD
)
3905 (void) strcat(flbuf
, "o");
3906 if (flags
& ACE_F_DELAYED
)
3907 (void) strcat(flbuf
, "y");
3908 (void) printf("%-6s %-20s %-15s %-8s %s\n",
3909 octetstr(&np
->ipNetToMediaIfIndex
, 'a',
3910 ifname
, sizeof (ifname
)),
3911 pr_addr(np
->ipNetToMediaNetAddress
,
3912 abuf
, sizeof (abuf
)),
3913 octetstr(&np
->ipNetToMediaInfo
.ntm_mask
, 'd',
3914 maskbuf
, sizeof (maskbuf
)),
3916 octetstr(&np
->ipNetToMediaPhysAddress
, 'h',
3917 xbuf
, sizeof (xbuf
)));
3918 } /* 'for' loop 2 ends */
3919 } /* 'for' loop 1 ends */
3920 (void) fflush(stdout
);
3923 /* --------------------- NDP_REPORT (netstat -p) -------------------------- */
3926 ndp_report(mib_item_t
*item
)
3929 char abuf
[MAXHOSTNAMELEN
+ 1];
3932 char xbuf
[STR_EXPAND
* OCTET_LENGTH
+ 1];
3933 mib2_ipv6NetToMediaEntry_t
*np6
;
3934 char ifname
[LIFNAMSIZ
+ 1];
3937 if (!(family_selected(AF_INET6
)))
3941 for (; item
; item
= item
->next_item
) {
3943 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
3944 (void) printf("Group = %d, mib_id = %d, "
3945 "length = %d, valp = 0x%p\n",
3946 item
->group
, item
->mib_id
, item
->length
,
3949 if (!(item
->group
== MIB2_IP6
&&
3950 item
->mib_id
== MIB2_IP6_MEDIA
))
3951 continue; /* 'for' loop 1 */
3955 for (np6
= (mib2_ipv6NetToMediaEntry_t
*)item
->valp
;
3956 (char *)np6
< (char *)item
->valp
+ item
->length
;
3957 /* LINTED: (note 1) */
3958 np6
= (mib2_ipv6NetToMediaEntry_t
*)((char *)np6
+
3959 ipv6NetToMediaEntrySize
)) {
3961 (void) puts("\nNet to Media Table: IPv6");
3962 (void) puts(" If Physical Address "
3963 " Type State Destination/Mask");
3964 (void) puts("----- ----------------- "
3965 "------- ------------ "
3966 "---------------------------");
3970 switch (np6
->ipv6NetToMediaState
) {
3972 state
= "INCOMPLETE";
3975 state
= "REACHABLE";
3986 case ND_UNREACHABLE
:
3987 state
= "UNREACHABLE";
3993 switch (np6
->ipv6NetToMediaType
) {
4007 (void) printf("%-5s %-17s %-7s %-12s %-27s\n",
4008 ifindex2str(np6
->ipv6NetToMediaIfIndex
, ifname
),
4009 octetstr(&np6
->ipv6NetToMediaPhysAddress
, 'h',
4010 xbuf
, sizeof (xbuf
)),
4013 pr_addr6(&np6
->ipv6NetToMediaNetAddress
,
4014 abuf
, sizeof (abuf
)));
4015 } /* 'for' loop 2 ends */
4016 } /* 'for' loop 1 ends */
4017 (void) putchar('\n');
4018 (void) fflush(stdout
);
4021 /* ------------------------- ire_report (netstat -r) ------------------------ */
4023 static boolean_t
ire_report_item_v4(const mib2_ipRouteEntry_t
*, boolean_t
);
4024 static boolean_t
ire_report_item_v6(const mib2_ipv6RouteEntry_t
*, boolean_t
);
4027 ire_report(const mib_item_t
*item
)
4030 boolean_t print_hdr_once_v4
= B_TRUE
;
4031 boolean_t print_hdr_once_v6
= B_TRUE
;
4032 mib2_ipRouteEntry_t
*rp
;
4033 mib2_ipv6RouteEntry_t
*rp6
;
4035 for (; item
!= NULL
; item
= item
->next_item
) {
4037 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
4038 (void) printf("Group = %d, mib_id = %d, "
4039 "length = %d, valp = 0x%p\n",
4040 item
->group
, item
->mib_id
,
4041 item
->length
, item
->valp
);
4043 if (!((item
->group
== MIB2_IP
&&
4044 item
->mib_id
== MIB2_IP_ROUTE
) ||
4045 (item
->group
== MIB2_IP6
&&
4046 item
->mib_id
== MIB2_IP6_ROUTE
)))
4047 continue; /* 'for' loop 1 */
4049 if (item
->group
== MIB2_IP
&& !family_selected(AF_INET
))
4050 continue; /* 'for' loop 1 */
4051 else if (item
->group
== MIB2_IP6
&& !family_selected(AF_INET6
))
4052 continue; /* 'for' loop 1 */
4055 if (item
->group
== MIB2_IP
) {
4056 (void) printf("%u records for "
4057 "ipRouteEntryTable:\n",
4058 item
->length
/sizeof (mib2_ipRouteEntry_t
));
4060 (void) printf("%u records for "
4061 "ipv6RouteEntryTable:\n",
4063 sizeof (mib2_ipv6RouteEntry_t
));
4067 if (item
->group
== MIB2_IP
) {
4068 for (rp
= (mib2_ipRouteEntry_t
*)item
->valp
;
4069 (char *)rp
< (char *)item
->valp
+ item
->length
;
4070 /* LINTED: (note 1) */
4071 rp
= (mib2_ipRouteEntry_t
*)((char *)rp
+
4072 ipRouteEntrySize
)) {
4073 print_hdr_once_v4
= ire_report_item_v4(rp
,
4077 for (rp6
= (mib2_ipv6RouteEntry_t
*)item
->valp
;
4078 (char *)rp6
< (char *)item
->valp
+ item
->length
;
4079 /* LINTED: (note 1) */
4080 rp6
= (mib2_ipv6RouteEntry_t
*)((char *)rp6
+
4081 ipv6RouteEntrySize
)) {
4082 print_hdr_once_v6
= ire_report_item_v6(rp6
,
4086 } /* 'for' loop 1 ends */
4087 (void) fflush(stdout
);
4091 * Match a user-supplied device name. We do this by string because
4092 * the MIB2 interface gives us interface name strings rather than
4093 * ifIndex numbers. The "none" rule matches only routes with no
4094 * interface. The "any" rule matches routes with any non-blank
4095 * interface. A base name ("hme0") matches all aliases as well
4099 dev_name_match(const DeviceName
*devnam
, const char *ifname
)
4104 return (devnam
->o_length
== 0); /* "none" */
4105 if (*ifname
== '\0')
4106 return (devnam
->o_length
!= 0); /* "any" */
4107 iflen
= strlen(ifname
);
4108 /* The check for ':' here supports interface aliases. */
4109 if (iflen
> devnam
->o_length
||
4110 (iflen
< devnam
->o_length
&& devnam
->o_bytes
[iflen
] != ':'))
4112 return (strncmp(ifname
, devnam
->o_bytes
, iflen
) == 0);
4116 * Match a user-supplied IP address list. The "any" rule matches any
4117 * non-zero address. The "none" rule matches only the zero address.
4118 * IPv6 addresses supplied by the user are ignored. If the user
4119 * supplies a subnet mask, then match routes that are at least that
4120 * specific (use the user's mask). If the user supplies only an
4121 * address, then select any routes that would match (use the route's
4125 v4_addr_match(IpAddress addr
, IpAddress mask
, const filter_t
*fp
)
4129 in_addr_t faddr
, fmask
;
4131 if (fp
->u
.a
.f_address
== NULL
) {
4132 if (IN6_IS_ADDR_UNSPECIFIED(&fp
->u
.a
.f_mask
))
4133 return (addr
!= INADDR_ANY
); /* "any" */
4135 return (addr
== INADDR_ANY
); /* "none" */
4137 if (!IN6_IS_V4MASK(fp
->u
.a
.f_mask
))
4139 IN6_V4MAPPED_TO_IPADDR(&fp
->u
.a
.f_mask
, fmask
);
4140 if (fmask
!= IP_HOST_MASK
) {
4145 for (app
= fp
->u
.a
.f_address
->h_addr_list
; (aptr
= *app
) != NULL
; app
++)
4146 /* LINTED: (note 1) */
4147 if (IN6_IS_ADDR_V4MAPPED((in6_addr_t
*)aptr
)) {
4148 /* LINTED: (note 1) */
4149 IN6_V4MAPPED_TO_IPADDR((in6_addr_t
*)aptr
, faddr
);
4150 if (((faddr
^ addr
) & mask
) == 0)
4157 * Run through the filter list for an IPv4 MIB2 route entry. If all
4158 * filters of a given type fail to match, then the route is filtered
4159 * out (not displayed). If no filter is given or at least one filter
4160 * of each type matches, then display the route.
4163 ire_filter_match_v4(const mib2_ipRouteEntry_t
*rp
, uint_t flag_b
)
4169 for (idx
= 0; idx
< NFILTERKEYS
; idx
++)
4170 if ((fp
= filters
[idx
]) != NULL
) {
4172 for (; fp
!= NULL
; fp
= fp
->f_next
) {
4175 if (fp
->u
.f_family
!= AF_INET
)
4176 continue; /* 'for' loop 2 */
4179 if (!dev_name_match(&rp
->ipRouteIfIndex
,
4181 continue; /* 'for' loop 2 */
4184 if (!v4_addr_match(rp
->ipRouteDest
,
4185 rp
->ipRouteMask
, fp
))
4186 continue; /* 'for' loop 2 */
4189 if ((flag_b
& fp
->u
.f
.f_flagset
) !=
4190 fp
->u
.f
.f_flagset
||
4191 (flag_b
& fp
->u
.f
.f_flagclear
))
4192 continue; /* 'for' loop 2 */
4196 } /* 'for' loop 2 ends */
4200 /* 'for' loop 1 ends */
4205 * Given an IPv4 MIB2 route entry, form the list of flags for the
4209 form_v4_route_flags(const mib2_ipRouteEntry_t
*rp
, char *flags
)
4214 (void) strcpy(flags
, "U");
4215 /* RTF_INDIRECT wins over RTF_GATEWAY - don't display both */
4216 if (rp
->ipRouteInfo
.re_flags
& RTF_INDIRECT
) {
4217 (void) strcat(flags
, "I");
4219 } else if (rp
->ipRouteInfo
.re_ire_type
& IRE_OFFLINK
) {
4220 (void) strcat(flags
, "G");
4223 /* IRE_IF_CLONE wins over RTF_HOST - don't display both */
4224 if (rp
->ipRouteInfo
.re_ire_type
& IRE_IF_CLONE
) {
4225 (void) strcat(flags
, "C");
4227 } else if (rp
->ipRouteMask
== IP_HOST_MASK
) {
4228 (void) strcat(flags
, "H");
4231 if (rp
->ipRouteInfo
.re_flags
& RTF_DYNAMIC
) {
4232 (void) strcat(flags
, "D");
4235 if (rp
->ipRouteInfo
.re_ire_type
== IRE_BROADCAST
) { /* Broadcast */
4236 (void) strcat(flags
, "b");
4239 if (rp
->ipRouteInfo
.re_ire_type
== IRE_LOCAL
) { /* Local */
4240 (void) strcat(flags
, "L");
4243 if (rp
->ipRouteInfo
.re_flags
& RTF_SETSRC
) {
4244 (void) strcat(flags
, "S"); /* Setsrc */
4247 if (rp
->ipRouteInfo
.re_flags
& RTF_REJECT
) {
4248 (void) strcat(flags
, "R");
4251 if (rp
->ipRouteInfo
.re_flags
& RTF_BLACKHOLE
) {
4252 (void) strcat(flags
, "B");
4255 if (rp
->ipRouteInfo
.re_flags
& RTF_ZONE
) {
4256 (void) strcat(flags
, "Z");
4262 static const char ire_hdr_v4
[] =
4263 "\n%s Table: IPv4\n";
4264 static const char ire_hdr_v4_compat
[] =
4266 static const char ire_hdr_v4_verbose
[] =
4267 " Destination Mask Gateway Device "
4268 " MTU Ref Flg Out In/Fwd\n"
4269 "-------------------- --------------- -------------------- ------ "
4270 "----- --- --- ----- ------\n";
4272 static const char ire_hdr_v4_normal
[] =
4273 " Destination Gateway Flags Ref Use Interface"
4274 "\n-------------------- -------------------- ----- ----- ---------- "
4278 ire_report_item_v4(const mib2_ipRouteEntry_t
*rp
, boolean_t first
)
4280 char dstbuf
[MAXHOSTNAMELEN
+ 4]; /* + "/<num>" */
4281 char maskbuf
[MAXHOSTNAMELEN
+ 1];
4282 char gwbuf
[MAXHOSTNAMELEN
+ 1];
4283 char ifname
[LIFNAMSIZ
+ 1];
4284 char flags
[10]; /* RTF_ flags */
4287 if (!(Aflag
|| (rp
->ipRouteInfo
.re_ire_type
!= IRE_IF_CLONE
&&
4288 rp
->ipRouteInfo
.re_ire_type
!= IRE_BROADCAST
&&
4289 rp
->ipRouteInfo
.re_ire_type
!= IRE_MULTICAST
&&
4290 rp
->ipRouteInfo
.re_ire_type
!= IRE_NOROUTE
&&
4291 rp
->ipRouteInfo
.re_ire_type
!= IRE_LOCAL
))) {
4295 flag_b
= form_v4_route_flags(rp
, flags
);
4297 if (!ire_filter_match_v4(rp
, flag_b
))
4301 (void) printf(v4compat
? ire_hdr_v4_compat
: ire_hdr_v4
,
4302 Vflag
? "IRE" : "Routing");
4303 (void) printf(Vflag
? ire_hdr_v4_verbose
: ire_hdr_v4_normal
);
4307 if (flag_b
& FLF_H
) {
4308 (void) pr_addr(rp
->ipRouteDest
, dstbuf
, sizeof (dstbuf
));
4310 (void) pr_net(rp
->ipRouteDest
, rp
->ipRouteMask
,
4311 dstbuf
, sizeof (dstbuf
));
4314 (void) printf("%-20s %-15s %-20s %-6s %5u %3u "
4317 pr_mask(rp
->ipRouteMask
, maskbuf
, sizeof (maskbuf
)),
4318 pr_addrnz(rp
->ipRouteNextHop
, gwbuf
, sizeof (gwbuf
)),
4319 octetstr(&rp
->ipRouteIfIndex
, 'a', ifname
, sizeof (ifname
)),
4320 rp
->ipRouteInfo
.re_max_frag
,
4321 rp
->ipRouteInfo
.re_ref
,
4323 rp
->ipRouteInfo
.re_obpkt
,
4324 rp
->ipRouteInfo
.re_ibpkt
);
4326 (void) printf("%-20s %-20s %-5s %4u %10u %-9s\n",
4328 pr_addrnz(rp
->ipRouteNextHop
, gwbuf
, sizeof (gwbuf
)),
4330 rp
->ipRouteInfo
.re_ref
,
4331 rp
->ipRouteInfo
.re_obpkt
+ rp
->ipRouteInfo
.re_ibpkt
,
4332 octetstr(&rp
->ipRouteIfIndex
, 'a',
4333 ifname
, sizeof (ifname
)));
4339 * Match a user-supplied IP address list against an IPv6 route entry.
4340 * If the user specified "any," then any non-zero address matches. If
4341 * the user specified "none," then only the zero address matches. If
4342 * the user specified a subnet mask length, then use that in matching
4343 * routes (select routes that are at least as specific). If the user
4344 * specified only an address, then use the route's mask (select routes
4345 * that would match that address). IPv4 addresses are ignored.
4348 v6_addr_match(const Ip6Address
*addr
, int masklen
, const filter_t
*fp
)
4354 const uint8_t *aptr
;
4356 if (fp
->u
.a
.f_address
== NULL
) {
4357 if (IN6_IS_ADDR_UNSPECIFIED(&fp
->u
.a
.f_mask
)) /* any */
4358 return (!IN6_IS_ADDR_UNSPECIFIED(addr
));
4359 return (IN6_IS_ADDR_UNSPECIFIED(addr
)); /* "none" */
4362 /* 'for' loop 1a: */
4363 for (ucp
= fp
->u
.a
.f_mask
.s6_addr
;
4364 ucp
< fp
->u
.a
.f_mask
.s6_addr
+ sizeof (fp
->u
.a
.f_mask
.s6_addr
);
4368 fmasklen
+= 9 - ffs(*ucp
);
4369 break; /* 'for' loop 1a */
4372 } /* 'for' loop 1a ends */
4373 if (fmasklen
!= IPV6_ABITS
) {
4374 if (fmasklen
> masklen
)
4378 /* 'for' loop 1b: */
4379 for (app
= fp
->u
.a
.f_address
->h_addr_list
;
4380 (aptr
= (uint8_t *)*app
) != NULL
; app
++) {
4381 /* LINTED: (note 1) */
4382 if (IN6_IS_ADDR_V4MAPPED((in6_addr_t
*)aptr
))
4383 continue; /* 'for' loop 1b */
4384 ucp
= addr
->s6_addr
;
4385 for (i
= masklen
; i
>= 8; i
-= 8)
4386 if (*ucp
++ != *aptr
++)
4387 break; /* 'for' loop 1b */
4389 (i
< 8 && ((*ucp
^ *aptr
) & ~(0xff >> i
)) == 0))
4391 } /* 'for' loop 1b ends */
4396 * Run through the filter list for an IPv6 MIB2 IRE. For a given
4397 * type, if there's at least one filter and all filters of that type
4398 * fail to match, then the route doesn't match and isn't displayed.
4399 * If at least one matches, or none are specified, for each of the
4400 * types, then the route is selected and displayed.
4403 ire_filter_match_v6(const mib2_ipv6RouteEntry_t
*rp6
, uint_t flag_b
)
4409 for (idx
= 0; idx
< NFILTERKEYS
; idx
++)
4410 if ((fp
= filters
[idx
]) != NULL
) {
4412 for (; fp
!= NULL
; fp
= fp
->f_next
) {
4415 if (fp
->u
.f_family
!= AF_INET6
)
4420 if (!dev_name_match(&rp6
->
4421 ipv6RouteIfIndex
, fp
->u
.f_ifname
))
4426 if (!v6_addr_match(&rp6
->ipv6RouteDest
,
4427 rp6
->ipv6RoutePfxLength
, fp
))
4432 if ((flag_b
& fp
->u
.f
.f_flagset
) !=
4433 fp
->u
.f
.f_flagset
||
4434 (flag_b
& fp
->u
.f
.f_flagclear
))
4440 } /* 'for' loop 2 ends */
4444 /* 'for' loop 1 ends */
4449 * Given an IPv6 MIB2 route entry, form the list of flags for the
4453 form_v6_route_flags(const mib2_ipv6RouteEntry_t
*rp6
, char *flags
)
4458 (void) strcpy(flags
, "U");
4459 /* RTF_INDIRECT wins over RTF_GATEWAY - don't display both */
4460 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_INDIRECT
) {
4461 (void) strcat(flags
, "I");
4463 } else if (rp6
->ipv6RouteInfo
.re_ire_type
& IRE_OFFLINK
) {
4464 (void) strcat(flags
, "G");
4468 /* IRE_IF_CLONE wins over RTF_HOST - don't display both */
4469 if (rp6
->ipv6RouteInfo
.re_ire_type
& IRE_IF_CLONE
) {
4470 (void) strcat(flags
, "C");
4472 } else if (rp6
->ipv6RoutePfxLength
== IPV6_ABITS
) {
4473 (void) strcat(flags
, "H");
4477 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_DYNAMIC
) {
4478 (void) strcat(flags
, "D");
4481 if (rp6
->ipv6RouteInfo
.re_ire_type
== IRE_LOCAL
) { /* Local */
4482 (void) strcat(flags
, "L");
4485 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_SETSRC
) {
4486 (void) strcat(flags
, "S"); /* Setsrc */
4489 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_REJECT
) {
4490 (void) strcat(flags
, "R");
4493 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_BLACKHOLE
) {
4494 (void) strcat(flags
, "B");
4497 if (rp6
->ipv6RouteInfo
.re_flags
& RTF_ZONE
) {
4498 (void) strcat(flags
, "Z");
4504 static const char ire_hdr_v6
[] =
4505 "\n%s Table: IPv6\n";
4506 static const char ire_hdr_v6_verbose
[] =
4507 " Destination/Mask Gateway If MTU "
4508 "Ref Flags Out In/Fwd\n"
4509 "--------------------------- --------------------------- ----- ----- "
4510 "--- ----- ------ ------\n";
4511 static const char ire_hdr_v6_normal
[] =
4512 " Destination/Mask Gateway Flags Ref Use "
4514 "--------------------------- --------------------------- ----- --- ------- "
4518 ire_report_item_v6(const mib2_ipv6RouteEntry_t
*rp6
, boolean_t first
)
4520 char dstbuf
[MAXHOSTNAMELEN
+ 1];
4521 char gwbuf
[MAXHOSTNAMELEN
+ 1];
4522 char ifname
[LIFNAMSIZ
+ 1];
4523 char flags
[10]; /* RTF_ flags */
4526 if (!(Aflag
|| (rp6
->ipv6RouteInfo
.re_ire_type
!= IRE_IF_CLONE
&&
4527 rp6
->ipv6RouteInfo
.re_ire_type
!= IRE_MULTICAST
&&
4528 rp6
->ipv6RouteInfo
.re_ire_type
!= IRE_NOROUTE
&&
4529 rp6
->ipv6RouteInfo
.re_ire_type
!= IRE_LOCAL
))) {
4533 flag_b
= form_v6_route_flags(rp6
, flags
);
4535 if (!ire_filter_match_v6(rp6
, flag_b
))
4539 (void) printf(ire_hdr_v6
, Vflag
? "IRE" : "Routing");
4540 (void) printf(Vflag
? ire_hdr_v6_verbose
: ire_hdr_v6_normal
);
4545 (void) printf("%-27s %-27s %-5s %5u %3u "
4547 pr_prefix6(&rp6
->ipv6RouteDest
,
4548 rp6
->ipv6RoutePfxLength
, dstbuf
, sizeof (dstbuf
)),
4549 IN6_IS_ADDR_UNSPECIFIED(&rp6
->ipv6RouteNextHop
) ?
4551 pr_addr6(&rp6
->ipv6RouteNextHop
, gwbuf
, sizeof (gwbuf
)),
4552 octetstr(&rp6
->ipv6RouteIfIndex
, 'a',
4553 ifname
, sizeof (ifname
)),
4554 rp6
->ipv6RouteInfo
.re_max_frag
,
4555 rp6
->ipv6RouteInfo
.re_ref
,
4557 rp6
->ipv6RouteInfo
.re_obpkt
,
4558 rp6
->ipv6RouteInfo
.re_ibpkt
);
4560 (void) printf("%-27s %-27s %-5s %3u %7u %-5s\n",
4561 pr_prefix6(&rp6
->ipv6RouteDest
,
4562 rp6
->ipv6RoutePfxLength
, dstbuf
, sizeof (dstbuf
)),
4563 IN6_IS_ADDR_UNSPECIFIED(&rp6
->ipv6RouteNextHop
) ?
4565 pr_addr6(&rp6
->ipv6RouteNextHop
, gwbuf
, sizeof (gwbuf
)),
4567 rp6
->ipv6RouteInfo
.re_ref
,
4568 rp6
->ipv6RouteInfo
.re_obpkt
+ rp6
->ipv6RouteInfo
.re_ibpkt
,
4569 octetstr(&rp6
->ipv6RouteIfIndex
, 'a',
4570 ifname
, sizeof (ifname
)));
4575 /* ------------------------------ TCP_REPORT------------------------------- */
4577 static const char tcp_hdr_v4
[] =
4579 static const char tcp_hdr_v4_compat
[] =
4581 static const char tcp_hdr_v4_verbose
[] =
4582 "Local/Remote Address Swind Snext Suna Rwind Rnext Rack "
4584 "-------------------- ----- -------- -------- ----- -------- -------- "
4585 "----- ----- -----------\n";
4586 static const char tcp_hdr_v4_normal
[] =
4587 " Local Address Remote Address Swind Send-Q Rwind Recv-Q "
4589 "-------------------- -------------------- ----- ------ ----- ------ "
4592 static const char tcp_hdr_v6
[] =
4594 static const char tcp_hdr_v6_verbose
[] =
4595 "Local/Remote Address Swind Snext Suna Rwind Rnext "
4596 " Rack Rto Mss State If\n"
4597 "--------------------------------- ----- -------- -------- ----- -------- "
4598 "-------- ----- ----- ----------- -----\n";
4599 static const char tcp_hdr_v6_normal
[] =
4600 " Local Address Remote Address "
4601 "Swind Send-Q Rwind Recv-Q State If\n"
4602 "--------------------------------- --------------------------------- "
4603 "----- ------ ----- ------ ----------- -----\n";
4605 static boolean_t
tcp_report_item_v4(const mib2_tcpConnEntry_t
*,
4607 static boolean_t
tcp_report_item_v6(const mib2_tcp6ConnEntry_t
*,
4611 tcp_report(const mib_item_t
*item
)
4614 boolean_t print_hdr_once_v4
= B_TRUE
;
4615 boolean_t print_hdr_once_v6
= B_TRUE
;
4616 mib2_tcpConnEntry_t
*tp
;
4617 mib2_tcp6ConnEntry_t
*tp6
;
4619 if (!protocol_selected(IPPROTO_TCP
))
4622 for (; item
!= NULL
; item
= item
->next_item
) {
4624 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
4625 (void) printf("Group = %d, mib_id = %d, "
4626 "length = %d, valp = 0x%p\n",
4627 item
->group
, item
->mib_id
,
4628 item
->length
, item
->valp
);
4631 if (!((item
->group
== MIB2_TCP
&&
4632 item
->mib_id
== MIB2_TCP_CONN
) ||
4633 (item
->group
== MIB2_TCP6
&&
4634 item
->mib_id
== MIB2_TCP6_CONN
)))
4635 continue; /* 'for' loop 1 */
4637 if (item
->group
== MIB2_TCP
&& !family_selected(AF_INET
))
4638 continue; /* 'for' loop 1 */
4639 else if (item
->group
== MIB2_TCP6
&& !family_selected(AF_INET6
))
4640 continue; /* 'for' loop 1 */
4642 if (item
->group
== MIB2_TCP
) {
4643 for (tp
= (mib2_tcpConnEntry_t
*)item
->valp
;
4644 (char *)tp
< (char *)item
->valp
+ item
->length
;
4645 /* LINTED: (note 1) */
4646 tp
= (mib2_tcpConnEntry_t
*)((char *)tp
+
4647 tcpConnEntrySize
)) {
4648 print_hdr_once_v4
= tcp_report_item_v4(tp
,
4652 for (tp6
= (mib2_tcp6ConnEntry_t
*)item
->valp
;
4653 (char *)tp6
< (char *)item
->valp
+ item
->length
;
4654 /* LINTED: (note 1) */
4655 tp6
= (mib2_tcp6ConnEntry_t
*)((char *)tp6
+
4656 tcp6ConnEntrySize
)) {
4657 print_hdr_once_v6
= tcp_report_item_v6(tp6
,
4661 } /* 'for' loop 1 ends */
4662 (void) fflush(stdout
);
4667 tcp_report_item_v4(const mib2_tcpConnEntry_t
*tp
, boolean_t first
)
4670 * lname and fname below are for the hostname as well as the portname
4671 * There is no limit on portname length so we assume MAXHOSTNAMELEN
4674 char lname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
4675 char fname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
4677 if (!(Aflag
|| tp
->tcpConnEntryInfo
.ce_state
>= TCPS_ESTABLISHED
))
4678 return (first
); /* Nothing to print */
4681 (void) printf(v4compat
? tcp_hdr_v4_compat
: tcp_hdr_v4
);
4682 (void) printf(Vflag
? tcp_hdr_v4_verbose
: tcp_hdr_v4_normal
);
4686 (void) printf("%-20s\n%-20s %5u %08x %08x %5u %08x %08x "
4688 pr_ap(tp
->tcpConnLocalAddress
,
4689 tp
->tcpConnLocalPort
, "tcp", lname
, sizeof (lname
)),
4690 pr_ap(tp
->tcpConnRemAddress
,
4691 tp
->tcpConnRemPort
, "tcp", fname
, sizeof (fname
)),
4692 tp
->tcpConnEntryInfo
.ce_swnd
,
4693 tp
->tcpConnEntryInfo
.ce_snxt
,
4694 tp
->tcpConnEntryInfo
.ce_suna
,
4695 tp
->tcpConnEntryInfo
.ce_rwnd
,
4696 tp
->tcpConnEntryInfo
.ce_rnxt
,
4697 tp
->tcpConnEntryInfo
.ce_rack
,
4698 tp
->tcpConnEntryInfo
.ce_rto
,
4699 tp
->tcpConnEntryInfo
.ce_mss
,
4700 mitcp_state(tp
->tcpConnEntryInfo
.ce_state
));
4702 int sq
= (int)tp
->tcpConnEntryInfo
.ce_snxt
-
4703 (int)tp
->tcpConnEntryInfo
.ce_suna
- 1;
4704 int rq
= (int)tp
->tcpConnEntryInfo
.ce_rnxt
-
4705 (int)tp
->tcpConnEntryInfo
.ce_rack
;
4707 (void) printf("%-20s %-20s %5u %6d %5u %6d\n",
4708 pr_ap(tp
->tcpConnLocalAddress
,
4709 tp
->tcpConnLocalPort
, "tcp", lname
, sizeof (lname
)),
4710 pr_ap(tp
->tcpConnRemAddress
,
4711 tp
->tcpConnRemPort
, "tcp", fname
, sizeof (fname
)),
4712 tp
->tcpConnEntryInfo
.ce_swnd
,
4714 tp
->tcpConnEntryInfo
.ce_rwnd
,
4716 mitcp_state(tp
->tcpConnEntryInfo
.ce_state
));
4723 tcp_report_item_v6(const mib2_tcp6ConnEntry_t
*tp6
, boolean_t first
)
4726 * lname and fname below are for the hostname as well as the portname
4727 * There is no limit on portname length so we assume MAXHOSTNAMELEN
4730 char lname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
4731 char fname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
4732 char ifname
[LIFNAMSIZ
+ 1];
4735 if (!(Aflag
|| tp6
->tcp6ConnEntryInfo
.ce_state
>= TCPS_ESTABLISHED
))
4736 return (first
); /* Nothing to print */
4739 (void) printf(tcp_hdr_v6
);
4740 (void) printf(Vflag
? tcp_hdr_v6_verbose
: tcp_hdr_v6_normal
);
4743 ifnamep
= (tp6
->tcp6ConnIfIndex
!= 0) ?
4744 if_indextoname(tp6
->tcp6ConnIfIndex
, ifname
) : NULL
;
4745 if (ifnamep
== NULL
)
4749 (void) printf("%-33s\n%-33s %5u %08x %08x %5u %08x %08x "
4750 "%5u %5u %-11s %s\n",
4751 pr_ap6(&tp6
->tcp6ConnLocalAddress
,
4752 tp6
->tcp6ConnLocalPort
, "tcp", lname
, sizeof (lname
)),
4753 pr_ap6(&tp6
->tcp6ConnRemAddress
,
4754 tp6
->tcp6ConnRemPort
, "tcp", fname
, sizeof (fname
)),
4755 tp6
->tcp6ConnEntryInfo
.ce_swnd
,
4756 tp6
->tcp6ConnEntryInfo
.ce_snxt
,
4757 tp6
->tcp6ConnEntryInfo
.ce_suna
,
4758 tp6
->tcp6ConnEntryInfo
.ce_rwnd
,
4759 tp6
->tcp6ConnEntryInfo
.ce_rnxt
,
4760 tp6
->tcp6ConnEntryInfo
.ce_rack
,
4761 tp6
->tcp6ConnEntryInfo
.ce_rto
,
4762 tp6
->tcp6ConnEntryInfo
.ce_mss
,
4763 mitcp_state(tp6
->tcp6ConnEntryInfo
.ce_state
),
4766 int sq
= (int)tp6
->tcp6ConnEntryInfo
.ce_snxt
-
4767 (int)tp6
->tcp6ConnEntryInfo
.ce_suna
- 1;
4768 int rq
= (int)tp6
->tcp6ConnEntryInfo
.ce_rnxt
-
4769 (int)tp6
->tcp6ConnEntryInfo
.ce_rack
;
4771 (void) printf("%-33s %-33s %5u %6d %5u %6d %-11s %s\n",
4772 pr_ap6(&tp6
->tcp6ConnLocalAddress
,
4773 tp6
->tcp6ConnLocalPort
, "tcp", lname
, sizeof (lname
)),
4774 pr_ap6(&tp6
->tcp6ConnRemAddress
,
4775 tp6
->tcp6ConnRemPort
, "tcp", fname
, sizeof (fname
)),
4776 tp6
->tcp6ConnEntryInfo
.ce_swnd
,
4778 tp6
->tcp6ConnEntryInfo
.ce_rwnd
,
4780 mitcp_state(tp6
->tcp6ConnEntryInfo
.ce_state
),
4787 /* ------------------------------- UDP_REPORT------------------------------- */
4789 static boolean_t
udp_report_item_v4(const mib2_udpEntry_t
*ude
,
4791 static boolean_t
udp_report_item_v6(const mib2_udp6Entry_t
*ude6
,
4794 static const char udp_hdr_v4
[] =
4795 " Local Address Remote Address State\n"
4796 "-------------------- -------------------- ----------\n";
4798 static const char udp_hdr_v6
[] =
4799 " Local Address Remote Address "
4801 "--------------------------------- --------------------------------- "
4802 "---------- -----\n";
4805 udp_report(const mib_item_t
*item
)
4808 boolean_t print_hdr_once_v4
= B_TRUE
;
4809 boolean_t print_hdr_once_v6
= B_TRUE
;
4810 mib2_udpEntry_t
*ude
;
4811 mib2_udp6Entry_t
*ude6
;
4813 if (!protocol_selected(IPPROTO_UDP
))
4817 for (; item
; item
= item
->next_item
) {
4819 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
4820 (void) printf("Group = %d, mib_id = %d, "
4821 "length = %d, valp = 0x%p\n",
4822 item
->group
, item
->mib_id
,
4823 item
->length
, item
->valp
);
4825 if (!((item
->group
== MIB2_UDP
&&
4826 item
->mib_id
== MIB2_UDP_ENTRY
) ||
4827 (item
->group
== MIB2_UDP6
&&
4828 item
->mib_id
== MIB2_UDP6_ENTRY
)))
4829 continue; /* 'for' loop 1 */
4831 if (item
->group
== MIB2_UDP
&& !family_selected(AF_INET
))
4832 continue; /* 'for' loop 1 */
4833 else if (item
->group
== MIB2_UDP6
&& !family_selected(AF_INET6
))
4834 continue; /* 'for' loop 1 */
4836 /* xxx.xxx.xxx.xxx,pppp sss... */
4837 if (item
->group
== MIB2_UDP
) {
4838 for (ude
= (mib2_udpEntry_t
*)item
->valp
;
4839 (char *)ude
< (char *)item
->valp
+ item
->length
;
4840 /* LINTED: (note 1) */
4841 ude
= (mib2_udpEntry_t
*)((char *)ude
+
4843 print_hdr_once_v4
= udp_report_item_v4(ude
,
4847 for (ude6
= (mib2_udp6Entry_t
*)item
->valp
;
4848 (char *)ude6
< (char *)item
->valp
+ item
->length
;
4849 /* LINTED: (note 1) */
4850 ude6
= (mib2_udp6Entry_t
*)((char *)ude6
+
4852 print_hdr_once_v6
= udp_report_item_v6(ude6
,
4856 } /* 'for' loop 1 ends */
4857 (void) fflush(stdout
);
4861 udp_report_item_v4(const mib2_udpEntry_t
*ude
, boolean_t first
)
4863 char lname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
4864 /* hostname + portname */
4866 if (!(Aflag
|| ude
->udpEntryInfo
.ue_state
>= MIB2_UDP_connected
))
4867 return (first
); /* Nothing to print */
4870 (void) printf(v4compat
? "\nUDP\n" : "\nUDP: IPv4\n");
4871 (void) printf(udp_hdr_v4
);
4875 (void) printf("%-20s ",
4876 pr_ap(ude
->udpLocalAddress
, ude
->udpLocalPort
, "udp",
4877 lname
, sizeof (lname
)));
4878 (void) printf("%-20s %s\n",
4879 ude
->udpEntryInfo
.ue_state
== MIB2_UDP_connected
?
4880 pr_ap(ude
->udpEntryInfo
.ue_RemoteAddress
,
4881 ude
->udpEntryInfo
.ue_RemotePort
, "udp", lname
, sizeof (lname
)) :
4883 miudp_state(ude
->udpEntryInfo
.ue_state
));
4889 udp_report_item_v6(const mib2_udp6Entry_t
*ude6
, boolean_t first
)
4891 char lname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
4892 /* hostname + portname */
4893 char ifname
[LIFNAMSIZ
+ 1];
4894 const char *ifnamep
;
4896 if (!(Aflag
|| ude6
->udp6EntryInfo
.ue_state
>= MIB2_UDP_connected
))
4897 return (first
); /* Nothing to print */
4900 (void) printf("\nUDP: IPv6\n");
4901 (void) printf(udp_hdr_v6
);
4905 ifnamep
= (ude6
->udp6IfIndex
!= 0) ?
4906 if_indextoname(ude6
->udp6IfIndex
, ifname
) : NULL
;
4908 (void) printf("%-33s ",
4909 pr_ap6(&ude6
->udp6LocalAddress
,
4910 ude6
->udp6LocalPort
, "udp", lname
, sizeof (lname
)));
4911 (void) printf("%-33s %-10s %s\n",
4912 ude6
->udp6EntryInfo
.ue_state
== MIB2_UDP_connected
?
4913 pr_ap6(&ude6
->udp6EntryInfo
.ue_RemoteAddress
,
4914 ude6
->udp6EntryInfo
.ue_RemotePort
, "udp", lname
, sizeof (lname
)) :
4916 miudp_state(ude6
->udp6EntryInfo
.ue_state
),
4917 ifnamep
== NULL
? "" : ifnamep
);
4922 /* ------------------------------ SCTP_REPORT------------------------------- */
4924 static const char sctp_hdr
[] =
4926 static const char sctp_hdr_normal
[] =
4927 " Local Address Remote Address "
4928 "Swind Send-Q Rwind Recv-Q StrsI/O State\n"
4929 "------------------------------- ------------------------------- "
4930 "------ ------ ------ ------ ------- -----------";
4933 nssctp_state(int state
)
4935 static char sctpsbuf
[50];
4939 case MIB2_SCTP_closed
:
4942 case MIB2_SCTP_cookieWait
:
4945 case MIB2_SCTP_cookieEchoed
:
4946 cp
= "COOKIE_ECHOED";
4948 case MIB2_SCTP_established
:
4951 case MIB2_SCTP_shutdownPending
:
4952 cp
= "SHUTDOWN_PENDING";
4954 case MIB2_SCTP_shutdownSent
:
4955 cp
= "SHUTDOWN_SENT";
4957 case MIB2_SCTP_shutdownReceived
:
4958 cp
= "SHUTDOWN_RECEIVED";
4960 case MIB2_SCTP_shutdownAckSent
:
4961 cp
= "SHUTDOWN_ACK_SENT";
4963 case MIB2_SCTP_listen
:
4967 (void) snprintf(sctpsbuf
, sizeof (sctpsbuf
),
4968 "UNKNOWN STATE(%d)", state
);
4976 static const mib2_sctpConnRemoteEntry_t
*
4977 sctp_getnext_rem(const mib_item_t
**itemp
,
4978 const mib2_sctpConnRemoteEntry_t
*current
, uint32_t associd
)
4980 const mib_item_t
*item
= *itemp
;
4981 const mib2_sctpConnRemoteEntry_t
*sre
;
4983 for (; item
!= NULL
; item
= item
->next_item
, current
= NULL
) {
4984 if (!(item
->group
== MIB2_SCTP
&&
4985 item
->mib_id
== MIB2_SCTP_CONN_REMOTE
)) {
4989 if (current
!= NULL
) {
4990 /* LINTED: (note 1) */
4991 sre
= (const mib2_sctpConnRemoteEntry_t
*)
4992 ((const char *)current
+ sctpRemoteEntrySize
);
4996 for (; (char *)sre
< (char *)item
->valp
+ item
->length
;
4997 /* LINTED: (note 1) */
4998 sre
= (const mib2_sctpConnRemoteEntry_t
*)
4999 ((const char *)sre
+ sctpRemoteEntrySize
)) {
5000 if (sre
->sctpAssocId
!= associd
) {
5011 static const mib2_sctpConnLocalEntry_t
*
5012 sctp_getnext_local(const mib_item_t
**itemp
,
5013 const mib2_sctpConnLocalEntry_t
*current
, uint32_t associd
)
5015 const mib_item_t
*item
= *itemp
;
5016 const mib2_sctpConnLocalEntry_t
*sle
;
5018 for (; item
!= NULL
; item
= item
->next_item
, current
= NULL
) {
5019 if (!(item
->group
== MIB2_SCTP
&&
5020 item
->mib_id
== MIB2_SCTP_CONN_LOCAL
)) {
5024 if (current
!= NULL
) {
5025 /* LINTED: (note 1) */
5026 sle
= (const mib2_sctpConnLocalEntry_t
*)
5027 ((const char *)current
+ sctpLocalEntrySize
);
5031 for (; (char *)sle
< (char *)item
->valp
+ item
->length
;
5032 /* LINTED: (note 1) */
5033 sle
= (const mib2_sctpConnLocalEntry_t
*)
5034 ((const char *)sle
+ sctpLocalEntrySize
)) {
5035 if (sle
->sctpAssocId
!= associd
) {
5047 sctp_pr_addr(int type
, char *name
, int namelen
, const in6_addr_t
*addr
,
5054 * Address is either a v4 mapped or v6 addr. If
5055 * it's a v4 mapped, convert to v4 before
5059 case MIB2_SCTP_ADDR_V4
:
5063 IN6_V4MAPPED_TO_IPADDR(&v6addr
, v4addr
);
5065 (void) pr_ap(v4addr
, port
, "sctp", name
, namelen
);
5067 (void) pr_addr(v4addr
, name
, namelen
);
5071 case MIB2_SCTP_ADDR_V6
:
5074 (void) pr_ap6(addr
, port
, "sctp", name
, namelen
);
5076 (void) pr_addr6(addr
, name
, namelen
);
5081 (void) snprintf(name
, namelen
, "<unknown addr type>");
5087 sctp_conn_report_item(const mib_item_t
*head
, const mib2_sctpConnEntry_t
*sp
)
5089 char lname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
5090 char fname
[MAXHOSTNAMELEN
+ MAXHOSTNAMELEN
+ 1];
5091 const mib2_sctpConnRemoteEntry_t
*sre
= NULL
;
5092 const mib2_sctpConnLocalEntry_t
*sle
= NULL
;
5093 const mib_item_t
*local
= head
;
5094 const mib_item_t
*remote
= head
;
5095 uint32_t id
= sp
->sctpAssocId
;
5096 boolean_t printfirst
= B_TRUE
;
5098 sctp_pr_addr(sp
->sctpAssocRemPrimAddrType
, fname
, sizeof (fname
),
5099 &sp
->sctpAssocRemPrimAddr
, sp
->sctpAssocRemPort
);
5100 sctp_pr_addr(sp
->sctpAssocRemPrimAddrType
, lname
, sizeof (lname
),
5101 &sp
->sctpAssocLocPrimAddr
, sp
->sctpAssocLocalPort
);
5103 (void) printf("%-31s %-31s %6u %6d %6u %6d %3d/%-3d %s\n",
5105 sp
->sctpConnEntryInfo
.ce_swnd
,
5106 sp
->sctpConnEntryInfo
.ce_sendq
,
5107 sp
->sctpConnEntryInfo
.ce_rwnd
,
5108 sp
->sctpConnEntryInfo
.ce_recvq
,
5109 sp
->sctpAssocInStreams
, sp
->sctpAssocOutStreams
,
5110 nssctp_state(sp
->sctpAssocState
));
5116 /* Print remote addresses/local addresses on following lines */
5117 while ((sre
= sctp_getnext_rem(&remote
, sre
, id
)) != NULL
) {
5118 if (!IN6_ARE_ADDR_EQUAL(&sre
->sctpAssocRemAddr
,
5119 &sp
->sctpAssocRemPrimAddr
)) {
5120 if (printfirst
== B_TRUE
) {
5121 (void) fputs("\t<Remote: ", stdout
);
5122 printfirst
= B_FALSE
;
5124 (void) fputs(", ", stdout
);
5126 sctp_pr_addr(sre
->sctpAssocRemAddrType
, fname
,
5127 sizeof (fname
), &sre
->sctpAssocRemAddr
, -1);
5128 if (sre
->sctpAssocRemAddrActive
== MIB2_SCTP_ACTIVE
) {
5129 (void) fputs(fname
, stdout
);
5131 (void) printf("(%s)", fname
);
5135 if (printfirst
== B_FALSE
) {
5137 printfirst
= B_TRUE
;
5139 while ((sle
= sctp_getnext_local(&local
, sle
, id
)) != NULL
) {
5140 if (!IN6_ARE_ADDR_EQUAL(&sle
->sctpAssocLocalAddr
,
5141 &sp
->sctpAssocLocPrimAddr
)) {
5142 if (printfirst
== B_TRUE
) {
5143 (void) fputs("\t<Local: ", stdout
);
5144 printfirst
= B_FALSE
;
5146 (void) fputs(", ", stdout
);
5148 sctp_pr_addr(sle
->sctpAssocLocalAddrType
, lname
,
5149 sizeof (lname
), &sle
->sctpAssocLocalAddr
, -1);
5150 (void) fputs(lname
, stdout
);
5153 if (printfirst
== B_FALSE
) {
5159 sctp_report(const mib_item_t
*item
)
5161 const mib_item_t
*head
;
5162 const mib2_sctpConnEntry_t
*sp
;
5163 boolean_t first
= B_TRUE
;
5166 for (; item
!= NULL
; item
= item
->next_item
) {
5168 if (!(item
->group
== MIB2_SCTP
&&
5169 item
->mib_id
== MIB2_SCTP_CONN
))
5172 for (sp
= item
->valp
;
5173 (char *)sp
< (char *)item
->valp
+ item
->length
;
5174 /* LINTED: (note 1) */
5175 sp
= (mib2_sctpConnEntry_t
*)((char *)sp
+ sctpEntrySize
)) {
5177 sp
->sctpAssocState
>= MIB2_SCTP_established
) {
5178 if (first
== B_TRUE
) {
5179 (void) puts(sctp_hdr
);
5180 (void) puts(sctp_hdr_normal
);
5183 sctp_conn_report_item(head
, sp
);
5192 return (n
!= 1 ? "s" : "");
5198 return (n
!= 1 ? "ies" : "y");
5204 return (n
!= 1 ? "es" : "");
5215 } else if (n
< 1024 * 1024) {
5218 } else if (n
< 1024 * 1024 * 1024) {
5223 n
/= 1024 * 1024 * 1024;
5226 (void) snprintf(buf
, sizeof (buf
), "%4u%c", n
, t
);
5230 /* --------------------- mrt_report (netstat -m) -------------------------- */
5233 mrt_report(mib_item_t
*item
)
5238 struct mfcctl
*mfccp
;
5241 char abuf
[MAXHOSTNAMELEN
+ 4]; /* Include CIDR /<num>. */
5243 if (!(family_selected(AF_INET
)))
5247 for (; item
; item
= item
->next_item
) {
5249 (void) printf("\n--- Entry %d ---\n", ++jtemp
);
5250 (void) printf("Group = %d, mib_id = %d, "
5251 "length = %d, valp = 0x%p\n",
5252 item
->group
, item
->mib_id
, item
->length
,
5255 if (item
->group
!= EXPER_DVMRP
)
5256 continue; /* 'for' loop 1 */
5258 switch (item
->mib_id
) {
5260 case EXPER_DVMRP_VIF
:
5262 (void) printf("%u records for ipVifTable:\n",
5263 item
->length
/sizeof (struct vifctl
));
5264 if (item
->length
/sizeof (struct vifctl
) == 0) {
5265 (void) puts("\nVirtual Interface Table is "
5270 (void) puts("\nVirtual Interface Table\n"
5271 " Vif Threshold Rate_Limit Local-Address"
5272 " Remote-Address Pkt_in Pkt_out");
5275 for (vip
= (struct vifctl
*)item
->valp
;
5276 (char *)vip
< (char *)item
->valp
+ item
->length
;
5277 /* LINTED: (note 1) */
5278 vip
= (struct vifctl
*)((char *)vip
+
5280 if (vip
->vifc_lcl_addr
.s_addr
== 0)
5281 continue; /* 'for' loop 2 */
5282 /* numvifs = vip->vifc_vifi; */
5285 (void) printf(" %2u %3u "
5288 vip
->vifc_threshold
,
5289 vip
->vifc_rate_limit
,
5290 pr_addr(vip
->vifc_lcl_addr
.s_addr
,
5291 abuf
, sizeof (abuf
)));
5292 (void) printf(" %-15.15s %8u %8u\n",
5293 (vip
->vifc_flags
& VIFF_TUNNEL
) ?
5294 pr_addr(vip
->vifc_rmt_addr
.s_addr
,
5295 abuf
, sizeof (abuf
)) : "",
5298 } /* 'for' loop 2 ends */
5300 (void) printf("Numvifs: %d\n", numvifs
);
5303 case EXPER_DVMRP_MRT
:
5305 (void) printf("%u records for ipMfcTable:\n",
5306 item
->length
/sizeof (struct vifctl
));
5307 if (item
->length
/sizeof (struct vifctl
) == 0) {
5308 (void) puts("\nMulticast Forwarding Cache is "
5313 (void) puts("\nMulticast Forwarding Cache\n"
5314 " Origin-Subnet Mcastgroup "
5315 "# Pkts In-Vif Out-vifs/Forw-ttl");
5317 for (mfccp
= (struct mfcctl
*)item
->valp
;
5318 (char *)mfccp
< (char *)item
->valp
+ item
->length
;
5319 /* LINTED: (note 1) */
5320 mfccp
= (struct mfcctl
*)((char *)mfccp
+
5324 (void) printf(" %-30.15s",
5325 pr_addr(mfccp
->mfcc_origin
.s_addr
,
5326 abuf
, sizeof (abuf
)));
5327 (void) printf("%-15.15s %6s %3u ",
5328 pr_net(mfccp
->mfcc_mcastgrp
.s_addr
,
5329 mfccp
->mfcc_mcastgrp
.s_addr
,
5330 abuf
, sizeof (abuf
)),
5331 pktscale((int)mfccp
->mfcc_pkt_cnt
),
5332 mfccp
->mfcc_parent
);
5334 for (vifi
= 0; vifi
< MAXVIFS
; ++vifi
) {
5335 if (mfccp
->mfcc_ttls
[vifi
]) {
5336 (void) printf(" %u (%u)",
5338 mfccp
->mfcc_ttls
[vifi
]);
5342 (void) putchar('\n');
5344 (void) printf("\nTotal no. of entries in cache: %d\n",
5348 } /* 'for' loop 1 ends */
5349 (void) putchar('\n');
5350 (void) fflush(stdout
);
5354 * Get the stats for the cache named 'name'. If prefix != 0, then
5355 * interpret the name as a prefix, and sum up stats for all caches
5359 kmem_cache_stats(char *title
, char *name
, int prefix
, int64_t *total_bytes
)
5363 int64_t total_alloc
= 0;
5364 int alloc_fail
, total_alloc_fail
= 0;
5368 int buf_max
, total_buf_max
= 0;
5369 int buf_inuse
, total_buf_inuse
= 0;
5373 len
= prefix
? strlen(name
) : 256;
5376 for (ksp
= kc
->kc_chain
; ksp
!= NULL
; ksp
= ksp
->ks_next
) {
5378 if (strcmp(ksp
->ks_class
, "kmem_cache") != 0)
5379 continue; /* 'for' loop 1 */
5382 * Hack alert: because of the way streams messages are
5383 * allocated, every constructed free dblk has an associated
5384 * mblk. From the allocator's viewpoint those mblks are
5385 * allocated (because they haven't been freed), but from
5386 * our viewpoint they're actually free (because they're
5387 * not currently in use). To account for this caching
5388 * effect we subtract the total constructed free dblks
5389 * from the total allocated mblks to derive mblks in use.
5391 if (strcmp(name
, "streams_mblk") == 0 &&
5392 strncmp(ksp
->ks_name
, "streams_dblk", 12) == 0) {
5393 (void) safe_kstat_read(kc
, ksp
, NULL
);
5395 kstat_named_value(ksp
, "buf_constructed");
5396 continue; /* 'for' loop 1 */
5399 if (strncmp(ksp
->ks_name
, name
, len
) != 0)
5400 continue; /* 'for' loop 1 */
5402 (void) safe_kstat_read(kc
, ksp
, NULL
);
5404 alloc
= kstat_named_value(ksp
, "alloc");
5405 alloc_fail
= kstat_named_value(ksp
, "alloc_fail");
5406 buf_size
= kstat_named_value(ksp
, "buf_size");
5407 buf_avail
= kstat_named_value(ksp
, "buf_avail");
5408 buf_total
= kstat_named_value(ksp
, "buf_total");
5409 buf_max
= kstat_named_value(ksp
, "buf_max");
5410 buf_inuse
= buf_total
- buf_avail
;
5412 if (Vflag
&& prefix
) {
5413 (void) snprintf(buf
, sizeof (buf
), "%s%s", title
,
5414 ksp
->ks_name
+ len
);
5415 (void) printf(" %-18s %6u %9u %11u %11u\n",
5416 buf
, buf_inuse
, buf_max
, alloc
, alloc_fail
);
5419 total_alloc
+= alloc
;
5420 total_alloc_fail
+= alloc_fail
;
5421 total_buf_max
+= buf_max
;
5422 total_buf_inuse
+= buf_inuse
;
5423 *total_bytes
+= (int64_t)buf_inuse
* buf_size
;
5424 } /* 'for' loop 1 ends */
5426 if (buf_size
== 0) {
5427 (void) printf("%-22s [couldn't find statistics for %s]\n",
5432 if (Vflag
&& prefix
)
5433 (void) snprintf(buf
, sizeof (buf
), "%s_total", title
);
5435 (void) snprintf(buf
, sizeof (buf
), "%s", title
);
5437 (void) printf("%-22s %6d %9d %11lld %11d\n", buf
,
5438 total_buf_inuse
, total_buf_max
, total_alloc
, total_alloc_fail
);
5444 int64_t total_bytes
= 0;
5446 (void) puts("streams allocation:");
5447 (void) printf("%63s\n", "cumulative allocation");
5448 (void) printf("%63s\n",
5449 "current maximum total failures");
5451 kmem_cache_stats("streams",
5452 "stream_head_cache", 0, &total_bytes
);
5453 kmem_cache_stats("queues", "queue_cache", 0, &total_bytes
);
5454 kmem_cache_stats("mblk", "streams_mblk", 0, &total_bytes
);
5455 kmem_cache_stats("dblk", "streams_dblk", 1, &total_bytes
);
5456 kmem_cache_stats("linkblk", "linkinfo_cache", 0, &total_bytes
);
5457 kmem_cache_stats("syncq", "syncq_cache", 0, &total_bytes
);
5458 kmem_cache_stats("qband", "qband_cache", 0, &total_bytes
);
5460 (void) printf("\n%lld Kbytes allocated for streams data\n",
5461 total_bytes
/ 1024);
5463 (void) putchar('\n');
5464 (void) fflush(stdout
);
5467 /* --------------------------------- */
5470 * Print an IPv4 address. Remove the matching part of the domain name
5471 * from the returned name.
5474 pr_addr(uint_t addr
, char *dst
, uint_t dstlen
)
5477 struct hostent
*hp
= NULL
;
5478 static char domain
[MAXHOSTNAMELEN
+ 1];
5479 static boolean_t first
= B_TRUE
;
5484 if (sysinfo(SI_HOSTNAME
, domain
, MAXHOSTNAMELEN
) != -1 &&
5485 (cp
= strchr(domain
, '.'))) {
5486 (void) strncpy(domain
, cp
+ 1, sizeof (domain
));
5493 hp
= getipnodebyaddr((char *)&addr
, sizeof (uint_t
), AF_INET
,
5497 if ((cp
= strchr(hp
->h_name
, '.')) != NULL
&&
5498 strcasecmp(cp
+ 1, domain
) == 0)
5504 (void) strncpy(dst
, cp
, dstlen
);
5505 dst
[dstlen
- 1] = 0;
5507 (void) inet_ntop(AF_INET
, (char *)&addr
, dst
, dstlen
);
5515 * Print a non-zero IPv4 address. Print " --" if the address is zero.
5518 pr_addrnz(ipaddr_t addr
, char *dst
, uint_t dstlen
)
5520 if (addr
== INADDR_ANY
) {
5521 (void) strlcpy(dst
, " --", dstlen
);
5524 return (pr_addr(addr
, dst
, dstlen
));
5528 * Print an IPv6 address. Remove the matching part of the domain name
5529 * from the returned name.
5532 pr_addr6(const struct in6_addr
*addr
, char *dst
, uint_t dstlen
)
5535 struct hostent
*hp
= NULL
;
5536 static char domain
[MAXHOSTNAMELEN
+ 1];
5537 static boolean_t first
= B_TRUE
;
5542 if (sysinfo(SI_HOSTNAME
, domain
, MAXHOSTNAMELEN
) != -1 &&
5543 (cp
= strchr(domain
, '.'))) {
5544 (void) strncpy(domain
, cp
+ 1, sizeof (domain
));
5551 hp
= getipnodebyaddr((char *)addr
,
5552 sizeof (struct in6_addr
), AF_INET6
, &error_num
);
5555 if ((cp
= strchr(hp
->h_name
, '.')) != NULL
&&
5556 strcasecmp(cp
+ 1, domain
) == 0)
5562 (void) strncpy(dst
, cp
, dstlen
);
5563 dst
[dstlen
- 1] = 0;
5565 (void) inet_ntop(AF_INET6
, (void *)addr
, dst
, dstlen
);
5572 /* For IPv4 masks */
5574 pr_mask(uint_t addr
, char *dst
, uint_t dstlen
)
5576 uint8_t *ip_addr
= (uint8_t *)&addr
;
5578 (void) snprintf(dst
, dstlen
, "%d.%d.%d.%d",
5579 ip_addr
[0], ip_addr
[1], ip_addr
[2], ip_addr
[3]);
5584 * For ipv6 masks format is : dest/mask
5585 * Does not print /128 to save space in printout. H flag carries this notion.
5588 pr_prefix6(const struct in6_addr
*addr
, uint_t prefixlen
, char *dst
,
5593 if (IN6_IS_ADDR_UNSPECIFIED(addr
) && prefixlen
== 0) {
5594 (void) strncpy(dst
, "default", dstlen
);
5595 dst
[dstlen
- 1] = 0;
5599 (void) pr_addr6(addr
, dst
, dstlen
);
5600 if (prefixlen
!= IPV6_ABITS
) {
5601 /* How much room is left? */
5602 cp
= strchr(dst
, '\0');
5603 if (dst
+ dstlen
> cp
) {
5604 dstlen
-= (cp
- dst
);
5605 (void) snprintf(cp
, dstlen
, "/%d", prefixlen
);
5611 /* Print IPv4 address and port */
5613 pr_ap(uint_t addr
, uint_t port
, char *proto
,
5614 char *dst
, uint_t dstlen
)
5618 if (addr
== INADDR_ANY
) {
5619 (void) strncpy(dst
, " *", dstlen
);
5620 dst
[dstlen
- 1] = 0;
5622 (void) pr_addr(addr
, dst
, dstlen
);
5624 /* How much room is left? */
5625 cp
= strchr(dst
, '\0');
5626 if (dst
+ dstlen
> cp
+ 1) {
5628 dstlen
-= (cp
- dst
);
5630 (void) portname(port
, proto
, cp
, dstlen
);
5635 /* Print IPv6 address and port */
5637 pr_ap6(const in6_addr_t
*addr
, uint_t port
, char *proto
,
5638 char *dst
, uint_t dstlen
)
5642 if (IN6_IS_ADDR_UNSPECIFIED(addr
)) {
5643 (void) strncpy(dst
, " *", dstlen
);
5644 dst
[dstlen
- 1] = 0;
5646 (void) pr_addr6(addr
, dst
, dstlen
);
5648 /* How much room is left? */
5649 cp
= strchr(dst
, '\0');
5650 if (dst
+ dstlen
+ 1 > cp
) {
5652 dstlen
-= (cp
- dst
);
5654 (void) portname(port
, proto
, cp
, dstlen
);
5660 * Returns -2 to indicate a discontiguous mask. Otherwise returns between
5664 v4_cidr_len(uint_t mask
)
5669 for (i
= 0; i
< 32; i
++) {
5673 return (-2); /* Discontiguous IPv4 netmask. */
5682 append_v4_cidr_len(char *dst
, uint_t dstlen
, int prefixlen
)
5686 /* 4 bytes leaves room for '/' 'N' 'N' '\0' */
5687 if (strlen(dst
) <= dstlen
- 4) {
5688 prefixptr
= dst
+ strlen(dst
);
5691 * Cut off last 3 chars of very-long DNS name. All callers
5692 * should give us enough room, but name services COULD give us
5693 * a way-too-big name (see above).
5695 prefixptr
= dst
+ strlen(dst
) - 3;
5697 /* At this point "prefixptr" is guaranteed to point to 4 bytes. */
5699 if (prefixlen
>= 0) {
5700 if (prefixlen
> 32) /* Shouldn't happen, but... */
5702 (void) snprintf(prefixptr
, 4, "/%d", prefixlen
);
5703 } else if (prefixlen
== -2) {
5704 /* "/NM" == Noncontiguous Mask. */
5705 (void) strcat(prefixptr
, "/NM");
5707 /* Else print nothing extra. */
5711 * Return the name of the network whose address is given. The address is
5712 * assumed to be that of a net or subnet, not a host.
5715 pr_net(uint_t addr
, uint_t mask
, char *dst
, uint_t dstlen
)
5718 struct netent
*np
= NULL
;
5719 struct hostent
*hp
= NULL
;
5723 int prefixlen
= -1; /* -1 == Don't print prefix! */
5724 /* -2 == Noncontiguous mask... */
5726 if (addr
== INADDR_ANY
&& mask
== INADDR_ANY
) {
5727 (void) strlcpy(dst
, "default", dstlen
);
5732 prefixlen
= v4_cidr_len(ntohl(mask
));
5734 if (!Nflag
&& addr
) {
5736 if (IN_CLASSA(addr
)) {
5737 mask
= (uint_t
)IN_CLASSA_NET
;
5739 } else if (IN_CLASSB(addr
)) {
5740 mask
= (uint_t
)IN_CLASSB_NET
;
5743 mask
= (uint_t
)IN_CLASSC_NET
;
5747 * If there are more bits than the standard mask
5748 * would suggest, subnets must be in use. Guess at
5749 * the subnet mask, assuming reasonable width subnet
5752 while (addr
& ~mask
)
5753 /* compiler doesn't sign extend! */
5754 mask
= (mask
| ((int)mask
>> subnetshift
));
5756 prefixlen
= v4_cidr_len(mask
);
5759 while ((mask
& 1) == 0)
5760 mask
>>= 1, net
>>= 1;
5762 np
= getnetbyaddr(net
, AF_INET
);
5764 if (np
&& np
->n_net
== net
)
5768 * Look for subnets in hosts map.
5771 hp
= getipnodebyaddr((char *)&addr
, sizeof (uint_t
),
5772 AF_INET
, &error_num
);
5779 (void) strlcpy(dst
, cp
, dstlen
);
5781 (void) inet_ntop(AF_INET
, (char *)&addr
, dst
, dstlen
);
5784 append_v4_cidr_len(dst
, dstlen
, prefixlen
);
5792 * Return the name of the network whose address is given.
5793 * The address is assumed to be a host address.
5796 pr_netaddr(uint_t addr
, uint_t mask
, char *dst
, uint_t dstlen
)
5799 struct netent
*np
= NULL
;
5800 struct hostent
*hp
= NULL
;
5806 uint_t nbo_addr
= addr
; /* network byte order */
5807 int prefixlen
= -1; /* -1 == Don't print prefix! */
5808 /* -2 == Noncontiguous mask... */
5812 if (addr
== INADDR_ANY
&& mask
== INADDR_ANY
) {
5813 (void) strlcpy(dst
, "default", dstlen
);
5818 prefixlen
= v4_cidr_len(mask
);
5820 /* Figure out network portion of address (with host portion = 0) */
5822 /* Try figuring out mask if unknown (all 0s). */
5824 if (IN_CLASSA(addr
)) {
5825 mask
= (uint_t
)IN_CLASSA_NET
;
5827 } else if (IN_CLASSB(addr
)) {
5828 mask
= (uint_t
)IN_CLASSB_NET
;
5831 mask
= (uint_t
)IN_CLASSC_NET
;
5835 * If there are more bits than the standard mask
5836 * would suggest, subnets must be in use. Guess at
5837 * the subnet mask, assuming reasonable width subnet
5840 while (addr
& ~mask
)
5841 /* compiler doesn't sign extend! */
5842 mask
= (mask
| ((int)mask
>> subnetshift
));
5844 prefixlen
= v4_cidr_len(mask
);
5846 net
= netshifted
= addr
& mask
;
5847 while ((mask
& 1) == 0)
5848 mask
>>= 1, netshifted
>>= 1;
5851 net
= netshifted
= 0;
5853 /* Try looking up name unless -n was specified. */
5856 np
= getnetbyaddr(netshifted
, AF_INET
);
5858 if (np
&& np
->n_net
== netshifted
)
5862 * Look for subnets in hosts map.
5865 hp
= getipnodebyaddr((char *)&nbo_addr
, sizeof (uint_t
),
5866 AF_INET
, &error_num
);
5873 (void) strlcpy(dst
, cp
, dstlen
);
5874 append_v4_cidr_len(dst
, dstlen
, prefixlen
);
5880 * No name found for net: fallthru and return in decimal
5885 in
.s_addr
= htonl(net
);
5886 (void) inet_ntop(AF_INET
, (char *)&in
, dst
, dstlen
);
5887 append_v4_cidr_len(dst
, dstlen
, prefixlen
);
5894 * Return the filter mode as a string:
5897 * otherwise "<unknown>"
5900 fmodestr(uint_t fmode
)
5908 return ("<unknown>");
5912 #define MAX_STRING_SIZE 256
5915 * Pretty print a port number. If the Nflag was
5916 * specified, use numbers instead of names.
5919 portname(uint_t port
, char *proto
, char *dst
, uint_t dstlen
)
5921 struct servent
*sp
= NULL
;
5923 if (!Nflag
&& port
) {
5925 sp
= getservbyport(htons(port
), proto
);
5928 if (sp
|| port
== 0)
5929 (void) snprintf(dst
, dstlen
, "%.*s", MAXHOSTNAMELEN
,
5930 sp
? sp
->s_name
: "*");
5932 (void) snprintf(dst
, dstlen
, "%d", port
);
5933 dst
[dstlen
- 1] = 0;
5939 fail(int do_perror
, char *message
, ...)
5943 va_start(args
, message
);
5944 (void) fputs("netstat: ", stderr
);
5945 (void) vfprintf(stderr
, message
, args
);
5948 (void) fprintf(stderr
, ": %s", strerror(errno
));
5949 (void) fputc('\n', stderr
);
5954 * Return value of named statistic for given kstat_named kstat;
5955 * return 0LL if named statistic is not in list (use "ll" as a
5956 * type qualifier when printing 64-bit int's with printf() )
5959 kstat_named_value(kstat_t
*ksp
, char *name
)
5967 knp
= kstat_data_lookup(ksp
, name
);
5971 switch (knp
->data_type
) {
5972 case KSTAT_DATA_INT32
:
5973 case KSTAT_DATA_UINT32
:
5974 value
= (uint64_t)(knp
->value
.ui32
);
5976 case KSTAT_DATA_INT64
:
5977 case KSTAT_DATA_UINT64
:
5978 value
= knp
->value
.ui64
;
5989 safe_kstat_read(kstat_ctl_t
*kc
, kstat_t
*ksp
, void *data
)
5991 kid_t kstat_chain_id
= kstat_read(kc
, ksp
, data
);
5993 if (kstat_chain_id
== -1)
5994 fail(1, "kstat_read(%p, '%s') failed", (void *)kc
,
5996 return (kstat_chain_id
);
6000 * Parse a list of IRE flag characters into a bit field.
6003 flag_bits(const char *arg
)
6009 fatal(1, "missing flag list\n");
6012 while (*arg
!= '\0') {
6013 if ((cp
= strchr(flag_list
, *arg
)) == NULL
)
6014 fatal(1, "%c: illegal flag\n", *arg
);
6015 val
|= 1 << (cp
- flag_list
);
6022 * Handle -f argument. Validate input format, sort by keyword, and
6023 * save off digested results.
6026 process_filter(char *arg
)
6038 /* Look up the keyword first */
6039 if (strchr(arg
, ':') == NULL
) {
6042 for (idx
= 0; idx
< NFILTERKEYS
; idx
++) {
6043 klen
= strlen(filter_keys
[idx
]);
6044 if (strncmp(filter_keys
[idx
], arg
, klen
) == 0 &&
6048 if (idx
>= NFILTERKEYS
)
6049 fatal(1, "%s: unknown filter keyword\n", arg
);
6051 /* Advance past keyword and separator. */
6055 if ((newf
= malloc(sizeof (*newf
))) == NULL
) {
6061 if (strcmp(arg
, "inet") == 0) {
6062 newf
->u
.f_family
= AF_INET
;
6063 } else if (strcmp(arg
, "inet6") == 0) {
6064 newf
->u
.f_family
= AF_INET6
;
6065 } else if (strcmp(arg
, "unix") == 0) {
6066 newf
->u
.f_family
= AF_UNIX
;
6068 newf
->u
.f_family
= strtol(arg
, &cp
, 0);
6069 if (arg
== cp
|| *cp
!= '\0')
6070 fatal(1, "%s: unknown address family.\n", arg
);
6075 if (strcmp(arg
, "none") == 0) {
6076 newf
->u
.f_ifname
= NULL
;
6079 if (strcmp(arg
, "any") == 0) {
6080 newf
->u
.f_ifname
= "";
6083 val
= strtol(arg
, &cp
, 0);
6084 if (val
<= 0 || arg
== cp
|| cp
[0] != '\0') {
6085 if ((val
= if_nametoindex(arg
)) == 0) {
6090 newf
->u
.f_ifname
= arg
;
6094 V4MASK_TO_V6(IP_HOST_MASK
, newf
->u
.a
.f_mask
);
6095 if (strcmp(arg
, "any") == 0) {
6096 /* Special semantics; any address *but* zero */
6097 newf
->u
.a
.f_address
= NULL
;
6098 (void) memset(&newf
->u
.a
.f_mask
, 0,
6099 sizeof (newf
->u
.a
.f_mask
));
6102 if (strcmp(arg
, "none") == 0) {
6103 newf
->u
.a
.f_address
= NULL
;
6106 if ((cp
= strrchr(arg
, '/')) != NULL
)
6108 hp
= getipnodebyname(arg
, AF_INET6
, AI_V4MAPPED
|AI_ALL
,
6111 fatal(1, "%s: invalid or unknown host address\n", arg
);
6112 newf
->u
.a
.f_address
= hp
;
6114 V4MASK_TO_V6(IP_HOST_MASK
, newf
->u
.a
.f_mask
);
6116 val
= strtol(cp
, &cp2
, 0);
6117 if (cp
!= cp2
&& cp2
[0] == '\0') {
6119 * If decode as "/n" works, then translate
6122 if (hp
->h_addr_list
[0] != NULL
&&
6123 /* LINTED: (note 1) */
6124 IN6_IS_ADDR_V4MAPPED((in6_addr_t
*)
6125 hp
->h_addr_list
[0])) {
6130 if (val
< 0 || val
>= maxv
)
6131 fatal(1, "%d: not in range 0 to %d\n",
6133 if (maxv
== IP_ABITS
)
6134 val
+= IPV6_ABITS
- IP_ABITS
;
6135 ucp
= newf
->u
.a
.f_mask
.s6_addr
;
6137 *ucp
++ = 0xff, val
-= 8;
6138 *ucp
++ = (0xff << (8 - val
)) & 0xff;
6139 while (ucp
< newf
->u
.a
.f_mask
.s6_addr
+
6140 sizeof (newf
->u
.a
.f_mask
.s6_addr
))
6142 /* Otherwise, try as numeric address */
6143 } else if (inet_pton(AF_INET6
,
6144 cp
, &newf
->u
.a
.f_mask
) <= 0) {
6145 fatal(1, "%s: illegal mask format\n", cp
);
6152 newf
->u
.f
.f_flagset
= flag_bits(arg
+ 1);
6153 newf
->u
.f
.f_flagclear
= 0;
6154 } else if (*arg
== '-') {
6155 newf
->u
.f
.f_flagset
= 0;
6156 newf
->u
.f
.f_flagclear
= flag_bits(arg
+ 1);
6158 newf
->u
.f
.f_flagset
= flag_bits(arg
);
6159 newf
->u
.f
.f_flagclear
= ~newf
->u
.f
.f_flagset
;
6166 newf
->f_next
= filters
[idx
];
6167 filters
[idx
] = newf
;
6170 /* Determine if user wants this address family printed. */
6172 family_selected(int family
)
6176 if (v4compat
&& family
== AF_INET6
)
6178 if ((fp
= filters
[FK_AF
]) == NULL
)
6180 while (fp
!= NULL
) {
6181 if (fp
->u
.f_family
== family
)
6189 * Convert the interface index to a string using the buffer `ifname', which
6190 * must be at least LIFNAMSIZ bytes. We first try to map it to name. If that
6191 * fails (e.g., because we're inside a zone and it does not have access to
6192 * interface for the index in question), just return "if#<num>".
6195 ifindex2str(uint_t ifindex
, char *ifname
)
6197 if (if_indextoname(ifindex
, ifname
) == NULL
)
6198 (void) snprintf(ifname
, LIFNAMSIZ
, "if#%d", ifindex
);
6204 * print the usage line
6207 usage(char *cmdname
)
6209 (void) fprintf(stderr
, "usage: %s [-anv] [-f address_family] "
6210 "[-T d|u]\n", cmdname
);
6211 (void) fprintf(stderr
, " %s [-n] [-f address_family] "
6212 "[-P protocol] [-T d|u] [-g | -p | -s [interval [count]]]\n",
6214 (void) fprintf(stderr
, " %s -m [-v] [-T d|u] "
6215 "[interval [count]]\n", cmdname
);
6216 (void) fprintf(stderr
, " %s -i [-I interface] [-an] "
6217 "[-f address_family] [-T d|u] [interval [count]]\n", cmdname
);
6218 (void) fprintf(stderr
, " %s -r [-anv] "
6219 "[-f address_family|filter] [-T d|u]\n", cmdname
);
6220 (void) fprintf(stderr
, " %s -M [-ns] [-f address_family] "
6221 "[-T d|u]\n", cmdname
);
6222 (void) fprintf(stderr
, " %s -D [-I interface] "
6223 "[-f address_family] [-T d|u]\n", cmdname
);
6228 * fatal: print error message to stderr and
6229 * call exit(errcode)
6233 fatal(int errcode
, char *format
, ...)
6240 va_start(argp
, format
);
6241 (void) vfprintf(stderr
, format
, argp
);