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
|
package dhcpv6
import (
"fmt"
"strings"
"github.com/u-root/uio/uio"
)
// OptionCodes are a collection of option codes.
type OptionCodes []OptionCode
// Add adds an option to the list, ignoring duplicates.
func (o *OptionCodes) Add(c OptionCode) {
if !o.Contains(c) {
*o = append(*o, c)
}
}
// Contains returns whether the option codes contain c.
func (o OptionCodes) Contains(c OptionCode) bool {
for _, oo := range o {
if oo == c {
return true
}
}
return false
}
// ToBytes implements Option.ToBytes.
func (o OptionCodes) ToBytes() []byte {
buf := uio.NewBigEndianBuffer(nil)
for _, ro := range o {
buf.Write16(uint16(ro))
}
return buf.Data()
}
func (o OptionCodes) String() string {
names := make([]string, 0, len(o))
for _, code := range o {
names = append(names, code.String())
}
return strings.Join(names, ", ")
}
// FromBytes populates o from binary-encoded data.
func (o *OptionCodes) FromBytes(data []byte) error {
buf := uio.NewBigEndianBuffer(data)
for buf.Has(2) {
o.Add(OptionCode(buf.Read16()))
}
return buf.FinError()
}
// OptRequestedOption implements the requested options option as defined by RFC
// 3315 Section 22.7.
func OptRequestedOption(o ...OptionCode) Option {
return &optRequestedOption{
OptionCodes: o,
}
}
type optRequestedOption struct {
OptionCodes
}
// Code implements Option.Code.
func (*optRequestedOption) Code() OptionCode {
return OptionORO
}
func (op *optRequestedOption) String() string {
return fmt.Sprintf("%s: %s", op.Code(), op.OptionCodes)
}
|