diff --git a/format/inet.go b/format/inet.go index 29e7e565..9993f9d6 100644 --- a/format/inet.go +++ b/format/inet.go @@ -84,8 +84,8 @@ const ( LinkTypeFC_2_WITH_FRAME_DELIMS = 225 LinkTypeIPNET = 226 LinkTypeCAN_SOCKETCAN = 227 - LinkTypeIPV4 = 228 - LinkTypeIPV6 = 229 + LinkTypeIPv4 = 228 + LinkTypeIPv6 = 229 LinkTypeIEEE802_15_4_NOFCS = 230 LinkTypeDBUS = 231 LinkTypeDVB_CI = 235 @@ -218,8 +218,8 @@ var LinkTypeMap = scalar.UintMap{ LinkTypeFC_2_WITH_FRAME_DELIMS: {Sym: "fc_2_with_frame_delims", Description: `Fibre Channel FC-2 frames, beginning an encoding of the SOF, followed by a Frame_Header, and ending with an encoding of the SOF`}, LinkTypeIPNET: {Sym: "ipnet", Description: `Solaris ipnet pseudo-header, followed by an IPv4 or IPv6 datagram`}, LinkTypeCAN_SOCKETCAN: {Sym: "can_socketcan", Description: `CAN (Controller Area Network) frames, with a pseudo-header followed by the frame payload`}, - LinkTypeIPV4: {Sym: "ipv4", Description: `Raw IPv4`}, - LinkTypeIPV6: {Sym: "ipv6", Description: `Raw IPv6`}, + LinkTypeIPv4: {Sym: "ipv4", Description: `Raw IPv4`}, + LinkTypeIPv6: {Sym: "ipv6", Description: `Raw IPv6`}, LinkTypeIEEE802_15_4_NOFCS: {Sym: "ieee802_15_4_nofcs", Description: `IEEE 802.15.4 Low-Rate Wireless Network, without the FCS at the end of the frame`}, LinkTypeDBUS: {Sym: "dbus", Description: `Raw D-Bus messages`}, LinkTypeDVB_CI: {Sym: "dvb_ci", Description: `DVB-CI (DVB Common Interface for communication between a PC Card module and a DVB receiver)`}, diff --git a/format/inet/flowsdecoder/flowsdecoder.go b/format/inet/flowsdecoder/flowsdecoder.go index 97efbd21..7882d69a 100644 --- a/format/inet/flowsdecoder/flowsdecoder.go +++ b/format/inet/flowsdecoder/flowsdecoder.go @@ -170,6 +170,18 @@ func New(options DecoderOptions) *Decoder { return flowDecoder } +func (fd *Decoder) EthernetFrame(bs []byte) error { + return fd.packet(gopacket.NewPacket(bs, layers.LayerTypeEthernet, gopacket.Lazy)) +} + +func (fd *Decoder) IPv4Packet(bs []byte) error { + return fd.packet(gopacket.NewPacket(bs, layers.LayerTypeIPv4, gopacket.Lazy)) +} + +func (fd *Decoder) IPv6Packet(bs []byte) error { + return fd.packet(gopacket.NewPacket(bs, layers.LayerTypeIPv6, gopacket.Lazy)) +} + func (fd *Decoder) SLLPacket(bs []byte) error { return fd.packet(gopacket.NewPacket(bs, layers.LayerTypeLinuxSLL, gopacket.Lazy)) } @@ -178,10 +190,6 @@ func (fd *Decoder) SLL2Packet(bs []byte) error { return fd.packet(gopacket.NewPacket(bs, layers.LayerTypeLinuxSLL2, gopacket.Lazy)) } -func (fd *Decoder) EthernetFrame(bs []byte) error { - return fd.packet(gopacket.NewPacket(bs, layers.LayerTypeEthernet, gopacket.Lazy)) -} - func (fd *Decoder) LoopbackFrame(bs []byte) error { return fd.packet(gopacket.NewPacket(bs, layers.LayerTypeLoopback, gopacket.Lazy)) } diff --git a/format/inet/ipv4_packet.go b/format/inet/ipv4_packet.go index 9cf1c36d..bc411f48 100644 --- a/format/inet/ipv4_packet.go +++ b/format/inet/ipv4_packet.go @@ -18,7 +18,10 @@ func init() { interp.RegisterFormat(decode.Format{ Name: format.IPV4_PACKET, Description: "Internet protocol v4 packet", - Groups: []string{format.INET_PACKET}, + Groups: []string{ + format.INET_PACKET, + format.LINK_FRAME, + }, Dependencies: []decode.Dependency{ {Names: []string{format.IP_PACKET}, Group: &ipv4IpPacketGroup}, }, @@ -51,8 +54,11 @@ var mapUToIPv4Sym = scalar.UintFn(func(s scalar.Uint) (scalar.Uint, error) { func decodeIPv4(d *decode.D) any { var ipi format.InetPacketIn + var lfi format.LinkFrameIn if d.ArgAs(&ipi) && ipi.EtherType != format.EtherTypeIPv4 { d.Fatalf("incorrect ethertype %d", ipi.EtherType) + } else if d.ArgAs(&lfi) && lfi.Type != format.LinkTypeIPv4 { + d.Fatalf("incorrect linktype %d", lfi.Type) } d.FieldU4("version") diff --git a/format/inet/ipv6_packet.go b/format/inet/ipv6_packet.go index f456a9a2..30b724a4 100644 --- a/format/inet/ipv6_packet.go +++ b/format/inet/ipv6_packet.go @@ -17,7 +17,10 @@ func init() { interp.RegisterFormat(decode.Format{ Name: format.IPV6_PACKET, Description: "Internet protocol v6 packet", - Groups: []string{format.INET_PACKET}, + Groups: []string{ + format.INET_PACKET, + format.LINK_FRAME, + }, Dependencies: []decode.Dependency{ {Names: []string{format.IP_PACKET}, Group: &ipv6IpPacketGroup}, }, @@ -110,8 +113,11 @@ var mapUToIPv6Sym = scalar.BitBufFn(func(s scalar.BitBuf) (scalar.BitBuf, error) func decodeIPv6(d *decode.D) any { var ipi format.InetPacketIn + var lfi format.LinkFrameIn if d.ArgAs(&ipi) && ipi.EtherType != format.EtherTypeIPv6 { d.Fatalf("incorrect ethertype %d", ipi.EtherType) + } else if d.ArgAs(&lfi) && lfi.Type != format.LinkTypeIPv6 { + d.Fatalf("incorrect linktype %d", lfi.Type) } d.FieldU4("version") diff --git a/format/inet/sll2_packet.go b/format/inet/sll2_packet.go index 14d87695..ba21c4ef 100644 --- a/format/inet/sll2_packet.go +++ b/format/inet/sll2_packet.go @@ -55,7 +55,7 @@ func decodeSLL2(d *decode.D) any { "payload", d.BitsLeft(), sllPacket2InetPacketGroup, - format.LinkFrameIn{Type: int(protcolType)}, + format.InetPacketIn{EtherType: int(protcolType)}, ) default: d.FieldRawLen("payload", d.BitsLeft()) diff --git a/format/inet/sll_packet.go b/format/inet/sll_packet.go index 1db01a6d..2a93a880 100644 --- a/format/inet/sll_packet.go +++ b/format/inet/sll_packet.go @@ -132,7 +132,7 @@ func decodeSLL(d *decode.D) any { "payload", d.BitsLeft(), sllPacketInetPacketGroup, - format.LinkFrameIn{Type: int(protcolType)}, + format.InetPacketIn{EtherType: int(protcolType)}, ) default: d.FieldU16LE("protocol_type") diff --git a/format/inet/testdata/tls12-ipv4-linkframe-keylog.pcapng b/format/inet/testdata/tls12-ipv4-linkframe-keylog.pcapng new file mode 100644 index 00000000..d9bf1ab5 Binary files /dev/null and b/format/inet/testdata/tls12-ipv4-linkframe-keylog.pcapng differ diff --git a/format/inet/testdata/tls12-ipv4-linkframe-keylog.pcapng.fqtest b/format/inet/testdata/tls12-ipv4-linkframe-keylog.pcapng.fqtest new file mode 100644 index 00000000..b67e7c65 --- /dev/null +++ b/format/inet/testdata/tls12-ipv4-linkframe-keylog.pcapng.fqtest @@ -0,0 +1,100 @@ +# tls12-dsb.pcapng from https://gitlab.com/wireshark/wireshark/-/tree/master/test/captures +$ fq 'first(grep_by(.type=="enhanced_packet")), .[0].tcp_connections | dv' tls12-ipv4-linkframe-keylog.pcapng + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].blocks[3]{}: block 0x12c-0x267.7 (316) +0x120| 06 00 00 00| ....| type: "enhanced_packet" (0x6) (Enhanced Packet Block) 0x12c-0x12f.7 (4) +0x130|3c 01 00 00 |<... | length: 316 0x130-0x133.7 (4) +0x130| 00 00 00 00 | .... | interface_id: 0 0x134-0x137.7 (4) +0x130| dd 7a 05 00 | .z.. | timestamp_high: 359133 0x138-0x13b.7 (4) +0x130| a3 2d 60 23| .-`#| timestamp_low: 593505699 0x13c-0x13f.7 (4) +0x140|19 01 00 00 |.... | capture_packet_length: 281 0x140-0x143.7 (4) +0x140| 19 01 00 00 | .... | original_packet_length: 281 0x144-0x147.7 (4) + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| packet{}: (ipv4_packet) 0x148-0x260.7 (281) +0x140| 45 | E | version: 4 0x148-0x148.3 (0.4) +0x140| 45 | E | ihl: 5 0x148.4-0x148.7 (0.4) +0x140| 00 | . | dscp: 0 0x149-0x149.5 (0.6) +0x140| 00 | . | ecn: 0 0x149.6-0x149.7 (0.2) +0x140| 01 19 | .. | total_length: 281 0x14a-0x14b.7 (2) +0x140| e1 ea | .. | identification: 57834 0x14c-0x14d.7 (2) +0x140| 40 | @ | reserved: 0 0x14e-0x14e (0.1) +0x140| 40 | @ | dont_fragment: true 0x14e.1-0x14e.1 (0.1) +0x140| 40 | @ | more_fragments: false 0x14e.2-0x14e.2 (0.1) +0x140| 40 00| @.| fragment_offset: 0 0x14e.3-0x14f.7 (1.5) +0x150|40 |@ | ttl: 64 0x150-0x150.7 (1) +0x150| 06 | . | protocol: "tcp" (6) (Transmission control protocol) 0x151-0x151.7 (1) +0x150| 18 0f | .. | header_checksum: 0x180f (valid) 0x152-0x153.7 (2) +0x150| 0a 09 00 02 | .... | source_ip: "10.9.0.2" (0xa090002) 0x154-0x157.7 (4) +0x150| 5d b8 d8 22 | ].." | destination_ip: "93.184.216.34" (0x5db8d822) 0x158-0x15b.7 (4) + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| payload{}: (tcp_segment) 0x15c-0x260.7 (261) +0x150| b6 d0 | .. | source_port: 46800 0x15c-0x15d.7 (2) +0x150| 01 bb| ..| destination_port: "https" (443) (http protocol over TLS/SSL) 0x15e-0x15f.7 (2) +0x160|fb c2 e0 52 |...R | sequence_number: 4223852626 0x160-0x163.7 (4) +0x160| de 55 1a e0 | .U.. | acknowledgment_number: 3730119392 0x164-0x167.7 (4) +0x160| 80 | . | data_offset: 8 0x168-0x168.3 (0.4) +0x160| 80 | . | reserved: 0 0x168.4-0x168.6 (0.3) +0x160| 80 | . | ns: false 0x168.7-0x168.7 (0.1) +0x160| 18 | . | cwr: false 0x169-0x169 (0.1) +0x160| 18 | . | ece: false 0x169.1-0x169.1 (0.1) +0x160| 18 | . | urg: false 0x169.2-0x169.2 (0.1) +0x160| 18 | . | ack: true 0x169.3-0x169.3 (0.1) +0x160| 18 | . | psh: true 0x169.4-0x169.4 (0.1) +0x160| 18 | . | rst: false 0x169.5-0x169.5 (0.1) +0x160| 18 | . | syn: false 0x169.6-0x169.6 (0.1) +0x160| 18 | . | fin: false 0x169.7-0x169.7 (0.1) +0x160| 00 e5 | .. | window_size: 229 0x16a-0x16b.7 (2) +0x160| 40 f1 | @. | checksum: 0x40f1 0x16c-0x16d.7 (2) +0x160| 00 00| ..| urgent_pointer: 0 0x16e-0x16f.7 (2) + | | | options[0:3]: 0x170-0x17b.7 (12) + | | | [0]{}: option 0x170-0x170.7 (1) +0x170|01 |. | kind: "nop" (1) (No operation) 0x170-0x170.7 (1) + | | | [1]{}: option 0x171-0x171.7 (1) +0x170| 01 | . | kind: "nop" (1) (No operation) 0x171-0x171.7 (1) + | | | [2]{}: option 0x172-0x17b.7 (10) +0x170| 08 | . | kind: "timestamp" (8) (Timestamp and echo of previous timestamp) 0x172-0x172.7 (1) +0x170| 0a | . | length: 10 0x173-0x173.7 (1) +0x170| c8 fa fa 0d | .... | value: 3371891213 0x174-0x177.7 (4) +0x170| 88 06 26 a6 | ..&. | echo_reply: 2282104486 0x178-0x17b.7 (4) +0x170| 16 03 01 00| ....| payload: raw bits 0x17c-0x260.7 (229) +0x180|e0 01 00 00 dc 03 03 f6 7a 28 b3 86 b3 1c 62 0d|........z(....b.| +* |until 0x260.7 (229) | | +0x260| 00 00 00 | ... | padding: raw bits 0x261-0x263.7 (3) + | | | options[0:0]: 0x264-NA (0) +0x260| 3c 01 00 00 | <... | footer_length: 316 0x264-0x267.7 (4) + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef|.[0].tcp_connections[0:2]: 0x2814-NA (0) + | | | [0]{}: tcp_connection 0x2814-NA (0) + | | | client{}: 0x2814-NA (0) + | | | ip: "10.9.0.2" 0x2814-NA (0) + | | | port: 46800 0x2814-NA (0) + | | | has_start: false 0x2814-NA (0) + | | | has_end: false 0x2814-NA (0) + | | | skipped_bytes: 0 0x2814-NA (0) + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| + 0x000|16 03 01 00 e0 01 00 00 dc 03 03 f6 7a 28 b3 86|............z(..| stream: raw bits 0x0-0x1ea.7 (491) + * |until 0x1ea.7 (end) (491) | | + | | | server{}: 0x2814-NA (0) + | | | ip: "93.184.216.34" 0x2814-NA (0) + | | | port: "https" (443) (http protocol over TLS/SSL) 0x2814-NA (0) + | | | has_start: false 0x2814-NA (0) + | | | has_end: false 0x2814-NA (0) + | | | skipped_bytes: 0 0x2814-NA (0) + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| + 0x000|16 03 03 00 70 02 00 00 6c 03 03 75 d0 16 e2 3a|....p...l..u...:| stream: raw bits 0x0-0xe4d.7 (3662) + * |until 0xe4d.7 (end) (3662) | | + | | | [1]{}: tcp_connection 0x2814-NA (0) + | | | client{}: 0x2814-NA (0) + | | | ip: "10.9.0.2" 0x2814-NA (0) + | | | port: 46802 0x2814-NA (0) + | | | has_start: false 0x2814-NA (0) + | | | has_end: false 0x2814-NA (0) + | | | skipped_bytes: 0 0x2814-NA (0) + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| + 0x000|16 03 01 00 e0 01 00 00 dc 03 03 1e 0d 63 b4 1d|.............c..| stream: raw bits 0x0-0x1ea.7 (491) + * |until 0x1ea.7 (end) (491) | | + | | | server{}: 0x2814-NA (0) + | | | ip: "93.184.216.34" 0x2814-NA (0) + | | | port: "https" (443) (http protocol over TLS/SSL) 0x2814-NA (0) + | | | has_start: false 0x2814-NA (0) + | | | has_end: false 0x2814-NA (0) + | | | skipped_bytes: 0 0x2814-NA (0) + |00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f|0123456789abcdef| + 0x000|16 03 03 00 70 02 00 00 6c 03 03 2e af a1 24 6f|....p...l.....$o| stream: raw bits 0x0-0xe4d.7 (3662) + * |until 0xe4d.7 (end) (3662) | | diff --git a/format/pcap/shared.go b/format/pcap/shared.go index 578bb3bf..82ad9048 100644 --- a/format/pcap/shared.go +++ b/format/pcap/shared.go @@ -8,10 +8,12 @@ import ( ) var linkToDecodeFn = map[int]func(fd *flowsdecoder.Decoder, bs []byte) error{ - format.LinkTypeNULL: (*flowsdecoder.Decoder).LoopbackFrame, format.LinkTypeETHERNET: (*flowsdecoder.Decoder).EthernetFrame, + format.LinkTypeIPv4: (*flowsdecoder.Decoder).IPv4Packet, + format.LinkTypeIPv6: (*flowsdecoder.Decoder).IPv6Packet, format.LinkTypeLINUX_SLL: (*flowsdecoder.Decoder).SLLPacket, format.LinkTypeLINUX_SLL2: (*flowsdecoder.Decoder).SLL2Packet, + format.LinkTypeNULL: (*flowsdecoder.Decoder).LoopbackFrame, } // TODO: make some of this shared if more packet capture formats are added