Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b19238c4 authored by Erik Kline's avatar Erik Kline Committed by Lorenzo Colitti
Browse files

Accept DHCP responses from non-67 server source ports

Bug: 24687559
Change-Id: I5f03b8b2780c558281d8a50d0893fd64f2812add
parent 496906ee
Loading
Loading
Loading
Loading
+14 −2
Original line number Diff line number Diff line
@@ -673,6 +673,14 @@ abstract class DhcpPacket {
        return new String(bytes, 0, length, StandardCharsets.US_ASCII);
    }

    private static boolean isPacketToOrFromClient(short udpSrcPort, short udpDstPort) {
        return (udpSrcPort == DHCP_CLIENT) || (udpDstPort == DHCP_CLIENT);
    }

    private static boolean isPacketServerToServer(short udpSrcPort, short udpDstPort) {
        return (udpSrcPort == DHCP_SERVER) && (udpDstPort == DHCP_SERVER);
    }

    public static class ParseException extends Exception {
        public ParseException(String msg, Object... args) {
            super(String.format(msg, args));
@@ -791,8 +799,12 @@ abstract class DhcpPacket {
            short udpLen = packet.getShort();
            short udpChkSum = packet.getShort();

            if ((udpSrcPort != DHCP_SERVER) && (udpSrcPort != DHCP_CLIENT)) {
                throw new ParseException("Invalid source port %d", udpSrcPort);
            // Only accept packets to or from the well-known client port (expressly permitting
            // packets from ports other than the well-known server port; http://b/24687559), and
            // server-to-server packets, e.g. for relays.
            if (!isPacketToOrFromClient(udpSrcPort, udpDstPort) &&
                !isPacketServerToServer(udpSrcPort, udpDstPort)) {
                return null;
            }
        }

+36 −0
Original line number Diff line number Diff line
@@ -514,4 +514,40 @@ public class DhcpPacketTest extends TestCase {
        assertDhcpResults("10.32.158.205/20", "10.32.144.1", "148.88.65.52,148.88.65.53",
                "lancs.ac.uk", "10.32.255.128", null, 7200, false, dhcpResults);
    }

    @SmallTest
    public void testUdpServerAnySourcePort() throws Exception {
        final ByteBuffer packet = ByteBuffer.wrap(HexEncoding.decode((
            // Ethernet header.
            "9cd917000000001c2e0000000800" +
            // IP header.
            "45a00148000040003d115087d18194fb0a0f7af2" +
            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
            // NOTE: The server source port is not the canonical port 67.
            "C29F004401341268" +
            // BOOTP header.
            "02010600d628ba8200000000000000000a0f7af2000000000a0fc818" +
            // MAC address.
            "9cd91700000000000000000000000000" +
            // Server name.
            "0000000000000000000000000000000000000000000000000000000000000000" +
            "0000000000000000000000000000000000000000000000000000000000000000" +
            // File.
            "0000000000000000000000000000000000000000000000000000000000000000" +
            "0000000000000000000000000000000000000000000000000000000000000000" +
            "0000000000000000000000000000000000000000000000000000000000000000" +
            "0000000000000000000000000000000000000000000000000000000000000000" +
            // Options.
            "6382536335010236040a0169fc3304000151800104ffff000003040a0fc817060cd1818003d1819403" +
            "d18180060f0777766d2e6564751c040a0fffffff000000"
        ).toCharArray(), false));

        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
        assertTrue(offerPacket instanceof DhcpOfferPacket);
        assertEquals("9CD917000000", HexDump.toHexString(offerPacket.getClientMac()));
        DhcpResults dhcpResults = offerPacket.toDhcpResults();
        assertDhcpResults("10.15.122.242/16", "10.15.200.23",
                "209.129.128.3,209.129.148.3,209.129.128.6",
                "wvm.edu", "10.1.105.252", null, 86400, false, dhcpResults);
    }
}