summaryrefslogtreecommitdiff
path: root/common/testutils/hostdevice/com/android/testutils/PacketFilter.kt
diff options
context:
space:
mode:
Diffstat (limited to 'common/testutils/hostdevice/com/android/testutils/PacketFilter.kt')
-rw-r--r--common/testutils/hostdevice/com/android/testutils/PacketFilter.kt148
1 files changed, 0 insertions, 148 deletions
diff --git a/common/testutils/hostdevice/com/android/testutils/PacketFilter.kt b/common/testutils/hostdevice/com/android/testutils/PacketFilter.kt
deleted file mode 100644
index 1bb6d683..00000000
--- a/common/testutils/hostdevice/com/android/testutils/PacketFilter.kt
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.testutils
-
-import java.net.Inet4Address
-import java.util.function.Predicate
-
-// Some of the below constants are duplicated with NetworkStackConstants, but this is a hostdevice
-// library usable for host-side tests, so device-side utils are not usable, and there is no
-// host-side non-test library to host common constants.
-private const val ETHER_TYPE_OFFSET = 12
-private const val ETHER_HEADER_LENGTH = 14
-private const val IPV4_PROTOCOL_OFFSET = ETHER_HEADER_LENGTH + 9
-private const val IPV6_PROTOCOL_OFFSET = ETHER_HEADER_LENGTH + 6
-private const val IPV4_CHECKSUM_OFFSET = ETHER_HEADER_LENGTH + 10
-private const val IPV4_DST_OFFSET = ETHER_HEADER_LENGTH + 16
-private const val IPV4_HEADER_LENGTH = 20
-private const val IPV6_HEADER_LENGTH = 40
-private const val IPV4_PAYLOAD_OFFSET = ETHER_HEADER_LENGTH + IPV4_HEADER_LENGTH
-private const val IPV6_PAYLOAD_OFFSET = ETHER_HEADER_LENGTH + IPV6_HEADER_LENGTH
-private const val UDP_HEADER_LENGTH = 8
-private const val BOOTP_OFFSET = IPV4_PAYLOAD_OFFSET + UDP_HEADER_LENGTH
-private const val BOOTP_TID_OFFSET = BOOTP_OFFSET + 4
-private const val BOOTP_CLIENT_MAC_OFFSET = BOOTP_OFFSET + 28
-private const val DHCP_OPTIONS_OFFSET = BOOTP_OFFSET + 240
-private const val ARP_OPCODE_OFFSET = ETHER_HEADER_LENGTH + 6
-
-/**
- * A [Predicate] that matches a [ByteArray] if it contains the specified [bytes] at the specified
- * [offset].
- */
-class OffsetFilter(val offset: Int, vararg val bytes: Byte) : Predicate<ByteArray> {
- override fun test(packet: ByteArray) =
- bytes.withIndex().all { it.value == packet[offset + it.index] }
-}
-
-private class UdpPortFilter(
- private val udpOffset: Int,
- private val src: Short?,
- private val dst: Short?
-) : Predicate<ByteArray> {
- override fun test(t: ByteArray): Boolean {
- if (src != null && !OffsetFilter(udpOffset,
- src.toInt().ushr(8).toByte(), src.toByte()).test(t)) {
- return false
- }
-
- if (dst != null && !OffsetFilter(udpOffset + 2,
- dst.toInt().ushr(8).toByte(), dst.toByte()).test(t)) {
- return false
- }
- return true
- }
-}
-
-/**
- * A [Predicate] that matches ethernet-encapped packets that contain an UDP over IPv4 datagram.
- */
-class IPv4UdpFilter @JvmOverloads constructor(
- srcPort: Short? = null,
- dstPort: Short? = null
-) : Predicate<ByteArray> {
- private val impl = OffsetFilter(ETHER_TYPE_OFFSET, 0x08, 0x00 /* IPv4 */).and(
- OffsetFilter(IPV4_PROTOCOL_OFFSET, 17 /* UDP */)).and(
- UdpPortFilter(IPV4_PAYLOAD_OFFSET, srcPort, dstPort))
- override fun test(t: ByteArray) = impl.test(t)
-}
-
-/**
- * A [Predicate] that matches ethernet-encapped packets that contain an UDP over IPv6 datagram.
- */
-class IPv6UdpFilter @JvmOverloads constructor(
- srcPort: Short? = null,
- dstPort: Short? = null
-) : Predicate<ByteArray> {
- private val impl = OffsetFilter(ETHER_TYPE_OFFSET, 0x86.toByte(), 0xdd.toByte() /* IPv6 */).and(
- OffsetFilter(IPV6_PROTOCOL_OFFSET, 17 /* UDP */)).and(
- UdpPortFilter(IPV6_PAYLOAD_OFFSET, srcPort, dstPort))
- override fun test(t: ByteArray) = impl.test(t)
-}
-
-/**
- * A [Predicate] that matches ethernet-encapped packets sent to the specified IPv4 destination.
- */
-class IPv4DstFilter(dst: Inet4Address) : Predicate<ByteArray> {
- private val impl = OffsetFilter(IPV4_DST_OFFSET, *dst.address)
- override fun test(t: ByteArray) = impl.test(t)
-}
-
-/**
- * A [Predicate] that matches ethernet-encapped ARP requests.
- */
-class ArpRequestFilter : Predicate<ByteArray> {
- private val impl = OffsetFilter(ETHER_TYPE_OFFSET, 0x08, 0x06 /* ARP */)
- .and(OffsetFilter(ARP_OPCODE_OFFSET, 0x00, 0x01 /* request */))
- override fun test(t: ByteArray) = impl.test(t)
-}
-
-/**
- * A [Predicate] that matches ethernet-encapped DHCP packets sent from a DHCP client.
- */
-class DhcpClientPacketFilter : Predicate<ByteArray> {
- private val impl = IPv4UdpFilter(srcPort = 68, dstPort = 67)
- override fun test(t: ByteArray) = impl.test(t)
-}
-
-/**
- * A [Predicate] that matches a [ByteArray] if it contains a ethernet-encapped DHCP packet that
- * contains the specified option with the specified [bytes] as value.
- */
-class DhcpOptionFilter(val option: Byte, vararg val bytes: Byte) : Predicate<ByteArray> {
- override fun test(packet: ByteArray): Boolean {
- val option = findDhcpOption(packet, option) ?: return false
- return option.contentEquals(bytes)
- }
-}
-
-/**
- * Find a DHCP option in a packet and return its value, if found.
- */
-fun findDhcpOption(packet: ByteArray, option: Byte): ByteArray? =
- findOptionOffset(packet, option, DHCP_OPTIONS_OFFSET)?.let {
- val optionLen = packet[it + 1]
- return packet.copyOfRange(it + 2 /* type, length bytes */, it + 2 + optionLen)
- }
-
-private tailrec fun findOptionOffset(packet: ByteArray, option: Byte, searchOffset: Int): Int? {
- if (packet.size <= searchOffset + 2 /* type, length bytes */) return null
-
- return if (packet[searchOffset] == option) searchOffset else {
- val optionLen = packet[searchOffset + 1]
- findOptionOffset(packet, option, searchOffset + 2 + optionLen)
- }
-}