Common subdirectories: nmap-3.10ALPHA9/docs and nmap-3.10ALPHA9-tcp-multiport/docs Common subdirectories: nmap-3.10ALPHA9/libpcap-possiblymodified and nmap-3.10ALPHA9-tcp-multiport/libpcap-possiblymodified Common subdirectories: nmap-3.10ALPHA9/mswin32 and nmap-3.10ALPHA9-tcp-multiport/mswin32 Common subdirectories: nmap-3.10ALPHA9/nbase and nmap-3.10ALPHA9-tcp-multiport/nbase Common subdirectories: nmap-3.10ALPHA9/nmapfe and nmap-3.10ALPHA9-tcp-multiport/nmapfe diff -U4 nmap-3.10ALPHA9/NmapOps.cc nmap-3.10ALPHA9-tcp-multiport/NmapOps.cc --- nmap-3.10ALPHA9/NmapOps.cc 2002-12-25 01:13:04.000000000 -0700 +++ nmap-3.10ALPHA9-tcp-multiport/NmapOps.cc 2003-02-06 11:00:00.000000000 -0700 @@ -197,22 +197,11 @@ if (connectscan && spoofsource) { error("WARNING: -S will only affect the source address used in a connect() scan if you specify one of your own addresses. Use -sS or another raw scan if you want to completely spoof your source address, but then you need to know what you're doing to obtain meaningful results."); } - if ((pingtype & PINGTYPE_TCP) && (!o.isr00t || o.af() != AF_INET)) { - /* We will have to do a connect() style ping */ - if (num_ping_synprobes && num_ping_ackprobes) { - fatal("WARNING: Cannot use both SYN and ACK ping probes if you are nonroot or using IPv6"); - } - if (num_ping_synprobes > 1 || num_ping_ackprobes > 1) { - error("WARNING: Multiple probe ports were given, but only the first one will be used for your connect()-style TCP ping."); - } - - if (num_ping_synprobes > 0) { - num_ping_ackprobes = 1; - num_ping_synprobes = 0; - ping_ackprobes[0] = ping_synprobes[0]; - } + /* We'll have to do a connect() style ping; make sure we only use ACK probes */ + if ((pingtype & PINGTYPE_TCP) && (!o.isr00t || o.af() != AF_INET) && num_ping_synprobes) { + fatal("WARNING: Please use ACK ping probes only if you are nonroot or using IPv6"); } if (ipprotscan + (TCPScan() || UDPScan()) + listscan + pingscan > 1) { fatal("Sorry, the IPProtoscan, Listscan, and Pingscan (-sO, -sL, -sP) must currently be used alone rathre than combined with other scan types."); diff -U4 nmap-3.10ALPHA9/NmapOps.h nmap-3.10ALPHA9-tcp-multiport/NmapOps.h --- nmap-3.10ALPHA9/NmapOps.h 2002-12-25 00:58:57.000000000 -0700 +++ nmap-3.10ALPHA9-tcp-multiport/NmapOps.h 2003-02-06 10:47:29.000000000 -0700 @@ -90,9 +90,9 @@ u16 magic_port; unsigned short magic_port_set; /* Was this set by user? */ int num_ping_synprobes; u16 ping_synprobes[MAX_PROBE_PORTS]; - /* The first of the "ackprobes" is used when doing a connect() ping */ + /* The "ackprobes" are also used when doing a connect() ping */ int num_ping_ackprobes; u16 ping_ackprobes[MAX_PROBE_PORTS]; /* Scan timing/politeness issues */ diff -U4 nmap-3.10ALPHA9/targets.cc nmap-3.10ALPHA9-tcp-multiport/targets.cc --- nmap-3.10ALPHA9/targets.cc 2002-12-25 01:00:20.000000000 -0700 +++ nmap-3.10ALPHA9-tcp-multiport/targets.cc 2003-02-10 07:32:11.000000000 -0700 @@ -85,8 +85,9 @@ { int hostnum = gethostnum(hostbatch, target); int i; + int p; int seq; int tmpsd; struct timeval tv; @@ -103,21 +104,23 @@ /* If this is a tcp connect() pingscan, close all sockets */ if (style == pingstyle_connecttcp) { seq = hostnum * pt->max_tries + trynum; - assert(tqi->sockets[seq] >= 0); - for(i=0; i <= pt->block_tries; i++) { - seq = hostnum * pt->max_tries + i; - tmpsd = tqi->sockets[seq]; - if (tmpsd >= 0) { - assert(tqi->sockets_out > 0); - tqi->sockets_out--; - close(tmpsd); - if (tmpsd == tqi->maxsd) tqi->maxsd--; - FD_CLR(tmpsd, &(tqi->fds_r)); - FD_CLR(tmpsd, &(tqi->fds_w)); - FD_CLR(tmpsd, &(tqi->fds_x)); - tqi->sockets[seq] = -1; + for(p=0; p < o.num_ping_ackprobes; p++) { + assert(tqi->sockets[p][seq] >= 0); + for(i=0; i <= pt->block_tries; i++) { + seq = hostnum * pt->max_tries + i; + tmpsd = tqi->sockets[p][seq]; + if (tmpsd >= 0) { + assert(tqi->sockets_out > 0); + tqi->sockets_out--; + close(tmpsd); + if (tmpsd == tqi->maxsd) tqi->maxsd--; + FD_CLR(tmpsd, &(tqi->fds_r)); + FD_CLR(tmpsd, &(tqi->fds_w)); + FD_CLR(tmpsd, &(tqi->fds_x)); + tqi->sockets[p][seq] = -1; + } } } } @@ -310,8 +313,9 @@ pcap_t *pd = NULL; char filter[512]; unsigned short sportbase; int max_width = 0; +int p; int group_start, group_end, direction; /* For going forward or backward through grouplen */ bzero((char *)&ptech, sizeof(ptech)); @@ -341,17 +345,13 @@ ptech.rawtcpscan = 1; else ptech.connecttcpscan = 1; } - if (ptech.connecttcpscan) - probes_per_host = 1; /* Only the first probe port is used in this case */ - else { - probes_per_host = 0; - if (pingtype & PINGTYPE_ICMP_PING) probes_per_host++; - if (pingtype & PINGTYPE_ICMP_MASK) probes_per_host++; - if (pingtype & PINGTYPE_ICMP_TS) probes_per_host++; - probes_per_host += o.num_ping_synprobes + o.num_ping_ackprobes; - } + probes_per_host = 0; + if (pingtype & PINGTYPE_ICMP_PING) probes_per_host++; + if (pingtype & PINGTYPE_ICMP_MASK) probes_per_host++; + if (pingtype & PINGTYPE_ICMP_TS) probes_per_host++; + probes_per_host += o.num_ping_synprobes + o.num_ping_ackprobes; pt.min_group_size = MAX(3, MAX(o.min_parallelism, 16) / probes_per_host); pt.group_size = (o.max_parallelism)? MIN(o.max_parallelism, gsize) : gsize; @@ -366,15 +366,15 @@ if (ptech.connecttcpscan) { max_width = (o.max_parallelism)? o.max_parallelism : MAX(1, max_sd() - 4); max_block_size = MIN(50, max_width); -} + bzero((char *)&tqi, sizeof(tqi)); -bzero((char *)&tqi, sizeof(tqi)); -if (ptech.connecttcpscan) { - tqi.sockets = (int *) safe_malloc(sizeof(int) * (pt.max_tries) * num_hosts); - memset(tqi.sockets, 255, sizeof(int) * (pt.max_tries) * num_hosts); + for(p=0; p < o.num_ping_ackprobes; p++) { + tqi.sockets[p] = (int *) safe_malloc(sizeof(int) * (pt.max_tries) * num_hosts); + memset(tqi.sockets[p], 255, sizeof(int) * (pt.max_tries) * num_hosts); + } FD_ZERO(&(tqi.fds_r)); FD_ZERO(&(tqi.fds_w)); FD_ZERO(&(tqi.fds_x)); tqi.sockets_out = 0; @@ -474,10 +474,9 @@ if (ptech.rawtcpscan) sendrawtcppingqueries(rawsd, hostbatch[hostnum], pingtype, seq, time, &pt); else if (ptech.connecttcpscan) { - /* still only one port probed for connect tcp */ - sendconnecttcpquery(hostbatch, &tqi, hostbatch[hostnum], o.ping_ackprobes[0], seq, time, &pt, &to, max_width); + sendconnecttcpqueries(hostbatch, &tqi, hostbatch[hostnum], seq, time, &pt, &to, max_width); } pt.block_unaccounted++; gettimeofday(&t2, NULL); if (TIMEVAL_SUBTRACT(t2,time[seq]) > 1000000) { @@ -524,9 +523,11 @@ /* pt.block_unaccounted = pt.group_end - pt.group_start + 1; */ } close(sd); - if (ptech.connecttcpscan) free(tqi.sockets); + if (ptech.connecttcpscan) + for(p=0; p < o.num_ping_ackprobes; p++) + free(tqi.sockets[p]); if (sd >= 0) close(sd); if (rawsd >= 0) close(rawsd); if (rawpingsd >= 0) close(rawpingsd); free(time); @@ -536,10 +537,24 @@ gsize = pt.group_size; return; } +int sendconnecttcpqueries(Target *hostbatch[], struct tcpqueryinfo *tqi, + Target *target, int seq, + struct timeval *time, struct pingtune *pt, + struct timeout_info *to, int max_width) { + int i; + + for( i=0; i 0 && o.scan_delay) enforce_scan_delay(NULL); + sendconnecttcpquery(hostbatch, tqi, target, i, seq, time, pt, to, max_width); + } + + return 0; +} + int sendconnecttcpquery(Target *hostbatch[], struct tcpqueryinfo *tqi, - Target *target, u16 probe_port, int seq, + Target *target, int probe_port_num, int seq, struct timeval *time, struct pingtune *pt, struct timeout_info *to, int max_width) { int res,i; @@ -557,13 +572,13 @@ if (tqi->sockets_out == max_width) { /* We've got to free one! */ for(i=0; i < trynum; i++) { tmpsd = hostnum * pt->max_tries + i; - if (tqi->sockets[tmpsd] >= 0) { + if (tqi->sockets[probe_port_num][tmpsd] >= 0) { if (o.debugging) log_write(LOG_STDOUT, "sendconnecttcpquery: Scavenging a free socket due to serious shortage\n"); - close(tqi->sockets[tmpsd]); - tqi->sockets[tmpsd] = -1; + close(tqi->sockets[probe_port_num][tmpsd]); + tqi->sockets[probe_port_num][tmpsd] = -1; tqi->sockets_out--; break; } } @@ -571,35 +586,35 @@ fatal("sendconnecttcpquery: Could not scavenge a free socket!"); } /* Since we know we now have a free s0cket, lets take it */ - assert(tqi->sockets[seq] == -1); - tqi->sockets[seq] = socket(o.af(), SOCK_STREAM, IPPROTO_TCP); - if (tqi->sockets[seq] == -1) + assert(tqi->sockets[probe_port_num][seq] == -1); + tqi->sockets[probe_port_num][seq] = socket(o.af(), SOCK_STREAM, IPPROTO_TCP); + if (tqi->sockets[probe_port_num][seq] == -1) fatal("Socket creation in sendconnecttcpquery"); - tqi->maxsd = MAX(tqi->maxsd, tqi->sockets[seq]); + tqi->maxsd = MAX(tqi->maxsd, tqi->sockets[probe_port_num][seq]); tqi->sockets_out++; - unblock_socket(tqi->sockets[seq]); - init_socket(tqi->sockets[seq]); + unblock_socket(tqi->sockets[probe_port_num][seq]); + init_socket(tqi->sockets[probe_port_num][seq]); if (target->TargetSockAddr(&sock, &socklen) != 0) fatal("Unable to get target sock in sendconnecttcpquery"); if (sin->sin_family == AF_INET) - sin->sin_port = htons(probe_port); + sin->sin_port = htons(o.ping_ackprobes[probe_port_num]); #if HAVE_IPV6 - else sin6->sin6_port = htons(probe_port); + else sin6->sin6_port = htons(o.ping_ackprobes[probe_port_num]); #endif //HAVE_IPV6 - res = connect(tqi->sockets[seq],(struct sockaddr *)&sock, socklen); + res = connect(tqi->sockets[probe_port_num][seq],(struct sockaddr *)&sock, socklen); gettimeofday(&time[seq], NULL); if ((res != -1 || errno == ECONNREFUSED)) { /* This can happen on localhost, successful/failing connection immediately in non-blocking mode */ hostupdate(hostbatch, target, HOST_UP, 1, trynum, to, &time[seq], pt, tqi, pingstyle_connecttcp); - if (tqi->maxsd == tqi->sockets[seq]) tqi->maxsd--; + if (tqi->maxsd == tqi->sockets[probe_port_num][seq]) tqi->maxsd--; } else if (errno == ENETUNREACH) { if (o.debugging) error("Got ENETUNREACH from sendconnecttcpquery connect()"); @@ -607,11 +622,11 @@ &time[seq], pt, tqi, pingstyle_connecttcp); } else { /* We'll need to select() and wait it out */ - FD_SET(tqi->sockets[seq], &(tqi->fds_r)); - FD_SET(tqi->sockets[seq], &(tqi->fds_w)); - FD_SET(tqi->sockets[seq], &(tqi->fds_x)); + FD_SET(tqi->sockets[probe_port_num][seq], &(tqi->fds_r)); + FD_SET(tqi->sockets[probe_port_num][seq], &(tqi->fds_w)); + FD_SET(tqi->sockets[probe_port_num][seq], &(tqi->fds_x)); } return 0; } @@ -776,8 +791,9 @@ struct timeval myto, start, end; int hostindex; int trynum, newstate = HOST_DOWN; int seq; +int p; char buf[256]; int foundsomething = 0; fd_set myfds_r,myfds_w,myfds_x; gettimeofday(&start, NULL); @@ -794,73 +810,75 @@ if (res > 0) { for(hostindex = pt->group_start; hostindex <= pt->group_end; hostindex++) { for(trynum=0; trynum <= pt->block_tries; trynum++) { seq = hostindex * pt->max_tries + trynum; - if (tqi->sockets[seq] >= 0) { - if (o.debugging > 1) { - if (FD_ISSET(tqi->sockets[seq], &(myfds_r))) { - log_write(LOG_STDOUT, "WRITE selected for machine %s\n", hostbatch[hostindex]->targetipstr()); - } - if ( FD_ISSET(tqi->sockets[seq], &myfds_w)) { - log_write(LOG_STDOUT, "READ selected for machine %s\n", hostbatch[hostindex]->targetipstr()); - } - if ( FD_ISSET(tqi->sockets[seq], &myfds_x)) { - log_write(LOG_STDOUT, "EXC selected for machine %s\n", hostbatch[hostindex]->targetipstr()); + for(p=0; p < o.num_ping_ackprobes; p++) { + if (tqi->sockets[p][seq] >= 0) { + if (o.debugging > 1) { + if (FD_ISSET(tqi->sockets[p][seq], &(myfds_r))) { + log_write(LOG_STDOUT, "WRITE selected for machine %s\n", hostbatch[hostindex]->targetipstr()); + } + if ( FD_ISSET(tqi->sockets[p][seq], &myfds_w)) { + log_write(LOG_STDOUT, "READ selected for machine %s\n", hostbatch[hostindex]->targetipstr()); + } + if ( FD_ISSET(tqi->sockets[p][seq], &myfds_x)) { + log_write(LOG_STDOUT, "EXC selected for machine %s\n", hostbatch[hostindex]->targetipstr()); + } } - } - if (FD_ISSET(tqi->sockets[seq], &myfds_r) || FD_ISSET(tqi->sockets[seq], &myfds_w) || FD_ISSET(tqi->sockets[seq], &myfds_x)) { - foundsomething = 0; - res2 = read(tqi->sockets[seq], buf, sizeof(buf) - 1); - if (res2 == -1) { - switch(errno) { - case ECONNREFUSED: - case EAGAIN: + if (FD_ISSET(tqi->sockets[p][seq], &myfds_r) || FD_ISSET(tqi->sockets[p][seq], &myfds_w) || FD_ISSET(tqi->sockets[p][seq], &myfds_x)) { + foundsomething = 0; + res2 = read(tqi->sockets[p][seq], buf, sizeof(buf) - 1); + if (res2 == -1) { + switch(errno) { + case ECONNREFUSED: + case EAGAIN: #ifdef WIN32 // case WSAENOTCONN: // needed? this fails around here on my system #endif - if (errno == EAGAIN && o.verbose) { - log_write(LOG_STDOUT, "Machine %s MIGHT actually be listening on probe port %d\n", hostbatch[hostindex]->targetipstr(), o.ping_ackprobes[0]); - } - foundsomething = 1; - newstate = HOST_UP; - break; - case ENETDOWN: - case ENETUNREACH: - case ENETRESET: - case ECONNABORTED: - case ETIMEDOUT: - case EHOSTDOWN: - case EHOSTUNREACH: - foundsomething = 1; - newstate = HOST_DOWN; - break; - default: - snprintf (buf, sizeof(buf), "Strange read error from %s", hostbatch[hostindex]->targetipstr()); - perror(buf); - break; + if (errno == EAGAIN && o.verbose) { + log_write(LOG_STDOUT, "Machine %s MIGHT actually be listening on probe port %d\n", hostbatch[hostindex]->targetipstr(), o.ping_ackprobes[p]); + } + foundsomething = 1; + newstate = HOST_UP; + break; + case ENETDOWN: + case ENETUNREACH: + case ENETRESET: + case ECONNABORTED: + case ETIMEDOUT: + case EHOSTDOWN: + case EHOSTUNREACH: + foundsomething = 1; + newstate = HOST_DOWN; + break; + default: + snprintf (buf, sizeof(buf), "Strange read error from %s", hostbatch[hostindex]->targetipstr()); + perror(buf); + break; + } + } else { + foundsomething = 1; + newstate = HOST_UP; + if (o.verbose) { + buf[res2] = '\0'; + if (res2 == 0) + log_write(LOG_STDOUT, "Machine %s is actually LISTENING on probe port %d\n", + hostbatch[hostindex]->targetipstr(), + o.ping_ackprobes[p]); + else + log_write(LOG_STDOUT, "Machine %s is actually LISTENING on probe port %d, banner: %s\n", + hostbatch[hostindex]->targetipstr(), + o.ping_ackprobes[p], buf); + } } - } else { - foundsomething = 1; - newstate = HOST_UP; - if (o.verbose) { - buf[res2] = '\0'; - if (res2 == 0) - log_write(LOG_STDOUT, "Machine %s is actually LISTENING on probe port %d\n", - hostbatch[hostindex]->targetipstr(), - o.ping_ackprobes[0]); - else - log_write(LOG_STDOUT, "Machine %s is actually LISTENING on probe port %d, banner: %s\n", - hostbatch[hostindex]->targetipstr(), - o.ping_ackprobes[0], buf); - } - } - if (foundsomething) { - hostupdate(hostbatch, hostbatch[hostindex], newstate, 1, trynum, + if (foundsomething) { + hostupdate(hostbatch, hostbatch[hostindex], newstate, 1, trynum, to, &time[seq], pt, tqi, pingstyle_connecttcp); /* break;*/ + } } } - } + } } } } gettimeofday(&end, NULL); @@ -876,12 +894,14 @@ the next group :( I'll miss these little guys. */ for(hostindex = pt->group_start; hostindex <= pt->group_end; hostindex++) { for(trynum=0; trynum <= pt->block_tries; trynum++) { seq = hostindex * pt->max_tries + trynum; - if ( tqi->sockets[seq] >= 0) { - tqi->sockets_out--; - close(tqi->sockets[seq]); - tqi->sockets[seq] = -1; + for(p=0; p < o.num_ping_ackprobes; p++) { + if ( tqi->sockets[p][seq] >= 0) { + tqi->sockets_out--; + close(tqi->sockets[p][seq]); + tqi->sockets[p][seq] = -1; + } } } } tqi->maxsd = 0; diff -U4 nmap-3.10ALPHA9/targets.h nmap-3.10ALPHA9-tcp-multiport/targets.h --- nmap-3.10ALPHA9/targets.h 2002-12-25 00:50:15.000000000 -0700 +++ nmap-3.10ALPHA9-tcp-multiport/targets.h 2003-02-06 15:39:06.000000000 -0700 @@ -90,9 +90,9 @@ int discardtimesbefore; }; struct tcpqueryinfo { - int *sockets; + int *sockets[MAX_PROBE_PORTS]; int maxsd; fd_set fds_r; fd_set fds_w; fd_set fds_x; @@ -120,9 +120,11 @@ int sendrawtcppingqueries(int rawsd, Target *target, int pingtype, int seq, struct timeval *time, struct pingtune *pt); int sendrawtcppingquery(int rawsd, Target *target, int pingtype, u16 probe_port, int seq, struct timeval *time, struct pingtune *pt); -int sendconnecttcpquery(Target *hostbatch[], struct tcpqueryinfo *tqi, Target *target, u16 probe_port, +int sendconnecttcpqueries(Target *hostbatch[], struct tcpqueryinfo *tqi, Target *target, + int seq, struct timeval *time, struct pingtune *pt, struct timeout_info *to, int max_width); +int sendconnecttcpquery(Target *hostbatch[], struct tcpqueryinfo *tqi, Target *target, int probe_port_num, int seq, struct timeval *time, struct pingtune *pt, struct timeout_info *to, int max_width); int get_connecttcpscan_results(struct tcpqueryinfo *tqi, Target *hostbatch[], struct timeval *time, struct pingtune *pt,