Dealing with directional out-of-order packet?

The directional out-of-order maybe caused by some network tapping
devices and/or some mirroring polices of the switches. In wireshark, it
will often appear as pairs of packets of different directions labeled as
“TCP ACKed unseen segment” and “TCP Spurious Retransmission”.

It will make many Binpac analyzers unable to work normally because
in most cases the current state of one direction depends on the packets
of the opposite direction.

In theory if we know the number of the bytes we have missed from
the other direction, we could make a good guess if we should use
another state to decode current packet.

So my question is: is this other-side gap information available in

Thanks in advance and best regards,


Is it already available in the form you'd prefer? Possibly not. You
can maybe look at whether TCP_Analyzer::IsPartial() and
TCP_Analyzer::HadGap() could be used to detect the situation.

Can the exact information you want be made available? If this is in
the context of your own custom analyzer, you can store any arbitrary
state in the analyzer that you want and access it from BinPAC code.

Ideally, this sounds like something to fix in the capture setup, not
to try to generally workaround in BinPAC/Zeek.

- Jon

Thank you for your advice.

I agree with you that it is a capture setup problem so I gave up.

Just for the record, if anybody want to try to fix this kind of out-of-order,
avoid to access the derived analyzer class in .pac file, just use the base
class TCP_ApplicationAnalyzer, like below:

#include “analyzer/protocol/tcp/TCP.h”

refine connection HBASE_Conn += {
// gap recording structure

function set_gap(seq: uint64 ,len: int, orig: bool): void
if (orig)

function proc_hbase_preamble(msg: HBASE_Preamble): bool
auto t = ((analyzer::tcp::TCP_ApplicationAnalyzer *)

If you try to type cast bro_analyzer() back to the original
analyzer::HBase:HBASE_Analyzer *, then you may encounter
troublesome header file circular reference/forward declaration

Then just call your set_gap() in HBASE_Analyzer::Undelivered()
method like this:

void HBASE_Analyzer::Undelivered(uint64 seq, int len, bool orig)
tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
had_gap = true;
interp->NewGap(orig, len);
interp->set_gap(seq, len, orig);

And don’t forget to remove the return statement in
HBASE_Analyzer::DeliverStream() method when has_gap is true.

And remember that the gapped data will be processed normally
when they finally arrived.

Obviously the real implementation code will be a mess.


------------------ Original ------------------