-
Notifications
You must be signed in to change notification settings - Fork 1
/
net_packet_tcp.go
115 lines (96 loc) · 2.39 KB
/
net_packet_tcp.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package derive
import (
"net"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/nextlinux/tracee/pkg/events"
"github.com/nextlinux/tracee/types/trace"
)
func NetPacketTCP() DeriveFunction {
return deriveSingleEvent(events.NetPacketTCP, deriveNetPacketTCPArgs())
}
func deriveNetPacketTCPArgs() deriveArgsFunction {
return func(event trace.Event) ([]interface{}, error) {
var ok bool
var payload []byte
var layerType gopacket.LayerType
var srcIP net.IP
var dstIP net.IP
// sanity checks
payloadArg := events.GetArg(&event, "payload")
if payloadArg == nil {
return nil, noPayloadError()
}
if payload, ok = payloadArg.Value.([]byte); !ok {
return nil, nonByteArgError()
}
payloadSize := len(payload)
if payloadSize < 1 {
return nil, emptyPayloadError()
}
// event retval encodes layer 3 protocol type
if event.ReturnValue&familyIpv4 == familyIpv4 {
layerType = layers.LayerTypeIPv4
} else if event.ReturnValue&familyIpv6 == familyIpv6 {
layerType = layers.LayerTypeIPv6
} else {
return nil, nil
}
// parse packet
packet := gopacket.NewPacket(
payload,
layerType,
gopacket.Default,
)
if packet == nil {
return []interface{}{}, parsePacketError()
}
layer3 := packet.NetworkLayer()
switch v := layer3.(type) {
case (*layers.IPv4):
srcIP = v.SrcIP
dstIP = v.DstIP
case (*layers.IPv6):
srcIP = v.SrcIP
dstIP = v.DstIP
default:
return nil, nil
}
layer4 := packet.TransportLayer()
switch l4 := layer4.(type) {
case (*layers.TCP):
var tcp trace.ProtoTCP
copyTCPToProtoTCP(l4, &tcp)
return []interface{}{
srcIP,
dstIP,
tcp.SrcPort,
tcp.DstPort,
tcp,
}, nil
}
return nil, notProtoPacketError("TCP")
}
}
//
// TCP protocol type conversion (from gopacket layer to trace type)
//
func copyTCPToProtoTCP(l4 *layers.TCP, proto *trace.ProtoTCP) {
proto.SrcPort = uint16(l4.SrcPort)
proto.DstPort = uint16(l4.DstPort)
proto.Seq = l4.Seq
proto.Ack = l4.Ack
proto.DataOffset = l4.DataOffset
proto.FIN = boolToUint8(l4.FIN)
proto.SYN = boolToUint8(l4.SYN)
proto.RST = boolToUint8(l4.RST)
proto.PSH = boolToUint8(l4.PSH)
proto.ACK = boolToUint8(l4.ACK)
proto.URG = boolToUint8(l4.URG)
proto.ECE = boolToUint8(l4.ECE)
proto.NS = boolToUint8(l4.NS)
proto.Window = l4.Window
proto.Checksum = l4.Checksum
proto.Urgent = l4.Urgent
// TODO: TCP options
}