-
Notifications
You must be signed in to change notification settings - Fork 13
/
attr_far.go
140 lines (129 loc) · 2.82 KB
/
attr_far.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
package gtp5gnl
import (
"net"
"github.com/khirono/go-nl"
)
const (
FAR_ID = iota + 3
FAR_APPLY_ACTION
FAR_FORWARDING_PARAMETER
FAR_RELATED_TO_PDR
FAR_SEID
FAR_BAR_ID
)
type FAR struct {
ID uint32
Action uint16
Param *ForwardParam
PDRIDs []uint16
BARID *uint8
SEID *uint64
}
func DecodeFAR(b []byte) (*FAR, error) {
far := new(FAR)
for len(b) > 0 {
hdr, n, err := nl.DecodeAttrHdr(b)
if err != nil {
return nil, err
}
attrLen := int(hdr.Len)
switch hdr.MaskedType() {
case FAR_ID:
far.ID = native.Uint32(b[n:attrLen])
case FAR_APPLY_ACTION:
far.Action = native.Uint16(b[n:attrLen])
case FAR_FORWARDING_PARAMETER:
param, err := DecodeForwardParam(b[n:attrLen])
if err != nil {
return nil, err
}
far.Param = ¶m
case FAR_RELATED_TO_PDR:
d := b[n:attrLen]
for len(d) > 0 {
v := native.Uint16(d)
far.PDRIDs = append(far.PDRIDs, v)
d = d[2:]
}
case FAR_BAR_ID:
v := b[n]
far.BARID = &v
case FAR_SEID:
v := native.Uint64(b[n:attrLen])
far.SEID = &v
}
b = b[hdr.Len.Align():]
}
return far, nil
}
const (
FORWARDING_PARAMETER_OUTER_HEADER_CREATION = iota + 1
FORWARDING_PARAMETER_FORWARDING_POLICY
FORWARDING_PARAMETER_PFCPSM_REQ_FLAGS
FORWARDING_PARAMETER_TOS_TC
)
type ForwardParam struct {
Creation *HeaderCreation
Policy *string
TosTc uint8
}
func DecodeForwardParam(b []byte) (ForwardParam, error) {
var param ForwardParam
for len(b) > 0 {
hdr, n, err := nl.DecodeAttrHdr(b)
if err != nil {
return param, err
}
attrLen := int(hdr.Len)
switch hdr.MaskedType() {
case FORWARDING_PARAMETER_OUTER_HEADER_CREATION:
hc, err := DecodeHeaderCreation(b[n:attrLen])
if err != nil {
return param, err
}
param.Creation = &hc
case FORWARDING_PARAMETER_FORWARDING_POLICY:
s, _, _ := nl.DecodeAttrString(b[n:attrLen])
param.Policy = &s
case FORWARDING_PARAMETER_TOS_TC:
param.TosTc = b[n]
}
b = b[hdr.Len.Align():]
}
return param, nil
}
const (
OUTER_HEADER_CREATION_DESCRIPTION = iota + 1
OUTER_HEADER_CREATION_O_TEID
OUTER_HEADER_CREATION_PEER_ADDR_IPV4
OUTER_HEADER_CREATION_PORT
)
type HeaderCreation struct {
Desc uint16
TEID uint32
PeerAddr net.IP
Port uint16
}
func DecodeHeaderCreation(b []byte) (HeaderCreation, error) {
var hc HeaderCreation
for len(b) > 0 {
hdr, n, err := nl.DecodeAttrHdr(b)
if err != nil {
return hc, err
}
attrLen := int(hdr.Len)
switch hdr.MaskedType() {
case OUTER_HEADER_CREATION_DESCRIPTION:
hc.Desc = native.Uint16(b[n:attrLen])
case OUTER_HEADER_CREATION_O_TEID:
hc.TEID = native.Uint32(b[n:attrLen])
case OUTER_HEADER_CREATION_PEER_ADDR_IPV4:
hc.PeerAddr = make([]byte, 4)
copy(hc.PeerAddr, b[n:n+4])
case OUTER_HEADER_CREATION_PORT:
hc.Port = native.Uint16(b[n:attrLen])
}
b = b[hdr.Len.Align():]
}
return hc, nil
}