diff options
author | Christopher Koch <chrisko@google.com> | 2019-01-10 16:19:02 -0800 |
---|---|---|
committer | insomniac <insomniacslk@users.noreply.github.com> | 2019-01-14 23:19:04 +0000 |
commit | 81af01ddbffafdc6904a8092cba3adf92008c715 (patch) | |
tree | 0bccb58f602c9289cdf4893297d579119591f98f /dhcpv4/options.go | |
parent | 833f274e1aca3b23320f6d31c246c73eefd38974 (diff) |
dhcpv4: change OptionCode to an interface for humanization.
Interface'd OptionCodes can print the correct human string.
It sucks because option codes are just a byte, but depending on where
you use them, they are interpreted differently. BSDP option codes !=
DHCP option codes.
Diffstat (limited to 'dhcpv4/options.go')
-rw-r--r-- | dhcpv4/options.go | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/dhcpv4/options.go b/dhcpv4/options.go index 905495e..44bf1d3 100644 --- a/dhcpv4/options.go +++ b/dhcpv4/options.go @@ -24,9 +24,6 @@ var ( ErrInvalidOptions = errors.New("invalid options data") ) -// OptionCode is a single byte representing the code for a given Option. -type OptionCode byte - // Option is an interface that all DHCP v4 options adhere to. type Option interface { Code() OptionCode @@ -137,15 +134,23 @@ func (o Options) Has(code OptionCode) bool { // // Returns an error if any invalid option or length is found. func OptionsFromBytes(data []byte) (Options, error) { - return OptionsFromBytesWithParser(data, ParseOption, true) + return OptionsFromBytesWithParser(data, codeGetter, ParseOption, true) } -// OptionParser is a function signature for option parsing +// OptionParser is a function signature for option parsing. type OptionParser func(code OptionCode, data []byte) (Option, error) +// OptionCodeGetter parses a code into an OptionCode. +type OptionCodeGetter func(code uint8) OptionCode + +// codeGetter is an OptionCodeGetter for DHCP optionCodes. +func codeGetter(c uint8) OptionCode { + return optionCode(c) +} + // OptionsFromBytesWithParser parses Options from byte sequences using the // parsing function that is passed in as a paremeter -func OptionsFromBytesWithParser(data []byte, parser OptionParser, checkEndOption bool) (Options, error) { +func OptionsFromBytesWithParser(data []byte, coder OptionCodeGetter, parser OptionParser, checkEndOption bool) (Options, error) { if len(data) == 0 { return nil, nil } @@ -160,11 +165,11 @@ func OptionsFromBytesWithParser(data []byte, parser OptionParser, checkEndOption // 1 byte: option code // 1 byte: option length n // n bytes: data - code := OptionCode(buf.Read8()) + code := buf.Read8() - if code == OptionPad { + if code == OptionPad.Code() { continue - } else if code == OptionEnd { + } else if code == OptionEnd.Code() { end = true break } @@ -177,12 +182,14 @@ func OptionsFromBytesWithParser(data []byte, parser OptionParser, checkEndOption } data = data[:length:length] - if _, ok := options[code]; !ok { - order = append(order, code) + // Get the OptionCode for this guy. + c := coder(code) + if _, ok := options[c]; !ok { + order = append(order, c) } // RFC 3396: Just concatenate the data if the option code was // specified multiple times. - options[code] = append(options[code], data...) + options[c] = append(options[c], data...) } // If we never read the End option, the sender of this packet screwed @@ -193,7 +200,7 @@ func OptionsFromBytesWithParser(data []byte, parser OptionParser, checkEndOption // Any bytes left must be padding. for buf.Len() >= 1 { - if OptionCode(buf.Read8()) != OptionPad { + if buf.Read8() != OptionPad.Code() { return nil, ErrInvalidOptions } } @@ -212,16 +219,16 @@ func OptionsFromBytesWithParser(data []byte, parser OptionParser, checkEndOption // Marshal writes options binary representations to b. func (o Options) Marshal(b *uio.Lexer) { for _, opt := range o { - code := opt.Code() + code := opt.Code().Code() // Even if the End option is in there, don't marshal it until // the end. - if code == OptionEnd { + if code == OptionEnd.Code() { continue - } else if code == OptionPad { + } else if code == OptionPad.Code() { // Some DHCPv4 options have fixed length and do not put // length on the wire. - b.Write8(uint8(code)) + b.Write8(code) continue } @@ -231,7 +238,7 @@ func (o Options) Marshal(b *uio.Lexer) { // option is simply listed multiple times. for len(data) > 0 { // 1 byte: option code - b.Write8(uint8(code)) + b.Write8(code) n := len(data) if n > math.MaxUint8 { |