Fix reassembly of data w/ sizes beyond 32-bit capacities (BIT-348).

The main change is that reassembly code (e.g. for TCP) now uses
int64/uint64 (signedness is situational) data types in place of int
types in order to support delivering data to analyzers that pass 2GB
thresholds.  There's also changes in logic that accompany the change in
data types, e.g. to fix TCP sequence space arithmetic inconsistencies.

Another significant change is in the Analyzer API: the *Packet and
*Undelivered methods now use a uint64 in place of an int for the
relative sequence space offset parameter.
This commit is contained in:
Jon Siwek 2014-04-09 13:03:24 -05:00
parent 2f57c26d5b
commit 2b3c2bd394
75 changed files with 1627 additions and 1540 deletions

View file

@ -97,9 +97,9 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt)
// Linux MTU discovery for UDP can do this, for example. // Linux MTU discovery for UDP can do this, for example.
s->Weird("fragment_with_DF", ip); s->Weird("fragment_with_DF", ip);
int offset = ip->FragOffset(); uint16 offset = ip->FragOffset();
int len = ip->TotalLen(); uint32 len = ip->TotalLen();
int hdr_len = ip->HdrLen(); uint16 hdr_len = ip->HdrLen();
if ( len < hdr_len ) if ( len < hdr_len )
{ {
@ -107,7 +107,7 @@ void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt)
return; return;
} }
int upper_seq = offset + len - hdr_len; uint64 upper_seq = offset + len - hdr_len;
if ( ! offset ) if ( ! offset )
// Make sure to use the first fragment header's next field. // Make sure to use the first fragment header's next field.
@ -178,7 +178,7 @@ void FragReassembler::Weird(const char* name) const
} }
} }
void FragReassembler::Overlap(const u_char* b1, const u_char* b2, int n) void FragReassembler::Overlap(const u_char* b1, const u_char* b2, uint64 n)
{ {
if ( memcmp((const void*) b1, (const void*) b2, n) ) if ( memcmp((const void*) b1, (const void*) b2, n) )
Weird("fragment_inconsistency"); Weird("fragment_inconsistency");
@ -231,7 +231,7 @@ void FragReassembler::BlockInserted(DataBlock* /* start_block */)
return; return;
// We have it all. Compute the expected size of the fragment. // We have it all. Compute the expected size of the fragment.
int n = proto_hdr_len + frag_size; uint64 n = proto_hdr_len + frag_size;
// It's possible that we have blocks associated with this fragment // It's possible that we have blocks associated with this fragment
// that exceed this size, if we saw MF fragments (which don't lead // that exceed this size, if we saw MF fragments (which don't lead

View file

@ -34,14 +34,14 @@ public:
protected: protected:
void BlockInserted(DataBlock* start_block); void BlockInserted(DataBlock* start_block);
void Overlap(const u_char* b1, const u_char* b2, int n); void Overlap(const u_char* b1, const u_char* b2, uint64 n);
void Weird(const char* name) const; void Weird(const char* name) const;
u_char* proto_hdr; u_char* proto_hdr;
IP_Hdr* reassembled_pkt; IP_Hdr* reassembled_pkt;
int proto_hdr_len; uint16 proto_hdr_len;
NetSessions* s; NetSessions* s;
int frag_size; // size of fully reassembled fragment uint64 frag_size; // size of fully reassembled fragment
uint16 next_proto; // first IPv6 fragment header's next proto field uint16 next_proto; // first IPv6 fragment header's next proto field
HashKey* key; HashKey* key;

View file

@ -7,14 +7,9 @@
#include "Reassem.h" #include "Reassem.h"
#include "Serializer.h" #include "Serializer.h"
const bool DEBUG_reassem = false; static const bool DEBUG_reassem = false;
#ifdef DEBUG DataBlock::DataBlock(const u_char* data, uint64 size, uint64 arg_seq,
int reassem_seen_bytes = 0;
int reassem_copied_bytes = 0;
#endif
DataBlock::DataBlock(const u_char* data, int size, int arg_seq,
DataBlock* arg_prev, DataBlock* arg_next) DataBlock* arg_prev, DataBlock* arg_next)
{ {
seq = arg_seq; seq = arg_seq;
@ -23,10 +18,6 @@ DataBlock::DataBlock(const u_char* data, int size, int arg_seq,
memcpy((void*) block, (const void*) data, size); memcpy((void*) block, (const void*) data, size);
#ifdef DEBUG
reassem_copied_bytes += size;
#endif
prev = arg_prev; prev = arg_prev;
next = arg_next; next = arg_next;
@ -38,9 +29,9 @@ DataBlock::DataBlock(const u_char* data, int size, int arg_seq,
Reassembler::total_size += pad_size(size) + padded_sizeof(DataBlock); Reassembler::total_size += pad_size(size) + padded_sizeof(DataBlock);
} }
unsigned int Reassembler::total_size = 0; uint64 Reassembler::total_size = 0;
Reassembler::Reassembler(int init_seq, ReassemblerType arg_type) Reassembler::Reassembler(uint64 init_seq, ReassemblerType arg_type)
{ {
blocks = last_block = 0; blocks = last_block = 0;
trim_seq = last_reassem_seq = init_seq; trim_seq = last_reassem_seq = init_seq;
@ -51,24 +42,20 @@ Reassembler::~Reassembler()
ClearBlocks(); ClearBlocks();
} }
void Reassembler::NewBlock(double t, int seq, int len, const u_char* data) void Reassembler::NewBlock(double t, uint64 seq, uint64 len, const u_char* data)
{ {
if ( len == 0 ) if ( len == 0 )
return; return;
#ifdef DEBUG uint64 upper_seq = seq + len;
reassem_seen_bytes += len;
#endif
int upper_seq = seq + len; if ( upper_seq <= trim_seq )
if ( seq_delta(upper_seq, trim_seq) <= 0 )
// Old data, don't do any work for it. // Old data, don't do any work for it.
return; return;
if ( seq_delta(seq, trim_seq) < 0 ) if ( seq < trim_seq )
{ // Partially old data, just keep the good stuff. { // Partially old data, just keep the good stuff.
int amount_old = seq_delta(trim_seq, seq); uint64 amount_old = trim_seq - seq;
data += amount_old; data += amount_old;
seq += amount_old; seq += amount_old;
@ -86,42 +73,42 @@ void Reassembler::NewBlock(double t, int seq, int len, const u_char* data)
BlockInserted(start_block); BlockInserted(start_block);
} }
int Reassembler::TrimToSeq(int seq) uint64 Reassembler::TrimToSeq(uint64 seq)
{ {
int num_missing = 0; uint64 num_missing = 0;
// Do this accounting before looking for Undelivered data, // Do this accounting before looking for Undelivered data,
// since that will alter last_reassem_seq. // since that will alter last_reassem_seq.
if ( blocks ) if ( blocks )
{ {
if ( seq_delta(blocks->seq, last_reassem_seq) > 0 ) if ( blocks->seq > last_reassem_seq )
// An initial hole. // An initial hole.
num_missing += seq_delta(blocks->seq, last_reassem_seq); num_missing += blocks->seq - last_reassem_seq;
} }
else if ( seq_delta(seq, last_reassem_seq) > 0 ) else if ( seq > last_reassem_seq )
{ // Trimming data we never delivered. { // Trimming data we never delivered.
if ( ! blocks ) if ( ! blocks )
// We won't have any accounting based on blocks // We won't have any accounting based on blocks
// for this hole. // for this hole.
num_missing += seq_delta(seq, last_reassem_seq); num_missing += seq - last_reassem_seq;
} }
if ( seq_delta(seq, last_reassem_seq) > 0 ) if ( seq > last_reassem_seq )
{ {
// We're trimming data we never delivered. // We're trimming data we never delivered.
Undelivered(seq); Undelivered(seq);
} }
while ( blocks && seq_delta(blocks->upper, seq) <= 0 ) while ( blocks && blocks->upper <= seq )
{ {
DataBlock* b = blocks->next; DataBlock* b = blocks->next;
if ( b && seq_delta(b->seq, seq) <= 0 ) if ( b && b->seq <= seq )
{ {
if ( blocks->upper != b->seq ) if ( blocks->upper != b->seq )
num_missing += seq_delta(b->seq, blocks->upper); num_missing += b->seq - blocks->upper;
} }
else else
{ {
@ -129,7 +116,7 @@ int Reassembler::TrimToSeq(int seq)
// Second half of test is for acks of FINs, which // Second half of test is for acks of FINs, which
// don't get entered into the sequence space. // don't get entered into the sequence space.
if ( blocks->upper != seq && blocks->upper != seq - 1 ) if ( blocks->upper != seq && blocks->upper != seq - 1 )
num_missing += seq_delta(seq, blocks->upper); num_missing += seq - blocks->upper;
} }
delete blocks; delete blocks;
@ -150,7 +137,7 @@ int Reassembler::TrimToSeq(int seq)
else else
last_block = 0; last_block = 0;
if ( seq_delta(seq, trim_seq) > 0 ) if ( seq > trim_seq )
// seq is further ahead in the sequence space. // seq is further ahead in the sequence space.
trim_seq = seq; trim_seq = seq;
@ -169,9 +156,9 @@ void Reassembler::ClearBlocks()
last_block = 0; last_block = 0;
} }
int Reassembler::TotalSize() const uint64 Reassembler::TotalSize() const
{ {
int size = 0; uint64 size = 0;
for ( DataBlock* b = blocks; b; b = b->next ) for ( DataBlock* b = blocks; b; b = b->next )
size += b->Size(); size += b->Size();
@ -184,18 +171,18 @@ void Reassembler::Describe(ODesc* d) const
d->Add("reassembler"); d->Add("reassembler");
} }
void Reassembler::Undelivered(int up_to_seq) void Reassembler::Undelivered(uint64 up_to_seq)
{ {
// TrimToSeq() expects this. // TrimToSeq() expects this.
last_reassem_seq = up_to_seq; last_reassem_seq = up_to_seq;
} }
DataBlock* Reassembler::AddAndCheck(DataBlock* b, int seq, int upper, DataBlock* Reassembler::AddAndCheck(DataBlock* b, uint64 seq, uint64 upper,
const u_char* data) const u_char* data)
{ {
if ( DEBUG_reassem ) if ( DEBUG_reassem )
{ {
DEBUG_MSG("%.6f Reassembler::AddAndCheck seq=%d, upper=%d\n", DEBUG_MSG("%.6f Reassembler::AddAndCheck seq=%"PRIu64", upper=%"PRIu64"\n",
network_time, seq, upper); network_time, seq, upper);
} }
@ -209,10 +196,10 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, int seq, int upper,
// Find the first block that doesn't come completely before the // Find the first block that doesn't come completely before the
// new data. // new data.
while ( b->next && seq_delta(b->upper, seq) <= 0 ) while ( b->next && b->upper <= seq )
b = b->next; b = b->next;
if ( seq_delta(b->upper, seq) <= 0 ) if ( b->upper <= seq )
{ {
// b is the last block, and it comes completely before // b is the last block, and it comes completely before
// the new block. // the new block.
@ -222,21 +209,20 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, int seq, int upper,
DataBlock* new_b = 0; DataBlock* new_b = 0;
if ( seq_delta(upper, b->seq) <= 0 ) if ( upper <= b->seq )
{ {
// The new block comes completely before b. // The new block comes completely before b.
new_b = new DataBlock(data, seq_delta(upper, seq), seq, new_b = new DataBlock(data, upper - seq, seq, b->prev, b);
b->prev, b);
if ( b == blocks ) if ( b == blocks )
blocks = new_b; blocks = new_b;
return new_b; return new_b;
} }
// The blocks overlap, complain. // The blocks overlap, complain.
if ( seq_delta(seq, b->seq) < 0 ) if ( seq < b->seq )
{ {
// The new block has a prefix that comes before b. // The new block has a prefix that comes before b.
int prefix_len = seq_delta(b->seq, seq); uint64 prefix_len = b->seq - seq;
new_b = new DataBlock(data, prefix_len, seq, b->prev, b); new_b = new DataBlock(data, prefix_len, seq, b->prev, b);
if ( b == blocks ) if ( b == blocks )
blocks = new_b; blocks = new_b;
@ -247,11 +233,11 @@ DataBlock* Reassembler::AddAndCheck(DataBlock* b, int seq, int upper,
else else
new_b = b; new_b = b;
int overlap_start = seq; uint64 overlap_start = seq;
int overlap_offset = seq_delta(overlap_start, b->seq); uint64 overlap_offset = overlap_start - b->seq;
int new_b_len = seq_delta(upper, seq); uint64 new_b_len = upper - seq;
int b_len = seq_delta(b->upper, overlap_start); uint64 b_len = b->upper - overlap_start;
int overlap_len = min(new_b_len, b_len); uint64 overlap_len = min(new_b_len, b_len);
Overlap(&b->block[overlap_offset], data, overlap_len); Overlap(&b->block[overlap_offset], data, overlap_len);

View file

@ -8,16 +8,16 @@
class DataBlock { class DataBlock {
public: public:
DataBlock(const u_char* data, int size, int seq, DataBlock(const u_char* data, uint64 size, uint64 seq,
DataBlock* prev, DataBlock* next); DataBlock* prev, DataBlock* next);
~DataBlock(); ~DataBlock();
int Size() const { return upper - seq; } uint64 Size() const { return upper - seq; }
DataBlock* next; // next block with higher seq # DataBlock* next; // next block with higher seq #
DataBlock* prev; // previous block with lower seq # DataBlock* prev; // previous block with lower seq #
int seq, upper; uint64 seq, upper;
u_char* block; u_char* block;
}; };
@ -26,22 +26,22 @@ enum ReassemblerType { REASSEM_IP, REASSEM_TCP };
class Reassembler : public BroObj { class Reassembler : public BroObj {
public: public:
Reassembler(int init_seq, ReassemblerType arg_type); Reassembler(uint64 init_seq, ReassemblerType arg_type);
virtual ~Reassembler(); virtual ~Reassembler();
void NewBlock(double t, int seq, int len, const u_char* data); void NewBlock(double t, uint64 seq, uint64 len, const u_char* data);
// Throws away all blocks up to seq. Returns number of bytes // Throws away all blocks up to seq. Returns number of bytes
// if not all in-sequence, 0 if they were. // if not all in-sequence, 0 if they were.
int TrimToSeq(int seq); uint64 TrimToSeq(uint64 seq);
// Delete all held blocks. // Delete all held blocks.
void ClearBlocks(); void ClearBlocks();
int HasBlocks() const { return blocks != 0; } int HasBlocks() const { return blocks != 0; }
int LastReassemSeq() const { return last_reassem_seq; } uint64 LastReassemSeq() const { return last_reassem_seq; }
int TotalSize() const; // number of bytes buffered up uint64 TotalSize() const; // number of bytes buffered up
void Describe(ODesc* d) const; void Describe(ODesc* d) const;
@ -49,7 +49,7 @@ public:
static Reassembler* Unserialize(UnserialInfo* info); static Reassembler* Unserialize(UnserialInfo* info);
// Sum over all data buffered in some reassembler. // Sum over all data buffered in some reassembler.
static unsigned int TotalMemoryAllocation() { return total_size; } static uint64 TotalMemoryAllocation() { return total_size; }
protected: protected:
Reassembler() { } Reassembler() { }
@ -58,20 +58,20 @@ protected:
friend class DataBlock; friend class DataBlock;
virtual void Undelivered(int up_to_seq); virtual void Undelivered(uint64 up_to_seq);
virtual void BlockInserted(DataBlock* b) = 0; virtual void BlockInserted(DataBlock* b) = 0;
virtual void Overlap(const u_char* b1, const u_char* b2, int n) = 0; virtual void Overlap(const u_char* b1, const u_char* b2, uint64 n) = 0;
DataBlock* AddAndCheck(DataBlock* b, int seq, DataBlock* AddAndCheck(DataBlock* b, uint64 seq,
int upper, const u_char* data); uint64 upper, const u_char* data);
DataBlock* blocks; DataBlock* blocks;
DataBlock* last_block; DataBlock* last_block;
int last_reassem_seq; uint64 last_reassem_seq;
int trim_seq; // how far we've trimmed uint64 trim_seq; // how far we've trimmed
static unsigned int total_size; static uint64 total_size;
}; };
inline DataBlock::~DataBlock() inline DataBlock::~DataBlock()

View file

@ -160,7 +160,7 @@ void ProfileLogger::Log()
file->Write(fmt("%.06f Connections expired due to inactivity: %d\n", file->Write(fmt("%.06f Connections expired due to inactivity: %d\n",
network_time, killed_by_inactivity)); network_time, killed_by_inactivity));
file->Write(fmt("%.06f Total reassembler data: %dK\n", network_time, file->Write(fmt("%.06f Total reassembler data: %"PRIu64"K\n", network_time,
Reassembler::TotalMemoryAllocation() / 1024)); Reassembler::TotalMemoryAllocation() / 1024));
// Signature engine. // Signature engine.

View file

@ -203,7 +203,7 @@ void Analyzer::Done()
finished = true; finished = true;
} }
void Analyzer::NextPacket(int len, const u_char* data, bool is_orig, int seq, void Analyzer::NextPacket(int len, const u_char* data, bool is_orig, uint64 seq,
const IP_Hdr* ip, int caplen) const IP_Hdr* ip, int caplen)
{ {
if ( skip ) if ( skip )
@ -250,7 +250,7 @@ void Analyzer::NextStream(int len, const u_char* data, bool is_orig)
} }
} }
void Analyzer::NextUndelivered(int seq, int len, bool is_orig) void Analyzer::NextUndelivered(uint64 seq, int len, bool is_orig)
{ {
if ( skip ) if ( skip )
return; return;
@ -287,7 +287,7 @@ void Analyzer::NextEndOfData(bool is_orig)
} }
void Analyzer::ForwardPacket(int len, const u_char* data, bool is_orig, void Analyzer::ForwardPacket(int len, const u_char* data, bool is_orig,
int seq, const IP_Hdr* ip, int caplen) uint64 seq, const IP_Hdr* ip, int caplen)
{ {
if ( output_handler ) if ( output_handler )
output_handler->DeliverPacket(len, data, is_orig, seq, output_handler->DeliverPacket(len, data, is_orig, seq,
@ -335,7 +335,7 @@ void Analyzer::ForwardStream(int len, const u_char* data, bool is_orig)
AppendNewChildren(); AppendNewChildren();
} }
void Analyzer::ForwardUndelivered(int seq, int len, bool is_orig) void Analyzer::ForwardUndelivered(uint64 seq, int len, bool is_orig)
{ {
if ( output_handler ) if ( output_handler )
output_handler->Undelivered(seq, len, is_orig); output_handler->Undelivered(seq, len, is_orig);
@ -595,9 +595,9 @@ SupportAnalyzer* Analyzer::FirstSupportAnalyzer(bool orig)
} }
void Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, void Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
int seq, const IP_Hdr* ip, int caplen) uint64 seq, const IP_Hdr* ip, int caplen)
{ {
DBG_LOG(DBG_ANALYZER, "%s DeliverPacket(%d, %s, %d, %p, %d) [%s%s]", DBG_LOG(DBG_ANALYZER, "%s DeliverPacket(%d, %s, %"PRIu64", %p, %d) [%s%s]",
fmt_analyzer(this).c_str(), len, is_orig ? "T" : "F", seq, ip, caplen, fmt_analyzer(this).c_str(), len, is_orig ? "T" : "F", seq, ip, caplen,
fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : ""); fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
} }
@ -609,9 +609,9 @@ void Analyzer::DeliverStream(int len, const u_char* data, bool is_orig)
fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : ""); fmt_bytes((const char*) data, min(40, len)), len > 40 ? "..." : "");
} }
void Analyzer::Undelivered(int seq, int len, bool is_orig) void Analyzer::Undelivered(uint64 seq, int len, bool is_orig)
{ {
DBG_LOG(DBG_ANALYZER, "%s Undelivered(%d, %d, %s)", DBG_LOG(DBG_ANALYZER, "%s Undelivered(%"PRIu64", %d, %s)",
fmt_analyzer(this).c_str(), seq, len, is_orig ? "T" : "F"); fmt_analyzer(this).c_str(), seq, len, is_orig ? "T" : "F");
} }
@ -793,7 +793,7 @@ SupportAnalyzer* SupportAnalyzer::Sibling(bool only_active) const
} }
void SupportAnalyzer::ForwardPacket(int len, const u_char* data, bool is_orig, void SupportAnalyzer::ForwardPacket(int len, const u_char* data, bool is_orig,
int seq, const IP_Hdr* ip, int caplen) uint64 seq, const IP_Hdr* ip, int caplen)
{ {
// We do not call parent's method, as we're replacing the functionality. // We do not call parent's method, as we're replacing the functionality.
@ -834,7 +834,7 @@ void SupportAnalyzer::ForwardStream(int len, const u_char* data, bool is_orig)
Parent()->DeliverStream(len, data, is_orig); Parent()->DeliverStream(len, data, is_orig);
} }
void SupportAnalyzer::ForwardUndelivered(int seq, int len, bool is_orig) void SupportAnalyzer::ForwardUndelivered(uint64 seq, int len, bool is_orig)
{ {
// We do not call parent's method, as we're replacing the functionality. // We do not call parent's method, as we're replacing the functionality.

View file

@ -44,7 +44,7 @@ public:
* Analyzer::DeliverPacket(). * Analyzer::DeliverPacket().
*/ */
virtual void DeliverPacket(int len, const u_char* data, virtual void DeliverPacket(int len, const u_char* data,
bool orig, int seq, bool orig, uint64 seq,
const IP_Hdr* ip, int caplen) const IP_Hdr* ip, int caplen)
{ } { }
@ -59,7 +59,7 @@ public:
* Hook for receiving notification of stream gaps. Parameters are the * Hook for receiving notification of stream gaps. Parameters are the
* same as for Analyzer::Undelivered(). * same as for Analyzer::Undelivered().
*/ */
virtual void Undelivered(int seq, int len, bool orig) { } virtual void Undelivered(uint64 seq, int len, bool orig) { }
}; };
/** /**
@ -143,7 +143,7 @@ public:
* @param caplen The packet's capture length, if available. * @param caplen The packet's capture length, if available.
*/ */
void NextPacket(int len, const u_char* data, bool is_orig, void NextPacket(int len, const u_char* data, bool is_orig,
int seq = -1, const IP_Hdr* ip = 0, int caplen = 0); uint64 seq = -1, const IP_Hdr* ip = 0, int caplen = 0);
/** /**
* Passes stream input to the analyzer for processing. The analyzer * Passes stream input to the analyzer for processing. The analyzer
@ -173,7 +173,7 @@ public:
* *
* @param is_orig True if this is about originator-side input. * @param is_orig True if this is about originator-side input.
*/ */
void NextUndelivered(int seq, int len, bool is_orig); void NextUndelivered(uint64 seq, int len, bool is_orig);
/** /**
* Reports a message boundary. This is a generic method that can be * Reports a message boundary. This is a generic method that can be
@ -195,7 +195,7 @@ public:
* Parameters are the same as for NextPacket(). * Parameters are the same as for NextPacket().
*/ */
virtual void ForwardPacket(int len, const u_char* data, virtual void ForwardPacket(int len, const u_char* data,
bool orig, int seq, bool orig, uint64 seq,
const IP_Hdr* ip, int caplen); const IP_Hdr* ip, int caplen);
/** /**
@ -212,7 +212,7 @@ public:
* *
* Parameters are the same as for NextUndelivered(). * Parameters are the same as for NextUndelivered().
*/ */
virtual void ForwardUndelivered(int seq, int len, bool orig); virtual void ForwardUndelivered(uint64 seq, int len, bool orig);
/** /**
* Forwards an end-of-data notification on to all child analyzers. * Forwards an end-of-data notification on to all child analyzers.
@ -227,7 +227,7 @@ public:
* Parameters are the same. * Parameters are the same.
*/ */
virtual void DeliverPacket(int len, const u_char* data, bool orig, virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
/** /**
* Hook for accessing stream input for parsing. This is called by * Hook for accessing stream input for parsing. This is called by
@ -241,7 +241,7 @@ public:
* NextUndelivered() and can be overridden by derived classes. * NextUndelivered() and can be overridden by derived classes.
* Parameters are the same. * Parameters are the same.
*/ */
virtual void Undelivered(int seq, int len, bool orig); virtual void Undelivered(uint64 seq, int len, bool orig);
/** /**
* Hook for accessing end-of-data notifications. This is called by * Hook for accessing end-of-data notifications. This is called by
@ -749,7 +749,7 @@ public:
* Parameters same as for Analyzer::ForwardPacket. * Parameters same as for Analyzer::ForwardPacket.
*/ */
virtual void ForwardPacket(int len, const u_char* data, bool orig, virtual void ForwardPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
/** /**
* Passes stream input to the next sibling SupportAnalyzer if any, or * Passes stream input to the next sibling SupportAnalyzer if any, or
@ -769,7 +769,7 @@ public:
* *
* Parameters same as for Analyzer::ForwardPacket. * Parameters same as for Analyzer::ForwardPacket.
*/ */
virtual void ForwardUndelivered(int seq, int len, bool orig); virtual void ForwardUndelivered(uint64 seq, int len, bool orig);
protected: protected:
friend class Analyzer; friend class Analyzer;

View file

@ -22,7 +22,7 @@ void AYIYA_Analyzer::Done()
Event(udp_session_done); Event(udp_session_done);
} }
void AYIYA_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) void AYIYA_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, uint64 seq, const IP_Hdr* ip, int caplen)
{ {
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);

View file

@ -12,7 +12,7 @@ public:
virtual void Done(); virtual void Done();
virtual void DeliverPacket(int len, const u_char* data, bool orig, virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new AYIYA_Analyzer(conn); } { return new AYIYA_Analyzer(conn); }

View file

@ -46,7 +46,7 @@ void BackDoorEndpoint::FinalCheckForRlogin()
} }
} }
int BackDoorEndpoint::DataSent(double /* t */, int seq, int BackDoorEndpoint::DataSent(double /* t */, uint64 seq,
int len, int caplen, const u_char* data, int len, int caplen, const u_char* data,
const IP_Hdr* /* ip */, const IP_Hdr* /* ip */,
const struct tcphdr* /* tp */) const struct tcphdr* /* tp */)
@ -60,8 +60,8 @@ int BackDoorEndpoint::DataSent(double /* t */, int seq,
if ( endp->state == tcp::TCP_ENDPOINT_PARTIAL ) if ( endp->state == tcp::TCP_ENDPOINT_PARTIAL )
is_partial = 1; is_partial = 1;
int ack = endp->AckSeq() - endp->StartSeq(); uint64 ack = endp->ToRelativeSeqSpace(endp->AckSeq(), endp->AckWraps());
int top_seq = seq + len; uint64 top_seq = seq + len;
if ( top_seq <= ack || top_seq <= max_top_seq ) if ( top_seq <= ack || top_seq <= max_top_seq )
// There is no new data in this packet. // There is no new data in this packet.
@ -124,7 +124,7 @@ RecordVal* BackDoorEndpoint::BuildStats()
return stats; return stats;
} }
void BackDoorEndpoint::CheckForRlogin(int seq, int len, const u_char* data) void BackDoorEndpoint::CheckForRlogin(uint64 seq, int len, const u_char* data)
{ {
if ( rlogin_checking_done ) if ( rlogin_checking_done )
return; return;
@ -177,7 +177,7 @@ void BackDoorEndpoint::CheckForRlogin(int seq, int len, const u_char* data)
if ( seq < max_top_seq ) if ( seq < max_top_seq )
{ // trim to just the new data { // trim to just the new data
int delta = max_top_seq - seq; int64 delta = max_top_seq - seq;
seq += delta; seq += delta;
data += delta; data += delta;
len -= delta; len -= delta;
@ -255,7 +255,7 @@ void BackDoorEndpoint::RloginSignatureFound(int len)
endp->TCP()->ConnectionEvent(rlogin_signature_found, vl); endp->TCP()->ConnectionEvent(rlogin_signature_found, vl);
} }
void BackDoorEndpoint::CheckForTelnet(int /* seq */, int len, const u_char* data) void BackDoorEndpoint::CheckForTelnet(uint64 /* seq */, int len, const u_char* data)
{ {
if ( len >= 3 && if ( len >= 3 &&
data[0] == TELNET_IAC && IS_TELNET_NEGOTIATION_CMD(data[1]) ) data[0] == TELNET_IAC && IS_TELNET_NEGOTIATION_CMD(data[1]) )
@ -346,7 +346,7 @@ void BackDoorEndpoint::TelnetSignatureFound(int len)
endp->TCP()->ConnectionEvent(telnet_signature_found, vl); endp->TCP()->ConnectionEvent(telnet_signature_found, vl);
} }
void BackDoorEndpoint::CheckForSSH(int seq, int len, const u_char* data) void BackDoorEndpoint::CheckForSSH(uint64 seq, int len, const u_char* data)
{ {
if ( seq == 1 && CheckForString("SSH-", data, len) && len > 4 && if ( seq == 1 && CheckForString("SSH-", data, len) && len > 4 &&
(data[4] == '1' || data[4] == '2') ) (data[4] == '1' || data[4] == '2') )
@ -363,8 +363,9 @@ void BackDoorEndpoint::CheckForSSH(int seq, int len, const u_char* data)
if ( seq > max_top_seq ) if ( seq > max_top_seq )
{ // Estimate number of packets in the sequence gap { // Estimate number of packets in the sequence gap
int gap = seq - max_top_seq; int64 gap = seq - max_top_seq;
num_pkts += int((gap + DEFAULT_MTU - 1) / DEFAULT_MTU); if ( gap > 0 )
num_pkts += uint64((gap + DEFAULT_MTU - 1) / DEFAULT_MTU);
} }
++num_pkts; ++num_pkts;
@ -388,7 +389,7 @@ void BackDoorEndpoint::CheckForSSH(int seq, int len, const u_char* data)
} }
} }
void BackDoorEndpoint::CheckForRootBackdoor(int seq, int len, const u_char* data) void BackDoorEndpoint::CheckForRootBackdoor(uint64 seq, int len, const u_char* data)
{ {
// Check for root backdoor signature: an initial payload of // Check for root backdoor signature: an initial payload of
// exactly "# ". // exactly "# ".
@ -397,7 +398,7 @@ void BackDoorEndpoint::CheckForRootBackdoor(int seq, int len, const u_char* data
SignatureFound(root_backdoor_signature_found); SignatureFound(root_backdoor_signature_found);
} }
void BackDoorEndpoint::CheckForFTP(int seq, int len, const u_char* data) void BackDoorEndpoint::CheckForFTP(uint64 seq, int len, const u_char* data)
{ {
// Check for FTP signature // Check for FTP signature
// //
@ -429,7 +430,7 @@ void BackDoorEndpoint::CheckForFTP(int seq, int len, const u_char* data)
SignatureFound(ftp_signature_found); SignatureFound(ftp_signature_found);
} }
void BackDoorEndpoint::CheckForNapster(int seq, int len, const u_char* data) void BackDoorEndpoint::CheckForNapster(uint64 seq, int len, const u_char* data)
{ {
// Check for Napster signature "GETfoobar" or "SENDfoobar" where // Check for Napster signature "GETfoobar" or "SENDfoobar" where
// "foobar" is the Napster handle associated with the request // "foobar" is the Napster handle associated with the request
@ -449,7 +450,7 @@ void BackDoorEndpoint::CheckForNapster(int seq, int len, const u_char* data)
SignatureFound(napster_signature_found); SignatureFound(napster_signature_found);
} }
void BackDoorEndpoint::CheckForSMTP(int seq, int len, const u_char* data) void BackDoorEndpoint::CheckForSMTP(uint64 seq, int len, const u_char* data)
{ {
const char* smtp_handshake[] = { "HELO", "EHLO", 0 }; const char* smtp_handshake[] = { "HELO", "EHLO", 0 };
@ -460,7 +461,7 @@ void BackDoorEndpoint::CheckForSMTP(int seq, int len, const u_char* data)
SignatureFound(smtp_signature_found); SignatureFound(smtp_signature_found);
} }
void BackDoorEndpoint::CheckForIRC(int seq, int len, const u_char* data) void BackDoorEndpoint::CheckForIRC(uint64 seq, int len, const u_char* data)
{ {
if ( seq != 1 || is_partial ) if ( seq != 1 || is_partial )
return; return;
@ -475,7 +476,7 @@ void BackDoorEndpoint::CheckForIRC(int seq, int len, const u_char* data)
SignatureFound(irc_signature_found); SignatureFound(irc_signature_found);
} }
void BackDoorEndpoint::CheckForGnutella(int seq, int len, const u_char* data) void BackDoorEndpoint::CheckForGnutella(uint64 seq, int len, const u_char* data)
{ {
// After connecting to the server, the connecting client says: // After connecting to the server, the connecting client says:
// //
@ -492,13 +493,13 @@ void BackDoorEndpoint::CheckForGnutella(int seq, int len, const u_char* data)
SignatureFound(gnutella_signature_found); SignatureFound(gnutella_signature_found);
} }
void BackDoorEndpoint::CheckForGaoBot(int seq, int len, const u_char* data) void BackDoorEndpoint::CheckForGaoBot(uint64 seq, int len, const u_char* data)
{ {
if ( seq == 1 && CheckForString("220 Bot Server (Win32)", data, len) ) if ( seq == 1 && CheckForString("220 Bot Server (Win32)", data, len) )
SignatureFound(gaobot_signature_found); SignatureFound(gaobot_signature_found);
} }
void BackDoorEndpoint::CheckForKazaa(int seq, int len, const u_char* data) void BackDoorEndpoint::CheckForKazaa(uint64 seq, int len, const u_char* data)
{ {
// *Some*, though not all, KaZaa connections begin with: // *Some*, though not all, KaZaa connections begin with:
// //
@ -565,7 +566,7 @@ int is_absolute_url(const u_char* data, int len)
return *abs_url_sig_pos == '\0'; return *abs_url_sig_pos == '\0';
} }
void BackDoorEndpoint::CheckForHTTP(int seq, int len, const u_char* data) void BackDoorEndpoint::CheckForHTTP(uint64 seq, int len, const u_char* data)
{ {
// According to the RFC, we should look for // According to the RFC, we should look for
// '<method> SP <url> SP HTTP/<version> CR LF' // '<method> SP <url> SP HTTP/<version> CR LF'
@ -629,7 +630,7 @@ void BackDoorEndpoint::CheckForHTTP(int seq, int len, const u_char* data)
} }
} }
void BackDoorEndpoint::CheckForHTTPProxy(int /* seq */, int len, void BackDoorEndpoint::CheckForHTTPProxy(uint64 /* seq */, int len,
const u_char* data) const u_char* data)
{ {
// Proxy ONLY accepts absolute URI's: "The absoluteURI form is // Proxy ONLY accepts absolute URI's: "The absoluteURI form is
@ -713,7 +714,7 @@ void BackDoor_Analyzer::Init()
} }
void BackDoor_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, void BackDoor_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
int seq, const IP_Hdr* ip, int caplen) uint64 seq, const IP_Hdr* ip, int caplen)
{ {
Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen);

View file

@ -14,7 +14,7 @@ class BackDoorEndpoint {
public: public:
BackDoorEndpoint(tcp::TCP_Endpoint* e); BackDoorEndpoint(tcp::TCP_Endpoint* e);
int DataSent(double t, int seq, int len, int caplen, const u_char* data, int DataSent(double t, uint64 seq, int len, int caplen, const u_char* data,
const IP_Hdr* ip, const struct tcphdr* tp); const IP_Hdr* ip, const struct tcphdr* tp);
RecordVal* BuildStats(); RecordVal* BuildStats();
@ -22,23 +22,23 @@ public:
void FinalCheckForRlogin(); void FinalCheckForRlogin();
protected: protected:
void CheckForRlogin(int seq, int len, const u_char* data); void CheckForRlogin(uint64 seq, int len, const u_char* data);
void RloginSignatureFound(int len); void RloginSignatureFound(int len);
void CheckForTelnet(int seq, int len, const u_char* data); void CheckForTelnet(uint64 seq, int len, const u_char* data);
void TelnetSignatureFound(int len); void TelnetSignatureFound(int len);
void CheckForSSH(int seq, int len, const u_char* data); void CheckForSSH(uint64 seq, int len, const u_char* data);
void CheckForFTP(int seq, int len, const u_char* data); void CheckForFTP(uint64 seq, int len, const u_char* data);
void CheckForRootBackdoor(int seq, int len, const u_char* data); void CheckForRootBackdoor(uint64 seq, int len, const u_char* data);
void CheckForNapster(int seq, int len, const u_char* data); void CheckForNapster(uint64 seq, int len, const u_char* data);
void CheckForGnutella(int seq, int len, const u_char* data); void CheckForGnutella(uint64 seq, int len, const u_char* data);
void CheckForKazaa(int seq, int len, const u_char* data); void CheckForKazaa(uint64 seq, int len, const u_char* data);
void CheckForHTTP(int seq, int len, const u_char* data); void CheckForHTTP(uint64 seq, int len, const u_char* data);
void CheckForHTTPProxy(int seq, int len, const u_char* data); void CheckForHTTPProxy(uint64 seq, int len, const u_char* data);
void CheckForSMTP(int seq, int len, const u_char* data); void CheckForSMTP(uint64 seq, int len, const u_char* data);
void CheckForIRC(int seq, int len, const u_char* data); void CheckForIRC(uint64 seq, int len, const u_char* data);
void CheckForGaoBot(int seq, int len, const u_char* data); void CheckForGaoBot(uint64 seq, int len, const u_char* data);
void SignatureFound(EventHandlerPtr e, int do_orig = 0); void SignatureFound(EventHandlerPtr e, int do_orig = 0);
@ -48,11 +48,11 @@ protected:
tcp::TCP_Endpoint* endp; tcp::TCP_Endpoint* endp;
int is_partial; int is_partial;
int max_top_seq; uint64 max_top_seq;
int rlogin_checking_done; int rlogin_checking_done;
int rlogin_num_null; int rlogin_num_null;
int rlogin_string_separator_pos; uint64 rlogin_string_separator_pos;
int rlogin_slash_seen; int rlogin_slash_seen;
uint32 num_pkts; uint32 num_pkts;
@ -80,7 +80,7 @@ protected:
// We support both packet and stream input, and can be instantiated // We support both packet and stream input, and can be instantiated
// even if the TCP analyzer is not yet reassembling. // even if the TCP analyzer is not yet reassembling.
virtual void DeliverPacket(int len, const u_char* data, bool is_orig, virtual void DeliverPacket(int len, const u_char* data, bool is_orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
virtual void DeliverStream(int len, const u_char* data, bool is_orig); virtual void DeliverStream(int len, const u_char* data, bool is_orig);
void StatEvent(); void StatEvent();

View file

@ -68,7 +68,7 @@ void BitTorrent_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
} }
} }
void BitTorrent_Analyzer::Undelivered(int seq, int len, bool orig) void BitTorrent_Analyzer::Undelivered(uint64 seq, int len, bool orig)
{ {
tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);

View file

@ -16,7 +16,7 @@ public:
virtual void Done(); virtual void Done();
virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void DeliverStream(int len, const u_char* data, bool orig);
virtual void Undelivered(int seq, int len, bool orig); virtual void Undelivered(uint64 seq, int len, bool orig);
virtual void EndpointEOF(bool is_orig); virtual void EndpointEOF(bool is_orig);
static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)

