summaryrefslogtreecommitdiffhomepage
path: root/dhcpv4/options.go
diff options
context:
space:
mode:
Diffstat (limited to 'dhcpv4/options.go')
-rw-r--r--dhcpv4/options.go43
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()...)
}