diff options
author | Lorenzo Colitti <lorenzo@google.com> | 2015-03-12 22:36:49 +0900 |
---|---|---|
committer | Lorenzo Colitti <lorenzo@google.com> | 2015-03-16 21:57:00 +0900 |
commit | 15204d50b4220f98e4144567a9cfa4418cc9763a (patch) | |
tree | 85c51eef243f33e7e32ec92e52705fce81ae9aa4 /services/net | |
parent | c77f04f9bc61f6956ec8a6f498912cd0ffa8b7f8 (diff) | |
download | frameworks_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.java | 38 |
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(); |