forked from microsoft/retina
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatapath_drop_windows.go
More file actions
206 lines (177 loc) · 6.98 KB
/
Copy pathdatapath_drop_windows.go
File metadata and controls
206 lines (177 loc) · 6.98 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium
package ebpfwindows
import (
"errors"
"fmt"
"github.com/cilium/cilium/pkg/byteorder"
"github.com/cilium/cilium/pkg/identity"
)
const (
DropNotifyVersion0 = iota
DropNotifyVersion1
DropNotifyVersion2
)
const (
// dropNotifyV1Len is the amount of packet data provided in a v0/v1 drop notification.
dropNotifyV1Len = 36
dropPktmonNotifyV1Len = 57
maxCapLength = 128
)
var dropNotifyLengthFromVersion = map[uint16]uint{
DropNotifyVersion0: dropNotifyV1Len, // retain backwards compatibility for testing.
DropNotifyVersion1: dropNotifyV1Len,
}
var PktmonDropNotifyLengthFromVersion = map[uint16]uint{
DropNotifyVersion1: dropPktmonNotifyV1Len, // retain backwards compatibility for testing.
}
var (
errUnexpectedDropNotifyLength = errors.New("unexpected DropNotify data length")
errInvalidDropNotifyVersion = errors.New("invalid DropNotify version")
)
// DropNotify is the message format of a drop notification in the BPF ring buffer
type DropNotify struct {
Type uint8
SubType uint32
Source uint16
Hash uint32
OrigLen uint32
CapLen uint16
Version uint16
SrcLabel identity.NumericIdentity
DstLabel identity.NumericIdentity
DstID uint32
Line uint16
File uint8
ExtError int8
Ifindex uint32
}
type NetEventDataHeader struct {
Type uint8 // uint8_t type
Version uint16 // uint16_t version
}
type PktmonEvtStreamPacketDescriptor struct {
PacketOriginalLength uint32 // uint32_t packet_original_length
PacketLoggedLength uint32 // uint32_t packet_logged_length
PacketMetadataLength uint32 // uint32_t packet_metadata_length
}
type PktmonEvtStreamMetadata struct {
PktGroupID uint64 // uint64_t pkt_groupid
PktCount uint16 // uint16_t pkt_count
AppearanceCount uint16 // uint16_t appearance_count
DirectionName uint16 // uint16_t direction_name
PacketType uint16 // uint16_t packet_type
ComponentID uint16 // uint16_t component_id
EdgeID uint16 // uint16_t edge_id
FilterID uint16 // uint16_t filter_id
DropReason uint32 // uint32_t drop_reason
DropLocation uint32 // uint32_t drop_location
ProcNum uint16 // uint16_t proc_num
Timestamp uint64 // uint64_t timestamp
}
type PktmonEvtStreamPacketHeader struct {
EventID uint8 // uint8_t eventid
PacketDescriptor PktmonEvtStreamPacketDescriptor // pktmon_evt_stream_packet_descriptor
Metadata PktmonEvtStreamMetadata // pktmon_evt_stream_metadata
}
type PktmonDropNotify struct {
VersionHeader NetEventDataHeader // netevent_data_header_t version_header
PktmonHeader PktmonEvtStreamPacketHeader // pktmon_evt_stream_packet_header pktmon_header
}
// DecodeDropNotify will decode 'data' into the provided DropNotify structure
func DecodePktmonDrop(data []byte, pdn *PktmonDropNotify) error {
if err := pdn.decodePktmonDrop(data); err != nil {
return err
}
return nil
}
// DataOffset returns the offset from the beginning of PktmonDropNotify where the
// notification data begins.
func (n *PktmonDropNotify) DataOffset() uint {
return dropNotifyLengthFromVersion[n.VersionHeader.Version]
}
func (n *PktmonDropNotify) decodePktmonDrop(data []byte) error {
if l := len(data); l < dropPktmonNotifyV1Len {
return fmt.Errorf("%w: expected at least %d but got %d", errUnexpectedDropNotifyLength, dropPktmonNotifyV1Len, l)
}
version := byteorder.Native.Uint16(data[2:4])
// Check against max version.
if version > DropNotifyVersion1 {
return fmt.Errorf("%w: Unrecognized pktmon drop event version %d\nRaw data bytes: %v\nData size: %d\nType: %d\n",
errInvalidDropNotifyVersion, version,
data,
len(data))
}
// Decode logic for version >= v0/v1.
n.VersionHeader.Type = data[0]
n.VersionHeader.Version = version
n.PktmonHeader.EventID = data[4]
n.PktmonHeader.PacketDescriptor.PacketOriginalLength = byteorder.Native.Uint32(data[5:9])
n.PktmonHeader.PacketDescriptor.PacketLoggedLength = byteorder.Native.Uint32(data[9:13])
n.PktmonHeader.PacketDescriptor.PacketMetadataLength = byteorder.Native.Uint32(data[13:17])
n.PktmonHeader.Metadata.PktGroupID = byteorder.Native.Uint64(data[17:25])
n.PktmonHeader.Metadata.PktCount = byteorder.Native.Uint16(data[25:27])
n.PktmonHeader.Metadata.AppearanceCount = byteorder.Native.Uint16(data[27:29])
n.PktmonHeader.Metadata.DirectionName = byteorder.Native.Uint16(data[29:31])
n.PktmonHeader.Metadata.PacketType = byteorder.Native.Uint16(data[31:33])
n.PktmonHeader.Metadata.ComponentID = byteorder.Native.Uint16(data[33:35])
n.PktmonHeader.Metadata.EdgeID = byteorder.Native.Uint16(data[35:37])
n.PktmonHeader.Metadata.FilterID = byteorder.Native.Uint16(data[37:39])
n.PktmonHeader.Metadata.DropReason = byteorder.Native.Uint32(data[39:43])
n.PktmonHeader.Metadata.DropLocation = byteorder.Native.Uint32(data[43:47])
n.PktmonHeader.Metadata.ProcNum = byteorder.Native.Uint16(data[47:49])
n.PktmonHeader.Metadata.Timestamp = byteorder.Native.Uint64(data[49:57])
return nil
}
func (n *PktmonDropNotify) ConvertToDropNotify(dn *DropNotify) {
dn.Type = 1
dn.SubType = n.PktmonHeader.Metadata.DropReason
dn.OrigLen = n.PktmonHeader.PacketDescriptor.PacketOriginalLength
dn.CapLen = uint16(min(maxCapLength, dn.OrigLen))
dn.Version = n.VersionHeader.Version
}
// DecodeDropNotify will decode 'data' into the provided DropNotify structure
func DecodeDropNotify(data []byte, dn *DropNotify) error {
return dn.decodeDropNotify(data)
}
func (n *DropNotify) decodeDropNotify(data []byte) error {
if l := len(data); l < dropNotifyV1Len {
return fmt.Errorf("%w: expected at least %d but got %d", errUnexpectedDropNotifyLength, dropNotifyV1Len, l)
}
version := byteorder.Native.Uint16(data[14:16])
// Check against max version.
if version > DropNotifyVersion1 {
return fmt.Errorf("%w: Unrecognized drop event version %d", errInvalidDropNotifyVersion, version)
}
// Decode logic for version >= v0/v1.
n.Type = data[0]
n.SubType = uint32(data[1])
n.Source = byteorder.Native.Uint16(data[2:4])
n.Hash = byteorder.Native.Uint32(data[4:8])
n.OrigLen = byteorder.Native.Uint32(data[8:12])
n.CapLen = byteorder.Native.Uint16(data[12:14])
n.Version = version
n.SrcLabel = identity.NumericIdentity(byteorder.Native.Uint32(data[16:20]))
n.DstLabel = identity.NumericIdentity(byteorder.Native.Uint32(data[20:24]))
n.DstID = byteorder.Native.Uint32(data[24:28])
n.Line = byteorder.Native.Uint16(data[28:30])
n.File = data[30]
n.ExtError = int8(data[31])
n.Ifindex = byteorder.Native.Uint32(data[32:36])
return nil
}
// IsL3Device returns true if the trace comes from an L3 device.
func (n *DropNotify) IsL3Device() bool {
return false
}
// IsIPv6 returns true if the trace refers to an IPv6 packet.
func (n *DropNotify) IsIPv6() bool {
return false
}
// DataOffset returns the offset from the beginning of DropNotify where the
// notification data begins.
//
// Returns zero for invalid or unknown DropNotify messages.
func (n *DropNotify) DataOffset() uint {
return dropNotifyLengthFromVersion[n.Version]
}