From 29e92df3f28da4dc207e659c820228721ddd16d4 Mon Sep 17 00:00:00 2001 From: Xiao Ma Date: Fri, 21 Apr 2023 20:48:02 +0900 Subject: [PATCH] Add an integration test to verify zero-length DHCP packet. DHCP packet listener closes the listening socket and stops reading packet upon receiving a zero-length DHCP packet, which will break the following DHCP handshake. Add an integration test to verify the current behavior. A follow-up fix will verify if DHCP server will accept the zero-length DHCP packet and continue reading packet on that socket. Bug: 269692093 Test: atest TetheringIntegrationTests Change-Id: I5990e37cdfad4e8e4337b0bb1a74632286884baf --- .../base/android/net/TetheringTester.java | 10 ++++- .../android/net/EthernetTetheringTest.java | 38 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/Tethering/tests/integration/base/android/net/TetheringTester.java b/Tethering/tests/integration/base/android/net/TetheringTester.java index ae39b246b6..1c0803eb82 100644 --- a/Tethering/tests/integration/base/android/net/TetheringTester.java +++ b/Tethering/tests/integration/base/android/net/TetheringTester.java @@ -628,7 +628,7 @@ public final class TetheringTester { return false; } - private void sendUploadPacket(ByteBuffer packet) throws Exception { + public void sendUploadPacket(ByteBuffer packet) throws Exception { mDownstreamReader.sendResponse(packet); } @@ -680,4 +680,12 @@ public final class TetheringTester { return verifyPacketNotNull("Download fail", getDownloadPacket(filter)); } + + // Send DHCPDISCOVER to DHCP server to see if DHCP server is still alive to handle + // the upcoming DHCP packets. This method should be only used when we know the DHCP + // server has been created successfully before. + public boolean testDhcpServerAlive(final MacAddress mac) throws Exception { + sendDhcpDiscover(mac.toByteArray()); + return getNextDhcpPacket() != null; + } } diff --git a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java index 55854e273f..21927df301 100644 --- a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java +++ b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java @@ -39,6 +39,7 @@ import static com.android.net.module.util.NetworkStackConstants.IPV4_HEADER_MIN_ import static com.android.net.module.util.NetworkStackConstants.IPV4_LENGTH_OFFSET; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -839,4 +840,41 @@ public class EthernetTetheringTest extends EthernetTetheringTestBase { REMOTE_NAT64_ADDR /* downloadSrcIp */, clatIp6 /* downloadDstIp */, tester, true /* isClat */); } + + private static final byte[] ZeroLengthDhcpPacket = new byte[] { + // scapy.Ether( + // dst="ff:ff:ff:ff:ff:ff") + // scapy.IP( + // dst="255.255.255.255") + // scapy.UDP(sport=68, dport=67) + /* Ethernet Header */ + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xe0, (byte) 0x4f, (byte) 0x43, (byte) 0xe6, (byte) 0xfb, (byte) 0xd2, + (byte) 0x08, (byte) 0x00, + /* Ip header */ + (byte) 0x45, (byte) 0x00, (byte) 0x00, (byte) 0x1c, (byte) 0x00, (byte) 0x01, + (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x11, (byte) 0xb6, (byte) 0x58, + (byte) 0x64, (byte) 0x4f, (byte) 0x60, (byte) 0x29, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, + /* UDP header */ + (byte) 0x00, (byte) 0x44, (byte) 0x00, (byte) 0x43, + (byte) 0x00, (byte) 0x08, (byte) 0x3a, (byte) 0xdf + }; + + @Test + public void testTetherZeroLengthDhcpPacket() throws Exception { + final TetheringTester tester = initTetheringTester(toList(TEST_IP4_ADDR), + toList(TEST_IP4_DNS)); + tester.createTetheredDevice(TEST_MAC, false /* hasIpv6 */); + + // Send a zero-length DHCP packet to upstream DHCP server. + final ByteBuffer packet = ByteBuffer.wrap(ZeroLengthDhcpPacket); + tester.sendUploadPacket(packet); + + // Send DHCPDISCOVER packet from another downstream tethered device to verify that upstream + // DHCP server has closed the listening socket and stopped reading, then we will not receive + // any DHCPOFFER in this case. + final MacAddress macAddress = MacAddress.fromString("11:22:33:44:55:66"); + assertFalse(tester.testDhcpServerAlive(macAddress)); + } }