summaryrefslogtreecommitdiffstats
path: root/services/net/java/android/net/dhcp/DhcpPacket.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/net/java/android/net/dhcp/DhcpPacket.java')
-rw-r--r--services/net/java/android/net/dhcp/DhcpPacket.java27
1 files changed, 21 insertions, 6 deletions
diff --git a/services/net/java/android/net/dhcp/DhcpPacket.java b/services/net/java/android/net/dhcp/DhcpPacket.java
index f97df83..820a03d 100644
--- a/services/net/java/android/net/dhcp/DhcpPacket.java
+++ b/services/net/java/android/net/dhcp/DhcpPacket.java
@@ -6,6 +6,7 @@ import android.net.NetworkUtils;
import android.os.Build;
import android.os.SystemProperties;
import android.system.OsConstants;
+import com.android.internal.annotations.VisibleForTesting;
import java.io.UnsupportedEncodingException;
import java.net.Inet4Address;
@@ -13,9 +14,8 @@ import java.net.UnknownHostException;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.nio.charset.StandardCharsets;
import java.nio.ShortBuffer;
-
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -701,7 +701,8 @@ abstract class DhcpPacket {
* A subset of the optional parameters are parsed and are stored
* in object fields.
*/
- public static DhcpPacket decodeFullPacket(ByteBuffer packet, int pktType) throws ParseException
+ @VisibleForTesting
+ static DhcpPacket decodeFullPacket(ByteBuffer packet, int pktType) throws ParseException
{
// bootp parameters
int transactionId;
@@ -809,7 +810,11 @@ abstract class DhcpPacket {
// server-to-server packets, e.g. for relays.
if (!isPacketToOrFromClient(udpSrcPort, udpDstPort) &&
!isPacketServerToServer(udpSrcPort, udpDstPort)) {
- return null;
+ // This should almost never happen because we use SO_ATTACH_FILTER on the packet
+ // socket to drop packets that don't have the right source ports. However, it's
+ // possible that a packet arrives between when the socket is bound and when the
+ // filter is set. http://b/26696823 .
+ throw new ParseException("Unexpected UDP ports %d->%d", udpSrcPort, udpDstPort);
}
}
@@ -860,8 +865,12 @@ abstract class DhcpPacket {
+ 64 // skip server host name (64 chars)
+ 128); // skip boot file name (128 chars)
- int dhcpMagicCookie = packet.getInt();
+ // Ensure this is a DHCP packet with a magic cookie, and not BOOTP. http://b/31850211
+ if (packet.remaining() < 4) {
+ throw new ParseException("DHCP packet without a magic cookie");
+ }
+ int dhcpMagicCookie = packet.getInt();
if (dhcpMagicCookie != DHCP_MAGIC_COOKIE) {
throw new ParseException("Bad magic cookie 0x%08x, should be 0x%08x", dhcpMagicCookie,
DHCP_MAGIC_COOKIE);
@@ -1049,7 +1058,13 @@ abstract class DhcpPacket {
public static DhcpPacket decodeFullPacket(byte[] packet, int length, int pktType)
throws ParseException {
ByteBuffer buffer = ByteBuffer.wrap(packet, 0, length).order(ByteOrder.BIG_ENDIAN);
- return decodeFullPacket(buffer, pktType);
+ try {
+ return decodeFullPacket(buffer, pktType);
+ } catch (ParseException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new ParseException("DHCP parsing error: %s", e.getMessage());
+ }
}
/**