summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBrandon Bennett <bennetb@gmail.com>2018-05-11 14:09:24 -0600
committerinsomniac <insomniacslk@users.noreply.github.com>2018-05-11 21:09:24 +0100
commitd7cd0594274352de80d86a3bf32b487dfde63629 (patch)
tree11e49ad04a68378dc8e689c26098f7b4ef8f53c1
parenteab1c08cbc637f5d370bf84da1feba8673fb7cc3 (diff)
add dhcpv4.GetOption and dhcpv4.GetSingleOption methods (#63)
GetOption and GetOneOption are convenience methods for getting a DHCPv4 option from its Option Code. GetOption returns a list of options that match since the DHCP RFC allows for an option to be present multiple times with its values appended together. (Note: I am not sure I've ever seen this done and it's not clear if how option parsing would work for more complex values. Is appending done at the byte level? ) GetOneOption will return the first found option that matches a code.
-rw-r--r--dhcpv4/dhcpv4.go25
-rw-r--r--dhcpv4/dhcpv4_test.go22
2 files changed, 47 insertions, 0 deletions
diff --git a/dhcpv4/dhcpv4.go b/dhcpv4/dhcpv4.go
index 3deda86..226c077 100644
--- a/dhcpv4/dhcpv4.go
+++ b/dhcpv4/dhcpv4.go
@@ -511,6 +511,31 @@ func (d *DHCPv4) Options() []Option {
return d.options
}
+// GetOption will attempt to get all options that match a DHCPv4 option
+// from its OptionCode. If the option was not found it will return an
+// empty list.
+func (d *DHCPv4) GetOption(code OptionCode) []Option {
+ opts := []Option{}
+ for _, opt := range d.Options() {
+ if opt.Code() == code {
+ opts = append(opts, opt)
+ }
+ }
+ return opts
+}
+
+// GetOneOption will attempt to get an option that match a Option code.
+// If there are multiple options with the same OptionCode it will only return
+// the first one found. If no matching option is found nil will be returned.
+func (d *DHCPv4) GetOneOption(code OptionCode) Option {
+ for _, opt := range d.Options() {
+ if opt.Code() == code {
+ return opt
+ }
+ }
+ return nil
+}
+
// StrippedOptions works like Options, but it does not return anything after the
// End option.
func (d *DHCPv4) StrippedOptions() []Option {
diff --git a/dhcpv4/dhcpv4_test.go b/dhcpv4/dhcpv4_test.go
index 065b6e0..4e4f7b5 100644
--- a/dhcpv4/dhcpv4_test.go
+++ b/dhcpv4/dhcpv4_test.go
@@ -300,6 +300,28 @@ func TestNewToBytes(t *testing.T) {
require.Equal(t, expected, got)
}
+func TestGetOption(t *testing.T) {
+ d, err := New()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ hostnameOpt := &OptionGeneric{OptionCode: OptionHostName, Data: []byte("darkstar")}
+ bootFileOpt1 := &OptionGeneric{OptionCode: OptionBootfileName, Data: []byte("boot.img")}
+ bootFileOpt2 := &OptionGeneric{OptionCode: OptionBootfileName, Data: []byte("boot2.img")}
+ d.AddOption(hostnameOpt)
+ d.AddOption(bootFileOpt1)
+ d.AddOption(bootFileOpt2)
+
+ require.Equal(t, d.GetOption(OptionHostName), []Option{hostnameOpt})
+ require.Equal(t, d.GetOption(OptionBootfileName), []Option{bootFileOpt1, bootFileOpt2})
+ require.Equal(t, d.GetOption(OptionRouter), []Option{})
+
+ require.Equal(t, d.GetOneOption(OptionHostName), hostnameOpt)
+ require.Equal(t, d.GetOneOption(OptionBootfileName), bootFileOpt1)
+ require.Equal(t, d.GetOneOption(OptionRouter), nil)
+}
+
// TODO
// test broadcast/unicast flags
// test Options setter/getter