diff --git a/dhcpv4/dhcpv4.go b/dhcpv4/dhcpv4.go index 1d8ddef1..0bfea480 100644 --- a/dhcpv4/dhcpv4.go +++ b/dhcpv4/dhcpv4.go @@ -262,7 +262,11 @@ func NewReplyFromRequest(request *DHCPv4, modifiers ...Modifier) (*DHCPv4, error return New(PrependModifiers(modifiers, WithReply(request), WithGatewayIP(request.GatewayIPAddr), - WithRelayAgentInfo(request), + WithOptionCopied(request, OptionRelayAgentInformation), + + // RFC 6842 states the Client Identifier option must be copied + // from the request if a client specified it. + WithOptionCopied(request, OptionClientIdentifier), )...) } diff --git a/dhcpv4/modifiers.go b/dhcpv4/modifiers.go index 2bf79b83..0ab35bc5 100644 --- a/dhcpv4/modifiers.go +++ b/dhcpv4/modifiers.go @@ -43,18 +43,16 @@ func WithGatewayIP(ip net.IP) Modifier { } } -// WithRelayAgentInfo copies the relay options from the request to the reply. -func WithRelayAgentInfo(request *DHCPv4) Modifier { +// WithOptionCopied copies the value of option opt from request. +func WithOptionCopied(request *DHCPv4, opt OptionCode) Modifier { return func(d *DHCPv4) { - // If request has Relay Agent Info copy it to the reply - if relayOpt := request.RelayAgentInfo(); relayOpt != nil { - d.UpdateOption(Option{Code: OptionRelayAgentInformation, Value: relayOpt}) + if val := request.Options.Get(opt); val != nil { + d.UpdateOption(OptGeneric(opt, val)) } } } -// WithReply fills in opcode, hwtype, xid, clienthwaddr, flags, and gateway ip -// addr from the given packet. +// WithReply fills in opcode, hwtype, xid, clienthwaddr, and flags from the given packet. func WithReply(request *DHCPv4) Modifier { return func(d *DHCPv4) { if request.OpCode == OpcodeBootRequest { diff --git a/dhcpv4/option_misc.go b/dhcpv4/option_misc.go index 01de95f7..e91b34d8 100644 --- a/dhcpv4/option_misc.go +++ b/dhcpv4/option_misc.go @@ -16,3 +16,8 @@ func OptDomainSearch(labels *rfc1035label.Labels) Option { func OptClientArch(archs ...iana.Arch) Option { return Option{Code: OptionClientSystemArchitectureType, Value: iana.Archs(archs)} } + +// OptClientIdentifier returns a new Client Identifier option. +func OptClientIdentifier(ident []byte) Option { + return OptGeneric(OptionClientIdentifier, ident) +}