View file

@ -207,7 +207,7 @@ void BitTorrentTracker_Analyzer::ServerReply(int len, const u_char* data)
} }
} }
void BitTorrentTracker_Analyzer::Undelivered(int seq, int len, bool orig) void BitTorrentTracker_Analyzer::Undelivered(uint64 seq, int len, bool orig)
{ {
tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);

View file

@ -49,7 +49,7 @@ public:
virtual void Done(); virtual void Done();
virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void DeliverStream(int len, const u_char* data, bool orig);
virtual void Undelivered(int seq, int len, bool orig); virtual void Undelivered(uint64 seq, int len, bool orig);
virtual void EndpointEOF(bool is_orig); virtual void EndpointEOF(bool is_orig);
static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)

View file

@ -36,7 +36,7 @@ void ConnSize_Analyzer::Done()
Analyzer::Done(); Analyzer::Done();
} }
void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, int seq, const IP_Hdr* ip, int caplen) void ConnSize_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen)
{ {
Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen);

View file

@ -26,7 +26,7 @@ public:
protected: protected:
virtual void DeliverPacket(int len, const u_char* data, bool is_orig, virtual void DeliverPacket(int len, const u_char* data, bool is_orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
uint64_t orig_bytes; uint64_t orig_bytes;

View file

@ -21,7 +21,7 @@ void DHCP_Analyzer::Done()
} }
void DHCP_Analyzer::DeliverPacket(int len, const u_char* data, void DHCP_Analyzer::DeliverPacket(int len, const u_char* data,
bool orig, int seq, const IP_Hdr* ip, int caplen) bool orig, uint64 seq, const IP_Hdr* ip, int caplen)
{ {
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
interp->NewData(orig, data, data + len); interp->NewData(orig, data, data + len);

View file

@ -14,7 +14,7 @@ public:
virtual void Done(); virtual void Done();
virtual void DeliverPacket(int len, const u_char* data, bool orig, virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new DHCP_Analyzer(conn); } { return new DHCP_Analyzer(conn); }

View file

@ -153,7 +153,7 @@ void DNP3_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
} }
} }
void DNP3_Analyzer::Undelivered(int seq, int len, bool orig) void DNP3_Analyzer::Undelivered(uint64 seq, int len, bool orig)
{ {
TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
interp->NewGap(orig, len); interp->NewGap(orig, len);

View file

@ -14,7 +14,7 @@ public:
virtual void Done(); virtual void Done();
virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void DeliverStream(int len, const u_char* data, bool orig);
virtual void Undelivered(int seq, int len, bool orig); virtual void Undelivered(uint64 seq, int len, bool orig);
virtual void EndpointEOF(bool is_orig); virtual void EndpointEOF(bool is_orig);
static Analyzer* InstantiateAnalyzer(Connection* conn) static Analyzer* InstantiateAnalyzer(Connection* conn)

View file

@ -1146,7 +1146,7 @@ void DNS_Analyzer::Done()
} }
void DNS_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, void DNS_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen) uint64 seq, const IP_Hdr* ip, int caplen)
{ {
tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen);

View file

@ -258,7 +258,7 @@ public:
~DNS_Analyzer(); ~DNS_Analyzer();
virtual void DeliverPacket(int len, const u_char* data, bool orig, virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
virtual void Init(); virtual void Init();
virtual void Done(); virtual void Done();

View file

@ -34,7 +34,7 @@ void File_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
return; return;
} }
void File_Analyzer::Undelivered(int seq, int len, bool orig) void File_Analyzer::Undelivered(uint64 seq, int len, bool orig)
{ {
TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
} }
@ -79,10 +79,10 @@ void IRC_Data::DeliverStream(int len, const u_char* data, bool orig)
file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), orig); file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), orig);
} }
void IRC_Data::Undelivered(int seq, int len, bool orig) void IRC_Data::Undelivered(uint64 seq, int len, bool orig)
{ {
File_Analyzer::Undelivered(seq, len, orig); File_Analyzer::Undelivered(seq, len, orig);
file_mgr->Gap(seq, len, GetAnalyzerTag(), Conn(), orig); file_mgr->Gap(seq - 1, len, GetAnalyzerTag(), Conn(), orig);
} }
FTP_Data::FTP_Data(Connection* conn) FTP_Data::FTP_Data(Connection* conn)
@ -102,8 +102,8 @@ void FTP_Data::DeliverStream(int len, const u_char* data, bool orig)
file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), orig); file_mgr->DataIn(data, len, GetAnalyzerTag(), Conn(), orig);
} }
void FTP_Data::Undelivered(int seq, int len, bool orig) void FTP_Data::Undelivered(uint64 seq, int len, bool orig)
{ {
File_Analyzer::Undelivered(seq, len, orig); File_Analyzer::Undelivered(seq, len, orig);
file_mgr->Gap(seq, len, GetAnalyzerTag(), Conn(), orig); file_mgr->Gap(seq - 1, len, GetAnalyzerTag(), Conn(), orig);
} }

