Break out resolve and resolve_numeric.

Besides the confusingness of the nodns argument being negatively
phrased, it had the value 0 in every existing call. Split out the nodns
special case into a separate function resolve_numeric.

This also has the side effect of changing the number of parameters to
the resolve function, which will cause a compile error for any calls I
might have missed changing when I changed the return code meaning in the
previous commit.

Ncat has its own copy of resolve, which obeys the global o.nodns rather
than a parameter. I'm leaving that alone for now. But give it the same
resolve_internal function, and make resolve call it with different flags
depending on the value of o.nodns.
This commit is contained in:
david 2012-09-15 17:56:11 +00:00
parent 0e738370ee
commit 113e0b975f
8 changed files with 81 additions and 41 deletions

View file

@ -339,7 +339,7 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
}
proxy->host.setHostName(name);
if (resolve(name, 0, 0, &ss, &sslen, o.pf()) != 0) {
if (resolve(name, 0, &ss, &sslen, o.pf()) != 0) {
fatal("Could not resolve idle scan zombie host: %s", name);
}
proxy->host.setTargetSockAddr(&ss, sslen);

View file

@ -374,15 +374,10 @@ after:
return(d - data);
}
/* Tries to resolve the given name (or literal IP) into a sockaddr structure.
- Parameter "hostname" is the name to be resolved.
- Parameter "port" sets the port in each returned address structure
(you can safely pass 0 for the port if you don't care)
- Parameter "nodns": If set, it means that the supplied hostname is actually a
numeric IP address. The flag prevents any type of name resolution service
from being called. In 99% of the cases this should be 0.
Returns 0 on success, or a getaddrinfo return code on failure. */
int resolve(const char *hostname, u16 port, int nodns, struct sockaddr_storage *ss, size_t *sslen, int af){
/* 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, u16 port,
struct sockaddr_storage *ss, size_t *sslen, int af, int addl_flags) {
struct addrinfo hints;
struct addrinfo *result;
char portbuf[16];
@ -395,8 +390,7 @@ int resolve(const char *hostname, u16 port, int nodns, struct sockaddr_storage *
memset(&hints, 0, sizeof(hints));
hints.ai_family = af;
hints.ai_socktype = SOCK_DGRAM;
if (nodns)
hints.ai_flags |= AI_NUMERICHOST;
hints.ai_flags |= addl_flags;
/* Make the port number a string to give to getaddrinfo. */
rc = Snprintf(portbuf, sizeof(portbuf), "%hu", port);
@ -414,6 +408,23 @@ int resolve(const char *hostname, u16 port, int nodns, struct sockaddr_storage *
return 0;
}
/* Resolves the given hostname or IP address with getaddrinfo, and stores the
first result (if any) in *ss and *sslen. The value of port will be set in the
appropriate place in *ss; set to 0 if you don't care. af may be AF_UNSPEC, in
which case getaddrinfo may return e.g. both IPv4 and IPv6 results; which one
is first depends on the system configuration. Returns 0 on success, or a
getaddrinfo return code (suitable for passing to gai_strerror) on failure.
*ss and *sslen are always defined when this function returns 0. */
int resolve(const char *hostname, u16 port, struct sockaddr_storage *ss, size_t *sslen, int af) {
return resolve_internal(hostname, port, ss, sslen, af, 0);
}
/* As resolve, but do not do DNS resolution of hostnames; the first argument
must be the string representation of a numeric IP address. */
int resolve_numeric(const char *ip, u16 port, struct sockaddr_storage *ss, size_t *sslen, int af) {
return resolve_internal(ip, port, ss, sslen, af, AI_NUMERICHOST);
}
/*
* Returns 1 if this is a reserved IP address, where "reserved" means
* either a private address, non-routable address, or even a non-reserved

View file

@ -157,15 +157,18 @@ int netutil_error(const char *str, ...)
contain a newline character at the end. */
int parse_ip_options(const char *txt, u8 *data, int datalen, int* firsthopoff, int* lasthopoff, char *errstr, size_t errstrlen);
/* Tries to resolve the given name (or literal IP) into a sockaddr structure.
- Parameter "hostname" is the name to be resolved.
- Parameter "port" sets the port in each returned address structure
(you can safely pass 0 for the port if you don't care)
- Parameter "nodns": If set, it means that the supplied hostname is actually a
numeric IP address. The flag prevents any type of name resolution service
from being called. In 99% of the cases this should be 0.
Returns 0 on success, or a getaddrinfo return code on failure. */
int resolve(const char *hostname, u16 port, int nodns, struct sockaddr_storage *ss, size_t *sslen, int af);
/* Resolves the given hostname or IP address with getaddrinfo, and stores the
first result (if any) in *ss and *sslen. The value of port will be set in the
appropriate place in *ss; set to 0 if you don't care. af may be AF_UNSPEC, in
which case getaddrinfo may return e.g. both IPv4 and IPv6 results; which one
is first depends on the system configuration. Returns 0 on success, or a
getaddrinfo return code (suitable for passing to gai_strerror) on failure.
*ss and *sslen are always defined when this function returns 0. */
int resolve(const char *hostname, u16 port, struct sockaddr_storage *ss, size_t *sslen, int af);
/* As resolve, but do not do DNS resolution of hostnames; the first argument
must be the string representation of a numeric IP address. */
int resolve_numeric(const char *ip, u16 port, struct sockaddr_storage *ss, size_t *sslen, int af);
/*
* Returns 1 if this is a reserved IP address, where "reserved" means

View file

@ -180,25 +180,24 @@ void options_init(void)
#endif
}
/* Tries to resolve the given name (or literal IP) into a sockaddr structure.
Pass 0 for the port if you don't care. Returns 0 on success, or a getaddrinfo
return code on error. */
int resolve(char *hostname, unsigned short port,
struct sockaddr_storage *ss, size_t *sslen, int af)
/* 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 hints;
struct addrinfo *result;
char portbuf[16];
int rc;
size_t rc=0;
assert(hostname);
assert(ss);
assert(sslen);
memset(&hints, 0, sizeof(hints));
hints.ai_family = af;
hints.ai_socktype = SOCK_DGRAM;
if (o.nodns)
hints.ai_flags |= AI_NUMERICHOST;
hints.ai_flags |= addl_flags;
/* Make the port number a string to give to getaddrinfo. */
rc = Snprintf(portbuf, sizeof(portbuf), "%hu", port);
@ -216,6 +215,27 @@ int resolve(char *hostname, unsigned short port,
return 0;
}
/* Resolves the given hostname or IP address with getaddrinfo, and stores the
first result (if any) in *ss and *sslen. The value of port will be set in the
appropriate place in *ss; set to 0 if you don't care. af may be AF_UNSPEC, in
which case getaddrinfo may return e.g. both IPv4 and IPv6 results; which one
is first depends on the system configuration. Returns 0 on success, or a
getaddrinfo return code (suitable for passing to gai_strerror) on failure.
*ss and *sslen are always defined when this function returns 0.
If the global o.nodns is true, then do not resolve any names with DNS. */
int resolve(const char *hostname, unsigned short port,
struct sockaddr_storage *ss, size_t *sslen, int af)
{
int flags;
flags = 0;
if (o.nodns)
flags |= AI_NUMERICHOST;
return resolve_internal(hostname, port, ss, sslen, af, flags);
}
int fdinfo_close(struct fdinfo *fdn)
{
#ifdef HAVE_OPENSSL

View file

@ -172,10 +172,16 @@ extern struct timeval start_time;
/* Initializes global options to their default values. */
void options_init(void);
/* Tries to resolve the given name (or literal IP) into a sockaddr structure.
Pass 0 for the port if you don't care. Returns 0 on success, or a getaddrinfo
return code on error. */
int resolve(char *hostname, unsigned short port,
/* Resolves the given hostname or IP address with getaddrinfo, and stores the
first result (if any) in *ss and *sslen. The value of port will be set in the
appropriate place in *ss; set to 0 if you don't care. af may be AF_UNSPEC, in
which case getaddrinfo may return e.g. both IPv4 and IPv6 results; which one
is first depends on the system configuration. Returns 0 on success, or a
getaddrinfo return code (suitable for passing to gai_strerror) on failure.
*ss and *sslen are always defined when this function returns 0.
If the global o.nodns is true, then do not resolve any names with DNS. */
int resolve(const char *hostname, unsigned short port,
struct sockaddr_storage *ss, size_t *sslen, int af);
int fdinfo_close(struct fdinfo *fdn);

View file

@ -996,7 +996,7 @@ void parse_options(int argc, char **argv) {
/* Try to resolve it */
struct sockaddr_in decoytemp;
size_t decoytemplen = sizeof(struct sockaddr_in);
if (resolve(p, 0, 0, (sockaddr_storage*)&decoytemp, &decoytemplen, AF_INET) == 0) {
if (resolve(p, 0, (sockaddr_storage*)&decoytemp, &decoytemplen, AF_INET) == 0) {
o.decoys[o.numdecoys] = decoytemp.sin_addr;
o.numdecoys++;
} else {
@ -1338,7 +1338,7 @@ void apply_delayed_options() {
size_t sslen;
if (o.spoofsource) {
if (resolve(delayed_options.spoofSource, 0, 0, &ss, &sslen, o.af()) != 0)
if (resolve(delayed_options.spoofSource, 0, &ss, &sslen, o.af()) != 0)
fatal("Failed to resolve/decode supposed %s source address %s.", (o.af() == AF_INET) ? "IPv4" : "IPv6", delayed_options.spoofSource);
o.setSourceSockAddr(&ss, sslen);
}
@ -1633,7 +1633,7 @@ int nmap_main(int argc, char *argv[]) {
size_t sslen;
dst = route_dst_hosts[i].c_str();
if (resolve(dst, 0, 0, &ss, &sslen, o.af()) != 0)
if (resolve(dst, 0, &ss, &sslen, o.af()) != 0)
fatal("Can't resolve %s.", dst);
printf("%s\n", inet_ntop_ez(&ss, sslen));
@ -1936,7 +1936,7 @@ int nmap_main(int argc, char *argv[]) {
currenths->setSourceSockAddr(&ss, sslen);
} else {
if (gethostname(myname, MAXHOSTNAMELEN) ||
resolve(myname, 0, 0, &ss, &sslen, o.af()) != 0)
resolve(myname, 0, &ss, &sslen, o.af()) != 0)
fatal("Cannot get hostname! Try using -S <my_IP_address> or -e <interface to scan through>\n");
o.setSourceSockAddr(&ss, sslen);

View file

@ -820,7 +820,7 @@ static void add_dns_server(char *ipaddrs) {
for (hostname = strtok(ipaddrs, " ,"); hostname != NULL; hostname = strtok(NULL, " ,")) {
if (resolve(hostname, 0, 0, (struct sockaddr_storage *) &addr, &addr_len, PF_UNSPEC) != 0) continue;
if (resolve(hostname, 0, (struct sockaddr_storage *) &addr, &addr_len, PF_UNSPEC) != 0) continue;
for(servI = servs.begin(); servI != servs.end(); servI++) {
tpserv = *servI;

View file

@ -106,7 +106,7 @@ extern NpingOps o;
int atoIP(const char *hostname, struct in_addr *dst){
struct sockaddr_in i;
unsigned int stlen=0;
if ( resolve(hostname, 0, 0, (sockaddr_storage*)&i, (size_t *)&stlen , PF_INET) != 0 )
if ( resolve(hostname, 0, (sockaddr_storage*)&i, (size_t *)&stlen , PF_INET) != 0 )
return OP_FAILURE;
*dst=i.sin_addr;
return OP_SUCCESS;
@ -118,7 +118,7 @@ int atoIP(const char *hostname, struct sockaddr_storage *ss, int family){
return OP_FAILURE;
if(family!=AF_INET && family!=AF_INET6)
return OP_FAILURE;
if ( resolve(hostname, 0, 0, ss, &stlen , family) != 0 )
if ( resolve(hostname, 0, ss, &stlen , family) != 0 )
return OP_FAILURE;
return OP_SUCCESS;
} /* End of atoIP */
@ -556,7 +556,7 @@ int resolveCached(char *host, struct sockaddr_storage *ss, size_t *sslen, int pf
misses++;
outPrint(DBG_4, "resolveCached(): Cache miss %d for %s\n", misses, host);
if( (result=resolve(host, 0, 0, ss, sslen, pf)) == 0 ){
if( (result=resolve(host, 0, ss, sslen, pf)) == 0 ){
/* Increment count */
if( cached_count < MAX_CACHED_HOSTS )