diff options
Diffstat (limited to 'dhcpv6/option_requestedoption.go')
-rw-r--r-- | dhcpv6/option_requestedoption.go | 81 |
1 files changed, 46 insertions, 35 deletions
diff --git a/dhcpv6/option_requestedoption.go b/dhcpv6/option_requestedoption.go index 54ff5bf..0d16c74 100644 --- a/dhcpv6/option_requestedoption.go +++ b/dhcpv6/option_requestedoption.go @@ -7,58 +7,69 @@ import ( "github.com/u-root/u-root/pkg/uio" ) -// OptRequestedOption implements the requested options option. -// -// This module defines the OptRequestedOption structure. -// https://www.ietf.org/rfc/rfc3315.txt -type OptRequestedOption struct { - requestedOptions []OptionCode +// 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) + } } -func (op *OptRequestedOption) Code() OptionCode { - return OptionORO +// 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 } -func (op *OptRequestedOption) ToBytes() []byte { +// ToBytes implements Option.ToBytes. +func (o OptionCodes) ToBytes() []byte { buf := uio.NewBigEndianBuffer(nil) - for _, ro := range op.requestedOptions { + for _, ro := range o { buf.Write16(uint16(ro)) } return buf.Data() } -func (op *OptRequestedOption) RequestedOptions() []OptionCode { - return op.requestedOptions +func (o OptionCodes) String() string { + names := make([]string, 0, len(o)) + for _, code := range o { + names = append(names, code.String()) + } + return strings.Join(names, ", ") } -func (op *OptRequestedOption) SetRequestedOptions(opts []OptionCode) { - op.requestedOptions = opts +// 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() } -func (op *OptRequestedOption) AddRequestedOption(opt OptionCode) { - for _, requestedOption := range op.requestedOptions { - if opt == requestedOption { - fmt.Printf("Warning: option %s is already set, appending duplicate", opt) - } +// OptRequestedOption implements the requested options option as defined by RFC +// 3315 Section 22.7. +func OptRequestedOption(o ...OptionCode) Option { + return &optRequestedOption{ + OptionCodes: o, } - op.requestedOptions = append(op.requestedOptions, opt) } -func (op *OptRequestedOption) String() string { - names := make([]string, 0, len(op.requestedOptions)) - for _, code := range op.requestedOptions { - names = append(names, code.String()) - } - return fmt.Sprintf("OptRequestedOption{options=[%v]}", strings.Join(names, ", ")) +type optRequestedOption struct { + OptionCodes } -// build an OptRequestedOption structure from a sequence of bytes. -// The input data does not include option code and length bytes. -func ParseOptRequestedOption(data []byte) (*OptRequestedOption, error) { - var opt OptRequestedOption - buf := uio.NewBigEndianBuffer(data) - for buf.Has(2) { - opt.requestedOptions = append(opt.requestedOptions, OptionCode(buf.Read16())) - } - return &opt, buf.FinError() +// Code implements Option.Code. +func (*optRequestedOption) Code() OptionCode { + return OptionORO +} + +func (op *optRequestedOption) String() string { + return fmt.Sprintf("RequestedOptions: %s", op.OptionCodes) } |