-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathattr_pdr.go
397 lines (372 loc) · 8.13 KB
/
attr_pdr.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
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
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
package gtp5gnl
import (
"log"
"net"
"github.com/khirono/go-nl"
)
const (
PDR_ID = iota + 3
PDR_PRECEDENCE
PDR_PDI
PDR_OUTER_HEADER_REMOVAL
PDR_FAR_ID
PDR_ROLE_ADDR_IPV4
PDR_UNIX_SOCKET_PATH
PDR_QER_ID
PDR_SEID
PDR_URR_ID
PDR_PDN_TYPE
)
type PDR struct {
ID uint16
Precedence *uint32
PDI *PDI
OuterHdrRemoval *uint8
FARID *uint32
QERID []uint32
URRID []uint32
SEID *uint64
PDNType *uint8
}
func DecodePDR(b []byte) (*PDR, error) {
pdr := new(PDR)
for len(b) > 0 {
hdr, n, err := nl.DecodeAttrHdr(b)
if err != nil {
return nil, err
}
attrLen := int(hdr.Len)
switch hdr.MaskedType() {
case PDR_ID:
pdr.ID = native.Uint16(b[n:attrLen])
case PDR_PRECEDENCE:
v := native.Uint32(b[n:attrLen])
pdr.Precedence = &v
case PDR_PDI:
pdi, err := DecodePDI(b[n:attrLen])
if err != nil {
return nil, err
}
pdr.PDI = &pdi
case PDR_OUTER_HEADER_REMOVAL:
v := uint8(b[n])
pdr.OuterHdrRemoval = &v
case PDR_FAR_ID:
v := native.Uint32(b[n:attrLen])
pdr.FARID = &v
case PDR_QER_ID:
v := native.Uint32(b[n:attrLen])
pdr.QERID = append(pdr.QERID, v)
case PDR_URR_ID:
v := native.Uint32(b[n:attrLen])
pdr.URRID = append(pdr.URRID, v)
case PDR_SEID:
v := native.Uint64(b[n:attrLen])
pdr.SEID = &v
case PDR_PDN_TYPE:
v := b[n]
pdr.PDNType = &v
default:
log.Printf("unknown type: %v\n", hdr.Type)
}
b = b[hdr.Len.Align():]
}
return pdr, nil
}
const (
PDI_UE_ADDR_IPV4 = iota + 1
PDI_F_TEID
PDI_SDF_FILTER
PDI_SRC_INTF
PDI_ETHERNET_PACKET_FILTER
)
type PDI struct {
SrcIntf *uint8
UEAddr net.IP
FTEID *FTEID
SDF *SDFFilter
EPFs []EthPktFilter
}
func DecodePDI(b []byte) (PDI, error) {
var pdi PDI
for len(b) > 0 {
hdr, n, err := nl.DecodeAttrHdr(b)
if err != nil {
return pdi, err
}
attrLen := int(hdr.Len)
switch hdr.MaskedType() {
case PDI_UE_ADDR_IPV4:
pdi.UEAddr = make([]byte, 4)
copy(pdi.UEAddr, b[n:n+4])
case PDI_F_TEID:
fteid, err := DecodeFTEID(b[n:attrLen])
if err != nil {
return pdi, err
}
pdi.FTEID = &fteid
case PDI_SDF_FILTER:
sdf, err := DecodeSDFFilter(b[n:attrLen])
if err != nil {
return pdi, err
}
pdi.SDF = &sdf
case PDI_ETHERNET_PACKET_FILTER:
epf, err := DecodeEthPktFilter(b[n:attrLen])
if err != nil {
return pdi, err
}
pdi.EPFs = append(pdi.EPFs, epf)
case PDI_SRC_INTF:
v := b[n]
pdi.SrcIntf = &v
}
b = b[hdr.Len.Align():]
}
return pdi, nil
}
const (
F_TEID_I_TEID = iota + 1
F_TEID_GTPU_ADDR_IPV4
)
type FTEID struct {
TEID uint32
GTPuAddr net.IP
}
func DecodeFTEID(b []byte) (FTEID, error) {
var fteid FTEID
for len(b) > 0 {
hdr, n, err := nl.DecodeAttrHdr(b)
if err != nil {
return fteid, err
}
attrLen := int(hdr.Len)
switch hdr.MaskedType() {
case F_TEID_I_TEID:
fteid.TEID = native.Uint32(b[n:attrLen])
case F_TEID_GTPU_ADDR_IPV4:
fteid.GTPuAddr = make([]byte, 4)
copy(fteid.GTPuAddr, b[n:n+4])
}
b = b[hdr.Len.Align():]
}
return fteid, nil
}
const (
SDF_FILTER_FLOW_DESCRIPTION = iota + 1
SDF_FILTER_TOS_TRAFFIC_CLASS
SDF_FILTER_SECURITY_PARAMETER_INDEX
SDF_FILTER_FLOW_LABEL
SDF_FILTER_SDF_FILTER_ID
)
type SDFFilter struct {
FD *FlowDesc
TTC *uint16
SPI *uint32
FL *uint32
BID *uint32
}
func DecodeSDFFilter(b []byte) (SDFFilter, error) {
var sdf SDFFilter
for len(b) > 0 {
hdr, n, err := nl.DecodeAttrHdr(b)
if err != nil {
return sdf, err
}
attrLen := int(hdr.Len)
switch hdr.MaskedType() {
case SDF_FILTER_FLOW_DESCRIPTION:
fd, err := DecodeFlowDesc(b[n:attrLen])
if err != nil {
return sdf, err
}
sdf.FD = &fd
case SDF_FILTER_TOS_TRAFFIC_CLASS:
v := native.Uint16(b[n:attrLen])
sdf.TTC = &v
case SDF_FILTER_SECURITY_PARAMETER_INDEX:
v := native.Uint32(b[n:attrLen])
sdf.SPI = &v
case SDF_FILTER_FLOW_LABEL:
v := native.Uint32(b[n:attrLen])
sdf.FL = &v
case SDF_FILTER_SDF_FILTER_ID:
v := native.Uint32(b[n:attrLen])
sdf.BID = &v
default:
log.Printf("unknown type: %v\n", hdr.Type)
}
b = b[hdr.Len.Align():]
}
return sdf, nil
}
const (
FLOW_DESCRIPTION_ACTION = iota + 1
FLOW_DESCRIPTION_DIRECTION
FLOW_DESCRIPTION_PROTOCOL
FLOW_DESCRIPTION_SRC_IPV4
FLOW_DESCRIPTION_SRC_MASK
FLOW_DESCRIPTION_DEST_IPV4
FLOW_DESCRIPTION_DEST_MASK
FLOW_DESCRIPTION_SRC_PORT
FLOW_DESCRIPTION_DEST_PORT
)
const (
SDF_FILTER_ACTION_UNSPEC = iota
SDF_FILTER_PERMIT
)
const (
SDF_FILTER_DIRECTION_UNSPEC = iota
SDF_FILTER_IN
SDF_FILTER_OUT
)
type FlowDesc struct {
Action uint8
Dir uint8
Proto uint8
Src net.IPNet
Dst net.IPNet
SrcPorts [][]uint16
DstPorts [][]uint16
}
func DecodeFlowDesc(b []byte) (FlowDesc, error) {
var fd FlowDesc
for len(b) > 0 {
hdr, n, err := nl.DecodeAttrHdr(b)
if err != nil {
return fd, err
}
attrLen := int(hdr.Len)
switch hdr.MaskedType() {
case FLOW_DESCRIPTION_ACTION:
fd.Action = b[n]
case FLOW_DESCRIPTION_DIRECTION:
fd.Dir = b[n]
case FLOW_DESCRIPTION_PROTOCOL:
fd.Proto = b[n]
case FLOW_DESCRIPTION_SRC_IPV4:
fd.Src.IP = make([]byte, 4)
copy(fd.Src.IP, b[n:n+4])
case FLOW_DESCRIPTION_SRC_MASK:
fd.Src.Mask = make([]byte, 4)
copy(fd.Src.Mask, b[n:n+4])
case FLOW_DESCRIPTION_DEST_IPV4:
fd.Dst.IP = make([]byte, 4)
copy(fd.Dst.IP, b[n:n+4])
case FLOW_DESCRIPTION_DEST_MASK:
fd.Dst.Mask = make([]byte, 4)
copy(fd.Dst.Mask, b[n:n+4])
case FLOW_DESCRIPTION_SRC_PORT:
for n < attrLen {
v := native.Uint32(b[n:attrLen])
lb := uint16(v >> 16)
ub := uint16(v)
x := []uint16{lb}
if ub != lb {
x = append(x, ub)
}
fd.SrcPorts = append(fd.SrcPorts, x)
n += 4
}
case FLOW_DESCRIPTION_DEST_PORT:
for n < attrLen {
v := native.Uint32(b[n:attrLen])
lb := uint16(v >> 16)
ub := uint16(v)
x := []uint16{lb}
if ub != lb {
x = append(x, ub)
}
fd.DstPorts = append(fd.DstPorts, x)
n += 4
}
default:
log.Printf("unknown type: %v\n", hdr.Type)
}
b = b[hdr.Len.Align():]
}
return fd, nil
}
const (
EPF_FILTER_ETHERNET_FILTER_ID = iota + 1
EPF_FILTER_ETHERNET_FILTER_PROPERTIES
EPF_FILTER_MACADDRESS
EPF_FILTER_ETHERTYPE
EPF_FILTER_CTAG
EPF_FILTER_STAG
EPF_FILTER_SDF_FILTER
)
type EthPktFilter struct {
EthFilterID *uint32
MACAddrs []MACAddrFields
Ethertype *uint16
}
const (
MACADDRESS_SRC = iota + 1
MACADDRESS_DST
MACADDRESS_UPPER_SRC
MACADDRESS_UPPER_DST
)
type MACAddrFields struct {
SourceMACAddress string
DestinationMACAddress string
UpperSourceMACAddress string
UpperDestinationMACAddress string
}
func DecodeMACAddrFields(b []byte) (MACAddrFields, error) {
var macAddrFields MACAddrFields
var macAddr net.HardwareAddr = make([]byte, 6)
for len(b) > 0 {
hdr, n, err := nl.DecodeAttrHdr(b)
if err != nil {
return macAddrFields, err
}
attrLen := int(hdr.Len)
switch hdr.MaskedType() {
case MACADDRESS_SRC:
copy(macAddr, b[n:attrLen])
macAddrFields.SourceMACAddress = macAddr.String()
case MACADDRESS_DST:
copy(macAddr, b[n:attrLen])
macAddrFields.DestinationMACAddress = macAddr.String()
case MACADDRESS_UPPER_SRC:
copy(macAddr, b[n:attrLen])
macAddrFields.UpperSourceMACAddress = macAddr.String()
case MACADDRESS_UPPER_DST:
copy(macAddr, b[n:attrLen])
macAddrFields.UpperDestinationMACAddress = macAddr.String()
default:
log.Printf("unknown type: %v\n", hdr.Type)
}
b = b[hdr.Len.Align():]
}
return macAddrFields, nil
}
func DecodeEthPktFilter(b []byte) (EthPktFilter, error) {
var epf EthPktFilter
for len(b) > 0 {
hdr, n, err := nl.DecodeAttrHdr(b)
if err != nil {
return epf, err
}
attrLen := int(hdr.Len)
switch hdr.MaskedType() {
case EPF_FILTER_ETHERNET_FILTER_ID:
v := native.Uint32(b[n:attrLen])
epf.EthFilterID = &v
case EPF_FILTER_MACADDRESS:
macAddrFields, err := DecodeMACAddrFields(b[n:attrLen])
if err != nil {
return epf, err
}
epf.MACAddrs = append(epf.MACAddrs, macAddrFields)
case EPF_FILTER_ETHERTYPE:
v := native.Uint16(b[n:attrLen])
epf.Ethertype = &v
default:
log.Printf("unknown type: %v\n", hdr.Type)
}
b = b[hdr.Len.Align():]
}
return epf, nil
}