mirror of
https://github.com/nmap/nmap.git
synced 2025-12-07 21:21:31 +00:00
Make a new function called resolve_all in tcpip.cc, which is like
resolve except that it returns all resolved addresses. Use this new function to resolve IPv4 addresses instead of gethostbyname in TargetGroup.cc. The gethostbyname code assumed that only IPv4 addresses would be returned. If the resolver returned IPv6 addresses, TargetGroup would blindly copy the first four bytes of the IPv6 address into the IPv4 struct. This was first reported by Mats Erik Andersson at http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=584301; he also suggested the fix.
This commit is contained in:
34
tcpip.cc
34
tcpip.cc
@@ -911,23 +911,37 @@ const char *inet_socktop(struct sockaddr_storage *ss) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Tries to resolve the given name (or literal IP) into a sockaddr
|
||||
structure. The af should be PF_INET (for IPv4) or PF_INET6. Returns 0
|
||||
if hostname cannot be resolved. It is OK to pass in a sockaddr_in or
|
||||
sockaddr_in6 casted to a sockaddr_storage as long as you use the matching
|
||||
pf.*/
|
||||
int resolve(char *hostname, struct sockaddr_storage *ss, size_t *sslen, int pf) {
|
||||
/* Tries to resolve the given name (or literal IP) into a sockaddr structure.
|
||||
This function calls getaddrinfo and returns the same addrinfo linked list
|
||||
that getaddrinfo produces. Returns NULL for any error or failure to resolve.
|
||||
You need to call freeaddrinfo on the result. */
|
||||
struct addrinfo *resolve_all(char *hostname, int pf)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result;
|
||||
int rc;
|
||||
|
||||
assert(ss);
|
||||
assert(sslen);
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = pf;
|
||||
/* Otherwise we get multiple identical addresses with different socktypes. */
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
rc = getaddrinfo(hostname, NULL, &hints, &result);
|
||||
if (rc != 0 || result == NULL)
|
||||
return 0;
|
||||
if (rc != 0)
|
||||
return NULL;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Tries to resolve the given name (or literal IP) into a sockaddr structure.
|
||||
The af should be PF_INET (for IPv4) or PF_INET6. Returns 0 if hostname
|
||||
cannot be resolved. It is OK to pass in a sockaddr_in or sockaddr_in6 casted
|
||||
to a sockaddr_storage as long as you use the matching pf. */
|
||||
int resolve(char *hostname, struct sockaddr_storage *ss, size_t *sslen, int pf) {
|
||||
struct addrinfo *result;
|
||||
|
||||
assert(ss);
|
||||
assert(sslen);
|
||||
result = resolve_all(hostname, pf);
|
||||
assert(result->ai_addrlen > 0
|
||||
&& result->ai_addrlen <= (int) sizeof(struct sockaddr_storage));
|
||||
*sslen = result->ai_addrlen;
|
||||
|
||||
Reference in New Issue
Block a user