mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Short-circuit os fingerprint matching if accuracy cannot be achieved
This commit is contained in:
21
osscan.cc
21
osscan.cc
@@ -339,10 +339,13 @@ static int AVal_match(const FingerTest &reference, const FingerTest &fprint, con
|
||||
accuracy (between 0 and 1) is returned). If MatchPoints is not NULL, it is
|
||||
a special "fingerprints" which tells how many points each test is worth. */
|
||||
double compare_fingerprints(const FingerPrint *referenceFP, const FingerPrint *observedFP,
|
||||
const FingerPrintDef *MatchPoints, int verbose) {
|
||||
const FingerPrintDef *MatchPoints, int verbose,
|
||||
double threshold) {
|
||||
unsigned long num_subtests = 0, num_subtests_succeeded = 0;
|
||||
assert(referenceFP);
|
||||
assert(observedFP);
|
||||
// If we fall this far behind, we can't catch up
|
||||
unsigned long max_mismatch = (1.0 - threshold) * referenceFP->match.numprints;
|
||||
|
||||
for (int i = 0; i < NUM_FPTESTS; i++) {
|
||||
const FingerTest ¤t_ref = referenceFP->tests[i];
|
||||
@@ -355,6 +358,9 @@ double compare_fingerprints(const FingerPrint *referenceFP, const FingerPrint *o
|
||||
&new_subtests, &new_subtests_succeeded, 0, verbose);
|
||||
num_subtests += new_subtests;
|
||||
num_subtests_succeeded += new_subtests_succeeded;
|
||||
if (num_subtests - num_subtests_succeeded > max_mismatch) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(num_subtests_succeeded <= num_subtests);
|
||||
@@ -394,7 +400,7 @@ void match_fingerprint(const FingerPrint *FP, FingerPrintResultsIPv4 *FPR,
|
||||
for (current_os = DB->prints.begin(); current_os != DB->prints.end(); current_os++) {
|
||||
skipfp = 0;
|
||||
|
||||
acc = compare_fingerprints(*current_os, &FP_copy, DB->MatchPoints, 0);
|
||||
acc = compare_fingerprints(*current_os, &FP_copy, DB->MatchPoints, 0, FPR_entrance_requirement);
|
||||
|
||||
if (acc >= FPR_entrance_requirement || acc == 1.0) {
|
||||
|
||||
@@ -460,6 +466,7 @@ void match_fingerprint(const FingerPrint *FP, FingerPrintResultsIPv4 *FPR,
|
||||
/* Calculate the new min req. */
|
||||
if (FPR->num_matches == max_prints) {
|
||||
FPR_entrance_requirement = FPR->accuracy[max_prints - 1] + 0.00001;
|
||||
FPR_entrance_requirement = MIN(FPR_entrance_requirement, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -643,6 +650,15 @@ const char *FingerTest::getAVal(const char *attr) {
|
||||
return results->at(idx);
|
||||
}
|
||||
|
||||
int FingerTest::getMaxPoints() const {
|
||||
int points = 0;
|
||||
for (size_t i = 0; i < def->numAttrs; i++) {
|
||||
if ((*results)[i] != NULL)
|
||||
points += def->Attrs[i].points;
|
||||
}
|
||||
return points;
|
||||
}
|
||||
|
||||
/* This is a less-than relation predicate that establishes the preferred order
|
||||
of tests when they are displayed. Returns true if and only if the test a
|
||||
should come before the test b. */
|
||||
@@ -1043,6 +1059,7 @@ fparse:
|
||||
goto top;
|
||||
}
|
||||
current->setTest(test);
|
||||
current->match.numprints += test.getMaxPoints();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
osscan.h
9
osscan.h
@@ -175,14 +175,12 @@ struct FingerMatch {
|
||||
int line; /* For reference prints, the line # in nmap-os-db */
|
||||
/* For IPv6 matches, the number of fingerprints that contributed to this
|
||||
* classification group */
|
||||
/* For IPv4 fingerprints, the number of points possible */
|
||||
unsigned short numprints;
|
||||
const char *OS_name;
|
||||
std::vector<OS_Classification> OS_class;
|
||||
|
||||
FingerMatch() {
|
||||
line = -1;
|
||||
OS_name = NULL;
|
||||
}
|
||||
FingerMatch() : line(-1), numprints(0), OS_name(NULL) {}
|
||||
};
|
||||
|
||||
struct FingerPrintDB;
|
||||
@@ -210,6 +208,7 @@ struct FingerTest {
|
||||
const char *getAVal(const char *attr);
|
||||
const char *getAValName(u8 index) const;
|
||||
const char *getTestName() const { return def->name.str; }
|
||||
int getMaxPoints() const;
|
||||
};
|
||||
|
||||
struct FingerPrint {
|
||||
@@ -256,7 +255,7 @@ void free_fingerprint_file(FingerPrintDB *DB);
|
||||
accuracy (between 0 and 1) is returned). MatchPoints is
|
||||
a special "fingerprints" which tells how many points each test is worth. */
|
||||
double compare_fingerprints(const FingerPrint *referenceFP, const FingerPrint *observedFP,
|
||||
const FingerPrintDef *MatchPoints, int verbose);
|
||||
const FingerPrintDef *MatchPoints, int verbose, double threshold);
|
||||
|
||||
/* Takes a fingerprint and looks for matches inside the passed in
|
||||
reference fingerprint DB. The results are stored in in FPR (which
|
||||
|
||||
Reference in New Issue
Block a user