diff options
author | lprylli <49498490+lprylli@users.noreply.github.com> | 2019-05-22 02:15:26 -0700 |
---|---|---|
committer | Pablo Mazzini <pmazzini@gmail.com> | 2019-05-22 10:15:26 +0100 |
commit | 5dce45b2b680c398f6052c14c0f7558add495130 (patch) | |
tree | 308a885dc4d10fc70b0f1ac18e1218a9fc6ce3bf | |
parent | 1a0fc7419d4541c26b2d25b4d089a66853e91d76 (diff) |
Ignore bytes after end of IP packet in BroadcastRawUDPConn.ReadFrom (#292)
When reading raw packets from the network, it can happen that the raw
ethernet packet read has undefined bytes after the end of the ip
packet (either from the network or in some cases from the local
stack).
Those bytes should not be passed to the dhcp-receiver otherwise the
option parser which is picky about final padding byte will silently
discard the dhcp-reply.
Rename ipLen, udpLen variables with more explicit names to avoid
confusion between header, payload, total length possibly considered
in this function.
Tested: ast2500 bmc reproducing the issue + existing go test for coverage.
Signed-off-by: Loic Prylli <lprylli@netflix.com>
-rw-r--r-- | dhcpv4/nclient4/conn_linux.go | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/dhcpv4/nclient4/conn_linux.go b/dhcpv4/nclient4/conn_linux.go index 00c8a32..d6edc38 100644 --- a/dhcpv4/nclient4/conn_linux.go +++ b/dhcpv4/nclient4/conn_linux.go @@ -115,11 +115,11 @@ func udpMatch(addr *net.UDPAddr, bound *net.UDPAddr) bool { // ReadFrom reads raw IP packets and will try to match them against // upc.boundAddr. Any matching packets are returned via the given buffer. func (upc *BroadcastRawUDPConn) ReadFrom(b []byte) (int, net.Addr, error) { - ipLen := IPv4MaximumHeaderSize - udpLen := UDPMinimumSize + ipHdrMaxLen := IPv4MaximumHeaderSize + udpHdrLen := UDPMinimumSize for { - pkt := make([]byte, ipLen+udpLen+len(b)) + pkt := make([]byte, ipHdrMaxLen+udpHdrLen+len(b)) n, _, err := upc.PacketConn.ReadFrom(pkt) if err != nil { return 0, nil, err @@ -137,7 +137,7 @@ func (upc *BroadcastRawUDPConn) ReadFrom(b []byte) (int, net.Addr, error) { if ipHdr.TransportProtocol() != UDPProtocolNumber { continue } - udpHdr := UDP(buf.Consume(udpLen)) + udpHdr := UDP(buf.Consume(udpHdrLen)) addr := &net.UDPAddr{ IP: net.IP(ipHdr.DestinationAddress()), @@ -150,7 +150,10 @@ func (upc *BroadcastRawUDPConn) ReadFrom(b []byte) (int, net.Addr, error) { IP: net.IP(ipHdr.SourceAddress()), Port: int(udpHdr.SourcePort()), } - return copy(b, buf.ReadAll()), srcAddr, nil + // Extra padding after end of IP packet should be ignored, + // if not dhcp option parsing will fail. + dhcpLen := int(ipHdr.PayloadLength()) - udpHdrLen + return copy(b, buf.Consume(dhcpLen)), srcAddr, nil } } |