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

Commit e59d031f authored by Remi NGUYEN VAN's avatar Remi NGUYEN VAN
Browse files

Fix BOOTP fields for server-generated DHCP packets

Set siaddr to the server address instead of zero in DHCPOFFER
Set siaddr to zero instead of the server address in DHCPNAK
Set giaddr to the relay address instead of the server address in
DHCPNAK
Set giaddr to the relay address instead of zero on DHCPACK and
DHCPOFFER
Set server identifier option in DHCPNAK

Current code is not compliant with RFC2131 and does not match dnsmasq
behavior. It was not an issue until now since the packets were only used
by the DHCP client, which does not send DHCPOFFER or DHCPNAK.

Bug: b/109584964
Test: following DhcpServerTest.py regression tests pass:
      test_discover_bootpfields
      test_request_selecting_inuse
      test_request_rebinding_relayed
      test_discover_relayed_broadcastbit
      test_request_rebinding_wrongaddr_relayed
      Also: atest FrameworksNetTests

Change-Id: Ie0bf780498e38945444bff66ca499cff5983a97f
parent b825510b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -30,8 +30,8 @@ class DhcpAckPacket extends DhcpPacket {
    private final Inet4Address mSrcIp;

    DhcpAckPacket(int transId, short secs, boolean broadcast, Inet4Address serverAddress,
                  Inet4Address clientIp, Inet4Address yourIp, byte[] clientMac) {
        super(transId, secs, clientIp, yourIp, serverAddress, INADDR_ANY, clientMac, broadcast);
            Inet4Address relayIp, Inet4Address clientIp, Inet4Address yourIp, byte[] clientMac) {
        super(transId, secs, clientIp, yourIp, serverAddress, relayIp, clientMac, broadcast);
        mBroadcast = broadcast;
        mSrcIp = serverAddress;
    }
+4 −3
Original line number Diff line number Diff line
@@ -26,9 +26,10 @@ class DhcpNakPacket extends DhcpPacket {
    /**
     * Generates a NAK packet with the specified parameters.
     */
    DhcpNakPacket(int transId, short secs, Inet4Address nextIp, Inet4Address relayIp,
            byte[] clientMac, boolean broadcast) {
        super(transId, secs, INADDR_ANY, INADDR_ANY, nextIp, relayIp, clientMac, broadcast);
    DhcpNakPacket(int transId, short secs, Inet4Address relayIp, byte[] clientMac,
            boolean broadcast) {
        super(transId, secs, INADDR_ANY /* clientIp */, INADDR_ANY /* yourIp */,
                INADDR_ANY /* nextIp */, relayIp, clientMac, broadcast);
    }

    public String toString() {
+2 −2
Original line number Diff line number Diff line
@@ -32,8 +32,8 @@ class DhcpOfferPacket extends DhcpPacket {
     * Generates a OFFER packet with the specified parameters.
     */
    DhcpOfferPacket(int transId, short secs, boolean broadcast, Inet4Address serverAddress,
                    Inet4Address clientIp, Inet4Address yourIp, byte[] clientMac) {
        super(transId, secs, clientIp, yourIp, INADDR_ANY, INADDR_ANY, clientMac, broadcast);
            Inet4Address relayIp, Inet4Address clientIp, Inet4Address yourIp, byte[] clientMac) {
        super(transId, secs, clientIp, yourIp, serverAddress, relayIp, clientMac, broadcast);
        mSrcIp = serverAddress;
    }

+14 −11
Original line number Diff line number Diff line
@@ -1085,7 +1085,7 @@ public abstract class DhcpPacket {
                break;
            case DHCP_MESSAGE_TYPE_OFFER:
                newPacket = new DhcpOfferPacket(
                    transactionId, secs, broadcast, ipSrc, clientIp, yourIp, clientMac);
                    transactionId, secs, broadcast, ipSrc, relayIp, clientIp, yourIp, clientMac);
                break;
            case DHCP_MESSAGE_TYPE_REQUEST:
                newPacket = new DhcpRequestPacket(
@@ -1098,11 +1098,11 @@ public abstract class DhcpPacket {
                break;
            case DHCP_MESSAGE_TYPE_ACK:
                newPacket = new DhcpAckPacket(
                    transactionId, secs, broadcast, ipSrc, clientIp, yourIp, clientMac);
                    transactionId, secs, broadcast, ipSrc, relayIp, clientIp, yourIp, clientMac);
                break;
            case DHCP_MESSAGE_TYPE_NAK:
                newPacket = new DhcpNakPacket(
                        transactionId, secs, nextIp, relayIp, clientMac, broadcast);
                        transactionId, secs, relayIp, clientMac, broadcast);
                break;
            case DHCP_MESSAGE_TYPE_RELEASE:
                if (serverIdentifier == null) {
@@ -1234,12 +1234,13 @@ public abstract class DhcpPacket {
     * parameters.
     */
    public static ByteBuffer buildOfferPacket(int encap, int transactionId,
        boolean broadcast, Inet4Address serverIpAddr, Inet4Address clientIpAddr,
        byte[] mac, Integer timeout, Inet4Address netMask, Inet4Address bcAddr,
        List<Inet4Address> gateways, List<Inet4Address> dnsServers,
        boolean broadcast, Inet4Address serverIpAddr, Inet4Address relayIp,
        Inet4Address yourIp, byte[] mac, Integer timeout, Inet4Address netMask,
        Inet4Address bcAddr, List<Inet4Address> gateways, List<Inet4Address> dnsServers,
        Inet4Address dhcpServerIdentifier, String domainName) {
        DhcpPacket pkt = new DhcpOfferPacket(
            transactionId, (short) 0, broadcast, serverIpAddr, INADDR_ANY, clientIpAddr, mac);
                transactionId, (short) 0, broadcast, serverIpAddr, relayIp,
                INADDR_ANY /* clientIp */, yourIp, mac);
        pkt.mGateways = gateways;
        pkt.mDnsServers = dnsServers;
        pkt.mLeaseTime = timeout;
@@ -1254,12 +1255,13 @@ public abstract class DhcpPacket {
     * Builds a DHCP-ACK packet from the required specified parameters.
     */
    public static ByteBuffer buildAckPacket(int encap, int transactionId,
        boolean broadcast, Inet4Address serverIpAddr, Inet4Address clientIpAddr,
        boolean broadcast, Inet4Address serverIpAddr, Inet4Address relayIp, Inet4Address yourIp,
        byte[] mac, Integer timeout, Inet4Address netMask, Inet4Address bcAddr,
        List<Inet4Address> gateways, List<Inet4Address> dnsServers,
        Inet4Address dhcpServerIdentifier, String domainName) {
        DhcpPacket pkt = new DhcpAckPacket(
            transactionId, (short) 0, broadcast, serverIpAddr, INADDR_ANY, clientIpAddr, mac);
                transactionId, (short) 0, broadcast, serverIpAddr, relayIp,
                INADDR_ANY /* clientIp */, yourIp, mac);
        pkt.mGateways = gateways;
        pkt.mDnsServers = dnsServers;
        pkt.mLeaseTime = timeout;
@@ -1274,10 +1276,11 @@ public abstract class DhcpPacket {
     * Builds a DHCP-NAK packet from the required specified parameters.
     */
    public static ByteBuffer buildNakPacket(int encap, int transactionId, Inet4Address serverIpAddr,
            byte[] mac, boolean broadcast, String message) {
            Inet4Address relayIp, byte[] mac, boolean broadcast, String message) {
        DhcpPacket pkt = new DhcpNakPacket(
                transactionId, (short) 0, serverIpAddr, serverIpAddr, mac, broadcast);
                transactionId, (short) 0, relayIp, mac, broadcast);
        pkt.mMessage = message;
        pkt.mServerIdentifier = serverIpAddr;
        return pkt.buildPacket(encap, DHCP_CLIENT, DHCP_SERVER);
    }

+6 −8
Original line number Diff line number Diff line
@@ -351,10 +351,8 @@ public class DhcpServer {
                mServingParams.getServerInet4Addr(), mServingParams.serverAddr.getPrefixLength());
        final ByteBuffer offerPacket = DhcpPacket.buildOfferPacket(
                ENCAP_BOOTP, request.mTransId, broadcastFlag, mServingParams.getServerInet4Addr(),
                lease.getNetAddr(), request.mClientMac, timeout,
                prefixMask,
                broadcastAddr,
                new ArrayList<>(mServingParams.defaultRouters),
                request.mRelayIp, lease.getNetAddr(), request.mClientMac, timeout, prefixMask,
                broadcastAddr, new ArrayList<>(mServingParams.defaultRouters),
                new ArrayList<>(mServingParams.dnsServers),
                mServingParams.getServerInet4Addr(), null /* domainName */);

@@ -368,9 +366,9 @@ public class DhcpServer {
        final boolean broadcastFlag = getBroadcastFlag(request, lease);
        final int timeout = getLeaseTimeout(lease);
        final ByteBuffer ackPacket = DhcpPacket.buildAckPacket(ENCAP_BOOTP, request.mTransId,
                broadcastFlag, mServingParams.getServerInet4Addr(), lease.getNetAddr(),
                request.mClientMac, timeout, mServingParams.getPrefixMaskAsAddress(),
                mServingParams.getBroadcastAddress(),
                broadcastFlag, mServingParams.getServerInet4Addr(), request.mRelayIp,
                lease.getNetAddr(), request.mClientMac, timeout,
                mServingParams.getPrefixMaskAsAddress(), mServingParams.getBroadcastAddress(),
                new ArrayList<>(mServingParams.defaultRouters),
                new ArrayList<>(mServingParams.dnsServers),
                mServingParams.getServerInet4Addr(), null /* domainName */);
@@ -383,7 +381,7 @@ public class DhcpServer {
        // Always set broadcast flag for NAK: client may not have a correct IP
        final ByteBuffer nakPacket = DhcpPacket.buildNakPacket(
                ENCAP_BOOTP, request.mTransId, mServingParams.getServerInet4Addr(),
                request.mClientMac, true /* broadcast */, message);
                request.mRelayIp, request.mClientMac, true /* broadcast */, message);

        final Inet4Address dst = isEmpty(request.mRelayIp)
                ? (Inet4Address) Inet4Address.ALL