package engine import "net" type L3Info struct { Version uint8 Protocol uint8 IHL uint8 SrcIP [4]byte DstIP [4]byte Length uint16 } func (i L3Info) SrcIPAddr() net.IP { return net.IP(i.SrcIP[:]) } func (i L3Info) DstIPAddr() net.IP { return net.IP(i.DstIP[:]) } type TCPInfo struct { SrcPort uint16 DstPort uint16 Seq uint32 Ack uint32 HdrLen uint8 SYN bool FIN bool RST bool ACK bool } type UDPInfo struct { SrcPort uint16 DstPort uint16 } func ParseL3(data []byte) (l3 L3Info, transport []byte, ok bool) { if len(data) < 20 { return } version := data[0] >> 4 if version != 4 { return } ihl := data[0] & 0x0F if ihl < 5 || len(data) < int(ihl)*4 { return } totalLen := int(uint16(data[2])<<8 | uint16(data[3])) if totalLen < int(ihl)*4 || totalLen > len(data) { totalLen = len(data) } return L3Info{ Version: 4, Protocol: data[9], IHL: ihl, Length: uint16(totalLen), SrcIP: [4]byte{data[12], data[13], data[14], data[15]}, DstIP: [4]byte{data[16], data[17], data[18], data[19]}, }, data[ihl*4:totalLen], true } func ParseTCP(transport []byte) (TCPInfo, []byte, bool) { if len(transport) < 20 { return TCPInfo{}, nil, false } dataOff := uint8(transport[12]>>4) * 4 if dataOff < 20 || len(transport) < int(dataOff) { return TCPInfo{}, nil, false } flags := transport[13] payloadLen := len(transport) - int(dataOff) return TCPInfo{ SrcPort: uint16(transport[0])<<8 | uint16(transport[1]), DstPort: uint16(transport[2])<<8 | uint16(transport[3]), Seq: uint32(transport[4])<<24 | uint32(transport[5])<<16 | uint32(transport[6])<<8 | uint32(transport[7]), Ack: uint32(transport[8])<<24 | uint32(transport[9])<<16 | uint32(transport[10])<<8 | uint32(transport[11]), HdrLen: dataOff, SYN: flags&0x02 != 0, FIN: flags&0x01 != 0, RST: flags&0x04 != 0, ACK: flags&0x10 != 0, }, transport[dataOff : dataOff+uint8(payloadLen)], true } func ParseUDP(transport []byte) (UDPInfo, []byte, bool) { if len(transport) < 8 { return UDPInfo{}, nil, false } return UDPInfo{ SrcPort: uint16(transport[0])<<8 | uint16(transport[1]), DstPort: uint16(transport[2])<<8 | uint16(transport[3]), }, transport[8:], true }