-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.go
194 lines (160 loc) · 4.33 KB
/
util.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
package libradius
import (
"encoding/binary"
"fmt"
"layeh.com/radius"
"layeh.com/radius/rfc2865"
)
type AVP struct {
VendorId uint32
TypeId uint8
ValueLen uint8
Value []byte
}
type WimarkAVPs struct {
ClientStr string
SessionInt int
}
type AirspaceAVPs struct {
ACLName string
}
type CiscoAVPs struct {
AccountInfo string
CommandCodeStr string
AuditSessionID string
CommandCodeBytes []byte
AVPList []string
}
func (a *AVP) String() string {
return fmt.Sprintf("Vendor: %d, Type: %d, Value: %s", a.VendorId, a.TypeId, string(a.Value))
}
func DecodeAVPairVSA(vsa []byte) (*AVP, error) {
if len(vsa) <= 6 {
return nil, fmt.Errorf("too short VSA: %d bytes", len(vsa))
}
return &AVP{
VendorId: binary.BigEndian.Uint32(vsa[0:4]),
TypeId: vsa[4],
ValueLen: vsa[5],
Value: vsa[6:],
}, nil
}
func DecodeAVPairsVSA(p *radius.Packet) ([]*AVP, error) {
var AVPItem *AVP
var AVPList []*AVP
var err error
for _, attr := range p.Attributes {
if attr.Type != rfc2865.VendorSpecific_Type {
continue
}
AVPItem, err = DecodeAVPairVSA(radius.Bytes(attr.Attribute))
if err != nil {
AVPList = nil
return nil, err
} else {
AVPList = append(AVPList, AVPItem)
}
}
return AVPList, nil
}
func DecodeAVPairsVSAByVendor(p *radius.Packet, vendorID uint32) ([]*AVP, error) {
var AVPList []*AVP
for _, attr := range p.Attributes {
if attr.Type == rfc2865.VendorSpecific_Type {
AVPItem, err := DecodeAVPairVSA(radius.Bytes(attr.Attribute))
if err != nil {
return nil, err
}
if AVPItem.VendorId == vendorID {
AVPList = append(AVPList, AVPItem)
}
}
}
return AVPList, nil
}
func DecodeWimarkAVPairsStruct(p *radius.Packet) (WimarkAVPs, error) {
var WimarkAVPStruct WimarkAVPs
AVPList, err := DecodeAVPairsVSAByVendor(p, VendorWimark)
if err != nil {
return WimarkAVPStruct, err
}
if AVPList == nil {
return WimarkAVPStruct, fmt.Errorf("avps is empty")
}
for _, AVPItem := range AVPList {
if AVPItem.TypeId == uint8(WimarkAVPTypeClientStr) {
WimarkAVPStruct.ClientStr = string(AVPItem.Value)
}
}
return WimarkAVPStruct, nil
}
func DecodeAirspaceAVPairsStruct(p *radius.Packet) (AirspaceAVPs, error) {
var AirspaceAVPStruct AirspaceAVPs
AVPList, err := DecodeAVPairsVSAByVendor(p, VendorAirspace)
if err != nil {
return AirspaceAVPStruct, err
}
if AVPList == nil {
return AirspaceAVPStruct, fmt.Errorf("avps is empty")
}
for _, AVPItem := range AVPList {
if AVPItem.TypeId == uint8(AirspaceAVPTypeACLName) {
AirspaceAVPStruct.ACLName = string(AVPItem.Value)
}
}
return AirspaceAVPStruct, nil
}
func DecodeCiscoAVPairsStruct(p *radius.Packet) (CiscoAVPs, error) {
var CiscoAVPStruct CiscoAVPs
AVPList, err := DecodeAVPairsVSAByVendor(p, VendorCisco)
if err != nil {
return CiscoAVPStruct, err
}
if AVPList == nil {
return CiscoAVPStruct, fmt.Errorf("avps is empty")
}
for _, AVPItem := range AVPList {
if AVPItem.TypeId == uint8(CiscoAVPTypeAccountInfo) {
CiscoAVPStruct.AccountInfo = string(AVPItem.Value)
}
if AVPItem.TypeId == uint8(CiscoAVPTypeCommandCode) {
CiscoAVPStruct.CommandCodeStr = string(AVPItem.Value)
CiscoAVPStruct.CommandCodeBytes = AVPItem.Value
}
if AVPItem.TypeId == uint8(CiscoAVPTypeDefault) {
CiscoAVPStruct.AVPList = append(CiscoAVPStruct.AVPList, string(AVPItem.Value))
}
}
return CiscoAVPStruct, nil
}
func AddVSAString(p *radius.Packet, vendor uint32, attribute uint8, value string) {
bytes, _ := radius.NewBytes([]byte(value))
attr := make(radius.Attribute, 2+len(bytes))
attr[0] = attribute
attr[1] = byte(len(attr))
copy(attr[2:], bytes)
vsa, _ := radius.NewVendorSpecific(vendor, attr)
p.Add(rfc2865.VendorSpecific_Type, vsa)
}
func AddVSAInt(p *radius.Packet, vendor uint32, attribute uint8, value int) {
bytes := radius.NewInteger(uint32(value))
attr := make(radius.Attribute, 2+len(bytes))
attr[0] = attribute
attr[1] = byte(len(attr))
copy(attr[2:], bytes)
vsa, _ := radius.NewVendorSpecific(vendor, attr)
p.Add(rfc2865.VendorSpecific_Type, vsa)
}
func CreateHexVSA(value string, t AVPType, vendor uint32) (hex []byte) {
if len(value) > 249 {
return
}
bytes := []byte(value)
attr := make([]byte, 2+len(bytes))
attr[0], attr[1] = byte(t), byte(len(attr))
copy(attr[2:], bytes)
hex = make([]byte, 4+len(attr))
binary.BigEndian.PutUint32(hex, vendor)
copy(hex[4:], attr)
return
}