mirror of
https://github.com/nmap/nmap.git
synced 2026-06-30 05:05:53 +00:00
move resolve_all to libnetutil. Let resolve use AI_IDN
This commit is contained in:
parent
3d71e96550
commit
c44b7b3f9b
4 changed files with 58 additions and 47 deletions
|
|
@ -138,6 +138,7 @@ typedef unsigned __int8 u_int8_t;
|
|||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <locale.h>
|
||||
|
||||
#define NBASE_MAX_ERR_STR_LEN 1024 /* Max length of an error message */
|
||||
|
||||
|
|
@ -351,25 +352,34 @@ after:
|
|||
return(d - data);
|
||||
}
|
||||
|
||||
/* Internal helper for resolve and resolve_numeric. addl_flags is ored into
|
||||
hints.ai_flags, so you can add AI_NUMERICHOST. */
|
||||
static int resolve_internal(const char *hostname, unsigned short port,
|
||||
struct sockaddr_storage *ss, size_t *sslen, int af, int addl_flags) {
|
||||
/* 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 if non-NULL. */
|
||||
static addrinfo *resolve_all_internal(const char *hostname, unsigned short port,
|
||||
int af, int addl_flags) {
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result;
|
||||
char portbuf[16];
|
||||
char *servname = NULL;
|
||||
int rc;
|
||||
|
||||
assert(hostname);
|
||||
assert(ss);
|
||||
assert(sslen);
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = af;
|
||||
/* Otherwise we get multiple identical addresses with different socktypes. */
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_flags |= addl_flags;
|
||||
|
||||
#ifdef AI_IDN
|
||||
/* Try resolving internationalized domain names */
|
||||
locale_t env_locale = newlocale(LC_CTYPE_MASK, "", (locale_t)0);
|
||||
hints.ai_flags |= AI_IDN;
|
||||
locale_t old_locale = (locale_t)0;
|
||||
if (env_locale != old_locale) {
|
||||
old_locale = uselocale(env_locale);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Make the port number a string to give to getaddrinfo. */
|
||||
if (port != 0) {
|
||||
rc = Snprintf(portbuf, sizeof(portbuf), "%hu", port);
|
||||
|
|
@ -378,8 +388,36 @@ static int resolve_internal(const char *hostname, unsigned short port,
|
|||
}
|
||||
|
||||
rc = getaddrinfo(hostname, servname, &hints, &result);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
|
||||
#ifdef AI_IDN
|
||||
if (env_locale != (locale_t)0) {
|
||||
// Restore the thread's previous locale configuration
|
||||
uselocale(old_locale);
|
||||
// Free the allocated memory for the temporary locale
|
||||
freelocale(env_locale);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rc != 0){
|
||||
if ((AI_NUMERICHOST & addl_flags) == 0)
|
||||
netutil_error("Error resolving %s: %s", hostname, gai_strerror(rc));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Internal helper for resolve and resolve_numeric. addl_flags is ored into
|
||||
hints.ai_flags, so you can add AI_NUMERICHOST. */
|
||||
static int resolve_internal(const char *hostname, unsigned short port,
|
||||
struct sockaddr_storage *ss, size_t *sslen, int af, int addl_flags) {
|
||||
struct addrinfo *result;
|
||||
|
||||
assert(hostname);
|
||||
assert(ss);
|
||||
assert(sslen);
|
||||
|
||||
result = resolve_all_internal(hostname, port, af, addl_flags);
|
||||
if (result == NULL)
|
||||
return EAI_NONAME;
|
||||
assert(result->ai_addrlen > 0 && result->ai_addrlen <= (int) sizeof(struct sockaddr_storage));
|
||||
|
|
@ -409,6 +447,10 @@ int resolve_numeric(const char *ip, unsigned short port,
|
|||
return resolve_internal(ip, port, ss, sslen, af, AI_NUMERICHOST);
|
||||
}
|
||||
|
||||
struct addrinfo *resolve_all(const char *hostname, int pf) {
|
||||
return resolve_all_internal(hostname, 0, pf, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns 1 if this is a reserved IP address, where "reserved" means
|
||||
* either a private address, non-routable address, or even a non-reserved
|
||||
|
|
|
|||
|
|
@ -146,6 +146,12 @@ int resolve(const char *hostname, unsigned short port,
|
|||
int resolve_numeric(const char *ip, unsigned short port,
|
||||
struct sockaddr_storage *ss, size_t *sslen, int af);
|
||||
|
||||
/* 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. */
|
||||
struct addrinfo *resolve_all(const char *hostname, int pf);
|
||||
|
||||
/*
|
||||
* Returns 1 if this is a reserved IP address, where "reserved" means
|
||||
* either a private address, non-routable address, or even a non-reserved
|
||||
|
|
|
|||
31
tcpip.cc
31
tcpip.cc
|
|
@ -381,37 +381,6 @@ const char *inet_socktop(const struct sockaddr_storage *ss) {
|
|||
return buf;
|
||||
}
|
||||
|
||||
/* 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 if non-NULL. */
|
||||
struct addrinfo *resolve_all(const char *hostname, int pf) {
|
||||
struct addrinfo hints;
|
||||
struct addrinfo *result;
|
||||
int rc;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = pf;
|
||||
/* Otherwise we get multiple identical addresses with different socktypes. */
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
#ifdef AI_IDN
|
||||
/* Try resolving internationalized domain names */
|
||||
hints.ai_flags = AI_IDN;
|
||||
setlocale(LC_CTYPE, "");
|
||||
#endif
|
||||
rc = getaddrinfo(hostname, NULL, &hints, &result);
|
||||
#ifdef AI_IDN
|
||||
setlocale(LC_CTYPE, o.locale);
|
||||
#endif
|
||||
if (rc != 0){
|
||||
if (o.debugging > 1)
|
||||
error("Error resolving %s: %s", hostname, gai_strerror(rc));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Send a pre-built IPv4 packet. Handles fragmentation and whether to send with
|
||||
an ethernet handle or a socket. */
|
||||
|
|
|
|||
6
tcpip.h
6
tcpip.h
|
|
@ -137,12 +137,6 @@ class PacketCounter {
|
|||
*/
|
||||
const char *inet_socktop(const struct sockaddr_storage *ss);
|
||||
|
||||
/* 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. */
|
||||
struct addrinfo *resolve_all(const char *hostname, int pf);
|
||||
|
||||
/* Takes a destination address (dst) and tries to determine the
|
||||
source address and interface necessary to route to this address.
|
||||
If no route is found, false is returned and rnfo is undefined. If
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue