summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dhcpv6/dhcpv6message.go12
-rw-r--r--dhcpv6/option_archtype.go3
-rw-r--r--dhcpv6/option_nii.go98
-rw-r--r--dhcpv6/options.go2
4 files changed, 106 insertions, 9 deletions
diff --git a/dhcpv6/dhcpv6message.go b/dhcpv6/dhcpv6message.go
index 3b31a5b..db29a44 100644
--- a/dhcpv6/dhcpv6message.go
+++ b/dhcpv6/dhcpv6message.go
@@ -143,14 +143,10 @@ func NewRequestFromAdvertise(advertise DHCPv6) (DHCPv6, error) {
})
req.AddOption(&oro)
// add OPTION_NII
- // TODO implement OptionNetworkInterfaceIdentifier
- nii := OptionGeneric{
- OptionCode: OPTION_NII,
- OptionData: []byte{
- 1, // UNDI - Universal Network Device Interface
- 3, 2, // UNDI rev. 3.2 - second generation EFI runtime driver support, see rfc4578
- },
- }
+ nii := OptNetworkInterfaceId{}
+ nii.SetType(1)
+ nii.SetMajor(3) // UNDI - Universal Network Device Interface
+ nii.SetMinor(2) // UNDI rev. 3.2 - second generation EFI runtime driver support, see rfc457
req.AddOption(&nii)
// add OptClientArchType
cat := OptClientArchType{}
diff --git a/dhcpv6/option_archtype.go b/dhcpv6/option_archtype.go
index b412a5b..71f67ff 100644
--- a/dhcpv6/option_archtype.go
+++ b/dhcpv6/option_archtype.go
@@ -48,7 +48,8 @@ func (op *OptClientArchType) Code() OptionCode {
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)
+ binary.BigEndian.PutUint16(buf[2:4], uint16(op.Length()))
+ binary.BigEndian.PutUint16(buf[4:6], uint16(op.archType))
return buf
}
diff --git a/dhcpv6/option_nii.go b/dhcpv6/option_nii.go
new file mode 100644
index 0000000..1df1579
--- /dev/null
+++ b/dhcpv6/option_nii.go
@@ -0,0 +1,98 @@
+package dhcpv6
+
+// This module defines the OptNetworkInterfaceId structure.
+// https://www.ietf.org/rfc/rfc5970.txt
+
+import (
+ "encoding/binary"
+ "fmt"
+)
+
+// see rfc4578
+const (
+ NII_LANDESK_NOPXE = iota
+ NII_PXE_GEN_I
+ NII_PXE_GEN_II
+ NII_UNDI_NOEFI
+ NII_UNDI_EFI_GEN_I
+ NII_UNDI_EFI_GEN_II
+)
+
+var NIIToStringMap = map[uint8]string{
+ NII_LANDESK_NOPXE: "LANDesk service agent boot ROMs. No PXE",
+ NII_PXE_GEN_I: "First gen. PXE boot ROMs",
+ NII_PXE_GEN_II: "Second gen. PXE boot ROMs",
+ NII_UNDI_NOEFI: "UNDI 32/64 bit. UEFI drivers, no UEFI runtime",
+ NII_UNDI_EFI_GEN_I: "UNDI 32/64 bit. UEFI runtime 1st gen",
+ NII_UNDI_EFI_GEN_II: "UNDI 32/64 bit. UEFI runtime 2nd gen",
+}
+
+type OptNetworkInterfaceId struct {
+ type_ uint8
+ major, minor uint8 // revision number
+}
+
+func (op *OptNetworkInterfaceId) Code() OptionCode {
+ return OPTION_NII
+}
+
+func (op *OptNetworkInterfaceId) ToBytes() []byte {
+ buf := make([]byte, 7)
+ binary.BigEndian.PutUint16(buf[0:2], uint16(OPTION_NII))
+ binary.BigEndian.PutUint16(buf[2:5], uint16(op.Length()))
+ buf[5] = op.type_
+ buf[6] = op.major
+ buf[7] = op.minor
+ return buf
+}
+
+func (op *OptNetworkInterfaceId) Type() uint8 {
+ return op.type_
+}
+
+func (op *OptNetworkInterfaceId) SetType(type_ uint8) {
+ op.type_ = type_
+}
+
+func (op *OptNetworkInterfaceId) Major() uint8 {
+ return op.major
+}
+
+func (op *OptNetworkInterfaceId) SetMajor(major uint8) {
+ op.major = major
+}
+
+func (op *OptNetworkInterfaceId) Minor() uint8 {
+ return op.minor
+}
+
+func (op *OptNetworkInterfaceId) SetMinor(minor uint8) {
+ op.minor = minor
+}
+
+func (op *OptNetworkInterfaceId) Length() int {
+ return 3
+}
+
+func (op *OptNetworkInterfaceId) String() string {
+ typeName, ok := NIIToStringMap[op.type_]
+ if !ok {
+ typeName = "Unknown"
+ }
+ return fmt.Sprintf("OptNetworkInterfaceId{type=%v, revision=%v.%v}",
+ typeName, op.major, op.minor,
+ )
+}
+
+// build an OptNetworkInterfaceId structure from a sequence of bytes.
+// The input data does not include option code and length bytes.
+func ParseOptNetworkInterfaceId(data []byte) (*OptNetworkInterfaceId, error) {
+ opt := OptNetworkInterfaceId{}
+ if len(data) != 3 {
+ return nil, fmt.Errorf("Invalid arch type data length. Expected 3 bytes, got %v", len(data))
+ }
+ opt.type_ = data[0]
+ opt.major = data[1]
+ opt.minor = data[2]
+ return &opt, nil
+}
diff --git a/dhcpv6/options.go b/dhcpv6/options.go
index 0268d22..3bca963 100644
--- a/dhcpv6/options.go
+++ b/dhcpv6/options.go
@@ -96,6 +96,8 @@ func ParseOption(dataStart []byte) (Option, error) {
opt, err = ParseOptInterfaceId(optData)
case OPTION_CLIENT_ARCH_TYPE:
opt, err = ParseOptClientArchType(optData)
+ case OPTION_NII:
+ opt, err = ParseOptNetworkInterfaceId(optData)
default:
opt = &OptionGeneric{OptionCode: code, OptionData: optData}
}