From 2e95c356d7ba97fffbe5ebdca82201ca474cd6f9 Mon Sep 17 00:00:00 2001 From: Patrick Rohr Date: Wed, 2 Apr 2025 09:39:45 -0700 Subject: [PATCH 1/4] s/payload/data/ for brevity Test: TH Flag: EXEMPT mainline Bug: 1000001 Change-Id: I03cdb93f616510c3648d91f993577cb4d846a5bd --- .../android/testutils/PacketBuilderUtils.kt | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/staticlibs/testutils/devicetests/com/android/testutils/PacketBuilderUtils.kt b/staticlibs/testutils/devicetests/com/android/testutils/PacketBuilderUtils.kt index 7a952f4df8..dba94d3638 100644 --- a/staticlibs/testutils/devicetests/com/android/testutils/PacketBuilderUtils.kt +++ b/staticlibs/testutils/devicetests/com/android/testutils/PacketBuilderUtils.kt @@ -271,12 +271,12 @@ class RaPkt( class Ip6Pkt( private val src: Inet6Address, private val dst: Inet6Address, - private val payload: L4Packet, + private val data: L4Packet, ) : L3Packet { - constructor(src: String, dst: String, payload: L4Packet) : this( + constructor(src: String, dst: String, data: L4Packet) : this( InetAddress.getByName(src) as Inet6Address, InetAddress.getByName(dst) as Inet6Address, - payload, + data, ) override val etherType = 0x86dd.toShort() @@ -290,8 +290,8 @@ class Ip6Pkt( init { val ipv6Header = ByteBuffer.allocate(40) ipv6Header.putInt((6 shl 28) or (tc shl 20) or flowlabel) - ipv6Header.putShort(payload.size) - ipv6Header.put(payload.proto) + ipv6Header.putShort(data.size) + ipv6Header.put(data.proto) ipv6Header.put(hlim) ipv6Header.put(src.getAddress()) ipv6Header.put(dst.getAddress()) @@ -299,7 +299,7 @@ class Ip6Pkt( val outputStream = ByteArrayOutputStream() outputStream.write(ipv6Header.array()) - outputStream.write(payload.toByteArray()) + outputStream.write(data.toByteArray()) bytes = outputStream.toByteArray() } @@ -315,18 +315,18 @@ class Ip6Pkt( * {@code * val ra = RaPkt(routerLft = 50, reachableTime = 100, flags = "O") * ra.addPioOption(prefix = "2001:db8::1/64", flags = "LA") - * val ipv6 = Ip6Pkt(src = "fe80::1", dst = "fe80::2", payload = ra) - * val ether = EtherPkt(src = "1:2:3:4:5:6", dst = "1:1:1:1:1:1", payload = ipv6) + * val ipv6 = Ip6Pkt(src = "fe80::1", dst = "fe80::2", data = ra) + * val ether = EtherPkt(src = "1:2:3:4:5:6", dst = "1:1:1:1:1:1", data = ipv6) * } * **/ class EtherPkt( dst: MacAddress, src: MacAddress, - payload: L3Packet, + data: L3Packet, ) : Packet { - constructor(dst: String, src: String, payload: L3Packet) : - this(MacAddress.fromString(dst), MacAddress.fromString(src), payload) + constructor(dst: String, src: String, data: L3Packet) : + this(MacAddress.fromString(dst), MacAddress.fromString(src), data) val bytes: ByteArray @@ -334,12 +334,12 @@ class EtherPkt( val ethernetHeader = ByteBuffer.allocate(14) ethernetHeader.put(dst.toByteArray()) ethernetHeader.put(src.toByteArray()) - ethernetHeader.putShort(payload.etherType) + ethernetHeader.putShort(data.etherType) ethernetHeader.flip() val outputStream = ByteArrayOutputStream() outputStream.write(ethernetHeader.array()) - outputStream.write(payload.toByteArray()) + outputStream.write(data.toByteArray()) bytes = outputStream.toByteArray() } From 22727f7bef2c2ae9e735fc226bce68aac1f69af7 Mon Sep 17 00:00:00 2001 From: Patrick Rohr Date: Wed, 2 Apr 2025 10:20:23 -0700 Subject: [PATCH 2/4] Add some documentation to RaPkt Test: TH Flag: EXEMPT mainline Bug: 1000001 Change-Id: I429b316a2660789316f46fae63c621d81dfe67af --- .../android/testutils/PacketBuilderUtils.kt | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/staticlibs/testutils/devicetests/com/android/testutils/PacketBuilderUtils.kt b/staticlibs/testutils/devicetests/com/android/testutils/PacketBuilderUtils.kt index dba94d3638..13a6cb6bd1 100644 --- a/staticlibs/testutils/devicetests/com/android/testutils/PacketBuilderUtils.kt +++ b/staticlibs/testutils/devicetests/com/android/testutils/PacketBuilderUtils.kt @@ -130,6 +130,11 @@ class NaPkt( * Class that facilitates the creation of RA packets. * * Default argument values reflect the rfc4861 defaults where applicable. + * + * @param routerLft lifetime of the default router in seconds. + * @param reachableTime The time, in milliseconds, that a node assumes a neighbor is reachable. + * @param retransTimer The time, in milliseconds, between retransmitted NS messages. + * @param flags The Router Advertisement flags. */ class RaPkt( private val routerLft: Short, @@ -137,6 +142,14 @@ class RaPkt( private val retransTimer: Int, private val flags: EnumSet, ) : L4Packet { + /** + * Convenience constructor accepting flags parameter as String + * + * @param routerLft lifetime of the default router in seconds. + * @param reachableTime The time, in milliseconds, that a node assumes a neighbor is reachable. + * @param retransTimer The time, in milliseconds, between retransmitted NS messages. + * @param flags The Router Advertisement flags as a String; e.g. {@code "MO"}. Defaults to "". + */ constructor( routerLft: Short = 1800, reachableTime: Int = 0, @@ -145,7 +158,9 @@ class RaPkt( ) : this(routerLft, reachableTime, retransTimer, enumSetOfFlags(flags)) enum class RaFlags(override val value: Int) : Flags { + /** Managed address configuration: indicates addresses are available via DHCPv6. */ M(0x80), + /** Other configuration: indicates other configuration info is available via DHCPv6. */ O(0x40), } @@ -169,12 +184,24 @@ class RaPkt( } enum class PioFlags(override val value: Int) : Flags { + /** On-Link: indicates that this prefix can be used for on-link determination. */ L(0x80), + /** Autonomous address-configuration: indicates that this prefix can be used for SLAAC. */ A(0x40), + /** Router Address: obsolete. */ R(0x20), + /** PD Preferred: indicates that the network prefers the use of DHCPv6-PD over SLAAC. */ P(0x10), } + /** + * Add a Prefix Information Option + * + * @param prefix The prefix of an IPv6 address. + * @param validLft The time, in seconds, that the prefix is valid for on-link determination. + * @param preferredLft The time, in seconds, that SLAAC-generated addresses remain preferred. + * @param flags The Prefix Information Option flags. + */ fun addPioOption( prefix: IpPrefix, validLft: Int, @@ -195,6 +222,14 @@ class RaPkt( outputStream.write(pio.array()) } + /** + * Add a Prefix Information Option + * + * @param prefix The IPv6 prefix as a String; e.g. {@code "2001:db8::/64"} + * @param validLft The time, in seconds, that the prefix is valid for on-link determination. + * @param preferredLft The time, in seconds, that SLAAC-generated addresses remain preferred. + * @param flags The PIO flags as a String; e.g. {@code "LA"} + */ fun addPioOption( prefix: String, validLft: Int = 2592000, @@ -204,6 +239,11 @@ class RaPkt( addPioOption(IpPrefix(prefix), validLft, preferredLft, enumSetOfFlags(flags)) } + /** Add a Recursive DNS Server Option + * + * @param dns The list of DNS servers. + * @param lft The time, in seconds, over which the DNS servers may be used for resolution. + */ fun addRdnssOption(dns: List, lft: Int) { val length = 1 + (dns.size * 2) val rdnss = ByteBuffer.allocate(length * 8) // length is in units of 8 octets. @@ -218,11 +258,21 @@ class RaPkt( outputStream.write(rdnss.array()) } + /** Add a Recursive DNS Server Option + * + * @param dns The list of DNS servers as a String; e.g. {@code "2001:db8:1,2001:db8:2"} + * @param lft The time, in seconds, over which the DNS servers may be used for resolution. + */ fun addRdnssOption(dns: String, lft: Int = 1800) { val dnsServers = dns.split(",").map { InetAddress.getByName(it) as Inet6Address } addRdnssOption(dnsServers, lft) } + /** Add a Route Information Option + * + * @param prefix The IPv6 prefix of the route. + * @param lft The lifetime of the route in seconds. + */ fun addRioOption(prefix: IpPrefix, lft: Int) { val rio = ByteBuffer.allocate(24) rio.put(24) // Type = 24 @@ -236,10 +286,20 @@ class RaPkt( outputStream.write(rio.array()) } + /** Add a Route Information Option + * + * @param prefix The IPv6 prefix of the route as a String; e.g. {@code "2001:db8::/48"} + * @param lft The lifetime of the route in seconds. + */ fun addRioOption(prefix: String, lft: Int = 1800) { addRioOption(IpPrefix(prefix), lft) } + /** Add a PREF64 Option + * + * @param prefix The PREF64 prefix. + * @param lft The lifetime of the PREF64 prefix in seconds. + */ fun addPref64Option(prefix: IpPrefix, lft: Int) { val pref64 = ByteBuffer.allocate(16) pref64.put(38) // Type = 38 @@ -260,6 +320,11 @@ class RaPkt( outputStream.write(pref64.array()) } + /** Add a PREF64 Option + * + * @param prefix The PREF64 prefix as a String; e.g. {@code "2001:db8::/64"} + * @param lft The lifetime of the PREF64 prefix in seconds. + */ fun addPref64Option(prefix: String, lft: Int = 1800) { addPref64Option(IpPrefix(prefix), lft) } From 91ef24c6f6c5535bbf18094ad8d728244fbe167f Mon Sep 17 00:00:00 2001 From: Patrick Rohr Date: Wed, 2 Apr 2025 11:37:24 -0700 Subject: [PATCH 3/4] Return this from add*Option methods To support friendlier builder syntax. Test: TH Flag: EXEMPT mainline Bug: 1000001 Change-Id: Iaf4250da61e2c0b5311682b2c462eb07467428f7 --- .../android/testutils/PacketBuilderUtils.kt | 40 ++++++++++++------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/staticlibs/testutils/devicetests/com/android/testutils/PacketBuilderUtils.kt b/staticlibs/testutils/devicetests/com/android/testutils/PacketBuilderUtils.kt index 13a6cb6bd1..4d5544a14c 100644 --- a/staticlibs/testutils/devicetests/com/android/testutils/PacketBuilderUtils.kt +++ b/staticlibs/testutils/devicetests/com/android/testutils/PacketBuilderUtils.kt @@ -105,13 +105,14 @@ class NaPkt( } /** Add Target Link-Layer Address Option */ - fun addTllaOption(lla: MacAddress) { + fun addTllaOption(lla: MacAddress): NaPkt { val llao = ByteBuffer.allocate(8) llao.put(2) // Type = 2 (Target Link-layer Address) llao.put(1) // Length in units of 8 octets llao.put(lla.toByteArray()) llao.flip() outputStream.write(llao.array()) + return this } /** @@ -119,8 +120,8 @@ class NaPkt( * * @param lla Link-Layer Address as a String; e.g. {@code "0:0:5e:0:53:0"} */ - fun addTllaOption(lla: String) { - addTllaOption(MacAddress.fromString(lla)) + fun addTllaOption(lla: String): NaPkt { + return addTllaOption(MacAddress.fromString(lla)) } override fun toByteArray() = outputStream.toByteArray() @@ -207,7 +208,7 @@ class RaPkt( validLft: Int, preferredLft: Int, flags: EnumSet, - ) { + ): RaPkt { if (!prefix.isIPv6()) throw IllegalArgumentException("Invalid prefix") val pio = ByteBuffer.allocate(32) pio.put(3) // Type = 3 @@ -220,6 +221,7 @@ class RaPkt( pio.put(prefix.getRawAddress()) pio.flip() outputStream.write(pio.array()) + return this } /** @@ -235,8 +237,13 @@ class RaPkt( validLft: Int = 2592000, preferredLft: Int = 604800, flags: String = "L", - ) { - addPioOption(IpPrefix(prefix), validLft, preferredLft, enumSetOfFlags(flags)) + ): RaPkt { + return addPioOption( + IpPrefix(prefix), + validLft, + preferredLft, + enumSetOfFlags(flags) + ) } /** Add a Recursive DNS Server Option @@ -244,7 +251,7 @@ class RaPkt( * @param dns The list of DNS servers. * @param lft The time, in seconds, over which the DNS servers may be used for resolution. */ - fun addRdnssOption(dns: List, lft: Int) { + fun addRdnssOption(dns: List, lft: Int): RaPkt { val length = 1 + (dns.size * 2) val rdnss = ByteBuffer.allocate(length * 8) // length is in units of 8 octets. rdnss.put(25) // Type = 25 @@ -256,6 +263,7 @@ class RaPkt( } rdnss.flip() outputStream.write(rdnss.array()) + return this } /** Add a Recursive DNS Server Option @@ -263,9 +271,9 @@ class RaPkt( * @param dns The list of DNS servers as a String; e.g. {@code "2001:db8:1,2001:db8:2"} * @param lft The time, in seconds, over which the DNS servers may be used for resolution. */ - fun addRdnssOption(dns: String, lft: Int = 1800) { + fun addRdnssOption(dns: String, lft: Int = 1800): RaPkt { val dnsServers = dns.split(",").map { InetAddress.getByName(it) as Inet6Address } - addRdnssOption(dnsServers, lft) + return addRdnssOption(dnsServers, lft) } /** Add a Route Information Option @@ -273,7 +281,7 @@ class RaPkt( * @param prefix The IPv6 prefix of the route. * @param lft The lifetime of the route in seconds. */ - fun addRioOption(prefix: IpPrefix, lft: Int) { + fun addRioOption(prefix: IpPrefix, lft: Int): RaPkt { val rio = ByteBuffer.allocate(24) rio.put(24) // Type = 24 rio.put(3) // Length = 3 -- TODO: support variable prefix length @@ -284,6 +292,7 @@ class RaPkt( rio.put(prefix.rawAddress) rio.flip() outputStream.write(rio.array()) + return this } /** Add a Route Information Option @@ -291,8 +300,8 @@ class RaPkt( * @param prefix The IPv6 prefix of the route as a String; e.g. {@code "2001:db8::/48"} * @param lft The lifetime of the route in seconds. */ - fun addRioOption(prefix: String, lft: Int = 1800) { - addRioOption(IpPrefix(prefix), lft) + fun addRioOption(prefix: String, lft: Int = 1800): RaPkt { + return addRioOption(IpPrefix(prefix), lft) } /** Add a PREF64 Option @@ -300,7 +309,7 @@ class RaPkt( * @param prefix The PREF64 prefix. * @param lft The lifetime of the PREF64 prefix in seconds. */ - fun addPref64Option(prefix: IpPrefix, lft: Int) { + fun addPref64Option(prefix: IpPrefix, lft: Int): RaPkt { val pref64 = ByteBuffer.allocate(16) pref64.put(38) // Type = 38 pref64.put(2) // Length = 2 (*8) @@ -318,6 +327,7 @@ class RaPkt( pref64.put(prefix.rawAddress, 0 /*offset*/, 12 /*length*/) // highest 96 bits of prefix. pref64.flip() outputStream.write(pref64.array()) + return this } /** Add a PREF64 Option @@ -325,8 +335,8 @@ class RaPkt( * @param prefix The PREF64 prefix as a String; e.g. {@code "2001:db8::/64"} * @param lft The lifetime of the PREF64 prefix in seconds. */ - fun addPref64Option(prefix: String, lft: Int = 1800) { - addPref64Option(IpPrefix(prefix), lft) + fun addPref64Option(prefix: String, lft: Int = 1800): RaPkt { + return addPref64Option(IpPrefix(prefix), lft) } override fun toByteArray() = outputStream.toByteArray() From e2db1fe7e04727a3d7b8c29269e62a26297cba93 Mon Sep 17 00:00:00 2001 From: Patrick Rohr Date: Wed, 2 Apr 2025 11:41:01 -0700 Subject: [PATCH 4/4] Use Kotlin syntax for getters Test: TH Flag: EXEMPT mainline Bug: 1000001 Change-Id: Ic4b22e2c6154bf634bfbbe6c539bc6b26a29b3af --- .../com/android/testutils/PacketBuilderUtils.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/staticlibs/testutils/devicetests/com/android/testutils/PacketBuilderUtils.kt b/staticlibs/testutils/devicetests/com/android/testutils/PacketBuilderUtils.kt index 4d5544a14c..3475c72584 100644 --- a/staticlibs/testutils/devicetests/com/android/testutils/PacketBuilderUtils.kt +++ b/staticlibs/testutils/devicetests/com/android/testutils/PacketBuilderUtils.kt @@ -213,12 +213,12 @@ class RaPkt( val pio = ByteBuffer.allocate(32) pio.put(3) // Type = 3 pio.put(4) // Length = 4 (*8) - pio.put(prefix.getPrefixLength().toByte()) // Prefix Length + pio.put(prefix.prefixLength.toByte()) // Prefix Length pio.put(flags.toByte()) // Flags pio.putInt(validLft) // Valid Lifetime pio.putInt(preferredLft) // Preferred Lifetime pio.putInt(0) // Reserved2 - pio.put(prefix.getRawAddress()) + pio.put(prefix.rawAddress) pio.flip() outputStream.write(pio.array()) return this @@ -368,8 +368,8 @@ class Ip6Pkt( ipv6Header.putShort(data.size) ipv6Header.put(data.proto) ipv6Header.put(hlim) - ipv6Header.put(src.getAddress()) - ipv6Header.put(dst.getAddress()) + ipv6Header.put(src.address) + ipv6Header.put(dst.address) ipv6Header.flip() val outputStream = ByteArrayOutputStream()