diff --git a/go.mod b/go.mod index f53ddddb6a0..3331c9b3225 100644 --- a/go.mod +++ b/go.mod @@ -41,6 +41,8 @@ require ( howett.net/plist v1.0.1 ) +require github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 + require ( github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect github.com/aead/poly1305 v0.0.0-20180717145839-3fee0db0b635 // indirect @@ -56,7 +58,6 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/quic-go/qpack v0.4.0 // indirect - github.com/u-root/uio v0.0.0-20240224005618-d2acac8f3701 // indirect go.uber.org/mock v0.4.0 // indirect golang.org/x/mod v0.18.0 // indirect golang.org/x/sync v0.7.0 // indirect diff --git a/internal/dhcpd/v4_unix.go b/internal/dhcpd/v4_unix.go index 5333390b8ce..8c980746b04 100644 --- a/internal/dhcpd/v4_unix.go +++ b/internal/dhcpd/v4_unix.go @@ -21,6 +21,8 @@ import ( "github.com/go-ping/ping" "github.com/insomniacslk/dhcp/dhcpv4" "github.com/insomniacslk/dhcp/dhcpv4/server4" + "github.com/u-root/uio/uio" + "golang.org/x/exp/slices" ) // v4Server is a DHCPv4 server. @@ -1280,6 +1282,23 @@ func (s *v4Server) packetHandler(conn net.PacketConn, peer net.Addr, req *dhcpv4 return } + if opt := req.Options.Get(dhcpv4.OptionClientIdentifier); opt != nil { + buf := uio.NewBigEndianBuffer(opt) + hdType := buf.Read8() + // refer: https://github.com/wireshark/wireshark/blob/c3cc0e5fa7123f3d493c6a61b8919eac2973000f/epan/dissectors/packet-dhcp.c#L2306 + // The code for this option is 61, and its minimum length is 2. + // + // Code Len Type Client-Identifier + // +-----+-----+-----+-----+-----+--- + // | 61 | n | t1 | i1 | i2 | ... + // +-----+-----+-----+-----+-----+--- + // A hardware type of 0 (zero) should be used when the value field + // contains an identifier other than a hardware address + // mac address length plus type field equal seven + if hdType > 0 && len(opt) == 7 { + buf.ReadBytes(req.ClientHWAddr) + } + } err = netutil.ValidateMAC(req.ClientHWAddr) if err != nil {