EthernetTetheringTest: add testIcmpv4Echo
Bug: 237369591 Test: atest EthernetTetheringTest Change-Id: I96278c17ce97b63860b9379675c6ac2941b4016f
This commit is contained in:
@@ -1547,7 +1547,7 @@ public class EthernetTetheringTest {
|
|||||||
// TODO: move ICMPv4 packet build function to common utilis.
|
// TODO: move ICMPv4 packet build function to common utilis.
|
||||||
@NonNull
|
@NonNull
|
||||||
private ByteBuffer buildIcmpEchoPacketV4(
|
private ByteBuffer buildIcmpEchoPacketV4(
|
||||||
@NonNull final MacAddress srcMac, @NonNull final MacAddress dstMac,
|
@Nullable final MacAddress srcMac, @Nullable final MacAddress dstMac,
|
||||||
@NonNull final Inet4Address srcIp, @NonNull final Inet4Address dstIp,
|
@NonNull final Inet4Address srcIp, @NonNull final Inet4Address dstIp,
|
||||||
int type, short id, short seq) throws Exception {
|
int type, short id, short seq) throws Exception {
|
||||||
if (type != ICMP_ECHO && type != ICMP_ECHOREPLY) {
|
if (type != ICMP_ECHO && type != ICMP_ECHOREPLY) {
|
||||||
@@ -1560,30 +1560,41 @@ public class EthernetTetheringTest {
|
|||||||
payload.putShort(seq);
|
payload.putShort(seq);
|
||||||
payload.rewind();
|
payload.rewind();
|
||||||
|
|
||||||
final int etherHeaderLen = Struct.getSize(EthernetHeader.class);
|
final boolean hasEther = (srcMac != null && dstMac != null);
|
||||||
|
final int etherHeaderLen = hasEther ? Struct.getSize(EthernetHeader.class) : 0;
|
||||||
final int ipv4HeaderLen = Struct.getSize(Ipv4Header.class);
|
final int ipv4HeaderLen = Struct.getSize(Ipv4Header.class);
|
||||||
final int Icmpv4HeaderLen = Struct.getSize(Icmpv4Header.class);
|
final int Icmpv4HeaderLen = Struct.getSize(Icmpv4Header.class);
|
||||||
final int payloadLen = payload.limit();
|
final int payloadLen = payload.limit();
|
||||||
final ByteBuffer packet = ByteBuffer.allocate(etherHeaderLen + ipv4HeaderLen
|
final ByteBuffer packet = ByteBuffer.allocate(etherHeaderLen + ipv4HeaderLen
|
||||||
+ Icmpv4HeaderLen + payloadLen);
|
+ Icmpv4HeaderLen + payloadLen);
|
||||||
|
|
||||||
final EthernetHeader ethHeader = new EthernetHeader(dstMac, srcMac, ETHER_TYPE_IPV4);
|
// [1] Ethernet header
|
||||||
|
if (hasEther) {
|
||||||
|
final EthernetHeader ethHeader = new EthernetHeader(dstMac, srcMac, ETHER_TYPE_IPV4);
|
||||||
|
ethHeader.writeToByteBuffer(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
// [2] IP header
|
||||||
final Ipv4Header ipv4Header = new Ipv4Header(TYPE_OF_SERVICE,
|
final Ipv4Header ipv4Header = new Ipv4Header(TYPE_OF_SERVICE,
|
||||||
(short) 0 /* totalLength, calculate later */, ID,
|
(short) 0 /* totalLength, calculate later */, ID,
|
||||||
FLAGS_AND_FRAGMENT_OFFSET, TIME_TO_LIVE, (byte) IPPROTO_ICMP,
|
FLAGS_AND_FRAGMENT_OFFSET, TIME_TO_LIVE, (byte) IPPROTO_ICMP,
|
||||||
(short) 0 /* checksum, calculate later */, srcIp, dstIp);
|
(short) 0 /* checksum, calculate later */, srcIp, dstIp);
|
||||||
|
ipv4Header.writeToByteBuffer(packet);
|
||||||
|
|
||||||
|
// [3] ICMP header
|
||||||
final Icmpv4Header icmpv4Header = new Icmpv4Header((byte) type, ICMPECHO_CODE,
|
final Icmpv4Header icmpv4Header = new Icmpv4Header((byte) type, ICMPECHO_CODE,
|
||||||
(short) 0 /* checksum, calculate later */);
|
(short) 0 /* checksum, calculate later */);
|
||||||
|
|
||||||
ethHeader.writeToByteBuffer(packet);
|
|
||||||
ipv4Header.writeToByteBuffer(packet);
|
|
||||||
icmpv4Header.writeToByteBuffer(packet);
|
icmpv4Header.writeToByteBuffer(packet);
|
||||||
|
|
||||||
|
// [4] Payload
|
||||||
packet.put(payload);
|
packet.put(payload);
|
||||||
packet.flip();
|
packet.flip();
|
||||||
|
|
||||||
// Used for updating IP header fields. IPv4 header offset in buffer equals ethernet header
|
// [5] Finalize packet
|
||||||
// length because IPv4 header is located next to ethernet header.
|
// Used for updating IP header fields. If there is Ehternet header, IPv4 header offset
|
||||||
final int ipv4HeaderOffset = etherHeaderLen;
|
// in buffer equals ethernet header length because IPv4 header is located next to ethernet
|
||||||
|
// header. Otherwise, IPv4 header offset is 0.
|
||||||
|
final int ipv4HeaderOffset = hasEther ? etherHeaderLen : 0;
|
||||||
|
|
||||||
// Populate the IPv4 totalLength field.
|
// Populate the IPv4 totalLength field.
|
||||||
packet.putShort(ipv4HeaderOffset + IPV4_LENGTH_OFFSET,
|
packet.putShort(ipv4HeaderOffset + IPV4_LENGTH_OFFSET,
|
||||||
@@ -1600,6 +1611,43 @@ public class EthernetTetheringTest {
|
|||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private ByteBuffer buildIcmpEchoPacketV4(@NonNull final Inet4Address srcIp,
|
||||||
|
@NonNull final Inet4Address dstIp, int type, short id, short seq)
|
||||||
|
throws Exception {
|
||||||
|
return buildIcmpEchoPacketV4(null /* srcMac */, null /* dstMac */, srcIp, dstIp,
|
||||||
|
type, id, seq);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIcmpv4Echo() throws Exception {
|
||||||
|
final TetheringTester tester = initTetheringTester(toList(TEST_IP4_ADDR),
|
||||||
|
toList(TEST_IP4_DNS));
|
||||||
|
final TetheredDevice tethered = tester.createTetheredDevice(TEST_MAC, false /* hasIpv6 */);
|
||||||
|
|
||||||
|
// TODO: remove the connectivity verification for upstream connected notification race.
|
||||||
|
// See the same reason in runUdp4Test().
|
||||||
|
probeV4TetheringConnectivity(tester, tethered, false /* is4To6 */);
|
||||||
|
|
||||||
|
final ByteBuffer request = buildIcmpEchoPacketV4(tethered.macAddr /* srcMac */,
|
||||||
|
tethered.routerMacAddr /* dstMac */, tethered.ipv4Addr /* srcIp */,
|
||||||
|
REMOTE_IP4_ADDR /* dstIp */, ICMP_ECHO, ICMPECHO_ID, ICMPECHO_SEQ);
|
||||||
|
tester.verifyUpload(request, p -> {
|
||||||
|
Log.d(TAG, "Packet in upstream: " + dumpHexString(p));
|
||||||
|
|
||||||
|
return isExpectedIcmpPacket(p, false /* hasEth */, true /* isIpv4 */, ICMP_ECHO);
|
||||||
|
});
|
||||||
|
|
||||||
|
final ByteBuffer reply = buildIcmpEchoPacketV4(REMOTE_IP4_ADDR /* srcIp*/,
|
||||||
|
(Inet4Address) TEST_IP4_ADDR.getAddress() /* dstIp */, ICMP_ECHOREPLY, ICMPECHO_ID,
|
||||||
|
ICMPECHO_SEQ);
|
||||||
|
tester.verifyDownload(reply, p -> {
|
||||||
|
Log.d(TAG, "Packet in downstream: " + dumpHexString(p));
|
||||||
|
|
||||||
|
return isExpectedIcmpPacket(p, true /* hasEth */, true /* isIpv4 */, ICMP_ECHOREPLY);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: support R device. See b/234727688.
|
// TODO: support R device. See b/234727688.
|
||||||
@Test
|
@Test
|
||||||
@IgnoreUpTo(Build.VERSION_CODES.R)
|
@IgnoreUpTo(Build.VERSION_CODES.R)
|
||||||
|
|||||||
Reference in New Issue
Block a user