mirror of
https://github.com/nmap/nmap.git
synced 2026-06-29 04:33:23 +00:00
Use TCPOptions class for IPv6 vectorization
This commit is contained in:
parent
c86a45ef6e
commit
84b525f61d
3 changed files with 36 additions and 95 deletions
76
FPEngine.cc
76
FPEngine.cc
|
|
@ -833,6 +833,33 @@ static int vectorize_icmpv6_code(const PacketElement *pe) {
|
|||
return icmpv6->getCode();
|
||||
}
|
||||
|
||||
struct tcpopt_vectorize_ctx {
|
||||
feature_node *features;
|
||||
const unsigned int base;
|
||||
unsigned int optnum;
|
||||
int mss;
|
||||
int sackok;
|
||||
int wscale;
|
||||
tcpopt_vectorize_ctx(feature_node *f, unsigned int i)
|
||||
: features(f), base(i), optnum(0), mss(-1), sackok(-1), wscale(-1) {}
|
||||
};
|
||||
|
||||
static const u8 MODEL_NUM_OPTS = 16;
|
||||
static bool tcpopt_vectorize(u8 op, u8 oplen, const u8 *data, void *ctx) {
|
||||
tcpopt_vectorize_ctx *c = static_cast<tcpopt_vectorize_ctx *>(ctx);
|
||||
c->features[c->base + c->optnum].value = op;
|
||||
c->features[c->base + c->optnum + MODEL_NUM_OPTS].value = oplen;
|
||||
if (op == TCPOPT_MSS && oplen == 4 && c->mss == -1)
|
||||
c->mss = (data[2] << 8) + data[3];
|
||||
else if (op == TCPOPT_SACKOK && oplen == 2 && c->sackok == -1)
|
||||
c->sackok = 1;
|
||||
else if (op == TCPOPT_WSCALE && oplen == 3 && c->wscale == -1)
|
||||
c->wscale = data[2];
|
||||
if (c->optnum++ < MODEL_NUM_OPTS)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct feature_node *vectorize(const FingerPrintResultsIPv6 *FPR) {
|
||||
const char * const IPV6_PROBE_NAMES[] = {"S1", "S2", "S3", "S4", "S5", "S6", "IE1", "IE2", "NS", "U1", "TECN", "T2", "T3", "T4", "T5", "T6", "T7"};
|
||||
const char * const TCP_PROBE_NAMES[] = {"S1", "S2", "S3", "S4", "S5", "S6", "TECN", "T2", "T3", "T4", "T5", "T6", "T7"};
|
||||
|
|
@ -877,17 +904,9 @@ static struct feature_node *vectorize(const FingerPrintResultsIPv6 *FPR) {
|
|||
const TCPHeader *tcp;
|
||||
u16 flags;
|
||||
u16 mask;
|
||||
unsigned int j;
|
||||
int mss;
|
||||
int sackok;
|
||||
int wscale;
|
||||
|
||||
probe_name = TCP_PROBE_NAMES[i];
|
||||
|
||||
mss = -1;
|
||||
sackok = -1;
|
||||
wscale = -1;
|
||||
|
||||
tcp = find_tcp(resps[probe_name].getPacket());
|
||||
if (tcp == NULL) {
|
||||
/* 49 TCP features. */
|
||||
|
|
@ -899,40 +918,17 @@ static struct feature_node *vectorize(const FingerPrintResultsIPv6 *FPR) {
|
|||
for (mask = 0x001; mask <= 0x800; mask <<= 1)
|
||||
features[idx++].value = (flags & mask) != 0;
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
nping_tcp_opt_t opt;
|
||||
opt = tcp->getOption(j);
|
||||
if (opt.value == NULL)
|
||||
break;
|
||||
features[idx++].value = opt.type;
|
||||
/* opt.len includes the two (type, len) bytes. */
|
||||
if (opt.type == TCPOPT_MSS && opt.len == 4 && mss == -1)
|
||||
mss = ntohs(*(u16 *) opt.value);
|
||||
else if (opt.type == TCPOPT_SACKOK && opt.len == 2 && sackok == -1)
|
||||
sackok = 1;
|
||||
else if (opt.type == TCPOPT_WSCALE && opt.len == 3 && wscale == -1)
|
||||
wscale = *(u8 *) opt.value;
|
||||
TCPOptions opts;
|
||||
tcpopt_vectorize_ctx ctx(features, idx);
|
||||
if (opts.fromTCPHeader(*tcp)) {
|
||||
opts.foreachOpt(tcpopt_vectorize, &ctx);
|
||||
}
|
||||
for (; j < 16; j++)
|
||||
idx++;
|
||||
idx += MODEL_NUM_OPTS * 2;
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
nping_tcp_opt_t opt;
|
||||
opt = tcp->getOption(j);
|
||||
if (opt.value == NULL)
|
||||
break;
|
||||
features[idx++].value = opt.len;
|
||||
}
|
||||
for (; j < 16; j++)
|
||||
idx++;
|
||||
|
||||
features[idx++].value = mss;
|
||||
features[idx++].value = sackok;
|
||||
features[idx++].value = wscale;
|
||||
if (mss != 0 && mss != -1)
|
||||
features[idx++].value = (float)tcp->getWindow() / mss;
|
||||
else
|
||||
features[idx++].value = -1;
|
||||
features[idx++].value = ctx.mss;
|
||||
features[idx++].value = ctx.sackok;
|
||||
features[idx++].value = ctx.wscale;
|
||||
features[idx++].value = (ctx.mss > 0) ? (float)tcp->getWindow() / ctx.mss : -1;
|
||||
}
|
||||
/* ICMPv6 features */
|
||||
for (i = 0; i < NELEMS(ICMPV6_PROBE_NAMES); i++) {
|
||||
|
|
|
|||
|
|
@ -813,47 +813,6 @@ const u8 *TCPHeader::getOptions(size_t *optslen) const {
|
|||
return this->h.options;
|
||||
} /* End of getOptions() */
|
||||
|
||||
struct tcpopt_atindex_ctx {
|
||||
unsigned int index;
|
||||
unsigned int found;
|
||||
nping_tcp_opt_t result;
|
||||
tcpopt_atindex_ctx() : index(0), found(0) {
|
||||
memset(&result, 0, sizeof(result));
|
||||
}
|
||||
};
|
||||
|
||||
static bool tcpopt_atindex(u8 op, u8 oplen, const u8 *data, void *ctx)
|
||||
{
|
||||
tcpopt_atindex_ctx *args = static_cast<tcpopt_atindex_ctx *>(ctx);
|
||||
if (args->index == args->found) {
|
||||
args->result.type = op;
|
||||
args->result.len = oplen;
|
||||
args->result.value = data + 2;
|
||||
return false;
|
||||
}
|
||||
args->found += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Returns the index-th option in the TCP header. On success it returns a
|
||||
* structure filled with option information. If there is no index-th option,
|
||||
* it returns a structure with st.value==NULL. Note that this function does
|
||||
* not perform strict validity checking. It does check that the length claimed
|
||||
* by the options does not exceed the available buffer but it does not check,
|
||||
* for example, that the MSS option always contains a length of 4. Also,
|
||||
* if the returned option type is TCPOPT_EOL or TCPOPT_NOOP, the len field
|
||||
* would be set to zero and the "value" field should NOT be accessed, as it
|
||||
* will not contain reliable information. */
|
||||
nping_tcp_opt_t TCPHeader::getOption(unsigned int index) const {
|
||||
TCPOptions opts;
|
||||
tcpopt_atindex_ctx ctx;
|
||||
if (opts.fromTCPHeader(*this)) {
|
||||
ctx.index = index;
|
||||
opts.foreachOpt(tcpopt_atindex, &ctx);
|
||||
}
|
||||
return ctx.result;
|
||||
}
|
||||
|
||||
|
||||
/* Returns a textual representation of a TCP Options code */
|
||||
const char *TCPHeader::optcode2str(u8 optcode){
|
||||
|
|
|
|||
|
|
@ -115,19 +115,6 @@
|
|||
|
||||
|
||||
|
||||
/*
|
||||
+--------+--------+---------+--------...
|
||||
| Type | Len | Value
|
||||
+--------+--------+---------+--------...
|
||||
*/
|
||||
struct nping_tcp_opt {
|
||||
u8 type; /* Option type code. */
|
||||
u8 len; /* Option length. */
|
||||
const u8 *value; /* Option value */
|
||||
}__attribute__((__packed__));
|
||||
typedef struct nping_tcp_opt nping_tcp_opt_t;
|
||||
|
||||
|
||||
class TCPHeader : public TransportLayerElement {
|
||||
|
||||
private:
|
||||
|
|
@ -252,7 +239,6 @@ class TCPHeader : public TransportLayerElement {
|
|||
|
||||
int setOptions(const u8 *optsbuff, size_t optslen);
|
||||
const u8 *getOptions(size_t *optslen) const;
|
||||
nping_tcp_opt_t getOption(unsigned int index) const;
|
||||
static const char *optcode2str(u8 optcode);
|
||||
|
||||
}; /* End of class TCPHeader */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue