From e0182254e66192bdf4103a37e222abea4eab8121 Mon Sep 17 00:00:00 2001 From: gengming3 Date: Sat, 23 Nov 2024 14:43:14 +0800 Subject: [PATCH] add sflow parse ipip protocol five-tuple --- packet/network.go | 12 +++++++++ packet/transport.go | 61 ++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/packet/network.go b/packet/network.go index e6aaa87e..40a9d4fa 100644 --- a/packet/network.go +++ b/packet/network.go @@ -64,6 +64,9 @@ const ( // IANAProtoICMP is IANA Internet Control Message number IANAProtoICMP = 1 + // IANAProtoIPIP is IANA User Datagram number + IANAProtoIPIP = 4 + // IANAProtoTCP is IANA Transmission Control number IANAProtoTCP = 6 @@ -123,6 +126,15 @@ func (p *Packet) decodeNextLayer() error { p.L4 = udp len = 8 + + case IANAProtoIPIP: + ipip, err := decodeIPIP(p.data) + if err != nil { + return err + } + + p.L4 = ipip + len = 40 default: return errUnknownTransportLayer } diff --git a/packet/transport.go b/packet/transport.go index 694bfbc3..a1cbe092 100644 --- a/packet/transport.go +++ b/packet/transport.go @@ -22,7 +22,10 @@ package packet -import "errors" +import ( + "errors" + "net" +) // TCPHeader represents TCP header type TCPHeader struct { @@ -39,9 +42,30 @@ type UDPHeader struct { DstPort int } +// IPIPHeader represents IPIP header +type IPIPHeader struct { + InnerVersion int + InnerTOS int + InnerTotalLen int + InnerID int + InnerFlags int + InnerFragOff int + InnerTTL int + InnerProtocol int + InnerChecksum int + InnerSrc string + InnerDst string + SrcPort int + DstPort int + DataOffset int + Reserved int + Flags int +} + var ( - errShortTCPHeaderLength = errors.New("short TCP header length") - errShortUDPHeaderLength = errors.New("short UDP header length") + errShortTCPHeaderLength = errors.New("short TCP header length") + errShortUDPHeaderLength = errors.New("short UDP header length") + errShortIPIPHeaderLength = errors.New("short IPIP header length") ) func decodeTCP(b []byte) (TCPHeader, error) { @@ -68,3 +92,34 @@ func decodeUDP(b []byte) (UDPHeader, error) { DstPort: int(b[2])<<8 | int(b[3]), }, nil } + +func decodeIPIP(b []byte) (IPIPHeader, error) { + if len(b) < 40 { + return IPIPHeader{}, errShortIPIPHeaderLength + } + + var ( + src net.IP = b[12:16] + dst net.IP = b[16:20] + ) + + ipipHeader := IPIPHeader{ + InnerVersion: int(b[0] & 0xf0 >> 4), + InnerTOS: int(b[1]), + InnerTotalLen: int(b[2])<<8 | int(b[3]), + InnerID: int(b[4])<<8 | int(b[5]), + InnerFlags: int(b[6] & 0x07), + InnerTTL: int(b[8]), + InnerProtocol: int(b[9]), + InnerChecksum: int(b[10])<<8 | int(b[11]), + InnerSrc: src.String(), + InnerDst: dst.String(), + SrcPort: int(b[20])<<8 | int(b[21]), + DstPort: int(b[22])<<8 | int(b[23]), + DataOffset: int(b[32]) >> 4, + Reserved: 0, + Flags: ((int(b[32])<<8 | int(b[33])) & 0x01ff), + } + + return ipipHeader, nil +}