1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00

Allow IPv6 fingerprinting to continue if sendto fails

http://seclists.org/nmap-dev/2014/q3/201

The fingerprint will be marked G=N, so ineligible for submission. Still
matches well against scanme.nmap.org, though.
This commit is contained in:
dmiller
2014-08-27 03:08:29 +00:00
parent 062b780a48
commit 8e4f61725e
4 changed files with 27 additions and 1 deletions

View File

@@ -463,7 +463,10 @@ void FPNetworkControl::probe_transmission_handler(nsock_pool nsp, nsock_event ns
/* Send the packet*/ /* Send the packet*/
assert(myprobe->host != NULL); assert(myprobe->host != NULL);
if (send_ip_packet(this->rawsd, myprobe->getEthernet(), myprobe->host->getTargetAddress(), buf, len) == -1) { if (send_ip_packet(this->rawsd, myprobe->getEthernet(), myprobe->host->getTargetAddress(), buf, len) == -1) {
pfatal("Unable to send packet in %s", __func__); myprobe->setFailed();
this->cc_report_final_timeout();
myprobe->host->fail_one_probe();
gh_perror("Unable to send packet in %s", __func__);
} }
myprobe->setTimeSent(); myprobe->setTimeSent();
free(buf); free(buf);
@@ -743,6 +746,9 @@ void FPHost6::fill_FPR(FingerPrintResultsIPv6 *FPR) {
break; break;
} }
} }
/* Did we fail to send some probe? */
FPR->incomplete = this->incomplete_fp;
} }
static const IPv6Header *find_ipv6(const PacketElement *pe) { static const IPv6Header *find_ipv6(const PacketElement *pe) {
@@ -1212,6 +1218,7 @@ void FPHost::__reset() {
this->probes_sent = 0; this->probes_sent = 0;
this->probes_answered = 0; this->probes_answered = 0;
this->probes_unanswered = 0; this->probes_unanswered = 0;
this->incomplete_fp = false;
this->detection_done = false; this->detection_done = false;
this->timedprobes_sent = false; this->timedprobes_sent = false;
this->target_host = NULL; this->target_host = NULL;
@@ -1244,6 +1251,12 @@ const struct sockaddr_storage *FPHost::getTargetAddress() {
return this->target_host->TargetSockAddr(); return this->target_host->TargetSockAddr();
} }
/* Marks one probe as unanswerable, making the fingerprint incomplete and
* ineligible for submission */
void FPHost::fail_one_probe() {
this->probes_unanswered++;
this->incomplete_fp = true;
}
/* Accesses the Target object associated with the FPHost to extract the port /* Accesses the Target object associated with the FPHost to extract the port
* numbers to be used in OS detection. In particular it extracts: * numbers to be used in OS detection. In particular it extracts:

View File

@@ -392,6 +392,7 @@ class FPHost {
unsigned int probes_sent; /* Number of FPProbes sent (not counting retransmissions) */ unsigned int probes_sent; /* Number of FPProbes sent (not counting retransmissions) */
unsigned int probes_answered; /* Number of FPResponses received */ unsigned int probes_answered; /* Number of FPResponses received */
unsigned int probes_unanswered; /* Number of FPProbes that timedout (after all retransmissions) */ unsigned int probes_unanswered; /* Number of FPProbes that timedout (after all retransmissions) */
bool incomplete_fp; /* True if we were unable to send all attempted probes */
bool detection_done; /* True if the OS detection process has been completed. */ bool detection_done; /* True if the OS detection process has been completed. */
bool timedprobes_sent; /* True if the probes that have timing requirements were sent */ bool timedprobes_sent; /* True if the probes that have timing requirements were sent */
Target *target_host; /* Info about the host to fingerprint */ Target *target_host; /* Info about the host to fingerprint */
@@ -424,6 +425,7 @@ class FPHost {
virtual int schedule() = 0; virtual int schedule() = 0;
virtual int callback(const u8 *pkt, size_t pkt_len, const struct timeval *tv) = 0; virtual int callback(const u8 *pkt, size_t pkt_len, const struct timeval *tv) = 0;
const struct sockaddr_storage *getTargetAddress(); const struct sockaddr_storage *getTargetAddress();
void fail_one_probe();
}; };

View File

@@ -138,6 +138,7 @@ FingerPrintResults::FingerPrintResults() {
distance = -1; distance = -1;
distance_guess = -1; distance_guess = -1;
maxTimingRatio = 0; maxTimingRatio = 0;
incomplete = false;
} }
FingerPrintResults::~FingerPrintResults() { FingerPrintResults::~FingerPrintResults() {
@@ -233,6 +234,10 @@ const char *FingerPrintResults::OmitSubmissionFP() {
return "Didn't receive UDP response. Please try again with -sSU"; return "Didn't receive UDP response. Please try again with -sSU";
} }
if (incomplete) {
return "Some probes failed to send so results incomplete";
}
return NULL; return NULL;
} }
@@ -246,6 +251,10 @@ const char *FingerPrintResultsIPv6::OmitSubmissionFP() {
return reason; return reason;
} }
if (incomplete) {
return "Some probes failed to send so results incomplete";
}
return NULL; return NULL;
} }

View File

@@ -181,6 +181,8 @@ class FingerPrintResults {
consistency standpoint. */ consistency standpoint. */
double maxTimingRatio; double maxTimingRatio;
bool incomplete; /* Were we unable to send all necessary probes? */
/* If the fingerprint is of potentially poor quality, we don't want to /* If the fingerprint is of potentially poor quality, we don't want to
print it and ask the user to submit it. In that case, the reason print it and ask the user to submit it. In that case, the reason
for skipping the FP is returned as a static string. If the FP is for skipping the FP is returned as a static string. If the FP is