From 52de87b9749469767e651466ac988f636d26598c Mon Sep 17 00:00:00 2001 From: david Date: Sat, 3 Sep 2011 18:48:11 +0000 Subject: [PATCH] Use a sockaddr_storage for recvfrom in get_rpc_results. Previously it was hardcoded to be sockaddr_in, which is obviously wrong for IPv6. This was only used to filter out packets from other than the host we are scanning. It may have still been succeeding by accident if part of the IPv6 address had the bytes 00000000, because for me the port number is at the same offset in sockaddr_in and sockaddr_in6, and target->v4host().s_addr returns 00000000 for an IPv6 host. --- nmap_rpc.cc | 26 +++++++++++++++++++++----- utils.h | 6 ------ 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/nmap_rpc.cc b/nmap_rpc.cc index f00c2e045..2b0314415 100644 --- a/nmap_rpc.cc +++ b/nmap_rpc.cc @@ -497,6 +497,19 @@ static int rpc_are_we_done(char *msg, int msg_len, Target *target, return 0; } +static unsigned short sockaddr_port(const struct sockaddr_storage *ss) { + unsigned short port; + + if (ss->ss_family == AF_INET) + port = ((struct sockaddr_in *) ss)->sin_port; + else if (ss->ss_family == AF_INET6) + port = ((struct sockaddr_in6 *) ss)->sin6_port; + else + port = 0; + + return ntohs(port); +} + void get_rpc_results(Target *target, struct portinfo *scan, struct scanstats *ss, struct portinfolist *pil, struct rpcscaninfo *rsi) { @@ -506,8 +519,9 @@ void get_rpc_results(Target *target, struct portinfo *scan, struct timeval tv; int res; static char readbuf[512]; - struct sockaddr_in from; - recvfrom6_t fromlen = sizeof(struct sockaddr_in); + struct sockaddr_storage from; + recvfrom6_t fromlen = sizeof(from); + unsigned short fromport; char *current_msg; unsigned long current_msg_len; @@ -552,13 +566,15 @@ void get_rpc_results(Target *target, struct portinfo *scan, rsi->rpc_status = RPC_STATUS_NOT_RPC; return; } + fromport = sockaddr_port(&from); if (o.debugging > 1) log_write(LOG_PLAIN, "Received %d byte UDP packet\n", res); /* Now we check that the response is from the expected host/port */ - if (from.sin_addr.s_addr != target->v4host().s_addr || - from.sin_port != htons(rsi->rpc_current_port->portno)) { + if (!sockaddr_storage_equal(&from, target->TargetSockAddr()) || + fromport != rsi->rpc_current_port->portno) { if (o.debugging > 1) { - log_write(LOG_PLAIN, "Received UDP packet from %d.%d.%d.%d/%hu when expecting packet from %d.%d.%d.%d/%hu\n", NIPQUAD(from.sin_addr.s_addr), ntohs(from.sin_port), NIPQUAD(target->v4host().s_addr), rsi->rpc_current_port->portno); + log_write(LOG_PLAIN, "Received UDP packet from %s/%hu", inet_ntop_ez(&from, fromlen), fromport); + log_write(LOG_PLAIN, " when expecting packet from %s/%hu\n", target->targetipstr(), rsi->rpc_current_port->portno); } continue; } diff --git a/utils.h b/utils.h index eb7f79a61..9115a9fdf 100644 --- a/utils.h +++ b/utils.h @@ -149,12 +149,6 @@ #define TRUE 1 #endif -#define NIPQUAD(addr) \ - (((addr) >> 0) & 0xff), \ - (((addr) >> 8) & 0xff), \ - (((addr) >> 16) & 0xff), \ - (((addr) >> 24) & 0xff) - #define MAX_PARSE_ARGS 254 /* +1 for integrity checking + 1 for null term */