From edd0ae198b792ac68c7a353a46d20f59ad7f7db6 Mon Sep 17 00:00:00 2001 From: Mattias Wadman Date: Fri, 7 Jan 2022 12:02:38 +0100 Subject: [PATCH] tcp,flow: By default allow missing syn/ack for now Is probably what you usually want --- format/inet/flowsdecoder/flowsdecoder.go | 7 +- .../inet/testdata/flow_missing_synack.fqtest | 75 ++++++++++++++++++ format/inet/testdata/flow_missing_synack.pcap | Bin 0 -> 27241 bytes 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 format/inet/testdata/flow_missing_synack.fqtest create mode 100644 format/inet/testdata/flow_missing_synack.pcap diff --git a/format/inet/flowsdecoder/flowsdecoder.go b/format/inet/flowsdecoder/flowsdecoder.go index ca036ff9..4eb5c36e 100644 --- a/format/inet/flowsdecoder/flowsdecoder.go +++ b/format/inet/flowsdecoder/flowsdecoder.go @@ -1,5 +1,7 @@ package flowsdecoder +// TODO: option to not allow missing syn/ack? + import ( "bytes" "encoding/binary" @@ -49,7 +51,10 @@ func (t *TCPConnection) ReassembledSG(sg reassembly.ScatterGather, ac reassembly dir, _, _, skip := sg.Info() length, _ := sg.Lengths() - if skip != 0 { + if skip == -1 { + // can't find where skip == -1 is documented but this is what gopacket reassemblydump does + // to allow missing syn/ack + } else if skip != 0 { // stream has missing bytes return } diff --git a/format/inet/testdata/flow_missing_synack.fqtest b/format/inet/testdata/flow_missing_synack.fqtest new file mode 100644 index 00000000..8e809138 --- /dev/null +++ b/format/inet/testdata/flow_missing_synack.fqtest @@ -0,0 +1,75 @@ +# ssl_test.pcap from https://www.cloudshark.org/captures/a9718e5fdb28 +$ fq '.tcp_connections | d' flow_missing_synack.pcap + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.tcp_connections[0:8]: + | | | [0]{}: + | | | source_ip: "192.168.1.4" + | | | source_port: 2061 + | | | destination_ip: "192.168.1.3" + | | | destination_port: "https" (443) (http protocol over TLS/SSL) + 0x0000|16 03 01 00 9e 01 00 00 9a 03 01 50 83 9c fa fe|...........P....| client_stream: raw bits + * |until 0x177.7 (end) (376) | | + 0x0000|16 03 01 00 35 02 00 00 31 03 01 50 83 9c 9f e3|....5...1..P....| server_stream: raw bits + * |until 0x42b.7 (end) (1068) | | + | | | [1]{}: + | | | source_ip: "192.168.1.4" + | | | source_port: 2068 + | | | destination_ip: "192.168.1.3" + | | | destination_port: "https" (443) (http protocol over TLS/SSL) + 0x0000|16 03 01 00 9e 01 00 00 9a 03 01 50 83 9d 00 a1|...........P....| client_stream: raw bits + * |until 0x177.7 (end) (376) | | + 0x0000|16 03 01 00 35 02 00 00 31 03 01 50 83 9c a5 e5|....5...1..P....| server_stream: raw bits + * |until 0x42b.7 (end) (1068) | | + | | | [2]{}: + | | | source_ip: "192.168.1.4" + | | | source_port: 2070 + | | | destination_ip: "192.168.1.3" + | | | destination_port: "https" (443) (http protocol over TLS/SSL) + 0x0000|16 03 01 00 9e 01 00 00 9a 03 01 50 83 9d 03 f3|...........P....| client_stream: raw bits + * |until 0x2ad.7 (end) (686) | | + 0x0000|16 03 01 00 35 02 00 00 31 03 01 50 83 9c a8 b2|....5...1..P....| server_stream: raw bits + * |until 0x53c.7 (end) (1341) | | + | | | [3]{}: + | | | source_ip: "192.168.1.4" + | | | source_port: 2071 + | | | destination_ip: "192.168.1.3" + | | | destination_port: "https" (443) (http protocol over TLS/SSL) + 0x0000|16 03 01 01 6e 01 00 01 6a 03 01 50 83 9d 03 d8|....n...j..P....| client_stream: raw bits + * |until 0x2df.7 (end) (736) | | + 0x0000|16 03 01 00 51 02 00 00 4d 03 01 50 83 9c a8 fc|....Q...M..P....| server_stream: raw bits + * |until 0x1b7.7 (end) (440) | | + | | | [4]{}: + | | | source_ip: "192.168.1.4" + | | | source_port: 2072 + | | | destination_ip: "192.168.1.3" + | | | destination_port: "https" (443) (http protocol over TLS/SSL) + 0x0000|16 03 01 01 6e 01 00 01 6a 03 01 50 83 9d 03 94|....n...j..P....| client_stream: raw bits + * |until 0x2fd.7 (end) (766) | | + 0x0000|16 03 01 00 51 02 00 00 4d 03 01 50 83 9c a8 d8|....Q...M..P....| server_stream: raw bits + * |until 0x1b7.7 (end) (440) | | + | | | [5]{}: + | | | source_ip: "192.168.1.4" + | | | source_port: 2073 + | | | destination_ip: "192.168.1.3" + | | | destination_port: "https" (443) (http protocol over TLS/SSL) + 0x0000|16 03 01 01 6e 01 00 01 6a 03 01 50 83 9d 0d 96|....n...j..P....| client_stream: raw bits + * |until 0x2fd.7 (end) (766) | | + 0x0000|16 03 01 00 51 02 00 00 4d 03 01 50 83 9c b2 45|....Q...M..P...E| server_stream: raw bits + * |until 0x2d73.7 (end) (11636) | | + | | | [6]{}: + | | | source_ip: "192.168.1.4" + | | | source_port: 2078 + | | | destination_ip: "192.168.1.3" + | | | destination_port: "https" (443) (http protocol over TLS/SSL) + 0x0000|16 03 01 01 6e 01 00 01 6a 03 01 50 83 9d d7 3a|....n...j..P...:| client_stream: raw bits + * |until 0x38c.7 (end) (909) | | + 0x0000|16 03 01 00 51 02 00 00 4d 03 01 50 83 9d 7c ac|....Q...M..P..|.| server_stream: raw bits + * |until 0x2d5.7 (end) (726) | | + | | | [7]{}: + | | | source_ip: "192.168.1.4" + | | | source_port: 2085 + | | | destination_ip: "192.168.1.3" + | | | destination_port: "https" (443) (http protocol over TLS/SSL) + 0x0000|16 03 01 01 6e 01 00 01 6a 03 01 50 83 9e 02 2b|....n...j..P...+| client_stream: raw bits + * |until 0x4a0.7 (end) (1185) | | + 0x0000|16 03 01 00 51 02 00 00 4d 03 01 50 83 9d a7 8b|....Q...M..P....| server_stream: raw bits + * |until 0x4f3.7 (end) (1268) | | diff --git a/format/inet/testdata/flow_missing_synack.pcap b/format/inet/testdata/flow_missing_synack.pcap new file mode 100644 index 0000000000000000000000000000000000000000..5a31265ef5373f4c1f46f05b405b55249ff2fc30 GIT binary patch literal 27241 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