summaryrefslogtreecommitdiffstats
path: root/services/net
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2015-03-12 22:36:49 +0900
committerLorenzo Colitti <lorenzo@google.com>2015-03-16 21:57:00 +0900
commit15204d50b4220f98e4144567a9cfa4418cc9763a (patch)
tree85c51eef243f33e7e32ec92e52705fce81ae9aa4 /services/net
parentc77f04f9bc61f6956ec8a6f498912cd0ffa8b7f8 (diff)
downloadframeworks_base-15204d50b4220f98e4144567a9cfa4418cc9763a.zip
frameworks_base-15204d50b4220f98e4144567a9cfa4418cc9763a.tar.gz
frameworks_base-15204d50b4220f98e4144567a9cfa4418cc9763a.tar.bz2
DHCP: Ethernet/IP packet header changes.
1. Support L2_ENCAP when building packets as well as when parsing. 2. Skip IP options when parsing DHCP packets. Bug: 19704592 Change-Id: Ic27a45790ed1cf7cf5b82d63b6c0b64c909a570f
Diffstat (limited to 'services/net')
-rw-r--r--services/net/java/android/net/dhcp/DhcpPacket.java38
1 files changed, 31 insertions, 7 deletions
diff --git a/services/net/java/android/net/dhcp/DhcpPacket.java b/services/net/java/android/net/dhcp/DhcpPacket.java
index 2384848..a4d0ec4 100644
--- a/services/net/java/android/net/dhcp/DhcpPacket.java
+++ b/services/net/java/android/net/dhcp/DhcpPacket.java
@@ -1,5 +1,7 @@
package android.net.dhcp;
+import android.system.OsConstants;
+
import java.net.Inet4Address;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
@@ -21,6 +23,10 @@ abstract class DhcpPacket {
public static final Inet4Address INADDR_ANY = (Inet4Address) Inet4Address.ANY;
public static final Inet4Address INADDR_BROADCAST = (Inet4Address) Inet4Address.ALL;
+ public static final byte[] ETHER_BROADCAST = new byte[] {
+ (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ };
/**
* Packet encapsulations.
@@ -246,6 +252,7 @@ abstract class DhcpPacket {
byte requestCode, boolean broadcast) {
byte[] destIpArray = destIp.getAddress();
byte[] srcIpArray = srcIp.getAddress();
+ int ipHeaderOffset = 0;
int ipLengthOffset = 0;
int ipChecksumOffset = 0;
int endIpHeader = 0;
@@ -256,11 +263,17 @@ abstract class DhcpPacket {
buf.clear();
buf.order(ByteOrder.BIG_ENDIAN);
+ if (encap == ENCAP_L2) {
+ buf.put(ETHER_BROADCAST);
+ buf.put(mClientMac);
+ buf.putShort((short) OsConstants.ETH_P_IP);
+ }
+
// if a full IP packet needs to be generated, put the IP & UDP
// headers in place, and pre-populate with artificial values
// needed to seed the IP checksum.
- if (encap == ENCAP_L3) {
- // fake IP header, used in the IP-header checksum
+ if (encap <= ENCAP_L3) {
+ ipHeaderOffset = buf.position();
buf.put(IP_VERSION_HEADER_LEN);
buf.put(IP_TOS_LOWDELAY); // tos: IPTOS_LOWDELAY
ipLengthOffset = buf.position();
@@ -319,7 +332,7 @@ abstract class DhcpPacket {
// If an IP packet is being built, the IP & UDP checksums must be
// computed.
- if (encap == ENCAP_L3) {
+ if (encap <= ENCAP_L3) {
// fix UDP header: insert length
short udpLen = (short)(buf.position() - udpHeaderOffset);
buf.putShort(udpLengthOffset, udpLen);
@@ -342,10 +355,10 @@ abstract class DhcpPacket {
udpHeaderOffset,
buf.position()));
// fix IP header: insert length
- buf.putShort(ipLengthOffset, (short)buf.position());
+ buf.putShort(ipLengthOffset, (short)(buf.position() - ipHeaderOffset));
// fixup IP-header checksum
buf.putShort(ipChecksumOffset,
- (short) checksum(buf, 0, 0, endIpHeader));
+ (short) checksum(buf, 0, ipHeaderOffset, endIpHeader));
}
}
@@ -586,13 +599,18 @@ abstract class DhcpPacket {
short l2type = packet.getShort();
- if (l2type != 0x0800)
+ if (l2type != OsConstants.ETH_P_IP)
return null;
}
if ((pktType == ENCAP_L2) || (pktType == ENCAP_L3)) {
// assume l2type is 0x0800, i.e. IP
- byte ipType = packet.get();
+ byte ipTypeAndLength = packet.get();
+ int ipVersion = (ipTypeAndLength & 0xf0) >> 4;
+ if (ipVersion != 4) {
+ return null;
+ }
+
// System.out.println("ipType is " + ipType);
byte ipDiffServicesField = packet.get();
short ipTotalLength = packet.getShort();
@@ -609,6 +627,12 @@ abstract class DhcpPacket {
if (ipProto != IP_TYPE_UDP) // UDP
return null;
+ // Skip options.
+ int optionWords = ((ipTypeAndLength & 0x0f) - 5);
+ for (int i = 0; i < optionWords; i++) {
+ packet.getInt();
+ }
+
// assume UDP
short udpSrcPort = packet.getShort();
short udpDstPort = packet.getShort();