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
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user