diff --git a/FPEngine.cc b/FPEngine.cc index bfa5d68..8df0e89 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 std::map& resps, int target_distance) { + const IPv6Header *ipv6; + int max_freq = 0, vhlim = 0; + std::vector hlims; + std::map freq; + + for (std::map::const_iterator rs_iter = resps.begin(); rs_iter != resps.end(); rs_iter++) { + ipv6 = find_ipv6( (rs_iter->second).getPacket() ); + if (ipv6 != NULL) + hlims.push_back(ipv6->getHopLimit()); + } + + for (std::vector::iterator hl_iter = hlims.begin(); hl_iter != hlims.end(); hl_iter++) { + int hlim = *hl_iter; + if (freq.find(hlim) == freq.end()) + freq[hlim] = 1; + else + freq[hlim] += 1; + } + + for (std::map::const_iterator fr_iter = freq.begin(); fr_iter != freq.end(); fr_iter++) { + if (max_freq < fr_iter->second) { + vhlim = fr_iter->first; + max_freq = fr_iter->second; + } + } + + if (target_distance > 0) + vhlim += target_distance - 1; + + return vhlim; +} + 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)]; @@ -858,6 +884,7 @@ static struct feature_node *vectorize(const FingerPrintResultsIPv6 *FPR) { features[idx++].value = vectorize_plen(resps[probe_name].getPacket()); features[idx++].value = vectorize_tc(resps[probe_name].getPacket()); } + features[idx++].value = vectorize_hlim(resps, FPR->distance); /* TCP features */ features[idx++].value = vectorize_isr(resps); for (i = 0; i < NELEMS(TCP_PROBE_NAMES); i++) {