mirror of
https://github.com/nmap/nmap.git
synced 2025-12-07 13:11:28 +00:00
IPv6 hop limit feature for OS detection, patch by Alexandru Geana
This commit is contained in:
51
FPEngine.cc
51
FPEngine.cc
@@ -130,6 +130,7 @@
|
|||||||
#include "nmap_error.h"
|
#include "nmap_error.h"
|
||||||
#include "osscan.h"
|
#include "osscan.h"
|
||||||
#include "linear.h"
|
#include "linear.h"
|
||||||
|
#include "FPModel.h"
|
||||||
extern NmapOps o;
|
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;
|
/* Not all operating systems allow setting the flow label in outgoing packets;
|
||||||
notably all Unixes other than Linux when using raw sockets. This function
|
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.
|
finds out whether the flow labels we set are likely really being sent.
|
||||||
@@ -784,6 +777,43 @@ static double vectorize_tc(const PacketElement *pe) {
|
|||||||
return ipv6->getTrafficClass();
|
return ipv6->getTrafficClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For reference, the dev@nmap.org email thread which contains the explanations for the
|
||||||
|
* design decisions of this vectorization method:
|
||||||
|
* http://seclists.org/nmap-dev/2015/q1/218
|
||||||
|
*/
|
||||||
|
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<std::string, FPPacket>& resps) {
|
static double vectorize_isr(std::map<std::string, FPPacket>& resps) {
|
||||||
const char * const SEQ_PROBE_NAMES[] = {"S1", "S2", "S3", "S4", "S5", "S6"};
|
const char * const SEQ_PROBE_NAMES[] = {"S1", "S2", "S3", "S4", "S5", "S6"};
|
||||||
u32 seqs[NELEMS(SEQ_PROBE_NAMES)];
|
u32 seqs[NELEMS(SEQ_PROBE_NAMES)];
|
||||||
@@ -857,6 +887,7 @@ static struct feature_node *vectorize(const FingerPrintResultsIPv6 *FPR) {
|
|||||||
probe_name = IPV6_PROBE_NAMES[i];
|
probe_name = IPV6_PROBE_NAMES[i];
|
||||||
features[idx++].value = vectorize_plen(resps[probe_name].getPacket());
|
features[idx++].value = vectorize_plen(resps[probe_name].getPacket());
|
||||||
features[idx++].value = vectorize_tc(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 */
|
/* TCP features */
|
||||||
features[idx++].value = vectorize_isr(resps);
|
features[idx++].value = vectorize_isr(resps);
|
||||||
@@ -1539,7 +1570,9 @@ void FPHost6::finish() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->target_host->distance = this->target_host->FPR->distance = distance;
|
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 {
|
struct tcp_desc {
|
||||||
|
|||||||
1715
FPModel.cc
1715
FPModel.cc
File diff suppressed because one or more lines are too long
10
FPModel.h
Normal file
10
FPModel.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef _FPMODEL_H_
|
||||||
|
#define _FPMODEL_H_
|
||||||
|
|
||||||
|
extern struct model FPModel;
|
||||||
|
extern double FPscale[][2];
|
||||||
|
extern double FPmean[][676];
|
||||||
|
extern double FPvariance[][676];
|
||||||
|
extern FingerMatch FPmatches[];
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -137,6 +137,7 @@ FingerPrintResults::FingerPrintResults() {
|
|||||||
osscan_opentcpport = osscan_closedtcpport = osscan_closedudpport = -1;
|
osscan_opentcpport = osscan_closedtcpport = osscan_closedudpport = -1;
|
||||||
distance = -1;
|
distance = -1;
|
||||||
distance_guess = -1;
|
distance_guess = -1;
|
||||||
|
distance_calculation_method = DIST_METHOD_NONE;
|
||||||
maxTimingRatio = 0;
|
maxTimingRatio = 0;
|
||||||
incomplete = false;
|
incomplete = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,6 +143,16 @@ struct OS_Classification_Results {
|
|||||||
int overall_results; /* OSSCAN_TOOMANYMATCHES, OSSCAN_NOMATCHES, OSSCAN_SUCCESS, etc */
|
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 {
|
class FingerPrintResults {
|
||||||
public: /* For now ... a lot of the data members should be made private */
|
public: /* For now ... a lot of the data members should be made private */
|
||||||
FingerPrintResults();
|
FingerPrintResults();
|
||||||
@@ -173,6 +183,7 @@ class FingerPrintResults {
|
|||||||
otherwise -1) */
|
otherwise -1) */
|
||||||
int distance; /* How "far" is this FP gotten from? */
|
int distance; /* How "far" is this FP gotten from? */
|
||||||
int distance_guess; /* How "far" is this FP gotten from? by guessing based on ttl. */
|
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
|
/* The largest ratio we have seen of time taken vs. target time
|
||||||
between sending 1st tseq probe and sending first ICMP echo probe.
|
between sending 1st tseq probe and sending first ICMP echo probe.
|
||||||
|
|||||||
10
Target.h
10
Target.h
@@ -151,16 +151,6 @@ enum osscan_flags {
|
|||||||
OS_NOTPERF=0, OS_PERF, OS_PERF_UNREL
|
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 {
|
struct host_timeout_nfo {
|
||||||
unsigned long msecs_used; /* How many msecs has this Target used? */
|
unsigned long msecs_used; /* How many msecs has this Target used? */
|
||||||
bool toclock_running; /* Is the clock running right now? */
|
bool toclock_running; /* Is the clock running right now? */
|
||||||
|
|||||||
Reference in New Issue
Block a user