17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
545916cd2Sjpk * Common Development and Distribution License (the "License").
645916cd2Sjpk * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
22550b6e40SSowmini Varadhan * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate * Copyright (c) 1990 Mentat Inc.
247c478bd9Sstevel@tonic-gate * netstat.c 2.2, last change 9/9/91
257c478bd9Sstevel@tonic-gate * MROUTING Revision 3.5
26d38b7101SDan McDonald * Copyright 2018, Joyent, Inc.
27a02120c4SAndy Fiddaman * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
28*cdfd7f6bSJason King * Copyright 2021 Racktop Systems, Inc.
297c478bd9Sstevel@tonic-gate */
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate /*
327c478bd9Sstevel@tonic-gate * simple netstat based on snmp/mib-2 interface to the TCP/IP stack
337c478bd9Sstevel@tonic-gate *
347c478bd9Sstevel@tonic-gate * TODO:
357c478bd9Sstevel@tonic-gate * Add ability to request subsets from kernel (with level = MIB2_IP;
367c478bd9Sstevel@tonic-gate * name = 0 meaning everything for compatibility)
377c478bd9Sstevel@tonic-gate */
387c478bd9Sstevel@tonic-gate
397c478bd9Sstevel@tonic-gate #include <stdio.h>
407c478bd9Sstevel@tonic-gate #include <stdlib.h>
417c478bd9Sstevel@tonic-gate #include <stdarg.h>
427c478bd9Sstevel@tonic-gate #include <unistd.h>
437c478bd9Sstevel@tonic-gate #include <strings.h>
447c478bd9Sstevel@tonic-gate #include <string.h>
457c478bd9Sstevel@tonic-gate #include <errno.h>
467c478bd9Sstevel@tonic-gate #include <ctype.h>
477c478bd9Sstevel@tonic-gate #include <kstat.h>
487c478bd9Sstevel@tonic-gate #include <assert.h>
4926fd7700SKrishnendu Sadhukhan - Sun Microsystems #include <locale.h>
50afee3dc6SRobert Mustacchi #include <synch.h>
51afee3dc6SRobert Mustacchi #include <thread.h>
5278a2e113SAndy Fiddaman #include <pwd.h>
5378a2e113SAndy Fiddaman #include <limits.h>
5478a2e113SAndy Fiddaman #include <sys/ccompile.h>
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate #include <sys/types.h>
5778a2e113SAndy Fiddaman #include <sys/stat.h>
587c478bd9Sstevel@tonic-gate #include <sys/stream.h>
597c478bd9Sstevel@tonic-gate #include <stropts.h>
607c478bd9Sstevel@tonic-gate #include <sys/strstat.h>
617c478bd9Sstevel@tonic-gate #include <sys/tihdr.h>
6278a2e113SAndy Fiddaman #include <procfs.h>
6378a2e113SAndy Fiddaman #include <dirent.h>
647c478bd9Sstevel@tonic-gate
657c478bd9Sstevel@tonic-gate #include <sys/socket.h>
6678a2e113SAndy Fiddaman #include <sys/socketvar.h>
677c478bd9Sstevel@tonic-gate #include <sys/sockio.h>
687c478bd9Sstevel@tonic-gate #include <netinet/in.h>
697c478bd9Sstevel@tonic-gate #include <net/if.h>
707c478bd9Sstevel@tonic-gate #include <net/route.h>
717c478bd9Sstevel@tonic-gate
727c478bd9Sstevel@tonic-gate #include <inet/mib2.h>
737c478bd9Sstevel@tonic-gate #include <inet/ip.h>
747c478bd9Sstevel@tonic-gate #include <inet/arp.h>
757c478bd9Sstevel@tonic-gate #include <inet/tcp.h>
767c478bd9Sstevel@tonic-gate #include <netinet/igmp_var.h>
777c478bd9Sstevel@tonic-gate #include <netinet/ip_mroute.h>
787c478bd9Sstevel@tonic-gate
797c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
807c478bd9Sstevel@tonic-gate #include <netdb.h>
817c478bd9Sstevel@tonic-gate #include <fcntl.h>
827c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h>
837c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
847c478bd9Sstevel@tonic-gate
857c478bd9Sstevel@tonic-gate #include <netinet/dhcp.h>
867c478bd9Sstevel@tonic-gate #include <dhcpagent_ipc.h>
877c478bd9Sstevel@tonic-gate #include <dhcpagent_util.h>
887c478bd9Sstevel@tonic-gate #include <compat.h>
8978a2e113SAndy Fiddaman #include <sys/mkdev.h>
907c478bd9Sstevel@tonic-gate
9145916cd2Sjpk #include <libtsnet.h>
9245916cd2Sjpk #include <tsol/label.h>
9345916cd2Sjpk
9478a2e113SAndy Fiddaman #include <libproc.h>
9526fd7700SKrishnendu Sadhukhan - Sun Microsystems
9678a2e113SAndy Fiddaman #include "statcommon.h"
977c478bd9Sstevel@tonic-gate
987c478bd9Sstevel@tonic-gate #define STR_EXPAND 4
997c478bd9Sstevel@tonic-gate
1007c478bd9Sstevel@tonic-gate #define V4MASK_TO_V6(v4, v6) ((v6)._S6_un._S6_u32[0] = 0xfffffffful, \
1017c478bd9Sstevel@tonic-gate (v6)._S6_un._S6_u32[1] = 0xfffffffful, \
1027c478bd9Sstevel@tonic-gate (v6)._S6_un._S6_u32[2] = 0xfffffffful, \
1037c478bd9Sstevel@tonic-gate (v6)._S6_un._S6_u32[3] = (v4))
1047c478bd9Sstevel@tonic-gate
1057c478bd9Sstevel@tonic-gate #define IN6_IS_V4MASK(v6) ((v6)._S6_un._S6_u32[0] == 0xfffffffful && \
1067c478bd9Sstevel@tonic-gate (v6)._S6_un._S6_u32[1] == 0xfffffffful && \
1077c478bd9Sstevel@tonic-gate (v6)._S6_un._S6_u32[2] == 0xfffffffful)
1087c478bd9Sstevel@tonic-gate
109d04ccbb3Scarlsonj /*
110d04ccbb3Scarlsonj * This is used as a cushion in the buffer allocation directed by SIOCGLIFNUM.
111d04ccbb3Scarlsonj * Because there's no locking between SIOCGLIFNUM and SIOCGLIFCONF, it's
112d04ccbb3Scarlsonj * possible for an administrator to plumb new interfaces between those two
113d04ccbb3Scarlsonj * calls, resulting in the failure of the latter. This addition makes that
114d04ccbb3Scarlsonj * less likely.
115d04ccbb3Scarlsonj */
116d04ccbb3Scarlsonj #define LIFN_GUARD_VALUE 10
117d04ccbb3Scarlsonj
1187c478bd9Sstevel@tonic-gate typedef struct mib_item_s {
1197c478bd9Sstevel@tonic-gate struct mib_item_s *next_item;
1207c478bd9Sstevel@tonic-gate int group;
1217c478bd9Sstevel@tonic-gate int mib_id;
1227c478bd9Sstevel@tonic-gate int length;
1237c478bd9Sstevel@tonic-gate void *valp;
1247c478bd9Sstevel@tonic-gate } mib_item_t;
1257c478bd9Sstevel@tonic-gate
1267c478bd9Sstevel@tonic-gate struct ifstat {
1277c478bd9Sstevel@tonic-gate uint64_t ipackets;
1287c478bd9Sstevel@tonic-gate uint64_t ierrors;
1297c478bd9Sstevel@tonic-gate uint64_t opackets;
1307c478bd9Sstevel@tonic-gate uint64_t oerrors;
1317c478bd9Sstevel@tonic-gate uint64_t collisions;
1327c478bd9Sstevel@tonic-gate };
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate struct iflist {
1357c478bd9Sstevel@tonic-gate struct iflist *next_if;
1367c478bd9Sstevel@tonic-gate char ifname[LIFNAMSIZ];
1377c478bd9Sstevel@tonic-gate struct ifstat tot;
1387c478bd9Sstevel@tonic-gate };
1397c478bd9Sstevel@tonic-gate
14078a2e113SAndy Fiddaman static void fatal(int, char *, ...) __NORETURN;
14178a2e113SAndy Fiddaman
1427c478bd9Sstevel@tonic-gate static mib_item_t *mibget(int sd);
1437c478bd9Sstevel@tonic-gate static void mibfree(mib_item_t *firstitem);
1447c478bd9Sstevel@tonic-gate static int mibopen(void);
1457c478bd9Sstevel@tonic-gate static void mib_get_constants(mib_item_t *item);
1467c478bd9Sstevel@tonic-gate static mib_item_t *mib_item_dup(mib_item_t *item);
14778a2e113SAndy Fiddaman static mib_item_t *mib_item_diff(mib_item_t *item1, mib_item_t *item2);
1487c478bd9Sstevel@tonic-gate static void mib_item_destroy(mib_item_t **item);
1497c478bd9Sstevel@tonic-gate
1507c478bd9Sstevel@tonic-gate static boolean_t octetstrmatch(const Octet_t *a, const Octet_t *b);
15145916cd2Sjpk static char *octetstr(const Octet_t *op, int code,
1527c478bd9Sstevel@tonic-gate char *dst, uint_t dstlen);
15378a2e113SAndy Fiddaman static char *pr_addr(uint_t addr, char *dst, uint_t dstlen);
1547c478bd9Sstevel@tonic-gate static char *pr_addrnz(ipaddr_t addr, char *dst, uint_t dstlen);
1557c478bd9Sstevel@tonic-gate static char *pr_addr6(const in6_addr_t *addr,
1567c478bd9Sstevel@tonic-gate char *dst, uint_t dstlen);
15778a2e113SAndy Fiddaman static char *pr_mask(uint_t addr, char *dst, uint_t dstlen);
15845916cd2Sjpk static char *pr_prefix6(const struct in6_addr *addr,
15945916cd2Sjpk uint_t prefixlen, char *dst, uint_t dstlen);
1607c478bd9Sstevel@tonic-gate static char *pr_ap(uint_t addr, uint_t port,
1617c478bd9Sstevel@tonic-gate char *proto, char *dst, uint_t dstlen);
1627c478bd9Sstevel@tonic-gate static char *pr_ap6(const in6_addr_t *addr, uint_t port,
1637c478bd9Sstevel@tonic-gate char *proto, char *dst, uint_t dstlen);
1647c478bd9Sstevel@tonic-gate static char *pr_net(uint_t addr, uint_t mask,
1657c478bd9Sstevel@tonic-gate char *dst, uint_t dstlen);
1667c478bd9Sstevel@tonic-gate static char *pr_netaddr(uint_t addr, uint_t mask,
1677c478bd9Sstevel@tonic-gate char *dst, uint_t dstlen);
1687c478bd9Sstevel@tonic-gate static char *fmodestr(uint_t fmode);
1697c478bd9Sstevel@tonic-gate static char *portname(uint_t port, char *proto,
1707c478bd9Sstevel@tonic-gate char *dst, uint_t dstlen);
1717c478bd9Sstevel@tonic-gate
17245916cd2Sjpk static const char *mitcp_state(int code,
17345916cd2Sjpk const mib2_transportMLPEntry_t *attr);
17445916cd2Sjpk static const char *miudp_state(int code,
17545916cd2Sjpk const mib2_transportMLPEntry_t *attr);
1767c478bd9Sstevel@tonic-gate
1777c478bd9Sstevel@tonic-gate static void stat_report(mib_item_t *item);
1787c478bd9Sstevel@tonic-gate static void mrt_stat_report(mib_item_t *item);
1797c478bd9Sstevel@tonic-gate static void arp_report(mib_item_t *item);
1807c478bd9Sstevel@tonic-gate static void ndp_report(mib_item_t *item);
1817c478bd9Sstevel@tonic-gate static void mrt_report(mib_item_t *item);
1827c478bd9Sstevel@tonic-gate static void if_stat_total(struct ifstat *oldstats,
1837c478bd9Sstevel@tonic-gate struct ifstat *newstats, struct ifstat *sumstats);
1847c478bd9Sstevel@tonic-gate static void if_report(mib_item_t *item, char *ifname,
1857c478bd9Sstevel@tonic-gate int Iflag_only, boolean_t once_only);
1867c478bd9Sstevel@tonic-gate static void if_report_ip4(mib2_ipAddrEntry_t *ap,
1877c478bd9Sstevel@tonic-gate char ifname[], char logintname[],
1887c478bd9Sstevel@tonic-gate struct ifstat *statptr, boolean_t ksp_not_null);
1897c478bd9Sstevel@tonic-gate static void if_report_ip6(mib2_ipv6AddrEntry_t *ap6,
1907c478bd9Sstevel@tonic-gate char ifname[], char logintname[],
1917c478bd9Sstevel@tonic-gate struct ifstat *statptr, boolean_t ksp_not_null);
19245916cd2Sjpk static void ire_report(const mib_item_t *item);
19345916cd2Sjpk static void tcp_report(const mib_item_t *item);
19445916cd2Sjpk static void udp_report(const mib_item_t *item);
19578a2e113SAndy Fiddaman static void uds_report(kstat_ctl_t *);
1967c478bd9Sstevel@tonic-gate static void group_report(mib_item_t *item);
197bd670b35SErik Nordmark static void dce_report(mib_item_t *item);
1987c478bd9Sstevel@tonic-gate static void print_ip_stats(mib2_ip_t *ip);
1997c478bd9Sstevel@tonic-gate static void print_icmp_stats(mib2_icmp_t *icmp);
2007c478bd9Sstevel@tonic-gate static void print_ip6_stats(mib2_ipv6IfStatsEntry_t *ip6);
2017c478bd9Sstevel@tonic-gate static void print_icmp6_stats(mib2_ipv6IfIcmpEntry_t *icmp6);
2027c478bd9Sstevel@tonic-gate static void print_sctp_stats(mib2_sctp_t *tcp);
2037c478bd9Sstevel@tonic-gate static void print_tcp_stats(mib2_tcp_t *tcp);
2047c478bd9Sstevel@tonic-gate static void print_udp_stats(mib2_udp_t *udp);
2057c478bd9Sstevel@tonic-gate static void print_rawip_stats(mib2_rawip_t *rawip);
2067c478bd9Sstevel@tonic-gate static void print_igmp_stats(struct igmpstat *igps);
2077c478bd9Sstevel@tonic-gate static void print_mrt_stats(struct mrtstat *mrts);
20845916cd2Sjpk static void sctp_report(const mib_item_t *item);
2097c478bd9Sstevel@tonic-gate static void sum_ip6_stats(mib2_ipv6IfStatsEntry_t *ip6,
2107c478bd9Sstevel@tonic-gate mib2_ipv6IfStatsEntry_t *sum6);
2117c478bd9Sstevel@tonic-gate static void sum_icmp6_stats(mib2_ipv6IfIcmpEntry_t *icmp6,
2127c478bd9Sstevel@tonic-gate mib2_ipv6IfIcmpEntry_t *sum6);
2137c478bd9Sstevel@tonic-gate static void m_report(void);
2147c478bd9Sstevel@tonic-gate static void dhcp_report(char *);
2157c478bd9Sstevel@tonic-gate
2167c478bd9Sstevel@tonic-gate static uint64_t kstat_named_value(kstat_t *, char *);
2177c478bd9Sstevel@tonic-gate static kid_t safe_kstat_read(kstat_ctl_t *, kstat_t *, void *);
2187c478bd9Sstevel@tonic-gate static int isnum(char *);
2197c478bd9Sstevel@tonic-gate static char *plural(int n);
2207c478bd9Sstevel@tonic-gate static char *pluraly(int n);
2217c478bd9Sstevel@tonic-gate static char *plurales(int n);
2227c478bd9Sstevel@tonic-gate static void process_filter(char *arg);
223e11c3f44Smeem static char *ifindex2str(uint_t, char *);
2247c478bd9Sstevel@tonic-gate static boolean_t family_selected(int family);
2257c478bd9Sstevel@tonic-gate
2267c478bd9Sstevel@tonic-gate static void usage(char *);
22778a2e113SAndy Fiddaman static char *get_username(uid_t);
22878a2e113SAndy Fiddaman
22978a2e113SAndy Fiddaman static void process_hash_build(void);
23078a2e113SAndy Fiddaman static void process_hash_free(void);
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gate #define PLURAL(n) plural((int)n)
2337c478bd9Sstevel@tonic-gate #define PLURALY(n) pluraly((int)n)
2347c478bd9Sstevel@tonic-gate #define PLURALES(n) plurales((int)n)
2357c478bd9Sstevel@tonic-gate #define IFLAGMOD(flg, val1, val2) if (flg == val1) flg = val2
2367c478bd9Sstevel@tonic-gate #define MDIFF(diff, elem2, elem1, member) (diff)->member = \
2377c478bd9Sstevel@tonic-gate (elem2)->member - (elem1)->member
2387c478bd9Sstevel@tonic-gate
2397c478bd9Sstevel@tonic-gate static boolean_t Aflag = B_FALSE; /* All sockets/ifs/rtng-tbls */
240d38b7101SDan McDonald static boolean_t CIDRflag = B_FALSE; /* CIDR for IPv4 -i/-r addrs */
241bd670b35SErik Nordmark static boolean_t Dflag = B_FALSE; /* DCE info */
2427c478bd9Sstevel@tonic-gate static boolean_t Iflag = B_FALSE; /* IP Traffic Interfaces */
2437c478bd9Sstevel@tonic-gate static boolean_t Mflag = B_FALSE; /* STREAMS Memory Statistics */
2447c478bd9Sstevel@tonic-gate static boolean_t Nflag = B_FALSE; /* Numeric Network Addresses */
2457c478bd9Sstevel@tonic-gate static boolean_t Rflag = B_FALSE; /* Routing Tables */
24645916cd2Sjpk static boolean_t RSECflag = B_FALSE; /* Security attributes */
2477c478bd9Sstevel@tonic-gate static boolean_t Sflag = B_FALSE; /* Per-protocol Statistics */
2487c478bd9Sstevel@tonic-gate static boolean_t Vflag = B_FALSE; /* Verbose */
24978a2e113SAndy Fiddaman static boolean_t Uflag = B_FALSE; /* Show PID and UID info. */
2507c478bd9Sstevel@tonic-gate static boolean_t Pflag = B_FALSE; /* Net to Media Tables */
2517c478bd9Sstevel@tonic-gate static boolean_t Gflag = B_FALSE; /* Multicast group membership */
2527c478bd9Sstevel@tonic-gate static boolean_t MMflag = B_FALSE; /* Multicast routing table */
2537c478bd9Sstevel@tonic-gate static boolean_t DHCPflag = B_FALSE; /* DHCP statistics */
254bd670b35SErik Nordmark static boolean_t Xflag = B_FALSE; /* Debug Info */
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate static int v4compat = 0; /* Compatible printing format for status */
2577c478bd9Sstevel@tonic-gate
2587c478bd9Sstevel@tonic-gate static int proto = IPPROTO_MAX; /* all protocols */
2597c478bd9Sstevel@tonic-gate kstat_ctl_t *kc = NULL;
2607c478bd9Sstevel@tonic-gate
261afee3dc6SRobert Mustacchi /*
262afee3dc6SRobert Mustacchi * Name service timeout detection constants.
263afee3dc6SRobert Mustacchi */
264afee3dc6SRobert Mustacchi static mutex_t ns_lock = ERRORCHECKMUTEX;
265afee3dc6SRobert Mustacchi static boolean_t ns_active = B_FALSE; /* Is a lookup ongoing? */
266afee3dc6SRobert Mustacchi static hrtime_t ns_starttime; /* Time the lookup started */
267afee3dc6SRobert Mustacchi static int ns_sleeptime = 2; /* Time in seconds between checks */
268afee3dc6SRobert Mustacchi static int ns_warntime = 2; /* Time in seconds before warning */
269afee3dc6SRobert Mustacchi
2707c478bd9Sstevel@tonic-gate /*
2717c478bd9Sstevel@tonic-gate * Sizes of data structures extracted from the base mib.
2727c478bd9Sstevel@tonic-gate * This allows the size of the tables entries to grow while preserving
2737c478bd9Sstevel@tonic-gate * binary compatibility.
2747c478bd9Sstevel@tonic-gate */
2757c478bd9Sstevel@tonic-gate static int ipAddrEntrySize;
2767c478bd9Sstevel@tonic-gate static int ipRouteEntrySize;
2777c478bd9Sstevel@tonic-gate static int ipNetToMediaEntrySize;
2787c478bd9Sstevel@tonic-gate static int ipMemberEntrySize;
2797c478bd9Sstevel@tonic-gate static int ipGroupSourceEntrySize;
28045916cd2Sjpk static int ipRouteAttributeSize;
2817c478bd9Sstevel@tonic-gate static int vifctlSize;
2827c478bd9Sstevel@tonic-gate static int mfcctlSize;
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gate static int ipv6IfStatsEntrySize;
2857c478bd9Sstevel@tonic-gate static int ipv6IfIcmpEntrySize;
2867c478bd9Sstevel@tonic-gate static int ipv6AddrEntrySize;
2877c478bd9Sstevel@tonic-gate static int ipv6RouteEntrySize;
2887c478bd9Sstevel@tonic-gate static int ipv6NetToMediaEntrySize;
2897c478bd9Sstevel@tonic-gate static int ipv6MemberEntrySize;
2907c478bd9Sstevel@tonic-gate static int ipv6GroupSourceEntrySize;
2917c478bd9Sstevel@tonic-gate
292bd670b35SErik Nordmark static int ipDestEntrySize;
293bd670b35SErik Nordmark
29445916cd2Sjpk static int transportMLPSize;
2957c478bd9Sstevel@tonic-gate static int tcpConnEntrySize;
2967c478bd9Sstevel@tonic-gate static int tcp6ConnEntrySize;
2977c478bd9Sstevel@tonic-gate static int udpEntrySize;
2987c478bd9Sstevel@tonic-gate static int udp6EntrySize;
2997c478bd9Sstevel@tonic-gate static int sctpEntrySize;
3007c478bd9Sstevel@tonic-gate static int sctpLocalEntrySize;
3017c478bd9Sstevel@tonic-gate static int sctpRemoteEntrySize;
3027c478bd9Sstevel@tonic-gate
3037c478bd9Sstevel@tonic-gate #define protocol_selected(p) (proto == IPPROTO_MAX || proto == (p))
3047c478bd9Sstevel@tonic-gate
3057c478bd9Sstevel@tonic-gate /* Machinery used for -f (filter) option */
3065c0b7edeSseb enum { FK_AF = 0, FK_OUTIF, FK_DST, FK_FLAGS, NFILTERKEYS };
3077c478bd9Sstevel@tonic-gate
3087c478bd9Sstevel@tonic-gate static const char *filter_keys[NFILTERKEYS] = {
3095c0b7edeSseb "af", "outif", "dst", "flags"
3107c478bd9Sstevel@tonic-gate };
3117c478bd9Sstevel@tonic-gate
3125f9878b0Sken Powell - Sun Microsystem static m_label_t *zone_security_label = NULL;
3135f9878b0Sken Powell - Sun Microsystem
3147c478bd9Sstevel@tonic-gate /* Flags on routes */
3157c478bd9Sstevel@tonic-gate #define FLF_A 0x00000001
316bd670b35SErik Nordmark #define FLF_b 0x00000002
3177c478bd9Sstevel@tonic-gate #define FLF_D 0x00000004
3187c478bd9Sstevel@tonic-gate #define FLF_G 0x00000008
3197c478bd9Sstevel@tonic-gate #define FLF_H 0x00000010
3207c478bd9Sstevel@tonic-gate #define FLF_L 0x00000020
3217c478bd9Sstevel@tonic-gate #define FLF_U 0x00000040
3227c478bd9Sstevel@tonic-gate #define FLF_M 0x00000080
3237c478bd9Sstevel@tonic-gate #define FLF_S 0x00000100
324bd670b35SErik Nordmark #define FLF_C 0x00000200 /* IRE_IF_CLONE */
325bd670b35SErik Nordmark #define FLF_I 0x00000400 /* RTF_INDIRECT */
326bd670b35SErik Nordmark #define FLF_R 0x00000800 /* RTF_REJECT */
327bd670b35SErik Nordmark #define FLF_B 0x00001000 /* RTF_BLACKHOLE */
328550b6e40SSowmini Varadhan #define FLF_Z 0x00100000 /* RTF_ZONE */
329bd670b35SErik Nordmark
330550b6e40SSowmini Varadhan static const char flag_list[] = "AbDGHLUMSCIRBZ";
3317c478bd9Sstevel@tonic-gate
3327c478bd9Sstevel@tonic-gate typedef struct filter_rule filter_t;
3337c478bd9Sstevel@tonic-gate
3347c478bd9Sstevel@tonic-gate struct filter_rule {
3357c478bd9Sstevel@tonic-gate filter_t *f_next;
3367c478bd9Sstevel@tonic-gate union {
3377c478bd9Sstevel@tonic-gate int f_family;
3387c478bd9Sstevel@tonic-gate const char *f_ifname;
3397c478bd9Sstevel@tonic-gate struct {
3407c478bd9Sstevel@tonic-gate struct hostent *f_address;
3417c478bd9Sstevel@tonic-gate in6_addr_t f_mask;
3427c478bd9Sstevel@tonic-gate } a;
3437c478bd9Sstevel@tonic-gate struct {
3447c478bd9Sstevel@tonic-gate uint_t f_flagset;
3457c478bd9Sstevel@tonic-gate uint_t f_flagclear;
3467c478bd9Sstevel@tonic-gate } f;
3477c478bd9Sstevel@tonic-gate } u;
3487c478bd9Sstevel@tonic-gate };
3497c478bd9Sstevel@tonic-gate
3507c478bd9Sstevel@tonic-gate /*
3517c478bd9Sstevel@tonic-gate * The user-specified filters are linked into lists separated by
3527c478bd9Sstevel@tonic-gate * keyword (type of filter). Thus, the matching algorithm is:
3537c478bd9Sstevel@tonic-gate * For each non-empty filter list
3547c478bd9Sstevel@tonic-gate * If no filters in the list match
3557c478bd9Sstevel@tonic-gate * then stop here; route doesn't match
3567c478bd9Sstevel@tonic-gate * If loop above completes, then route does match and will be
3577c478bd9Sstevel@tonic-gate * displayed.
3587c478bd9Sstevel@tonic-gate */
3597c478bd9Sstevel@tonic-gate static filter_t *filters[NFILTERKEYS];
3607c478bd9Sstevel@tonic-gate
36126fd7700SKrishnendu Sadhukhan - Sun Microsystems static uint_t timestamp_fmt = NODATE;
36226fd7700SKrishnendu Sadhukhan - Sun Microsystems
36326fd7700SKrishnendu Sadhukhan - Sun Microsystems #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
36426fd7700SKrishnendu Sadhukhan - Sun Microsystems #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't */
36526fd7700SKrishnendu Sadhukhan - Sun Microsystems #endif
36626fd7700SKrishnendu Sadhukhan - Sun Microsystems
367afee3dc6SRobert Mustacchi static void
ns_lookup_start(void)368afee3dc6SRobert Mustacchi ns_lookup_start(void)
369afee3dc6SRobert Mustacchi {
370afee3dc6SRobert Mustacchi mutex_enter(&ns_lock);
371afee3dc6SRobert Mustacchi ns_active = B_TRUE;
372afee3dc6SRobert Mustacchi ns_starttime = gethrtime();
373afee3dc6SRobert Mustacchi mutex_exit(&ns_lock);
374afee3dc6SRobert Mustacchi }
375afee3dc6SRobert Mustacchi
376afee3dc6SRobert Mustacchi static void
ns_lookup_end(void)377afee3dc6SRobert Mustacchi ns_lookup_end(void)
378afee3dc6SRobert Mustacchi {
379afee3dc6SRobert Mustacchi mutex_enter(&ns_lock);
380afee3dc6SRobert Mustacchi ns_active = B_FALSE;
381afee3dc6SRobert Mustacchi mutex_exit(&ns_lock);
382afee3dc6SRobert Mustacchi }
383afee3dc6SRobert Mustacchi
384afee3dc6SRobert Mustacchi /*
385afee3dc6SRobert Mustacchi * When name services are not functioning, this program appears to hang to the
386afee3dc6SRobert Mustacchi * user. To try and give the user a chance of figuring out that this might be
387afee3dc6SRobert Mustacchi * the case, we end up warning them and suggest that they may want to use the -n
388afee3dc6SRobert Mustacchi * flag.
389afee3dc6SRobert Mustacchi */
390afee3dc6SRobert Mustacchi /* ARGSUSED */
391afee3dc6SRobert Mustacchi static void *
ns_warning_thr(void * unsued)392afee3dc6SRobert Mustacchi ns_warning_thr(void *unsued)
393afee3dc6SRobert Mustacchi {
394afee3dc6SRobert Mustacchi for (;;) {
395afee3dc6SRobert Mustacchi hrtime_t now;
396afee3dc6SRobert Mustacchi
397afee3dc6SRobert Mustacchi (void) sleep(ns_sleeptime);
398afee3dc6SRobert Mustacchi now = gethrtime();
399afee3dc6SRobert Mustacchi mutex_enter(&ns_lock);
400afee3dc6SRobert Mustacchi if (ns_active && now - ns_starttime >= ns_warntime * NANOSEC) {
401afee3dc6SRobert Mustacchi (void) fprintf(stderr, "warning: data "
402afee3dc6SRobert Mustacchi "available, but name service lookups are "
403afee3dc6SRobert Mustacchi "taking a while. Use the -n option to "
404afee3dc6SRobert Mustacchi "disable name service lookups.\n");
405afee3dc6SRobert Mustacchi mutex_exit(&ns_lock);
406afee3dc6SRobert Mustacchi return (NULL);
407afee3dc6SRobert Mustacchi }
408afee3dc6SRobert Mustacchi mutex_exit(&ns_lock);
409afee3dc6SRobert Mustacchi }
410afee3dc6SRobert Mustacchi
411afee3dc6SRobert Mustacchi return (NULL);
412afee3dc6SRobert Mustacchi }
413afee3dc6SRobert Mustacchi
4147c478bd9Sstevel@tonic-gate int
main(int argc,char ** argv)4157c478bd9Sstevel@tonic-gate main(int argc, char **argv)
4167c478bd9Sstevel@tonic-gate {
4177c478bd9Sstevel@tonic-gate char *name;
4187c478bd9Sstevel@tonic-gate mib_item_t *item = NULL;
4197c478bd9Sstevel@tonic-gate mib_item_t *previtem = NULL;
4207c478bd9Sstevel@tonic-gate int sd = -1;
4217c478bd9Sstevel@tonic-gate char *ifname = NULL;
4227c478bd9Sstevel@tonic-gate int interval = 0; /* Single time by default */
4237c478bd9Sstevel@tonic-gate int count = -1; /* Forever */
4247c478bd9Sstevel@tonic-gate int c;
4257c478bd9Sstevel@tonic-gate int d;
4267c478bd9Sstevel@tonic-gate /*
4277c478bd9Sstevel@tonic-gate * Possible values of 'Iflag_only':
4287c478bd9Sstevel@tonic-gate * -1, no feature-flags;
4297c478bd9Sstevel@tonic-gate * 0, IFlag and other feature-flags enabled
4307c478bd9Sstevel@tonic-gate * 1, IFlag is the only feature-flag enabled
4317c478bd9Sstevel@tonic-gate * : trinary variable, modified using IFLAGMOD()
4327c478bd9Sstevel@tonic-gate */
4337c478bd9Sstevel@tonic-gate int Iflag_only = -1;
4347c478bd9Sstevel@tonic-gate boolean_t once_only = B_FALSE; /* '-i' with count > 1 */
4357c478bd9Sstevel@tonic-gate extern char *optarg;
4367c478bd9Sstevel@tonic-gate extern int optind;
4377c478bd9Sstevel@tonic-gate char *default_ip_str = NULL;
4387c478bd9Sstevel@tonic-gate
4397c478bd9Sstevel@tonic-gate name = argv[0];
4407c478bd9Sstevel@tonic-gate
4417c478bd9Sstevel@tonic-gate v4compat = get_compat_flag(&default_ip_str);
4427c478bd9Sstevel@tonic-gate if (v4compat == DEFAULT_PROT_BAD_VALUE)
4437c478bd9Sstevel@tonic-gate fatal(2, "%s: %s: Bad value for %s in %s\n", name,
4447c478bd9Sstevel@tonic-gate default_ip_str, DEFAULT_IP, INET_DEFAULT_FILE);
4457c478bd9Sstevel@tonic-gate free(default_ip_str);
4467c478bd9Sstevel@tonic-gate
44726fd7700SKrishnendu Sadhukhan - Sun Microsystems (void) setlocale(LC_ALL, "");
44826fd7700SKrishnendu Sadhukhan - Sun Microsystems (void) textdomain(TEXT_DOMAIN);
44926fd7700SKrishnendu Sadhukhan - Sun Microsystems
45078a2e113SAndy Fiddaman while ((c = getopt(argc, argv, "acdimnrspMguvxf:P:I:DRT:")) != -1) {
4517c478bd9Sstevel@tonic-gate switch ((char)c) {
4527c478bd9Sstevel@tonic-gate case 'a': /* all connections */
4537c478bd9Sstevel@tonic-gate Aflag = B_TRUE;
4547c478bd9Sstevel@tonic-gate break;
4557c478bd9Sstevel@tonic-gate
456d38b7101SDan McDonald case 'c':
457d38b7101SDan McDonald CIDRflag = B_TRUE;
458d38b7101SDan McDonald break;
459d38b7101SDan McDonald
460bd670b35SErik Nordmark case 'd': /* DCE info */
4617c478bd9Sstevel@tonic-gate Dflag = B_TRUE;
462bd670b35SErik Nordmark IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
4637c478bd9Sstevel@tonic-gate break;
4647c478bd9Sstevel@tonic-gate
4657c478bd9Sstevel@tonic-gate case 'i': /* interface (ill/ipif report) */
4667c478bd9Sstevel@tonic-gate Iflag = B_TRUE;
4677c478bd9Sstevel@tonic-gate IFLAGMOD(Iflag_only, -1, 1); /* '-i' exists */
4687c478bd9Sstevel@tonic-gate break;
4697c478bd9Sstevel@tonic-gate
4707c478bd9Sstevel@tonic-gate case 'm': /* streams msg report */
4717c478bd9Sstevel@tonic-gate Mflag = B_TRUE;
4727c478bd9Sstevel@tonic-gate IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
4737c478bd9Sstevel@tonic-gate break;
4747c478bd9Sstevel@tonic-gate
4757c478bd9Sstevel@tonic-gate case 'n': /* numeric format */
4767c478bd9Sstevel@tonic-gate Nflag = B_TRUE;
4777c478bd9Sstevel@tonic-gate break;
4787c478bd9Sstevel@tonic-gate
4797c478bd9Sstevel@tonic-gate case 'r': /* route tables */
4807c478bd9Sstevel@tonic-gate Rflag = B_TRUE;
4817c478bd9Sstevel@tonic-gate IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
4827c478bd9Sstevel@tonic-gate break;
4837c478bd9Sstevel@tonic-gate
48445916cd2Sjpk case 'R': /* security attributes */
48545916cd2Sjpk RSECflag = B_TRUE;
48645916cd2Sjpk IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
48745916cd2Sjpk break;
48845916cd2Sjpk
4897c478bd9Sstevel@tonic-gate case 's': /* per-protocol statistics */
4907c478bd9Sstevel@tonic-gate Sflag = B_TRUE;
4917c478bd9Sstevel@tonic-gate IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
4927c478bd9Sstevel@tonic-gate break;
4937c478bd9Sstevel@tonic-gate
4947c478bd9Sstevel@tonic-gate case 'p': /* arp/ndp table */
4957c478bd9Sstevel@tonic-gate Pflag = B_TRUE;
4967c478bd9Sstevel@tonic-gate IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
4977c478bd9Sstevel@tonic-gate break;
4987c478bd9Sstevel@tonic-gate
4997c478bd9Sstevel@tonic-gate case 'M': /* multicast routing tables */
5007c478bd9Sstevel@tonic-gate MMflag = B_TRUE;
5017c478bd9Sstevel@tonic-gate IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
5027c478bd9Sstevel@tonic-gate break;
5037c478bd9Sstevel@tonic-gate
5047c478bd9Sstevel@tonic-gate case 'g': /* multicast group membership */
5057c478bd9Sstevel@tonic-gate Gflag = B_TRUE;
5067c478bd9Sstevel@tonic-gate IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
5077c478bd9Sstevel@tonic-gate break;
5087c478bd9Sstevel@tonic-gate
5097c478bd9Sstevel@tonic-gate case 'v': /* verbose output format */
5107c478bd9Sstevel@tonic-gate Vflag = B_TRUE;
5117c478bd9Sstevel@tonic-gate IFLAGMOD(Iflag_only, 1, 0); /* see macro def'n */
5127c478bd9Sstevel@tonic-gate break;
5137c478bd9Sstevel@tonic-gate
51478a2e113SAndy Fiddaman case 'u': /* show pid and uid information */
51578a2e113SAndy Fiddaman Uflag = B_TRUE;
51678a2e113SAndy Fiddaman break;
51778a2e113SAndy Fiddaman
518bd670b35SErik Nordmark case 'x': /* turn on debugging */
519bd670b35SErik Nordmark Xflag = B_TRUE;
520bd670b35SErik Nordmark break;
521bd670b35SErik Nordmark
5227c478bd9Sstevel@tonic-gate case 'f':
5237c478bd9Sstevel@tonic-gate process_filter(optarg);
5247c478bd9Sstevel@tonic-gate break;
5257c478bd9Sstevel@tonic-gate
5267c478bd9Sstevel@tonic-gate case 'P':
5277c478bd9Sstevel@tonic-gate if (strcmp(optarg, "ip") == 0) {
5287c478bd9Sstevel@tonic-gate proto = IPPROTO_IP;
5297c478bd9Sstevel@tonic-gate } else if (strcmp(optarg, "ipv6") == 0 ||
5307c478bd9Sstevel@tonic-gate strcmp(optarg, "ip6") == 0) {
5317c478bd9Sstevel@tonic-gate v4compat = 0; /* Overridden */
5327c478bd9Sstevel@tonic-gate proto = IPPROTO_IPV6;
5337c478bd9Sstevel@tonic-gate } else if (strcmp(optarg, "icmp") == 0) {
5347c478bd9Sstevel@tonic-gate proto = IPPROTO_ICMP;
5357c478bd9Sstevel@tonic-gate } else if (strcmp(optarg, "icmpv6") == 0 ||
5367c478bd9Sstevel@tonic-gate strcmp(optarg, "icmp6") == 0) {
5377c478bd9Sstevel@tonic-gate v4compat = 0; /* Overridden */
5387c478bd9Sstevel@tonic-gate proto = IPPROTO_ICMPV6;
5397c478bd9Sstevel@tonic-gate } else if (strcmp(optarg, "igmp") == 0) {
5407c478bd9Sstevel@tonic-gate proto = IPPROTO_IGMP;
5417c478bd9Sstevel@tonic-gate } else if (strcmp(optarg, "udp") == 0) {
5427c478bd9Sstevel@tonic-gate proto = IPPROTO_UDP;
5437c478bd9Sstevel@tonic-gate } else if (strcmp(optarg, "tcp") == 0) {
5447c478bd9Sstevel@tonic-gate proto = IPPROTO_TCP;
5457c478bd9Sstevel@tonic-gate } else if (strcmp(optarg, "sctp") == 0) {
5467c478bd9Sstevel@tonic-gate proto = IPPROTO_SCTP;
5477c478bd9Sstevel@tonic-gate } else if (strcmp(optarg, "raw") == 0 ||
5487c478bd9Sstevel@tonic-gate strcmp(optarg, "rawip") == 0) {
5497c478bd9Sstevel@tonic-gate proto = IPPROTO_RAW;
5507c478bd9Sstevel@tonic-gate } else {
5517c478bd9Sstevel@tonic-gate fatal(1, "%s: unknown protocol.\n", optarg);
5527c478bd9Sstevel@tonic-gate }
5537c478bd9Sstevel@tonic-gate break;
5547c478bd9Sstevel@tonic-gate
5557c478bd9Sstevel@tonic-gate case 'I':
5567c478bd9Sstevel@tonic-gate ifname = optarg;
5577c478bd9Sstevel@tonic-gate Iflag = B_TRUE;
5587c478bd9Sstevel@tonic-gate IFLAGMOD(Iflag_only, -1, 1); /* see macro def'n */
5597c478bd9Sstevel@tonic-gate break;
5607c478bd9Sstevel@tonic-gate
5617c478bd9Sstevel@tonic-gate case 'D':
5627c478bd9Sstevel@tonic-gate DHCPflag = B_TRUE;
5637c478bd9Sstevel@tonic-gate Iflag_only = 0;
5647c478bd9Sstevel@tonic-gate break;
5657c478bd9Sstevel@tonic-gate
56626fd7700SKrishnendu Sadhukhan - Sun Microsystems case 'T':
56726fd7700SKrishnendu Sadhukhan - Sun Microsystems if (optarg) {
56826fd7700SKrishnendu Sadhukhan - Sun Microsystems if (*optarg == 'u')
56926fd7700SKrishnendu Sadhukhan - Sun Microsystems timestamp_fmt = UDATE;
57026fd7700SKrishnendu Sadhukhan - Sun Microsystems else if (*optarg == 'd')
57126fd7700SKrishnendu Sadhukhan - Sun Microsystems timestamp_fmt = DDATE;
57226fd7700SKrishnendu Sadhukhan - Sun Microsystems else
57326fd7700SKrishnendu Sadhukhan - Sun Microsystems usage(name);
57426fd7700SKrishnendu Sadhukhan - Sun Microsystems } else {
57526fd7700SKrishnendu Sadhukhan - Sun Microsystems usage(name);
57626fd7700SKrishnendu Sadhukhan - Sun Microsystems }
57726fd7700SKrishnendu Sadhukhan - Sun Microsystems break;
57826fd7700SKrishnendu Sadhukhan - Sun Microsystems
5797c478bd9Sstevel@tonic-gate case '?':
5807c478bd9Sstevel@tonic-gate default:
5817c478bd9Sstevel@tonic-gate usage(name);
5827c478bd9Sstevel@tonic-gate }
5837c478bd9Sstevel@tonic-gate }
5847c478bd9Sstevel@tonic-gate
58545916cd2Sjpk /*
58645916cd2Sjpk * Make sure -R option is set only on a labeled system.
58745916cd2Sjpk */
58845916cd2Sjpk if (RSECflag && !is_system_labeled()) {
58945916cd2Sjpk (void) fprintf(stderr, "-R set but labeling is not enabled\n");
59045916cd2Sjpk usage(name);
59145916cd2Sjpk }
59245916cd2Sjpk
5937c478bd9Sstevel@tonic-gate /*
5947c478bd9Sstevel@tonic-gate * Handle other arguments: find interval, count; the
5957c478bd9Sstevel@tonic-gate * flags that accept 'interval' and 'count' are OR'd
5967c478bd9Sstevel@tonic-gate * in the outermost 'if'; more flags may be added as
5977c478bd9Sstevel@tonic-gate * required
5987c478bd9Sstevel@tonic-gate */
5997c478bd9Sstevel@tonic-gate if (Iflag || Sflag || Mflag) {
6007c478bd9Sstevel@tonic-gate for (d = optind; d < argc; d++) {
6017c478bd9Sstevel@tonic-gate if (isnum(argv[d])) {
6027c478bd9Sstevel@tonic-gate interval = atoi(argv[d]);
6037c478bd9Sstevel@tonic-gate if (d + 1 < argc &&
6047c478bd9Sstevel@tonic-gate isnum(argv[d + 1])) {
6057c478bd9Sstevel@tonic-gate count = atoi(argv[d + 1]);
6067c478bd9Sstevel@tonic-gate optind++;
607