EthernetTetheringTest: add testTetherTcpV6
Bug: 237369591
Test: atest EthernetTetheringTest
Change-Id: I476a8d984eb8ccb6b2e64d6c36dbb455029a4c51
diff --git a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
index de788e7..50786e6 100644
--- a/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
+++ b/Tethering/tests/integration/src/android/net/EthernetTetheringTest.java
@@ -1036,26 +1036,21 @@
private static final ByteBuffer TX_PAYLOAD =
ByteBuffer.wrap(new byte[] { (byte) 0x56, (byte) 0x78 });
+ private short getEthType(@NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp) {
+ return isAddressIpv4(srcIp, dstIp) ? (short) ETHER_TYPE_IPV4 : (short) ETHER_TYPE_IPV6;
+ }
+
+ private int getIpProto(@NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp) {
+ return isAddressIpv4(srcIp, dstIp) ? IPPROTO_IP : IPPROTO_IPV6;
+ }
+
@NonNull
private ByteBuffer buildUdpPacket(
@Nullable final MacAddress srcMac, @Nullable final MacAddress dstMac,
@NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp,
short srcPort, short dstPort, @Nullable final ByteBuffer payload)
throws Exception {
- int ipProto;
- short ethType;
- if (srcIp instanceof Inet4Address && dstIp instanceof Inet4Address) {
- ipProto = IPPROTO_IP;
- ethType = (short) ETHER_TYPE_IPV4;
- } else if (srcIp instanceof Inet6Address && dstIp instanceof Inet6Address) {
- ipProto = IPPROTO_IPV6;
- ethType = (short) ETHER_TYPE_IPV6;
- } else {
- fail("Unsupported conditions: srcIp " + srcIp + ", dstIp " + dstIp);
- // Make compiler happy to the uninitialized ipProto and ethType.
- return null; // unreachable, the annotation @NonNull of function return value is true.
- }
-
+ final int ipProto = getIpProto(srcIp, dstIp);
final boolean hasEther = (srcMac != null && dstMac != null);
final int payloadLen = (payload == null) ? 0 : payload.limit();
final ByteBuffer buffer = PacketBuilder.allocate(hasEther, ipProto, IPPROTO_UDP,
@@ -1063,7 +1058,9 @@
final PacketBuilder packetBuilder = new PacketBuilder(buffer);
// [1] Ethernet header
- if (hasEther) packetBuilder.writeL2Header(srcMac, dstMac, (short) ethType);
+ if (hasEther) {
+ packetBuilder.writeL2Header(srcMac, dstMac, getEthType(srcIp, dstIp));
+ }
// [2] IP header
if (ipProto == IPPROTO_IP) {
@@ -1784,23 +1781,25 @@
@NonNull final InetAddress srcIp, @NonNull final InetAddress dstIp,
short srcPort, short dstPort, final short seq, final short ack,
final byte tcpFlags, @NonNull final ByteBuffer payload) throws Exception {
- // TODO: support IPv6
- if (!(srcIp instanceof Inet4Address && dstIp instanceof Inet4Address)) {
- fail("Unsupported conditions: srcIp " + srcIp + ", dstIp " + dstIp);
- return null;
- }
-
+ final int ipProto = getIpProto(srcIp, dstIp);
final boolean hasEther = (srcMac != null && dstMac != null);
- final ByteBuffer buffer = PacketBuilder.allocate(hasEther, IPPROTO_IP, IPPROTO_TCP,
+ final ByteBuffer buffer = PacketBuilder.allocate(hasEther, ipProto, IPPROTO_TCP,
payload.limit());
final PacketBuilder packetBuilder = new PacketBuilder(buffer);
// [1] Ethernet header
- if (hasEther) packetBuilder.writeL2Header(srcMac, dstMac, (short) ETHER_TYPE_IPV4);
+ if (hasEther) {
+ packetBuilder.writeL2Header(srcMac, dstMac, getEthType(srcIp, dstIp));
+ }
// [2] IP header
- packetBuilder.writeIpv4Header(TYPE_OF_SERVICE, ID, FLAGS_AND_FRAGMENT_OFFSET,
+ if (ipProto == IPPROTO_IP) {
+ packetBuilder.writeIpv4Header(TYPE_OF_SERVICE, ID, FLAGS_AND_FRAGMENT_OFFSET,
TIME_TO_LIVE, (byte) IPPROTO_TCP, (Inet4Address) srcIp, (Inet4Address) dstIp);
+ } else {
+ packetBuilder.writeIpv6Header(VERSION_TRAFFICCLASS_FLOWLABEL, (byte) IPPROTO_TCP,
+ HOP_LIMIT, (Inet6Address) srcIp, (Inet6Address) dstIp);
+ }
// [3] TCP header
packetBuilder.writeTcpHeader(srcPort, dstPort, seq, ack, tcpFlags, WINDOW, URGENT_POINTER);
@@ -1818,14 +1817,14 @@
@NonNull final InetAddress dstIp, short seq, short ack, byte tcpFlags,
@NonNull final ByteBuffer payload, @NonNull final TetheringTester tester)
throws Exception {
+ final boolean isIpv4 = isAddressIpv4(srcIp, dstIp);
final ByteBuffer testPacket = buildTcpPacket(null /* srcMac */, null /* dstMac */,
srcIp, dstIp, REMOTE_PORT /* srcPort */, LOCAL_PORT /* dstPort */, seq, ack,
tcpFlags, payload);
tester.verifyDownload(testPacket, p -> {
Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
- return isExpectedTcpPacket(p, true /* hasEther */, true /* isIpv4 */, seq,
- payload);
+ return isExpectedTcpPacket(p, true /* hasEther */, isIpv4, seq, payload);
});
}
@@ -1834,21 +1833,22 @@
@NonNull final InetAddress dstIp, short seq, short ack, byte tcpFlags,
@NonNull final ByteBuffer payload, @NonNull final TetheringTester tester)
throws Exception {
+ final boolean isIpv4 = isAddressIpv4(srcIp, dstIp);
final ByteBuffer testPacket = buildTcpPacket(srcMac, dstMac, srcIp, dstIp,
LOCAL_PORT /* srcPort */, REMOTE_PORT /* dstPort */, seq, ack, tcpFlags,
payload);
tester.verifyUpload(testPacket, p -> {
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
- return isExpectedTcpPacket(p, false /* hasEther */, true /* isIpv4 */,
- seq, payload);
+ return isExpectedTcpPacket(p, false /* hasEther */, isIpv4, seq, payload);
});
}
- void runTcpTest(@NonNull final MacAddress srcMac, @NonNull final MacAddress dstMac,
- @NonNull final InetAddress remoteIp, @NonNull final InetAddress tetheringUpstreamIp,
- @NonNull final InetAddress clientIp, @NonNull final TetheringTester tester)
- throws Exception {
+ void runTcpTest(
+ @NonNull final MacAddress uploadSrcMac, @NonNull final MacAddress uploadDstMac,
+ @NonNull final InetAddress uploadSrcIp, @NonNull final InetAddress uploadDstIp,
+ @NonNull final InetAddress downloadSrcIp, @NonNull final InetAddress downloadDstIp,
+ @NonNull final TetheringTester tester) throws Exception {
// Three way handshake and data transfer.
//
// Server (base seq = 2000) Client (base seq = 1000)
@@ -1873,24 +1873,26 @@
// This test can only verify the packets are transferred end to end but TCP state.
// TODO: verify TCP state change via /proc/net/nf_conntrack or netlink conntrack event.
// [1] [UPLOAD] [SYN]: SEQ = 1000
- sendUploadPacketTcp(srcMac, dstMac, clientIp, remoteIp, (short) 1000 /* seq */,
- (short) 0 /* ack */, TCPHDR_SYN, EMPTY_PAYLOAD, tester);
+ sendUploadPacketTcp(uploadSrcMac, uploadDstMac, uploadSrcIp, uploadDstIp,
+ (short) 1000 /* seq */, (short) 0 /* ack */, TCPHDR_SYN, EMPTY_PAYLOAD,
+ tester);
// [2] [DONWLOAD] [SYN + ACK]: SEQ = 2000, ACK = 1001
- sendDownloadPacketTcp(remoteIp, tetheringUpstreamIp, (short) 2000 /* seq */,
- (short) 1001 /* ack */, (byte) ((TCPHDR_SYN | TCPHDR_ACK) & 0xff),
- EMPTY_PAYLOAD, tester);
+ sendDownloadPacketTcp(downloadSrcIp, downloadDstIp, (short) 2000 /* seq */,
+ (short) 1001 /* ack */, (byte) ((TCPHDR_SYN | TCPHDR_ACK) & 0xff), EMPTY_PAYLOAD,
+ tester);
// [3] [UPLOAD] [ACK]: SEQ = 1001, ACK = 2001
- sendUploadPacketTcp(srcMac, dstMac, clientIp, remoteIp, (short) 1001 /* seq */,
- (short) 2001 /* ack */, TCPHDR_ACK, EMPTY_PAYLOAD, tester);
+ sendUploadPacketTcp(uploadSrcMac, uploadDstMac, uploadSrcIp, uploadDstIp,
+ (short) 1001 /* seq */, (short) 2001 /* ack */, TCPHDR_ACK, EMPTY_PAYLOAD, tester);
// [4] [UPLOAD] [ACK]: SEQ = 1001, ACK = 2001, 2 byte payload
- sendUploadPacketTcp(srcMac, dstMac, clientIp, remoteIp, (short) 1001 /* seq */,
- (short) 2001 /* ack */, TCPHDR_ACK, TX_PAYLOAD, tester);
+ sendUploadPacketTcp(uploadSrcMac, uploadDstMac, uploadSrcIp, uploadDstIp,
+ (short) 1001 /* seq */, (short) 2001 /* ack */, TCPHDR_ACK, TX_PAYLOAD,
+ tester);
// [5] [DONWLOAD] [ACK]: SEQ = 2001, ACK = 1003, 2 byte payload
- sendDownloadPacketTcp(remoteIp, tetheringUpstreamIp, (short) 2001 /* seq */,
+ sendDownloadPacketTcp(downloadSrcIp, downloadDstIp, (short) 2001 /* seq */,
(short) 1003 /* ack */, TCPHDR_ACK, RX_PAYLOAD, tester);
}
@@ -1904,10 +1906,22 @@
// See the same reason in runUdp4Test().
probeV4TetheringConnectivity(tester, tethered, false /* is4To6 */);
- runTcpTest(tethered.macAddr /* srcMac */, tethered.routerMacAddr /* dstMac */,
- REMOTE_IP4_ADDR /* remoteIp */,
- TEST_IP4_ADDR.getAddress() /* tetheringUpstreamIp */,
- tethered.ipv4Addr /* clientIp */, tester);
+ runTcpTest(tethered.macAddr /* uploadSrcMac */, tethered.routerMacAddr /* uploadDstMac */,
+ tethered.ipv4Addr /* uploadSrcIp */, REMOTE_IP4_ADDR /* uploadDstIp */,
+ REMOTE_IP4_ADDR /* downloadSrcIp */, TEST_IP4_ADDR.getAddress() /* downloadDstIp */,
+ tester);
+ }
+
+ @Test
+ public void testTetherTcpV6() throws Exception {
+ final TetheringTester tester = initTetheringTester(toList(TEST_IP6_ADDR),
+ toList(TEST_IP6_DNS));
+ final TetheredDevice tethered = tester.createTetheredDevice(TEST_MAC, true /* hasIpv6 */);
+
+ runTcpTest(tethered.macAddr /* uploadSrcMac */, tethered.routerMacAddr /* uploadDstMac */,
+ tethered.ipv6Addr /* uploadSrcIp */, REMOTE_IP6_ADDR /* uploadDstIp */,
+ REMOTE_IP6_ADDR /* downloadSrcIp */, tethered.ipv6Addr /* downloadDstIp */,
+ tester);
}
private <T> List<T> toList(T... array) {