diff --git a/FPEngine.cc b/FPEngine.cc index bc1894332..d8d965a7f 100644 --- a/FPEngine.cc +++ b/FPEngine.cc @@ -463,7 +463,10 @@ void FPNetworkControl::probe_transmission_handler(nsock_pool nsp, nsock_event ns /* Send the packet*/ assert(myprobe->host != NULL); 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(); free(buf); @@ -743,6 +746,9 @@ void FPHost6::fill_FPR(FingerPrintResultsIPv6 *FPR) { break; } } + + /* Did we fail to send some probe? */ + FPR->incomplete = this->incomplete_fp; } static const IPv6Header *find_ipv6(const PacketElement *pe) { @@ -1212,6 +1218,7 @@ void FPHost::__reset() { this->probes_sent = 0; this->probes_answered = 0; this->probes_unanswered = 0; + this->incomplete_fp = false; this->detection_done = false; this->timedprobes_sent = false; this->target_host = NULL; @@ -1244,6 +1251,12 @@ const struct sockaddr_storage *FPHost::getTargetAddress() { 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 * numbers to be used in OS detection. In particular it extracts: diff --git a/FPEngine.h b/FPEngine.h index bf5a44539..da9ae3eb1 100644 --- a/FPEngine.h +++ b/FPEngine.h @@ -392,6 +392,7 @@ class FPHost { unsigned int probes_sent; /* Number of FPProbes sent (not counting retransmissions) */ unsigned int probes_answered; /* Number of FPResponses received */ 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 timedprobes_sent; /* True if the probes that have timing requirements were sent */ Target *target_host; /* Info about the host to fingerprint */ @@ -424,6 +425,7 @@ class FPHost { virtual int schedule() = 0; virtual int callback(const u8 *pkt, size_t pkt_len, const struct timeval *tv) = 0; const struct sockaddr_storage *getTargetAddress(); + void fail_one_probe(); }; diff --git a/FingerPrintResults.cc b/FingerPrintResults.cc index c7ad750e0..89e4d9aa6 100644 --- a/FingerPrintResults.cc +++ b/FingerPrintResults.cc @@ -138,6 +138,7 @@ FingerPrintResults::FingerPrintResults() { distance = -1; distance_guess = -1; maxTimingRatio = 0; + incomplete = false; } FingerPrintResults::~FingerPrintResults() { @@ -233,6 +234,10 @@ const char *FingerPrintResults::OmitSubmissionFP() { return "Didn't receive UDP response. Please try again with -sSU"; } + if (incomplete) { + return "Some probes failed to send so results incomplete"; + } + return NULL; } @@ -246,6 +251,10 @@ const char *FingerPrintResultsIPv6::OmitSubmissionFP() { return reason; } + if (incomplete) { + return "Some probes failed to send so results incomplete"; + } + return NULL; } diff --git a/FingerPrintResults.h b/FingerPrintResults.h index d468fcfa0..143462c76 100644 --- a/FingerPrintResults.h +++ b/FingerPrintResults.h @@ -181,6 +181,8 @@ class FingerPrintResults { consistency standpoint. */ 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 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