diff options
Diffstat (limited to 'dhcpv4/options.go')
-rw-r--r-- | dhcpv4/options.go | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/dhcpv4/options.go b/dhcpv4/options.go index 59f2c83..6576c05 100644 --- a/dhcpv4/options.go +++ b/dhcpv4/options.go @@ -10,6 +10,7 @@ type OptionCode byte var MagicCookie = []byte{99, 130, 83, 99} +// TODO: implement Option as an interface similar to dhcpv6. type Option struct { Code OptionCode Data []byte @@ -38,18 +39,29 @@ func ParseOption(dataStart []byte) (*Option, error) { } } +// OptionsFromBytes parses a sequence of bytes until the end and builds a list +// of options from it. The sequence must contain the Magic Cookie. Returns an +// error if any invalid option or length is found. func OptionsFromBytes(data []byte) ([]Option, error) { - // Parse a sequence of bytes until the end and build a list of options from - // it. The sequence must contain the Magic Cookie. - // Returns an error if any invalid option or length is found. - if len(data) < 4 { + if len(data) < len(MagicCookie) { return nil, errors.New("Invalid options: shorter than 4 bytes") } - if !bytes.Equal(data[:4], MagicCookie) { - return nil, errors.New(fmt.Sprintf("Invalid Magic Cookie: %v", data[:4])) + if !bytes.Equal(data[:len(MagicCookie)], MagicCookie) { + return nil, fmt.Errorf("Invalid Magic Cookie: %v", data[:len(MagicCookie)]) } + opts, err := OptionsFromBytesWithoutMagicCookie(data[len(MagicCookie):]) + if err != nil { + return nil, err + } + return opts, nil +} + +// OptionsFromBytesWithoutMagicCookie parses a sequence of bytes until the end +// and builds a list of options from it. The sequence should not contain the +// DHCP magic cookie. Returns an error if any invalid option or length is found. +func OptionsFromBytesWithoutMagicCookie(data []byte) ([]Option, error) { options := make([]Option, 0, 10) - idx := 4 + idx := 0 for { if idx == len(data) { break @@ -64,9 +76,10 @@ func OptionsFromBytes(data []byte) ([]Option, error) { return nil, err } options = append(options, *opt) + + // Options with zero length have no length byte, so here we handle the + // ones with nonzero length if len(opt.Data) > 0 { - // options with zero length have no length byte, so here we handle the ones with - // nonzero length idx++ } idx += len(opt.Data) @@ -74,10 +87,16 @@ func OptionsFromBytes(data []byte) ([]Option, error) { return options, nil } +// OptionsToBytes converts a list of options to a wire-format representation +// with the DHCP magic cookie prepended. func OptionsToBytes(options []Option) []byte { - // Convert a list of options to a wire-format representation. This will - // include the Magic Cookie - ret := MagicCookie + return append(MagicCookie, OptionsToBytesWithoutMagicCookie(options)...) +} + +// OptionsToBytesWithoutMagicCookie converts a list of options to a wire-format +// representation. +func OptionsToBytesWithoutMagicCookie(options []Option) []byte { + ret := []byte{} for _, opt := range options { ret = append(ret, opt.ToBytes()...) } |