From a308aef89d5b262c9e04f51e2a695bee90446cb1 Mon Sep 17 00:00:00 2001 From: Jeff Morriss Date: Sat, 28 Feb 2015 22:20:07 -0500 Subject: Look for and use gethostbyname() if we don't have getaddrinfo(). Fail to configure if we can't find any name resolver (autotools only). This puts back the gethostbyname()/gethostbyname2() code removed in I3348179626e97daaddfbc89e3ed21e39915e3de4 and If59ce8a038776eadd6cd1794ed0e2dad8bf8a22c but as a last-resort option (only if we don't have a better or more modern name resolver). As suggested/requested by Guy in https://code.wireshark.org/review/#/c/7423/ Change-Id: I706dbbd65135f47c67d3d8d88a61ad7273914c47 Reviewed-on: https://code.wireshark.org/review/7447 Petri-Dish: Jeff Morriss Tested-by: Petri Dish Buildbot Reviewed-by: Jeff Morriss --- ConfigureChecks.cmake | 2 ++ acinclude.m4 | 43 +++++++++++++++++++++++++------ cmakeconfig.h.in | 6 +++++ configure.ac | 33 +++++++++++++++++++----- epan/addr_resolv.c | 70 +++++++++++++++++++++++++++++++++++++++++++-------- 5 files changed, 129 insertions(+), 25 deletions(-) diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index 50e312e04a..69ca619068 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -69,6 +69,8 @@ cmake_pop_check_state() # check_symbol_exists("floorl" "math.h" HAVE_FLOORL) check_function_exists("getaddrinfo" HAVE_GETADDRINFO) +check_function_exists("gethostbyname" HAVE_GETHOSTBYNAME) +check_function_exists("gethostbyname2" HAVE_GETHOSTBYNAME2) check_function_exists("getopt_long" HAVE_GETOPT_LONG) if(HAVE_GETOPT_LONG) if(HAVE_GETOPT_H) diff --git a/acinclude.m4 b/acinclude.m4 index 6db1b966eb..2d89e2278e 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -276,19 +276,46 @@ AC_DEFUN([AC_WIRESHARK_GETADDRINFO_LIB_CHECK], AC_CHECK_FUNCS(getaddrinfo, , AC_CHECK_LIB(nsl, getaddrinfo, [ - NSL_LIBS="-lnsl" + NSL_LIBS="-lnsl" AC_DEFINE(HAVE_GETADDRINFO, 1, [Defined if we have getaddrinfo]) ])) AC_SUBST(NSL_LIBS) ]) +# +# AC_WIRESHARK_GETHOSTBY_LIB_CHECK +# +# Checks whether we need "-lnsl" to get "gethostby*()", which we use +# in "resolv.c". +# +# Adapted from stuff in the AC_PATH_XTRA macro in "acspecific.m4" in +# GNU Autoconf 2.13; the comment came from there. +# Done by Guy Harris on 2000-01-14. +# +AC_DEFUN([AC_WIRESHARK_GETHOSTBY_LIB_CHECK], +[ + # msh@cis.ufl.edu says -lnsl (and -lsocket) are needed for his 386/AT, + # to get the SysV transport functions. + # chad@anasazi.com says the Pyramid MIS-ES running DC/OSx (SVR4) + # needs -lnsl. + # The nsl library prevents programs from opening the X display + # on Irix 5.2, according to dickey@clark.net. + AC_CHECK_FUNCS(gethostbyname, , + AC_CHECK_LIB(nsl, gethostbyname, + [ + NSL_LIBS="-lnsl" + AC_DEFINE(HAVE_GETHOSTBYNAME, 1, [Defined if we have gethostbyname]) + ])) + AC_SUBST(NSL_LIBS) +]) + # # AC_WIRESHARK_SOCKET_LIB_CHECK # # Checks whether we need "-lsocket" to get "socket()", which is used -# by libpcap on some platforms - and, in effect, "getaddrinfo()" on -# most if not all platforms (so that it can use NIS or DNS or... -# to look up host names). +# by libpcap on some platforms - and, in effect, "gethostbyname()" or +# "getaddrinfo()" on most if not all platforms (so that it can use NIS or +# DNS or... to look up host names). # # Adapted from stuff in the AC_PATH_XTRA macro in "acspecific.m4" in # GNU Autoconf 2.13; the comment came from there. @@ -1105,8 +1132,8 @@ AC_DEFUN([AC_WIRESHARK_ADNS_CHECK], AC_CHECK_LIB(adns, adns_init, [ ADNS_LIBS=-ladns - AC_DEFINE(HAVE_GNU_ADNS, 1, [Define to use GNU ADNS library]) - have_good_adns=yes + AC_DEFINE(HAVE_GNU_ADNS, 1, [Define to use GNU ADNS library]) + have_good_adns=yes ],, $SOCKET_LIBS $NSL_LIBS ) else @@ -1136,8 +1163,8 @@ AC_DEFUN([AC_WIRESHARK_LIBCAP_CHECK], AC_CHECK_LIB(cap, cap_set_flag, [ LIBCAP_LIBS=-lcap - AC_DEFINE(HAVE_LIBCAP, 1, [Define to use the libcap library]) - have_good_libcap=yes + AC_DEFINE(HAVE_LIBCAP, 1, [Define to use the libcap library]) + have_good_libcap=yes ],, ) else diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in index 2887c27c80..0ad3fb521a 100644 --- a/cmakeconfig.h.in +++ b/cmakeconfig.h.in @@ -70,6 +70,12 @@ /* Define to 1 if you have the `getaddrinfo' function. */ #cmakedefine HAVE_GETADDRINFO 1 +/* Define to 1 if you have the `gethostbyname' function. */ +#cmakedefine HAVE_GETHOSTBYNAME 1 + +/* Define to 1 if you have the `gethostbyname2' function. */ +#cmakedefine HAVE_GETHOSTBYNAME2 1 + /* Define to 1 if you have the getopt_long function. */ #cmakedefine HAVE_GETOPT_LONG 1 diff --git a/configure.ac b/configure.ac index 6fe5adf103..ab37da80a4 100644 --- a/configure.ac +++ b/configure.ac @@ -2187,10 +2187,6 @@ AC_SUBST(randpkt_man) AC_SUBST(wiresharkfilter_man) -dnl Checks for "getaddrinfo()" - and "-lnsl", if we need it to get -dnl "getaddrinfo()". -AC_WIRESHARK_GETADDRINFO_LIB_CHECK - dnl Checks for "connect()", used as a proxy for "socket()" - and dnl "-lsocket", if we need it to get "connect()". AC_WIRESHARK_SOCKET_LIB_CHECK @@ -2685,7 +2681,7 @@ AC_MSG_CHECKING(whether to use the c-ares library if available) AC_ARG_WITH(c-ares, AC_HELP_STRING( [--with-c-ares@<:@=DIR@:>@], - [use c-ares (located in directory DIR, if supplied) - supersedes --with-adns @<:@default=yes, if present@:>@]), + [use c-ares (located in directory DIR, if supplied) - supersedes --with-adns @<:@default=yes, if present@:>@]), [ if test "x$withval" = "xno"; then want_c_ares=no @@ -2710,7 +2706,7 @@ AC_MSG_CHECKING(whether to use the GNU ADNS library if available) AC_ARG_WITH(adns, AC_HELP_STRING( [--with-adns@<:@=DIR@:>@], - [use GNU ADNS (located in directory DIR, if supplied) @<:@default=yes, if present@:>@]), + [use GNU ADNS (located in directory DIR, if supplied) @<:@default=yes, if present@:>@]), [ if test "x$withval" = "xno"; then want_adns=no @@ -2729,6 +2725,31 @@ else fi AC_SUBST(ADNS_LIBS) +if test "x$have_good_c_ares" != "xyes" -a "x$have_good_adns" != "xyes"; then + # We don't have an asynchronous name resolver, look for a synchronous one + + dnl Checks for "getaddrinfo()" - and "-lnsl", if we need it to get + dnl "getaddrinfo()". + AC_WIRESHARK_GETADDRINFO_LIB_CHECK + + if test "x$ac_cv_func_getaddrinfo" != "xyes" ; then + # We don't have the modern name resolver, try older stuff + + dnl Checks for "gethostbyname()" - and "-lnsl", if we need it to get + dnl "gethostbyname()". + AC_WIRESHARK_GETHOSTBY_LIB_CHECK + + if test "x$ac_cv_func_gethostbyname" != "xyes" ; then + # Hopefully this never actually happens. + # The code works even without name resolvers but we + # alert the user to this unusual condition. + AC_MSG_ERROR(Couldn't find any name resolvers!) + fi + + AC_CHECK_FUNCS(gethostbyname2) + fi +fi + dnl GEOIP Check GEOIP_LIBS='' AC_MSG_CHECKING(whether to use the GeoIP IP address mapping library if available) diff --git a/epan/addr_resolv.c b/epan/addr_resolv.c index 9002ad7940..11c37c9ce5 100644 --- a/epan/addr_resolv.c +++ b/epan/addr_resolv.c @@ -889,7 +889,7 @@ try_resolv: fill_dummy_ip4(addr, tp); return tp; } -#elif defined(HAVE_GETADDRINFO) + /* * The Windows "gethostbyaddr()" insists on translating 0.0.0.0 to * the name of the host on which it's running; to work around that @@ -899,6 +899,7 @@ try_resolv: * Presumably getaddrinfo() behaves the same way. Anyway, we should * never get to this code on Windows since those builds include c-ares. */ +#elif defined(HAVE_GETADDRINFO) if (addr != 0) { struct sockaddr_in sin; @@ -911,6 +912,17 @@ try_resolv: return tp; } } +#elif defined(HAVE_GETHOSTBYNAME) + if (addr != 0) { + struct hostent *hostp; + + hostp = gethostbyaddr((const char *)&addr, 4, AF_INET); + + if (hostp != NULL && hostp->h_name[0] != '\0') { + g_strlcpy(tp->name, hostp->h_name, MAXNAMELEN); + return tp; + } + } #endif /* unknown host or DNS timeout */ @@ -943,6 +955,8 @@ host_lookup6(const struct e_in6_addr *addr, gboolean *found) async_dns_queue_msg_t *caqm; #elif defined(HAVE_GETADDRINFO) struct sockaddr_in6 sin6; +#elif defined(HAVE_GETHOSTBYNAME) + struct hostent *hostp; #endif #endif /* INET6 */ @@ -991,14 +1005,22 @@ try_resolv: return tp; } #elif defined(HAVE_GETADDRINFO) - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_family = AF_INET6; - memcpy(sin6.sin6_addr.s6_addr, addr, sizeof(*addr)); - if (getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), - tp->name, sizeof(tp->name), - NULL, 0, NI_NAMEREQD) == 0) { - return tp; - } + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_family = AF_INET6; + memcpy(sin6.sin6_addr.s6_addr, addr, sizeof(*addr)); + if (getnameinfo((struct sockaddr *)&sin6, sizeof(sin6), + tp->name, sizeof(tp->name), + NULL, 0, NI_NAMEREQD) == 0) { + return tp; + } +#elif defined(HAVE_GETHOSTBYNAME) + /* Quick hack to avoid DNS/YP timeout */ + hostp = gethostbyaddr((const char *)addr, sizeof(*addr), AF_INET6); + + if (hostp != NULL && hostp->h_name[0] != '\0') { + g_strlcpy(tp->name, hostp->h_name, MAXNAMELEN); + return tp; + } #endif #endif /* INET6 */ } @@ -3249,6 +3271,8 @@ get_host_ipaddr(const char *host, guint32 *addrp) async_hostent_t ahe; #elif defined(HAVE_GETADDRINFO) struct addrinfo hint, *result = NULL; +#elif defined(HAVE_GETHOSTBYNAME) + struct hostent *hp; #endif /* @@ -3315,6 +3339,18 @@ get_host_ipaddr(const char *host, guint32 *addrp) return ret_val; } } +#elif defined(HAVE_GETHOSTBYNAME) + hp = gethostbyname(host); + if (hp == NULL) { + /* No. */ + return FALSE; + /* Apparently, some versions of gethostbyaddr can + * return IPv6 addresses. */ + } else if (hp->h_length <= (int) sizeof (struct in_addr)) { + memcpy(&ipaddr, hp->h_addr, hp->h_length); + } else { + return FALSE; + } #endif } else { /* Does the string really contain dotted-quad IP? @@ -3346,6 +3382,8 @@ get_host_ipaddr6(const char *host, struct e_in6_addr *addrp) async_hostent_t ahe; #elif defined(HAVE_GETADDRINFO) struct addrinfo hint, *result = NULL; +#elif defined(HAVE_GETHOSTBYNAME2) + struct hostent *hp; #endif /* HAVE_C_ARES */ if (str_to_ip6(host, addrp)) @@ -3408,6 +3446,12 @@ get_host_ipaddr6(const char *host, struct e_in6_addr *addrp) return ret_val; } } +#elif defined(HAVE_GETHOSTBYNAME2) + hp = gethostbyname2(host, AF_INET6); + if (hp != NULL && hp->h_length == sizeof(struct e_in6_addr)) { + memcpy(addrp, hp->h_addr, hp->h_length); + return TRUE; + } #endif return FALSE; @@ -3418,8 +3462,9 @@ get_host_ipaddr6(const char *host, struct e_in6_addr *addrp) * Return "ip6" if it is IPv6, "ip" otherwise (including the case * that we don't know) */ -const char* host_ip_af(const char *host -#ifndef HAVE_GETADDRINFO +const char * +host_ip_af(const char *host +#if !defined(HAVE_GETADDRINFO) || !defined(HAVE_GETHOSTBYNAME2) _U_ #endif ) @@ -3435,6 +3480,9 @@ const char* host_ip_af(const char *host } freeaddrinfo(result); } +#elif defined(HAVE_GETHOSTBYNAME2) + struct hostent *h; + return (h = gethostbyname2(host, AF_INET6)) && h->h_addrtype == AF_INET6 ? "ip6" : "ip"; #endif return af; } -- cgit v1.2.1