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

Commit 86bff867 authored by Lorenzo Colitti's avatar Lorenzo Colitti
Browse files

DHCP: glue code.

1. Add a method to make a DhcpResults object from a DHCP packet.
2. Add a method to fetch the client MAC from the packet. This is
   needed to check that the message is for us (lots of DHCP
   messages are broadcast).
3. Add a length argument to the method that parses DHCP packets,
   so the caller can use the same MTU-sized array all the time
   instead of having to pass in a new array for every packet.

Bug: 19704592
Change-Id: I58223f5ec90fb5c762bc2934649e02f9122018b2
parent 7f7cc611
Loading
Loading
Loading
Loading
+58 −3
Original line number Diff line number Diff line
package android.net.dhcp;

import android.net.DhcpResults;
import android.net.LinkAddress;
import android.net.NetworkUtils;
import android.os.Build;
import android.os.SystemProperties;
import android.system.OsConstants;

import java.net.Inet4Address;
@@ -27,6 +32,8 @@ abstract class DhcpPacket {
            (byte) 0xff, (byte) 0xff, (byte) 0xff,
            (byte) 0xff, (byte) 0xff, (byte) 0xff,
    };
    // Minimum length of a DHCP packet w/o options: Ethernet header, IP header, fixed bootp format.
    public static final int MIN_PACKET_LENGTH_L2 = 14 + 20 + 300;

    /**
     * Packet encapsulations.
@@ -179,6 +186,7 @@ abstract class DhcpPacket {
     * DHCP Optional Type: Vendor Class Identifier
     */
    protected static final byte DHCP_VENDOR_CLASS_ID = 60;
    protected String mVendorId;

    /**
     * DHCP Optional Type: DHCP Client Identifier
@@ -242,6 +250,13 @@ abstract class DhcpPacket {
        return mTransId;
    }

    /**
     * Returns the client MAC.
     */
    public byte[] getClientMac() {
        return mClientMac;
    }

    /**
     * Creates a new L3 packet (including IP header) containing the
     * DHCP udp packet.  This method relies upon the delegated method
@@ -820,18 +835,58 @@ abstract class DhcpPacket {
        newPacket.mRequestedParams = expectedParams;
        newPacket.mServerIdentifier = serverIdentifier;
        newPacket.mSubnetMask = netMask;
        newPacket.mVendorId = vendorId;
        return newPacket;
    }

    /**
     * Parse a packet from an array of bytes.
     * Parse a packet from an array of bytes, stopping at the given length.
     */
    public static DhcpPacket decodeFullPacket(byte[] packet, int pktType)
    public static DhcpPacket decodeFullPacket(byte[] packet, int length, int pktType)
    {
        ByteBuffer buffer = ByteBuffer.wrap(packet).order(ByteOrder.BIG_ENDIAN);
        ByteBuffer buffer = ByteBuffer.wrap(packet, 0, length).order(ByteOrder.BIG_ENDIAN);
        return decodeFullPacket(buffer, pktType);
    }

    /**
     *  Construct a DhcpResults object from a DHCP reply packet.
     */
    public DhcpResults toDhcpResults() {
        Inet4Address ipAddress = mYourIp;
        if (ipAddress == Inet4Address.ANY) {
            ipAddress = mClientIp;
            if (ipAddress == Inet4Address.ANY) {
                return null;
            }
        }

        int prefixLength;
        if (mSubnetMask != null) {
            try {
                prefixLength = NetworkUtils.netmaskToPrefixLength(mSubnetMask);
            } catch (IllegalArgumentException e) {
                // Non-contiguous netmask.
                return null;
            }
        } else {
            prefixLength = NetworkUtils.getImplicitNetmask(ipAddress);
        }

        DhcpResults results = new DhcpResults();
        try {
            results.ipAddress = new LinkAddress(ipAddress, prefixLength);
        } catch (IllegalArgumentException e) {
            return null;
        }
        results.gateway = mGateway;
        results.dnsServers.addAll(mDnsServers);
        results.domains = mDomainName;
        results.serverAddress = mServerIdentifier;
        results.vendorInfo = mVendorId;
        results.leaseDuration = mLeaseTime;
        return results;
    }

    /**
     * Builds a DHCP-DISCOVER packet from the required specified
     * parameters.