1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-17 21:19:01 +00:00

adding IPv6 support to RPC scan

This commit is contained in:
kris
2008-01-15 00:50:26 +00:00
parent 9bc09ef2cc
commit 1a5657511f
5 changed files with 56 additions and 29 deletions

View File

@@ -1,5 +1,9 @@
# Nmap Changelog ($Id$); -*-text-*- # Nmap Changelog ($Id$); -*-text-*-
o Added IPv6 host support to the RPC scan. Attempting this before
(via -sV) caused a segmentation fault. Thanks to Will Cladek for
the report. [Kris]
o We now escape newlines, carriage returns, and tabs (\n\r\t) in XML o We now escape newlines, carriage returns, and tabs (\n\r\t) in XML
output. While those are allowed in XML attributes, they get output. While those are allowed in XML attributes, they get
normalized which can make formatting the output difficult for normalized which can make formatting the output difficult for

View File

@@ -479,7 +479,7 @@ void NmapOps::ValidateOptions() {
fatal("--min-parallelism=%i must be less than or equal to --max-parallelism=%i",min_parallelism,max_parallelism); fatal("--min-parallelism=%i must be less than or equal to --max-parallelism=%i",min_parallelism,max_parallelism);
} }
if (af() == AF_INET6 && (numdecoys|osscan|bouncescan|fragscan|ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|rpcscan|synscan|udpscan|windowscan|xmasscan)) { if (af() == AF_INET6 && (numdecoys|osscan|bouncescan|fragscan|ackscan|finscan|idlescan|ipprotscan|maimonscan|nullscan|synscan|udpscan|windowscan|xmasscan)) {
fatal("Sorry -- IPv6 support is currently only available for connect() scan (-sT), ping scan (-sP), and list scan (-sL). OS detection and decoys are also not supported with IPv6. Further support is under consideration."); fatal("Sorry -- IPv6 support is currently only available for connect() scan (-sT), ping scan (-sP), and list scan (-sL). OS detection and decoys are also not supported with IPv6. Further support is under consideration.");
} }

View File

