summaryrefslogtreecommitdiffhomepage
path: root/dhcpv6/dhcpv6.go
diff options
context:
space:
mode:
Diffstat (limited to 'dhcpv6/dhcpv6.go')
-rw-r--r--dhcpv6/dhcpv6.go83
1 files changed, 83 insertions, 0 deletions
diff --git a/dhcpv6/dhcpv6.go b/dhcpv6/dhcpv6.go
index 0dabca5..adc52c5 100644
--- a/dhcpv6/dhcpv6.go
+++ b/dhcpv6/dhcpv6.go
@@ -1,8 +1,10 @@
package dhcpv6
import (
+ "errors"
"fmt"
"net"
+ "strings"
)
type DHCPv6 interface {
@@ -199,3 +201,84 @@ func EncapsulateRelay(d DHCPv6, mType MessageType, linkAddr, peerAddr net.IP) (D
outer.AddOption(&orm)
return &outer, nil
}
+
+// IsNetboot function takes a DHCPv6 message and returns true if the machine
+// is trying to netboot. It checks if "boot file" is one of the requested
+// options, which is useful for SOLICIT/REQUEST packet types, it also checks
+// if the "boot file" option is included in the packet, which is useful for
+// ADVERTISE/REPLY packet.
+func IsNetboot(msg DHCPv6) bool {
+ if IsOptionRequested(msg, OptionBootfileURL) {
+ return true
+ }
+ if optbf := msg.GetOneOption(OptionBootfileURL); optbf != nil {
+ return true
+ }
+ return false
+}
+
+// IsOptionRequested function takes a DHCPv6 message and an OptionCode, and
+// returns true if that option is within the requested options of the DHCPv6
+// message.
+func IsOptionRequested(msg DHCPv6, requested OptionCode) bool {
+ for _, optoro := range msg.GetOption(OptionORO) {
+ for _, o := range optoro.(*OptRequestedOption).RequestedOptions() {
+ if o == requested {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+// IsUsingUEFI function takes a DHCPv6 message and returns true if
+// the machine trying to netboot is using UEFI of false if it is not.
+func IsUsingUEFI(msg DHCPv6) bool {
+ // RFC 4578 says:
+ // As of the writing of this document, the following pre-boot
+ // architecture types have been requested.
+ // Type Architecture Name
+ // ---- -----------------
+ // 0 Intel x86PC
+ // 1 NEC/PC98
+ // 2 EFI Itanium
+ // 3 DEC Alpha
+ // 4 Arc x86
+ // 5 Intel Lean Client
+ // 6 EFI IA32
+ // 7 EFI BC
+ // 8 EFI Xscale
+ // 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
+ }
+ }
+ if opt := msg.GetOneOption(OptionUserClass); opt != nil {
+ optuc := opt.(*OptUserClass)
+ for _, uc := range optuc.UserClasses {
+ if strings.Contains(string(uc), "EFI") {
+ return true
+ }
+ }
+ }
+ return false
+}
+
+// GetTransactionID returns a transactionID of a message or its inner message
+// in case of relay
+func GetTransactionID(packet DHCPv6) (uint32, error) {
+ if message, ok := packet.(*DHCPv6Message); ok {
+ return message.TransactionID(), nil
+ }
+ if relay, ok := packet.(*DHCPv6Relay); ok {
+ message, err := relay.GetInnerMessage()
+ if err != nil {
+ return 0, err
+ }
+ return GetTransactionID(message)
+ }
+ return 0, errors.New("Invalid DHCPv6 packet")
+}