summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorlprylli <49498490+lprylli@users.noreply.github.com>2019-05-22 02:15:26 -0700
committerPablo Mazzini <pmazzini@gmail.com>2019-05-22 10:15:26 +0100
commit5dce45b2b680c398f6052c14c0f7558add495130 (patch)
tree308a885dc4d10fc70b0f1ac18e1218a9fc6ce3bf
parent1a0fc7419d4541c26b2d25b4d089a66853e91d76 (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.go13
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
}
}