View file

@ -17,7 +17,7 @@ public:
virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void DeliverStream(int len, const u_char* data, bool orig);
void Undelivered(int seq, int len, bool orig); void Undelivered(uint64 seq, int len, bool orig);
// static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) // static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)
// { return new File_Analyzer(conn); } // { return new File_Analyzer(conn); }
@ -38,7 +38,7 @@ public:
virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void DeliverStream(int len, const u_char* data, bool orig);
virtual void Undelivered(int seq, int len, bool orig); virtual void Undelivered(uint64 seq, int len, bool orig);
static Analyzer* InstantiateAnalyzer(Connection* conn) static Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new IRC_Data(conn); } { return new IRC_Data(conn); }
@ -52,7 +52,7 @@ public:
virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void DeliverStream(int len, const u_char* data, bool orig);
virtual void Undelivered(int seq, int len, bool orig); virtual void Undelivered(uint64 seq, int len, bool orig);
static Analyzer* InstantiateAnalyzer(Connection* conn) static Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new FTP_Data(conn); } { return new FTP_Data(conn); }

View file

@ -23,7 +23,7 @@ void GTPv1_Analyzer::Done()
Event(udp_session_done); Event(udp_session_done);
} }
void GTPv1_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) void GTPv1_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, uint64 seq, const IP_Hdr* ip, int caplen)
{ {
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
try try

View file

@ -12,7 +12,7 @@ public:
virtual void Done(); virtual void Done();
virtual void DeliverPacket(int len, const u_char* data, bool orig, virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new GTPv1_Analyzer(conn); } { return new GTPv1_Analyzer(conn); }

View file

@ -1115,11 +1115,11 @@ void HTTP_Analyzer::DeliverStream(int len, const u_char* data, bool is_orig)
} }
} }
void HTTP_Analyzer::Undelivered(int seq, int len, bool is_orig) void HTTP_Analyzer::Undelivered(uint64 seq, int len, bool is_orig)
{ {
tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig); tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig);
// DEBUG_MSG("Undelivered from %d: %d bytes\n", seq, length); // DEBUG_MSG("Undelivered from %"PRIu64": %d bytes\n", seq, length);
HTTP_Message* msg = HTTP_Message* msg =
is_orig ? request_message : reply_message; is_orig ? request_message : reply_message;
@ -1131,7 +1131,7 @@ void HTTP_Analyzer::Undelivered(int seq, int len, bool is_orig)
{ {
if ( msg ) if ( msg )
msg->SubmitEvent(mime::MIME_EVENT_CONTENT_GAP, msg->SubmitEvent(mime::MIME_EVENT_CONTENT_GAP,
fmt("seq=%d, len=%d", seq, len)); fmt("seq=%"PRIu64", len=%d", seq, len));
} }
// Check if the content gap falls completely within a message body // Check if the content gap falls completely within a message body

View file

@ -161,7 +161,7 @@ public:
HTTP_Analyzer(Connection* conn); HTTP_Analyzer(Connection* conn);
~HTTP_Analyzer(); ~HTTP_Analyzer();
void Undelivered(tcp::TCP_Endpoint* sender, int seq, int len); void Undelivered(tcp::TCP_Endpoint* sender, uint64 seq, int len);
void HTTP_Header(int is_orig, mime::MIME_Header* h); void HTTP_Header(int is_orig, mime::MIME_Header* h);
void HTTP_EntityData(int is_orig, const BroString* entity_data); void HTTP_EntityData(int is_orig, const BroString* entity_data);
@ -177,7 +177,7 @@ public:
// Overriden from Analyzer. // Overriden from Analyzer.
virtual void Done(); virtual void Done();
virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void DeliverStream(int len, const u_char* data, bool orig);
virtual void Undelivered(int seq, int len, bool orig); virtual void Undelivered(uint64 seq, int len, bool orig);
// Overriden from tcp::TCP_ApplicationAnalyzer // Overriden from tcp::TCP_ApplicationAnalyzer
virtual void EndpointEOF(bool is_orig); virtual void EndpointEOF(bool is_orig);

