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
This commit is contained in:
Xiao Ma 2023-04-21 20:48:02 +09:00
commit 29e92df3f2
2 changed files with 47 additions and 1 deletions

View file

@ -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;
}
}

View file

@ -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));
}
}