summaryrefslogtreecommitdiffhomepage
path: root/dhcpv6/option_requestedoption.go
blob: bba5e487430626eb64c7deb62538b21cab916018 (plain)
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)
}