View file

@ -31,7 +31,7 @@ void ICMP_Analyzer::Done()
} }
void ICMP_Analyzer::DeliverPacket(int len, const u_char* data, void ICMP_Analyzer::DeliverPacket(int len, const u_char* data,
bool is_orig, int seq, const IP_Hdr* ip, int caplen) bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen)
{ {
assert(ip); assert(ip);

View file

@ -29,7 +29,7 @@ protected:
virtual void Done(); virtual void Done();
virtual void DeliverPacket(int len, const u_char* data, bool orig, virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
virtual bool IsReuse(double t, const u_char* pkt); virtual bool IsReuse(double t, const u_char* pkt);
virtual unsigned int MemoryAllocation() const; virtual unsigned int MemoryAllocation() const;

View file

@ -24,7 +24,7 @@ InterConnEndpoint::InterConnEndpoint(tcp::TCP_Endpoint* e)
#define NORMAL_LINE_LENGTH 80 #define NORMAL_LINE_LENGTH 80
int InterConnEndpoint::DataSent(double t, int seq, int len, int caplen, int InterConnEndpoint::DataSent(double t, uint64 seq, int len, int caplen,
const u_char* data, const IP_Hdr* /* ip */, const u_char* data, const IP_Hdr* /* ip */,
const struct tcphdr* /* tp */) const struct tcphdr* /* tp */)
{ {
@ -37,8 +37,8 @@ int InterConnEndpoint::DataSent(double t, int seq, int len, int caplen,
if ( endp->state == tcp::TCP_ENDPOINT_PARTIAL ) if ( endp->state == tcp::TCP_ENDPOINT_PARTIAL )
is_partial = 1; is_partial = 1;
int ack = endp->AckSeq() - endp->StartSeq(); uint64 ack = endp->ToRelativeSeqSpace(endp->AckSeq(), endp->AckWraps());
int top_seq = seq + len; uint64 top_seq = seq + len;
if ( top_seq <= ack || top_seq <= max_top_seq ) if ( top_seq <= ack || top_seq <= max_top_seq )
// There is no new data in this packet // There is no new data in this packet
@ -46,7 +46,7 @@ int InterConnEndpoint::DataSent(double t, int seq, int len, int caplen,
if ( seq < max_top_seq ) if ( seq < max_top_seq )
{ // Only consider new data { // Only consider new data
int amount_seen = max_top_seq - seq; int64 amount_seen = max_top_seq - seq;
seq += amount_seen; seq += amount_seen;
data += amount_seen; data += amount_seen;
len -= amount_seen; len -= amount_seen;
@ -184,7 +184,7 @@ void InterConn_Analyzer::Init()
} }
void InterConn_Analyzer::DeliverPacket(int len, const u_char* data, void InterConn_Analyzer::DeliverPacket(int len, const u_char* data,
bool is_orig, int seq, const IP_Hdr* ip, int caplen) bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen)
{ {
tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, is_orig, tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, is_orig,
seq, ip, caplen); seq, ip, caplen);

View file

@ -13,7 +13,7 @@ class InterConnEndpoint : public BroObj {
public: public:
InterConnEndpoint(tcp::TCP_Endpoint* e); InterConnEndpoint(tcp::TCP_Endpoint* e);
int DataSent(double t, int seq, int len, int caplen, const u_char* data, int DataSent(double t, uint64 seq, int len, int caplen, const u_char* data,
const IP_Hdr* ip, const struct tcphdr* tp); const IP_Hdr* ip, const struct tcphdr* tp);
RecordVal* BuildStats(); RecordVal* BuildStats();
@ -25,7 +25,7 @@ protected:
tcp::TCP_Endpoint* endp; tcp::TCP_Endpoint* endp;
double last_keystroke_time; double last_keystroke_time;
int max_top_seq; uint64 max_top_seq;
uint32 num_pkts; uint32 num_pkts;
uint32 num_keystrokes_two_in_a_row; uint32 num_keystrokes_two_in_a_row;
uint32 num_normal_interarrivals; uint32 num_normal_interarrivals;
@ -56,7 +56,7 @@ protected:
// We support both packet and stream input and can be put in place even // We support both packet and stream input and can be put in place even
// if the TCP analyzer is not yet reassembling. // if the TCP analyzer is not yet reassembling.
virtual void DeliverPacket(int len, const u_char* data, bool is_orig, virtual void DeliverPacket(int len, const u_char* data, bool is_orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
virtual void DeliverStream(int len, const u_char* data, bool is_orig); virtual void DeliverStream(int len, const u_char* data, bool is_orig);
void StatEvent(); void StatEvent();

View file

@ -31,7 +31,7 @@ void ModbusTCP_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
interp->NewData(orig, data, data + len); interp->NewData(orig, data, data + len);
} }
void ModbusTCP_Analyzer::Undelivered(int seq, int len, bool orig) void ModbusTCP_Analyzer::Undelivered(uint64 seq, int len, bool orig)
{ {
TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
interp->NewGap(orig, len); interp->NewGap(orig, len);

View file

@ -14,7 +14,7 @@ public:
virtual void Done(); virtual void Done();
virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void DeliverStream(int len, const u_char* data, bool orig);
virtual void Undelivered(int seq, int len, bool orig); virtual void Undelivered(uint64 seq, int len, bool orig);
virtual void EndpointEOF(bool is_orig); virtual void EndpointEOF(bool is_orig);
static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)

View file

@ -211,7 +211,7 @@ void Contents_NCP_Analyzer::DeliverStream(int len, const u_char* data, bool orig
} }
} }
void Contents_NCP_Analyzer::Undelivered(int seq, int len, bool orig) void Contents_NCP_Analyzer::Undelivered(uint64 seq, int len, bool orig)
{ {
tcp::TCP_SupportAnalyzer::Undelivered(seq, len, orig); tcp::TCP_SupportAnalyzer::Undelivered(seq, len, orig);

View file

@ -90,7 +90,7 @@ public:
protected: protected:
virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void DeliverStream(int len, const u_char* data, bool orig);
virtual void Undelivered(int seq, int len, bool orig); virtual void Undelivered(uint64 seq, int len, bool orig);
NCP_FrameBuffer buffer; NCP_FrameBuffer buffer;
NCP_Session* session; NCP_Session* session;

View file

@ -513,7 +513,7 @@ void NetbiosSSN_Analyzer::ConnectionClosed(tcp::TCP_Endpoint* endpoint,
} }
void NetbiosSSN_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, void NetbiosSSN_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen) uint64 seq, const IP_Hdr* ip, int caplen)
{ {
tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen);

View file

@ -146,7 +146,7 @@ public:
virtual void Done(); virtual void Done();
virtual void DeliverPacket(int len, const u_char* data, bool orig, virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new NetbiosSSN_Analyzer(conn); } { return new NetbiosSSN_Analyzer(conn); }

View file

@ -25,7 +25,7 @@ void NTP_Analyzer::Done()
Event(udp_session_done); Event(udp_session_done);
} }
void NTP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, int seq, const IP_Hdr* ip, int caplen) void NTP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq, const IP_Hdr* ip, int caplen)
{ {
Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen);

View file

@ -46,7 +46,7 @@ public:
protected: protected:
virtual void Done(); virtual void Done();
virtual void DeliverPacket(int len, const u_char* data, bool orig, virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
int Request(const u_char* data, int len); int Request(const u_char* data, int len);
int Reply(const u_char* data, int len); int Reply(const u_char* data, int len);

View file

@ -30,7 +30,7 @@ void PIA::ClearBuffer(Buffer* buffer)
buffer->size = 0; buffer->size = 0;
} }
void PIA::AddToBuffer(Buffer* buffer, int seq, int len, const u_char* data, void PIA::AddToBuffer(Buffer* buffer, uint64 seq, int len, const u_char* data,
bool is_orig) bool is_orig)
{ {
u_char* tmp = 0; u_char* tmp = 0;
@ -77,7 +77,7 @@ void PIA::PIA_Done()
FinishEndpointMatcher(); FinishEndpointMatcher();
} }
void PIA::PIA_DeliverPacket(int len, const u_char* data, bool is_orig, int seq, void PIA::PIA_DeliverPacket(int len, const u_char* data, bool is_orig, uint64 seq,
const IP_Hdr* ip, int caplen) const IP_Hdr* ip, int caplen)
{ {
if ( pkt_buffer.state == SKIPPING ) if ( pkt_buffer.state == SKIPPING )
@ -256,7 +256,7 @@ void PIA_TCP::DeliverStream(int len, const u_char* data, bool is_orig)
stream_buffer.state = new_state; stream_buffer.state = new_state;
} }
void PIA_TCP::Undelivered(int seq, int len, bool is_orig) void PIA_TCP::Undelivered(uint64 seq, int len, bool is_orig)
{ {
tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig); tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig);
@ -337,8 +337,8 @@ void PIA_TCP::ActivateAnalyzer(analyzer::Tag tag, const Rule* rule)
new tcp::TCP_Reassembler(this, tcp, tcp::TCP_Reassembler::Direct, new tcp::TCP_Reassembler(this, tcp, tcp::TCP_Reassembler::Direct,
tcp->Resp()); tcp->Resp());
int orig_seq = 0; uint64 orig_seq = 0;
int resp_seq = 0; uint64 resp_seq = 0;
for ( DataBlock* b = pkt_buffer.head; b; b = b->next ) for ( DataBlock* b = pkt_buffer.head; b; b = b->next )
{ {

View file

@ -42,7 +42,7 @@ public:
protected: protected:
void PIA_Done(); void PIA_Done();
void PIA_DeliverPacket(int len, const u_char* data, bool is_orig, void PIA_DeliverPacket(int len, const u_char* data, bool is_orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
enum State { INIT, BUFFERING, MATCHING_ONLY, SKIPPING } state; enum State { INIT, BUFFERING, MATCHING_ONLY, SKIPPING } state;
@ -52,7 +52,7 @@ protected:
const u_char* data; const u_char* data;
bool is_orig; bool is_orig;
int len; int len;
int seq; uint64 seq;
DataBlock* next; DataBlock* next;
}; };
@ -65,7 +65,7 @@ protected:
State state; State state;
}; };
void AddToBuffer(Buffer* buffer, int seq, int len, void AddToBuffer(Buffer* buffer, uint64 seq, int len,
const u_char* data, bool is_orig); const u_char* data, bool is_orig);
void AddToBuffer(Buffer* buffer, int len, void AddToBuffer(Buffer* buffer, int len,
const u_char* data, bool is_orig); const u_char* data, bool is_orig);
@ -105,7 +105,7 @@ protected:
} }
virtual void DeliverPacket(int len, const u_char* data, bool is_orig, virtual void DeliverPacket(int len, const u_char* data, bool is_orig,
int seq, const IP_Hdr* ip, int caplen) uint64 seq, const IP_Hdr* ip, int caplen)
{ {
Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen);
PIA_DeliverPacket(len, data, is_orig, seq, ip, caplen); PIA_DeliverPacket(len, data, is_orig, seq, ip, caplen);
@ -150,14 +150,14 @@ protected:
} }
virtual void DeliverPacket(int len, const u_char* data, bool is_orig, virtual void DeliverPacket(int len, const u_char* data, bool is_orig,
int seq, const IP_Hdr* ip, int caplen) uint64 seq, const IP_Hdr* ip, int caplen)
{ {
Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen); Analyzer::DeliverPacket(len, data, is_orig, seq, ip, caplen);
PIA_DeliverPacket(len, data, is_orig, seq, ip, caplen); PIA_DeliverPacket(len, data, is_orig, seq, ip, caplen);
} }
virtual void DeliverStream(int len, const u_char* data, bool is_orig); virtual void DeliverStream(int len, const u_char* data, bool is_orig);
virtual void Undelivered(int seq, int len, bool is_orig); virtual void Undelivered(uint64 seq, int len, bool is_orig);
virtual void ActivateAnalyzer(analyzer::Tag tag, virtual void ActivateAnalyzer(analyzer::Tag tag,
const Rule* rule = 0); const Rule* rule = 0);

View file

