diff options
author | Chris Koch <chrisko@google.com> | 2019-12-28 09:49:06 -0800 |
---|---|---|
committer | insomniac <insomniacslk@users.noreply.github.com> | 2020-03-05 15:51:55 +0000 |
commit | 72e14d6762cd895f00fd5c04fec8a16df521b65f (patch) | |
tree | f7238d1821e2c6070ebf5e611808964e1b77c08a | |
parent | bb0c09a3da430db48a7bd0749b7d5411649e1026 (diff) |
v6: add BootFileParam getter
Signed-off-by: Chris Koch <chrisko@google.com>
-rw-r--r-- | dhcpv6/dhcpv6message.go | 12 | ||||
-rw-r--r-- | dhcpv6/option_bootfileparam.go | 27 | ||||
-rw-r--r-- | dhcpv6/option_bootfileparam_test.go | 8 | ||||
-rw-r--r-- | dhcpv6/options.go | 2 | ||||
-rw-r--r-- | netboot/netboot.go | 10 |
5 files changed, 34 insertions, 25 deletions
diff --git a/dhcpv6/dhcpv6message.go b/dhcpv6/dhcpv6message.go index 4e5717f..745a837 100644 --- a/dhcpv6/dhcpv6message.go +++ b/dhcpv6/dhcpv6message.go @@ -116,6 +116,18 @@ func (mo MessageOptions) BootFileURL() string { return "" } +// BootFileParam returns the Boot File Param option as defined by RFC 5970. +func (mo MessageOptions) BootFileParam() []string { + opt := mo.Options.GetOne(OptionBootfileParam) + if opt == nil { + return nil + } + if u, ok := opt.(optBootFileParam); ok { + return []string(u) + } + return nil +} + // ElapsedTime returns the Elapsed Time option as defined by RFC 3315 Section 22.9. // // ElapsedTime returns a duration of 0 if the option is not present. diff --git a/dhcpv6/option_bootfileparam.go b/dhcpv6/option_bootfileparam.go index 13ec16a..4e2750b 100644 --- a/dhcpv6/option_bootfileparam.go +++ b/dhcpv6/option_bootfileparam.go @@ -6,21 +6,21 @@ import ( "github.com/u-root/u-root/pkg/uio" ) -// OptBootFileParam implements the OptionBootfileParam option -// -// This module defines the OPT_BOOTFILE_PARAM structure. -// https://www.ietf.org/rfc/rfc5970.txt (section 3.2) -type OptBootFileParam []string +// OptBootFileParam returns a BootfileParam option as defined in RFC 5970 +// Section 3.2. +func OptBootFileParam(args ...string) Option { + return optBootFileParam(args) +} -var _ Option = OptBootFileParam(nil) +type optBootFileParam []string // Code returns the option code -func (op OptBootFileParam) Code() OptionCode { +func (optBootFileParam) Code() OptionCode { return OptionBootfileParam } // ToBytes serializes the option and returns it as a sequence of bytes -func (op OptBootFileParam) ToBytes() []byte { +func (op optBootFileParam) ToBytes() []byte { buf := uio.NewBigEndianBuffer(nil) for _, param := range op { if len(param) >= 1<<16 { @@ -41,14 +41,15 @@ func (op OptBootFileParam) ToBytes() []byte { return buf.Data() } -func (op OptBootFileParam) String() string { - return fmt.Sprintf("OptBootFileParam(%v)", ([]string)(op)) +func (op optBootFileParam) String() string { + return fmt.Sprintf("BootFileParam: %v", ([]string)(op)) } -// ParseOptBootFileParam builds an OptBootFileParam structure from a sequence +// parseOptBootFileParam builds an OptBootFileParam structure from a sequence // of bytes. The input data does not include option code and length bytes. -func ParseOptBootFileParam(data []byte) (result OptBootFileParam, err error) { +func parseOptBootFileParam(data []byte) (optBootFileParam, error) { buf := uio.NewBigEndianBuffer(data) + var result optBootFileParam for buf.Has(2) { length := buf.Read16() result = append(result, string(buf.CopyN(int(length)))) @@ -56,5 +57,5 @@ func ParseOptBootFileParam(data []byte) (result OptBootFileParam, err error) { if err := buf.FinError(); err != nil { return nil, err } - return + return result, nil } diff --git a/dhcpv6/option_bootfileparam_test.go b/dhcpv6/option_bootfileparam_test.go index 80a4386..467f245 100644 --- a/dhcpv6/option_bootfileparam_test.go +++ b/dhcpv6/option_bootfileparam_test.go @@ -11,13 +11,13 @@ import ( var ( testBootfileParams0Compiled = "\x00\x0eroot=/dev/sda1\x00\x00\x00\x02rw" - testBootfileParams1 = []string{ + testBootfileParams1 = []string{ "initrd=http://myserver.mycompany.local/initrd.xz", "", "root=/dev/sda1", "rw", "netconsole=..:\000:.something\000here.::..", - string(make([]byte, (1<<16) - 1)), + string(make([]byte, (1<<16)-1)), } ) @@ -41,7 +41,7 @@ func compileTestBootfileParams(t *testing.T, params []string) []byte { func TestOptBootFileParam(t *testing.T) { expected := string(compileTestBootfileParams(t, testBootfileParams1)) - opt, err := ParseOptBootFileParam([]byte(expected)) + opt, err := parseOptBootFileParam([]byte(expected)) if err != nil { t.Fatal(err) } @@ -54,7 +54,7 @@ func TestParsedTypeOptBootFileParam(t *testing.T) { tryParse := func(compiled []byte, expected []string) { opt, err := ParseOption(OptionBootfileParam, compiled) require.NoError(t, err) - bootfileParamOpt, ok := opt.(OptBootFileParam) + bootfileParamOpt, ok := opt.(optBootFileParam) require.True(t, ok, fmt.Sprintf("invalid type: %T instead of %T", opt, bootfileParamOpt)) require.Equal(t, compiled, bootfileParamOpt.ToBytes()) require.Equal(t, expected, ([]string)(bootfileParamOpt)) diff --git a/dhcpv6/options.go b/dhcpv6/options.go index 63261c1..23a0ba9 100644 --- a/dhcpv6/options.go +++ b/dhcpv6/options.go @@ -80,7 +80,7 @@ func ParseOption(code OptionCode, optData []byte) (Option, error) { case OptionBootfileURL: opt, err = parseOptBootFileURL(optData) case OptionBootfileParam: - opt, err = ParseOptBootFileParam(optData) + opt, err = parseOptBootFileParam(optData) case OptionClientArchType: opt, err = parseOptClientArchType(optData) case OptionNII: diff --git a/netboot/netboot.go b/netboot/netboot.go index 4e1603c..b32f69e 100644 --- a/netboot/netboot.go +++ b/netboot/netboot.go @@ -96,7 +96,7 @@ func RequestNetbootv4(ifname string, timeout time.Duration, retries int, modifie // ConversationToNetconf extracts network configuration and boot file URL from a // DHCPv6 4-way conversation and returns them, or an error if any. func ConversationToNetconf(conversation []dhcpv6.DHCPv6) (*BootConf, error) { - var advertise, reply, optionsSource *dhcpv6.Message + var advertise, reply *dhcpv6.Message for _, m := range conversation { switch m.Type() { case dhcpv6.MessageTypeAdvertise: @@ -118,21 +118,17 @@ func ConversationToNetconf(conversation []dhcpv6.DHCPv6) (*BootConf, error) { if u := reply.Options.BootFileURL(); len(u) > 0 { bootconf.BootfileURL = u - optionsSource = reply + bootconf.BootfileParam = reply.Options.BootFileParam() } else { log.Printf("no bootfile URL option found in REPLY, fallback to ADVERTISE's value") if u := advertise.Options.BootFileURL(); len(u) > 0 { bootconf.BootfileURL = u - optionsSource = advertise + bootconf.BootfileParam = advertise.Options.BootFileParam() } } if len(bootconf.BootfileURL) == 0 { return nil, errors.New("no bootfile URL option found") } - - if bootfileParamOption := optionsSource.GetOneOption(dhcpv6.OptionBootfileParam); bootfileParamOption != nil { - bootconf.BootfileParam = bootfileParamOption.(dhcpv6.OptBootFileParam) - } return bootconf, nil } |