1package dictionary
2
3import (
4	"bytes"
5	"fmt"
6	"strconv"
7)
8
9type Dictionary struct {
10	Attributes []*Attribute
11	Values     []*Value
12	Vendors    []*Vendor
13}
14
15func (d *Dictionary) GoString() string {
16	var b bytes.Buffer
17	b.WriteString("&dictionary.Dictionary{")
18
19	if len(d.Attributes) > 0 {
20		b.WriteString("Attributes:[]*dictionary.Attribute{")
21		for _, attr := range d.Attributes {
22			fmt.Fprintf(&b, "%#v,", attr)
23		}
24		b.WriteString("},")
25	}
26
27	if len(d.Values) > 0 {
28		b.WriteString("Values:[]*dictionary.Value{")
29		for _, value := range d.Values {
30			fmt.Fprintf(&b, "%#v,", value)
31		}
32		b.WriteString("},")
33	}
34
35	if len(d.Vendors) > 0 {
36		b.WriteString("Vendors:[]*dictionary.Vendor{")
37		for _, vendor := range d.Vendors {
38			fmt.Fprintf(&b, "%#v,", vendor)
39		}
40		b.WriteString("},")
41	}
42
43	b.WriteString("}")
44	return b.String()
45}
46
47type AttributeType int
48
49const (
50	AttributeString AttributeType = iota + 1
51	AttributeOctets
52	AttributeIPAddr
53	AttributeDate
54	AttributeInteger
55	AttributeIPv6Addr
56	AttributeIPv6Prefix
57	AttributeIFID
58	AttributeInteger64
59
60	AttributeVSA
61
62	AttributeEther
63	AttributeABinary
64	AttributeByte
65	AttributeShort
66	AttributeSigned
67	AttributeTLV
68	AttributeIPv4Prefix
69)
70
71func (t AttributeType) String() string {
72	switch t {
73	case AttributeString:
74		return "string"
75	case AttributeOctets:
76		return "octets"
77	case AttributeIPAddr:
78		return "ipaddr"
79	case AttributeDate:
80		return "date"
81	case AttributeInteger:
82		return "integer"
83	case AttributeIPv6Addr:
84		return "ipv6addr"
85	case AttributeIPv6Prefix:
86		return "ipv6prefix"
87	case AttributeIFID:
88		return "ifid"
89	case AttributeInteger64:
90		return "integer64"
91
92	case AttributeVSA:
93		return "vsa"
94
95	case AttributeEther:
96		return "ether"
97	case AttributeABinary:
98		return "abinary"
99	case AttributeByte:
100		return "byte"
101	case AttributeShort:
102		return "short"
103	case AttributeSigned:
104		return "signed"
105	case AttributeTLV:
106		return "tlv"
107	case AttributeIPv4Prefix:
108		return "ipv4prefix"
109	}
110	return "AttributeType(" + strconv.Itoa(int(t)) + ")"
111}
112
113type OID []int
114
115func (o OID) Equals(other OID) bool {
116	if len(o) != len(other) {
117		return false
118	}
119	for i, n := 0, len(o); i < n; i++ {
120		if o[i] != other[i] {
121			return false
122		}
123	}
124	return true
125}
126
127func (o OID) String() string {
128	if len(o) == 0 {
129		return ""
130	}
131
132	const maximumIntLength = 3
133	b := make([]byte, 0, len(o)*(maximumIntLength+1)-1)
134	for i, e := range o {
135		if i > 0 {
136			b = append(b, '.')
137		}
138		b = strconv.AppendInt(b, int64(e), 10)
139	}
140	return string(b)
141}
142
143const (
144	EncryptUserPassword   = 1
145	EncryptTunnelPassword = 2
146)
147
148type Attribute struct {
149	Name string
150	OID  OID
151	Type AttributeType
152
153	Size IntFlag
154
155	FlagEncrypt IntFlag
156	FlagHasTag  BoolFlag
157	FlagConcat  BoolFlag
158}
159
160func (a *Attribute) HasTag() bool {
161	return a.FlagHasTag.Valid && a.FlagHasTag.Bool
162}
163
164func (a *Attribute) Equals(o *Attribute) bool {
165	if a == o {
166		return true
167	}
168	if a == nil || o == nil {
169		return false
170	}
171
172	if a.Name != o.Name || !a.OID.Equals(o.OID) || a.Type != o.Type {
173		return false
174	}
175
176	if a.Size != o.Size {
177		return false
178	}
179
180	if a.FlagEncrypt != o.FlagEncrypt || a.FlagHasTag != o.FlagHasTag || a.FlagConcat != o.FlagConcat {
181		return false
182	}
183
184	return true
185}
186
187func (a *Attribute) GoString() string {
188	var b bytes.Buffer
189	b.WriteString("&dictionary.Attribute{")
190
191	fmt.Fprintf(&b, "Name:%#v,", a.Name)
192	fmt.Fprintf(&b, "OID:%#v,", a.OID)
193	fmt.Fprintf(&b, "Type:%#v,", a.Type)
194
195	if a.Size.Valid {
196		fmt.Fprintf(&b, "Size:%#v,", a.Size)
197	}
198
199	if a.FlagEncrypt.Valid {
200		fmt.Fprintf(&b, "FlagEncrypt:%#v,", a.FlagEncrypt)
201	}
202	if a.FlagHasTag.Valid {
203		fmt.Fprintf(&b, "FlagHasTag:%#v,", a.FlagHasTag)
204	}
205	if a.FlagConcat.Valid {
206		fmt.Fprintf(&b, "FlagConcat:%#v,", a.FlagConcat)
207	}
208
209	b.WriteString("}")
210	return b.String()
211}
212
213type Value struct {
214	Attribute string
215	Name      string
216	Number    int
217}
218
219type Vendor struct {
220	Name   string
221	Number int
222
223	TypeOctets   *int
224	LengthOctets *int
225
226	Attributes []*Attribute
227	Values     []*Value
228}
229
230func (v *Vendor) GetTypeOctets() int {
231	if v.TypeOctets == nil {
232		return 1
233	}
234	return *v.TypeOctets
235}
236
237func (v *Vendor) GetLengthOctets() int {
238	if v.LengthOctets == nil {
239		return 1
240	}
241	return *v.LengthOctets
242}
243
244func (v *Vendor) GoString() string {
245	var b bytes.Buffer
246	b.WriteString("&dictionary.Vendor{")
247
248	fmt.Fprintf(&b, "Name:%#v,", v.Name)
249	fmt.Fprintf(&b, "Number:%#v,", v.Number)
250
251	fmt.Fprintf(&b, "TypeOctets:%#v,", v.TypeOctets)
252	fmt.Fprintf(&b, "LengthOctets:%#v,", v.LengthOctets)
253
254	if len(v.Attributes) > 0 {
255		b.WriteString("Attributes:[]*dictionary.Attribute{")
256		for _, attr := range v.Attributes {
257			fmt.Fprintf(&b, "%#v,", attr)
258		}
259		b.WriteString("},")
260	}
261	if len(v.Values) > 0 {
262		b.WriteString("Values:[]*dictionary.Value{")
263		for _, value := range v.Values {
264			fmt.Fprintf(&b, "%#v,", value)
265		}
266		b.WriteString("},")
267	}
268
269	b.WriteString("}")
270	return b.String()
271}
272
273type IntFlag struct {
274	Int   int
275	Valid bool
276}
277
278type BoolFlag struct {
279	Bool  bool
280	Valid bool
281}
282