From 07011cbb99dd3daeaeff03796ddee9fafb48a5c2 Mon Sep 17 00:00:00 2001 From: josh Date: Sat, 6 Jun 2009 00:04:31 +0000 Subject: [PATCH] Made a change to validate_scan_lists to combine port lists when -PA and -PS are called together when nmap is running as nonroot or using IPv6. --- CHANGELOG | 4 ++++ nmap.cc | 52 +++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 525055ac7..aa1e81d09 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,9 @@ # Nmap Changelog ($Id$); -*-text-*- +o Tweaked validate_scan_lists so as to handle -SP and -SA at the same time when + running nmap as nonroot or using IPv6. It now combines the two port lists + [Josh Marlow] + o Added another case to NmapOps::RawScan() to cover the case where we are using a SYN ping scan and issuing raw packets. This fixes a bug wherein nmap would not display the "Raw packets sent..." message [Josh Marlow] diff --git a/nmap.cc b/nmap.cc index 8c968cfb8..a9125eaba 100644 --- a/nmap.cc +++ b/nmap.cc @@ -450,6 +450,21 @@ static char *grab_next_host_spec(FILE *inputfd, int argc, char **fakeargv) { return host_spec; } +static int insert_port_into_merge_list(unsigned short *mlist, + int *merged_port_count, int idx, + unsigned short p) { + int i; + // make sure the port isn't already in the list + for (i = 0; i < idx; i++) { + if (mlist[i] == p) { + (*merged_port_count)--; + return idx; + } + } + mlist[idx] = p; + return idx + 1; +} + void validate_scan_lists(scan_lists &ports, NmapOps &o){ if (o.pingtype == PINGTYPE_UNKNOWN) { if (o.isr00t && o.pf() == PF_INET) { @@ -467,13 +482,40 @@ void validate_scan_lists(scan_lists &ports, NmapOps &o){ if ((o.pingtype & PINGTYPE_TCP) && (!o.isr00t || o.pf() != PF_INET)) { // We will have to do a connect() style ping - if (ports.syn_ping_count && ports.ack_ping_count) { - fatal("Cannot use both SYN and ACK ping probes if you are nonroot or using IPv6"); - } // Pretend we wanted SYN probes all along. if (ports.ack_ping_count > 0) { - ports.syn_ping_count = ports.ack_ping_count; - ports.syn_ping_ports = ports.ack_ping_ports; + // Combine the ACK and SYN ping port lists since they both reduce to + // SYN probes in this case + int merged_port_count, i, j = 0; + unsigned short *merged_port_list = NULL; + + merged_port_count = ports.ack_ping_count + ports.syn_ping_count; + merged_port_list = + (unsigned short *) safe_zalloc(merged_port_count * sizeof(unsigned short)); + + for (i = 0; i < ports.syn_ping_count; i++) { + j = insert_port_into_merge_list(merged_port_list, + &merged_port_count, j, + ports.syn_ping_ports[i]); + } + for (i = 0; i < ports.ack_ping_count; i++) { + j = insert_port_into_merge_list(merged_port_list, + &merged_port_count, j, + ports.ack_ping_ports[i]); + } + + // if there were duplicate ports then we can save some memory + if (merged_port_count < (ports.ack_ping_count + ports.syn_ping_count)) { + merged_port_list = (unsigned short*) + safe_realloc(merged_port_list, merged_port_count); + } + + // clean up a bit + free(ports.syn_ping_ports); + free(ports.ack_ping_ports); + + ports.syn_ping_count = merged_port_count; + ports.syn_ping_ports = merged_port_list; ports.ack_ping_count = 0; ports.ack_ping_ports = NULL; }