diff options
Diffstat (limited to 'dhcpv4/option_router.go')
-rw-r--r-- | dhcpv4/option_router.go | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/dhcpv4/option_router.go b/dhcpv4/option_router.go index 3154edd..60a96d1 100644 --- a/dhcpv4/option_router.go +++ b/dhcpv4/option_router.go @@ -3,6 +3,8 @@ package dhcpv4 import ( "fmt" "net" + + "github.com/u-root/u-root/pkg/uio" ) // This option implements the router option @@ -13,28 +15,30 @@ type OptRouter struct { Routers []net.IP } -// ParseOptRouter returns a new OptRouter from a byte stream, or error if any. -func ParseOptRouter(data []byte) (*OptRouter, error) { - if len(data) < 2 { - return nil, ErrShortByteStream - } - code := OptionCode(data[0]) - if code != OptionRouter { - return nil, fmt.Errorf("expected code %v, got %v", OptionRouter, code) - } - length := int(data[1]) - if length == 0 || length%4 != 0 { - return nil, fmt.Errorf("Invalid length: expected multiple of 4 larger than 4, got %v", length) +// ParseIPs parses an IPv4 address from a DHCP packet as used and specified by +// options in RFC 2132, Sections 3.5 through 3.13, 8.2, 8.3, 8.5, 8.6, 8.9, and +// 8.10. +func ParseIPs(data []byte) ([]net.IP, error) { + buf := uio.NewBigEndianBuffer(data) + + if buf.Len() == 0 { + return nil, fmt.Errorf("IP DHCP options must always list at least one IP") } - if len(data) < 2+length { - return nil, ErrShortByteStream + + ips := make([]net.IP, 0, buf.Len()/net.IPv4len) + for buf.Has(net.IPv4len) { + ips = append(ips, net.IP(buf.CopyN(net.IPv4len))) } - routers := make([]net.IP, 0, length%4) - for idx := 0; idx < length; idx += 4 { - b := data[2+idx : 2+idx+4] - routers = append(routers, net.IPv4(b[0], b[1], b[2], b[3])) + return ips, buf.FinError() +} + +// ParseOptRouter returns a new OptRouter from a byte stream, or error if any. +func ParseOptRouter(data []byte) (*OptRouter, error) { + ips, err := ParseIPs(data) + if err != nil { + return nil, err } - return &OptRouter{Routers: routers}, nil + return &OptRouter{Routers: ips}, nil } // Code returns the option code. |