summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChris Koch <chrisko@google.com>2019-12-28 09:49:06 -0800
committerinsomniac <insomniacslk@users.noreply.github.com>2020-03-05 15:51:55 +0000
commit72e14d6762cd895f00fd5c04fec8a16df521b65f (patch)
treef7238d1821e2c6070ebf5e611808964e1b77c08a
parentbb0c09a3da430db48a7bd0749b7d5411649e1026 (diff)
v6: add BootFileParam getter
Signed-off-by: Chris Koch <chrisko@google.com>
-rw-r--r--dhcpv6/dhcpv6message.go12
-rw-r--r--dhcpv6/option_bootfileparam.go27
-rw-r--r--dhcpv6/option_bootfileparam_test.go8
-rw-r--r--dhcpv6/options.go2
-rw-r--r--netboot/netboot.go10
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
}