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

Commit 025f4a5a authored by Lorenzo Colitti's avatar Lorenzo Colitti
Browse files

Support DHCP replies with multiple default gateways.

Just use the first one for compatibility with the legacy client.

Bug: 23975855
Change-Id: Id6a0b0de32e8947c12c02eb9a3be417e2f82c99a
parent b19238c4
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ class DhcpAckPacket extends DhcpPacket {

        return s + " ACK: your new IP " + mYourIp +
                ", netmask " + mSubnetMask +
                ", gateway " + mGateway + dnsServers +
                ", gateways " + mGateways + dnsServers +
                ", lease time " + mLeaseTime;
    }

@@ -79,7 +79,7 @@ class DhcpAckPacket extends DhcpPacket {
        }

        addTlv(buffer, DHCP_SUBNET_MASK, mSubnetMask);
        addTlv(buffer, DHCP_ROUTER, mGateway);
        addTlv(buffer, DHCP_ROUTER, mGateways);
        addTlv(buffer, DHCP_DOMAIN_NAME, mDomainName);
        addTlv(buffer, DHCP_BROADCAST_ADDRESS, mBroadcastAddress);
        addTlv(buffer, DHCP_DNS_SERVER, mDnsServers);
+2 −2
Original line number Diff line number Diff line
@@ -48,7 +48,7 @@ class DhcpOfferPacket extends DhcpPacket {
        }

        return s + " OFFER, ip " + mYourIp + ", mask " + mSubnetMask +
                dnsServers + ", gateway " + mGateway +
                dnsServers + ", gateways " + mGateways +
                " lease time " + mLeaseTime + ", domain " + mDomainName;
    }

@@ -81,7 +81,7 @@ class DhcpOfferPacket extends DhcpPacket {
        }

        addTlv(buffer, DHCP_SUBNET_MASK, mSubnetMask);
        addTlv(buffer, DHCP_ROUTER, mGateway);
        addTlv(buffer, DHCP_ROUTER, mGateways);
        addTlv(buffer, DHCP_DOMAIN_NAME, mDomainName);
        addTlv(buffer, DHCP_BROADCAST_ADDRESS, mBroadcastAddress);
        addTlv(buffer, DHCP_DNS_SERVER, mDnsServers);
