Merge remote-tracking branch 'origin/topic/jsiwek/bit-348'

* origin/topic/jsiwek/bit-348:
  Update SNMP analyzer's DeliverPacket method signature.
  Fix reassembly of data w/ sizes beyond 32-bit capacities (BIT-348).

Conflicts:
	src/analyzer/protocol/file/File.cc
	src/analyzer/protocol/file/File.h
This commit is contained in:
Robin Sommer 2014-04-24 18:04:44 -07:00
commit 116ed370a2
77 changed files with 1628 additions and 1542 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

@ -1173,7 +1173,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

@ -40,7 +40,7 @@ void File_Analyzer::DeliverStream(int len, const u_char* data, bool orig)
orig, file_id_resp); orig, file_id_resp);
} }
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);

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); }

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

@ -1129,11 +1129,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;
@ -1145,7 +1145,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

@ -162,7 +162,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);
@ -178,7 +178,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

@ -25,7 +25,7 @@ void SNMP_Analyzer::Done()
} }
void SNMP_Analyzer::DeliverPacket(int len, const u_char* data, bool orig, void SNMP_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

@ -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 SNMP_Analyzer(conn); } { return new SNMP_Analyzer(conn); }

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,31 @@ 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, TCP_Flags flags, int& do_close, int& gen_event);
uint32 base_seq, uint32 last_seq,
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(uint64 rel_seq, uint64 rel_ack,
uint32 base_seq, uint32 ack_seq,
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 +181,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 +251,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 +288,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 +301,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 +319,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,94 @@ 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 to 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 +133,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 +161,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 +204,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,12 +134,6 @@ 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 )
// 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; return;
} }
@ -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]);
}