diff --git a/FPEngine.cc b/FPEngine.cc index bfa5d68..91d510e 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); @@ -1538,8 +1565,8 @@ void FPHost6::finish() { distance_calculation_method = DIST_METHOD_ICMP; } - this->target_host->distance = this->target_host->FPR->distance = distance; - this->target_host->distance_calculation_method = distance_calculation_method; + this->target_host->FPR->distance = distance; + 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..184da97 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,8 @@ 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 method in which the distance was calculated */ + /* 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.cc b/Target.cc index 8074108..0b3d10a 100644 --- a/Target.cc +++ b/Target.cc @@ -145,8 +145,6 @@ void Target::Initialize() { hostname = NULL; targetname = NULL; memset(&seq, 0, sizeof(seq)); - distance = -1; - distance_calculation_method = DIST_METHOD_NONE; FPR = NULL; osscan_flag = OS_NOTPERF; weird_responses = flags = 0; diff --git a/Target.h b/Target.h index 40b9f1f..34a21c6 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? */ @@ -315,8 +305,6 @@ class Target { void osscanSetFlag(int flag); struct seq_info seq; - int distance; - enum dist_calc_method distance_calculation_method; FingerPrintResults *FPR; /* FP results get by the OS scan system. */ PortList ports; diff --git a/osscan2.cc b/osscan2.cc index 322004a..ba595b6 100644 --- a/osscan2.cc +++ b/osscan2.cc @@ -857,8 +857,8 @@ static void endRound(OsScanInfo *OSI, HostOsScan *HOS, int roundNum) { distance_calculation_method = DIST_METHOD_ICMP; } - hsi->target->distance = hsi->target->FPR->distance = distance; - hsi->target->distance_calculation_method = distance_calculation_method; + hsi->target->FPR->distance = distance; + hsi->target->FPR->distance_calculation_method = distance_calculation_method; hsi->target->FPR->distance_guess = hsi->hss->distance_guess; } @@ -914,8 +914,8 @@ static void printFP(OsScanInfo *OSI) { "No OS matches for %s by new os scan system.\n\nTCP/IP fingerprint:\n%s", hsi->target->targetipstr(), mergeFPs(FPR->FPs, FPR->numFPs, true, - hsi->target->TargetSockAddr(), hsi->target->distance, - hsi->target->distance_calculation_method, + hsi->target->TargetSockAddr(), hsi->target->FPR->distance, + hsi->target->FPR->distance_calculation_method, hsi->target->MACAddress(), FPR->osscan_opentcpport, FPR->osscan_closedtcpport, FPR->osscan_closedudpport, false)); diff --git a/output.cc b/output.cc index 3dabb51..d472176 100644 --- a/output.cc +++ b/output.cc @@ -707,7 +707,7 @@ void printportoutput(Target *currenths, PortList *plist) { first = 0; if (o.reason) { if (current->reason.ttl) - Tbl->addItemFormatted(rowno, reasoncol, false, "%s ttl %d", + Tbl->addItemFormatted(rowno, reasoncol, false, "%s ttl %d", port_reason_str(current->reason), current->reason.ttl); else Tbl->addItem(rowno, reasoncol, true, port_reason_str(current->reason)); @@ -772,7 +772,7 @@ void printportoutput(Target *currenths, PortList *plist) { Tbl->addItem(rowno, servicecol, true, serviceinfo); if (o.reason) { if (current->reason.ttl) - Tbl->addItemFormatted(rowno, reasoncol, false, "%s ttl %d", + Tbl->addItemFormatted(rowno, reasoncol, false, "%s ttl %d", port_reason_str(current->reason), current->reason.ttl); else Tbl->addItem(rowno, reasoncol, true, port_reason_str(current->reason)); @@ -1673,8 +1673,8 @@ void printmacinfo(Target *currenths) { const char *FingerPrintResultsIPv4::merge_fpr(const Target *currenths, bool isGoodFP, bool wrapit) const { return mergeFPs(this->FPs, this->numFPs, isGoodFP, currenths->TargetSockAddr(), - currenths->distance, - currenths->distance_calculation_method, + currenths->FPR->distance, + currenths->FPR->distance_calculation_method, currenths->MACAddress(), this->osscan_opentcpport, this->osscan_closedtcpport, this->osscan_closedudpport, wrapit); @@ -1797,7 +1797,7 @@ const char *FingerPrintResultsIPv6::merge_fpr(const Target *currenths, /* Write the SCAN line. */ WriteSInfo(str, sizeof(str), isGoodFP, "6", currenths->TargetSockAddr(), - currenths->distance, currenths->distance_calculation_method, + currenths->FPR->distance, currenths->FPR->distance_calculation_method, currenths->MACAddress(), this->osscan_opentcpport, this->osscan_closedtcpport, this->osscan_closedudpport); result << str << "\n"; @@ -2002,11 +2002,11 @@ void printosscanoutput(Target *currenths) { xml_newline(); } - if (currenths->distance != -1) { + if (currenths->FPR->distance != -1) { log_write(LOG_PLAIN, "Network Distance: %d hop%s\n", - currenths->distance, (currenths->distance == 1) ? "" : "s"); + currenths->FPR->distance, (currenths->FPR->distance == 1) ? "" : "s"); xml_open_start_tag("distance"); - xml_attribute("value", "%d", currenths->distance); + xml_attribute("value", "%d", currenths->FPR->distance); xml_close_empty_tag(); xml_newline(); } diff --git a/traceroute.cc b/traceroute.cc index a271494..1a1b59b 100644 --- a/traceroute.cc +++ b/traceroute.cc @@ -574,8 +574,8 @@ void HostState::child_parent_ttl(u8 ttl, Hop **child, Hop **parent) { u8 HostState::distance_guess(const Target *target) { /* Use the distance from OS detection if we have it. */ - if (target->distance != -1) - return target->distance; + if (target->FPR->distance != -1) + return target->FPR->distance; else /* initial_ttl is a variable with file-level scope. */ return initial_ttl; @@ -1493,8 +1493,8 @@ void TracerouteState::transfer_hops() { /* Set the hop distance for OS fingerprints. */ if ((*it)->reached_target) { - (*it)->target->distance = (*it)->reached_target; - (*it)->target->distance_calculation_method = DIST_METHOD_TRACEROUTE; + (*it)->target->FPR->distance = (*it)->reached_target; + (*it)->target->FPR->distance_calculation_method = DIST_METHOD_TRACEROUTE; } } }