From: Roy Marples Date: Wed, 18 Apr 2007 10:16:51 +0000 (+0000) Subject: Use getnameinfo instead of gethostbyaddr. X-Git-Tag: v3.2.3~273 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9679555cdca2289c20bab4a526d2e999726c06f4;p=thirdparty%2Fdhcpcd.git Use getnameinfo instead of gethostbyaddr. --- diff --git a/ChangeLog b/ChangeLog index e50c038d..b5a733ac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ +Use getnameinfo instead of gethostbyaddr. Remove gateways from the ROUTES and add to GATEWAYS define #INFO_COMPAT if you wish your .info file to add support for some old 1.x and 2.x structure. diff --git a/configure.c b/configure.c index 55415af0..bfd5ee8a 100644 --- a/configure.c +++ b/configure.c @@ -505,11 +505,8 @@ int configure (const options_t *options, interface_t *iface, route_t *route = NULL; route_t *new_route = NULL; route_t *old_route = NULL; - struct hostent *he = NULL; char newhostname[HOSTNAME_MAX_LEN] = {0}; char curhostname[HOSTNAME_MAX_LEN] = {0}; - char *dname = NULL; - int dnamel = 0; if (! options || ! iface || ! dhcp) return -1; @@ -666,16 +663,41 @@ int configure (const options_t *options, interface_t *iface, /* Now we have made a resolv.conf we can obtain a hostname if we need one */ if (options->dohostname && ! dhcp->hostname) { - he = gethostbyaddr (inet_ntoa (dhcp->address), - sizeof (struct in_addr), AF_INET); - if (he) { - dname = he->h_name; - while (*dname > 32) - dname++; - dnamel = dname - he->h_name; - memcpy (newhostname, he->h_name, dnamel); - newhostname[dnamel] = 0; + union { + struct sockaddr sa; + struct sockaddr_in sin; + } su; + socklen_t salen; + char addr[NI_MAXHOST]; + struct addrinfo hints, *res; + + salen = sizeof (struct sockaddr); + memset (&su.sa, 0, salen); + su.sin.sin_family = AF_INET; + su.sin.sin_len = sizeof (struct sockaddr_in); + memcpy (&su.sin.sin_addr, &dhcp->address, sizeof (struct in_addr)); + + if (getnameinfo (&su.sa, salen, addr, sizeof (addr), + NULL, 0, NI_NAMEREQD) == 0) { + memset (&hints, 0, sizeof (hints)); + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_NUMERICHOST; + /* Check for a malicious PTR record */ + if (getaddrinfo (addr, "0", &hints, &res) == 0) { + freeaddrinfo (res); + addr[0] = '\0'; + logger (LOG_DEBUG, "malicious PTR record detected"); + } } + + /* Split the hostname from the domain */ + if (addr[0]) { + char *p = addr; + char *token = strsep (&p, "."); + if (token) + strlcpy (newhostname, token, sizeof (newhostname)); + } else + logger (LOG_ERR, "failed to lookup the hostname"); } gethostname (curhostname, sizeof (curhostname)); diff --git a/dhcpcd.8 b/dhcpcd.8 index f200f401..eec47653 100644 --- a/dhcpcd.8 +++ b/dhcpcd.8 @@ -1,6 +1,6 @@ .\" $Id$ .\" -.TH DHCPCD 8 "27 February 2007" "dhcpcd 3.0" +.TH DHCPCD 8 "18 April 2007" "dhcpcd 3.0" .SH NAME dhcpcd \- DHCP client daemon @@ -183,7 +183,8 @@ By default .B dhcpcd will NOT set hostname of the host to the hostname option received from DHCP server unless the current hostname is blank, (none) or -localhost. +localhost. If no hostname is returned by the DHCP server then we attempt +to lookup the hostname via DNS. .TP .BI \-F \ none | ptr | both Forces