diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/cmd-inet/usr.bin/netstat/netstat.c | 108 | ||||
-rw-r--r-- | usr/src/cmd/cmd-inet/usr.sbin/ping/ping.c | 22 | ||||
-rw-r--r-- | usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ipaddr.c | 58 | ||||
-rw-r--r-- | usr/src/cmd/cmd-inet/usr.sbin/traceroute/traceroute.c | 66 |
4 files changed, 214 insertions, 40 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.bin/netstat/netstat.c b/usr/src/cmd/cmd-inet/usr.bin/netstat/netstat.c index 47296e9bd4..2607c5cde6 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/netstat/netstat.c +++ b/usr/src/cmd/cmd-inet/usr.bin/netstat/netstat.c @@ -23,6 +23,7 @@ * Copyright (c) 1990 Mentat Inc. * netstat.c 2.2, last change 9/9/91 * MROUTING Revision 3.5 + * Copyright (c) 2017, Joyent, Inc. */ /* @@ -55,6 +56,8 @@ #include <kstat.h> #include <assert.h> #include <locale.h> +#include <synch.h> +#include <thread.h> #include <sys/types.h> #include <sys/stream.h> @@ -253,6 +256,15 @@ static int proto = IPPROTO_MAX; /* all protocols */ kstat_ctl_t *kc = NULL; /* + * Name service timeout detection constants. + */ +static mutex_t ns_lock = ERRORCHECKMUTEX; +static boolean_t ns_active = B_FALSE; /* Is a lookup ongoing? */ +static hrtime_t ns_starttime; /* Time the lookup started */ +static int ns_sleeptime = 2; /* Time in seconds between checks */ +static int ns_warntime = 2; /* Time in seconds before warning */ + +/* * Sizes of data structures extracted from the base mib. * This allows the size of the tables entries to grow while preserving * binary compatibility. @@ -349,6 +361,55 @@ static uint_t timestamp_fmt = NODATE; #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't */ #endif +static void +ns_lookup_start(void) +{ + mutex_enter(&ns_lock); + ns_active = B_TRUE; + ns_starttime = gethrtime(); + mutex_exit(&ns_lock); +} + +static void +ns_lookup_end(void) +{ + mutex_enter(&ns_lock); + ns_active = B_FALSE; + mutex_exit(&ns_lock); +} + +/* + * When name services are not functioning, this program appears to hang to the + * user. To try and give the user a chance of figuring out that this might be + * the case, we end up warning them and suggest that they may want to use the -n + * flag. + */ +/* ARGSUSED */ +static void * +ns_warning_thr(void *unsued) +{ + for (;;) { + hrtime_t now; + + (void) sleep(ns_sleeptime); + now = gethrtime(); + mutex_enter(&ns_lock); + if (ns_active && now - ns_starttime >= ns_warntime * NANOSEC) { + (void) fprintf(stderr, "warning: data " + "available, but name service lookups are " + "taking a while. Use the -n option to " + "disable name service lookups.\n"); + mutex_exit(&ns_lock); + return (NULL); + } + mutex_exit(&ns_lock); + } + + /* LINTED: E_STMT_NOT_REACHED */ + return (NULL); +} + + int main(int argc, char **argv) { @@ -558,6 +619,15 @@ main(int argc, char **argv) if (interval) setbuf(stdout, NULL); + /* + * Start up the thread to check for name services warnings. + */ + if (thr_create(NULL, 0, ns_warning_thr, NULL, + THR_DETACHED | THR_DAEMON, NULL) != 0) { + fatal(1, "%s: failed to create name services " + "thread: %s\n", name, strerror(errno)); + } + if (DHCPflag) { dhcp_report(Iflag ? ifname : NULL); exit(0); @@ -972,7 +1042,8 @@ mib_item_dup(mib_item_t *item) * for item->mib_id == 0 */ static mib_item_t * -mib_item_diff(mib_item_t *item1, mib_item_t *item2) { +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 */ @@ -1498,7 +1569,8 @@ mibdiff_out_of_memory:; * mib_item_diff */ static void -mib_item_destroy(mib_item_t **itemp) { +mib_item_destroy(mib_item_t **itemp) +{ int nitems = 0; int c = 0; mib_item_t *tempp; @@ -3264,8 +3336,9 @@ if_report(mib_item_t *item, char *matchname, static void if_report_ip4(mib2_ipAddrEntry_t *ap, - char ifname[], char logintname[], struct ifstat *statptr, - boolean_t ksp_not_null) { + char ifname[], char logintname[], struct ifstat *statptr, + boolean_t ksp_not_null) +{ char abuf[MAXHOSTNAMELEN + 1]; char dstbuf[MAXHOSTNAMELEN + 1]; @@ -3297,7 +3370,7 @@ if_report_ip4(mib2_ipAddrEntry_t *ap, (void) printf("%-5s %-4u ", logintname, ap->ipAdEntInfo.ae_mtu); if (ap->ipAdEntInfo.ae_flags & IFF_POINTOPOINT) (void) pr_addr(ap->ipAdEntInfo.ae_pp_dst_addr, abuf, - sizeof (abuf)); + sizeof (abuf)); else (void) pr_netaddr(ap->ipAdEntAddr, ap->ipAdEntNetMask, abuf, sizeof (abuf)); @@ -3312,8 +3385,9 @@ if_report_ip4(mib2_ipAddrEntry_t *ap, static void if_report_ip6(mib2_ipv6AddrEntry_t *ap6, - char ifname[], char logintname[], struct ifstat *statptr, - boolean_t ksp_not_null) { + char ifname[], char logintname[], struct ifstat *statptr, + boolean_t ksp_not_null) +{ char abuf[MAXHOSTNAMELEN + 1]; char dstbuf[MAXHOSTNAMELEN + 1]; @@ -5450,8 +5524,7 @@ plurales(int n) } static char * -pktscale(n) - int n; +pktscale(int n) { static char buf[6]; char t; @@ -5735,8 +5808,10 @@ pr_addr(uint_t addr, char *dst, uint_t dstlen) } cp = NULL; if (!Nflag) { + ns_lookup_start(); hp = getipnodebyaddr((char *)&addr, sizeof (uint_t), AF_INET, &error_num); + ns_lookup_end(); if (hp) { if ((cp = strchr(hp->h_name, '.')) != NULL && strcasecmp(cp + 1, domain) == 0) @@ -5791,8 +5866,10 @@ pr_addr6(const struct in6_addr *addr, char *dst, uint_t dstlen) } cp = NULL; if (!Nflag) { + ns_lookup_start(); hp = getipnodebyaddr((char *)addr, sizeof (struct in6_addr), AF_INET6, &error_num); + ns_lookup_end(); if (hp) { if ((cp = strchr(hp->h_name, '.')) != NULL && strcasecmp(cp + 1, domain) == 0) @@ -5943,15 +6020,19 @@ pr_net(uint_t addr, uint_t mask, char *dst, uint_t dstlen) net = addr & mask; while ((mask & 1) == 0) mask >>= 1, net >>= 1; + ns_lookup_start(); np = getnetbyaddr(net, AF_INET); + ns_lookup_end(); if (np && np->n_net == net) cp = np->n_name; else { /* * Look for subnets in hosts map. */ + ns_lookup_start(); hp = getipnodebyaddr((char *)&addr, sizeof (uint_t), AF_INET, &error_num); + ns_lookup_end(); if (hp) cp = hp->h_name; } @@ -6025,15 +6106,19 @@ pr_netaddr(uint_t addr, uint_t mask, char *dst, uint_t dstlen) /* Try looking up name unless -n was specified. */ if (!Nflag) { + ns_lookup_start(); np = getnetbyaddr(netshifted, AF_INET); + ns_lookup_end(); if (np && np->n_net == netshifted) cp = np->n_name; else { /* * Look for subnets in hosts map. */ + ns_lookup_start(); hp = getipnodebyaddr((char *)&nbo_addr, sizeof (uint_t), AF_INET, &error_num); + ns_lookup_end(); if (hp) cp = hp->h_name; } @@ -6133,8 +6218,11 @@ portname(uint_t port, char *proto, char *dst, uint_t dstlen) { struct servent *sp = NULL; - if (!Nflag && port) + if (!Nflag && port) { + ns_lookup_start(); sp = getservbyport(htons(port), proto); + ns_lookup_end(); + } if (sp || port == 0) (void) snprintf(dst, dstlen, "%.*s", MAXHOSTNAMELEN, sp ? sp->s_name : "*"); diff --git a/usr/src/cmd/cmd-inet/usr.sbin/ping/ping.c b/usr/src/cmd/cmd-inet/usr.sbin/ping/ping.c index 2d79419245..c6f8257ae9 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/ping/ping.c +++ b/usr/src/cmd/cmd-inet/usr.sbin/ping/ping.c @@ -38,7 +38,7 @@ */ /* - * Copyright 2015, Joyent, Inc. + * Copyright (c) 2017, Joyent, Inc. */ #include <assert.h> @@ -187,7 +187,6 @@ static boolean_t ns_active = _B_FALSE; /* Lookup is going on */ static hrtime_t ns_starttime; /* Time the lookup started */ static int ns_sleeptime = 2; /* Time in seconds between checks */ static int ns_warntime = 2; /* Time in seconds before warning */ -static int ns_warninter = 60; /* Time in seconds between warnings */ /* * This buffer stores the received packets. Currently it needs to be 32 bit @@ -1927,7 +1926,7 @@ send_scheduled_probe() */ static void recv_icmp_packet(struct addrinfo *ai_dst, int recv_sock6, int recv_sock, -ushort_t udp_src_port6, ushort_t udp_src_port) + ushort_t udp_src_port6, ushort_t udp_src_port) { struct msghdr in_msg; struct iovec iov; @@ -2591,7 +2590,6 @@ ping_gettime(struct msghdr *msg, struct timeval *tv) static void * ns_warning_thr(void *unused) { - hrtime_t last_warn = 0; for (;;) { hrtime_t now; @@ -2600,15 +2598,13 @@ ns_warning_thr(void *unused) mutex_enter(&ns_lock); if (ns_active == _B_TRUE && now - ns_starttime >= ns_warntime * NANOSEC) { - if (now - last_warn >= - ns_warninter * NANOSEC) { - last_warn = now; - Fprintf(stderr, "%s: warning: ICMP responses " - "received, but name service lookups are " - "taking a while. Use ping -n to disable " - "name service lookups.\n", - progname); - } + Fprintf(stderr, "%s: warning: ICMP responses " + "received, but name service lookups are " + "taking a while. Use ping -n to disable " + "name service lookups.\n", + progname); + mutex_exit(&ns_lock); + return (NULL); } mutex_exit(&ns_lock); } diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ipaddr.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ipaddr.c index c42c55dfef..9c44e4ff00 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ipaddr.c +++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ipaddr.c @@ -21,6 +21,7 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2017, Joyent, Inc. */ #include <stdio.h> @@ -39,9 +40,12 @@ #include <signal.h> #include <setjmp.h> #include <arpa/inet.h> +#include <sys/time.h> #include "snoop.h" static sigjmp_buf nisjmp; +static hrtime_t snoop_lastwarn; /* Last time NS warning fired */ +static unsigned snoop_warninter = 60; /* Time in seconds between warnings */ #define MAXHASH 1024 /* must be a power of 2 */ @@ -86,6 +90,19 @@ wakeup(int n) extern char *inet_ntoa(); +static void +snoop_nswarn(void) +{ + hrtime_t now = gethrtime(); + + if (now - snoop_lastwarn >= snoop_warninter * NANOSEC) { + snoop_lastwarn = now; + (void) fprintf(stderr, "snoop: warning: packets captured, but " + "name service lookups are timing out. Use snoop -r to " + "disable name service lookups\n"); + } +} + static struct hostdata * iplookup(struct in_addr ipaddr) { @@ -112,17 +129,21 @@ iplookup(struct in_addr ipaddr) * an unresponsive name server. * Give it 3 sec to do its work. */ - if (! rflg && sigsetjmp(nisjmp, 1) == 0) { - (void) snoop_alarm(3, wakeup); - hp = getipnodebyaddr((char *)&ipaddr, sizeof (int), - AF_INET, &error_num); - if (hp == NULL && inet_lnaof(ipaddr) == 0) { - np = getnetbyaddr(inet_netof(ipaddr), AF_INET); - if (np) - return (addhost(AF_INET, &ipaddr, np->n_name, - np->n_aliases)); + if (!rflg) { + if (sigsetjmp(nisjmp, 1) == 0) { + (void) snoop_alarm(3, wakeup); + hp = getipnodebyaddr((char *)&ipaddr, sizeof (int), + AF_INET, &error_num); + if (hp == NULL && inet_lnaof(ipaddr) == 0) { + np = getnetbyaddr(inet_netof(ipaddr), AF_INET); + if (np) + return (addhost(AF_INET, &ipaddr, + np->n_name, np->n_aliases)); + } + (void) snoop_alarm(0, wakeup); + } else { + snoop_nswarn(); } - (void) snoop_alarm(0, wakeup); } retval = addhost(AF_INET, &ipaddr, @@ -158,11 +179,15 @@ ip6lookup(const struct in6_addr *ip6addr) * an unresponsive name server. * Give it 3 sec to do its work. */ - if (! rflg && sigsetjmp(nisjmp, 1) == 0) { - (void) snoop_alarm(3, wakeup); - hp = getipnodebyaddr(ip6addr, sizeof (struct in6_addr), - AF_INET6, &error_num); - (void) snoop_alarm(0, wakeup); + if (!rflg) { + if (sigsetjmp(nisjmp, 1) == 0) { + (void) snoop_alarm(3, wakeup); + hp = getipnodebyaddr(ip6addr, sizeof (struct in6_addr), + AF_INET6, &error_num); + (void) snoop_alarm(0, wakeup); + } else { + snoop_nswarn(); + } } else { hp = NULL; } @@ -295,8 +320,7 @@ addrtoname(int family, const void *ipaddr) } void -load_names(fname) - char *fname; +load_names(char *fname) { char buf[1024]; char *addr, *name, *alias; diff --git a/usr/src/cmd/cmd-inet/usr.sbin/traceroute/traceroute.c b/usr/src/cmd/cmd-inet/usr.sbin/traceroute/traceroute.c index b8b56259ad..98d452665a 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/traceroute/traceroute.c +++ b/usr/src/cmd/cmd-inet/usr.sbin/traceroute/traceroute.c @@ -1,6 +1,7 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright (c) 2017, Joyent, Inc. */ /* @@ -61,6 +62,8 @@ #include <setjmp.h> #include <limits.h> #include <zone.h> +#include <thread.h> +#include <synch.h> #include <priv_utils.h> @@ -184,6 +187,15 @@ ushort_t off = 0; /* set DF bit */ static jmp_buf env; /* stack environment for longjmp() */ boolean_t raw_req; /* if sndsock for IPv4 must be raw */ +/* + * Name service lookup related data. + */ +static mutex_t tr_nslock = ERRORCHECKMUTEX; +static boolean_t tr_nsactive = _B_FALSE; /* Lookup ongoing */ +static hrtime_t tr_nsstarttime; /* Start time */ +static int tr_nssleeptime = 2; /* Interval between checks */ +static int tr_nswarntime = 2; /* Interval to warn after */ + /* Forwards */ static uint_t calc_packetlen(int, struct pr_set *); extern int check_reply(struct msghdr *, int, int, uchar_t *, uchar_t *); @@ -237,6 +249,7 @@ static void tv_sub(struct timeval *, struct timeval *); static void usage(void); static int wait_for_reply(int, struct msghdr *, struct timeval *); static double xsqrt(double); +static void *ns_warning_thr(void *); /* * main @@ -515,6 +528,17 @@ main(int argc, char **argv) exit(EXIT_FAILURE); } + /* + * Start up the name services warning thread. + */ + if (thr_create(NULL, 0, ns_warning_thr, NULL, + THR_DETACHED | THR_DAEMON, NULL) != 0) { + Fprintf(stderr, "%s: failed to create name services " + "thread: %s\n", prog, strerror(errno)); + exit(EXIT_FAILURE); + } + + /* resolve hostnames */ resolve_nodes(&family_input, &ai_dst); if (ai_dst == NULL) { @@ -1980,6 +2004,10 @@ inet_name(union any_in_addr *in, int family) if (first && !nflag) { /* find out the domain name */ first = _B_FALSE; + mutex_enter(&tr_nslock); + tr_nsactive = _B_TRUE; + tr_nsstarttime = gethrtime(); + mutex_exit(&tr_nslock); if (gethostname(domain, MAXHOSTNAMELEN) == 0 && (cp = strchr(domain, '.')) != NULL) { (void) strncpy(domain, cp + 1, sizeof (domain) - 1); @@ -1987,9 +2015,16 @@ inet_name(union any_in_addr *in, int family) } else { domain[0] = '\0'; } + mutex_enter(&tr_nslock); + tr_nsactive = _B_FALSE; + mutex_exit(&tr_nslock); } flags = (nflag) ? NI_NUMERICHOST : NI_NAMEREQD; + mutex_enter(&tr_nslock); + tr_nsactive = _B_TRUE; + tr_nsstarttime = gethrtime(); + mutex_exit(&tr_nslock); if (getnameinfo(sa, slen, hbuf, sizeof (hbuf), NULL, 0, flags) != 0) { if (inet_ntop(family, (const void *)&in->addr6, hbuf, sizeof (hbuf)) == NULL) @@ -1998,6 +2033,9 @@ inet_name(union any_in_addr *in, int family) strcmp(cp + 1, domain) == 0) { *cp = '\0'; } + mutex_enter(&tr_nslock); + tr_nsactive = _B_FALSE; + mutex_exit(&tr_nslock); (void) strlcpy(line, hbuf, sizeof (line)); return (line); @@ -2205,3 +2243,31 @@ usage(void) "[packetlen]\n", prog); exit(EXIT_FAILURE); } + +/* ARGSUSED */ +static void * +ns_warning_thr(void *unused) +{ + for (;;) { + hrtime_t now; + + (void) sleep(tr_nssleeptime); + + now = gethrtime(); + mutex_enter(&tr_nslock); + if (tr_nsactive && now - tr_nsstarttime >= + tr_nswarntime * NANOSEC) { + Fprintf(stderr, "%s: warning: responses " + "received, but name service lookups are " + "taking a while. Use %s -n to disable " + "name service lookups.\n", + prog, prog); + mutex_exit(&tr_nslock); + return (NULL); + } + mutex_exit(&tr_nslock); + } + + /* LINTED: E_STMT_NOT_REACHED */ + return (NULL); +} |