diff --git a/FPEngine.cc b/FPEngine.cc index bfa5d68..5cbe025 100644 --- a/FPEngine.cc +++ b/FPEngine.cc @@ -130,6 +130,7 @@ #include "nmap_error.h" #include "osscan.h" #include "linear.h" +#include "FPModel.h" extern NmapOps o; @@ -697,14 +698,6 @@ FPEngine6::~FPEngine6() { } - -/* From FPModel.cc. */ -extern struct model FPModel; -extern double FPscale[][2]; -extern double FPmean[][659]; -extern double FPvariance[][659]; -extern FingerMatch FPmatches[]; - /* Not all operating systems allow setting the flow label in outgoing packets; notably all Unixes other than Linux when using raw sockets. This function finds out whether the flow labels we set are likely really being sent. @@ -784,6 +777,39 @@ static double vectorize_tc(const PacketElement *pe) { return ipv6->getTrafficClass(); } +static int vectorize_hlim(const PacketElement *pe, int target_distance, enum dist_calc_method method) { + const IPv6Header *ipv6; + int hlim; + int er_lim; + + ipv6 = find_ipv6(pe); + if (ipv6 == NULL) + return -1; + hlim = ipv6->getHopLimit(); + + if (method != DIST_METHOD_NONE) { + if (method == DIST_METHOD_TRACEROUTE || method == DIST_METHOD_ICMP) { + if (target_distance > 0) + hlim += target_distance - 1; + } + er_lim = 5; + } else + er_lim = 20; + + if (32 - er_lim <= hlim && hlim <= 32) + hlim = 32; + else if (64 - er_lim <= hlim && hlim <= 64) + hlim = 64; + else if (128 - er_lim <= hlim && hlim <= 128) + hlim = 128; + else if (255 - er_lim <= hlim && hlim <= 255) + hlim = 255; + else + hlim = -1; + + return hlim; +} + static double vectorize_isr(std::map& resps) { const char * const SEQ_PROBE_NAMES[] = {"S1", "S2", "S3", "S4", "S5", "S6"}; u32 seqs[NELEMS(SEQ_PROBE_NAMES)]; @@ -857,6 +883,7 @@ static struct feature_node *vectorize(const FingerPrintResultsIPv6 *FPR) { probe_name = IPV6_PROBE_NAMES[i]; features[idx++].value = vectorize_plen(resps[probe_name].getPacket()); features[idx++].value = vectorize_tc(resps[probe_name].getPacket()); + features[idx++].value = vectorize_hlim(resps[probe_name].getPacket(), FPR->distance, FPR->distance_calculation_method); } /* TCP features */ features[idx++].value = vectorize_isr(resps); @@ -1539,7 +1566,9 @@ void FPHost6::finish() { } this->target_host->distance = this->target_host->FPR->distance = distance; - this->target_host->distance_calculation_method = distance_calculation_method; + this->target_host->distance_calculation_method = + this->target_host->FPR->distance_calculation_method = + distance_calculation_method; } struct tcp_desc { diff --git a/FingerPrintResults.cc b/FingerPrintResults.cc index 89e4d9a..0a86a13 100644 --- a/FingerPrintResults.cc +++ b/FingerPrintResults.cc @@ -137,6 +137,7 @@ FingerPrintResults::FingerPrintResults() { osscan_opentcpport = osscan_closedtcpport = osscan_closedudpport = -1; distance = -1; distance_guess = -1; + distance_calculation_method = DIST_METHOD_NONE; maxTimingRatio = 0; incomplete = false; } diff --git a/FingerPrintResults.h b/FingerPrintResults.h index 143462c..1c7b79d 100644 --- a/FingerPrintResults.h +++ b/FingerPrintResults.h @@ -143,6 +143,16 @@ struct OS_Classification_Results { int overall_results; /* OSSCAN_TOOMANYMATCHES, OSSCAN_NOMATCHES, OSSCAN_SUCCESS, etc */ }; +/* The method used to calculate the Target::distance, included in OS + fingerprints. */ +enum dist_calc_method { + DIST_METHOD_NONE, + DIST_METHOD_LOCALHOST, + DIST_METHOD_DIRECT, + DIST_METHOD_ICMP, + DIST_METHOD_TRACEROUTE +}; + class FingerPrintResults { public: /* For now ... a lot of the data members should be made private */ FingerPrintResults(); @@ -173,6 +183,7 @@ class FingerPrintResults { otherwise -1) */ int distance; /* How "far" is this FP gotten from? */ int distance_guess; /* How "far" is this FP gotten from? by guessing based on ttl. */ + enum dist_calc_method distance_calculation_method; /* The largest ratio we have seen of time taken vs. target time between sending 1st tseq probe and sending first ICMP echo probe. diff --git a/Target.h b/Target.h index 40b9f1f..b72b91c 100644 --- a/Target.h +++ b/Target.h @@ -151,16 +151,6 @@ enum osscan_flags { OS_NOTPERF=0, OS_PERF, OS_PERF_UNREL }; -/* The method used to calculate the Target::distance, included in OS - fingerprints. */ -enum dist_calc_method { - DIST_METHOD_NONE, - DIST_METHOD_LOCALHOST, - DIST_METHOD_DIRECT, - DIST_METHOD_ICMP, - DIST_METHOD_TRACEROUTE -}; - struct host_timeout_nfo { unsigned long msecs_used; /* How many msecs has this Target used? */ bool toclock_running; /* Is the clock running right now? */