| /* |
| * CDDL HEADER START |
| * |
| * The contents of this file are subject to the terms of the |
| * Common Development and Distribution License (the "License"). |
| * You may not use this file except in compliance with the License. |
| * |
| * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
| * or http://www.opensolaris.org/os/licensing. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * |
| * When distributing Covered Code, include this CDDL HEADER in each |
| * file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
| * If applicable, add the following below this CDDL HEADER, with the |
| * fields enclosed by brackets "[]" replaced with your own identifying |
| * information: Portions Copyright [yyyy] [name of copyright owner] |
| * |
| * CDDL HEADER END |
| */ |
| /* |
| * Copyright 2006 Sun Microsystems, Inc. All rights reserved. |
| * Use is subject to license terms. |
| */ |
| |
| /* |
| * Copyright (c) 1990 Mentat Inc. |
| * netstat.c 2.2, last change 9/9/91 |
| * MROUTING Revision 3.5 |
| */ |
| |
| #pragma ident "%Z%%M% %I% %E% SMI" |
| |
| /* |
| * simple netstat based on snmp/mib-2 interface to the TCP/IP stack |
| * |
| * NOTES: |
| * 1. A comment "LINTED: (note 1)" appears before certain lines where |
| * lint would have complained, "pointer cast may result in improper |
| * alignment". These are lines where lint had suspected potential |
| * improper alignment of a data structure; in each such situation |
| * we have relied on the kernel guaranteeing proper alignment. |
| * 2. Some 'for' loops have been commented as "'for' loop 1", etc |
| * because they have 'continue' or 'break' statements in their |
| * bodies. 'continue' statements have been used inside some loops |
| * where avoiding them would have led to deep levels of indentation. |
| * |
| * TODO: |
| * Add ability to request subsets from kernel (with level = MIB2_IP; |
| * name = 0 meaning everything for compatibility) |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <stdarg.h> |
| #include <unistd.h> |
| #include <strings.h> |
| #include <string.h> |
| #include <errno.h> |
| #include <ctype.h> |
| #include <kstat.h> |
| #include <assert.h> |
| |
| #include <sys/types.h> |
| #include <sys/stream.h> |
| #include <stropts.h> |
| #include <sys/strstat.h> |
| #include <sys/tihdr.h> |
| |
| #include <sys/socket.h> |
| #include <sys/sockio.h> |
| #include <netinet/in.h> |
| #include <net/if.h> |
| #include <net/route.h> |
| |
| #include <inet/common.h> |
| #include <inet/mib2.h> |
| #include <inet/ip.h> |
| #include <inet/arp.h> |
| #include <inet/tcp.h> |
| #include <netinet/igmp_var.h> |
| #include <netinet/ip_mroute.h> |
| |
| #include <arpa/inet.h> |
| #include <netdb.h> |
| #include <fcntl.h> |
| #include <sys/systeminfo.h> |
| #include <arpa/inet.h> |
| |
| #include <netinet/dhcp.h> |
| #include <dhcpagent_ipc.h> |
| #include <dhcpagent_util.h> |
| #include <compat.h> |
| |
| #include <libtsnet.h> |
| #include <tsol/label.h> |
| |
| extern void unixpr(kstat_ctl_t *kc); |
| |
| #define STR_EXPAND 4 |
| |
| #define V4MASK_TO_V6(v4, v6) ((v6)._S6_un._S6_u32[0] = 0xfffffffful, \ |
| (v6)._S6_un._S6_u32[1] = 0xfffffffful, \ |
| (v6)._S6_un._S6_u32[2] = 0xfffffffful, \ |
| (v6)._S6_un._S6_u32[3] = (v4)) |
| |
| #define IN6_IS_V4MASK(v6) ((v6)._S6_un._S6_u32[0] == 0xfffffffful && \ |
| (v6)._S6_un._S6_u32[1] == 0xfffffffful && \ |
| (v6)._S6_un._S6_u32[2] == 0xfffffffful) |
| |
| typedef struct mib_item_s { |
| struct mib_item_s *next_item; |
| int group; |
| int mib_id; |
| int length; |
| void *valp; |
| } mib_item_t; |
| |
| struct ifstat { |
| uint64_t ipackets; |
| uint64_t ierrors; |
| uint64_t opackets; |
| uint64_t oerrors; |
| uint64_t collisions; |
| }; |
| |
| struct iflist { |
| struct iflist *next_if; |
| char ifname[LIFNAMSIZ]; |
| struct ifstat tot; |
| }; |
| |
| static mib_item_t *mibget(int sd); |
| static void mibfree(mib_item_t *firstitem); |
| static int mibopen(void); |
| static void mib_get_constants(mib_item_t *item); |
| static mib_item_t *mib_item_dup(mib_item_t *item); |
| static mib_item_t *mib_item_diff(mib_item_t *item1, |
| mib_item_t *item2); |
| static void mib_item_destroy(mib_item_t **item); |
| |
| static boolean_t octetstrmatch(const Octet_t *a, const Octet_t *b); |
| static char *octetstr(const Octet_t *op, int code, |
| char *dst, uint_t dstlen); |
| static char *pr_addr(uint_t addr, |
| char *dst, uint_t dstlen); |
| static char *pr_addrnz(ipaddr_t addr, char *dst, uint_t dstlen); |
| static char *pr_addr6(const in6_addr_t *addr, |
| char *dst, uint_t dstlen); |
| static char *pr_mask(uint_t addr, |
| char *dst, uint_t dstlen); |
| static char *pr_prefix6(const struct in6_addr *addr, |
| uint_t prefixlen, char *dst, uint_t dstlen); |
| static char *pr_ap(uint_t addr, uint_t port, |
| char *proto, char *dst, uint_t dstlen); |
| static char *pr_ap6(const in6_addr_t *addr, uint_t port, |
| char *proto, char *dst, uint_t dstlen); |
| static char *pr_net(uint_t addr, uint_t mask, |
| char *dst, uint_t dstlen); |
| static char *pr_netaddr(uint_t addr, uint_t mask, |
| char *dst, uint_t dstlen); |
| static char *pr_netclassless(ipaddr_t addr, ipaddr_t mask, |
| char *dst, size_t dstlen); |
| static char *fmodestr(uint_t fmode); |
| static char *portname(uint_t port, char *proto, |
| char *dst, uint_t dstlen); |
| |
| static const char *mitcp_state(int code, |
| const mib2_transportMLPEntry_t *attr); |
| static const char *miudp_state(int code, |
| const mib2_transportMLPEntry_t *attr); |
| |
| static void stat_report(mib_item_t *item); |
| static void mrt_stat_report(mib_item_t *item); |
| static void arp_report(mib_item_t *item); |
| static void ndp_report(mib_item_t *item); |
| static void mrt_report(mib_item_t *item); |
| static void if_stat_total(struct ifstat *oldstats, |
| struct ifstat *newstats, struct ifstat *sumstats); |
| static void if_report(mib_item_t *item, char *ifname, |
| int Iflag_only, boolean_t once_only); |
| static void if_report_ip4(mib2_ipAddrEntry_t *ap, |
| char ifname[], char logintname[], |
| struct ifstat *statptr, boolean_t ksp_not_null); |
| static void if_report_ip6(mib2_ipv6AddrEntry_t *ap6, |
| char ifname[], char logintname[], |
| struct ifstat *statptr, boolean_t ksp_not_null); |
| static void ire_report(const mib_item_t *item); |
| static void tcp_report(const mib_item_t *item); |
| static void udp_report(const mib_item_t *item); |
| static void group_report(mib_item_t *item); |
| static void print_ip_stats(mib2_ip_t *ip); |
| static void print_icmp_stats(mib2_icmp_t *icmp); |
| static void print_ip6_stats(mib2_ipv6IfStatsEntry_t *ip6); |
| static void print_icmp6_stats(mib2_ipv6IfIcmpEntry_t *icmp6); |
| static void print_sctp_stats(mib2_sctp_t *tcp); |
| static void print_tcp_stats(mib2_tcp_t *tcp); |
| static void print_udp_stats(mib2_udp_t *udp); |
| static void print_rawip_stats(mib2_rawip_t *rawip); |
| static void print_igmp_stats(struct igmpstat *igps); |
| static void print_mrt_stats(struct mrtstat *mrts); |
| static void sctp_report(const mib_item_t *item); |
| static void sum_ip6_stats(mib2_ipv6IfStatsEntry_t *ip6, |
| mib2_ipv6IfStatsEntry_t *sum6); |
| static void sum_icmp6_stats(mib2_ipv6IfIcmpEntry_t *icmp6, |
| mib2_ipv6IfIcmpEntry_t *sum6); |
| static void m_report(void); |
| static void dhcp_report(char *); |
| |
| void fail(int, char *, ...); |
| static uint64_t kstat_named_value(kstat_t *, char *); |
| static kid_t safe_kstat_read(kstat_ctl_t *, kstat_t *, void *); |
| static int isnum(char *); |
| static char *plural(int n); |
| static char *pluraly(int n); |
| static char *plurales(int n); |
| static void process_filter(char *arg); |
| static boolean_t family_selected(int family); |
| |
| static void usage(char *); |
| static void fatal(int errcode, char *str1, ...); |
| |
| #define PLURAL(n) plural((int)n) |
| #define PLURALY(n) pluraly((int)n) |
| #define PLURALES(n) plurales((int)n) |
| #define IFLAGMOD(flg, val1, val2) if (flg == val1) flg = val2 |
| #define MDIFF(diff, elem2, elem1, member) (diff)->member = \ |
| (elem2)->member - (elem1)->member |
| |
| |
| static boolean_t Aflag = B_FALSE; /* All sockets/ifs/rtng-tbls */ |
| static boolean_t Dflag = B_FALSE; /* Debug Info */ |
| static boolean_t Iflag = B_FALSE; /* IP Traffic Interfaces */ |
| static boolean_t Mflag = B_FALSE; /* STREAMS Memory Statistics */ |
| static boolean_t Nflag = B_FALSE; /* Numeric Network Addresses */ |
| static boolean_t Rflag = B_FALSE; /* Routing Tables */ |
| static boolean_t RSECflag = B_FALSE; /* Security attributes */ |
| static boolean_t Sflag = B_FALSE; /* Per-protocol Statistics */ |
| static boolean_t Vflag = B_FALSE; /* Verbose */ |
| static boolean_t Pflag = B_FALSE; /* Net to Media Tables */ |
| static boolean_t Gflag = B_FALSE; /* Multicast group membership */ |
| static boolean_t MMflag = B_FALSE; /* Multicast routing table */ |
| static boolean_t DHCPflag = B_FALSE; /* DHCP statistics */ |
| |
| static int v4compat = 0; /* Compatible printing format for status */ |
| |
| static int proto = IPPROTO_MAX; /* all protocols */ |
| kstat_ctl_t *kc = NULL; |
| |
| /* |
| * Sizes of data structures extracted from the base mib. |
| * This allows the size of the tables entries to grow while preserving |
| * binary compatibility. |
| */ |
| static int ipAddrEntrySize; |
| static int ipRouteEntrySize; |
| static int ipNetToMediaEntrySize; |
| static int ipMemberEntrySize; |
| static int ipGroupSourceEntrySize; |
| static int ipRouteAttributeSize; |
| static int vifctlSize; |
| static int mfcctlSize; |
| |
| static int ipv6IfStatsEntrySize; |
| static int ipv6IfIcmpEntrySize; |
| static int ipv6AddrEntrySize; |
| static int ipv6RouteEntrySize; |
| static int ipv6NetToMediaEntrySize; |
| static int ipv6MemberEntrySize; |
| static int ipv6GroupSourceEntrySize; |
| |
| static int transportMLPSize; |
| static int tcpConnEntrySize; |
| static int tcp6ConnEntrySize; |
| static int udpEntrySize; |
| static int udp6EntrySize; |
| static int sctpEntrySize; |
| static int sctpLocalEntrySize; |
| static int sctpRemoteEntrySize; |
| |
| #define protocol_selected(p) (proto == IPPROTO_MAX || proto == (p)) |
| |
| /* Machinery used for -f (filter) option */ |
| #define FK_AF 0 |
| #define FK_INIF 1 |
| #define FK_OUTIF 2 |
| #define FK_SRC 3 |
| #define FK_DST 4 |
| #define FK_FLAGS 5 |
| #define NFILTERKEYS 6 |
| |
| static const char *filter_keys[NFILTERKEYS] = { |
| "af", "inif", "outif", "src", "dst", "flags" |
| }; |
| |
| /* Flags on routes */ |
| #define FLF_A 0x00000001 |
| #define FLF_B 0x00000002 |
| #define FLF_D 0x00000004 |
| #define FLF_G 0x00000008 |
| #define FLF_H 0x00000010 |
| #define FLF_L 0x00000020 |
| #define FLF_U 0x00000040 |
| #define FLF_M 0x00000080 |
| #define FLF_S 0x00000100 |
| static const char flag_list[] = "ABDGHLUMS"; |
| |
| typedef struct filter_rule filter_t; |
| |
| struct filter_rule { |
| filter_t *f_next; |
| union { |
| int f_family; |
| const char *f_ifname; |
| struct { |
| struct hostent *f_address; |
| in6_addr_t f_mask; |
| } a; |
| struct { |
| uint_t f_flagset; |
| uint_t f_flagclear; |
| } f; |
| } u; |
| }; |
| |
| /* |
| * The user-specified filters are linked into lists separated by |
| * keyword (type of filter). Thus, the matching algorithm is: |
| * For each non-empty filter list |
| * If no filters in the list match |
| * then stop here; route doesn't match |
| * If loop above completes, then route does match and will be |
| * displayed. |
| */ |
| static filter_t *filters[NFILTERKEYS]; |
| |
| int |
| main(int argc, char **argv) |
| { |
| char *name; |
| mib_item_t *item = NULL; |
| mib_item_t *previtem = NULL; |
| int sd = -1; |
| char *ifname = NULL; |
| int interval = 0; /* Single time by default */ |
| int count = -1; /* Forever */ |
| int c; |
| int d; |
| /* |
| * Possible values of 'Iflag_only': |
| * -1, no feature-flags; |
| * 0, IFlag and other feature-flags enabled |
| * 1, IFlag is the only feature-flag enabled |
| * : trinary variable, modified using IFLAGMOD() |
| */ |
| int Iflag_only = -1; |
| boolean_t once_only = B_FALSE; /* '-i' with count > 1 */ |
| extern char *optarg; |
| extern int optind; |
| char *default_ip_str = NULL; |
| |
| name = argv[0]; |
| |
| v4compat = get_compat_flag(&default_ip_str); |
| if (v4compat == DEFAULT_PROT_BAD_VALUE) |
| fatal(2, "%s: %s: Bad value for %s in %s\n", name, |
| default_ip_str, DEFAULT_IP, INET_DEFAULT_FILE); |
| free(default_ip_str); |
| |
| while ((c = getopt(argc, argv, "adimnrspMgvf:P:I:DR")) != -1) { |
| switch ((char)c) { |
| case 'a': /* all connections */ |
| Aflag = B_TRUE; |
| break; |
| |
| case 'd': /* turn on debugging */ |
| Dflag = B_TRUE; |
| break; |
| |
| case 'i': /* interface (ill/ipif report) */ |
| Iflag = B_TRUE; |
| IFLAGMOD(Iflag_only, -1, 1); /* '-i' exists */ |
| break; |
| |
| case 'm': /* streams msg report */ |
| Mflag = B_TRUE; |
| IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */ |
| break; |
| |
| case 'n': /* numeric format */ |
| Nflag = B_TRUE; |
| break; |
| |
| case 'r': /* route tables */ |
| Rflag = B_TRUE; |
| IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */ |
| break; |
| |
| case 'R': /* security attributes */ |
| RSECflag = B_TRUE; |
| IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */ |
| break; |
| |
| case 's': /* per-protocol statistics */ |
| Sflag = B_TRUE; |
| IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */ |
| break; |
| |
| case 'p': /* arp/ndp table */ |
| Pflag = B_TRUE; |
| IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */ |
| break; |
| |
| case 'M': /* multicast routing tables */ |
| MMflag = B_TRUE; |
| IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */ |
| break; |
| |
| case 'g': /* multicast group membership */ |
| Gflag = B_TRUE; |
| IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */ |
| break; |
| |
| case 'v': /* verbose output format */ |
| Vflag = B_TRUE; |
| IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */ |
| break; |
| |
| case 'f': |
| process_filter(optarg); |
| break; |
| |
| case 'P': |
| if (strcmp(optarg, "ip") == 0) { |
| proto = IPPROTO_IP; |
| } else if (strcmp(optarg, "ipv6") == 0 || |
| strcmp(optarg, "ip6") == 0) { |
| v4compat = 0; /* Overridden */ |
| proto = IPPROTO_IPV6; |
| } else if (strcmp(optarg, "icmp") == 0) { |
| proto = IPPROTO_ICMP; |
| } else if (strcmp(optarg, "icmpv6") == 0 || |
| strcmp(optarg, "icmp6") == 0) { |
| v4compat = 0; /* Overridden */ |
| proto = IPPROTO_ICMPV6; |
| } else if (strcmp(optarg, "igmp") == 0) { |
| proto = IPPROTO_IGMP; |
| } else if (strcmp(optarg, "udp") == 0) { |
| proto = IPPROTO_UDP; |
| } else if (strcmp(optarg, "tcp") == 0) { |
| proto = IPPROTO_TCP; |
| } else if (strcmp(optarg, "sctp") == 0) { |
| proto = IPPROTO_SCTP; |
| } else if (strcmp(optarg, "raw") == 0 || |
| strcmp(optarg, "rawip") == 0) { |
| proto = IPPROTO_RAW; |
| } else { |
| fatal(1, "%s: unknown protocol.\n", optarg); |
| } |
| break; |
| |
| case 'I': |
| ifname = optarg; |
| Iflag = B_TRUE; |
| IFLAGMOD(Iflag_only, -1, 1); /* see macro def'n */ |
| break; |
| |
| case 'D': |
| DHCPflag = B_TRUE; |
| Iflag_only = 0; |
| break; |
| |
| case '?': |
| default: |
| usage(name); |
| } |
| } |
| |
| /* |
| * Make sure -R option is set only on a labeled system. |
| */ |
| if (RSECflag && !is_system_labeled()) { |
| (void) fprintf(stderr, "-R set but labeling is not enabled\n"); |
| usage(name); |
| } |
| |
| /* |
| * Handle other arguments: find interval, count; the |
| * flags that accept 'interval' and 'count' are OR'd |
| * in the outermost 'if'; more flags may be added as |
| * required |
| */ |
| if (Iflag || Sflag || Mflag) { |
| for (d = optind; d < argc; d++) { |
| if (isnum(argv[d])) { |
| interval = atoi(argv[d]); |
| if (d + 1 < argc && |
| isnum(argv[d + 1])) { |
| count = atoi(argv[d + 1]); |
| optind++; |
| } |
| optind++; |
| if (interval == 0 || count == 0) |
| usage(name); |
| break; |
| } |
| } |
| } |
| if (optind < argc) { |
| if (Iflag && isnum(argv[optind])) { |
| count = atoi(argv[optind]); |
| if (count == 0) |
| usage(name); |
| optind++; |
| } |
| } |
| if (optind < argc) { |
| (void) fprintf(stderr, |
| "%s: extra arguments\n", name); |
| usage(name); |
| } |
| if (interval) |
| setbuf(stdout, NULL); |
| |
| if (DHCPflag) { |
| dhcp_report(Iflag ? ifname : NULL); |
| exit(0); |
| } |
| |
| /* Get data structures: priming before iteration */ |
| if (family_selected(AF_INET) || family_selected(AF_INET6)) { |
| sd = mibopen(); |
| if (sd == -1) |
| fatal(1, "can't open mib stream\n"); |
| if ((item = mibget(sd)) == NULL) { |
| (void) close(sd); |
| fatal(1, "mibget() failed\n"); |
| } |
| /* Extract constant sizes - need do once only */ |
| mib_get_constants(item); |
| } |
| if ((kc = kstat_open()) == NULL) { |
| mibfree(item); |
| (void) close(sd); |
| fail(1, "kstat_open(): can't open /dev/kstat"); |
| } |
| |
| if (interval <= 0) { |
| count = 1; |
| once_only = B_TRUE; |
| } |
| /* 'for' loop 1: */ |
| for (;;) { |
| mib_item_t *curritem = NULL; /* only for -[M]s */ |
| |
| /* netstat: AF_INET[6] behaviour */ |
| if (family_selected(AF_INET) || family_selected(AF_INET6)) { |
| if (Sflag) { |
| curritem = mib_item_diff(previtem, item); |
| if (curritem == NULL) |
| fatal(1, "can't process mib data, " |
| "out of memory\n"); |
| mib_item_destroy(&previtem); |
| } |
| |
| if (!(Iflag || Rflag || Sflag || Mflag || |
| MMflag || Pflag || Gflag || DHCPflag)) { |
| if (protocol_selected(IPPROTO_UDP)) |
| udp_report(item); |
| if (protocol_selected(IPPROTO_TCP)) |
| tcp_report(item); |
| if (protocol_selected(IPPROTO_SCTP)) |
| sctp_report(item); |
| } |
| if (Iflag) |
| if_report(item, ifname, Iflag_only, once_only); |
| if (Mflag) |
| m_report(); |
| if (Rflag) |
| ire_report(item); |
| if (Sflag && MMflag) { |
| mrt_stat_report(curritem); |
| } else { |
| if (Sflag) |
| stat_report(curritem); |
| if (MMflag) |
| mrt_report(item); |
| } |
| if (Gflag) |
| group_report(item); |
| if (Pflag) { |
| if (family_selected(AF_INET)) |
| arp_report(item); |
| if (family_selected(AF_INET6)) |
| ndp_report(item); |
| } |
| mib_item_destroy(&curritem); |
| } |
| |
| /* netstat: AF_UNIX behaviour */ |
| if (family_selected(AF_UNIX) && |
| (!(Iflag || Rflag || Sflag || Mflag || |
| MMflag || Pflag || Gflag))) |
| unixpr(kc); |
| (void) kstat_close(kc); |
| |
| /* iteration handling code */ |
| if (count > 0 && --count == 0) |
| break; |
| (void) sleep(interval); |
| |
| /* re-populating of data structures */ |
| if (family_selected(AF_INET) || family_selected(AF_INET6)) { |
| if (Sflag) { |
| /* previtem is a cut-down list */ |
| previtem = mib_item_dup(item); |
| if (previtem == NULL) |
| fatal(1, "can't process mib data, " |
| "out of memory\n"); |
| } |
| mibfree(item); |
| (void) close(sd); |
| if ((sd = mibopen()) == -1) |
| fatal(1, "can't open mib stream anymore\n"); |
| if ((item = mibget(sd)) == NULL) { |
| (void) close(sd); |
| fatal(1, "mibget() failed\n"); |
| } |
| } |
| if ((kc = kstat_open()) == NULL) |
| fail(1, "kstat_open(): can't open /dev/kstat"); |
| |
| } /* 'for' loop 1 ends */ |
| mibfree(item); |
| (void) close(sd); |
| |
| return (0); |
| } |
| |
| |
| static int |
| isnum(char *p) |
| { |
| int len; |
| int i; |
| |
| len = strlen(p); |
| for (i = 0; i < len; i++) |
| if (!isdigit(p[i])) |
| return (0); |
| return (1); |
| } |
| |
| |
| /* --------------------------------- MIBGET -------------------------------- */ |
| |
| static mib_item_t * |
| mibget(int sd) |
| { |
| /* |
| * buf is an automatic for this function, so the |
| * compiler has complete control over its alignment; |
| * it is assumed this alignment is satisfactory for |
| * it to be casted to certain other struct pointers |
| * here, such as struct T_optmgmt_ack * . |
| */ |
| uintptr_t buf[512 / sizeof (uintptr_t)]; |
| int flags; |
| int i, j, getcode; |
| struct strbuf ctlbuf, databuf; |
| struct T_optmgmt_req *tor = (struct T_optmgmt_req *)buf; |
| struct T_optmgmt_ack *toa = (struct T_optmgmt_ack *)buf; |
| struct T_error_ack *tea = (struct T_error_ack *)buf; |
| struct opthdr *req; |
| mib_item_t *first_item = NULL; |
| mib_item_t *last_item = NULL; |
| mib_item_t *temp; |
| |
| tor->PRIM_type = T_SVR4_OPTMGMT_REQ; |
| tor->OPT_offset = sizeof (struct T_optmgmt_req); |
| tor->OPT_length = sizeof (struct opthdr); |
| tor->MGMT_flags = T_CURRENT; |
| req = (struct opthdr *)&tor[1]; |
| req->level = MIB2_IP; /* any MIB2_xxx value ok here */ |
| req->name = 0; |
| req->len = 0; |
| |
| ctlbuf.buf = (char *)buf; |
| ctlbuf.len = tor->OPT_length + tor->OPT_offset; |
| flags = 0; |
| if (putmsg(sd, &ctlbuf, (struct strbuf *)0, flags) == -1) { |
| perror("mibget: putmsg(ctl) failed"); |
| goto error_exit; |
| } |
| |
| /* |
| * Each reply consists of a ctl part for one fixed structure |
| * or table, as defined in mib2.h. The format is a T_OPTMGMT_ACK, |
| * containing an opthdr structure. level/name identify the entry, |
| * len is the size of the data part of the message. |
| */ |
| req = (struct opthdr *)&toa[1]; |
| ctlbuf.maxlen = sizeof (buf); |
| j = 1; |
| for (;;) { |
| flags = 0; |
| getcode = getmsg(sd, &ctlbuf, (struct strbuf *)0, &flags); |
| if (getcode == -1) { |
| perror("mibget getmsg(ctl) failed"); |
| if (Dflag) { |
| (void) fputs("# level name len\n", |
| stderr); |
| i = 0; |
| for (last_item = first_item; last_item; |
| last_item = last_item->next_item) |
| (void) printf("%d %4d %5d %d\n", |
| ++i, |
| last_item->group, |
| last_item->mib_id, |
| last_item->length); |
| } |
| goto error_exit; |
| } |
| if (getcode == 0 && |
| ctlbuf.len >= sizeof (struct T_optmgmt_ack) && |
| toa->PRIM_type == T_OPTMGMT_ACK && |
| toa->MGMT_flags == T_SUCCESS && |
| req->len == 0) { |
| if (Dflag) |
| (void) printf("mibget getmsg() %d returned " |
| "EOD (level %ld, name %ld)\n", |
| j, req->level, req->name); |
| return (first_item); /* this is EOD msg */ |
| } |
| |
| if (ctlbuf.len >= sizeof (struct T_error_ack) && |
| tea->PRIM_type == T_ERROR_ACK) { |
| (void) fprintf(stderr, |
| "mibget %d gives T_ERROR_ACK: TLI_error = 0x%lx, " |
| "UNIX_error = 0x%lx\n", |
| j, tea->TLI_error, tea->UNIX_error); |
| |
| errno = (tea->TLI_error == TSYSERR) ? |
| tea->UNIX_error : EPROTO; |
| goto error_exit; |
| } |
| |
| if (getcode != MOREDATA || |
| ctlbuf.len < sizeof (struct T_optmgmt_ack) || |
| toa->PRIM_type != T_OPTMGMT_ACK || |
| toa->MGMT_flags != T_SUCCESS) { |
| (void) printf("mibget getmsg(ctl) %d returned %d, " |
| "ctlbuf.len = %d, PRIM_type = %ld\n", |
| j, getcode, ctlbuf.len, toa->PRIM_type); |
| |
| if (toa->PRIM_type == T_OPTMGMT_ACK) |
| (void) printf("T_OPTMGMT_ACK: " |
| "MGMT_flags = 0x%lx, req->len = %ld\n", |
| toa->MGMT_flags, req->len); |
| errno = ENOMSG; |
| goto error_exit; |
| } |
| |
| temp = (mib_item_t *)malloc(sizeof (mib_item_t)); |
| if (temp == NULL) { |
| perror("mibget malloc failed"); |
| goto error_exit; |
| } |
| if (last_item != NULL) |
| last_item->next_item = temp; |
| else |
| first_item = temp; |
| last_item = temp; |
| last_item->next_item = NULL; |
| last_item->group = req->level; |
| last_item->mib_id = req->name; |
| last_item->length = req->len; |
| last_item->valp = malloc((int)req->len); |
| if (last_item->valp == NULL) |
| goto error_exit; |
| if (Dflag) |
| (void) printf("msg %d: group = %4d mib_id = %5d" |
| "length = %d\n", |
| j, last_item->group, last_item->mib_id, |
| last_item->length); |
| |
| databuf.maxlen = last_item->length; |
| databuf.buf = (char *)last_item->valp; |
| databuf.len = 0; |
| flags = 0; |
| getcode = getmsg(sd, (struct strbuf *)0, &databuf, &flags); |
| if (getcode == -1) { |
| perror("mibget getmsg(data) failed"); |
| goto error_exit; |
| } else if (getcode != 0) { |
| (void) printf("mibget getmsg(data) returned %d, " |
| "databuf.maxlen = %d, databuf.len = %d\n", |
| getcode, databuf.maxlen, databuf.len); |
| goto error_exit; |
| } |
| j++; |
| } |
| /* NOTREACHED */ |
| |
| error_exit:; |
| mibfree(first_item); |
| return (NULL); |
| } |
| |
| /* |
| * mibfree: frees a linked list of type (mib_item_t *) |
| * returned by mibget(); this is NOT THE SAME AS |
| * mib_item_destroy(), so should be used for objects |
| * returned by mibget() only |
| */ |
| static void |
| mibfree(mib_item_t *firstitem) |
| { |
| mib_item_t *lastitem; |
| |
| while (firstitem != NULL) { |
| lastitem = firstitem; |
| firstitem = firstitem->next_item; |
| if (lastitem->valp != NULL) |
| free(lastitem->valp); |
| free(lastitem); |
| } |
| } |
| |
| static int |
| mibopen(void) |
| { |
| int sd; |
| |
| sd = open("/dev/arp", O_RDWR); |
| if (sd == -1) { |
| perror("arp open"); |
| return (-1); |
| } |
| if (ioctl(sd, I_PUSH, "tcp") == -1) { |
| perror("tcp I_PUSH"); |
| (void) close(sd); |
| return (-1); |
| } |
| if (ioctl(sd, I_PUSH, "udp") == -1) { |
| perror("udp I_PUSH"); |
| (void) close(sd); |
| return (-1); |
| } |
| if (ioctl(sd, I_PUSH, "icmp") == -1) { |
| perror("icmp I_PUSH"); |
| (void) close(sd); |
| return (-1); |
| } |
| return (sd); |
| } |
| |
| /* |
| * mib_item_dup: returns a clean mib_item_t * linked |
| * list, so that for every element item->mib_id is 0; |
| * to deallocate this linked list, use mib_item_destroy |
| */ |
| static mib_item_t * |
| mib_item_dup(mib_item_t *item) |
| { |
| int c = 0; |
| mib_item_t *localp; |
| mib_item_t *tempp; |
| |
| for (tempp = item; tempp; tempp = tempp->next_item) |
| if (tempp->mib_id == 0) |
| c++; |
| tempp = NULL; |
| |
| localp = (mib_item_t *)malloc(c * sizeof (mib_item_t)); |
| if (localp == NULL) |
| return (NULL); |
| c = 0; |
| for (; item; item = item->next_item) { |
| if (item->mib_id == 0) { |
| /* Replicate item in localp */ |
| (localp[c]).next_item = NULL; |
| (localp[c]).group = item->group; |
| (localp[c]).mib_id = item->mib_id; |
| (localp[c]).length = item->length; |
| (localp[c]).valp = (uintptr_t *)malloc( |
| item->length); |
| if ((localp[c]).valp == NULL) { |
| mib_item_destroy(&localp); |
| return (NULL); |
| } |
| (void *) memcpy((localp[c]).valp, |
| item->valp, |
| item->length); |
| tempp = &(localp[c]); |
| if (c > 0) |
| (localp[c - 1]).next_item = tempp; |
| c++; |
| } |
| } |
| return (localp); |
| } |
| |
| /* |
| * mib_item_diff: takes two (mib_item_t *) linked lists |
| * item1 and item2 and computes the difference between |
| * differentiable values in item2 against item1 for every |
| * given member of item2; returns an mib_item_t * linked |
| * list of diff's, or a copy of item2 if item1 is NULL; |
| * will return NULL if system out of memory; works only |
| * for item->mib_id == 0 |
| */ |
| static mib_item_t * |
| mib_item_diff(mib_item_t *item1, mib_item_t *item2) { |
| int nitems = 0; /* no. of items in item2 */ |
| mib_item_t *tempp2; /* walking copy of item2 */ |
| mib_item_t *tempp1; /* walking copy of item1 */ |
| mib_item_t *diffp; |
| mib_item_t *diffptr; /* walking copy of diffp */ |
| mib_item_t *prevp = NULL; |
| |
| if (item1 == NULL) { |
| diffp = mib_item_dup(item2); |
| return (diffp); |
| } |
| |
| for (tempp2 = item2; |
| tempp2; |
| tempp2 = tempp2->next_item) { |
| if (tempp2->mib_id == 0) |
| switch (tempp2->group) { |
| /* |
| * upon adding a case here, the same |
| * must also be added in the next |
| * switch statement, alongwith |
| * appropriate code |
| */ |
| case MIB2_IP: |
| case MIB2_IP6: |
| case EXPER_DVMRP: |
| case EXPER_IGMP: |
| case MIB2_ICMP: |
| case MIB2_ICMP6: |
| case MIB2_TCP: |
| case MIB2_UDP: |
| case MIB2_SCTP: |
| case EXPER_RAWIP: |
| nitems++; |
| } |
| } |
| tempp2 = NULL; |
| if (nitems == 0) { |
| diffp = mib_item_dup(item2); |
| return (diffp); |
| } |
| |
| diffp = (mib_item_t *)calloc(nitems, sizeof (mib_item_t)); |
| if (diffp == NULL) |
| return (NULL); |
| diffptr = diffp; |
| /* 'for' loop 1: */ |
| for (tempp2 = item2; tempp2 != NULL; tempp2 = tempp2->next_item) { |
| if (tempp2->mib_id != 0) |
| continue; /* 'for' loop 1 */ |
| /* 'for' loop 2: */ |
| for (tempp1 = item1; tempp1 != NULL; |
| tempp1 = tempp1->next_item) { |
| if (!(tempp1->mib_id == 0 && |
| tempp1->group == tempp2->group && |
| tempp1->mib_id == tempp2->mib_id)) |
| continue; /* 'for' loop 2 */ |
| /* found comparable data sets */ |
| if (prevp != NULL) |
| prevp->next_item = diffptr; |
| switch (tempp2->group) { |
| /* |
| * Indenting note: Because of long variable names |
| * in cases MIB2_IP6 and MIB2_ICMP6, their contents |
| * have been indented by one tab space only |
| */ |
| case MIB2_IP: { |
| mib2_ip_t *i2 = (mib2_ip_t *)tempp2->valp; |
| mib2_ip_t *i1 = (mib2_ip_t *)tempp1->valp; |
| mib2_ip_t *d; |
| |
| diffptr->group = tempp2->group; |
| diffptr->mib_id = tempp2->mib_id; |
| diffptr->length = tempp2->length; |
| d = (mib2_ip_t *)calloc(tempp2->length, 1); |
| if (d == NULL) |
| goto mibdiff_out_of_memory; |
| diffptr->valp = d; |
| d->ipForwarding = i2->ipForwarding; |
| d->ipDefaultTTL = i2->ipDefaultTTL; |
| MDIFF(d, i2, i1, ipInReceives); |
| MDIFF(d, i2, i1, ipInHdrErrors); |
| MDIFF(d, i2, i1, ipInAddrErrors); |
| MDIFF(d, i2, i1, ipInCksumErrs); |
| MDIFF(d, i2, i1, ipForwDatagrams); |
| MDIFF(d, i2, i1, ipForwProhibits); |
| MDIFF(d, i2, i1, ipInUnknownProtos); |
| MDIFF(d, i2, i1, ipInDiscards); |
| MDIFF(d, i2, i1, ipInDelivers); |
| MDIFF(d, i2, i1, ipOutRequests); |
| MDIFF(d, i2, i1, ipOutDiscards); |
| MDIFF(d, i2, i1, ipOutNoRoutes); |
| MDIFF(d, i2, i1, ipReasmTimeout); |
| MDIFF(d, i2, i1, ipReasmReqds); |
| MDIFF(d, i2, i1, ipReasmOKs); |
| MDIFF(d, i2, i1, ipReasmFails); |
| MDIFF(d, i2, i1, ipReasmDuplicates); |
| MDIFF(d, i2, i1, ipReasmPartDups); |
| MDIFF(d, i2, i1, ipFragOKs); |
| MDIFF(d, i2, i1, ipFragFails); |
| MDIFF(d, i2, i1, ipFragCreates); |
| MDIFF(d, i2, i1, ipRoutingDiscards); |
| MDIFF(d, i2, i1, tcpInErrs); |
| MDIFF(d, i2, i1, udpNoPorts); |
| MDIFF(d, i2, i1, udpInCksumErrs); |
| MDIFF(d, i2, i1, udpInOverflows); |
| MDIFF(d, i2, i1, rawipInOverflows); |
| MDIFF(d, i2, i1, ipsecInSucceeded); |
| MDIFF(d, i2, i1, ipsecInFailed); |
| MDIFF(d, i2, i1, ipInIPv6); |
| MDIFF(d, i2, i1, ipOutIPv6); |
| MDIFF(d, i2, i1, ipOutSwitchIPv6); |
| prevp = diffptr++; |
| break; |
| } |
| case MIB2_IP6: { |
| mib2_ipv6IfStatsEntry_t *i2; |
| mib2_ipv6IfStatsEntry_t *i1; |
| mib2_ipv6IfStatsEntry_t *d; |
| |
| i2 = (mib2_ipv6IfStatsEntry_t *)tempp2->valp; |
| i1 = (mib2_ipv6IfStatsEntry_t *)tempp1->valp; |
| diffptr->group = tempp2->group; |
| diffptr->mib_id = tempp2->mib_id; |
| diffptr->length = tempp2->length; |
| d = (mib2_ipv6IfStatsEntry_t *)calloc( |
| tempp2->length, 1); |
| if (d == NULL) |
| goto mibdiff_out_of_memory; |
| diffptr->valp = d; |
| d->ipv6Forwarding = i2->ipv6Forwarding; |
| d->ipv6DefaultHopLimit = |
| i2->ipv6DefaultHopLimit; |
| |
| MDIFF(d, i2, i1, ipv6InReceives); |
| MDIFF(d, i2, i1, ipv6InHdrErrors); |
| MDIFF(d, i2, i1, ipv6InTooBigErrors); |
| MDIFF(d, i2, i1, ipv6InNoRoutes); |
| MDIFF(d, i2, i1, ipv6InAddrErrors); |
| MDIFF(d, i2, i1, ipv6InUnknownProtos); |
| MDIFF(d, i2, i1, ipv6InTruncatedPkts); |
| MDIFF(d, i2, i1, ipv6InDiscards); |
| MDIFF(d, i2, i1, ipv6InDelivers); |
| MDIFF(d, i2, i1, ipv6OutForwDatagrams); |
| MDIFF(d, i2, i1, ipv6OutRequests); |
| MDIFF(d, i2, i1, ipv6OutDiscards); |
| MDIFF(d, i2, i1, ipv6OutNoRoutes); |
| MDIFF(d, i2, i1, ipv6OutFragOKs); |
| MDIFF(d, i2, i1, ipv6OutFragFails); |
| MDIFF(d, i2, i1, ipv6OutFragCreates); |
| MDIFF(d, i2, i1, ipv6ReasmReqds); |
| MDIFF(d, i2, i1, ipv6ReasmOKs); |
| MDIFF(d, i2, i1, ipv6ReasmFails); |
| MDIFF(d, i2, i1, ipv6InMcastPkts); |
| MDIFF(d, i2, i1, ipv6OutMcastPkts); |
| MDIFF(d, i2, i1, ipv6ReasmDuplicates); |
| MDIFF(d, i2, i1, ipv6ReasmPartDups); |
| MDIFF(d, i2, i1, ipv6ForwProhibits); |
| MDIFF(d, i2, i1, udpInCksumErrs); |
| MDIFF(d, i2, i1, udpInOverflows); |
| MDIFF(d, i2, i1, rawipInOverflows); |
| MDIFF(d, i2, i1, ipv6InIPv4); |
| MDIFF(d, i2, i1, ipv6OutIPv4); |
| MDIFF(d, i2, i1, ipv6OutSwitchIPv4); |
| prevp = diffptr++; |
| break; |
| } |
| case EXPER_DVMRP: { |
| struct mrtstat *m2; |
| struct mrtstat *m1; |
| struct mrtstat *d; |
| |
| m2 = (struct mrtstat *)tempp2->valp; |
| m1 = (struct mrtstat *)tempp1->valp; |
| diffptr->group = tempp2->group; |
| diffptr->mib_id = tempp2->mib_id; |
| diffptr->length = tempp2->length; |
| d = (struct mrtstat *)calloc(tempp2->length, 1); |
| if (d == NULL) |
| goto mibdiff_out_of_memory; |
| diffptr->valp = d; |
| MDIFF(d, m2, m1, mrts_mfc_hits); |
| MDIFF(d, m2, m1, mrts_mfc_misses); |
| MDIFF(d, m2, m1, mrts_fwd_in); |
| MDIFF(d, m2, m1, mrts_fwd_out); |
| d->mrts_upcalls = m2->mrts_upcalls; |
| MDIFF(d, m2, m1, mrts_fwd_drop); |
| MDIFF(d, m2, m1, mrts_bad_tunnel); |
| MDIFF(d, m2, m1, mrts_cant_tunnel); |
| MDIFF(d, m2, m1, mrts_wrong_if); |
| MDIFF(d, m2, m1, mrts_upq_ovflw); |
| MDIFF(d, m2, m1, mrts_cache_cleanups); |
| MDIFF(d, m2, m1, mrts_drop_sel); |
| MDIFF(d, m2, m1, mrts_q_overflow); |
| MDIFF(d, m2, m1, mrts_pkt2large); |
| MDIFF(d, m2, m1, mrts_pim_badversion); |
| MDIFF(d, m2, m1, mrts_pim_rcv_badcsum); |
| MDIFF(d, m2, m1, mrts_pim_badregisters); |
| MDIFF(d, m2, m1, mrts_pim_regforwards); |
| MDIFF(d, m2, m1, mrts_pim_regsend_drops); |
| MDIFF(d, m2, m1, mrts_pim_malformed); |
| MDIFF(d, m2, m1, mrts_pim_nomemory); |
| prevp = diffptr++; |
| break; |
| } |
| case EXPER_IGMP: { |
| struct igmpstat *i2; |
| struct igmpstat *i1; |
| struct igmpstat *d; |
| |
| i2 = (struct igmpstat *)tempp2->valp; |
| i1 = (struct igmpstat *)tempp1->valp; |
| diffptr->group = tempp2->group; |
| diffptr->mib_id = tempp2->mib_id; |
| diffptr->length = tempp2->length; |
| d = (struct igmpstat *)calloc( |
| tempp2->length, 1); |
| if (d == NULL) |
| goto mibdiff_out_of_memory; |
| diffptr->valp = d; |
| MDIFF(d, i2, i1, igps_rcv_total); |
| MDIFF(d, i2, i1, igps_rcv_tooshort); |
| MDIFF(d, i2, i1, igps_rcv_badsum); |
| MDIFF(d, i2, i1, igps_rcv_queries); |
| MDIFF(d, i2, i1, igps_rcv_badqueries); |
| MDIFF(d, i2, i1, igps_rcv_reports); |
| MDIFF(d, i2, i1, igps_rcv_badreports); |
| MDIFF(d, i2, i1, igps_rcv_ourreports); |
| MDIFF(d, i2, i1, igps_snd_reports); |
| prevp = diffptr++; |
| break; |
| } |
| case MIB2_ICMP: { |
| mib2_icmp_t *i2; |
| mib2_icmp_t *i1; |
| mib2_icmp_t *d; |
| |
| i2 = (mib2_icmp_t *)tempp2->valp; |
| i1 = (mib2_icmp_t *)tempp1->valp; |
| diffptr->group = tempp2->group; |
| diffptr->mib_id = tempp2->mib_id; |
| diffptr->length = tempp2->length; |
| d = (mib2_icmp_t *)calloc(tempp2->length, 1); |
| if (d == NULL) |
| goto mibdiff_out_of_memory; |
| diffptr->valp = d; |
| MDIFF(d, i2, i1, icmpInMsgs); |
| MDIFF(d, i2, i1, icmpInErrors); |
| MDIFF(d, i2, i1, icmpInCksumErrs); |
| MDIFF(d, i2, i1, icmpInUnknowns); |
| MDIFF(d, i2, i1, icmpInDestUnreachs); |
| MDIFF(d, i2, i1, icmpInTimeExcds); |
| MDIFF(d, i2, i1, icmpInParmProbs); |
| MDIFF(d, i2, i1, icmpInSrcQuenchs); |
| MDIFF(d, i2, i1, icmpInRedirects); |
| MDIFF(d, i2, i1, icmpInBadRedirects); |
| MDIFF(d, i2, i1, icmpInEchos); |
| MDIFF(d, i2, i1, icmpInEchoReps); |
| MDIFF(d, i2, i1, icmpInTimestamps); |
| MDIFF(d, i2, i1, icmpInAddrMasks); |
| MDIFF(d, i2, i1, icmpInAddrMaskReps); |
| MDIFF(d, i2, i1, icmpInFragNeeded); |
| MDIFF(d, i2, i1, icmpOutMsgs); |
| MDIFF(d, i2, i1, icmpOutDrops); |
| MDIFF(d, i2, i1, icmpOutErrors); |
| MDIFF(d, i2, i1, icmpOutDestUnreachs); |
| MDIFF(d, i2, i1, icmpOutTimeExcds); |
| MDIFF(d, i2, i1, icmpOutParmProbs); |
| MDIFF(d, i2, i1, icmpOutSrcQuenchs); |
| MDIFF(d, i2, i1, icmpOutRedirects); |
| MDIFF(d, i2, i1, icmpOutEchos); |
| MDIFF(d, i2, i1, icmpOutEchoReps); |
| MDIFF(d, i2, i1, icmpOutTimestamps); |
| MDIFF(d, i2, i1, icmpOutTimestampReps); |
| MDIFF(d, i2, i1, icmpOutAddrMasks); |
| MDIFF(d, i2, i1, icmpOutAddrMaskReps); |
| MDIFF(d, i2, i1, icmpOutFragNeeded); |
| MDIFF(d, i2, i1, icmpInOverflows); |
| prevp = diffptr++; |
| break; |
| } |
| case MIB2_ICMP6: { |
| mib2_ipv6IfIcmpEntry_t *i2; |
| mib2_ipv6IfIcmpEntry_t *i1; |
| mib2_ipv6IfIcmpEntry_t *d; |
| |
| i2 = (mib2_ipv6IfIcmpEntry_t *)tempp2->valp; |
| i1 = (mib2_ipv6IfIcmpEntry_t *)tempp1->valp; |
| diffptr->group = tempp2->group; |
| diffptr->mib_id = tempp2->mib_id; |
| diffptr->length = tempp2->length; |
| d = (mib2_ipv6IfIcmpEntry_t *)calloc(tempp2->length, 1); |
| if (d == NULL) |
| goto mibdiff_out_of_memory; |
| diffptr->valp = d; |
| MDIFF(d, i2, i1, ipv6IfIcmpInMsgs); |
| MDIFF(d, i2, i1, ipv6IfIcmpInErrors); |
| MDIFF(d, i2, i1, ipv6IfIcmpInDestUnreachs); |
| MDIFF(d, i2, i1, ipv6IfIcmpInAdminProhibs); |
| MDIFF(d, i2, i1, ipv6IfIcmpInTimeExcds); |
| MDIFF(d, i2, i1, ipv6IfIcmpInParmProblems); |
| MDIFF(d, i2, i1, ipv6IfIcmpInPktTooBigs); |
| MDIFF(d, i2, i1, ipv6IfIcmpInEchos); |
| MDIFF(d, i2, i1, ipv6IfIcmpInEchoReplies); |
| MDIFF(d, i2, i1, ipv6IfIcmpInRouterSolicits); |
| MDIFF(d, i2, i1, ipv6IfIcmpInRouterAdvertisements); |
| MDIFF(d, i2, i1, ipv6IfIcmpInNeighborSolicits); |
| MDIFF(d, i2, i1, ipv6IfIcmpInNeighborAdvertisements); |
| MDIFF(d, i2, i1, ipv6IfIcmpInRedirects); |
| MDIFF(d, i2, i1, ipv6IfIcmpInBadRedirects); |
| MDIFF(d, i2, i1, ipv6IfIcmpInGroupMembQueries); |
| MDIFF(d, i2, i1, ipv6IfIcmpInGroupMembResponses); |
| MDIFF(d, i2, i1, ipv6IfIcmpInGroupMembReductions); |
| MDIFF(d, i2, i1, ipv6IfIcmpInOverflows); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutMsgs); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutErrors); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutDestUnreachs); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutAdminProhibs); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutTimeExcds); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutParmProblems); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutPktTooBigs); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutEchos); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutEchoReplies); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutRouterSolicits); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutRouterAdvertisements); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutNeighborSolicits); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutNeighborAdvertisements); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutRedirects); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutGroupMembQueries); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutGroupMembResponses); |
| MDIFF(d, i2, i1, ipv6IfIcmpOutGroupMembReductions); |
| prevp = diffptr++; |
| break; |
| } |
| case MIB2_TCP: { |
| mib2_tcp_t *t2; |
| mib2_tcp_t *t1; |
| mib2_tcp_t *d; |
| |
| t2 = (mib2_tcp_t *)tempp2->valp; |
| t1 = (mib2_tcp_t *)tempp1->valp; |
| diffptr->group = tempp2->group; |
| diffptr->mib_id = tempp2->mib_id; |
| diffptr->length = tempp2->length; |
| d = (mib2_tcp_t *)calloc(tempp2->length, 1); |
| if (d == NULL) |
| goto mibdiff_out_of_memory; |
| diffptr->valp = d; |
| d->tcpRtoMin = t2->tcpRtoMin; |
| d->tcpRtoMax = t2->tcpRtoMax; |
| d->tcpMaxConn = t2->tcpMaxConn; |
| MDIFF(d, t2, t1, tcpActiveOpens); |
| MDIFF(d, t2, t1, tcpPassiveOpens); |
| MDIFF(d, t2, t1, tcpAttemptFails); |
| MDIFF(d, t2, t1, tcpEstabResets); |
| d->tcpCurrEstab = t2->tcpCurrEstab; |
| MDIFF(d, t2, t1, tcpOutSegs); |
| MDIFF(d, t2, t1, tcpOutDataSegs); |
| MDIFF(d, t2, t1, tcpOutDataBytes); |
| MDIFF(d, t2, t1, tcpRetransSegs); |
| MDIFF(d, t2, t1, tcpRetransBytes); |
| MDIFF(d, t2, t1, tcpOutAck); |
| MDIFF(d, t2, t1, tcpOutAckDelayed); |
| MDIFF(d, t2, t1, tcpOutUrg); |
| MDIFF(d, t2, t1, tcpOutWinUpdate); |
| MDIFF(d, t2, t1, tcpOutWinProbe); |
| MDIFF(d, t2, t1, tcpOutControl); |
| MDIFF(d, t2, t1, tcpOutRsts); |
| MDIFF(d, t2, t1, tcpOutFastRetrans); |
| MDIFF(d, t2, t1, tcpInSegs); |
| MDIFF(d, t2, t1, tcpInAckSegs); |
| MDIFF(d, t2, t1, tcpInAckBytes); |
| MDIFF(d, t2, t1, tcpInDupAck); |
| MDIFF(d, t2, t1, tcpInAckUnsent); |
| MDIFF(d, t2, t1, tcpInDataInorderSegs); |
| MDIFF(d, t2, t1, tcpInDataInorderBytes); |
| MDIFF(d, t2, t1, tcpInDataUnorderSegs); |
| MDIFF(d, t2, t1, tcpInDataUnorderBytes); |
| MDIFF(d, t2, t1, tcpInDataDupSegs); |
| MDIFF(d, t2, t1, tcpInDataDupBytes); |
| MDIFF(d, t2, t1, tcpInDataPartDupSegs); |
| MDIFF(d, t2, t1, tcpInDataPartDupBytes); |
| MDIFF(d, t2, t1, tcpInDataPastWinSegs); |
| MDIFF(d, t2, t1, tcpInDataPastWinBytes); |
| MDIFF(d, t2, t1, tcpInWinProbe); |
| MDIFF(d, t2, t1, tcpInWinUpdate); |
| MDIFF(d, t2, t1, tcpInClosed); |
| MDIFF(d, t2, t1, tcpRttNoUpdate); |
| MDIFF(d, t2, t1, tcpRttUpdate); |
| MDIFF(d, t2, t1, tcpTimRetrans); |
| MDIFF(d, t2, t1, tcpTimRetransDrop); |
| MDIFF(d, t2, t1, tcpTimKeepalive); |
| MDIFF(d, t2, t1, tcpTimKeepaliveProbe); |
| MDIFF(d, t2, t1, tcpTimKeepaliveDrop); |
| MDIFF(d, t2, t1, tcpListenDrop); |
| MDIFF(d, t2, t1, tcpListenDropQ0); |
| MDIFF(d, t2, t1, tcpHalfOpenDrop); |
| MDIFF(d, t2, t1, tcpOutSackRetransSegs); |
| prevp = diffptr++; |
| break; |
| } |
| case MIB2_UDP: { |
| mib2_udp_t *u2; |
| mib2_udp_t *u1; |
| mib2_udp_t *d; |
| |
| u2 = (mib2_udp_t *)tempp2->valp; |
| u1 = (mib2_udp_t *)tempp1->valp; |
| diffptr->group = tempp2->group; |
| diffptr->mib_id = tempp2->mib_id; |
| diffptr->length = tempp2->length; |
| d = (mib2_udp_t *)calloc(tempp2->length, 1); |
| if (d == NULL) |
| goto mibdiff_out_of_memory; |
| diffptr->valp = d; |
| MDIFF(d, u2, u1, udpInDatagrams); |
| MDIFF(d, u2, u1, udpInErrors); |
| MDIFF(d, u2, u1, udpOutDatagrams); |
| MDIFF(d, u2, u1, udpOutErrors); |
| prevp = diffptr++; |
| break; |
| } |
| case MIB2_SCTP: { |
| mib2_sctp_t *s2; |
| mib2_sctp_t *s1; |
| mib2_sctp_t *d; |
| |
| s2 = (mib2_sctp_t *)tempp2->valp; |
| s1 = (mib2_sctp_t *)tempp1->valp; |
| diffptr->group = tempp2->group; |
| diffptr->mib_id = tempp2->mib_id; |
| diffptr->length = tempp2->length; |
| d = (mib2_sctp_t *)calloc(tempp2->length, 1); |
| if (d == NULL) |
| goto mibdiff_out_of_memory; |
| diffptr->valp = d; |
| d->sctpRtoAlgorithm = s2->sctpRtoAlgorithm; |
| d->sctpRtoMin = s2->sctpRtoMin; |
| d->sctpRtoMax = s2->sctpRtoMax; |
| d->sctpRtoInitial = s2->sctpRtoInitial; |
| d->sctpMaxAssocs = s2->sctpMaxAssocs; |
| d->sctpValCookieLife = s2->sctpValCookieLife; |
| d->sctpMaxInitRetr = s2->sctpMaxInitRetr; |
| d->sctpCurrEstab = s2->sctpCurrEstab; |
| MDIFF(d, s2, s1, sctpActiveEstab); |
| MDIFF(d, s2, s1, sctpPassiveEstab); |
| MDIFF(d, s2, s1, sctpAborted); |
| MDIFF(d, s2, s1, sctpShutdowns); |
| MDIFF(d, s2, s1, sctpOutOfBlue); |
| MDIFF(d, s2, s1, sctpChecksumError); |
| MDIFF(d, s2, s1, sctpOutCtrlChunks); |
| MDIFF(d, s2, s1, sctpOutOrderChunks); |
| MDIFF(d, s2, s1, sctpOutUnorderChunks); |
| MDIFF(d, s2, s1, sctpRetransChunks); |
| MDIFF(d, s2, s1, sctpOutAck); |
| MDIFF(d, s2, s1, sctpOutAckDelayed); |
| MDIFF(d, s2, s1, sctpOutWinUpdate); |
| MDIFF(d, s2, s1, sctpOutFastRetrans); |
| MDIFF(d, s2, s1, sctpOutWinProbe); |
| MDIFF(d, s2, s1, sctpInCtrlChunks); |
| MDIFF(d, s2, s1, sctpInOrderChunks); |
| MDIFF(d, s2, s1, sctpInUnorderChunks); |
| MDIFF(d, s2, s1, sctpInAck); |
| MDIFF(d, s2, s1, sctpInDupAck); |
| MDIFF(d, s2, s1, sctpInAckUnsent); |
| MDIFF(d, s2, s1, sctpFragUsrMsgs); |
| MDIFF(d, s2, s1, sctpReasmUsrMsgs); |
| MDIFF(d, s2, s1, sctpOutSCTPPkts); |
| MDIFF(d, s2, s1, sctpInSCTPPkts); |
| MDIFF(d, s2, s1, sctpInInvalidCookie); |
| MDIFF(d, s2, s1, sctpTimRetrans); |
| MDIFF(d, s2, s1, sctpTimRetransDrop); |
| MDIFF(d, s2, s1, sctpTimHeartBeatProbe); |
| MDIFF(d, s2, s1, sctpTimHeartBeatDrop); |
| MDIFF(d, s2, s1, sctpListenDrop); |
| MDIFF(d, s2, s1, sctpInClosed); |
| prevp = diffptr++; |
| break; |
| } |
| case EXPER_RAWIP: { |
| mib2_rawip_t *r2; |
| mib2_rawip_t *r1; |
| mib2_rawip_t *d; |
| |
| r2 = (mib2_rawip_t *)tempp2->valp; |
| r1 = (mib2_rawip_t *)tempp1->valp; |
| diffptr->group = tempp2->group; |
| diffptr->mib_id = tempp2->mib_id; |
| diffptr->length = tempp2->length; |
| d = (mib2_rawip_t *)calloc(tempp2->length, 1); |
| if (d == NULL) |
| goto mibdiff_out_of_memory; |
| diffptr->valp = d; |
| MDIFF(d, r2, r1, rawipInDatagrams); |
| MDIFF(d, r2, r1, rawipInErrors); |
| MDIFF(d, r2, r1, rawipInCksumErrs); |
| MDIFF(d, r2, r1, rawipOutDatagrams); |
| MDIFF(d, r2, r1, rawipOutErrors); |
| prevp = diffptr++; |
| break; |
| } |
| /* |
| * there are more "group" types but they aren't |
| * required for the -s and -Ms options |
| */ |
| } |
| } /* 'for' loop 2 ends */ |
| tempp1 = NULL; |
| } /* 'for' loop 1 ends */ |
| tempp2 = NULL; |
| diffptr--; |
| diffptr->next_item = NULL; |
| return (diffp); |
| |
| mibdiff_out_of_memory:; |
| mib_item_destroy(&diffp); |
| return (NULL); |
| } |
| |
| /* |
| * mib_item_destroy: cleans up a mib_item_t * |
| * that was created by calling mib_item_dup or |
| * mib_item_diff |
| */ |
| static void |
| mib_item_destroy(mib_item_t **itemp) { |
| int nitems = 0; |
| int c = 0; |
| mib_item_t *tempp; |
| |
| if (itemp == NULL || *itemp == NULL) |
| return; |
| |
| for (tempp = *itemp; tempp != NULL; tempp = tempp->next_item) |
| if (tempp->mib_id == 0) |
| nitems++; |
| else |
| return; /* cannot destroy! */ |
| |
| if (nitems == 0) |
| return; /* cannot destroy! */ |
| |
| for (c = nitems - 1; c >= 0; c--) { |
| if ((itemp[0][c]).valp != NULL) |
| free((itemp[0][c]).valp); |
| } |
| free(*itemp); |
| |
| *itemp = NULL; |
| } |
| |
| /* Compare two Octet_ts. Return B_TRUE if they match, B_FALSE if not. */ |
| static boolean_t |
| octetstrmatch(const Octet_t *a, const Octet_t *b) |
| { |
| if (a == NULL || b == NULL) |
| return (B_FALSE); |
| |
| if (a->o_length != b->o_length) |
| return (B_FALSE); |
| |
| return (memcmp(a->o_bytes, b->o_bytes, a->o_length) == 0); |
| } |
| |
| /* If octetstr() changes make an appropriate change to STR_EXPAND */ |
| static char * |
| octetstr(const Octet_t *op, int code, char *dst, uint_t dstlen) |
| { |
| int i; |
| char *cp; |
| |
| cp = dst; |
| if (op) { |
| for (i = 0; i < op->o_length; i++) { |
| switch (code) { |
| case 'd': |
| if (cp - dst + 4 > dstlen) { |
| *cp = '\0'; |
| return (dst); |
| } |
| (void) snprintf(cp, 5, "%d.", |
| 0xff & op->o_bytes[i]); |
| cp = strchr(cp, '\0'); |
| break; |
| case 'a': |
| if (cp - dst + 1 > dstlen) { |
| *cp = '\0'; |
| return (dst); |
| } |
| *cp++ = op->o_bytes[i]; |
| break; |
| case 'h': |
| default: |
| if (cp - dst + 3 > dstlen) { |
| *cp = '\0'; |
| return (dst); |
| } |
| (void) snprintf(cp, 4, "%02x:", |
| 0xff & op->o_bytes[i]); |
| cp += 3; |
| break; |
| } |
| } |
| } |
| if (code != 'a' && cp != dst) |
| cp--; |
| *cp = '\0'; |
| return (dst); |
| } |
| |
| static const char * |
| mitcp_state(int state, const mib2_transportMLPEntry_t *attr) |
| { |
| static char tcpsbuf[50]; |
| const char *cp; |
| |
| switch (state) { |
| case TCPS_CLOSED: |
| cp = "CLOSED"; |
| break; |
| case TCPS_IDLE: |
| cp = "IDLE"; |
| break; |
| case TCPS_BOUND: |
| cp = "BOUND"; |
| break; |
| case TCPS_LISTEN: |
| cp = "LISTEN"; |
| break; |
| case TCPS_SYN_SENT: |
| cp = "SYN_SENT"; |
| break; |
| case TCPS_SYN_RCVD: |
| cp = "SYN_RCVD"; |
| break; |
| case TCPS_ESTABLISHED: |
| cp = "ESTABLISHED"; |
| break; |
| case TCPS_CLOSE_WAIT: |
| cp = "CLOSE_WAIT"; |
| break; |
| case TCPS_FIN_WAIT_1: |
| cp = "FIN_WAIT_1"; |
| break; |
| case TCPS_CLOSING: |
| cp = "CLOSING"; |
| break; |
| case TCPS_LAST_ACK: |
| cp = "LAST_ACK"; |
| break; |
| case TCPS_FIN_WAIT_2: |
| cp = "FIN_WAIT_2"; |
| break; |
| case TCPS_TIME_WAIT: |
| cp = "TIME_WAIT"; |
| break; |
| default: |
| (void) snprintf(tcpsbuf, sizeof (tcpsbuf), |
| "UnknownState(%d)", state); |
| cp = tcpsbuf; |
| break; |
| } |
| |
| if (RSECflag && attr != NULL && attr->tme_flags != 0) { |
| if (cp != tcpsbuf) { |
| (void) strlcpy(tcpsbuf, cp, sizeof (tcpsbuf)); |
| cp = tcpsbuf; |
| } |
| if (attr->tme_flags & MIB2_TMEF_PRIVATE) |
| (void) strlcat(tcpsbuf, " P", sizeof (tcpsbuf)); |
| if (attr->tme_flags & MIB2_TMEF_SHARED) |
| (void) strlcat(tcpsbuf, " S", sizeof (tcpsbuf)); |
| } |
| |
| return (cp); |
| } |
| |
| static const char * |
| miudp_state(int state, const mib2_transportMLPEntry_t *attr) |
| { |
| static char udpsbuf[50]; |
| const char *cp; |
| |
| switch (state) { |
| case MIB2_UDP_unbound: |
| cp = "Unbound"; |
| break; |
| case MIB2_UDP_idle: |
| cp = "Idle"; |
| break; |
| case MIB2_UDP_connected: |
| cp = "Connected"; |
| break; |
| default: |
| (void) snprintf(udpsbuf, sizeof (udpsbuf), |
| "Unknown State(%d)", state); |
| cp = udpsbuf; |
| break; |
| } |
| |
| if (RSECflag && attr != NULL && attr->tme_flags != 0) { |
| if (cp != udpsbuf) { |
| (void) strlcpy(udpsbuf, cp, sizeof (udpsbuf)); |
| cp = udpsbuf; |
| } |
| if (attr->tme_flags & MIB2_TMEF_PRIVATE) |
| (void) strlcat(udpsbuf, " P", sizeof (udpsbuf)); |
| if (attr->tme_flags & MIB2_TMEF_SHARED) |
| (void) strlcat(udpsbuf, " S", sizeof (udpsbuf)); |
| } |
| |
| return (cp); |
| } |
| |
| static int odd; |
| |
| static void |
| prval_init(void) |
| { |
| odd = 0; |
| } |
| |
| static void |
| prval(char *str, Counter val) |
| { |
| (void) printf("\t%-20s=%6u", str, val); |
| if (odd++ & 1) |
| (void) putchar('\n'); |
| } |
| |
| static void |
| prval64(char *str, Counter64 val) |
| { |
| (void) printf("\t%-20s=%6llu", str, val); |
| if (odd++ & 1) |
| (void) putchar('\n'); |
| } |
| |
| static void |
| pr_int_val(char *str, int val) |
| { |
| (void) printf("\t%-20s=%6d", str, val); |
| if (odd++ & 1) |
| (void) putchar('\n'); |
| } |
| |
| static void |
| pr_sctp_rtoalgo(char *str, int val) |
| { |
| (void) printf("\t%-20s=", str); |
| switch (val) { |
| case MIB2_SCTP_RTOALGO_OTHER: |
| (void) printf("%6.6s", "other"); |
| break; |
| |
| case MIB2_SCTP_RTOALGO_VANJ: |
| (void) printf("%6.6s", "vanj"); |
| break; |
| |
| default: |
| (void) printf("%6d", val); |
| break; |
| } |
| if (odd++ & 1) |
| (void) putchar('\n'); |
| } |
| |
| static void |
| prval_end(void) |
| { |
| if (odd++ & 1) |
| (void) putchar('\n'); |
| } |
| |
| /* Extract constant sizes */ |
| static void |
| mib_get_constants(mib_item_t *item) |
| { |
| /* 'for' loop 1: */ |
| for (; item; item = item->next_item) { |
| if (item->mib_id != 0) |
| continue; /* 'for' loop 1 */ |
| |
| switch (item->group) { |
| case MIB2_IP: { |
| mib2_ip_t *ip = (mib2_ip_t *)item->valp; |
| |
| ipAddrEntrySize = ip->ipAddrEntrySize; |
| ipRouteEntrySize = ip->ipRouteEntrySize; |
| ipNetToMediaEntrySize = ip->ipNetToMediaEntrySize; |
| ipMemberEntrySize = ip->ipMemberEntrySize; |
| ipGroupSourceEntrySize = ip->ipGroupSourceEntrySize; |
| ipRouteAttributeSize = ip->ipRouteAttributeSize; |
| transportMLPSize = ip->transportMLPSize; |
| assert(IS_P2ALIGNED(ipAddrEntrySize, |
| sizeof (mib2_ipAddrEntry_t *)) && |
| IS_P2ALIGNED(ipRouteEntrySize, |
| sizeof (mib2_ipRouteEntry_t *)) && |
| IS_P2ALIGNED(ipNetToMediaEntrySize, |
| sizeof (mib2_ipNetToMediaEntry_t *)) && |
| IS_P2ALIGNED(ipMemberEntrySize, |
| sizeof (ip_member_t *)) && |
| IS_P2ALIGNED(ipGroupSourceEntrySize, |
| sizeof (ip_grpsrc_t *)) && |
| IS_P2ALIGNED(ipRouteAttributeSize, |
| sizeof (mib2_ipAttributeEntry_t *)) && |
| IS_P2ALIGNED(transportMLPSize, |
| sizeof (mib2_transportMLPEntry_t *))); |
| break; |
| } |
| case EXPER_DVMRP: { |
| struct mrtstat *mrts = (struct mrtstat *)item->valp; |
| |
| vifctlSize = mrts->mrts_vifctlSize; |
| mfcctlSize = mrts->mrts_mfcctlSize; |
| assert(IS_P2ALIGNED(vifctlSize, |
| sizeof (struct vifclt *)) && |
| IS_P2ALIGNED(mfcctlSize, sizeof (struct mfcctl *))); |
| break; |
| } |
| case MIB2_IP6: { |
| mib2_ipv6IfStatsEntry_t *ip6; |
| /* Just use the first entry */ |
| |
| ip6 = (mib2_ipv6IfStatsEntry_t *)item->valp; |
| ipv6IfStatsEntrySize = ip6->ipv6IfStatsEntrySize; |
| ipv6AddrEntrySize = ip6->ipv6AddrEntrySize; |
| ipv6RouteEntrySize = ip6->ipv6RouteEntrySize; |
| ipv6NetToMediaEntrySize = ip6->ipv6NetToMediaEntrySize; |
| ipv6MemberEntrySize = ip6->ipv6MemberEntrySize; |
| ipv6GroupSourceEntrySize = |
| ip6->ipv6GroupSourceEntrySize; |
| assert(IS_P2ALIGNED(ipv6IfStatsEntrySize, |
| sizeof (mib2_ipv6IfStatsEntry_t *)) && |
| IS_P2ALIGNED(ipv6AddrEntrySize, |
| sizeof (mib2_ipv6AddrEntry_t *)) && |
| IS_P2ALIGNED(ipv6RouteEntrySize, |
| sizeof (mib2_ipv6RouteEntry_t *)) && |
| IS_P2ALIGNED(ipv6NetToMediaEntrySize, |
| sizeof (mib2_ipv6NetToMediaEntry_t *)) && |
| IS_P2ALIGNED(ipv6MemberEntrySize, |
| sizeof (ipv6_member_t *)) && |
| IS_P2ALIGNED(ipv6GroupSourceEntrySize, |
| sizeof (ipv6_grpsrc_t *))); |
| break; |
| } |
| case MIB2_ICMP6: { |
| mib2_ipv6IfIcmpEntry_t *icmp6; |
| /* Just use the first entry */ |
| |
| icmp6 = (mib2_ipv6IfIcmpEntry_t *)item->valp; |
| ipv6IfIcmpEntrySize = icmp6->ipv6IfIcmpEntrySize; |
| assert(IS_P2ALIGNED(ipv6IfIcmpEntrySize, |
| sizeof (mib2_ipv6IfIcmpEntry_t *))); |
| break; |
| } |
| case MIB2_TCP: { |
| mib2_tcp_t *tcp = (mib2_tcp_t *)item->valp; |
| |
| tcpConnEntrySize = tcp->tcpConnTableSize; |
| tcp6ConnEntrySize = tcp->tcp6ConnTableSize; |
| assert(IS_P2ALIGNED(tcpConnEntrySize, |
| sizeof (mib2_tcpConnEntry_t *)) && |
| IS_P2ALIGNED(tcp6ConnEntrySize, |
| sizeof (mib2_tcp6ConnEntry_t *))); |
| break; |
| } |
| case MIB2_UDP: { |
| mib2_udp_t *udp = (mib2_udp_t *)item->valp; |
| |
| udpEntrySize = udp->udpEntrySize; |
| udp6EntrySize = udp->udp6EntrySize; |
| assert(IS_P2ALIGNED(udpEntrySize, |
| sizeof (mib2_udpEntry_t *)) && |
| IS_P2ALIGNED(udp6EntrySize, |
| sizeof (mib2_udp6Entry_t *))); |
| break; |
| } |
| case MIB2_SCTP: { |
| mib2_sctp_t *sctp = (mib2_sctp_t *)item->valp; |
| |
| sctpEntrySize = sctp->sctpEntrySize; |
| sctpLocalEntrySize = sctp->sctpLocalEntrySize; |
| sctpRemoteEntrySize = sctp->sctpRemoteEntrySize; |
| break; |
| } |
| } |
| } /* 'for' loop 1 ends */ |
| |
| if (Dflag) { |
| (void) puts("mib_get_constants:"); |
| (void) printf("\tipv6IfStatsEntrySize %d\n", |
| ipv6IfStatsEntrySize); |
| (void) printf("\tipAddrEntrySize %d\n", ipAddrEntrySize); |
| (void) printf("\tipRouteEntrySize %d\n", ipRouteEntrySize); |
| (void) printf("\tipNetToMediaEntrySize %d\n", |
| ipNetToMediaEntrySize); |
| (void) printf("\tipMemberEntrySize %d\n", ipMemberEntrySize); |
| (void) printf("\tipRouteAttributeSize %d\n", |
| ipRouteAttributeSize); |
| (void) printf("\tvifctlSize %d\n", vifctlSize); |
| (void) printf("\tmfcctlSize %d\n", mfcctlSize); |
| |
| (void) printf("\tipv6AddrEntrySize %d\n", ipv6AddrEntrySize); |
| (void) printf("\tipv6RouteEntrySize %d\n", ipv6RouteEntrySize); |
| (void) printf("\tipv6NetToMediaEntrySize %d\n", |
| ipv6NetToMediaEntrySize); |
| (void) printf("\tipv6MemberEntrySize %d\n", |
| ipv6MemberEntrySize); |
| (void) printf("\tipv6IfIcmpEntrySize %d\n", |
| ipv6IfIcmpEntrySize); |
| (void) printf("\ttransportMLPSize %d\n", transportMLPSize); |
| (void) printf("\ttcpConnEntrySize %d\n", tcpConnEntrySize); |
| (void) printf("\ttcp6ConnEntrySize %d\n", tcp6ConnEntrySize); |
| (void) printf("\tudpEntrySize %d\n", udpEntrySize); |
| (void) printf("\tudp6EntrySize %d\n", udp6EntrySize); |
| (void) printf("\tsctpEntrySize %d\n", sctpEntrySize); |
| (void) printf("\tsctpLocalEntrySize %d\n", sctpLocalEntrySize); |
| (void) printf("\tsctpRemoteEntrySize %d\n", |
| sctpRemoteEntrySize); |
| } |
| } |
| |
| |
| /* ----------------------------- STAT_REPORT ------------------------------- */ |
| |
| static void |
| stat_report(mib_item_t *item) |
| { |
| int jtemp = 0; |
| char ifname[LIFNAMSIZ + 1]; |
| char *ifnamep; |
| |
| /* 'for' loop 1: */ |
| for (; item; item = item->next_item) { |
| if (Dflag) { |
| (void) printf("\n--- Entry %d ---\n", ++jtemp); |
| (void) printf("Group = %d, mib_id = %d, " |
| "length = %d, valp = 0x%p\n", |
| item->group, item->mib_id, |
| item->length, item->valp); |
| } |
| if (item->mib_id != 0) |
| continue; /* 'for' loop 1 */ |
| |
| switch (item->group) { |
| case MIB2_IP: { |
| mib2_ip_t *ip = (mib2_ip_t *)item->valp; |
| |
| if (protocol_selected(IPPROTO_IP) && |
| family_selected(AF_INET)) { |
| (void) fputs(v4compat ? "\nIP" : "\nIPv4", |
| stdout); |
| print_ip_stats(ip); |
| } |
| break; |
| } |
| case MIB2_ICMP: { |
| mib2_icmp_t *icmp = |
| (mib2_icmp_t *)item->valp; |
| |
| if (protocol_selected(IPPROTO_ICMP) && |
| family_selected(AF_INET)) { |
| (void) fputs(v4compat ? "\nICMP" : "\nICMPv4", |
| stdout); |
| print_icmp_stats(icmp); |
| } |
| break; |
| } |
| case MIB2_IP6: { |
| mib2_ipv6IfStatsEntry_t *ip6; |
| mib2_ipv6IfStatsEntry_t sum6; |
| |
| if (!(protocol_selected(IPPROTO_IPV6)) || |
| !(family_selected(AF_INET6))) |
| break; |
| bzero(&sum6, sizeof (sum6)); |
| /* 'for' loop 2a: */ |
| for (ip6 = (mib2_ipv6IfStatsEntry_t *)item->valp; |
| (char *)ip6 < (char *)item->valp |
| + item->length; |
| /* LINTED: (note 1) */ |
| ip6 = (mib2_ipv6IfStatsEntry_t *)((char *)ip6 + |
| ipv6IfStatsEntrySize)) { |
| |
| if (ip6->ipv6IfIndex == 0) { |
| /* |
| * The "unknown interface" ip6 |
| * mib. Just add to the sum. |
| */ |
| sum_ip6_stats(ip6, &sum6); |
| continue; /* 'for' loop 2a */ |
| } |
| ifnamep = if_indextoname( |
| ip6->ipv6IfIndex, |
| ifname); |
| if (ifnamep == NULL) { |
| (void) printf( |
| "Invalid ifindex %d\n", |
| ip6->ipv6IfIndex); |
| continue; /* 'for' loop 2a */ |
| } |
| |
| if (Aflag) { |
| (void) printf("\nIPv6 for %s\n", |
| ifnamep); |
| print_ip6_stats(ip6); |
| } |
| sum_ip6_stats(ip6, &sum6); |
| } /* 'for' loop 2a ends */ |
| (void) fputs("\nIPv6", stdout); |
| print_ip6_stats(&sum6); |
| break; |
| } |
| case MIB2_ICMP6: { |
| mib2_ipv6IfIcmpEntry_t *icmp6; |
| mib2_ipv6IfIcmpEntry_t sum6; |
| |
| if (!(protocol_selected(IPPROTO_ICMPV6)) || |
| !(family_selected(AF_INET6))) |
| break; |
| bzero(&sum6, sizeof (sum6)); |
| /* 'for' loop 2b: */ |
| for (icmp6 = |
| (mib2_ipv6IfIcmpEntry_t *)item->valp; |
| (char *)icmp6 < (char *)item->valp |
| + item->length; |
| icmp6 = |
| /* LINTED: (note 1) */ |
| (mib2_ipv6IfIcmpEntry_t *)((char *)icmp6 |
| + ipv6IfIcmpEntrySize)) { |
| |
| if (icmp6->ipv6IfIcmpIfIndex == 0) { |
| /* |
| * The "unknown interface" icmp6 |
| * mib. Just add to the sum. |
| */ |
| sum_icmp6_stats(icmp6, &sum6); |
| continue; /* 'for' loop 2b: */ |
| } |
| ifnamep = if_indextoname( |
| icmp6->ipv6IfIcmpIfIndex, ifname); |
| if (ifnamep == NULL) { |
| (void) printf( |
| "Invalid ifindex %d\n", |
| icmp6->ipv6IfIcmpIfIndex); |
| continue; /* 'for' loop 2b: */ |
| } |
| |
| if (Aflag) { |
| (void) printf( |
| "\nICMPv6 for %s\n", |
| ifnamep); |
| print_icmp6_stats(icmp6); |
| } |
| sum_icmp6_stats(icmp6, &sum6); |
| } /* 'for' loop 2b ends */ |
| (void) fputs("\nICMPv6", stdout); |
| print_icmp6_stats(&sum6); |
| break; |
| } |
| case MIB2_TCP: { |
| mib2_tcp_t *tcp = (mib2_tcp_t *)item->valp; |
| |
| if (protocol_selected(IPPROTO_TCP) && |
| (family_selected(AF_INET) || |
| family_selected(AF_INET6))) { |
| (void) fputs("\nTCP", stdout); |
| print_tcp_stats(tcp); |
| } |
| break; |
| } |
| case MIB2_UDP: { |
| mib2_udp_t *udp = (mib2_udp_t *)item->valp; |
| |
| if (protocol_selected(IPPROTO_UDP) && |
| (family_selected(AF_INET) || |
| family_selected(AF_INET6))) { |
| (void) fputs("\nUDP", stdout); |
| print_udp_stats(udp); |
| } |
| break; |
| } |
| case MIB2_SCTP: { |
| mib2_sctp_t *sctp = (mib2_sctp_t *)item->valp; |
| |
| if (protocol_selected(IPPROTO_SCTP) && |
| (family_selected(AF_INET) || |
| family_selected(AF_INET6))) { |
| (void) fputs("\nSCTP", stdout); |
| print_sctp_stats(sctp); |
| } |
| break; |
| } |
| case EXPER_RAWIP: { |
| mib2_rawip_t *rawip = |
| (mib2_rawip_t *)item->valp; |
| |
| if (protocol_selected(IPPROTO_RAW) && |
| (family_selected(AF_INET) || |
| family_selected(AF_INET6))) { |
| (void) fputs("\nRAWIP", stdout); |
| print_rawip_stats(rawip); |
| } |
| break; |
| } |
| case EXPER_IGMP: { |
| struct igmpstat *igps = |
| (struct igmpstat *)item->valp; |
| |
| if (protocol_selected(IPPROTO_IGMP) && |
| (family_selected(AF_INET))) { |
| (void) fputs("\nIGMP:\n", stdout); |
| print_igmp_stats(igps); |
| } |
| break; |
| } |
| } |
| } /* 'for' loop 1 ends */ |
| (void) putchar('\n'); |
| (void) fflush(stdout); |
| } |
| |
| static void |
| print_ip_stats(mib2_ip_t *ip) |
| { |
| prval_init(); |
| pr_int_val("ipForwarding", ip->ipForwarding); |
| pr_int_val("ipDefaultTTL", ip->ipDefaultTTL); |
| prval("ipInReceives", ip->ipInReceives); |
| prval("ipInHdrErrors", ip->ipInHdrErrors); |
| prval("ipInAddrErrors", ip->ipInAddrErrors); |
| prval("ipInCksumErrs", ip->ipInCksumErrs); |
| prval("ipForwDatagrams", ip->ipForwDatagrams); |
| prval("ipForwProhibits", ip->ipForwProhibits); |
| prval("ipInUnknownProtos", ip->ipInUnknownProtos); |
| prval("ipInDiscards", ip->ipInDiscards); |
| prval("ipInDelivers", ip->ipInDelivers); |
| prval("ipOutRequests", ip->ipOutRequests); |
| prval("ipOutDiscards", ip->ipOutDiscards); |
| prval("ipOutNoRoutes", ip->ipOutNoRoutes); |
| pr_int_val("ipReasmTimeout", ip->ipReasmTimeout); |
| prval("ipReasmReqds", ip->ipReasmReqds); |
| prval("ipReasmOKs", ip->ipReasmOKs); |
| prval("ipReasmFails", ip->ipReasmFails); |
| prval("ipReasmDuplicates", ip->ipReasmDuplicates); |
| prval("ipReasmPartDups", ip->ipReasmPartDups); |
| prval("ipFragOKs", ip->ipFragOKs); |
| prval("ipFragFails", ip->ipFragFails); |
| prval("ipFragCreates", ip->ipFragCreates); |
| prval("ipRoutingDiscards", ip->ipRoutingDiscards); |
| |
| prval("tcpInErrs", ip->tcpInErrs); |
| prval("udpNoPorts", ip->udpNoPorts); |
| prval("udpInCksumErrs", ip->udpInCksumErrs); |
| prval("udpInOverflows", ip->udpInOverflows); |
| prval("rawipInOverflows", ip->rawipInOverflows); |
| prval("ipsecInSucceeded", ip->ipsecInSucceeded); |
| prval("ipsecInFailed", ip->ipsecInFailed); |
| prval("ipInIPv6", ip->ipInIPv6); |
| prval("ipOutIPv6", ip->ipOutIPv6); |
| prval("ipOutSwitchIPv6", ip->ipOutSwitchIPv6); |
| prval_end(); |
| } |
| |
| static void |
| print_icmp_stats(mib2_icmp_t *icmp) |
| { |
| prval_init(); |
| prval("icmpInMsgs", icmp->icmpInMsgs); |
| prval("icmpInErrors", icmp->icmpInErrors); |
| prval("icmpInCksumErrs", icmp->icmpInCksumErrs); |
| prval("icmpInUnknowns", icmp->icmpInUnknowns); |
| prval("icmpInDestUnreachs", icmp->icmpInDestUnreachs); |
| prval("icmpInTimeExcds", icmp->icmpInTimeExcds); |
| prval("icmpInParmProbs", icmp->icmpInParmProbs); |
| prval("icmpInSrcQuenchs", icmp->icmpInSrcQuenchs); |
| prval("icmpInRedirects", icmp->icmpInRedirects); |
| prval("icmpInBadRedirects", icmp->icmpInBadRedirects); |
| prval("icmpInEchos", icmp->icmpInEchos); |
| prval("icmpInEchoReps", icmp->icmpInEchoReps); |
| prval("icmpInTimestamps", icmp->icmpInTimestamps); |
| prval("icmpInTimestampReps", icmp->icmpInTimestampReps); |
| prval("icmpInAddrMasks", icmp->icmpInAddrMasks); |
| prval("icmpInAddrMaskReps", icmp->icmpInAddrMaskReps); |
| prval("icmpInFragNeeded", icmp->icmpInFragNeeded); |
| prval("icmpOutMsgs", icmp->icmpOutMsgs); |
| prval("icmpOutDrops", icmp->icmpOutDrops); |
| prval("icmpOutErrors", icmp->icmpOutErrors); |
| prval("icmpOutDestUnreachs", icmp->icmpOutDestUnreachs); |
| prval("icmpOutTimeExcds", icmp->icmpOutTimeExcds); |
| prval("icmpOutParmProbs", icmp->icmpOutParmProbs); |
| prval("icmpOutSrcQuenchs", icmp->icmpOutSrcQuenchs); |
| prval("icmpOutRedirects", icmp->icmpOutRedirects); |
| prval("icmpOutEchos", icmp->icmpOutEchos); |
| prval("icmpOutEchoReps", icmp->icmpOutEchoReps); |
| prval("icmpOutTimestamps", icmp->icmpOutTimestamps); |
| prval("icmpOutTimestampReps", icmp->icmpOutTimestampReps); |
| prval("icmpOutAddrMasks", icmp->icmpOutAddrMasks); |
| prval("icmpOutAddrMaskReps", icmp->icmpOutAddrMaskReps); |
| prval("icmpOutFragNeeded", icmp->icmpOutFragNeeded); |
| prval("icmpInOverflows", icmp->icmpInOverflows); |
| prval_end(); |
| } |
| |
| static void |
| print_ip6_stats(mib2_ipv6IfStatsEntry_t *ip6) |
| { |
| prval_init(); |
| prval("ipv6Forwarding", ip6->ipv6Forwarding); |
| prval("ipv6DefaultHopLimit", ip6->ipv6DefaultHopLimit); |
| |
| prval("ipv6InReceives", ip6->ipv6InReceives); |
| prval("ipv6InHdrErrors", ip6->ipv6InHdrErrors); |
| prval("ipv6InTooBigErrors", ip6->ipv6InTooBigErrors); |
| prval("ipv6InNoRoutes", ip6->ipv6InNoRoutes); |
| prval("ipv6InAddrErrors", ip6->ipv6InAddrErrors); |
| prval("ipv6InUnknownProtos", ip6->ipv6InUnknownProtos); |
| prval("ipv6InTruncatedPkts", ip6->ipv6InTruncatedPkts); |
| prval("ipv6InDiscards", ip6->ipv6InDiscards); |
| prval("ipv6InDelivers", ip6->ipv6InDelivers); |
| prval("ipv6OutForwDatagrams", ip6->ipv6OutForwDatagrams); |
| prval("ipv6OutRequests", ip6->ipv6OutRequests); |
| prval("ipv6OutDiscards", ip6->ipv6OutDiscards); |
| prval("ipv6OutNoRoutes", ip6->ipv6OutNoRoutes); |
| prval("ipv6OutFragOKs", ip6->ipv6OutFragOKs); |
| prval("ipv6OutFragFails", ip6->ipv6OutFragFails); |
| prval("ipv6OutFragCreates", ip6->ipv6OutFragCreates); |
| prval("ipv6ReasmReqds", ip6->ipv6ReasmReqds); |
| prval("ipv6ReasmOKs", ip6->ipv6ReasmOKs); |
| prval("ipv6ReasmFails", ip6->ipv6ReasmFails); |
| prval("ipv6InMcastPkts", ip6->ipv6InMcastPkts); |
| prval("ipv6OutMcastPkts", ip6->ipv6OutMcastPkts); |
| prval("ipv6ReasmDuplicates", ip6->ipv6ReasmDuplicates); |
| prval("ipv6ReasmPartDups", ip6->ipv6ReasmPartDups); |
| prval("ipv6ForwProhibits", ip6->ipv6ForwProhibits); |
| prval("udpInCksumErrs", ip6->udpInCksumErrs); |
| prval("udpInOverflows", ip6->udpInOverflows); |
| prval("rawipInOverflows", ip6->rawipInOverflows); |
| prval("ipv6InIPv4", ip6->ipv6InIPv4); |
| prval("ipv6OutIPv4", ip6->ipv6OutIPv4); |
| prval("ipv6OutSwitchIPv4", ip6->ipv6OutSwitchIPv4); |
| prval_end(); |
| } |
| |
| static void |
| print_icmp6_stats(mib2_ipv6IfIcmpEntry_t *icmp6) |
| { |
| prval_init(); |
| prval("icmp6InMsgs", icmp6->ipv6IfIcmpInMsgs); |
| prval("icmp6InErrors", icmp6->ipv6IfIcmpInErrors); |
| prval("icmp6InDestUnreachs", icmp6->ipv6IfIcmpInDestUnreachs); |
| prval("icmp6InAdminProhibs", icmp6->ipv6IfIcmpInAdminProhibs); |
| prval("icmp6InTimeExcds", icmp6->ipv6IfIcmpInTimeExcds); |
| prval("icmp6InParmProblems", icmp6->ipv6IfIcmpInParmProblems); |
| prval("icmp6InPktTooBigs", icmp6->ipv6IfIcmpInPktTooBigs); |
| prval("icmp6InEchos", icmp6->ipv6IfIcmpInEchos); |
| prval("icmp6InEchoReplies", icmp6->ipv6IfIcmpInEchoReplies); |
| prval("icmp6InRouterSols", icmp6->ipv6IfIcmpInRouterSolicits); |
| prval("icmp6InRouterAds", |
| icmp6->ipv6IfIcmpInRouterAdvertisements); |
| prval("icmp6InNeighborSols", icmp6->ipv6IfIcmpInNeighborSolicits); |
| prval("icmp6InNeighborAds", |
| icmp6->ipv6IfIcmpInNeighborAdvertisements); |
| prval("icmp6InRedirects", icmp6->ipv6IfIcmpInRedirects); |
| prval("icmp6InBadRedirects", icmp6->ipv6IfIcmpInBadRedirects); |
| prval("icmp6InGroupQueries", icmp6->ipv6IfIcmpInGroupMembQueries); |
| prval("icmp6InGroupResps", icmp6->ipv6IfIcmpInGroupMembResponses); |
| prval("icmp6InGroupReds", icmp6->ipv6IfIcmpInGroupMembReductions); |
| prval("icmp6InOverflows", icmp6->ipv6IfIcmpInOverflows); |
| prval_end(); |
| prval_init(); |
| prval("icmp6OutMsgs", icmp6->ipv6IfIcmpOutMsgs); |
| prval("icmp6OutErrors", icmp6->ipv6IfIcmpOutErrors); |
| prval("icmp6OutDestUnreachs", icmp6->ipv6IfIcmpOutDestUnreachs); |
| prval("icmp6OutAdminProhibs", icmp6->ipv6IfIcmpOutAdminProhibs); |
| prval("icmp6OutTimeExcds", icmp6->ipv6IfIcmpOutTimeExcds); |
| prval("icmp6OutParmProblems", icmp6->ipv6IfIcmpOutParmProblems); |
| prval("icmp6OutPktTooBigs", icmp6->ipv6IfIcmpOutPktTooBigs); |
| prval("icmp6OutEchos", icmp6->ipv6IfIcmpOutEchos); |
| prval("icmp6OutEchoReplies", icmp6->ipv6IfIcmpOutEchoReplies); |
| prval("icmp6OutRouterSols", icmp6->ipv6IfIcmpOutRouterSolicits); |
| prval("icmp6OutRouterAds", |
| icmp6->ipv6IfIcmpOutRouterAdvertisements); |
| prval("icmp6OutNeighborSols", icmp6->ipv6IfIcmpOutNeighborSolicits); |
| prval("icmp6OutNeighborAds", |
| icmp6->ipv6IfIcmpOutNeighborAdvertisements); |
| prval("icmp6OutRedirects", icmp6->ipv6IfIcmpOutRedirects); |
| prval("icmp6OutGroupQueries", icmp6->ipv6IfIcmpOutGroupMembQueries); |
| prval("icmp6OutGroupResps", |
| icmp6->ipv6IfIcmpOutGroupMembResponses); |
| prval("icmp6OutGroupReds", |
| icmp6->ipv6IfIcmpOutGroupMembReductions); |
| prval_end(); |
| } |
| |
| static void |
| print_sctp_stats(mib2_sctp_t *sctp) |
| { |
| prval_init(); |
| pr_sctp_rtoalgo("sctpRtoAlgorithm", sctp->sctpRtoAlgorithm); |
| prval("sctpRtoMin", sctp->sctpRtoMin); |
| prval("sctpRtoMax", sctp->sctpRtoMax); |
| prval("sctpRtoInitial", sctp->sctpRtoInitial); |
| pr_int_val("sctpMaxAssocs", sctp->sctpMaxAssocs); |
| prval("sctpValCookieLife", sctp->sctpValCookieLife); |
| prval("sctpMaxInitRetr", sctp->sctpMaxInitRetr); |
| prval("sctpCurrEstab", sctp->sctpCurrEstab); |
| prval("sctpActiveEstab", sctp->sctpActiveEstab); |
| prval("sctpPassiveEstab", sctp->sctpPassiveEstab); |
| prval("sctpAborted", sctp->sctpAborted); |
| prval("sctpShutdowns", sctp->sctpShutdowns); |
| prval("sctpOutOfBlue", sctp->sctpOutOfBlue); |
| prval("sctpChecksumError", sctp->sctpChecksumError); |
| prval64("sctpOutCtrlChunks", sctp->sctpOutCtrlChunks); |
| prval64("sctpOutOrderChunks", sctp->sctpOutOrderChunks); |
| prval64("sctpOutUnorderChunks", sctp->sctpOutUnorderChunks); |
| prval64("sctpRetransChunks", sctp->sctpRetransChunks); |
| prval("sctpOutAck", sctp->sctpOutAck); |
| prval("sctpOutAckDelayed", sctp->sctpOutAckDelayed); |
| prval("sctpOutWinUpdate", sctp->sctpOutWinUpdate); |
| prval("sctpOutFastRetrans", sctp->sctpOutFastRetrans); |
| prval("sctpOutWinProbe", sctp->sctpOutWinProbe); |
| prval64("sctpInCtrlChunks", sctp->sctpInCtrlChunks); |
| prval64("sctpInOrderChunks", sctp->sctpInOrderChunks); |
| prval64("sctpInUnorderChunks", sctp->sctpInUnorderChunks); |
| prval("sctpInAck", sctp->sctpInAck); |
| prval("sctpInDupAck", sctp->sctpInDupAck); |
| prval("sctpInAckUnsent", sctp->sctpInAckUnsent); |
| prval64("sctpFragUsrMsgs", sctp->sctpFragUsrMsgs); |
| prval64("sctpReasmUsrMsgs", sctp->sctpReasmUsrMsgs); |
| prval64("sctpOutSCTPPkts", sctp->sctpOutSCTPPkts); |
| prval64("sctpInSCTPPkts", sctp->sctpInSCTPPkts); |
| prval("sctpInInvalidCookie", sctp->sctpInInvalidCookie); |
| prval("sctpTimRetrans", sctp->sctpTimRetrans); |
| prval("sctpTimRetransDrop", sctp->sctpTimRetransDrop); |
| prval("sctpTimHearBeatProbe", sctp->sctpTimHeartBeatProbe); |
| prval("sctpTimHearBeatDrop", sctp->sctpTimHeartBeatDrop); |
| prval("sctpListenDrop", sctp->sctpListenDrop); |
| prval("sctpInClosed", sctp->sctpInClosed); |
| prval_end(); |
| } |
| |
| static void |
| print_tcp_stats(mib2_tcp_t *tcp) |
| { |
| prval_init(); |
| pr_int_val("tcpRtoAlgorithm", tcp->tcpRtoAlgorithm); |
| pr_int_val("tcpRtoMin", tcp->tcpRtoMin); |
| pr_int_val("tcpRtoMax", tcp->tcpRtoMax); |
| pr_int_val("tcpMaxConn", tcp->tcpMaxConn); |
| prval("tcpActiveOpens", tcp->tcpActiveOpens); |
| prval("tcpPassiveOpens", tcp->tcpPassiveOpens); |
| prval("tcpAttemptFails", tcp->tcpAttemptFails); |
| prval("tcpEstabResets", tcp->tcpEstabResets); |
| prval("tcpCurrEstab", tcp->tcpCurrEstab); |
| prval("tcpOutSegs", tcp->tcpOutSegs); |
| prval("tcpOutDataSegs", tcp->tcpOutDataSegs); |
| prval("tcpOutDataBytes", tcp->tcpOutDataBytes); |
| prval("tcpRetransSegs", tcp->tcpRetransSegs); |
| prval("tcpRetransBytes", tcp->tcpRetransBytes); |
| prval("tcpOutAck", tcp->tcpOutAck); |
| prval("tcpOutAckDelayed", tcp->tcpOutAckDelayed); |
| prval("tcpOutUrg", tcp->tcpOutUrg); |
| prval("tcpOutWinUpdate", tcp->tcpOutWinUpdate); |
| prval("tcpOutWinProbe", tcp->tcpOutWinProbe); |
| prval("tcpOutControl", tcp->tcpOutControl); |
| prval("tcpOutRsts", tcp->tcpOutRsts); |
| prval("tcpOutFastRetrans", tcp->tcpOutFastRetrans); |
| prval("tcpInSegs", tcp->tcpInSegs); |
| prval_end(); |
| prval("tcpInAckSegs", tcp->tcpInAckSegs); |
| prval("tcpInAckBytes", tcp->tcpInAckBytes); |
| prval("tcpInDupAck", tcp->tcpInDupAck); |
| prval("tcpInAckUnsent", tcp->tcpInAckUnsent); |
| prval("tcpInInorderSegs", tcp->tcpInDataInorderSegs); |
| prval("tcpInInorderBytes", tcp->tcpInDataInorderBytes); |
| prval("tcpInUnorderSegs", tcp->tcpInDataUnorderSegs); |
| prval("tcpInUnorderBytes", tcp->tcpInDataUnorderBytes); |
| prval("tcpInDupSegs", tcp->tcpInDataDupSegs); |
| prval("tcpInDupBytes", tcp->tcpInDataDupBytes); |
| prval("tcpInPartDupSegs", tcp->tcpInDataPartDupSegs); |
| prval("tcpInPartDupBytes", tcp->tcpInDataPartDupBytes); |
| prval("tcpInPastWinSegs", tcp->tcpInDataPastWinSegs); |
| prval("tcpInPastWinBytes", tcp->tcpInDataPastWinBytes); |
| prval("tcpInWinProbe", tcp->tcpInWinProbe); |
| prval("tcpInWinUpdate", tcp->tcpInWinUpdate); |
| prval("tcpInClosed", tcp->tcpInClosed); |
| prval("tcpRttNoUpdate", tcp->tcpRttNoUpdate); |
| prval("tcpRttUpdate", tcp->tcpRttUpdate); |
| prval("tcpTimRetrans", tcp->tcpTimRetrans); |
| prval("tcpTimRetransDrop", tcp->tcpTimRetransDrop); |
| prval("tcpTimKeepalive", tcp->tcpTimKeepalive); |
| prval("tcpTimKeepaliveProbe", tcp->tcpTimKeepaliveProbe); |
| prval("tcpTimKeepaliveDrop", tcp->tcpTimKeepaliveDrop); |
| prval("tcpListenDrop", tcp->tcpListenDrop); |
| prval("tcpListenDropQ0", tcp->tcpListenDropQ0); |
| prval("tcpHalfOpenDrop", tcp->tcpHalfOpenDrop); |
| prval("tcpOutSackRetrans", tcp->tcpOutSackRetransSegs); |
| prval_end(); |
| |
| } |
| |
| static void |
| print_udp_stats(mib2_udp_t *udp) |
| { |
| prval_init(); |
| prval("udpInDatagrams", udp->udpInDatagrams); |
| prval("udpInErrors", udp->udpInErrors); |
| prval("udpOutDatagrams", udp->udpOutDatagrams); |
| prval("udpOutErrors", udp->udpOutErrors); |
| prval_end(); |
| } |
| |
| static void |
| print_rawip_stats(mib2_rawip_t *rawip) |
| { |
| prval_init(); |
| prval("rawipInDatagrams", rawip->rawipInDatagrams); |
| prval("rawipInErrors", rawip->rawipInErrors); |
| prval("rawipInCksumErrs", rawip->rawipInCksumErrs); |
| prval("rawipOutDatagrams", rawip->rawipOutDatagrams); |
| prval("rawipOutErrors", rawip->rawipOutErrors); |
| prval_end(); |
| } |
| |
| void |
| print_igmp_stats(struct igmpstat *igps) |
| { |
| (void) printf(" %10u message%s received\n", |
| igps->igps_rcv_total, PLURAL(igps->igps_rcv_total)); |
| (void) printf(" %10u message%s received with too few bytes\n", |
| igps->igps_rcv_tooshort, PLURAL(igps->igps_rcv_tooshort)); |
| (void) printf(" %10u message%s received with bad checksum\n", |
| igps->igps_rcv_badsum, PLURAL(igps->igps_rcv_badsum)); |
| (void) printf(" %10u membership quer%s received\n", |
| igps->igps_rcv_queries, PLURALY(igps->igps_rcv_queries)); |
| (void) printf(" %10u membership quer%s received with invalid " |
| "field(s)\n", |
| igps->igps_rcv_badqueries, PLURALY(igps->igps_rcv_badqueries)); |
| (void) printf(" %10u membership report%s received\n", |
| igps->igps_rcv_reports, PLURAL(igps->igps_rcv_reports)); |
| (void) printf(" %10u membership report%s received with invalid " |
| "field(s)\n", |
| igps->igps_rcv_badreports, PLURAL(igps->igps_rcv_badreports)); |
| (void) printf(" %10u membership report%s received for groups to " |
| "which we belong\n", |
| igps->igps_rcv_ourreports, PLURAL(igps->igps_rcv_ourreports)); |
| (void) printf(" %10u membership report%s sent\n", |
| igps->igps_snd_reports, PLURAL(igps->igps_snd_reports)); |
| } |
| |
| static void |
| print_mrt_stats(struct mrtstat *mrts) |
| { |
| (void) puts("DVMRP multicast routing:"); |
| (void) printf(" %10u hit%s - kernel forwarding cache hits\n", |
| mrts->mrts_mfc_hits, PLURAL(mrts->mrts_mfc_hits)); |
| (void) printf(" %10u miss%s - kernel forwarding cache misses\n", |
| mrts->mrts_mfc_misses, PLURALES(mrts->mrts_mfc_misses)); |
| (void) printf(" %10u packet%s potentially forwarded\n", |
| mrts->mrts_fwd_in, PLURAL(mrts->mrts_fwd_in)); |
| (void) printf(" %10u packet%s actually sent out\n", |
| mrts->mrts_fwd_out, PLURAL(mrts->mrts_fwd_out)); |
| (void) printf(" %10u upcall%s - upcalls made to mrouted\n", |
| mrts->mrts_upcalls, PLURAL(mrts->mrts_upcalls)); |
| (void) printf(" %10u packet%s not sent out due to lack of resources\n", |
| mrts->mrts_fwd_drop, PLURAL(mrts->mrts_fwd_drop)); |
| (void) printf(" %10u datagram%s with malformed tunnel options\n", |
| mrts->mrts_bad_tunnel, PLURAL(mrts->mrts_bad_tunnel)); |
| (void) printf(" %10u datagram%s with no room for tunnel options\n", |
| mrts->mrts_cant_tunnel, PLURAL(mrts->mrts_cant_tunnel)); |
| (void) printf(" %10u datagram%s arrived on wrong interface\n", |
| mrts->mrts_wrong_if, PLURAL(mrts->mrts_wrong_if)); |
| (void) printf(" %10u datagram%s dropped due to upcall Q overflow\n", |
| mrts->mrts_upq_ovflw, PLURAL(mrts->mrts_upq_ovflw)); |
| (void) printf(" %10u datagram%s cleaned up by the cache\n", |
| mrts->mrts_cache_cleanups, PLURAL(mrts->mrts_cache_cleanups)); |
| (void) printf(" %10u datagram%s dropped selectively by ratelimiter\n", |
| mrts->mrts_drop_sel, PLURAL(mrts->mrts_drop_sel)); |
| (void) printf(" %10u datagram%s dropped - bucket Q overflow\n", |
| mrts->mrts_q_overflow, PLURAL(mrts->mrts_q_overflow)); |
| (void) printf(" %10u datagram%s dropped - larger than bkt size\n", |
| mrts->mrts_pkt2large, PLURAL(mrts->mrts_pkt2large)); |
| (void) printf("\nPIM multicast routing:\n"); |
| (void) printf(" %10u datagram%s dropped - bad version number\n", |
| mrts->mrts_pim_badversion, PLURAL(mrts->mrts_pim_badversion)); |
| (void) printf(" %10u datagram%s dropped - bad checksum\n", |
| mrts->mrts_pim_rcv_badcsum, PLURAL(mrts->mrts_pim_rcv_badcsum)); |
| (void) printf(" %10u datagram%s dropped - bad register packets\n", |
| mrts->mrts_pim_badregisters, |
| PLURAL(mrts->mrts_pim_badregisters)); |
| (void) printf( |
| " %10u datagram%s potentially forwarded - register packets\n", |
| mrts->mrts_pim_regforwards, PLURAL(mrts->mrts_pim_regforwards)); |
| (void) printf(" %10u datagram%s dropped - register send drops\n", |
| mrts->mrts_pim_regsend_drops, |
| PLURAL(mrts->mrts_pim_regsend_drops)); |
| (void) printf(" %10u datagram%s dropped - packet malformed\n", |
| mrts->mrts_pim_malformed, PLURAL(mrts->mrts_pim_malformed)); |
| (void) printf(" %10u datagram%s dropped - no memory to forward\n", |
| mrts->mrts_pim_nomemory, PLURAL(mrts->mrts_pim_nomemory)); |
| } |
| |
| static void |
| sum_ip6_stats(mib2_ipv6IfStatsEntry_t *ip6, mib2_ipv6IfStatsEntry_t *sum6) |
| { |
| /* First few are not additive */ |
| sum6->ipv6Forwarding = ip6->ipv6Forwarding; |
| sum6->ipv6DefaultHopLimit = ip6->ipv6DefaultHopLimit; |
| |
| sum6->ipv6InReceives += ip6->ipv6InReceives; |
| sum6->ipv6InHdrErrors += ip6->ipv6InHdrErrors; |
| sum6->ipv6InTooBigErrors += ip6->ipv6InTooBigErrors; |
| sum6->ipv6InNoRoutes += ip6->ipv6InNoRoutes; |
| sum6->ipv6InAddrErrors += ip6->ipv6InAddrErrors; |
| sum6->ipv6InUnknownProtos += ip6->ipv6InUnknownProtos; |
| sum6->ipv6InTruncatedPkts += ip6->ipv6InTruncatedPkts; |
| sum6->ipv6InDiscards += ip6->ipv6InDiscards; |
| sum6->ipv6InDelivers += ip6->ipv6InDelivers; |
| sum6->ipv6OutForwDatagrams += ip6->ipv6OutForwDatagrams; |
| sum6->ipv6OutRequests += ip6->ipv6OutRequests; |
| sum6->ipv6OutDiscards += ip6->ipv6OutDiscards; |
| sum6->ipv6OutFragOKs += ip6->ipv6OutFragOKs; |
| sum6->ipv6OutFragFails += ip6->ipv6OutFragFails; |
| sum6->ipv6OutFragCreates += ip6->ipv6OutFragCreates; |
| sum6->ipv6ReasmReqds += ip6->ipv6ReasmReqds; |
| sum6->ipv6ReasmOKs += ip6->ipv6ReasmOKs; |
| sum6->ipv6ReasmFails += ip6->ipv6ReasmFails; |
| sum6->ipv6InMcastPkts += ip6->ipv6InMcastPkts; |
| sum6->ipv6OutMcastPkts += ip6->ipv6OutMcastPkts; |
| sum6->ipv6OutNoRoutes += ip6->ipv6OutNoRoutes; |
| sum6->ipv6ReasmDuplicates += ip6->ipv6ReasmDuplicates; |
| sum6->ipv6ReasmPartDups += ip6->ipv6ReasmPartDups; |
| sum6->ipv6ForwProhibits += ip6->ipv6ForwProhibits; |
| sum6->udpInCksumErrs += ip6->udpInCksumErrs; |
| sum6->udpInOverflows += ip6->udpInOverflows; |
| sum6->rawipInOverflows += ip6->rawipInOverflows; |
| } |
| |
| static void |
| sum_icmp6_stats(mib2_ipv6IfIcmpEntry_t *icmp6, mib2_ipv6IfIcmpEntry_t *sum6) |
| { |
| sum6->ipv6IfIcmpInMsgs += icmp6->ipv6IfIcmpInMsgs; |
| sum6->ipv6IfIcmpInErrors += icmp6->ipv6IfIcmpInErrors; |
| sum6->ipv6IfIcmpInDestUnreachs += icmp6->ipv6IfIcmpInDestUnreachs; |
| sum6->ipv6IfIcmpInAdminProhibs += icmp6->ipv6IfIcmpInAdminProhibs; |
| sum6->ipv6IfIcmpInTimeExcds += icmp6->ipv6IfIcmpInTimeExcds; |
| sum6->ipv6IfIcmpInParmProblems += icmp6->ipv6IfIcmpInParmProblems; |
| sum6->ipv6IfIcmpInPktTooBigs += icmp6->ipv6IfIcmpInPktTooBigs; |
| sum6->ipv6IfIcmpInEchos += icmp6->ipv6IfIcmpInEchos; |
| sum6->ipv6IfIcmpInEchoReplies += icmp6->ipv6IfIcmpInEchoReplies; |
| sum6->ipv6IfIcmpInRouterSolicits += icmp6->ipv6IfIcmpInRouterSolicits; |
| sum6->ipv6IfIcmpInRouterAdvertisements += |
| icmp6->ipv6IfIcmpInRouterAdvertisements; |
| sum6->ipv6IfIcmpInNeighborSolicits += |
| icmp6->ipv6IfIcmpInNeighborSolicits; |
| sum6->ipv6IfIcmpInNeighborAdvertisements += |
| icmp6->ipv6IfIcmpInNeighborAdvertisements; |
| sum6->ipv6IfIcmpInRedirects += icmp6->ipv6IfIcmpInRedirects; |
| sum6->ipv6IfIcmpInGroupMembQueries += |
| icmp6->ipv6IfIcmpInGroupMembQueries; |
| sum6->ipv6IfIcmpInGroupMembResponses += |
| icmp6->ipv6IfIcmpInGroupMembResponses; |
| sum6->ipv6IfIcmpInGroupMembReductions += |
| icmp6->ipv6IfIcmpInGroupMembReductions; |
| sum6->ipv6IfIcmpOutMsgs += icmp6->ipv6IfIcmpOutMsgs; |
| sum6->ipv6IfIcmpOutErrors += icmp6->ipv6IfIcmpOutErrors; |
| sum6->ipv6IfIcmpOutDestUnreachs += icmp6->ipv6IfIcmpOutDestUnreachs; |
| sum6->ipv6IfIcmpOutAdminProhibs += icmp6->ipv6IfIcmpOutAdminProhibs; |
| sum6->ipv6IfIcmpOutTimeExcds += icmp6->ipv6IfIcmpOutTimeExcds; |
| sum6->ipv6IfIcmpOutParmProblems += icmp6->ipv6IfIcmpOutParmProblems; |
| sum6->ipv6IfIcmpOutPktTooBigs += icmp6->ipv6IfIcmpOutPktTooBigs; |
| sum6->ipv6IfIcmpOutEchos += icmp6->ipv6IfIcmpOutEchos; |
| sum6->ipv6IfIcmpOutEchoReplies += icmp6->ipv6IfIcmpOutEchoReplies; |
| sum6->ipv6IfIcmpOutRouterSolicits += |
| icmp6->ipv6IfIcmpOutRouterSolicits; |
| sum6->ipv6IfIcmpOutRouterAdvertisements += |
| icmp6->ipv6IfIcmpOutRouterAdvertisements; |
| sum6->ipv6IfIcmpOutNeighborSolicits += |
| icmp6->ipv6IfIcmpOutNeighborSolicits; |
| sum6->ipv6IfIcmpOutNeighborAdvertisements += |
| icmp6->ipv6IfIcmpOutNeighborAdvertisements; |
| sum6->ipv6IfIcmpOutRedirects += icmp6->ipv6IfIcmpOutRedirects; |
| sum6->ipv6IfIcmpOutGroupMembQueries += |
| icmp6->ipv6IfIcmpOutGroupMembQueries; |
|