@ -399,7 +399,7 @@ Contents_RPC::~Contents_RPC()
{ {
} }
void Contents_RPC::Undelivered(int seq, int len, bool orig) void Contents_RPC::Undelivered(uint64 seq, int len, bool orig)
{ {
tcp::TCP_SupportAnalyzer::Undelivered(seq, len, orig); tcp::TCP_SupportAnalyzer::Undelivered(seq, len, orig);
NeedResync(); NeedResync();
@ -704,7 +704,7 @@ RPC_Analyzer::~RPC_Analyzer()
} }
void RPC_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, void RPC_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen) uint64 seq, const IP_Hdr* ip, int caplen)
{ {
tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen); tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
len = min(len, caplen); len = min(len, caplen);

View file

@ -203,7 +203,7 @@ protected:
virtual void Init(); virtual void Init();
virtual bool CheckResync(int& len, const u_char*& data, bool orig); virtual bool CheckResync(int& len, const u_char*& data, bool orig);
virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void DeliverStream(int len, const u_char* data, bool orig);
virtual void Undelivered(int seq, int len, bool orig); virtual void Undelivered(uint64 seq, int len, bool orig);
virtual void NeedResync() { virtual void NeedResync() {
resync_state = NEED_RESYNC; resync_state = NEED_RESYNC;
@ -234,7 +234,7 @@ public:
protected: protected:
virtual void DeliverPacket(int len, const u_char* data, bool orig, virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
void ExpireTimer(double t); void ExpireTimer(double t);

View file

@ -76,14 +76,14 @@ void SMTP_Analyzer::Done()
EndData(); EndData();
} }
void SMTP_Analyzer::Undelivered(int seq, int len, bool is_orig) void SMTP_Analyzer::Undelivered(uint64 seq, int len, bool is_orig)
{ {
tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig); tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, is_orig);
if ( len <= 0 ) if ( len <= 0 )
return; return;
const char* buf = fmt("seq = %d, len = %d", seq, len); const char* buf = fmt("seq = %"PRIu64", len = %d", seq, len);
int buf_len = strlen(buf); int buf_len = strlen(buf);
Unexpected(is_orig, "content gap", buf_len, buf); Unexpected(is_orig, "content gap", buf_len, buf);

View file

@ -44,7 +44,7 @@ public:
virtual void Done(); virtual void Done();
virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void DeliverStream(int len, const u_char* data, bool orig);
virtual void ConnectionFinished(int half_finished); virtual void ConnectionFinished(int half_finished);
virtual void Undelivered(int seq, int len, bool orig); virtual void Undelivered(uint64 seq, int len, bool orig);
void SkipData() { skip_data = 1; } // skip delivery of data lines void SkipData() { skip_data = 1; } // skip delivery of data lines

View file

@ -86,7 +86,7 @@ void SOCKS_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
} }
} }
void SOCKS_Analyzer::Undelivered(int seq, int len, bool orig) void SOCKS_Analyzer::Undelivered(uint64 seq, int len, bool orig)
{ {
tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
interp->NewGap(orig, len); interp->NewGap(orig, len);

View file

@ -23,7 +23,7 @@ public:
virtual void Done(); virtual void Done();
virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void DeliverStream(int len, const u_char* data, bool orig);
virtual void Undelivered(int seq, int len, bool orig); virtual void Undelivered(uint64 seq, int len, bool orig);
virtual void EndpointEOF(bool is_orig); virtual void EndpointEOF(bool is_orig);
static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)

View file

@ -57,7 +57,7 @@ void SSL_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
} }
} }
void SSL_Analyzer::Undelivered(int seq, int len, bool orig) void SSL_Analyzer::Undelivered(uint64 seq, int len, bool orig)
{ {
tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
had_gap = true; had_gap = true;

View file

@ -16,7 +16,7 @@ public:
// Overriden from Analyzer. // Overriden from Analyzer.
virtual void Done(); virtual void Done();
virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void DeliverStream(int len, const u_char* data, bool orig);
virtual void Undelivered(int seq, int len, bool orig); virtual void Undelivered(uint64 seq, int len, bool orig);
// Overriden from tcp::TCP_ApplicationAnalyzer. // Overriden from tcp::TCP_ApplicationAnalyzer.
virtual void EndpointEOF(bool is_orig); virtual void EndpointEOF(bool is_orig);

View file

@ -63,7 +63,7 @@ void SteppingStoneEndpoint::Done()
Event(stp_remove_endp, stp_id); Event(stp_remove_endp, stp_id);
} }
int SteppingStoneEndpoint::DataSent(double t, int seq, int len, int caplen, int SteppingStoneEndpoint::DataSent(double t, uint64 seq, int len, int caplen,
const u_char* data, const IP_Hdr* /* ip */, const u_char* data, const IP_Hdr* /* ip */,
const struct tcphdr* tp) const struct tcphdr* tp)
{ {
@ -90,8 +90,8 @@ int SteppingStoneEndpoint::DataSent(double t, int seq, int len, int caplen,
break; break;
} }
int ack = endp->AckSeq() - endp->StartSeq(); uint64 ack = endp->ToRelativeSeqSpace(endp->AckSeq(), endp->AckWraps());
int top_seq = seq + len; uint64 top_seq = seq + len;
if ( top_seq <= ack || top_seq <= stp_max_top_seq ) if ( top_seq <= ack || top_seq <= stp_max_top_seq )
// There is no new data in this packet // There is no new data in this packet
@ -179,7 +179,7 @@ void SteppingStone_Analyzer::Init()
} }
void SteppingStone_Analyzer::DeliverPacket(int len, const u_char* data, void SteppingStone_Analyzer::DeliverPacket(int len, const u_char* data,
bool is_orig, int seq, bool is_orig, uint64 seq,
const IP_Hdr* ip, int caplen) const IP_Hdr* ip, int caplen)
{ {
tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, is_orig, seq, tcp::TCP_ApplicationAnalyzer::DeliverPacket(len, data, is_orig, seq,

View file

@ -22,7 +22,7 @@ public:
~SteppingStoneEndpoint(); ~SteppingStoneEndpoint();
void Done(); void Done();
int DataSent(double t, int seq, int len, int caplen, const u_char* data, int DataSent(double t, uint64 seq, int len, int caplen, const u_char* data,
const IP_Hdr* ip, const struct tcphdr* tp); const IP_Hdr* ip, const struct tcphdr* tp);
protected: protected:
@ -30,7 +30,7 @@ protected:
void CreateEndpEvent(int is_orig); void CreateEndpEvent(int is_orig);
tcp::TCP_Endpoint* endp; tcp::TCP_Endpoint* endp;
int stp_max_top_seq; uint64 stp_max_top_seq;
double stp_last_time; double stp_last_time;
double stp_resume_time; double stp_resume_time;
SteppingStoneManager* stp_manager; SteppingStoneManager* stp_manager;
@ -60,7 +60,7 @@ protected:
// We support both packet and stream input and can be put in place even // We support both packet and stream input and can be put in place even
// if the TCP analyzer is not yet reassebmling. // if the TCP analyzer is not yet reassebmling.
virtual void DeliverPacket(int len, const u_char* data, bool is_orig, virtual void DeliverPacket(int len, const u_char* data, bool is_orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
virtual void DeliverStream(int len, const u_char* data, bool is_orig); virtual void DeliverStream(int len, const u_char* data, bool is_orig);
int orig_stream_pos; int orig_stream_pos;

View file

@ -28,7 +28,7 @@ void Syslog_Analyzer::Done()
Event(udp_session_done); Event(udp_session_done);
} }
void Syslog_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen) void Syslog_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, uint64 seq, const IP_Hdr* ip, int caplen)
{ {
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);
interp->NewData(orig, data, data + len); interp->NewData(orig, data, data + len);
@ -88,7 +88,7 @@ void Syslog_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, int
// interp->NewData(orig, data, data + len); // interp->NewData(orig, data, data + len);
// } // }
//void Syslog_tcp::TCP_Analyzer::Undelivered(int seq, int len, bool orig) //void Syslog_tcp::TCP_Analyzer::Undelivered(uint64 seq, int len, bool orig)
// { // {
// tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig); // tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
// interp->NewGap(orig, len); // interp->NewGap(orig, len);

View file

@ -16,7 +16,7 @@ public:
virtual void Done(); virtual void Done();
virtual void DeliverPacket(int len, const u_char* data, bool orig, virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new Syslog_Analyzer(conn); } { return new Syslog_Analyzer(conn); }
@ -38,7 +38,7 @@ protected:
// //
// virtual void Done(); // virtual void Done();
// virtual void DeliverStream(int len, const u_char* data, bool orig); // virtual void DeliverStream(int len, const u_char* data, bool orig);
// virtual void Undelivered(int seq, int len, bool orig); // virtual void Undelivered(uint64 seq, int len, bool orig);
// virtual void EndpointEOF(tcp::TCP_Reassembler* endp); // virtual void EndpointEOF(tcp::TCP_Reassembler* endp);
// //
// static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) // static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)

View file

@ -109,7 +109,7 @@ void ContentLine_Analyzer::DeliverStream(int len, const u_char* data,
seq += len; seq += len;
} }
void ContentLine_Analyzer::Undelivered(int seq, int len, bool orig) void ContentLine_Analyzer::Undelivered(uint64 seq, int len, bool orig)
{ {
ForwardUndelivered(seq, len, orig); ForwardUndelivered(seq, len, orig);
} }

View file

@ -53,14 +53,14 @@ public:
void SkipBytesAfterThisLine(int64_t length); void SkipBytesAfterThisLine(int64_t length);
void SkipBytes(int64_t length); void SkipBytes(int64_t length);
bool IsSkippedContents(int64_t seq, int64_t length) bool IsSkippedContents(uint64_t seq, int64_t length)
{ return seq + length <= seq_to_skip; } { return seq + length <= seq_to_skip; }
protected: protected:
ContentLine_Analyzer(const char* name, Connection* conn, bool orig); ContentLine_Analyzer(const char* name, Connection* conn, bool orig);
virtual void DeliverStream(int len, const u_char* data, bool is_orig); virtual void DeliverStream(int len, const u_char* data, bool is_orig);
virtual void Undelivered(int seq, int len, bool orig); virtual void Undelivered(uint64 seq, int len, bool orig);
virtual void EndpointEOF(bool is_orig); virtual void EndpointEOF(bool is_orig);
class State; class State;
@ -71,19 +71,19 @@ protected:
void CheckNUL(); void CheckNUL();
// Returns the sequence number delivered so far. // Returns the sequence number delivered so far.
int64_t SeqDelivered() const { return seq_delivered_in_lines; } uint64_t SeqDelivered() const { return seq_delivered_in_lines; }
u_char* buf; // where we build up the body of the request u_char* buf; // where we build up the body of the request
int offset; // where we are in buf int offset; // where we are in buf
int buf_len; // how big buf is, total int buf_len; // how big buf is, total
unsigned int last_char; // last (non-option) character scanned unsigned int last_char; // last (non-option) character scanned
int64_t seq; // last seq number uint64_t seq; // last seq number
int64_t seq_to_skip; uint64_t seq_to_skip;
// Seq delivered up to through NewLine() -- it is adjusted // Seq delivered up to through NewLine() -- it is adjusted
// *before* NewLine() is called. // *before* NewLine() is called.
int64_t seq_delivered_in_lines; uint64_t seq_delivered_in_lines;
// Number of bytes to be skipped after this line. See // Number of bytes to be skipped after this line. See
// comments in SkipBytesAfterThisLine(). // comments in SkipBytesAfterThisLine().

File diff suppressed because it is too large Load diff

View file

@ -102,9 +102,9 @@ protected:
// Analyzer interface. // Analyzer interface.
virtual void Init(); virtual void Init();
virtual void Done(); virtual void Done();
virtual void DeliverPacket(int len, const u_char* data, bool orig, int seq, const IP_Hdr* ip, int caplen); virtual void DeliverPacket(int len, const u_char* data, bool orig, uint64 seq, const IP_Hdr* ip, int caplen);
virtual void DeliverStream(int len, const u_char* data, bool orig); virtual void DeliverStream(int len, const u_char* data, bool orig);
virtual void Undelivered(int seq, int len, bool orig); virtual void Undelivered(uint64 seq, int len, bool orig);
virtual void FlipRoles(); virtual void FlipRoles();
virtual bool IsReuse(double t, const u_char* pkt); virtual bool IsReuse(double t, const u_char* pkt);
@ -119,42 +119,7 @@ protected:
bool ValidateChecksum(const struct tcphdr* tp, TCP_Endpoint* endpoint, bool ValidateChecksum(const struct tcphdr* tp, TCP_Endpoint* endpoint,
int len, int caplen); int len, int caplen);
// Update analysis based on flag combinations. The endpoint, base_seq void SetPartialStatus(TCP_Flags flags, bool is_orig);
// and len are needed for tracking various history information.
// dst_port is needed for trimming of FIN packets.
void CheckFlagCombos(TCP_Flags flags, TCP_Endpoint* endpoint,
uint32 base_seq, int len, int dst_port);
void UpdateWindow(TCP_Endpoint* endpoint, unsigned int window,
uint32 base_seq, uint32 ack_seq,
TCP_Flags flags);
void ProcessSYN(const IP_Hdr* ip, const struct tcphdr* tp,
uint32 tcp_hdr_len, int& seq_len,
TCP_Endpoint* endpoint, TCP_Endpoint* peer,
uint32 base_seq, uint32 ack_seq,
const IPAddr& orig_addr,
int is_orig, TCP_Flags flags);
void ProcessFIN(double t, TCP_Endpoint* endpoint, int& seq_len,
uint32 base_seq);
void ProcessRST(double t, TCP_Endpoint* endpoint, const IP_Hdr* ip,
uint32 base_seq, int len, int& seq_len);
void ProcessACK(TCP_Endpoint* endpoint, TCP_Endpoint* peer,
uint32 ack_seq, int is_orig, TCP_Flags flags);
void ProcessFlags(double t, const IP_Hdr* ip, const struct tcphdr* tp,
uint32 tcp_hdr_len, int len, int& seq_len,
TCP_Endpoint* endpoint, TCP_Endpoint* peer,
uint32 base_seq, uint32 ack_seq,
const IPAddr& orig_addr,
int is_orig, TCP_Flags flags);
void TransitionFromInactive(double t, TCP_Endpoint* endpoint,
uint32 base_seq, uint32 last_seq,
int SYN);
// Update the state machine of the TCPs based on the activity. This // Update the state machine of the TCPs based on the activity. This
// includes our pseudo-states such as TCP_ENDPOINT_PARTIAL. // includes our pseudo-states such as TCP_ENDPOINT_PARTIAL.
@ -164,8 +129,8 @@ protected:
// this fact. // this fact.
void UpdateStateMachine(double t, void UpdateStateMachine(double t,
TCP_Endpoint* endpoint, TCP_Endpoint* peer, TCP_Endpoint* endpoint, TCP_Endpoint* peer,
uint32 base_seq, uint32 ack_seq, uint32 last_seq, uint32 base_seq, uint32 ack_seq,
int len, int delta_last, int is_orig, TCP_Flags flags, int len, int32 delta_last, int is_orig, TCP_Flags flags,
int& do_close, int& gen_event); int& do_close, int& gen_event);
void UpdateInactiveState(double t, void UpdateInactiveState(double t,
@ -174,43 +139,34 @@ protected:
int len, int is_orig, TCP_Flags flags, int len, int is_orig, TCP_Flags flags,
int& do_close, int& gen_event); int& do_close, int& gen_event);
void UpdateSYN_SentState(double t, void UpdateSYN_SentState(
TCP_Endpoint* endpoint, TCP_Endpoint* peer, TCP_Endpoint* endpoint, TCP_Endpoint* peer,
uint32 base_seq, uint32 last_seq,
int len, int is_orig, TCP_Flags flags, int len, int is_orig, TCP_Flags flags,
int& do_close, int& gen_event); int& do_close, int& gen_event);
void UpdateEstablishedState(double t, void UpdateEstablishedState(
TCP_Endpoint* endpoint, TCP_Endpoint* peer, TCP_Endpoint* endpoint, TCP_Endpoint* peer,
uint32 base_seq, uint32 last_seq, TCP_Flags flags, int& do_close, int& gen_event);
int is_orig, TCP_Flags flags,
int& do_close, int& gen_event);
void UpdateClosedState(double t, TCP_Endpoint* endpoint, void UpdateClosedState(double t, TCP_Endpoint* endpoint,
int delta_last, TCP_Flags flags, int32 delta_last, TCP_Flags flags,
int& do_close); int& do_close);
void UpdateResetState(int len, TCP_Flags flags, TCP_Endpoint* endpoint, void UpdateResetState(int len, TCP_Flags flags);
uint32 base_seq, uint32 last_seq);
void GeneratePacketEvent(TCP_Endpoint* endpoint, TCP_Endpoint* peer, void GeneratePacketEvent(
uint32 base_seq, uint32 ack_seq, uint64 rel_seq, uint64 rel_ack,
const u_char* data, int len, int caplen, const u_char* data, int len, int caplen,
int is_orig, TCP_Flags flags); int is_orig, TCP_Flags flags);
int DeliverData(double t, const u_char* data, int len, int caplen, int DeliverData(double t, const u_char* data, int len, int caplen,
const IP_Hdr* ip, const struct tcphdr* tp, const IP_Hdr* ip, const struct tcphdr* tp,
TCP_Endpoint* endpoint, uint32 base_seq, TCP_Endpoint* endpoint, uint64 rel_data_seq,
int is_orig, TCP_Flags flags); int is_orig, TCP_Flags flags);
void CheckRecording(int need_contents, TCP_Flags flags); void CheckRecording(int need_contents, TCP_Flags flags);
void CheckPIA_FirstPacket(int is_orig, const IP_Hdr* ip); void CheckPIA_FirstPacket(int is_orig, const IP_Hdr* ip);
// Returns the difference between last_seq and the last sequence
// seen by the endpoint (may be negative).
int UpdateLastSeq(TCP_Endpoint* endpoint, uint32 last_seq,
TCP_Flags flags);
friend class ConnectionTimer; friend class ConnectionTimer;
void AttemptTimer(double t); void AttemptTimer(double t);
void PartialCloseTimer(double t); void PartialCloseTimer(double t);
@ -228,12 +184,6 @@ protected:
void SetReassembler(tcp::TCP_Reassembler* rorig, tcp::TCP_Reassembler* rresp); void SetReassembler(tcp::TCP_Reassembler* rorig, tcp::TCP_Reassembler* rresp);
Val* BuildSYNPacketVal(int is_orig,
const IP_Hdr* ip, const struct tcphdr* tcp);
RecordVal* BuildOSVal(int is_orig, const IP_Hdr* ip,
const struct tcphdr* tcp, uint32 tcp_hdr_len);
// Needs to be static because it's passed as a pointer-to-function // Needs to be static because it's passed as a pointer-to-function
// rather than pointer-to-member-function. // rather than pointer-to-member-function.
static int TCPOptionEvent(unsigned int opt, unsigned int optlen, static int TCPOptionEvent(unsigned int opt, unsigned int optlen,
@ -304,7 +254,7 @@ public:
virtual void PacketWithRST(); virtual void PacketWithRST();
virtual void DeliverPacket(int len, const u_char* data, bool orig, virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
virtual void Init(); virtual void Init();
// This suppresses violations if the TCP connection wasn't // This suppresses violations if the TCP connection wasn't
@ -341,7 +291,7 @@ class TCPStats_Endpoint {
public: public:
TCPStats_Endpoint(TCP_Endpoint* endp); TCPStats_Endpoint(TCP_Endpoint* endp);
int DataSent(double t, int seq, int len, int caplen, const u_char* data, int DataSent(double t, uint64 seq, int len, int caplen, const u_char* data,
const IP_Hdr* ip, const struct tcphdr* tp); const IP_Hdr* ip, const struct tcphdr* tp);
RecordVal* BuildStats(); RecordVal* BuildStats();
@ -354,7 +304,7 @@ protected:
int num_in_order; int num_in_order;
int num_OO; int num_OO;
int num_repl; int num_repl;
int max_top_seq; uint64 max_top_seq;
int last_id; int last_id;
int endian_type; int endian_type;
}; };
@ -372,7 +322,7 @@ public:
protected: protected:
virtual void DeliverPacket(int len, const u_char* data, bool is_orig, virtual void DeliverPacket(int len, const u_char* data, bool is_orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
TCPStats_Endpoint* orig_stats; TCPStats_Endpoint* orig_stats;
TCPStats_Endpoint* resp_stats; TCPStats_Endpoint* resp_stats;

View file

@ -20,7 +20,7 @@ TCP_Endpoint::TCP_Endpoint(TCP_Analyzer* arg_analyzer, int arg_is_orig)
peer = 0; peer = 0;
start_time = last_time = 0.0; start_time = last_time = 0.0;
start_seq = last_seq = ack_seq = 0; start_seq = last_seq = ack_seq = 0;
last_seq_high = ack_seq_high = 0; seq_wraps = ack_wraps = 0;
window = 0; window = 0;
window_scale = 0; window_scale = 0;
window_seq = window_ack_seq = 0; window_seq = window_ack_seq = 0;
@ -108,7 +108,8 @@ void TCP_Endpoint::CheckEOF()
contents_processor->CheckEOF(); contents_processor->CheckEOF();
} }
void TCP_Endpoint::SizeBufferedData(int& waiting_on_hole, int& waiting_on_ack) void TCP_Endpoint::SizeBufferedData(uint64& waiting_on_hole,
uint64& waiting_on_ack)
{ {
if ( contents_processor ) if ( contents_processor )
contents_processor->SizeBufferedData(waiting_on_hole, waiting_on_ack); contents_processor->SizeBufferedData(waiting_on_hole, waiting_on_ack);
@ -159,7 +160,7 @@ void TCP_Endpoint::SetState(EndpointState new_state)
} }
} }
bro_int_t TCP_Endpoint::Size() const uint64 TCP_Endpoint::Size() const
{ {
if ( prev_state == TCP_ENDPOINT_SYN_SENT && state == TCP_ENDPOINT_RESET && if ( prev_state == TCP_ENDPOINT_SYN_SENT && state == TCP_ENDPOINT_RESET &&
peer->state == TCP_ENDPOINT_INACTIVE && ! NoDataAcked() ) peer->state == TCP_ENDPOINT_INACTIVE && ! NoDataAcked() )
@ -168,14 +169,18 @@ bro_int_t TCP_Endpoint::Size() const
// and there was never a chance for this endpoint to send data anyway. // and there was never a chance for this endpoint to send data anyway.
return 0; return 0;
bro_int_t size; uint64 size;
uint64 last_seq_64 = ToFullSeqSpace(LastSeq(), SeqWraps());
uint64 ack_seq_64 = ToFullSeqSpace(AckSeq(), AckWraps());
uint64 last_seq_64 = (uint64(last_seq_high) << 32) | last_seq; // Going straight to relative sequence numbers and comparing those might
uint64 ack_seq_64 = (uint64(ack_seq_high) << 32) | ack_seq; // make more sense, but there's some cases (e.g. due to RSTs) where
// last_seq might not be initialized to a trustworthy value such that
// rel_seq > rel_ack, but last_seq_64 < start_seq, which is obviously wrong.
if ( last_seq_64 > ack_seq_64 ) if ( last_seq_64 > ack_seq_64 )
size = last_seq_64 - start_seq; size = last_seq_64 - StartSeqI64();
else else
size = ack_seq_64 - start_seq; size = ack_seq_64 - StartSeqI64();
// Don't include SYN octet in sequence space. For partial connections // Don't include SYN octet in sequence space. For partial connections
// (no SYN seen), we're still careful to adjust start_seq as though // (no SYN seen), we're still careful to adjust start_seq as though
@ -190,7 +195,7 @@ bro_int_t TCP_Endpoint::Size() const
return size; return size;
} }
int TCP_Endpoint::DataSent(double t, int seq, int len, int caplen, int TCP_Endpoint::DataSent(double t, uint64 seq, int len, int caplen,
const u_char* data, const u_char* data,
const IP_Hdr* ip, const struct tcphdr* tp) const IP_Hdr* ip, const struct tcphdr* tp)
{ {
@ -205,7 +210,7 @@ int TCP_Endpoint::DataSent(double t, int seq, int len, int caplen,
if ( contents_file && ! contents_processor && if ( contents_file && ! contents_processor &&
seq + len > contents_start_seq ) seq + len > contents_start_seq )
{ {
int under_seq = contents_start_seq - seq; int64 under_seq = contents_start_seq - seq;
if ( under_seq > 0 ) if ( under_seq > 0 )
{ {
seq += under_seq; seq += under_seq;
@ -236,7 +241,7 @@ int TCP_Endpoint::DataSent(double t, int seq, int len, int caplen,
return status; return status;
} }
void TCP_Endpoint::AckReceived(int seq) void TCP_Endpoint::AckReceived(uint64 seq)
{ {
if ( contents_processor ) if ( contents_processor )
contents_processor->AckReceived(seq); contents_processor->AckReceived(seq);
@ -246,7 +251,7 @@ void TCP_Endpoint::SetContentsFile(BroFile* f)
{ {
Ref(f); Ref(f);
contents_file = f; contents_file = f;
contents_start_seq = last_seq - start_seq; contents_start_seq = ToRelativeSeqSpace(last_seq, seq_wraps);
if ( contents_start_seq == 0 ) if ( contents_start_seq == 0 )
contents_start_seq = 1; // skip SYN contents_start_seq = 1; // skip SYN

View file

@ -38,32 +38,92 @@ public:
EndpointState State() const { return state; } EndpointState State() const { return state; }
void SetState(EndpointState new_state); void SetState(EndpointState new_state);
bro_int_t Size() const; uint64 Size() const;
int IsActive() const int IsActive() const
{ return state != TCP_ENDPOINT_INACTIVE && ! did_close; } { return state != TCP_ENDPOINT_INACTIVE && ! did_close; }
double StartTime() const { return start_time; } double StartTime() const { return start_time; }
double LastTime() const { return last_time; } double LastTime() const { return last_time; }
uint32 StartSeq() const { return start_seq; } /**
* @return The starting TCP sequence number for this endpoint.
*/
uint32 StartSeq() const { return static_cast<uint32>(start_seq); }
/**
* @return The starting TCP sequence number for this endpoint, in terms
* of a signed sequence space, which may account for initial
* sequence space wraparounds (underflow/overflow).
*/
int64 StartSeqI64() const { return start_seq; }
/**
* @return The sequence number after the last TCP sequence number seen
* from this endpoint.
*/
uint32 LastSeq() const { return last_seq; } uint32 LastSeq() const { return last_seq; }
/**
* @return The last TCP acknowledgement number seen from this endpoint.
*/
uint32 AckSeq() const { return ack_seq; } uint32 AckSeq() const { return ack_seq; }
void InitStartSeq(uint32 seq) { start_seq = seq; } /**
* @return The number of times the TCP sequence has wrapped around
* for this endpoint (i.e. overflowed a uint32).
*/
uint32 SeqWraps() const { return seq_wraps; }
/**
* @return The number of times the TCP acknowledgement sequence has
* wrapped around for this endpoint (i.e. overflowed a uint32).
*/
uint32 AckWraps() const { return ack_wraps; }
/**
* @param wraps Number of times a 32-bit sequence space has wrapped.
* @return A 64-bit sequence space number it would take to overflow
* a 32-bit sequence space \a wraps number of times.
*/
static uint64 ToFullSeqSpace(uint32 wraps)
{ return (uint64(wraps) << 32); }
/**
* @param tcp_seq_num A 32-bit TCP sequence space number.
* @param wraparounds Number of times a 32-bit sequence space has wrapped.
* @return \a tcp_seq_num expanded out in to a 64-bit sequence space,
* accounting for the number of times the 32-bit space overflowed.
*/
static uint64 ToFullSeqSpace(uint32 tcp_seq_num, uint32 wraparounds)
{ return ToFullSeqSpace(wraparounds) + tcp_seq_num; }
/**
* @param tcp_seq_num A 32-bit TCP sequence space number.
* @param wraparounds Number of times a 32-bit sequence space has wrapped.
* @return \a tcp_seq_num expanded out in to a 64-bit sequence space,
* accounting for the number of times the 32-bit space overflowed
* and relative the the starting sequence number for this endpoint.
*/
uint64 ToRelativeSeqSpace(uint32 tcp_seq_num, uint32 wraparounds) const
{
return ToFullSeqSpace(tcp_seq_num, wraparounds) - StartSeqI64();
}
void InitStartSeq(int64 seq) { start_seq = seq; }
void InitLastSeq(uint32 seq) { last_seq = seq; } void InitLastSeq(uint32 seq) { last_seq = seq; }
void InitAckSeq(uint32 seq) { ack_seq = seq; } void InitAckSeq(uint32 seq) { ack_seq = seq; }
void UpdateLastSeq(uint32 seq) void UpdateLastSeq(uint32 seq)
{ {
if ( seq < last_seq ) if ( seq < last_seq )
++last_seq_high; ++seq_wraps;
last_seq = seq; last_seq = seq;
} }
void UpdateAckSeq(uint32 seq) void UpdateAckSeq(uint32 seq)
{ {
if ( seq < ack_seq ) if ( seq < ack_seq )
++ack_seq_high; ++ack_wraps;
ack_seq = seq; ack_seq = seq;
} }
@ -71,7 +131,10 @@ public:
// We allow for possibly one octet being ack'd in the case of // We allow for possibly one octet being ack'd in the case of
// an initial SYN exchange. // an initial SYN exchange.
int NoDataAcked() const int NoDataAcked() const
{ return ack_seq == start_seq || ack_seq == start_seq + 1; } {
uint64 ack = ToFullSeqSpace(ack_seq, ack_wraps);
return ack == StartSeqI64() || ack == StartSeqI64() + 1;
}
Connection* Conn() const; Connection* Conn() const;
@ -96,16 +159,16 @@ public:
// //
// If we're not processing contents, then naturally each of // If we're not processing contents, then naturally each of
// these is empty. // these is empty.
void SizeBufferedData(int& waiting_on_hole, int& waiting_on_ack); void SizeBufferedData(uint64& waiting_on_hole, uint64& waiting_on_ack);
int ValidChecksum(const struct tcphdr* tp, int len) const; int ValidChecksum(const struct tcphdr* tp, int len) const;
// Returns true if the data was used (and hence should be recorded // Returns true if the data was used (and hence should be recorded
// in the save file), false otherwise. // in the save file), false otherwise.
int DataSent(double t, int seq, int len, int caplen, const u_char* data, int DataSent(double t, uint64 seq, int len, int caplen, const u_char* data,
const IP_Hdr* ip, const struct tcphdr* tp); const IP_Hdr* ip, const struct tcphdr* tp);
void AckReceived(int seq); void AckReceived(uint64 seq);
void SetContentsFile(BroFile* f); void SetContentsFile(BroFile* f);
BroFile* GetContentsFile() const { return contents_file; } BroFile* GetContentsFile() const { return contents_file; }
@ -139,20 +202,25 @@ public:
int window_scale; // from the TCP option int window_scale; // from the TCP option
uint32 window_ack_seq; // at which ack_seq number did we record 'window' uint32 window_ack_seq; // at which ack_seq number did we record 'window'
uint32 window_seq; // at which sending sequence number did we record 'window' uint32 window_seq; // at which sending sequence number did we record 'window'
int contents_start_seq; // relative seq # where contents file starts uint64 contents_start_seq; // relative seq # where contents file starts
int FIN_seq; // relative seq # to start_seq uint64 FIN_seq; // relative seq # to start_seq
int SYN_cnt, FIN_cnt, RST_cnt; int SYN_cnt, FIN_cnt, RST_cnt;
int did_close; // whether we've reported it closing int did_close; // whether we've reported it closing
int is_orig; int is_orig;
// Sequence numbers associated with last control packets. // Relative sequence numbers associated with last control packets.
// Used to determine whether ones seen again are interesting, // Used to determine whether ones seen again are interesting,
// for tracking history. // for tracking history.
uint32 hist_last_SYN, hist_last_FIN, hist_last_RST; uint64 hist_last_SYN, hist_last_FIN, hist_last_RST;
protected: protected:
uint32 start_seq, last_seq, ack_seq; // in host order int64 start_seq; // Initial TCP sequence number in host order.
uint32 last_seq_high, ack_seq_high; // Signed 64-bit to detect initial sequence wrapping.
// Use StartSeq() accessor if need it in terms of
// an absolute TCP sequence number.
uint32 last_seq, ack_seq; // in host order
uint32 seq_wraps, ack_wraps; // Number of times 32-bit TCP sequence space
// has wrapped around (overflowed).
}; };
#define ENDIAN_UNKNOWN 0 #define ENDIAN_UNKNOWN 0

View file

@ -14,11 +14,6 @@ using namespace analyzer::tcp;
// Note, sequence numbers are relative. I.e., they start with 1. // Note, sequence numbers are relative. I.e., they start with 1.
// TODO: The Reassembler should start using 64 bit ints for keeping track of
// sequence numbers; currently they become negative once 2GB are exceeded.
//
// See #348 for more information.
const bool DEBUG_tcp_contents = false; const bool DEBUG_tcp_contents = false;
const bool DEBUG_tcp_connection_close = false; const bool DEBUG_tcp_connection_close = false;
const bool DEBUG_tcp_match_undelivered = false; const bool DEBUG_tcp_match_undelivered = false;
@ -44,9 +39,7 @@ TCP_Reassembler::TCP_Reassembler(analyzer::Analyzer* arg_dst_analyzer,
deliver_tcp_contents = 0; deliver_tcp_contents = 0;
skip_deliveries = 0; skip_deliveries = 0;
did_EOF = 0; did_EOF = 0;
#ifdef ENABLE_SEQ_TO_SKIP
seq_to_skip = 0; seq_to_skip = 0;
#endif
in_delivery = false; in_delivery = false;
if ( tcp_contents ) if ( tcp_contents )
@ -73,12 +66,11 @@ TCP_Reassembler::~TCP_Reassembler()
void TCP_Reassembler::Done() void TCP_Reassembler::Done()
{ {
MatchUndelivered(-1); MatchUndelivered(-1, true);
if ( record_contents_file ) if ( record_contents_file )
{ // Record any undelivered data. { // Record any undelivered data.
if ( blocks && if ( blocks && last_reassem_seq < last_block->upper )
seq_delta(last_reassem_seq, last_block->upper) < 0 )
RecordToSeq(last_reassem_seq, last_block->upper, RecordToSeq(last_reassem_seq, last_block->upper,
record_contents_file); record_contents_file);
@ -86,13 +78,13 @@ void TCP_Reassembler::Done()
} }
} }
void TCP_Reassembler::SizeBufferedData(int& waiting_on_hole, void TCP_Reassembler::SizeBufferedData(uint64& waiting_on_hole,
int& waiting_on_ack) const uint64& waiting_on_ack) const
{ {
waiting_on_hole = waiting_on_ack = 0; waiting_on_hole = waiting_on_ack = 0;
for ( DataBlock* b = blocks; b; b = b->next ) for ( DataBlock* b = blocks; b; b = b->next )
{ {
if ( seq_delta(b->seq, last_reassem_seq) <= 0 ) if ( b->seq <= last_reassem_seq )
// We must have delivered this block, but // We must have delivered this block, but
// haven't yet trimmed it. // haven't yet trimmed it.
waiting_on_ack += b->Size(); waiting_on_ack += b->Size();
@ -126,7 +118,7 @@ void TCP_Reassembler::SetContentsFile(BroFile* f)
} }
void TCP_Reassembler::Undelivered(int up_to_seq) void TCP_Reassembler::Undelivered(uint64 up_to_seq)
{ {
TCP_Endpoint* endpoint = endp; TCP_Endpoint* endpoint = endp;
TCP_Endpoint* peer = endpoint->peer; TCP_Endpoint* peer = endpoint->peer;
@ -142,13 +134,7 @@ void TCP_Reassembler::Undelivered(int up_to_seq)
// was a keep-alive. So, in either case, just ignore it. // was a keep-alive. So, in either case, just ignore it.
// TODO: Don't we need to update last_reassm_seq ???? // TODO: Don't we need to update last_reassm_seq ????
if ( up_to_seq >=0 ) return;
// Since seq are currently only 32 bit signed
// integers, they will become negative if a
// connection has more than 2GB of data. Remove the
// above if and always return here, once we're using
// 64 bit ints
return;
} }
#if 0 #if 0
@ -156,15 +142,14 @@ void TCP_Reassembler::Undelivered(int up_to_seq)
{ {
// Make sure we're not worrying about undelivered // Make sure we're not worrying about undelivered
// FIN control octets! // FIN control octets!
int FIN_seq = endpoint->FIN_seq - endpoint->start_seq; if ( up_to_seq >= endpoint->FIN_seq )
if ( seq_delta(up_to_seq, FIN_seq) >= 0 ) up_to_seq = endpoint->FIN_seq - 1;
up_to_seq = FIN_seq - 1;
} }
#endif #endif
if ( DEBUG_tcp_contents ) if ( DEBUG_tcp_contents )
{ {
DEBUG_MSG("%.6f Undelivered: IsOrig()=%d up_to_seq=%d, last_reassm=%d, " DEBUG_MSG("%.6f Undelivered: IsOrig()=%d up_to_seq=%"PRIu64", last_reassm=%"PRIu64", "
"endp: FIN_cnt=%d, RST_cnt=%d, " "endp: FIN_cnt=%d, RST_cnt=%d, "
"peer: FIN_cnt=%d, RST_cnt=%d\n", "peer: FIN_cnt=%d, RST_cnt=%d\n",
network_time, IsOrig(), up_to_seq, last_reassem_seq, network_time, IsOrig(), up_to_seq, last_reassem_seq,
@ -172,7 +157,7 @@ void TCP_Reassembler::Undelivered(int up_to_seq)
peer->FIN_cnt, peer->RST_cnt); peer->FIN_cnt, peer->RST_cnt);
} }
if ( seq_delta(up_to_seq, last_reassem_seq) <= 0 ) if ( up_to_seq <= last_reassem_seq )
// This should never happen. (Reassembler::TrimToSeq has the only call // This should never happen. (Reassembler::TrimToSeq has the only call
// to this method and only if this condition is not true). // to this method and only if this condition is not true).
reporter->InternalError("Calling Undelivered for data that has already been delivered (or has already been marked as undelivered"); reporter->InternalError("Calling Undelivered for data that has already been delivered (or has already been marked as undelivered");
@ -195,10 +180,10 @@ void TCP_Reassembler::Undelivered(int up_to_seq)
{ {
if ( DEBUG_tcp_contents ) if ( DEBUG_tcp_contents )
{ {
DEBUG_MSG("%.6f Undelivered: IsOrig()=%d, seq=%d, len=%d, " DEBUG_MSG("%.6f Undelivered: IsOrig()=%d, seq=%"PRIu64", len=%"PRIu64", "
"skip_deliveries=%d\n", "skip_deliveries=%d\n",
network_time, IsOrig(), last_reassem_seq, network_time, IsOrig(), last_reassem_seq,
seq_delta(up_to_seq, last_reassem_seq), up_to_seq - last_reassem_seq,
skip_deliveries); skip_deliveries);
} }
@ -210,8 +195,8 @@ void TCP_Reassembler::Undelivered(int up_to_seq)
// packet, but it's undelievered because it's out of // packet, but it's undelievered because it's out of
// sequence. // sequence.
int seq = last_reassem_seq; uint64 seq = last_reassem_seq;
int len = seq_delta(up_to_seq, last_reassem_seq); uint64 len = up_to_seq - last_reassem_seq;
// Only report on content gaps for connections that // Only report on content gaps for connections that
// are in a cleanly established state. In other // are in a cleanly established state. In other
@ -255,19 +240,19 @@ void TCP_Reassembler::Undelivered(int up_to_seq)
RecordToSeq(last_reassem_seq, up_to_seq, record_contents_file); RecordToSeq(last_reassem_seq, up_to_seq, record_contents_file);
if ( tcp_match_undelivered ) if ( tcp_match_undelivered )
MatchUndelivered(up_to_seq); MatchUndelivered(up_to_seq, false);
// But we need to re-adjust last_reassem_seq in either case. // But we need to re-adjust last_reassem_seq in either case.
last_reassem_seq = up_to_seq; // we've done our best ... last_reassem_seq = up_to_seq; // we've done our best ...
} }
void TCP_Reassembler::MatchUndelivered(int up_to_seq) void TCP_Reassembler::MatchUndelivered(uint64 up_to_seq, bool use_last_upper)
{ {
if ( ! blocks || ! rule_matcher ) if ( ! blocks || ! rule_matcher )
return; return;
ASSERT(last_block); ASSERT(last_block);
if ( up_to_seq == -1 ) if ( use_last_upper )
up_to_seq = last_block->upper; up_to_seq = last_block->upper;
// ### Note: the original code did not check whether blocks have // ### Note: the original code did not check whether blocks have
@ -277,36 +262,35 @@ void TCP_Reassembler::MatchUndelivered(int up_to_seq)
// We are to match any undelivered data, from last_reassem_seq to // We are to match any undelivered data, from last_reassem_seq to
// min(last_block->upper, up_to_seq). // min(last_block->upper, up_to_seq).
// Is there such data? // Is there such data?
if ( seq_delta(up_to_seq, last_reassem_seq) <= 0 || if ( up_to_seq <= last_reassem_seq ||
seq_delta(last_block->upper, last_reassem_seq) <= 0 ) last_block->upper <= last_reassem_seq )
return; return;
// Skip blocks that are already delivered (but not ACK'ed). // Skip blocks that are already delivered (but not ACK'ed).
// Question: shall we instead keep a pointer to the first undelivered // Question: shall we instead keep a pointer to the first undelivered
// block? // block?
DataBlock* b; DataBlock* b;
for ( b = blocks; b && seq_delta(b->upper, last_reassem_seq) <= 0; for ( b = blocks; b && b->upper <= last_reassem_seq; b = b->next )
b = b->next )
tcp_analyzer->Conn()->Match(Rule::PAYLOAD, b->block, b->Size(), tcp_analyzer->Conn()->Match(Rule::PAYLOAD, b->block, b->Size(),
false, false, IsOrig(), false); false, false, IsOrig(), false);
ASSERT(b); ASSERT(b);
} }
void TCP_Reassembler::RecordToSeq(int start_seq, int stop_seq, BroFile* f) void TCP_Reassembler::RecordToSeq(uint64 start_seq, uint64 stop_seq, BroFile* f)
{ {
DataBlock* b = blocks; DataBlock* b = blocks;
// Skip over blocks up to the start seq. // Skip over blocks up to the start seq.
while ( b && seq_delta(b->upper, start_seq) <= 0 ) while ( b && b->upper <= start_seq )
b = b->next; b = b->next;
if ( ! b ) if ( ! b )
return; return;
int last_seq = start_seq; uint64 last_seq = start_seq;
while ( b && seq_delta(b->upper, stop_seq) <= 0 ) while ( b && b->upper <= stop_seq )
{ {
if ( seq_delta(b->seq, last_seq) > 0 ) if ( b->seq > last_seq )
RecordGap(last_seq, b->seq, f); RecordGap(last_seq, b->seq, f);
RecordBlock(b, f); RecordBlock(b, f);
@ -316,7 +300,7 @@ void TCP_Reassembler::RecordToSeq(int start_seq, int stop_seq, BroFile* f)
if ( b ) if ( b )
// Check for final gap. // Check for final gap.
if ( seq_delta(last_seq, stop_seq) < 0 ) if ( last_seq < stop_seq )
RecordGap(last_seq, stop_seq, f); RecordGap(last_seq, stop_seq, f);
} }
@ -337,9 +321,9 @@ void TCP_Reassembler::RecordBlock(DataBlock* b, BroFile* f)
} }
} }
void TCP_Reassembler::RecordGap(int start_seq, int upper_seq, BroFile* f) void TCP_Reassembler::RecordGap(uint64 start_seq, uint64 upper_seq, BroFile* f)
{ {
if ( f->Write(fmt("\n<<gap %d>>\n", seq_delta(upper_seq, start_seq))) ) if ( f->Write(fmt("\n<<gap %"PRIu64">>\n", upper_seq - start_seq)) )
return; return;
reporter->Error("TCP_Reassembler contents gap write failed"); reporter->Error("TCP_Reassembler contents gap write failed");
@ -356,8 +340,8 @@ void TCP_Reassembler::RecordGap(int start_seq, int upper_seq, BroFile* f)
void TCP_Reassembler::BlockInserted(DataBlock* start_block) void TCP_Reassembler::BlockInserted(DataBlock* start_block)
{ {
if ( seq_delta(start_block->seq, last_reassem_seq) > 0 || if ( start_block->seq > last_reassem_seq ||
seq_delta(start_block->upper, last_reassem_seq) <= 0 ) start_block->upper <= last_reassem_seq )
return; return;
// We've filled a leading hole. Deliver as much as possible. // We've filled a leading hole. Deliver as much as possible.
@ -367,12 +351,12 @@ void TCP_Reassembler::BlockInserted(DataBlock* start_block)
// loop we have to take care not to deliver already-delivered // loop we have to take care not to deliver already-delivered
// data. // data.
for ( DataBlock* b = start_block; for ( DataBlock* b = start_block;
b && seq_delta(b->seq, last_reassem_seq) <= 0; b = b->next ) b && b->seq <= last_reassem_seq; b = b->next )
{ {
if ( b->seq == last_reassem_seq ) if ( b->seq == last_reassem_seq )
{ // New stuff. { // New stuff.
int len = b->Size(); uint64 len = b->Size();
int seq = last_reassem_seq; uint64 seq = last_reassem_seq;
last_reassem_seq += len; last_reassem_seq += len;
@ -406,10 +390,10 @@ void TCP_Reassembler::BlockInserted(DataBlock* start_block)
// TCP_Connection::NextPacket. // TCP_Connection::NextPacket.
} }
void TCP_Reassembler::Overlap(const u_char* b1, const u_char* b2, int n) void TCP_Reassembler::Overlap(const u_char* b1, const u_char* b2, uint64 n)
{ {
if ( DEBUG_tcp_contents ) if ( DEBUG_tcp_contents )
DEBUG_MSG("%.6f TCP contents overlap: %d IsOrig()=%d\n", network_time, n, IsOrig()); DEBUG_MSG("%.6f TCP contents overlap: %"PRIu64" IsOrig()=%d\n", network_time, n, IsOrig());
if ( rexmit_inconsistency && if ( rexmit_inconsistency &&
memcmp((const void*) b1, (const void*) b2, n) && memcmp((const void*) b1, (const void*) b2, n) &&
@ -438,7 +422,7 @@ bool TCP_Reassembler::DoUnserialize(UnserialInfo* info)
return false; // Cannot be reached. return false; // Cannot be reached.
} }
void TCP_Reassembler::Deliver(int seq, int len, const u_char* data) void TCP_Reassembler::Deliver(uint64 seq, int len, const u_char* data)
{ {
if ( type == Direct ) if ( type == Direct )
dst_analyzer->NextStream(len, data, IsOrig()); dst_analyzer->NextStream(len, data, IsOrig());
@ -446,24 +430,24 @@ void TCP_Reassembler::Deliver(int seq, int len, const u_char* data)
dst_analyzer->ForwardStream(len, data, IsOrig()); dst_analyzer->ForwardStream(len, data, IsOrig());
} }
int TCP_Reassembler::DataSent(double t, int seq, int len, int TCP_Reassembler::DataSent(double t, uint64 seq, int len,
const u_char* data, bool replaying) const u_char* data, bool replaying)
{ {
int ack = seq_delta(endp->AckSeq(), endp->StartSeq()); uint64 ack = endp->ToRelativeSeqSpace(endp->AckSeq(), endp->AckWraps());
int upper_seq = seq + len; uint64 upper_seq = seq + len;
if ( DEBUG_tcp_contents ) if ( DEBUG_tcp_contents )
{ {
DEBUG_MSG("%.6f DataSent: IsOrig()=%d seq=%d upper=%d ack=%d\n", DEBUG_MSG("%.6f DataSent: IsOrig()=%d seq=%"PRIu64" upper=%"PRIu64" ack=%"PRIu64"\n",
network_time, IsOrig(), seq, upper_seq, ack); network_time, IsOrig(), seq, upper_seq, ack);
} }
if ( skip_deliveries ) if ( skip_deliveries )
return 0; return 0;
if ( seq_delta(seq, ack) < 0 && ! replaying ) if ( seq < ack && ! replaying )
{ {
if ( seq_delta(upper_seq, ack) <= 0 ) if ( upper_seq <= ack )
// We've already delivered this and it's been acked. // We've already delivered this and it's been acked.
return 0; return 0;
@ -472,7 +456,7 @@ int TCP_Reassembler::DataSent(double t, int seq, int len,
// packet held [a, a+b) and this packet holds [a, a+c) for c>b // packet held [a, a+b) and this packet holds [a, a+c) for c>b
// (which some TCP's will do when retransmitting). Trim the // (which some TCP's will do when retransmitting). Trim the
// packet to just the unacked data. // packet to just the unacked data.
int amount_acked = seq_delta(ack, seq); uint64 amount_acked = ack - seq;
seq += amount_acked; seq += amount_acked;
data += amount_acked; data += amount_acked;
len -= amount_acked; len -= amount_acked;
@ -500,16 +484,13 @@ int TCP_Reassembler::DataSent(double t, int seq, int len,
} }
void TCP_Reassembler::AckReceived(int seq) void TCP_Reassembler::AckReceived(uint64 seq)
{ {
if ( endp->FIN_cnt > 0 && seq_delta(seq, endp->FIN_seq) >= 0 ) if ( endp->FIN_cnt > 0 && seq >= endp->FIN_seq )
// TrimToSeq: FIN_seq - 1
seq = endp->FIN_seq - 1; seq = endp->FIN_seq - 1;
int bytes_covered = seq_delta(seq, trim_seq); if ( seq <= trim_seq )
// Nothing to do.
if ( bytes_covered <= 0 )
// Zero, or negative in sequence-space terms. Nothing to do.
return; return;
bool test_active = ! skip_deliveries && ! tcp_analyzer->Skipping() && bool test_active = ! skip_deliveries && ! tcp_analyzer->Skipping() &&
@ -517,12 +498,12 @@ void TCP_Reassembler::AckReceived(int seq)
(endp->state == TCP_ENDPOINT_ESTABLISHED && (endp->state == TCP_ENDPOINT_ESTABLISHED &&
endp->peer->state == TCP_ENDPOINT_ESTABLISHED ) ); endp->peer->state == TCP_ENDPOINT_ESTABLISHED ) );
int num_missing = TrimToSeq(seq); uint64 num_missing = TrimToSeq(seq);
if ( test_active ) if ( test_active )
{ {
++tot_ack_events; ++tot_ack_events;
tot_ack_bytes += bytes_covered; tot_ack_bytes += seq - trim_seq;
if ( num_missing > 0 ) if ( num_missing > 0 )
{ {
@ -602,20 +583,18 @@ void TCP_Reassembler::CheckEOF()
// Deliver, DeliverBlock is not virtual, and this allows us to insert // Deliver, DeliverBlock is not virtual, and this allows us to insert
// operations that apply to all connections using TCP_Contents. // operations that apply to all connections using TCP_Contents.
void TCP_Reassembler::DeliverBlock(int seq, int len, const u_char* data) void TCP_Reassembler::DeliverBlock(uint64 seq, int len, const u_char* data)
{ {
#ifdef ENABLE_SEQ_TO_SKIP if ( seq + len <= seq_to_skip )
if ( seq_delta(seq + len, seq_to_skip) <= 0 )
return; return;
if ( seq_delta(seq, seq_to_skip) < 0 ) if ( seq < seq_to_skip )
{ {
int to_skip = seq_delta(seq_to_skip, seq); uint64 to_skip = seq_to_skip - seq;
len -= to_skip; len -= to_skip;
data += to_skip; data += to_skip;
seq = seq_to_skip; seq = seq_to_skip;
} }
#endif
if ( deliver_tcp_contents ) if ( deliver_tcp_contents )
{ {
@ -640,23 +619,21 @@ void TCP_Reassembler::DeliverBlock(int seq, int len, const u_char* data)
in_delivery = true; in_delivery = true;
Deliver(seq, len, data); Deliver(seq, len, data);
in_delivery = false; in_delivery = false;
#ifdef ENABLE_SEQ_TO_SKIP
if ( seq_delta(seq + len, seq_to_skip) < 0 ) if ( seq + len < seq_to_skip )
SkipToSeq(seq_to_skip); SkipToSeq(seq_to_skip);
#endif
} }
#ifdef ENABLE_SEQ_TO_SKIP void TCP_Reassembler::SkipToSeq(uint64 seq)
void TCP_Reassembler::SkipToSeq(int seq)
{ {
if ( seq_delta(seq, seq_to_skip) > 0 ) if ( seq > seq_to_skip )
{ {
seq_to_skip = seq; seq_to_skip = seq;
if ( ! in_delivery ) if ( ! in_delivery )
TrimToSeq(seq); TrimToSeq(seq);
} }
} }
#endif
int TCP_Reassembler::DataPending() const int TCP_Reassembler::DataPending() const
{ {
@ -665,20 +642,28 @@ int TCP_Reassembler::DataPending() const
if ( skip_deliveries ) if ( skip_deliveries )
return 0; return 0;
uint32 delivered_seq = Endpoint()->StartSeq() + DataSeq(); uint64 delivered_seq = Endpoint()->StartSeqI64() + DataSeq();
uint64 last_seq = TCP_Endpoint::ToFullSeqSpace(Endpoint()->LastSeq(),
Endpoint()->SeqWraps());
if ( last_seq < delivered_seq )
return 0;
// Q. Can we say that? // Q. Can we say that?
// ASSERT(delivered_seq <= Endpoint()->LastSeq()); // ASSERT(delivered_seq <= last_seq);
// //
// A. Yes, but only if we express it with 64-bit comparison // A. That should be true if endpoints are always initialized w/
// to handle sequence wrapping around. (Or perhaps seq_delta // trustworthy sequence numbers, though it seems that may not currently
// is enough here?) // be the case. e.g. a RST packet may end up initializing the endpoint.
// In that case, maybe there's not any "right" way to initialize it, so
// the check for last_seq < delivered_seq sort of serves as a check for
// endpoints that weren't initialized w/ meaningful sequence numbers.
// We've delivered everything if we're up to the penultimate // We've delivered everything if we're up to the penultimate
// sequence number (since a FIN consumes an octet in the // sequence number (since a FIN consumes an octet in the
// sequence space), or right at it (because a RST does not). // sequence space), or right at it (because a RST does not).
if ( delivered_seq != Endpoint()->LastSeq() - 1 && if ( delivered_seq != last_seq - 1 &&
delivered_seq != Endpoint()->LastSeq() ) delivered_seq != last_seq )
return 1; return 1;
// If we've sent RST, then we can't send ACKs any more. // If we've sent RST, then we can't send ACKs any more.

View file

@ -4,13 +4,6 @@
#include "Reassem.h" #include "Reassem.h"
#include "TCP_Endpoint.h" #include "TCP_Endpoint.h"
// The skip_to_seq feature does not work correctly with connections >2GB due
// to use of 32 bit signed ints (see comments in TCP_Reassembler.cc) Since
// it's not used by any analyzer or policy script we disable it. Could be
// added back in once we start using 64bit integers.
//
// #define ENABLE_SEQ_TO_SKIP
class BroFile; class BroFile;
class Connection; class Connection;
@ -48,12 +41,12 @@ public:
// //
// If we're not processing contents, then naturally each of // If we're not processing contents, then naturally each of
// these is empty. // these is empty.
void SizeBufferedData(int& waiting_on_hole, int& waiting_on_ack) const; void SizeBufferedData(uint64& waiting_on_hole, uint64& waiting_on_ack) const;
// How much data is pending delivery since it's not yet reassembled. // How much data is pending delivery since it's not yet reassembled.
// Includes the data due to holes (so this value is a bit different // Includes the data due to holes (so this value is a bit different
// from waiting_on_hole above; and is computed in a different fashion). // from waiting_on_hole above; and is computed in a different fashion).
int NumUndeliveredBytes() const uint64 NumUndeliveredBytes() const
{ {
if ( last_block ) if ( last_block )
return last_block->upper - last_reassem_seq; return last_block->upper - last_reassem_seq;
@ -64,19 +57,15 @@ public:
void SetContentsFile(BroFile* f); void SetContentsFile(BroFile* f);
BroFile* GetContentsFile() const { return record_contents_file; } BroFile* GetContentsFile() const { return record_contents_file; }
void MatchUndelivered(int up_to_seq = -1); void MatchUndelivered(uint64 up_to_seq, bool use_last_upper);
#ifdef ENABLE_SEQ_TO_SKIP
// Skip up to seq, as if there's a content gap. // Skip up to seq, as if there's a content gap.
// Can be used to skip HTTP data for performance considerations. // Can be used to skip HTTP data for performance considerations.
void SkipToSeq(int seq); void SkipToSeq(uint64 seq);
} } // namespace analyzer::*
#endif int DataSent(double t, uint64 seq, int len, const u_char* data,
int DataSent(double t, int seq, int len, const u_char* data,
bool replaying=true); bool replaying=true);
void AckReceived(int seq); void AckReceived(uint64 seq);
// Checks if we have delivered all contents that we can possibly // Checks if we have delivered all contents that we can possibly
// deliver for this endpoint. Calls TCP_Analyzer::EndpointEOF() // deliver for this endpoint. Calls TCP_Analyzer::EndpointEOF()
@ -86,35 +75,32 @@ public:
int HasUndeliveredData() const { return HasBlocks(); } int HasUndeliveredData() const { return HasBlocks(); }
int HadGap() const { return had_gap; } int HadGap() const { return had_gap; }
int DataPending() const; int DataPending() const;
int DataSeq() const { return LastReassemSeq(); } uint64 DataSeq() const { return LastReassemSeq(); }
void DeliverBlock(int seq, int len, const u_char* data); void DeliverBlock(uint64 seq, int len, const u_char* data);
virtual void Deliver(int seq, int len, const u_char* data); virtual void Deliver(uint64 seq, int len, const u_char* data);
TCP_Endpoint* Endpoint() { return endp; } TCP_Endpoint* Endpoint() { return endp; }
const TCP_Endpoint* Endpoint() const { return endp; } const TCP_Endpoint* Endpoint() const { return endp; }
int IsOrig() const { return endp->IsOrig(); } int IsOrig() const { return endp->IsOrig(); }
#ifdef ENABLE_SEQ_TO_SKIP
bool IsSkippedContents(int seq, int length) const
{ return seq + length <= seq_to_skip; }
} } // namespace analyzer::*
#endif bool IsSkippedContents(uint64 seq, int length) const
{ return seq + length <= seq_to_skip; }
private: private:
TCP_Reassembler() { } TCP_Reassembler() { }
DECLARE_SERIAL(TCP_Reassembler); DECLARE_SERIAL(TCP_Reassembler);
void Undelivered(int up_to_seq); void Undelivered(uint64 up_to_seq);
void RecordToSeq(int start_seq, int stop_seq, BroFile* f); void RecordToSeq(uint64 start_seq, uint64 stop_seq, BroFile* f);
void RecordBlock(DataBlock* b, BroFile* f); void RecordBlock(DataBlock* b, BroFile* f);
void RecordGap(int start_seq, int upper_seq, BroFile* f); void RecordGap(uint64 start_seq, uint64 upper_seq, BroFile* f);
void BlockInserted(DataBlock* b); void BlockInserted(DataBlock* b);
void Overlap(const u_char* b1, const u_char* b2, int n); void Overlap(const u_char* b1, const u_char* b2, uint64 n);
TCP_Endpoint* endp; TCP_Endpoint* endp;
@ -123,9 +109,8 @@ private:
unsigned int did_EOF:1; unsigned int did_EOF:1;
unsigned int skip_deliveries:1; unsigned int skip_deliveries:1;
#ifdef ENABLE_SEQ_TO_SKIP uint64 seq_to_skip;
int seq_to_skip;
#endif
bool in_delivery; bool in_delivery;
BroFile* record_contents_file; // file on which to reassemble contents BroFile* record_contents_file; // file on which to reassemble contents

View file

@ -223,9 +223,10 @@ event connection_EOF%(c: connection, is_orig: bool%);
## corresponds to one set flag, as follows: ``S`` -> SYN; ``F`` -> FIN; ## corresponds to one set flag, as follows: ``S`` -> SYN; ``F`` -> FIN;
## ``R`` -> RST; ``A`` -> ACK; ``P`` -> PUSH. ## ``R`` -> RST; ``A`` -> ACK; ``P`` -> PUSH.
## ##
## seq: The packet's TCP sequence number. ## seq: The packet's relative TCP sequence number.
## ##
## ack: The packet's ACK number. ## ack: If the ACK flag is set for the packet, the packet's relative ACK
## number, else zero.
## ##
## len: The length of the TCP payload, as specified in the packet header. ## len: The length of the TCP payload, as specified in the packet header.
## ##

View file

@ -140,7 +140,7 @@ RecordVal* TeredoEncapsulation::BuildVal(const IP_Hdr* inner) const
} }
void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, void Teredo_Analyzer::DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen) uint64 seq, const IP_Hdr* ip, int caplen)
{ {
Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen); Analyzer::DeliverPacket(len, data, orig, seq, ip, caplen);

View file

@ -19,7 +19,7 @@ public:
virtual void Done(); virtual void Done();
virtual void DeliverPacket(int len, const u_char* data, bool orig, virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn) static analyzer::Analyzer* InstantiateAnalyzer(Connection* conn)
{ return new Teredo_Analyzer(conn); } { return new Teredo_Analyzer(conn); }

View file

@ -38,7 +38,7 @@ void UDP_Analyzer::Done()
} }
void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig,
int seq, const IP_Hdr* ip, int caplen) uint64 seq, const IP_Hdr* ip, int caplen)
{ {
assert(ip); assert(ip);

View file

@ -28,7 +28,7 @@ public:
protected: protected:
virtual void Done(); virtual void Done();
virtual void DeliverPacket(int len, const u_char* data, bool orig, virtual void DeliverPacket(int len, const u_char* data, bool orig,
int seq, const IP_Hdr* ip, int caplen); uint64 seq, const IP_Hdr* ip, int caplen);
virtual bool IsReuse(double t, const u_char* pkt); virtual bool IsReuse(double t, const u_char* pkt);
virtual unsigned int MemoryAllocation() const; virtual unsigned int MemoryAllocation() const;

View file

@ -119,7 +119,7 @@ struct ip6_rthdr {
// True if sequence # a is between b and c (b <= a <= c). It must be true // True if sequence # a is between b and c (b <= a <= c). It must be true
// that b <= c in the sequence space. // that b <= c in the sequence space.
inline int seq_between(uint32 a, uint32 b, uint32 c) inline bool seq_between(uint32 a, uint32 b, uint32 c)
{ {
if ( b <= c ) if ( b <= c )
return a >= b && a <= c; return a >= b && a <= c;
@ -128,9 +128,9 @@ inline int seq_between(uint32 a, uint32 b, uint32 c)
} }
// Returns a - b, adjusted for sequence wraparound. // Returns a - b, adjusted for sequence wraparound.
inline int seq_delta(uint32 a, uint32 b) inline int32 seq_delta(uint32 a, uint32 b)
{ {
return int(a-b); return a - b;
} }
class IPAddr; class IPAddr;

View file

@ -0,0 +1,12 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path conn
#open 2014-04-09-16-44-53
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents
#types time string addr port addr port enum string interval count count string bool count string count count count count set[string]
1395939406.175845 CjhGID4nQcgTWjvg4c 192.168.56.1 59763 192.168.56.101 63988 tcp ftp-data 0.001676 0 270 SF - 0 ShAdfFa 5 272 4 486 (empty)
1395939411.361078 CCvvfg3TEfuqmmG4bh 192.168.56.1 59764 192.168.56.101 37150 tcp ftp-data 150.496065 0 5416666670 SF - 4675708816 ShAdfFa 13 688 12 24454 (empty)
1395939399.984671 CXWv6p3arKYeMETxOg 192.168.56.1 59762 192.168.56.101 21 tcp ftp 169.634297 104 1041 SF - 0 ShAdDaFf 31 1728 18 1985 (empty)
#close 2014-04-09-16-44-54

View file

@ -0,0 +1,11 @@
#separator \x09
#set_separator ,
#empty_field (empty)
#unset_field -
#path files
#open 2014-04-09-16-44-53
#fields ts fuid tx_hosts rx_hosts conn_uids source depth analyzers mime_type filename duration local_orig is_orig seen_bytes total_bytes missing_bytes overflow_bytes timedout parent_fuid md5 sha1 sha256 extracted
#types time string set[addr] set[addr] set[string] string count set[string] string string interval bool bool count count count count bool string string string string string
1395939406.177079 FAb5m22Dhe2Zi95anf 192.168.56.101 192.168.56.1 CjhGID4nQcgTWjvg4c FTP_DATA 0 DATA_EVENT text/plain - 0.000000 - F 270 - 0 0 F - - - - -
1395939411.364462 FhI0ao2FNTjabdfSBd 192.168.56.101 192.168.56.1 CCvvfg3TEfuqmmG4bh FTP_DATA 0 DATA_EVENT text/plain - 150.490904 - F 23822 - 5416642848 0 F - - - - -
#close 2014-04-09-16-44-54

File diff suppressed because one or more lines are too long

View file

@ -3,9 +3,11 @@
#empty_field (empty) #empty_field (empty)
#unset_field - #unset_field -
#path weird #path weird
#open 2013-08-26-19-36-36 #open 2014-04-07-19-37-09
#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer #fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer
#types time string addr port addr port string string bool string #types time string addr port addr port string string bool string
1153491909.414066 - - - - - truncated_IP - F bro 1153491909.414066 - - - - - truncated_IP - F bro
1153491912.529443 CXWv6p3arKYeMETxOg 192.168.66.235 2582 166.161.16.230 502 binpac exception: out_of_bound: WriteSingleRegisterRequest: 4 > 0 - F bro 1153491912.529443 CXWv6p3arKYeMETxOg 192.168.66.235 2582 166.161.16.230 502 binpac exception: out_of_bound: WriteSingleRegisterRequest: 4 > 0 - F bro
#close 2013-08-26-19-36-36 1153491920.661039 CXWv6p3arKYeMETxOg 192.168.66.235 2582 166.161.16.230 502 TCP_ack_underflow_or_misorder - F bro
1153491929.715910 CXWv6p3arKYeMETxOg 192.168.66.235 2582 166.161.16.230 502 TCP_seq_underflow_or_misorder - F bro
#close 2014-04-07-19-37-09

Binary file not shown.

View file

@ -0,0 +1,22 @@
# @TEST-EXEC: bro -r $TRACES/ftp/bigtransfer.pcap %INPUT >out
# @TEST-EXEC: btest-diff out
# @TEST-EXEC: btest-diff files.log
# @TEST-EXEC: btest-diff conn.log
# The pcap has been truncated on purpose, so there's going to be large
# gaps that are there by design and shouldn't trigger the "skip
# deliveries" code paths because this test still needs to know about the
# payloads being delivered around critical boundaries (e.g. 32-bit TCP
# sequence wraparound and 32-bit data offsets).
redef tcp_excessive_data_without_further_acks=0;
event file_chunk(f: fa_file, data: string, off: count)
{
print "file_chunk", |data|, off, data;
}
event file_new(f: fa_file)
{
Files::add_analyzer(f, Files::ANALYZER_DATA_EVENT,
[$chunk_event=file_chunk]);
}