summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dhcpv4/option_archtype.go42
-rw-r--r--dhcpv4/option_archtype_test.go9
-rw-r--r--dhcpv6/dhcpv6.go10
-rw-r--r--dhcpv6/dhcpv6_test.go4
-rw-r--r--dhcpv6/modifiers.go6
-rw-r--r--dhcpv6/option_archtype.go62
-rw-r--r--dhcpv6/option_archtype_test.go5
-rw-r--r--iana/archtype.go41
8 files changed, 88 insertions, 91 deletions
diff --git a/dhcpv4/option_archtype.go b/dhcpv4/option_archtype.go
index 16ca98d..8eafc55 100644
--- a/dhcpv4/option_archtype.go
+++ b/dhcpv4/option_archtype.go
@@ -6,43 +6,14 @@ package dhcpv4
import (
"encoding/binary"
"fmt"
-)
-
-//ArchType encodes an architecture type in an uint16
-type ArchType uint16
-// see rfc4578
-const (
- INTEL_X86PC ArchType = 0
- NEC_PC98 ArchType = 1
- EFI_ITANIUM ArchType = 2
- DEC_ALPHA ArchType = 3
- ARC_X86 ArchType = 4
- INTEL_LEAN_CLIENT ArchType = 5
- EFI_IA32 ArchType = 6
- EFI_BC ArchType = 7
- EFI_XSCALE ArchType = 8
- EFI_X86_64 ArchType = 9
+ "github.com/insomniacslk/dhcp/iana"
)
-// ArchTypeToStringMap maps an ArchType to a mnemonic name
-var ArchTypeToStringMap = map[ArchType]string{
- INTEL_X86PC: "Intel x86PC",
- NEC_PC98: "NEC/PC98",
- EFI_ITANIUM: "EFI Itanium",
- DEC_ALPHA: "DEC Alpha",
- ARC_X86: "Arc x86",
- INTEL_LEAN_CLIENT: "Intel Lean Client",
- EFI_IA32: "EFI IA32",
- EFI_BC: "EFI BC",
- EFI_XSCALE: "EFI Xscale",
- EFI_X86_64: "EFI x86-64",
-}
-
// OptClientArchType represents an option encapsulating the Client System
// Architecture Type option Definition.
type OptClientArchType struct {
- ArchTypes []ArchType
+ ArchTypes []iana.ArchType
}
// Code returns the option code.
@@ -71,10 +42,7 @@ func (o *OptClientArchType) Length() int {
func (o *OptClientArchType) String() string {
var archTypes string
for idx, at := range o.ArchTypes {
- name, ok := ArchTypeToStringMap[at]
- if !ok {
- name = "Unknown"
- }
+ name := iana.ArchTypeToString(at)
archTypes += name
if idx < len(o.ArchTypes)-1 {
archTypes += ", "
@@ -100,10 +68,10 @@ func ParseOptClientArchType(data []byte) (*OptClientArchType, error) {
if len(data) < 2+length {
return nil, ErrShortByteStream
}
- archTypes := make([]ArchType, 0, length%2)
+ archTypes := make([]iana.ArchType, 0, length%2)
for idx := 0; idx < length; idx += 2 {
b := data[2+idx : 2+idx+2]
- archTypes = append(archTypes, ArchType(binary.BigEndian.Uint16(b)))
+ archTypes = append(archTypes, iana.ArchType(binary.BigEndian.Uint16(b)))
}
return &OptClientArchType{ArchTypes: archTypes}, nil
}
diff --git a/dhcpv4/option_archtype_test.go b/dhcpv4/option_archtype_test.go
index cb9bc3f..d803328 100644
--- a/dhcpv4/option_archtype_test.go
+++ b/dhcpv4/option_archtype_test.go
@@ -3,6 +3,7 @@ package dhcpv4
import (
"testing"
+ "github.com/insomniacslk/dhcp/iana"
"github.com/stretchr/testify/require"
)
@@ -14,7 +15,7 @@ func TestParseOptClientArchType(t *testing.T) {
}
opt, err := ParseOptClientArchType(data)
require.NoError(t, err)
- require.Equal(t, opt.ArchTypes[0], EFI_IA32)
+ require.Equal(t, opt.ArchTypes[0], iana.EFI_IA32)
}
func TestParseOptClientArchTypeMultiple(t *testing.T) {
@@ -26,8 +27,8 @@ func TestParseOptClientArchTypeMultiple(t *testing.T) {
}
opt, err := ParseOptClientArchType(data)
require.NoError(t, err)
- require.Equal(t, opt.ArchTypes[0], EFI_IA32)
- require.Equal(t, opt.ArchTypes[1], EFI_ITANIUM)
+ require.Equal(t, opt.ArchTypes[0], iana.EFI_IA32)
+ require.Equal(t, opt.ArchTypes[1], iana.EFI_ITANIUM)
}
func TestParseOptClientArchTypeInvalid(t *testing.T) {
@@ -61,7 +62,7 @@ func TestOptClientArchTypeParseAndToBytesMultiple(t *testing.T) {
func TestOptClientArchType(t *testing.T) {
opt := OptClientArchType{
- ArchTypes: []ArchType{EFI_ITANIUM},
+ ArchTypes: []iana.ArchType{iana.EFI_ITANIUM},
}
require.Equal(t, opt.Length(), 2)
require.Equal(t, opt.Code(), OptionClientSystemArchitectureType)
diff --git a/dhcpv6/dhcpv6.go b/dhcpv6/dhcpv6.go
index d82ed4a..9382334 100644
--- a/dhcpv6/dhcpv6.go
+++ b/dhcpv6/dhcpv6.go
@@ -5,6 +5,8 @@ import (
"fmt"
"net"
"strings"
+
+ "github.com/insomniacslk/dhcp/iana"
)
type DHCPv6 interface {
@@ -222,9 +224,11 @@ func IsUsingUEFI(msg DHCPv6) bool {
// 9 EFI x86-64
if opt := msg.GetOneOption(OptionClientArchType); opt != nil {
optat := opt.(*OptClientArchType)
- // TODO investigate if other types are appropriate
- if optat.ArchType == EFI_BC || optat.ArchType == EFI_X86_64 {
- return true
+ for _, at := range optat.ArchTypes {
+ // TODO investigate if other types are appropriate
+ if at == iana.EFI_BC || at == iana.EFI_X86_64 {
+ return true
+ }
}
}
if opt := msg.GetOneOption(OptionUserClass); opt != nil {
diff --git a/dhcpv6/dhcpv6_test.go b/dhcpv6/dhcpv6_test.go
index 812d284..6840252 100644
--- a/dhcpv6/dhcpv6_test.go
+++ b/dhcpv6/dhcpv6_test.go
@@ -218,14 +218,14 @@ func TestNewMessageTypeSolicitWithCID(t *testing.T) {
func TestIsUsingUEFIArchTypeTrue(t *testing.T) {
msg := DHCPv6Message{}
- opt := OptClientArchType{ArchType: EFI_BC}
+ opt := OptClientArchType{ArchTypes: []iana.ArchType{iana.EFI_BC}}
msg.AddOption(&opt)
require.True(t, IsUsingUEFI(&msg))
}
func TestIsUsingUEFIArchTypeFalse(t *testing.T) {
msg := DHCPv6Message{}
- opt := OptClientArchType{ArchType: INTEL_X86PC}
+ opt := OptClientArchType{ArchTypes: []iana.ArchType{iana.INTEL_X86PC}}
msg.AddOption(&opt)
require.False(t, IsUsingUEFI(&msg))
}
diff --git a/dhcpv6/modifiers.go b/dhcpv6/modifiers.go
index 32d11ac..6cd66db 100644
--- a/dhcpv6/modifiers.go
+++ b/dhcpv6/modifiers.go
@@ -2,6 +2,8 @@ package dhcpv6
import (
"log"
+
+ "github.com/insomniacslk/dhcp/iana"
)
// WithClientID adds a client ID option to a DHCPv6 packet
@@ -53,9 +55,9 @@ func WithUserClass(uc []byte) Modifier {
}
// WithArchType adds an arch type option to the packet
-func WithArchType(at ArchType) Modifier {
+func WithArchType(at iana.ArchType) Modifier {
return func(d DHCPv6) DHCPv6 {
- ao := OptClientArchType{ArchType: at}
+ ao := OptClientArchType{ArchTypes: []iana.ArchType{at}}
d.AddOption(&ao)
return d
}
diff --git a/dhcpv6/option_archtype.go b/dhcpv6/option_archtype.go
index a1b4a9b..231eddd 100644
--- a/dhcpv6/option_archtype.go
+++ b/dhcpv6/option_archtype.go
@@ -6,42 +6,14 @@ package dhcpv6
import (
"encoding/binary"
"fmt"
-)
-
-//ArchType encodes an architecture type in an uint16
-type ArchType uint16
+ "strings"
-// see rfc4578
-const (
- INTEL_X86PC ArchType = 0
- NEC_PC98 ArchType = 1
- EFI_ITANIUM ArchType = 2
- DEC_ALPHA ArchType = 3
- ARC_X86 ArchType = 4
- INTEL_LEAN_CLIENT ArchType = 5
- EFI_IA32 ArchType = 6
- EFI_BC ArchType = 7
- EFI_XSCALE ArchType = 8
- EFI_X86_64 ArchType = 9
+ "github.com/insomniacslk/dhcp/iana"
)
-// ArchTypeToStringMap maps an ArchType to a mnemonic name
-var ArchTypeToStringMap = map[ArchType]string{
- INTEL_X86PC: "Intel x86PC",
- NEC_PC98: "NEC/PC98",
- EFI_ITANIUM: "EFI Itanium",
- DEC_ALPHA: "DEC Alpha",
- ARC_X86: "Arc x86",
- INTEL_LEAN_CLIENT: "Intel Lean Client",
- EFI_IA32: "EFI IA32",
- EFI_BC: "EFI BC",
- EFI_XSCALE: "EFI Xscale",
- EFI_X86_64: "EFI x86-64",
-}
-
// OptClientArchType represents an option CLIENT_ARCH_TYPE
type OptClientArchType struct {
- ArchType ArchType
+ ArchTypes []iana.ArchType
}
func (op *OptClientArchType) Code() OptionCode {
@@ -49,23 +21,28 @@ func (op *OptClientArchType) Code() OptionCode {
}
func (op *OptClientArchType) ToBytes() []byte {
- buf := make([]byte, 6)
+ buf := make([]byte, 4)
binary.BigEndian.PutUint16(buf[0:2], uint16(OptionClientArchType))
binary.BigEndian.PutUint16(buf[2:4], uint16(op.Length()))
- binary.BigEndian.PutUint16(buf[4:6], uint16(op.ArchType))
+ u16 := make([]byte, 2)
+ for _, at := range op.ArchTypes {
+ binary.BigEndian.PutUint16(u16, uint16(at))
+ buf = append(buf, u16...)
+ }
return buf
}
func (op *OptClientArchType) Length() int {
- return 2
+ return 2*len(op.ArchTypes)
}
func (op *OptClientArchType) String() string {
- name, ok := ArchTypeToStringMap[op.ArchType]
- if !ok {
- name = "Unknown"
+ atStrings := make([]string, 0)
+ for _, at := range op.ArchTypes {
+ name := iana.ArchTypeToString(at)
+ atStrings = append(atStrings, name)
}
- return fmt.Sprintf("OptClientArchType{archtype=%v}", name)
+ return fmt.Sprintf("OptClientArchType{archtype=%v}", strings.Join(atStrings, ", "))
}
// ParseOptClientArchType builds an OptClientArchType structure from
@@ -73,9 +50,12 @@ func (op *OptClientArchType) String() string {
// length bytes.
func ParseOptClientArchType(data []byte) (*OptClientArchType, error) {
opt := OptClientArchType{}
- if len(data) != 2 {
- return nil, fmt.Errorf("Invalid arch type data length. Expected 2 bytes, got %v", len(data))
+ if len(data) == 0 || len(data)%2 != 0 {
+ return nil, fmt.Errorf("Invalid arch type data length. Expected multiple of 2 larger than 2, got %v", len(data))
+ }
+ for idx := 0; idx < len(data); idx += 2 {
+ b := data[idx : idx+2]
+ opt.ArchTypes = append(opt.ArchTypes, iana.ArchType(binary.BigEndian.Uint16(b)))
}
- opt.ArchType = ArchType(binary.BigEndian.Uint16(data))
return &opt, nil
}
diff --git a/dhcpv6/option_archtype_test.go b/dhcpv6/option_archtype_test.go
index 748c8c5..1848e55 100644
--- a/dhcpv6/option_archtype_test.go
+++ b/dhcpv6/option_archtype_test.go
@@ -3,6 +3,7 @@ package dhcpv6
import (
"testing"
+ "github.com/insomniacslk/dhcp/iana"
"github.com/stretchr/testify/require"
)
@@ -12,7 +13,7 @@ func TestParseOptClientArchType(t *testing.T) {
}
opt, err := ParseOptClientArchType(data)
require.NoError(t, err)
- require.Equal(t, opt.ArchType, EFI_IA32)
+ require.Equal(t, opt.ArchTypes[0], iana.EFI_IA32)
}
func TestParseOptClientArchTypeInvalid(t *testing.T) {
@@ -37,7 +38,7 @@ func TestOptClientArchTypeParseAndToBytes(t *testing.T) {
func TestOptClientArchType(t *testing.T) {
opt := OptClientArchType{
- ArchType: EFI_ITANIUM,
+ ArchTypes: []iana.ArchType{iana.EFI_ITANIUM},
}
require.Equal(t, opt.Length(), 2)
require.Equal(t, opt.Code(), OptionClientArchType)
diff --git a/iana/archtype.go b/iana/archtype.go
new file mode 100644
index 0000000..6b2cc9e
--- /dev/null
+++ b/iana/archtype.go
@@ -0,0 +1,41 @@
+package iana
+
+//ArchType encodes an architecture type in an uint16
+type ArchType uint16
+
+// see rfc4578
+const (
+ INTEL_X86PC ArchType = 0
+ NEC_PC98 ArchType = 1
+ EFI_ITANIUM ArchType = 2
+ DEC_ALPHA ArchType = 3
+ ARC_X86 ArchType = 4
+ INTEL_LEAN_CLIENT ArchType = 5
+ EFI_IA32 ArchType = 6
+ EFI_BC ArchType = 7
+ EFI_XSCALE ArchType = 8
+ EFI_X86_64 ArchType = 9
+)
+
+// ArchTypeToStringMap maps an ArchType to a mnemonic name
+var ArchTypeToStringMap = map[ArchType]string{
+ INTEL_X86PC: "Intel x86PC",
+ NEC_PC98: "NEC/PC98",
+ EFI_ITANIUM: "EFI Itanium",
+ DEC_ALPHA: "DEC Alpha",
+ ARC_X86: "Arc x86",
+ INTEL_LEAN_CLIENT: "Intel Lean Client",
+ EFI_IA32: "EFI IA32",
+ EFI_BC: "EFI BC",
+ EFI_XSCALE: "EFI Xscale",
+ EFI_X86_64: "EFI x86-64",
+}
+
+
+// ArchTypeToString returns a mnemonic name for a given architecture type
+func ArchTypeToString(a ArchType) string {
+ if at := ArchTypeToStringMap[a]; at != "" {
+ return at
+ }
+ return "Unknown"
+}