From 0ef7af55f53d22f97650f2d4a299567977da57fb Mon Sep 17 00:00:00 2001 From: Chris Koch Date: Fri, 6 Mar 2020 23:15:00 -0800 Subject: dhcp6: fix VendorOpts getter RFC 8415 Section 21.17 states it may appear more than once: Multiple instances of the Vendor-specific Information option may appear in a DHCP message. Each instance of the option is interpreted according to the option codes defined by the vendor identified by the Enterprise Number in that option. Servers and clients MUST NOT send more than one instance of the Vendor-specific Information option with the same Enterprise Number. Signed-off-by: Chris Koch --- dhcpv6/dhcpv6message.go | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/dhcpv6/dhcpv6message.go b/dhcpv6/dhcpv6message.go index 76404f2..0927038 100644 --- a/dhcpv6/dhcpv6message.go +++ b/dhcpv6/dhcpv6message.go @@ -179,16 +179,40 @@ func (mo MessageOptions) UserClasses() [][]byte { return nil } -// VendorOpts returns the enterprise number and a list of vendor options. -func (mo MessageOptions) VendorOpts() (uint32, Options) { - opt := mo.Options.GetOne(OptionVendorOpts) +// VendorOpts returns the all vendor-specific options. +// +// RFC 8415 Section 21.17: +// +// Multiple instances of the Vendor-specific Information option may appear in +// a DHCP message. +func (mo MessageOptions) VendorOpts() []*OptVendorOpts { + opt := mo.Options.Get(OptionVendorOpts) if opt == nil { - return 0, nil + return nil + } + var vo []*OptVendorOpts + for _, o := range opt { + if t, ok := o.(*OptVendorOpts); ok { + vo = append(vo, t) + } } - if t, ok := opt.(*OptVendorOpts); ok { - return t.EnterpriseNumber, t.VendorOpts + return vo +} + +// VendorOpt returns the vendor options matching the given enterprise number. +// +// RFC 8415 Section 21.17: +// +// Servers and clients MUST NOT send more than one instance of the +// Vendor-specific Information option with the same Enterprise Number. +func (mo MessageOptions) VendorOpt(enterpriseNumber uint32) Options { + vo := mo.VendorOpts() + for _, v := range vo { + if v.EnterpriseNumber == enterpriseNumber { + return v.VendorOpts + } } - return 0, nil + return nil } // ElapsedTime returns the Elapsed Time option as defined by RFC 3315 Section 22.9. -- cgit v1.2.3