diff --git a/services/net/java/android/net/dhcp/DhcpAckPacket.java b/services/net/java/android/net/dhcp/DhcpAckPacket.java index 334f708b88a97..df44b11fffa57 100644 --- a/services/net/java/android/net/dhcp/DhcpAckPacket.java +++ b/services/net/java/android/net/dhcp/DhcpAckPacket.java @@ -46,7 +46,7 @@ class DhcpAckPacket extends DhcpPacket { return s + " ACK: your new IP " + mYourIp + ", netmask " + mSubnetMask + - ", gateway " + mGateway + dnsServers + + ", gateways " + mGateways + dnsServers + ", lease time " + mLeaseTime; } @@ -79,7 +79,7 @@ class DhcpAckPacket extends DhcpPacket { } addTlv(buffer, DHCP_SUBNET_MASK, mSubnetMask); - addTlv(buffer, DHCP_ROUTER, mGateway); + addTlv(buffer, DHCP_ROUTER, mGateways); addTlv(buffer, DHCP_DOMAIN_NAME, mDomainName); addTlv(buffer, DHCP_BROADCAST_ADDRESS, mBroadcastAddress); addTlv(buffer, DHCP_DNS_SERVER, mDnsServers); diff --git a/services/net/java/android/net/dhcp/DhcpOfferPacket.java b/services/net/java/android/net/dhcp/DhcpOfferPacket.java index 7ca7100bbabc9..99154ef0498c8 100644 --- a/services/net/java/android/net/dhcp/DhcpOfferPacket.java +++ b/services/net/java/android/net/dhcp/DhcpOfferPacket.java @@ -48,7 +48,7 @@ class DhcpOfferPacket extends DhcpPacket { } return s + " OFFER, ip " + mYourIp + ", mask " + mSubnetMask + - dnsServers + ", gateway " + mGateway + + dnsServers + ", gateways " + mGateways + " lease time " + mLeaseTime + ", domain " + mDomainName; } @@ -81,7 +81,7 @@ class DhcpOfferPacket extends DhcpPacket { } addTlv(buffer, DHCP_SUBNET_MASK, mSubnetMask); - addTlv(buffer, DHCP_ROUTER, mGateway); + addTlv(buffer, DHCP_ROUTER, mGateways); addTlv(buffer, DHCP_DOMAIN_NAME, mDomainName); addTlv(buffer, DHCP_BROADCAST_ADDRESS, mBroadcastAddress); addTlv(buffer, DHCP_DNS_SERVER, mDnsServers); diff --git a/services/net/java/android/net/dhcp/DhcpPacket.java b/services/net/java/android/net/dhcp/DhcpPacket.java index d6540897b1fc7..8927bfa25654e 100644 --- a/services/net/java/android/net/dhcp/DhcpPacket.java +++ b/services/net/java/android/net/dhcp/DhcpPacket.java @@ -128,7 +128,7 @@ abstract class DhcpPacket { * DHCP Optional Type: DHCP Router */ protected static final byte DHCP_ROUTER = 3; - protected Inet4Address mGateway; + protected List mGateways; /** * DHCP Optional Type: DHCP DNS Server @@ -706,8 +706,8 @@ abstract class DhcpPacket { Inet4Address nextIp; Inet4Address relayIp; byte[] clientMac; - List dnsServers = new ArrayList(); - Inet4Address gateway = null; // aka router + List dnsServers = new ArrayList<>(); + List gateways = new ArrayList<>(); // aka router Inet4Address serverIdentifier = null; Inet4Address netMask = null; String message = null; @@ -883,8 +883,9 @@ abstract class DhcpPacket { expectedLen = 4; break; case DHCP_ROUTER: - gateway = readIpAddress(packet); - expectedLen = 4; + for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) { + gateways.add(readIpAddress(packet)); + } break; case DHCP_DNS_SERVER: for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) { @@ -1020,7 +1021,7 @@ abstract class DhcpPacket { newPacket.mBroadcastAddress = bcAddr; newPacket.mDnsServers = dnsServers; newPacket.mDomainName = domainName; - newPacket.mGateway = gateway; + newPacket.mGateways = gateways; newPacket.mHostName = hostName; newPacket.mLeaseTime = leaseTime; newPacket.mMessage = message; @@ -1076,7 +1077,11 @@ abstract class DhcpPacket { } catch (IllegalArgumentException e) { return null; } - results.gateway = mGateway; + + if (mGateways.size() > 0) { + results.gateway = mGateways.get(0); + } + results.dnsServers.addAll(mDnsServers); results.domains = mDomainName; results.serverAddress = mServerIdentifier; @@ -1118,11 +1123,11 @@ abstract class DhcpPacket { public static ByteBuffer buildOfferPacket(int encap, int transactionId, boolean broadcast, Inet4Address serverIpAddr, Inet4Address clientIpAddr, byte[] mac, Integer timeout, Inet4Address netMask, Inet4Address bcAddr, - Inet4Address gateway, List dnsServers, + List gateways, List dnsServers, Inet4Address dhcpServerIdentifier, String domainName) { DhcpPacket pkt = new DhcpOfferPacket( transactionId, (short) 0, broadcast, serverIpAddr, INADDR_ANY, clientIpAddr, mac); - pkt.mGateway = gateway; + pkt.mGateways = gateways; pkt.mDnsServers = dnsServers; pkt.mLeaseTime = timeout; pkt.mDomainName = domainName; @@ -1138,11 +1143,11 @@ abstract class DhcpPacket { public static ByteBuffer buildAckPacket(int encap, int transactionId, boolean broadcast, Inet4Address serverIpAddr, Inet4Address clientIpAddr, byte[] mac, Integer timeout, Inet4Address netMask, Inet4Address bcAddr, - Inet4Address gateway, List dnsServers, + List gateways, List dnsServers, Inet4Address dhcpServerIdentifier, String domainName) { DhcpPacket pkt = new DhcpAckPacket( transactionId, (short) 0, broadcast, serverIpAddr, INADDR_ANY, clientIpAddr, mac); - pkt.mGateway = gateway; + pkt.mGateways = gateways; pkt.mDnsServers = dnsServers; pkt.mLeaseTime = timeout; pkt.mDomainName = domainName; diff --git a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java index 0f1cb885ba210..7e60bf17d96e2 100644 --- a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java +++ b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java @@ -550,4 +550,38 @@ public class DhcpPacketTest extends TestCase { "209.129.128.3,209.129.148.3,209.129.128.6", "wvm.edu", "10.1.105.252", null, 86400, false, dhcpResults); } + + @SmallTest + public void testMultipleRouters() throws Exception { + final ByteBuffer packet = ByteBuffer.wrap(HexEncoding.decode(( + // Ethernet header. + "fc3d93000000" + "081735000000" + "0800" + + // IP header. + "45000148c2370000ff117ac2c0a8bd02ffffffff" + + // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation). + "0043004401343beb" + + // BOOTP header. + "0201060027f518e20000800000000000c0a8bd310000000000000000" + + // MAC address. + "fc3d9300000000000000000000000000" + + // Server name. + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + // File. + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + // Options. + "638253633501023604c0abbd023304000070803a04000038403b04000062700104ffffff00" + + "0308c0a8bd01ffffff0006080808080808080404ff000000000000" + ).toCharArray(), false)); + + DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2); + assertTrue(offerPacket instanceof DhcpOfferPacket); + assertEquals("FC3D93000000", HexDump.toHexString(offerPacket.getClientMac())); + DhcpResults dhcpResults = offerPacket.toDhcpResults(); + assertDhcpResults("192.168.189.49/24", "192.168.189.1", "8.8.8.8,8.8.4.4", + null, "192.171.189.2", null, 28800, false, dhcpResults); + } }