1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-09 14:11:29 +00:00

Create AVal vectors in-place, do not copy

At startup with -O, this change reduces overall memory use by 4%, total
alloc/frees by 70%, and total instructions by 45%.
This commit is contained in:
dmiller
2022-09-13 16:10:05 +00:00
parent 9a494348c5
commit 1d8bf1deff
3 changed files with 98 additions and 84 deletions

View File

@@ -97,7 +97,7 @@ void FingerPrint::sort() {
unsigned int i; unsigned int i;
for (i = 0; i < tests.size(); i++) for (i = 0; i < tests.size(); i++)
std::stable_sort(tests[i].results.begin(), tests[i].results.end()); std::stable_sort(tests[i].results->begin(), tests[i].results->end());
std::stable_sort(tests.begin(), tests.end()); std::stable_sort(tests.begin(), tests.end());
} }
@@ -178,28 +178,28 @@ static int AVal_match(const FingerTest *reference, const FingerTest *fprint, con
char *endptr; char *endptr;
/* We rely on AVals being sorted by attribute. */ /* We rely on AVals being sorted by attribute. */
prev_ref = reference->results.end(); prev_ref = reference->results->end();
prev_fp = fprint->results.end(); prev_fp = fprint->results->end();
current_ref = reference->results.begin(); current_ref = reference->results->begin();
current_fp = fprint->results.begin(); current_fp = fprint->results->begin();
current_points = points->results.begin(); current_points = points->results->begin();
while (current_ref != reference->results.end() while (current_ref != reference->results->end()
&& current_fp != fprint->results.end()) { && current_fp != fprint->results->end()) {
int d; int d;
/* Check for sortedness. */ /* Check for sortedness. */
if (prev_ref != reference->results.end()) if (prev_ref != reference->results->end())
assert(*prev_ref < *current_ref); assert(*prev_ref < *current_ref);
if (prev_fp != fprint->results.end()) if (prev_fp != fprint->results->end())
assert(*prev_fp < *current_fp); assert(*prev_fp < *current_fp);
d = strcmp(current_ref->attribute, current_fp->attribute); d = strcmp(current_ref->attribute, current_fp->attribute);
if (d == 0) { if (d == 0) {
for (; current_points != points->results.end(); current_points++) { for (; current_points != points->results->end(); current_points++) {
if (strcmp(current_ref->attribute, current_points->attribute) == 0) if (strcmp(current_ref->attribute, current_points->attribute) == 0)
break; break;
} }
if (current_points == points->results.end()) if (current_points == points->results->end())
fatal("%s: Failed to find point amount for test %s.%s", __func__, reference->name ? reference->name : "", current_ref->attribute); fatal("%s: Failed to find point amount for test %s.%s", __func__, reference->name ? reference->name : "", current_ref->attribute);
errno = 0; errno = 0;
pointsThisTest = strtol(current_points->value, &endptr, 10); pointsThisTest = strtol(current_points->value, &endptr, 10);
@@ -511,8 +511,8 @@ static int test2str(const FingerTest *test, char *s, const size_t n) {
goto error; goto error;
*p++ = '('; *p++ = '(';
for (av = test->results.begin(); av != test->results.end(); av++) { for (av = test->results->begin(); av != test->results->end(); av++) {
if (av != test->results.begin()) { if (av != test->results->begin()) {
if (p + 1 > end) if (p + 1 > end)
goto error; goto error;
*p++ = '%'; *p++ = '%';
@@ -556,14 +556,14 @@ static const char *strchr_p(const char *str, const char *end, char c) {
return NULL; return NULL;
} }
static std::vector<struct AVal> str2AVal(const char *str, const char *end) { static std::vector<struct AVal> *str2AVal(const char *str, const char *end) {
int i = 1; int i = 1;
int count = 1; int count = 1;
const char *q = str, *p=str; const char *q = str, *p=str;
std::vector<struct AVal> AVs; std::vector<struct AVal> *AVs = new std::vector<struct AVal>;
if (!*str || str == end) if (!*str || str == end)
return std::vector<struct AVal>(); return AVs;
/* count the AVals */ /* count the AVals */
while ((q = strchr_p(q, end, '%'))) { while ((q = strchr_p(q, end, '%'))) {
@@ -571,7 +571,7 @@ static std::vector<struct AVal> str2AVal(const char *str, const char *end) {
q++; q++;
} }
AVs.reserve(count); AVs->reserve(count);
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
struct AVal av; struct AVal av;
@@ -591,7 +591,7 @@ static std::vector<struct AVal> str2AVal(const char *str, const char *end) {
av.value = string_pool_substr(p, end); av.value = string_pool_substr(p, end);
} }
p = q + 1; p = q + 1;
AVs.push_back(av); AVs->push_back(av);
} }
return AVs; return AVs;
@@ -603,13 +603,13 @@ static std::vector<struct AVal> str2AVal(const char *str, const char *end) {
static bool test_match_literal(const FingerTest *a, const FingerTest *b) { static bool test_match_literal(const FingerTest *a, const FingerTest *b) {
std::vector<struct AVal>::const_iterator ia, ib; std::vector<struct AVal>::const_iterator ia, ib;
for (ia = a->results.begin(), ib = b->results.begin(); for (ia = a->results->begin(), ib = b->results->begin();
ia != a->results.end() && ib != b->results.end(); ia != a->results->end() && ib != b->results->end();
ia++, ib++) { ia++, ib++) {
if (strcmp(ia->attribute, ib->attribute) != 0) if (strcmp(ia->attribute, ib->attribute) != 0)
return false; return false;
} }
if (ia != a->results.end() || ib != b->results.end()) if (ia != a->results->end() || ib != b->results->end())
return false; return false;
return true; return true;

View File

@@ -125,7 +125,12 @@ struct FingerMatch {
struct FingerTest { struct FingerTest {
const char *name; const char *name;
std::vector<struct AVal> results; std::vector<struct AVal> *results;
FingerTest() : name(NULL), results(NULL) {}
~FingerTest() {
// name is allocated from string_pool
// results freed via ~FingerPrint()
}
bool operator<(const FingerTest& other) const { bool operator<(const FingerTest& other) const {
return strcmp(name, other.name) < 0; return strcmp(name, other.name) < 0;
} }
@@ -135,6 +140,13 @@ struct FingerPrint {
FingerMatch match; FingerMatch match;
std::vector<FingerTest> tests; std::vector<FingerTest> tests;
FingerPrint(); FingerPrint();
~FingerPrint() {
for (std::vector<FingerTest>::iterator t = this->tests.begin();
t != this->tests.end(); t++) {
if (t->results)
delete t->results;
}
}
void sort(); void sort();
}; };
/* This structure contains the important data from the fingerprint /* This structure contains the important data from the fingerprint
@@ -185,7 +197,6 @@ void match_fingerprint(const FingerPrint *FP, FingerPrintResultsIPv4 *FPR,
/* Returns true if perfect match -- if num_subtests & num_subtests_succeeded are non_null it updates them. if shortcircuit is zero, it does all the tests, otherwise it returns when the first one fails */ /* Returns true if perfect match -- if num_subtests & num_subtests_succeeded are non_null it updates them. if shortcircuit is zero, it does all the tests, otherwise it returns when the first one fails */
void freeFingerPrint(FingerPrint *FP);
void WriteSInfo(char *ostr, int ostrlen, bool isGoodFP, void WriteSInfo(char *ostr, int ostrlen, bool isGoodFP,
const char *engine_id, const char *engine_id,
const struct sockaddr_storage *addr, int distance, const struct sockaddr_storage *addr, int distance,

View File

@@ -2051,12 +2051,12 @@ void HostOsScan::makeFP(HostOsScanStats *hss) {
hss->FPtests[i] = new FingerTest; hss->FPtests[i] = new FingerTest;
AV.attribute = "R"; AV.attribute = "R";
AV.value = "N"; AV.value = "N";
hss->FPtests[i]->results.push_back(AV); hss->FPtests[i]->results->push_back(AV);
hss->FPtests[i]->name = (i == 3)? "ECN" : (i == 4)? "T1" : (i == 5)? "T2" : (i == 6)? "T3" : (i == 7)? "T4" : (i == 8)? "T5" : (i == 9)? "T6" : (i == 10)? "T7" : (i == 11)? "U1" : "IE"; hss->FPtests[i]->name = (i == 3)? "ECN" : (i == 4)? "T1" : (i == 5)? "T2" : (i == 6)? "T3" : (i == 7)? "T4" : (i == 8)? "T5" : (i == 9)? "T6" : (i == 10)? "T7" : (i == 11)? "U1" : "IE";
} }
else if (hss->FPtests[i]) { else if (hss->FPtests[i]) {
/* Replace TTL with initial TTL. */ /* Replace TTL with initial TTL. */
for (it = hss->FPtests[i]->results.begin(); it != hss->FPtests[i]->results.end(); it++) { for (it = hss->FPtests[i]->results->begin(); it != hss->FPtests[i]->results->end(); it++) {
if (strcmp(it->attribute, "T") == 0) { if (strcmp(it->attribute, "T") == 0) {
/* Found TTL item. The value for this attribute is the /* Found TTL item. The value for this attribute is the
* received TTL encoded in decimal. We replace it with the * received TTL encoded in decimal. We replace it with the
@@ -2312,11 +2312,11 @@ void HostOsScan::makeTSeqFP(HostOsScanStats *hss) {
int good_tcp_ipid_num, good_tcp_closed_ipid_num, good_icmp_ipid_num; int good_tcp_ipid_num, good_tcp_closed_ipid_num, good_icmp_ipid_num;
int tsnewval = 0; int tsnewval = 0;
std::vector<struct AVal> seq_AVs; std::vector<struct AVal> *seq_AVs = new std::vector<struct AVal>;
struct AVal AV; struct AVal AV;
/* Need 8 AVals for SP, GCD, ISR, TI, CI, II, SS, TS. */ /* Need 8 AVals for SP, GCD, ISR, TI, CI, II, SS, TS. */
seq_AVs.reserve(8); seq_AVs->reserve(8);
/* Now we make sure there are no gaps in our response array ... */ /* Now we make sure there are no gaps in our response array ... */
for (i = 0, j = 0; i < NUM_SEQ_SAMPLES; i++) { for (i = 0, j = 0; i < NUM_SEQ_SAMPLES; i++) {
@@ -2399,13 +2399,13 @@ void HostOsScan::makeTSeqFP(HostOsScanStats *hss) {
AV.attribute = "SP"; AV.attribute = "SP";
AV.value = string_pool_sprintf("%X", hss->si.index); AV.value = string_pool_sprintf("%X", hss->si.index);
seq_AVs.push_back(AV); seq_AVs->push_back(AV);
AV.attribute = "GCD"; AV.attribute = "GCD";
AV.value = string_pool_sprintf("%X", seq_gcd); AV.value = string_pool_sprintf("%X", seq_gcd);
seq_AVs.push_back(AV); seq_AVs->push_back(AV);
AV.attribute = "ISR"; AV.attribute = "ISR";
AV.value = string_pool_sprintf("%X", (unsigned int) seq_rate); AV.value = string_pool_sprintf("%X", (unsigned int) seq_rate);
seq_AVs.push_back(AV); seq_AVs->push_back(AV);
} else if (hss->si.responses > 0) { } else if (hss->si.responses > 0) {
if (o.debugging) if (o.debugging)
log_write(LOG_PLAIN, "Insufficient responses from %s for TCP sequencing (%d), OS detection may be less accurate\n", hss->target->targetipstr(), hss->si.responses); log_write(LOG_PLAIN, "Insufficient responses from %s for TCP sequencing (%d), OS detection may be less accurate\n", hss->target->targetipstr(), hss->si.responses);
@@ -2461,11 +2461,11 @@ void HostOsScan::makeTSeqFP(HostOsScanStats *hss) {
/* This fills in TI=Z or something like that. */ /* This fills in TI=Z or something like that. */
if (make_aval_ipid_seq(&AV, "TI", tcp_ipid_seqclass, hss->ipid.tcp_ipids) != NULL) if (make_aval_ipid_seq(&AV, "TI", tcp_ipid_seqclass, hss->ipid.tcp_ipids) != NULL)
seq_AVs.push_back(AV); seq_AVs->push_back(AV);
if (make_aval_ipid_seq(&AV, "CI", tcp_closed_ipid_seqclass, hss->ipid.tcp_closed_ipids) != NULL) if (make_aval_ipid_seq(&AV, "CI", tcp_closed_ipid_seqclass, hss->ipid.tcp_closed_ipids) != NULL)
seq_AVs.push_back(AV); seq_AVs->push_back(AV);
if (make_aval_ipid_seq(&AV, "II", icmp_ipid_seqclass, hss->ipid.icmp_ipids) != NULL) if (make_aval_ipid_seq(&AV, "II", icmp_ipid_seqclass, hss->ipid.icmp_ipids) != NULL)
seq_AVs.push_back(AV); seq_AVs->push_back(AV);
/* SS: Shared IP ID sequence boolean */ /* SS: Shared IP ID sequence boolean */
if ((tcp_ipid_seqclass == IPID_SEQ_INCR || if ((tcp_ipid_seqclass == IPID_SEQ_INCR ||
@@ -2483,7 +2483,7 @@ void HostOsScan::makeTSeqFP(HostOsScanStats *hss) {
} else { } else {
AV.value = "O"; AV.value = "O";
} }
seq_AVs.push_back(AV); seq_AVs->push_back(AV);
} }
/* Now we look at TCP Timestamp sequence prediction */ /* Now we look at TCP Timestamp sequence prediction */
@@ -2541,7 +2541,7 @@ void HostOsScan::makeTSeqFP(HostOsScanStats *hss) {
case TS_SEQ_ZERO: case TS_SEQ_ZERO:
AV.attribute = "TS"; AV.attribute = "TS";
AV.value = "0"; AV.value = "0";
seq_AVs.push_back(AV); seq_AVs->push_back(AV);
break; break;
case TS_SEQ_2HZ: case TS_SEQ_2HZ:
case TS_SEQ_100HZ: case TS_SEQ_100HZ:
@@ -2571,28 +2571,30 @@ void HostOsScan::makeTSeqFP(HostOsScanStats *hss) {
} }
AV.value = string_pool_sprintf("%X", tsnewval); AV.value = string_pool_sprintf("%X", tsnewval);
seq_AVs.push_back(AV); seq_AVs->push_back(AV);
break; break;
case TS_SEQ_UNSUPPORTED: case TS_SEQ_UNSUPPORTED:
AV.attribute = "TS"; AV.attribute = "TS";
AV.value = "U"; AV.value = "U";
seq_AVs.push_back(AV); seq_AVs->push_back(AV);
break; break;
} }
/* Now generate the SEQ line of the fingerprint if there are any test results /* Now generate the SEQ line of the fingerprint if there are any test results
in seq_AVs. */ in seq_AVs. */
if (!seq_AVs.empty()) { if (!seq_AVs->empty()) {
hss->FP_TSeq = new FingerTest; hss->FP_TSeq = new FingerTest;
hss->FP_TSeq->name = "SEQ"; hss->FP_TSeq->name = "SEQ";
hss->FP_TSeq->results = seq_AVs; hss->FP_TSeq->results = seq_AVs;
} }
else {
delete seq_AVs;
}
} }
void HostOsScan::makeTOpsFP(HostOsScanStats *hss) { void HostOsScan::makeTOpsFP(HostOsScanStats *hss) {
assert(hss); assert(hss);
std::vector<struct AVal> AVs;
int i, n; int i, n;
if (hss->TOpsReplyNum != 6) if (hss->TOpsReplyNum != 6)
@@ -2608,10 +2610,11 @@ void HostOsScan::makeTOpsFP(HostOsScanStats *hss) {
return; return;
} }
AVs.reserve(n); std::vector<struct AVal> *AVs = new std::vector<struct AVal>;
AVs->reserve(n);
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
AVs.push_back(*hss->TOps_AVs[i]); AVs->push_back(*hss->TOps_AVs[i]);
hss->FP_TOps = new FingerTest; hss->FP_TOps = new FingerTest;
hss->FP_TOps->results = AVs; hss->FP_TOps->results = AVs;
@@ -2621,7 +2624,6 @@ void HostOsScan::makeTOpsFP(HostOsScanStats *hss) {
void HostOsScan::makeTWinFP(HostOsScanStats *hss) { void HostOsScan::makeTWinFP(HostOsScanStats *hss) {
assert(hss); assert(hss);
std::vector<struct AVal> AVs;
int i, n; int i, n;
if (hss->TWinReplyNum != 6) if (hss->TWinReplyNum != 6)
@@ -2637,10 +2639,11 @@ void HostOsScan::makeTWinFP(HostOsScanStats *hss) {
return; return;
} }
AVs.reserve(n); std::vector<struct AVal> *AVs = new std::vector<struct AVal>;
AVs->reserve(n);
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
AVs.push_back(*hss->TWin_AVs[i]); AVs->push_back(*hss->TWin_AVs[i]);
hss->FP_TWin = new FingerTest; hss->FP_TWin = new FingerTest;
hss->FP_TWin->results = AVs; hss->FP_TWin->results = AVs;
@@ -2796,7 +2799,6 @@ bool HostOsScan::processTWinResp(HostOsScanStats *hss, const struct tcp_hdr *tcp
bool HostOsScan::processTEcnResp(HostOsScanStats *hss, const struct ip *ip) { bool HostOsScan::processTEcnResp(HostOsScanStats *hss, const struct ip *ip) {
std::vector<struct AVal> AVs;
struct AVal AV; struct AVal AV;
char ops_buf[256]; char ops_buf[256];
char quirks_buf[10]; char quirks_buf[10];
@@ -2809,11 +2811,12 @@ bool HostOsScan::processTEcnResp(HostOsScanStats *hss, const struct ip *ip) {
return false; return false;
/* Create the Avals */ /* Create the Avals */
AVs.reserve(numtests); std::vector<struct AVal> *AVs = new std::vector<struct AVal>;
AVs->reserve(numtests);
AV.attribute = "R"; AV.attribute = "R";
AV.value = "Y"; AV.value = "Y";
AVs.push_back(AV); AVs->push_back(AV);
/* don't frag flag */ /* don't frag flag */
AV.attribute = "DF"; AV.attribute = "DF";
@@ -2821,17 +2824,17 @@ bool HostOsScan::processTEcnResp(HostOsScanStats *hss, const struct ip *ip) {
AV.value = "Y"; AV.value = "Y";
else else
AV.value = "N"; AV.value = "N";
AVs.push_back(AV); AVs->push_back(AV);
/* TTL */ /* TTL */
AV.attribute = "T"; AV.attribute = "T";
AV.value = string_pool_sprintf("%d", ip->ip_ttl); AV.value = string_pool_sprintf("%d", ip->ip_ttl);
AVs.push_back(AV); AVs->push_back(AV);
/* TCP Window size */ /* TCP Window size */
AV.attribute = "W"; AV.attribute = "W";
AV.value = string_pool_sprintf("%hX", ntohs(tcp->th_win)); AV.value = string_pool_sprintf("%hX", ntohs(tcp->th_win));
AVs.push_back(AV); AVs->push_back(AV);
/* Now for the TCP options ... */ /* Now for the TCP options ... */
AV.attribute = "O"; AV.attribute = "O";
@@ -2844,7 +2847,7 @@ bool HostOsScan::processTEcnResp(HostOsScanStats *hss, const struct ip *ip) {
} }
AV.value = string_pool_insert(ops_buf); AV.value = string_pool_insert(ops_buf);
AVs.push_back(AV); AVs->push_back(AV);
/* Explicit Congestion Notification support test */ /* Explicit Congestion Notification support test */
AV.attribute = "CC"; AV.attribute = "CC";
@@ -2859,7 +2862,7 @@ bool HostOsScan::processTEcnResp(HostOsScanStats *hss, const struct ip *ip) {
AV.value = "N"; AV.value = "N";
else else
AV.value = "O"; AV.value = "O";
AVs.push_back(AV); AVs->push_back(AV);
/* TCP miscellaneous quirks test */ /* TCP miscellaneous quirks test */
AV.attribute = "Q"; AV.attribute = "Q";
@@ -2876,7 +2879,7 @@ bool HostOsScan::processTEcnResp(HostOsScanStats *hss, const struct ip *ip) {
} }
*p = '\0'; *p = '\0';
AV.value = string_pool_insert(quirks_buf); AV.value = string_pool_insert(quirks_buf);
AVs.push_back(AV); AVs->push_back(AV);
hss->FP_TEcn = new FingerTest; hss->FP_TEcn = new FingerTest;
hss->FP_TEcn->name = "ECN"; hss->FP_TEcn->name = "ECN";
@@ -2887,7 +2890,6 @@ bool HostOsScan::processTEcnResp(HostOsScanStats *hss, const struct ip *ip) {
bool HostOsScan::processT1_7Resp(HostOsScanStats *hss, const struct ip *ip, int replyNo) { bool HostOsScan::processT1_7Resp(HostOsScanStats *hss, const struct ip *ip, int replyNo) {
std::vector<struct AVal> AVs;
struct AVal AV; struct AVal AV;
assert(replyNo >= 0 && replyNo < 7); assert(replyNo >= 0 && replyNo < 7);
@@ -2909,13 +2911,14 @@ bool HostOsScan::processT1_7Resp(HostOsScanStats *hss, const struct ip *ip, int
else numtests = 10; else numtests = 10;
/* Create the Avals */ /* Create the Avals */
AVs.reserve(numtests); std::vector<struct AVal> *AVs = new std::vector<struct AVal>;
AVs->reserve(numtests);
/* First we give the "response" flag to say we did actually receive /* First we give the "response" flag to say we did actually receive
a packet -- this way we won't match a template with R=N */ a packet -- this way we won't match a template with R=N */
AV.attribute = "R"; AV.attribute = "R";
AV.value = "Y"; AV.value = "Y";
AVs.push_back(AV); AVs->push_back(AV);
/* Next we check whether the Don't Fragment bit is set */ /* Next we check whether the Don't Fragment bit is set */
AV.attribute = "DF"; AV.attribute = "DF";
@@ -2923,18 +2926,18 @@ bool HostOsScan::processT1_7Resp(HostOsScanStats *hss, const struct ip *ip, int
AV.value = "Y"; AV.value = "Y";
else else
AV.value = "N"; AV.value = "N";
AVs.push_back(AV); AVs->push_back(AV);
/* TTL */ /* TTL */
AV.attribute = "T"; AV.attribute = "T";
AV.value = string_pool_sprintf("%d", ip->ip_ttl); AV.value = string_pool_sprintf("%d", ip->ip_ttl);
AVs.push_back(AV); AVs->push_back(AV);
if (replyNo != 0) { if (replyNo != 0) {
/* Now we do the TCP Window size */ /* Now we do the TCP Window size */
AV.attribute = "W"; AV.attribute = "W";
AV.value = string_pool_sprintf("%hX", ntohs(tcp->th_win)); AV.value = string_pool_sprintf("%hX", ntohs(tcp->th_win));
AVs.push_back(AV); AVs->push_back(AV);
} }
/* Seq test values: /* Seq test values:
@@ -2952,7 +2955,7 @@ bool HostOsScan::processT1_7Resp(HostOsScanStats *hss, const struct ip *ip, int
AV.value = "A+"; AV.value = "A+";
else else
AV.value = "O"; AV.value = "O";
AVs.push_back(AV); AVs->push_back(AV);
/* ACK test values: /* ACK test values:
Z = zero Z = zero
@@ -2969,7 +2972,7 @@ bool HostOsScan::processT1_7Resp(HostOsScanStats *hss, const struct ip *ip, int
AV.value = "S+"; AV.value = "S+";
else else
AV.value = "O"; AV.value = "O";
AVs.push_back(AV); AVs->push_back(AV);
/* Flags. They must be in this order: /* Flags. They must be in this order:
E = ECN Echo E = ECN Echo
@@ -3001,7 +3004,7 @@ bool HostOsScan::processT1_7Resp(HostOsScanStats *hss, const struct ip *ip, int
} }
*p = '\0'; *p = '\0';
AV.value = string_pool_insert(flags_buf); AV.value = string_pool_insert(flags_buf);
AVs.push_back(AV); AVs->push_back(AV);
if (replyNo != 0) { if (replyNo != 0) {
char ops_buf[256]; char ops_buf[256];
@@ -3016,7 +3019,7 @@ bool HostOsScan::processT1_7Resp(HostOsScanStats *hss, const struct ip *ip, int
} }
AV.value = string_pool_insert(ops_buf); AV.value = string_pool_insert(ops_buf);
AVs.push_back(AV); AVs->push_back(AV);
} }
/* Rst Data CRC32 */ /* Rst Data CRC32 */
@@ -3027,7 +3030,7 @@ bool HostOsScan::processT1_7Resp(HostOsScanStats *hss, const struct ip *ip, int
} else { } else {
AV.value = "0"; AV.value = "0";
} }
AVs.push_back(AV); AVs->push_back(AV);
/* TCP miscellaneous quirks test */ /* TCP miscellaneous quirks test */
AV.attribute = "Q"; AV.attribute = "Q";
@@ -3044,7 +3047,7 @@ bool HostOsScan::processT1_7Resp(HostOsScanStats *hss, const struct ip *ip, int
} }
*p = '\0'; *p = '\0';
AV.value = string_pool_insert(quirks_buf); AV.value = string_pool_insert(quirks_buf);
AVs.push_back(AV); AVs->push_back(AV);
hss->FPtests[FP_T1_7_OFF + replyNo] = new FingerTest; hss->FPtests[FP_T1_7_OFF + replyNo] = new FingerTest;
hss->FPtests[FP_T1_7_OFF + replyNo]->results = AVs; hss->FPtests[FP_T1_7_OFF + replyNo]->results = AVs;
@@ -3055,7 +3058,6 @@ bool HostOsScan::processT1_7Resp(HostOsScanStats *hss, const struct ip *ip, int
bool HostOsScan::processTUdpResp(HostOsScanStats *hss, const struct ip *ip) { bool HostOsScan::processTUdpResp(HostOsScanStats *hss, const struct ip *ip) {
std::vector<struct AVal> AVs;
struct AVal AV; struct AVal AV;
assert(hss); assert(hss);
@@ -3094,12 +3096,13 @@ bool HostOsScan::processTUdpResp(HostOsScanStats *hss, const struct ip *ip) {
} }
/* Create the Avals */ /* Create the Avals */
AVs.reserve(numtests); std::vector<struct AVal> *AVs = new std::vector<struct AVal>;
AVs->reserve(numtests);
/* First of all, if we got this far the response was yes */ /* First of all, if we got this far the response was yes */
AV.attribute = "R"; AV.attribute = "R";
AV.value = "Y"; AV.value = "Y";
AVs.push_back(AV); AVs->push_back(AV);
/* Also, we now know that the port we reached was closed */ /* Also, we now know that the port we reached was closed */
if (hss->target->FPR->osscan_closedudpport == -1) if (hss->target->FPR->osscan_closedudpport == -1)
@@ -3111,23 +3114,23 @@ bool HostOsScan::processTUdpResp(HostOsScanStats *hss, const struct ip *ip) {
AV.value = "Y"; AV.value = "Y";
else else
AV.value = "N"; AV.value = "N";
AVs.push_back(AV); AVs->push_back(AV);
/* TTL */ /* TTL */
AV.attribute = "T"; AV.attribute = "T";
AV.value = string_pool_sprintf("%d", ip->ip_ttl); AV.value = string_pool_sprintf("%d", ip->ip_ttl);
AVs.push_back(AV); AVs->push_back(AV);
/* Now we look at the IP datagram length that was returned, some /* Now we look at the IP datagram length that was returned, some
machines send more of the original packet back than others */ machines send more of the original packet back than others */
AV.attribute = "IPL"; AV.attribute = "IPL";
AV.value = string_pool_sprintf("%hX", ntohs(ip->ip_len)); AV.value = string_pool_sprintf("%hX", ntohs(ip->ip_len));
AVs.push_back(AV); AVs->push_back(AV);
/* unused filed not zero in Destination Unreachable Message */ /* unused filed not zero in Destination Unreachable Message */
AV.attribute = "UN"; AV.attribute = "UN";
AV.value = string_pool_sprintf("%hX", ntohl(icmp->icmp_void)); AV.value = string_pool_sprintf("%hX", ntohl(icmp->icmp_void));
AVs.push_back(AV); AVs->push_back(AV);
/* OK, lets check the returned IP length, some systems @$@ this /* OK, lets check the returned IP length, some systems @$@ this
up */ up */
@@ -3136,7 +3139,7 @@ bool HostOsScan::processTUdpResp(HostOsScanStats *hss, const struct ip *ip) {
AV.value = "G"; AV.value = "G";
else else
AV.value = string_pool_sprintf("%hX", ntohs(ip2->ip_len)); AV.value = string_pool_sprintf("%hX", ntohs(ip2->ip_len));
AVs.push_back(AV); AVs->push_back(AV);
/* This next test doesn't work on Solaris because the lamers /* This next test doesn't work on Solaris because the lamers
overwrite our ip_id */ overwrite our ip_id */
@@ -3148,7 +3151,7 @@ bool HostOsScan::processTUdpResp(HostOsScanStats *hss, const struct ip *ip) {
AV.value = "G"; /* The good "expected" value */ AV.value = "G"; /* The good "expected" value */
else else
AV.value = string_pool_sprintf("%hX", ntohs(ip2->ip_id)); AV.value = string_pool_sprintf("%hX", ntohs(ip2->ip_id));
AVs.push_back(AV); AVs->push_back(AV);
#endif #endif
@@ -3171,7 +3174,7 @@ bool HostOsScan::processTUdpResp(HostOsScanStats *hss, const struct ip *ip) {
} }
*checksumptr = checksum; *checksumptr = checksum;
} }
AVs.push_back(AV); AVs->push_back(AV);
/* UDP checksum */ /* UDP checksum */
AV.attribute = "RUCK"; AV.attribute = "RUCK";
@@ -3179,7 +3182,7 @@ bool HostOsScan::processTUdpResp(HostOsScanStats *hss, const struct ip *ip) {
AV.value = "G"; /* The "expected" good value */ AV.value = "G"; /* The "expected" good value */
else else
AV.value = string_pool_sprintf("%hX", ntohs(udp->uh_sum)); AV.value = string_pool_sprintf("%hX", ntohs(udp->uh_sum));
AVs.push_back(AV); AVs->push_back(AV);
/* Finally we ensure the data is OK */ /* Finally we ensure the data is OK */
datastart = ((unsigned char *)udp) + 8; datastart = ((unsigned char *)udp) + 8;
@@ -3195,7 +3198,7 @@ bool HostOsScan::processTUdpResp(HostOsScanStats *hss, const struct ip *ip) {
AV.value = "I"; /* They modified it */ AV.value = "I"; /* They modified it */
else else
AV.value = "G"; AV.value = "G";
AVs.push_back(AV); AVs->push_back(AV);
hss->FP_TUdp = new FingerTest; hss->FP_TUdp = new FingerTest;
hss->FP_TUdp->name = "U1"; hss->FP_TUdp->name = "U1";
@@ -3213,7 +3216,6 @@ bool HostOsScan::processTUdpResp(HostOsScanStats *hss, const struct ip *ip) {
bool HostOsScan::processTIcmpResp(HostOsScanStats *hss, const struct ip *ip, int replyNo) { bool HostOsScan::processTIcmpResp(HostOsScanStats *hss, const struct ip *ip, int replyNo) {
assert(replyNo == 0 || replyNo == 1); assert(replyNo == 0 || replyNo == 1);
std::vector<struct AVal> AVs;
struct AVal AV; struct AVal AV;
int numtests = 4; int numtests = 4;
const struct ip *ip1, *ip2; const struct ip *ip1, *ip2;
@@ -3249,11 +3251,12 @@ bool HostOsScan::processTIcmpResp(HostOsScanStats *hss, const struct ip *ip, int
assert(icmp1->icmp_type == 0 && icmp2->icmp_type == 0); assert(icmp1->icmp_type == 0 && icmp2->icmp_type == 0);
/* Create the Avals */ /* Create the Avals */
AVs.reserve(numtests); std::vector<struct AVal> *AVs = new std::vector<struct AVal>;
AVs->reserve(numtests);
AV.attribute = "R"; AV.attribute = "R";
AV.value = "Y"; AV.value = "Y";
AVs.push_back(AV); AVs->push_back(AV);
/* DFI test values: /* DFI test values:
* Y. Both set DF; * Y. Both set DF;
@@ -3275,13 +3278,13 @@ bool HostOsScan::processTIcmpResp(HostOsScanStats *hss, const struct ip *ip, int
AV.value = "N"; AV.value = "N";
else else
AV.value = "O"; AV.value = "O";
AVs.push_back(AV); AVs->push_back(AV);
/* TTL */ /* TTL */
AV.attribute = "T"; AV.attribute = "T";
AV.value = string_pool_sprintf("%d", ip1->ip_ttl); AV.value = string_pool_sprintf("%d", ip1->ip_ttl);
AVs.push_back(AV); AVs->push_back(AV);
/* ICMP Code value. Test values: /* ICMP Code value. Test values:
* [Value]. Both set Code to the same value [Value]; * [Value]. Both set Code to the same value [Value];
@@ -3302,7 +3305,7 @@ bool HostOsScan::processTIcmpResp(HostOsScanStats *hss, const struct ip *ip, int
AV.value = "S"; AV.value = "S";
else else
AV.value = "O"; AV.value = "O";
AVs.push_back(AV); AVs->push_back(AV);
hss->FP_TIcmp= new FingerTest; hss->FP_TIcmp= new FingerTest;
hss->FP_TIcmp->name = "IE"; hss->FP_TIcmp->name = "IE";