+16 −11
Original line number Diff line number Diff line
@@ -128,7 +128,7 @@ abstract class DhcpPacket {
     * DHCP Optional Type: DHCP Router
     */
    protected static final byte DHCP_ROUTER = 3;
    protected Inet4Address mGateway;
    protected List <Inet4Address> mGateways;

    /**
     * DHCP Optional Type: DHCP DNS Server
@@ -706,8 +706,8 @@ abstract class DhcpPacket {
        Inet4Address nextIp;
        Inet4Address relayIp;
        byte[] clientMac;
        List<Inet4Address> dnsServers = new ArrayList<Inet4Address>();
        Inet4Address gateway = null; // aka router
        List<Inet4Address> dnsServers = new ArrayList<>();
        List<Inet4Address> gateways = new ArrayList<>();  // aka router
        Inet4Address serverIdentifier = null;
        Inet4Address netMask = null;
        String message = null;
@@ -883,8 +883,9 @@ abstract class DhcpPacket {
                            expectedLen = 4;
                            break;
                        case DHCP_ROUTER:
                            gateway = readIpAddress(packet);
                            expectedLen = 4;
                            for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) {
                                gateways.add(readIpAddress(packet));
                            }
                            break;
                        case DHCP_DNS_SERVER:
                            for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) {
@@ -1020,7 +1021,7 @@ abstract class DhcpPacket {
        newPacket.mBroadcastAddress = bcAddr;
        newPacket.mDnsServers = dnsServers;
        newPacket.mDomainName = domainName;
        newPacket.mGateway = gateway;
        newPacket.mGateways = gateways;
        newPacket.mHostName = hostName;
        newPacket.mLeaseTime = leaseTime;
        newPacket.mMessage = message;
@@ -1076,7 +1077,11 @@ abstract class DhcpPacket {
        } catch (IllegalArgumentException e) {
            return null;
        }
        results.gateway = mGateway;

        if (mGateways.size() > 0) {
            results.gateway = mGateways.get(0);
        }

        results.dnsServers.addAll(mDnsServers);
        results.domains = mDomainName;
        results.serverAddress = mServerIdentifier;
@@ -1118,11 +1123,11 @@ abstract class DhcpPacket {
    public static ByteBuffer buildOfferPacket(int encap, int transactionId,
        boolean broadcast, Inet4Address serverIpAddr, Inet4Address clientIpAddr,
        byte[] mac, Integer timeout, Inet4Address netMask, Inet4Address bcAddr,
        Inet4Address gateway, List<Inet4Address> dnsServers,
        List<Inet4Address> gateways, List<Inet4Address> dnsServers,
        Inet4Address dhcpServerIdentifier, String domainName) {
        DhcpPacket pkt = new DhcpOfferPacket(
            transactionId, (short) 0, broadcast, serverIpAddr, INADDR_ANY, clientIpAddr, mac);
        pkt.mGateway = gateway;
        pkt.mGateways = gateways;
        pkt.mDnsServers = dnsServers;
        pkt.mLeaseTime = timeout;
        pkt.mDomainName = domainName;
@@ -1138,11 +1143,11 @@ abstract class DhcpPacket {
    public static ByteBuffer buildAckPacket(int encap, int transactionId,
        boolean broadcast, Inet4Address serverIpAddr, Inet4Address clientIpAddr,
        byte[] mac, Integer timeout, Inet4Address netMask, Inet4Address bcAddr,
        Inet4Address gateway, List<Inet4Address> dnsServers,
        List<Inet4Address> gateways, List<Inet4Address> dnsServers,
        Inet4Address dhcpServerIdentifier, String domainName) {
        DhcpPacket pkt = new DhcpAckPacket(
            transactionId, (short) 0, broadcast, serverIpAddr, INADDR_ANY, clientIpAddr, mac);
        pkt.mGateway = gateway;
        pkt.mGateways = gateways;
        pkt.mDnsServers = dnsServers;
        pkt.mLeaseTime = timeout;
        pkt.mDomainName = domainName;
+34 −0
Original line number Diff line number Diff line
@@ -550,4 +550,38 @@ public class DhcpPacketTest extends TestCase {
                "209.129.128.3,209.129.148.3,209.129.128.6",
                "wvm.edu", "10.1.105.252", null, 86400, false, dhcpResults);
    }

    @SmallTest
    public void testMultipleRouters() throws Exception {
        final ByteBuffer packet = ByteBuffer.wrap(HexEncoding.decode((
            // Ethernet header.
            "fc3d93000000" + "081735000000" + "0800" +
            // IP header.
            "45000148c2370000ff117ac2c0a8bd02ffffffff" +
            // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
            "0043004401343beb" +
            // BOOTP header.
            "0201060027f518e20000800000000000c0a8bd310000000000000000" +
            // MAC address.
            "fc3d9300000000000000000000000000" +
            // Server name.
            "0000000000000000000000000000000000000000000000000000000000000000" +
            "0000000000000000000000000000000000000000000000000000000000000000" +
            // File.
            "0000000000000000000000000000000000000000000000000000000000000000" +
            "0000000000000000000000000000000000000000000000000000000000000000" +
            "0000000000000000000000000000000000000000000000000000000000000000" +
            "0000000000000000000000000000000000000000000000000000000000000000" +
            // Options.
            "638253633501023604c0abbd023304000070803a04000038403b04000062700104ffffff00" +
            "0308c0a8bd01ffffff0006080808080808080404ff000000000000"
        ).toCharArray(), false));

        DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
        assertTrue(offerPacket instanceof DhcpOfferPacket);
        assertEquals("FC3D93000000", HexDump.toHexString(offerPacket.getClientMac()));
        DhcpResults dhcpResults = offerPacket.toDhcpResults();
        assertDhcpResults("192.168.189.49/24", "192.168.189.1", "8.8.8.8,8.8.4.4",
                null, "192.171.189.2", null, 28800, false, dhcpResults);
    }
}