Files
Mellaris/engine/packet.go
T

92 lines
2.2 KiB
Go

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
}