@@ -212,13 +212,17 @@ int get_rpc_procs(unsigned long **programs, unsigned long *num_programs) {
/* Send an RPC query to the specified host/port on the specified protocol /* Send an RPC query to the specified host/port on the specified protocol
looking for the specified RPC program. We cache our sending sockets looking for the specified RPC program. We cache our sending sockets
to avoid recreating and (with TCP) reconnect()'ing them each time */ to avoid recreating and (with TCP) reconnect()'ing them each time */
int send_rpc_query(const struct in_addr *target_host, unsigned short portno, int send_rpc_query(Target *target_host, unsigned short portno,
int ipproto, unsigned long program, int scan_offset, int ipproto, unsigned long program, int scan_offset,
int trynum) { int trynum) {
static struct in_addr last_target_host; static struct sockaddr_storage last_target;
struct sockaddr_storage sock;
size_t socklen;
static int last_ipproto = -1; static int last_ipproto = -1;
static unsigned short last_portno = 0; struct sockaddr_in *sin = NULL, *lastsin = NULL;
struct sockaddr_in sock; #ifdef HAVE_IPV6
struct sockaddr_in6 *sin6 = NULL, *lastsin6 = NULL;
#endif
char rpch_buf[256]; char rpch_buf[256];
struct rpc_hdr *rpch; struct rpc_hdr *rpch;
int res, err = 0; int res, err = 0;
@@ -238,38 +242,57 @@ int send_rpc_query(const struct in_addr *target_host, unsigned short portno,
log_write(LOG_PLAIN, "Sending RPC probe for program %li to %hu/%s -- scan_offset=%d trynum=%d xid=%lX\n", program, portno, proto2ascii(ipproto), scan_offset, trynum, rpc_xid_base + ((portno & 0x3FFF) << 16) + (trynum << 30) + scan_offset); log_write(LOG_PLAIN, "Sending RPC probe for program %li to %hu/%s -- scan_offset=%d trynum=%d xid=%lX\n", program, portno, proto2ascii(ipproto), scan_offset, trynum, rpc_xid_base + ((portno & 0x3FFF) << 16) + (trynum << 30) + scan_offset);
} }
memset(&sock, 0, sizeof(sock));
target_host->TargetSockAddr(&sock, &socklen);
if (sock.ss_family == AF_INET) {
sin = (struct sockaddr_in *) &sock;
lastsin = (struct sockaddr_in *) &last_target;
sin->sin_port = htons(portno);
}
#ifdef HAVE_IPV6
else {
sin6 = (struct sockaddr_in6 *) &sock;
lastsin6 = (struct sockaddr_in6 *) &last_target;
sin6->sin6_port = htons(portno);
}
#endif
/* First we check whether we have to create a new connection -- we /* First we check whether we have to create a new connection -- we
need to if we have a new target_host, or a new portno, or the socket need to if we have a new target_host, or a new portno, or the socket
we want to use is -1 */ we want to use is -1 */
if (ipproto == IPPROTO_TCP && if (ipproto == IPPROTO_TCP) {
(last_target_host.s_addr != target_host->s_addr || if ((sock.ss_family == AF_INET &&
last_portno != portno || last_ipproto != IPPROTO_TCP)) { memcmp(sin, lastsin, sizeof(struct sockaddr_in)))
/* New host or port -- kill our old tcp socket */ #ifdef HAVE_IPV6
if (tcp_rpc_socket != -1) { || (sock.ss_family == AF_INET6 &&
close(tcp_rpc_socket); memcmp(sin6, lastsin6, sizeof(struct sockaddr_in6)))
tcp_rpc_socket = -1; #endif
tcp_readlen = 0; || last_ipproto != IPPROTO_TCP) {
/* New host or port -- kill our old tcp socket */
if (tcp_rpc_socket != -1) {
close(tcp_rpc_socket);
tcp_rpc_socket = -1;
tcp_readlen = 0;
}
} }
} }
last_ipproto = ipproto;
last_target_host.s_addr = target_host->s_addr;
last_portno = portno;
memset(&sock, 0, sizeof(sock)); last_target = sock;
sock.sin_family = AF_INET; last_ipproto = ipproto;
sock.sin_addr.s_addr = target_host->s_addr;
sock.sin_port = htons(portno);
if (ipproto == IPPROTO_TCP && tcp_rpc_socket == -1) { if (ipproto == IPPROTO_TCP && tcp_rpc_socket == -1) {
if ((tcp_rpc_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) if ((tcp_rpc_socket = socket(sock.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1)
pfatal("Socket troubles in %s", __func__); pfatal("Socket troubles in %s", __func__);
/* I should unblock the socket here and timeout the connect() */ /* I should unblock the socket here and timeout the connect() */
res = connect(tcp_rpc_socket, (struct sockaddr *) &sock, res = connect(tcp_rpc_socket, (struct sockaddr *) &sock,
sizeof(struct sockaddr_in)); sizeof(struct sockaddr_storage));
if (res == -1) { if (res == -1) {
if (o.debugging) { if (o.debugging) {
gh_perror("Failed to connect to port %d of %s in %s", gh_perror("Failed to connect to port %d of %s in %s",
portno, inet_ntoa(*target_host), __func__); portno, target_host->targetipstr(), __func__);
} }
close(tcp_rpc_socket); close(tcp_rpc_socket);
tcp_rpc_socket = -1; tcp_rpc_socket = -1;
@@ -277,7 +300,7 @@ int send_rpc_query(const struct in_addr *target_host, unsigned short portno,
} }
unblock_socket(tcp_rpc_socket); unblock_socket(tcp_rpc_socket);
} else if (ipproto == IPPROTO_UDP && udp_rpc_socket == -1) { } else if (ipproto == IPPROTO_UDP && udp_rpc_socket == -1) {
if ((udp_rpc_socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1) if ((udp_rpc_socket = socket(sock.ss_family, SOCK_DGRAM, 0)) == -1)
pfatal("UDP socket troubles in %s", __func__); pfatal("UDP socket troubles in %s", __func__);
unblock_socket(udp_rpc_socket); unblock_socket(udp_rpc_socket);
} }
@@ -306,7 +329,7 @@ int send_rpc_query(const struct in_addr *target_host, unsigned short portno,
if (o.debugging > 1) if (o.debugging > 1)
hdump((unsigned char *) rpch, sizeof(struct rpc_hdr)); hdump((unsigned char *) rpch, sizeof(struct rpc_hdr));
res = sendto(udp_rpc_socket, (char *)rpch, sizeof(struct rpc_hdr), 0, res = sendto(udp_rpc_socket, (char *)rpch, sizeof(struct rpc_hdr), 0,
(struct sockaddr *) &sock, sizeof(struct sockaddr_in)); (struct sockaddr *) &sock, sizeof(struct sockaddr_storage));
if (res == -1) if (res == -1)
err = socket_errno(); err = socket_errno();
} while(res == -1 && (err == EINTR || err == ENOBUFS)); } while(res == -1 && (err == EINTR || err == ENOBUFS));

View File

@@ -176,7 +176,7 @@ struct rpcscaninfo {
int get_rpc_procs(unsigned long **programs, unsigned long *num_programs); int get_rpc_procs(unsigned long **programs, unsigned long *num_programs);
char *nmap_getrpcnamebynum(unsigned long num); char *nmap_getrpcnamebynum(unsigned long num);
int send_rpc_query(const struct in_addr *target_host, unsigned short portno, int send_rpc_query(Target *target_host, unsigned short portno,
int ipproto, unsigned long program, int scan_offset, int ipproto, unsigned long program, int scan_offset,
int trynum); int trynum);
void get_rpc_results(Target *target, struct portinfo *scan, void get_rpc_results(Target *target, struct portinfo *scan,

View File

@@ -5098,7 +5098,7 @@ void pos_scan(Target *target, u16 *portarray, int numports, stype scantype) {
current->trynum++; current->trynum++;
gettimeofday(&current->sent[current->trynum], NULL); gettimeofday(&current->sent[current->trynum], NULL);
now = current->sent[current->trynum]; now = current->sent[current->trynum];
if (send_rpc_query(target->v4hostip(), rsi.rpc_current_port->portno, if (send_rpc_query(target, rsi.rpc_current_port->portno,
rsi.rpc_current_port->proto, rsi.rpc_current_port->proto,
current->portno, current - scan, current->portno, current - scan,
current->trynum) == -1) { current->trynum) == -1) {
@@ -5126,7 +5126,7 @@ void pos_scan(Target *target, u16 *portarray, int numports, stype scantype) {
/* if (!testinglist) testinglist = current; */ /* if (!testinglist) testinglist = current; */
ss.numqueries_outstanding++; ss.numqueries_outstanding++;
gettimeofday(&current->sent[0], NULL); gettimeofday(&current->sent[0], NULL);
if (send_rpc_query(target->v4hostip(), if (send_rpc_query(target,
rsi.rpc_current_port->portno, rsi.rpc_current_port->portno,
rsi.rpc_current_port->proto, current->portno, rsi.rpc_current_port->proto, current->portno,
current - scan, current->trynum) == -1) { current - scan, current->trynum) == -1) {