1package dictionarygen
2
3import (
4	"io"
5
6	"layeh.com/radius/dictionary"
7)
8
9func (g *Generator) genVendor(w io.Writer, vendor *dictionary.Vendor) {
10	ident := identifier(vendor.Name)
11
12	p(w)
13	p(w, `func _`, ident, `_AddVendor(p *radius.Packet, typ byte, attr radius.Attribute) (err error) {`)
14	p(w, `	var vsa radius.Attribute`)
15	p(w, `	vendor := make(radius.Attribute, 2+len(attr))`)
16	p(w, `	vendor[0] = typ`)
17	p(w, `	vendor[1] = byte(len(vendor))`)
18	p(w, `	copy(vendor[2:], attr)`)
19	p(w, `	vsa, err = radius.NewVendorSpecific(_`, ident, `_VendorID, vendor)`)
20	p(w, `	if err != nil {`)
21	p(w, `		return`)
22	p(w, `	}`)
23	p(w, `	p.Add(rfc2865.VendorSpecific_Type, vsa)`)
24	p(w, `	return`)
25	p(w, `}`)
26
27	p(w)
28	p(w, `func _`, ident, `_GetsVendor(p *radius.Packet, typ byte) (values []radius.Attribute) {`)
29	p(w, `	for _, attr := range p.Attributes[rfc2865.VendorSpecific_Type] {`)
30	p(w, `		vendorID, vsa, err := radius.VendorSpecific(attr)`)
31	p(w, `		if err != nil || vendorID != _`, ident, `_VendorID {`)
32	p(w, `			continue`)
33	p(w, `		}`)
34	p(w, `		for len(vsa) >= 3 {`)
35	p(w, `			vsaTyp, vsaLen := vsa[0], vsa[1]`)
36	p(w, `			if int(vsaLen) > len(vsa) || vsaLen < 3 {`) // malformed
37	p(w, `				break`)
38	p(w, `			}`)
39	p(w, `			if vsaTyp == typ {`)
40	p(w, `				values = append(values, vsa[2:int(vsaLen)])`)
41	p(w, `			}`)
42	p(w, `			vsa = vsa[int(vsaLen):]`)
43	p(w, `		}`)
44	p(w, `	}`)
45	p(w, `	return`)
46	p(w, `}`)
47
48	p(w)
49	p(w, `func _`, ident, `_LookupVendor(p *radius.Packet, typ byte) (attr radius.Attribute, ok bool) {`)
50	p(w, `	for _, a := range p.Attributes[rfc2865.VendorSpecific_Type] {`)
51	p(w, `		vendorID, vsa, err := radius.VendorSpecific(a)`)
52	p(w, `		if err != nil || vendorID != _`, ident, `_VendorID {`)
53	p(w, `			continue`)
54	p(w, `		}`)
55	p(w, `		for len(vsa) >= 3 {`)
56	p(w, `			vsaTyp, vsaLen := vsa[0], vsa[1]`)
57	p(w, `			if int(vsaLen) > len(vsa) || vsaLen < 3 {`) // malformed
58	p(w, `				break`)
59	p(w, `			}`)
60	p(w, `			if vsaTyp == typ {`)
61	p(w, `				return vsa[2:int(vsaLen)], true`)
62	p(w, `			}`)
63	p(w, `			vsa = vsa[int(vsaLen):]`)
64	p(w, `		}`)
65	p(w, `	}`)
66	p(w, `	return`)
67	p(w, `}`)
68
69	p(w)
70	p(w, `func _`, ident, `_SetVendor(p *radius.Packet, typ byte, attr radius.Attribute) (err error) {`)
71	p(w, `	for i := 0; i < len(p.Attributes[rfc2865.VendorSpecific_Type]); {`)
72	p(w, `		vendorID, vsa, err := radius.VendorSpecific(p.Attributes[rfc2865.VendorSpecific_Type][i])`)
73	p(w, `		if err != nil || vendorID != _`, ident, `_VendorID {`)
74	p(w, `			i++`)
75	p(w, `			continue`)
76	p(w, `		}`)
77	p(w, `		for j := 0; len(vsa[j:]) >= 3; {`)
78	p(w, `			vsaTyp, vsaLen := vsa[0], vsa[1]`)
79	p(w, `			if int(vsaLen) > len(vsa[j:]) || vsaLen < 3 {`) // malformed
80	p(w, `				i++`)
81	p(w, `				break`)
82	p(w, `			}`)
83	p(w, `			if vsaTyp == typ {`)
84	p(w, `				vsa = append(vsa[:j], vsa[j+int(vsaLen):]...)`)
85	p(w, `			}`)
86	p(w, `			j += int(vsaLen)`)
87	p(w, `		}`)
88	p(w, `		if len(vsa) > 0 {`)
89	p(w, `			copy(p.Attributes[rfc2865.VendorSpecific_Type][i][4:], vsa)`)
90	p(w, `			i++`)
91	p(w, `		} else {`)
92	p(w, `			p.Attributes[rfc2865.VendorSpecific_Type] = append(p.Attributes[rfc2865.VendorSpecific_Type][:i], p.Attributes[rfc2865.VendorSpecific_Type][i+i:]...)`)
93	p(w, `		}`)
94	p(w, `	}`)
95	p(w, `	return _`, ident, `_AddVendor(p, typ, attr)`)
96	p(w, `}`)
97
98	p(w)
99	p(w, `func _`, ident, `_DelVendor(p *radius.Packet, typ byte) {`)
100	p(w, `vsaLoop:`)
101	p(w, `	for i := 0; i < len(p.Attributes[rfc2865.VendorSpecific_Type]); {`)
102	p(w, `		attr := p.Attributes[rfc2865.VendorSpecific_Type][i]`)
103	p(w, `		vendorID, vsa, err := radius.VendorSpecific(attr)`)
104	p(w, `		if err != nil || vendorID != _`, ident, `_VendorID {`)
105	p(w, `			continue`)
106	p(w, `		}`)
107	p(w, `		offset := 0`)
108	p(w, `		for len(vsa[offset:]) >= 3 {`)
109	p(w, `			vsaTyp, vsaLen := vsa[offset], vsa[offset+1]`)
110	p(w, `			if int(vsaLen) > len(vsa) || vsaLen < 3 {`) // malformed
111	p(w, `				continue vsaLoop`)
112	p(w, `			}`)
113	p(w, `			if vsaTyp == typ {`)
114	p(w, `				copy(vsa[offset:], vsa[offset+int(vsaLen):])`)
115	p(w, `				vsa = vsa[:len(vsa)-int(vsaLen)]`)
116	p(w, `			} else {`)
117	p(w, `				offset += int(vsaLen)`)
118	p(w, `			}`)
119	p(w, `		}`)
120	p(w, `		if offset == 0 {`)
121	p(w, `			p.Attributes[rfc2865.VendorSpecific_Type] = append(p.Attributes[rfc2865.VendorSpecific_Type][:i], p.Attributes[rfc2865.VendorSpecific_Type][i+1:]...)`)
122	p(w, `		} else {`)
123	p(w, `			i++`)
124	p(w, `		}`)
125	p(w, `	}`)
126	p(w, `	return`)
127	p(w, `}`)
128}
129