summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dhcpv6/dhcpv6message.go11
-rw-r--r--dhcpv6/option_archtype.go83
-rw-r--r--dhcpv6/options.go2
3 files changed, 87 insertions, 9 deletions
diff --git a/dhcpv6/dhcpv6message.go b/dhcpv6/dhcpv6message.go
index 8368d6c..cd8ff61 100644
--- a/dhcpv6/dhcpv6message.go
+++ b/dhcpv6/dhcpv6message.go
@@ -152,15 +152,8 @@ func NewRequestFromAdvertise(advertise DHCPv6) (DHCPv6, error) {
},
}
req.AddOption(&nii)
- // add OPTION_CLIENT_ARCH_TYPE
- // TODO implement OptionClientArchType
- cat := OptionGeneric{
- OptionCode: OPTION_CLIENT_ARCH_TYPE,
- OptionData: []byte{
- 0, // Intel - see rfc4578
- 7, // EFI BC
- },
- }
+ cat := OptClientArchType{}
+ cat.SetArchType(EFI_BC)
req.AddOption(&cat)
// add OPTION_VENDOR_CLASS, only if present in the original request
// TODO implement OptionVendorClass
diff --git a/dhcpv6/option_archtype.go b/dhcpv6/option_archtype.go
new file mode 100644
index 0000000..6ed13f8
--- /dev/null
+++ b/dhcpv6/option_archtype.go
@@ -0,0 +1,83 @@
+package dhcpv6
+
+// This module defines the OptClientArchType structure.
+// https://www.ietf.org/rfc/rfc5970.txt
+
+import (
+ "encoding/binary"
+ "fmt"
+)
+
+type ArchType uint16
+
+const (
+ INTEL_X86PC ArchType = iota
+ NEC_PC98
+ EFI_ITANIUM
+ DEC_ALPHA
+ ARC_X86
+ INTEL_LEAN_CLIENT
+ EFI_IA32
+ EFI_BC
+ EFI_XSCALE
+ EFI_X86_64
+)
+
+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",
+}
+
+type OptClientArchType struct {
+ archType ArchType
+}
+
+func (op *OptClientArchType) Code() OptionCode {
+ return OPTION_CLIENT_ARCH_TYPE
+}
+
+func (op *OptClientArchType) ToBytes() []byte {
+ buf := make([]byte, 6)
+ binary.BigEndian.PutUint16(buf[0:2], uint16(OPTION_CLIENT_ARCH_TYPE))
+ binary.BigEndian.PutUint16(buf[2:4], 2)
+ return buf
+}
+
+func (op *OptClientArchType) ArchType() ArchType {
+ return op.archType
+}
+
+func (op *OptClientArchType) SetArchType(archType ArchType) {
+ op.archType = archType
+}
+
+func (op *OptClientArchType) Length() int {
+ return 2
+}
+
+func (op *OptClientArchType) String() string {
+ name, ok := ArchTypeToStringMap[op.archType]
+ if !ok {
+ name = "Unknown"
+ }
+ return fmt.Sprintf("OptClientArchType{archtype=%v}", name)
+}
+
+// build an OptClientArchType structure from a sequence of bytes.
+// The input data does not include option code and 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))
+ }
+ opt.archType = ArchType(binary.BigEndian.Uint16(data))
+ return &opt, nil
+}
diff --git a/dhcpv6/options.go b/dhcpv6/options.go
index 4ac5977..0268d22 100644
--- a/dhcpv6/options.go
+++ b/dhcpv6/options.go
@@ -94,6 +94,8 @@ func ParseOption(dataStart []byte) (Option, error) {
opt, err = ParseOptRemoteId(optData)
case OPTION_INTERFACE_ID:
opt, err = ParseOptInterfaceId(optData)
+ case OPTION_CLIENT_ARCH_TYPE:
+ opt, err = ParseOptClientArchType(optData)
default:
opt = &OptionGeneric{OptionCode: code, OptionData: optData}
}