• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package android.net.apf
17 
18 import android.net.apf.ApfCounterTracker.Counter
19 import android.net.apf.ApfCounterTracker.Counter.CORRUPT_DNS_PACKET
20 import android.net.apf.ApfCounterTracker.Counter.DROPPED_ETHERTYPE_NOT_ALLOWED
21 import android.net.apf.ApfCounterTracker.Counter.DROPPED_ETH_BROADCAST
22 import android.net.apf.ApfCounterTracker.Counter.DROPPED_RA
23 import android.net.apf.ApfCounterTracker.Counter.PASSED_ALLOCATE_FAILURE
24 import android.net.apf.ApfCounterTracker.Counter.PASSED_ARP_REQUEST
25 import android.net.apf.ApfCounterTracker.Counter.PASSED_MDNS
26 import android.net.apf.ApfCounterTracker.Counter.PASSED_TRANSMIT_FAILURE
27 import android.net.apf.ApfCounterTracker.Counter.TOTAL_PACKETS
28 import android.net.apf.ApfTestHelpers.Companion.DROP
29 import android.net.apf.ApfTestHelpers.Companion.MIN_PKT_SIZE
30 import android.net.apf.ApfTestHelpers.Companion.PASS
31 import android.net.apf.ApfTestHelpers.Companion.decodeCountersIntoMap
32 import android.net.apf.BaseApfGenerator.APF_VERSION_2
33 import android.net.apf.BaseApfGenerator.APF_VERSION_3
34 import android.net.apf.BaseApfGenerator.DROP_LABEL
35 import android.net.apf.BaseApfGenerator.IllegalInstructionException
36 import android.net.apf.BaseApfGenerator.MemorySlot
37 import android.net.apf.BaseApfGenerator.PASS_LABEL
38 import android.net.apf.BaseApfGenerator.Register.R0
39 import android.net.apf.BaseApfGenerator.Register.R1
40 import androidx.test.filters.SmallTest
41 import com.android.net.module.util.HexDump
42 import com.android.net.module.util.Struct
43 import com.android.net.module.util.structs.EthernetHeader
44 import com.android.net.module.util.structs.Ipv4Header
45 import com.android.net.module.util.structs.UdpHeader
46 import com.android.testutils.DevSdkIgnoreRule
47 import com.android.testutils.DevSdkIgnoreRunner
48 import java.nio.ByteBuffer
49 import kotlin.test.assertContentEquals
50 import kotlin.test.assertEquals
51 import kotlin.test.assertFailsWith
52 import org.junit.After
53 import org.junit.Assume.assumeTrue
54 import org.junit.Before
55 import org.junit.Rule
56 import org.junit.Test
57 import org.junit.runner.RunWith
58 import org.junit.runners.Parameterized
59 
60 const val ETH_HLEN = 14
61 const val IPV4_HLEN = 20
62 const val IPPROTO_UDP = 17
63 
64 /**
65  * Tests for APF generator instructions.
66  */
67 @RunWith(DevSdkIgnoreRunner::class)
68 @SmallTest
69 class ApfGeneratorTest {
70 
71     companion object {
72         @Parameterized.Parameters
73         @JvmStatic
datanull74         fun data(): Iterable<Any?> {
75             return mutableListOf<Int?>(
76                 ApfJniUtils.APF_INTERPRETER_VERSION_V6,
77                 ApfJniUtils.APF_INTERPRETER_VERSION_NEXT
78             )
79         }
80     }
81 
82     @get:Rule val ignoreRule = DevSdkIgnoreRule()
83 
84     // Indicates which apfInterpreter to load.
85     @Parameterized.Parameter(0)
86     @JvmField
87     var apfInterpreterVersion: Int = ApfJniUtils.APF_INTERPRETER_VERSION_NEXT
88 
89     private val ramSize = 2048
90     private val clampSize = 2048
91 
92     private val testPacket = byteArrayOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
93     private lateinit var apfTestHelpers: ApfTestHelpers
94 
95     @Before
setUpnull96     fun setUp() {
97         apfTestHelpers = ApfTestHelpers(apfInterpreterVersion)
98     }
99 
100     @After
tearDownnull101     fun tearDown() {
102         apfTestHelpers.resetTransmittedPacketMemory()
103     }
104 
105     @Test
testDataInstructionMustComeFirstnull106     fun testDataInstructionMustComeFirst() {
107         var gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
108         gen.addAllocateR0()
109         assertFailsWith<IllegalInstructionException> { gen.addData(ByteArray(3) { 0x01 }) }
110     }
111 
112     @Test
testApfInstructionEncodingSizeChecknull113     fun testApfInstructionEncodingSizeCheck() {
114         var gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
115         assertFailsWith<IllegalArgumentException> {
116             ApfV6Generator(ByteArray(65536) { 0x01 }, apfInterpreterVersion, ramSize, clampSize)
117         }
118         assertFailsWith<IllegalArgumentException> { gen.addAllocate(65536) }
119         assertFailsWith<IllegalArgumentException> { gen.addAllocate(-1) }
120         assertFailsWith<IllegalArgumentException> { gen.addDataCopy(-1, 1) }
121         assertFailsWith<IllegalArgumentException> { gen.addPacketCopy(-1, 1) }
122         assertFailsWith<IllegalArgumentException> { gen.addDataCopy(1, 256) }
123         assertFailsWith<IllegalArgumentException> { gen.addPacketCopy(1, 256) }
124         assertFailsWith<IllegalArgumentException> { gen.addDataCopy(1, -1) }
125         assertFailsWith<IllegalArgumentException> { gen.addPacketCopy(1, -1) }
126         assertFailsWith<IllegalArgumentException> { gen.addPacketCopyFromR0(256) }
127         assertFailsWith<IllegalArgumentException> { gen.addDataCopyFromR0(256) }
128         assertFailsWith<IllegalArgumentException> { gen.addPacketCopyFromR0(-1) }
129         assertFailsWith<IllegalArgumentException> { gen.addDataCopyFromR0(-1) }
130         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsQ(
131                 byteArrayOf(1, 'A'.code.toByte(), 0, 0),
132                 256,
133                 ApfV4Generator.DROP_LABEL
134         ) }
135         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsQ(
136                 byteArrayOf(1, 'a'.code.toByte(), 0, 0),
137                 0x0c,
138                 ApfV4Generator.DROP_LABEL
139         ) }
140         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsQ(
141                 byteArrayOf(1, '.'.code.toByte(), 0, 0),
142                 0x0c,
143                 ApfV4Generator.DROP_LABEL
144         ) }
145         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsQ(
146                 byteArrayOf(0, 0),
147                 0xc0,
148                 ApfV4Generator.DROP_LABEL
149         ) }
150         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsQ(
151                 byteArrayOf(1, 'A'.code.toByte()),
152                 0xc0,
153                 ApfV4Generator.DROP_LABEL
154         ) }
155         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsQ(
156                 byteArrayOf(64) + ByteArray(64) { 'A'.code.toByte() } + byteArrayOf(0, 0),
157                 0xc0,
158                 ApfV4Generator.DROP_LABEL
159         ) }
160         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsQ(
161                 byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte(), 0),
162                 0xc0,
163                 ApfV4Generator.DROP_LABEL
164         ) }
165         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsQ(
166                 byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte()),
167                 0xc0,
168                 ApfV4Generator.DROP_LABEL
169         ) }
170         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsQ(
171                 byteArrayOf(1, 'A'.code.toByte(), 0, 0),
172                 256,
173                 ApfV4Generator.DROP_LABEL
174         ) }
175         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsQ(
176                 byteArrayOf(1, 'a'.code.toByte(), 0, 0),
177                 0x0c,
178                 ApfV4Generator.DROP_LABEL
179         ) }
180         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsQ(
181                 byteArrayOf(1, '.'.code.toByte(), 0, 0),
182                 0x0c,
183                 ApfV4Generator.DROP_LABEL
184         ) }
185         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsQ(
186                 byteArrayOf(0, 0),
187                 0xc0,
188                 ApfV4Generator.DROP_LABEL
189         ) }
190         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsQ(
191                 byteArrayOf(1, 'A'.code.toByte()),
192                 0xc0,
193                 ApfV4Generator.DROP_LABEL
194         ) }
195         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsQ(
196                 byteArrayOf(64) + ByteArray(64) { 'A'.code.toByte() } + byteArrayOf(0, 0),
197                 0xc0,
198                 ApfV4Generator.DROP_LABEL
199         ) }
200         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsQ(
201                 byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte(), 0),
202                 0xc0,
203                 ApfV4Generator.DROP_LABEL
204         ) }
205         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsQ(
206                 byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte()),
207                 0xc0,
208                 ApfV4Generator.DROP_LABEL
209         ) }
210         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsA(
211                 byteArrayOf(1, 'a'.code.toByte(), 0, 0),
212                 ApfV4Generator.DROP_LABEL
213         ) }
214         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsA(
215                 byteArrayOf(1, '.'.code.toByte(), 0, 0),
216                 ApfV4Generator.DROP_LABEL
217         ) }
218         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsA(
219                 byteArrayOf(0, 0),
220                 ApfV4Generator.DROP_LABEL
221         ) }
222         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsA(
223                 byteArrayOf(1, 'A'.code.toByte()),
224                 ApfV4Generator.DROP_LABEL
225         ) }
226         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsA(
227                 byteArrayOf(64) + ByteArray(64) { 'A'.code.toByte() } + byteArrayOf(0, 0),
228                 ApfV4Generator.DROP_LABEL
229         ) }
230         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsA(
231                 byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte(), 0),
232                 ApfV4Generator.DROP_LABEL
233         ) }
234         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0DoesNotContainDnsA(
235                 byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte()),
236                 ApfV4Generator.DROP_LABEL
237         ) }
238         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsA(
239                 byteArrayOf(1, 'a'.code.toByte(), 0, 0),
240                 ApfV4Generator.DROP_LABEL
241         ) }
242         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsA(
243                 byteArrayOf(1, '.'.code.toByte(), 0, 0),
244                 ApfV4Generator.DROP_LABEL
245         ) }
246         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsA(
247                 byteArrayOf(0, 0),
248                 ApfV4Generator.DROP_LABEL
249         ) }
250         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsA(
251                 byteArrayOf(1, 'A'.code.toByte()),
252                 ApfV4Generator.DROP_LABEL
253         ) }
254         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsA(
255                 byteArrayOf(64) + ByteArray(64) { 'A'.code.toByte() } + byteArrayOf(0, 0),
256                 ApfV4Generator.DROP_LABEL
257         ) }
258         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsA(
259                 byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte(), 0),
260                 ApfV4Generator.DROP_LABEL
261         ) }
262         assertFailsWith<IllegalArgumentException> { gen.addJumpIfPktAtR0ContainDnsA(
263                 byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte()),
264                 ApfV4Generator.DROP_LABEL
265         ) }
266         assertFailsWith<IllegalArgumentException> {
267             gen.addJumpIfBytesAtR0Equal(ByteArray(2048) { 1 }, DROP_LABEL)
268         }
269         assertFailsWith<IllegalArgumentException> {
270             gen.addJumpIfBytesAtR0NotEqual(ByteArray(2048) { 1 }, DROP_LABEL)
271         }
272         assertFailsWith<IllegalArgumentException> { gen.addCountAndDrop(PASSED_ARP_REQUEST) }
273         assertFailsWith<IllegalArgumentException> { gen.addCountAndPass(DROPPED_ETH_BROADCAST) }
274         assertFailsWith<IllegalArgumentException> {
275             gen.addCountAndDropIfR0Equals(3, PASSED_ARP_REQUEST)
276         }
277         assertFailsWith<IllegalArgumentException> {
278             gen.addCountAndPassIfR0Equals(3, DROPPED_ETH_BROADCAST)
279         }
280         assertFailsWith<IllegalArgumentException> {
281             gen.addCountAndDropIfR0NotEquals(3, PASSED_ARP_REQUEST)
282         }
283         assertFailsWith<IllegalArgumentException> {
284             gen.addCountAndPassIfR0NotEquals(3, DROPPED_ETH_BROADCAST)
285         }
286         assertFailsWith<IllegalArgumentException> {
287             gen.addCountAndDropIfR0LessThan(3, PASSED_ARP_REQUEST)
288         }
289         assertFailsWith<IllegalArgumentException> {
290             gen.addCountAndPassIfR0LessThan(3, DROPPED_ETH_BROADCAST)
291         }
292         assertFailsWith<IllegalArgumentException> {
293             gen.addCountAndDropIfR0GreaterThan(3, PASSED_ARP_REQUEST)
294         }
295         assertFailsWith<IllegalArgumentException> {
296             gen.addCountAndPassIfR0GreaterThan(3, DROPPED_ETH_BROADCAST)
297         }
298         assertFailsWith<IllegalArgumentException> {
299             gen.addCountAndDropIfBytesAtR0NotEqual(byteArrayOf(1), PASSED_ARP_REQUEST)
300         }
301         assertFailsWith<IllegalArgumentException> {
302             gen.addCountAndDropIfBytesAtR0Equal(byteArrayOf(1), PASSED_ARP_REQUEST)
303         }
304         assertFailsWith<IllegalArgumentException> {
305             gen.addCountAndPassIfBytesAtR0Equal(byteArrayOf(1), DROPPED_ETH_BROADCAST)
306         }
307         assertFailsWith<IllegalArgumentException> {
308             gen.addCountAndDropIfR0AnyBitsSet(3, PASSED_ARP_REQUEST)
309         }
310         assertFailsWith<IllegalArgumentException> {
311             gen.addCountAndPassIfR0AnyBitsSet(3, DROPPED_ETH_BROADCAST)
312         }
313         assertFailsWith<IllegalArgumentException> {
314             gen.addCountAndDropIfR0IsOneOf(setOf(3), PASSED_ARP_REQUEST)
315         }
316         assertFailsWith<IllegalArgumentException> {
317             gen.addCountAndPassIfR0IsOneOf(setOf(3), DROPPED_ETH_BROADCAST)
318         }
319         assertFailsWith<IllegalArgumentException> {
320             gen.addCountAndDropIfR0IsNoneOf(setOf(3), PASSED_ARP_REQUEST)
321         }
322         assertFailsWith<IllegalArgumentException> {
323             gen.addCountAndPassIfR0IsNoneOf(setOf(3), DROPPED_ETH_BROADCAST)
324         }
325         assertFailsWith<IllegalArgumentException> {
326             gen.addCountAndDropIfBytesAtR0EqualsAnyOf(listOf(byteArrayOf(1)), PASSED_ARP_REQUEST)
327         }
328         assertFailsWith<IllegalArgumentException> {
329             gen.addCountAndPassIfBytesAtR0EqualsAnyOf(listOf(byteArrayOf(1)), DROPPED_ETH_BROADCAST)
330         }
331         assertFailsWith<IllegalArgumentException> {
332             gen.addCountAndDropIfBytesAtR0EqualsNoneOf(listOf(byteArrayOf(1)), PASSED_ARP_REQUEST)
333         }
334         assertFailsWith<IllegalArgumentException> {
335             gen.addCountAndPassIfBytesAtR0EqualsNoneOf(
336                     listOf(byteArrayOf(1)),
337                     DROPPED_ETH_BROADCAST
338             )
339         }
340         assertFailsWith<IllegalArgumentException> {
341             gen.addWrite32(byteArrayOf())
342         }
343         assertFailsWith<IllegalArgumentException> {
344             gen.addJumpIfOneOf(R0, setOf(), PASS_LABEL)
345         }
346         assertFailsWith<IllegalArgumentException> {
347             gen.addJumpIfOneOf(R0, setOf(-1, 1), PASS_LABEL)
348         }
349         assertFailsWith<IllegalArgumentException> {
350             gen.addJumpIfOneOf(R0, setOf(4294967296L, 1), PASS_LABEL)
351         }
352         assertFailsWith<IllegalArgumentException> {
353             gen.addJumpIfOneOf(R0, List(34) { (it + 1).toLong() }.toSet(), PASS_LABEL)
354         }
355         assertFailsWith<IllegalArgumentException> {
356             gen.addJumpIfBytesAtR0EqualsAnyOf(listOf(ByteArray(2048) { 1 }), PASS_LABEL )
357         }
358         assertFailsWith<IllegalArgumentException> {
359             gen.addJumpIfBytesAtR0EqualsAnyOf(
360                     listOf(byteArrayOf(1), byteArrayOf(1, 2)),
361                     PASS_LABEL
362             )
363         }
364 
365         val v4gen = ApfV4Generator(APF_VERSION_3, ramSize, clampSize)
366         assertFailsWith<IllegalArgumentException> { v4gen.addCountAndDrop(PASSED_ARP_REQUEST) }
367         assertFailsWith<IllegalArgumentException> { v4gen.addCountAndPass(DROPPED_ETH_BROADCAST) }
368         assertFailsWith<IllegalArgumentException> {
369             v4gen.addCountAndDropIfR0Equals(3, PASSED_ARP_REQUEST)
370         }
371         assertFailsWith<IllegalArgumentException> {
372             v4gen.addCountAndPassIfR0Equals(3, DROPPED_ETH_BROADCAST)
373         }
374         assertFailsWith<IllegalArgumentException> {
375             v4gen.addCountAndDropIfR0NotEquals(3, PASSED_ARP_REQUEST)
376         }
377         assertFailsWith<IllegalArgumentException> {
378             v4gen.addCountAndPassIfR0NotEquals(3, DROPPED_ETH_BROADCAST)
379         }
380         assertFailsWith<IllegalArgumentException> {
381             v4gen.addCountAndDropIfBytesAtR0Equal(byteArrayOf(1), PASSED_ARP_REQUEST)
382         }
383         assertFailsWith<IllegalArgumentException> {
384             v4gen.addCountAndPassIfBytesAtR0Equal(byteArrayOf(1), DROPPED_ETH_BROADCAST)
385         }
386         assertFailsWith<IllegalArgumentException> {
387             v4gen.addCountAndDropIfR0LessThan(3, PASSED_ARP_REQUEST)
388         }
389         assertFailsWith<IllegalArgumentException> {
390             v4gen.addCountAndPassIfR0LessThan(3, DROPPED_ETH_BROADCAST)
391         }
392         assertFailsWith<IllegalArgumentException> {
393             v4gen.addCountAndDropIfR0GreaterThan(3, PASSED_ARP_REQUEST)
394         }
395         assertFailsWith<IllegalArgumentException> {
396             v4gen.addCountAndPassIfR0GreaterThan(3, DROPPED_ETH_BROADCAST)
397         }
398         assertFailsWith<IllegalArgumentException> {
399             v4gen.addCountAndDropIfBytesAtR0NotEqual(byteArrayOf(1), PASSED_ARP_REQUEST)
400         }
401         assertFailsWith<IllegalArgumentException> {
402             v4gen.addCountAndDropIfR0AnyBitsSet(3, PASSED_ARP_REQUEST)
403         }
404         assertFailsWith<IllegalArgumentException> {
405             v4gen.addCountAndPassIfR0AnyBitsSet(3, DROPPED_ETH_BROADCAST)
406         }
407         assertFailsWith<IllegalArgumentException> {
408             v4gen.addCountAndDropIfR0IsOneOf(setOf(3), PASSED_ARP_REQUEST)
409         }
410         assertFailsWith<IllegalArgumentException> {
411             v4gen.addCountAndPassIfR0IsOneOf(setOf(3), DROPPED_ETH_BROADCAST)
412         }
413         assertFailsWith<IllegalArgumentException> {
414             v4gen.addCountAndDropIfR0IsNoneOf(setOf(3), PASSED_ARP_REQUEST)
415         }
416         assertFailsWith<IllegalArgumentException> {
417             v4gen.addCountAndPassIfR0IsNoneOf(setOf(3), DROPPED_ETH_BROADCAST)
418         }
419         assertFailsWith<IllegalArgumentException> {
420             v4gen.addCountAndDropIfBytesAtR0EqualsAnyOf(listOf(byteArrayOf(1)), PASSED_ARP_REQUEST)
421         }
422         assertFailsWith<IllegalArgumentException> {
423             v4gen.addCountAndPassIfBytesAtR0EqualsAnyOf(
424                     listOf(byteArrayOf(1)),
425                     DROPPED_ETH_BROADCAST
426             )
427         }
428         assertFailsWith<IllegalArgumentException> {
429             v4gen.addCountAndDropIfBytesAtR0EqualsNoneOf(listOf(byteArrayOf(1)), PASSED_ARP_REQUEST)
430         }
431         assertFailsWith<IllegalArgumentException> {
432             v4gen.addCountAndPassIfBytesAtR0EqualsNoneOf(
433                     listOf(byteArrayOf(1)),
434                     DROPPED_ETH_BROADCAST
435             )
436         }
437     }
438 
439     @Test
testValidateDnsNamesnull440     fun testValidateDnsNames() {
441         // '%' is a valid label character in mDNS subtype
442         // byte == 0xff means it is a '*' wildcard, which is a valid encoding.
443         val program = ApfV6Generator(ramSize, ramSize, clampSize).addJumpIfPktAtR0ContainDnsQ(
444                 byteArrayOf(1, '%'.code.toByte(), 0, 0),
445                 1,
446                 DROP_LABEL
447         ).addJumpIfPktAtR0ContainDnsA(
448                 byteArrayOf(0xff.toByte(), 1, 'B'.code.toByte(), 0, 0),
449                 DROP_LABEL
450         ).generate()
451     }
452 
453     @Test
testApfInstructionsEncodingnull454     fun testApfInstructionsEncoding() {
455         val v4gen = ApfV4Generator(APF_VERSION_2, ramSize, clampSize)
456         v4gen.addPass()
457         var program = v4gen.generate()
458         // encoding PASS opcode: opcode=0, imm_len=0, R=0
459         assertContentEquals(
460                 byteArrayOf(encodeInstruction(opcode = 0, immLength = 0, register = 0)),
461                 program
462         )
463         assertContentEquals(
464                 listOf("0: pass"),
465                 apfTestHelpers.disassembleApf(program).map { it.trim() }
466         )
467 
468         var gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
469         gen.addDrop()
470         program = gen.generate().skipDataAndDebug()
471         // encoding DROP opcode: opcode=0, imm_len=0, R=1
472         assertContentEquals(
473                 byteArrayOf(encodeInstruction(opcode = 0, immLength = 0, register = 1)),
474                 program
475         )
476         assertContentEquals(
477                 listOf("0: drop"),
478                 apfTestHelpers.disassembleApf(program).map { it.trim() }
479         )
480 
481         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
482         gen.addCountAndPass(129)
483         program = gen.generate().skipDataAndDebug()
484         // encoding COUNT(PASS) opcode: opcode=0, imm_len=size_of(imm), R=0, imm=counterNumber
485         assertContentEquals(
486                 byteArrayOf(
487                         encodeInstruction(opcode = 0, immLength = 1, register = 0),
488                         0x81.toByte()
489                 ),
490                 program
491         )
492         assertContentEquals(
493                 listOf("0: pass        counter=129"),
494                 apfTestHelpers.disassembleApf(program).map { it.trim() }
495         )
496 
497         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
498         gen.addCountAndDrop(1000)
499         program = gen.generate().skipDataAndDebug()
500         // encoding COUNT(DROP) opcode: opcode=0, imm_len=size_of(imm), R=1, imm=counterNumber
501         assertContentEquals(
502                 byteArrayOf(
503                         encodeInstruction(opcode = 0, immLength = 2, register = 1),
504                         0x03,
505                         0xe8.toByte()
506                 ),
507                 program
508         )
509         assertContentEquals(
510                 listOf("0: drop        counter=1000"),
511                 apfTestHelpers.disassembleApf(program).map { it.trim() }
512         )
513 
514         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
515         gen.addCountAndPass(PASSED_ARP_REQUEST)
516         program = gen.generate().skipDataAndDebug()
517         // encoding COUNT(PASS) opcode: opcode=0, imm_len=size_of(imm), R=0, imm=counterNumber
518         assertContentEquals(
519                 byteArrayOf(
520                         encodeInstruction(opcode = 0, immLength = 1, register = 0),
521                         PASSED_ARP_REQUEST.value().toByte()
522                 ),
523                 program
524         )
525         val expectedCounterValue1 = PASSED_ARP_REQUEST.value()
526         assertContentEquals(
527                 listOf("0: pass        counter=$expectedCounterValue1"),
528                 apfTestHelpers.disassembleApf(program).map { it.trim() }
529         )
530 
531         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
532         gen.addCountAndDrop(DROPPED_ETHERTYPE_NOT_ALLOWED)
533         program = gen.generate().skipDataAndDebug()
534         // encoding COUNT(DROP) opcode: opcode=0, imm_len=size_of(imm), R=1, imm=counterNumber
535         assertContentEquals(
536                 byteArrayOf(
537                         encodeInstruction(opcode = 0, immLength = 1, register = 1),
538                         DROPPED_ETHERTYPE_NOT_ALLOWED.value().toByte()
539                 ),
540                 program
541         )
542         val expectedCounterValue2 = DROPPED_ETHERTYPE_NOT_ALLOWED.value()
543         assertContentEquals(
544                 listOf("0: drop        counter=$expectedCounterValue2"),
545                 apfTestHelpers.disassembleApf(program).map { it.trim() }
546         )
547 
548         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
549         gen.addAllocateR0()
550         gen.addAllocate(1500)
551         program = gen.generate().skipDataAndDebug()
552         // encoding ALLOC opcode: opcode=21(EXT opcode number), imm=36(TRANS opcode number).
553         // R=0 means length stored in R0. R=1 means the length stored in imm1.
554         assertContentEquals(
555                 byteArrayOf(
556                         encodeInstruction(opcode = 21, immLength = 1, register = 0),
557                         36,
558                         encodeInstruction(opcode = 21, immLength = 1, register = 1),
559                         36,
560                         0x05,
561                         0xDC.toByte()
562                 ),
563                 program
564         )
565         assertContentEquals(listOf(
566                 "0: allocate    r0",
567                 "2: allocate    1500"
568         ), apfTestHelpers.disassembleApf(program).map { it.trim() })
569 
570         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
571         gen.addTransmitWithoutChecksum()
572         gen.addTransmitL4(30, 40, 50, 256, true)
573         program = gen.generate().skipDataAndDebug()
574         // encoding TRANSMIT opcode: opcode=21(EXT opcode number),
575         // imm=37(TRANSMIT opcode number),
576         assertContentEquals(byteArrayOf(
577                 encodeInstruction(opcode = 21, immLength = 1, register = 0),
578                 37, 255.toByte(), 255.toByte(),
579                 encodeInstruction(opcode = 21, immLength = 1, register = 1), 37, 30, 40, 50, 1, 0
580         ), program)
581         assertContentEquals(listOf(
582                 "0: transmit    ip_ofs=255",
583                 "4: transmitudp ip_ofs=30, csum_ofs=40, csum_start=50, partial_csum=0x0100",
584         ), apfTestHelpers.disassembleApf(program).map { it.trim() })
585 
586         val largeByteArray = ByteArray(256) { 0x01 }
587         gen = ApfV6Generator(largeByteArray, apfInterpreterVersion, ramSize, clampSize)
588         program = gen.generate()
589         val debugBufferSize = ramSize - program.size - Counter.totalSize()
590         assertContentEquals(
591                 byteArrayOf(
592                         encodeInstruction(opcode = 14, immLength = 2, register = 1), 1, 0
593                 ) + largeByteArray + byteArrayOf(
594                         encodeInstruction(opcode = 21, immLength = 1, register = 0),
595                         48, (debugBufferSize shr 8).toByte(), debugBufferSize.toByte()
596                 ),
597                 program
598         )
599         assertContentEquals(
600                 listOf(
601                         "0: data        256, " + "01".repeat(256),
602                         "259: debugbuf    size=$debugBufferSize"
603                 ),
604                 apfTestHelpers.disassembleApf(program).map { it.trim() }
605         )
606 
607         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
608         gen.addWriteU8(0x01)
609         gen.addWriteU16(0x0102)
610         gen.addWriteU32(0x01020304)
611         gen.addWriteU8(0x00)
612         gen.addWriteU8(0x80)
613         gen.addWriteU16(0x0000)
614         gen.addWriteU16(0x8000)
615         gen.addWriteU32(0x00000000)
616         gen.addWriteU32(0x80000000)
617         gen.addWrite32(-2)
618         gen.addWrite32(byteArrayOf(0xff.toByte(), 0xfe.toByte(), 0xfd.toByte(), 0xfc.toByte()))
619         program = gen.generate().skipDataAndDebug()
620         assertContentEquals(byteArrayOf(
621                 encodeInstruction(24, 1, 0), 0x01,
622                 encodeInstruction(24, 2, 0), 0x01, 0x02,
623                 encodeInstruction(24, 4, 0), 0x01, 0x02, 0x03, 0x04,
624                 encodeInstruction(24, 1, 0), 0x00,
625                 encodeInstruction(24, 1, 0), 0x80.toByte(),
626                 encodeInstruction(24, 2, 0), 0x00, 0x00,
627                 encodeInstruction(24, 2, 0), 0x80.toByte(), 0x00,
628                 encodeInstruction(24, 4, 0), 0x00, 0x00, 0x00, 0x00,
629                 encodeInstruction(24, 4, 0), 0x80.toByte(), 0x00, 0x00, 0x00,
630                 encodeInstruction(24, 4, 0), 0xff.toByte(), 0xff.toByte(),
631                 0xff.toByte(), 0xfe.toByte(),
632                 encodeInstruction(24, 4, 0), 0xff.toByte(), 0xfe.toByte(),
633                 0xfd.toByte(), 0xfc.toByte()), program)
634         assertContentEquals(listOf(
635                 "0: write       0x01",
636                 "2: write       0x0102",
637                 "5: write       0x01020304",
638                 "10: write       0x00",
639                 "12: write       0x80",
640                 "14: write       0x0000",
641                 "17: write       0x8000",
642                 "20: write       0x00000000",
643                 "25: write       0x80000000",
644                 "30: write       0xfffffffe",
645                 "35: write       0xfffefdfc"
646         ), apfTestHelpers.disassembleApf(program).map { it.trim() })
647 
648         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
649         gen.addWriteU8(R0)
650         gen.addWriteU16(R0)
651         gen.addWriteU32(R0)
652         gen.addWriteU8(R1)
653         gen.addWriteU16(R1)
654         gen.addWriteU32(R1)
655         program = gen.generate().skipDataAndDebug()
656         assertContentEquals(byteArrayOf(
657                 encodeInstruction(21, 1, 0), 38,
658                 encodeInstruction(21, 1, 0), 39,
659                 encodeInstruction(21, 1, 0), 40,
660                 encodeInstruction(21, 1, 1), 38,
661                 encodeInstruction(21, 1, 1), 39,
662                 encodeInstruction(21, 1, 1), 40
663         ), program)
664         assertContentEquals(listOf(
665                 "0: ewrite1     r0",
666                 "2: ewrite2     r0",
667                 "4: ewrite4     r0",
668                 "6: ewrite1     r1",
669                 "8: ewrite2     r1",
670                 "10: ewrite4     r1"
671         ), apfTestHelpers.disassembleApf(program).map { it.trim() })
672 
673         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
674         gen.addDataCopy(0, 2)
675         gen.addDataCopy(1, 1)
676         gen.addPacketCopy(1000, 255)
677         program = gen.generate().skipDataAndDebug()
678         assertContentEquals(byteArrayOf(
679                 encodeInstruction(25, 0, 1), 2,
680                 encodeInstruction(25, 1, 1), 1, 1,
681                 encodeInstruction(25, 2, 0),
682                 0x03.toByte(), 0xe8.toByte(), 0xff.toByte(),
683         ), program)
684         assertContentEquals(listOf(
685                 "0: datacopy    src=0, (2)c902",
686                 "2: datacopy    src=1, (1)02",
687                 "5: pktcopy     src=1000, len=255"
688         ), apfTestHelpers.disassembleApf(program).map { it.trim() })
689 
690         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
691         gen.addDataCopyFromR0(5)
692         gen.addPacketCopyFromR0(5)
693         gen.addDataCopyFromR0LenR1()
694         gen.addPacketCopyFromR0LenR1()
695         program = gen.generate().skipDataAndDebug()
696         assertContentEquals(byteArrayOf(
697                 encodeInstruction(21, 1, 1), 41, 5,
698                 encodeInstruction(21, 1, 0), 41, 5,
699                 encodeInstruction(21, 1, 1), 42,
700                 encodeInstruction(21, 1, 0), 42,
701         ), program)
702         assertContentEquals(listOf(
703                 "0: edatacopy   src=r0, len=5",
704                 "3: epktcopy    src=r0, len=5",
705                 "6: edatacopy   src=r0, len=r1",
706                 "8: epktcopy    src=r0, len=r1"
707         ), apfTestHelpers.disassembleApf(program).map{ it.trim() })
708 
709         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
710         gen.addJumpIfBytesAtR0Equal(byteArrayOf('a'.code.toByte()), ApfV4Generator.DROP_LABEL)
711         program = gen.generate().skipDataAndDebug()
712         assertContentEquals(byteArrayOf(
713                 encodeInstruction(opcode = 20, immLength = 1, register = 1),
714                 1,
715                 1,
716                 'a'.code.toByte()
717         ), program)
718         assertContentEquals(listOf(
719                 "0: jbseq       r0, (1), DROP, 61"
720         ), apfTestHelpers.disassembleApf(program).map{ it.trim() })
721 
722         val qnames = byteArrayOf(1, 'A'.code.toByte(), 1, 'B'.code.toByte(), 0, 0)
723         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
724         gen.addJumpIfPktAtR0DoesNotContainDnsQ(qnames, 0x0c, ApfV4Generator.DROP_LABEL)
725         gen.addJumpIfPktAtR0ContainDnsQ(qnames, 0x0c, ApfV4Generator.DROP_LABEL)
726         program = gen.generate().skipDataAndDebug()
727         assertContentEquals(byteArrayOf(
728                 encodeInstruction(21, 1, 0), 43, 11, 0x0c.toByte(),
729         ) + qnames + byteArrayOf(
730                 encodeInstruction(21, 1, 1), 43, 1, 0x0c.toByte(),
731         ) + qnames, program)
732         assertContentEquals(listOf(
733                 "0: jdnsqne     r0, DROP, PTR, (1)A(1)B(0)(0)",
734                 "10: jdnsqeq     r0, DROP, PTR, (1)A(1)B(0)(0)"
735         ), apfTestHelpers.disassembleApf(program).map{ it.trim() })
736 
737         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
738         gen.addJumpIfPktAtR0DoesNotContainDnsQSafe(qnames, 0x0c, ApfV4Generator.DROP_LABEL)
739         gen.addJumpIfPktAtR0ContainDnsQSafe(qnames, 0x0c, ApfV4Generator.DROP_LABEL)
740         program = gen.generate().skipDataAndDebug()
741         assertContentEquals(byteArrayOf(
742                 encodeInstruction(21, 1, 0), 45, 11, 0x0c.toByte(),
743         ) + qnames + byteArrayOf(
744                 encodeInstruction(21, 1, 1), 45, 1, 0x0c.toByte(),
745         ) + qnames, program)
746         assertContentEquals(listOf(
747                 "0: jdnsqnesafe r0, DROP, PTR, (1)A(1)B(0)(0)",
748                 "10: jdnsqeqsafe r0, DROP, PTR, (1)A(1)B(0)(0)"
749         ), apfTestHelpers.disassembleApf(program).map{ it.trim() })
750 
751         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
752         gen.addJumpIfPktAtR0DoesNotContainDnsA(qnames, ApfV4Generator.DROP_LABEL)
753         gen.addJumpIfPktAtR0ContainDnsA(qnames, ApfV4Generator.DROP_LABEL)
754         program = gen.generate().skipDataAndDebug()
755         assertContentEquals(byteArrayOf(
756                 encodeInstruction(21, 1, 0), 44, 10,
757         ) + qnames + byteArrayOf(
758                 encodeInstruction(21, 1, 1), 44, 1,
759         ) + qnames, program)
760         assertContentEquals(listOf(
761                 "0: jdnsane     r0, DROP, (1)A(1)B(0)(0)",
762                 "9: jdnsaeq     r0, DROP, (1)A(1)B(0)(0)"
763         ), apfTestHelpers.disassembleApf(program).map{ it.trim() })
764 
765         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
766         gen.addJumpIfPktAtR0DoesNotContainDnsASafe(qnames, ApfV4Generator.DROP_LABEL)
767         gen.addJumpIfPktAtR0ContainDnsASafe(qnames, ApfV4Generator.DROP_LABEL)
768         program = gen.generate().skipDataAndDebug()
769         assertContentEquals(byteArrayOf(
770                 encodeInstruction(21, 1, 0), 46, 10,
771         ) + qnames + byteArrayOf(
772                 encodeInstruction(21, 1, 1), 46, 1,
773         ) + qnames, program)
774         assertContentEquals(listOf(
775                 "0: jdnsanesafe r0, DROP, (1)A(1)B(0)(0)",
776                 "9: jdnsaeqsafe r0, DROP, (1)A(1)B(0)(0)"
777         ), apfTestHelpers.disassembleApf(program).map{ it.trim() })
778 
779         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
780         gen.addJumpIfOneOf(R1, List(32) { (it + 1).toLong() }.toSet(), DROP_LABEL)
781         gen.addJumpIfOneOf(R0, setOf(0, 257, 65536), DROP_LABEL)
782         gen.addJumpIfNoneOf(R0, setOf(1, 2, 3), DROP_LABEL)
783         program = gen.generate().skipDataAndDebug()
784         assertContentEquals(byteArrayOf(
785                 encodeInstruction(21, 1, 1), 47, 24, -16, 1, 2, 3, 4, 5, 6,
786                 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
787                 29, 30, 31, 32,
788                 encodeInstruction(21, 1, 0), 47, 8, 14, 0, 0, 0, 0, 0, 0,
789                 1, 1, 0, 1, 0, 0,
790                 encodeInstruction(21, 1, 0), 47, 1, 9, 1, 2, 3
791         ), program)
792 
793         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
794         gen.addJumpIfOneOf(R0, setOf(0, 128, 256, 65536), DROP_LABEL)
795         gen.addJumpIfNoneOf(R1, setOf(0, 128, 256, 65536), DROP_LABEL)
796         program = gen.generate().skipDataAndDebug()
797         assertContentEquals(listOf(
798                 "0: joneof      r0, DROP, { 0, 128, 256, 65536 }",
799                 "20: jnoneof     r1, DROP, { 0, 128, 256, 65536 }"
800         ), apfTestHelpers.disassembleApf(program).map{ it.trim() })
801 
802         gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
803         gen.addJumpIfBytesAtR0EqualsAnyOf(listOf(byteArrayOf(1, 2), byteArrayOf(3, 4)), DROP_LABEL)
804         gen.addJumpIfBytesAtR0EqualsNoneOf(listOf(byteArrayOf(1, 2), byteArrayOf(3, 4)), DROP_LABEL)
805         gen.addJumpIfBytesAtR0EqualsNoneOf(listOf(byteArrayOf(1, 1), byteArrayOf(1, 1)), DROP_LABEL)
806         program = gen.generate().skipDataAndDebug()
807         assertContentEquals(byteArrayOf(
808                 encodeInstruction(opcode = 20, immLength = 2, register = 1),
809                 0, 15, 8, 2, 1, 2, 3, 4,
810                 encodeInstruction(opcode = 20, immLength = 2, register = 0),
811                 0, 6, 8, 2, 1, 2, 3, 4,
812                 encodeInstruction(opcode = 20, immLength = 1, register = 0),
813                 1, 2, 1, 1
814         ), program)
815         assertContentEquals(listOf(
816                 "0: jbseq       r0, (2), DROP, { 0102, 0304 }[2]",
817                 "9: jbsne       r0, (2), DROP, { 0102, 0304 }[2]",
818                 "18: jbsne       r0, (2), DROP, 0101"
819         ), apfTestHelpers.disassembleApf(program).map{ it.trim() })
820     }
821 
822     @Test
testApf61InstructionEncodingnull823     fun testApf61InstructionEncoding() {
824         var gen = ApfV61Generator(apfInterpreterVersion, ramSize, clampSize)
825         gen.addCountAndDropIfR0Equals(1, DROPPED_RA)
826         var program = gen.generate().skipDataAndDebug()
827         assertContentEquals(byteArrayOf(
828             encodeInstruction(15, 1, 0),
829             DROPPED_RA.jumpDropLabel.toByte(),
830             1,
831         ), program)
832 
833         gen = ApfV61Generator(apfInterpreterVersion, ramSize, clampSize)
834         gen.addCountAndPassIfR0Equals(1, PASSED_MDNS)
835         program = gen.generate().skipDataAndDebug()
836         assertContentEquals(byteArrayOf(
837             encodeInstruction(15, 1, 0),
838             PASSED_MDNS.jumpPassLabel.toByte(),
839             1,
840         ), program)
841     }
842 
843     @Test
testWriteToTxBuffernull844     fun testWriteToTxBuffer() {
845         var program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
846                 .addAllocate(14)
847                 .addWriteU8(0x01)
848                 .addWriteU16(0x0203)
849                 .addWriteU32(0x04050607)
850                 .addWrite32(-2)
851                 .addWrite32(byteArrayOf(0xff.toByte(), 0xfe.toByte(), 0xfd.toByte(), 0xfc.toByte()))
852                 .addLoadImmediate(R0, 1)
853                 .addWriteU8(R0)
854                 .addLoadImmediate(R0, 0x0203)
855                 .addWriteU16(R0)
856                 .addLoadImmediate(R1, 0x04050607)
857                 .addWriteU32(R1)
858                 .addTransmitWithoutChecksum()
859                 .generate()
860         apfTestHelpers.assertPass(apfInterpreterVersion, program, ByteArray(MIN_PKT_SIZE))
861         val transmitPackets = apfTestHelpers.consumeTransmittedPackets(1)
862         assertContentEquals(
863                 byteArrayOf(
864                         0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xff.toByte(),
865                         0xff.toByte(), 0xff.toByte(), 0xfe.toByte(), 0xff.toByte(), 0xfe.toByte(),
866                         0xfd.toByte(), 0xfc.toByte(), 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07),
867                 transmitPackets[0]
868         )
869     }
870 
871     @Test
testCopyToTxBuffernull872     fun testCopyToTxBuffer() {
873         var program = ApfV6Generator(
874             byteArrayOf(33, 34, 35),
875             apfInterpreterVersion,
876             ramSize,
877             clampSize
878         )
879                 .addAllocate(14)
880                 .addDataCopy(3, 2) // arg1=src, arg2=len
881                 .addDataCopy(5, 1) // arg1=src, arg2=len
882                 .addPacketCopy(0, 1) // arg1=src, arg2=len
883                 .addPacketCopy(1, 3) // arg1=src, arg2=len
884                 .addLoadImmediate(R0, 3) // data copy offset
885                 .addDataCopyFromR0(2) // len
886                 .addLoadImmediate(R0, 5) // data copy offset
887                 .addLoadImmediate(R1, 1) // len
888                 .addDataCopyFromR0LenR1()
889                 .addLoadImmediate(R0, 0) // packet copy offset
890                 .addPacketCopyFromR0(1) // len
891                 .addLoadImmediate(R0, 1) // packet copy offset
892                 .addLoadImmediate(R1, 3) // len
893                 .addPacketCopyFromR0LenR1()
894                 .addTransmitWithoutChecksum()
895                 .generate()
896         apfTestHelpers.assertPass(apfInterpreterVersion, program, testPacket)
897         val transmitPackets = apfTestHelpers.consumeTransmittedPackets(1)
898         assertContentEquals(
899                 byteArrayOf(33, 34, 35, 1, 2, 3, 4, 33, 34, 35, 1, 2, 3, 4),
900                 transmitPackets[0]
901         )
902     }
903 
904     @Test
testCopyContentToTxBuffernull905     fun testCopyContentToTxBuffer() {
906         val program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
907                 .addAllocate(18)
908                 .addDataCopy(HexDump.hexStringToByteArray("112233445566"))
909                 .addDataCopy(HexDump.hexStringToByteArray("223344"))
910                 .addDataCopy(HexDump.hexStringToByteArray("778899"))
911                 .addDataCopy(HexDump.hexStringToByteArray("112233445566"))
912                 .addTransmitWithoutChecksum()
913                 .generate()
914         assertContentEquals(listOf(
915                 "0: data        9, 112233445566778899",
916                 "12: debugbuf    size=${ramSize - program.size - Counter.totalSize()}",
917                 "16: allocate    18",
918                 "20: datacopy    src=3, (6)112233445566",
919                 "23: datacopy    src=4, (3)223344",
920                 "26: datacopy    src=9, (3)778899",
921                 "29: datacopy    src=3, (6)112233445566",
922                 "32: transmit    ip_ofs=255"
923         ), apfTestHelpers.disassembleApf(program).map{ it.trim() })
924         apfTestHelpers.assertPass(apfInterpreterVersion, program, testPacket)
925         val transmitPackets = apfTestHelpers.consumeTransmittedPackets(1)
926         val transmitPkt = HexDump.toHexString(transmitPackets[0])
927         assertEquals("112233445566223344778899112233445566", transmitPkt)
928     }
929 
930     @Test
testCopyLargeContentToTxBufferWithCompressionnull931     fun testCopyLargeContentToTxBufferWithCompression() {
932         val program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
933             .addAllocate(300)
934             // Chunked into 255 and 35 bytes.
935             // 255 bytes appended to data region.
936             // 35 bytes compressed by reusing the duplicated chunk from the data region.
937             .addDataCopy(ByteArray(290) { 1 })
938             // Appended to the data region.
939             .addDataCopy(ByteArray(5) { 2 })
940             // Compressed by reusing the duplicated chunk from the data region.
941             .addDataCopy(ByteArray(3) { 1 } + ByteArray(2) { 2 })
942             .addTransmitWithoutChecksum()
943             .generate()
944 
945         val byteHexString = "01".repeat(255) + "02".repeat(5)
946         assertContentEquals(listOf(
947             "0: data        260, $byteHexString",
948             "263: debugbuf    size=${ramSize - program.size - Counter.totalSize()}",
949             "267: allocate    300",
950             "271: datacopy    src=3, (255)" + "01".repeat(255),
951             "274: datacopy    src=3, (35)" + "01".repeat(35),
952             "277: datacopy    src=258, (5)" + "02".repeat(5),
953             "281: datacopy    src=255, (5)" + "01".repeat(3) + "02".repeat(2),
954             "284: transmit    ip_ofs=255"
955         ), apfTestHelpers.disassembleApf(program).map{ it.trim() })
956         apfTestHelpers.assertPass(apfInterpreterVersion, program, testPacket)
957         val transmitPackets = apfTestHelpers.consumeTransmittedPackets(1)
958         val transmitPkt = HexDump.toHexString(transmitPackets[0])
959         assertEquals(
960             "01".repeat(290) + "02".repeat(5) + "01".repeat(3) + "02".repeat(2),
961             transmitPkt
962         )
963     }
964 
965     @Test
testCopyLargeContentToTxBufferWithoutCompressionnull966     fun testCopyLargeContentToTxBufferWithoutCompression() {
967         val program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
968             .addAllocate(300)
969             // Chunked into 255 and 45 bytes and then appended to the data region.
970             .addDataCopy(ByteArray(255) { 3 } + ByteArray(45) { 4 })
971             .addTransmitWithoutChecksum()
972             .generate()
973 
974         val byteHexString = "03".repeat(255) + "04".repeat(45)
975         assertContentEquals(listOf(
976             "0: data        300, $byteHexString",
977             "303: debugbuf    size=${ramSize - program.size - Counter.totalSize()}",
978             "307: allocate    300",
979             "311: datacopy    src=3, (255)" + "03".repeat(255),
980             "314: datacopy    src=258, (45)" + "04".repeat(45),
981             "318: transmit    ip_ofs=255"
982         ), apfTestHelpers.disassembleApf(program).map{ it.trim() })
983         apfTestHelpers.assertPass(apfInterpreterVersion, program, testPacket)
984         val transmitPackets = apfTestHelpers.consumeTransmittedPackets(1)
985         val transmitPkt = HexDump.toHexString(transmitPackets[0])
986         assertEquals( "03".repeat(255) + "04".repeat(45), transmitPkt)
987     }
988 
989     @Test
testJBSPTRMATCHOpcodeEncodingnull990     fun testJBSPTRMATCHOpcodeEncoding() {
991         assumeTrue(apfInterpreterVersion != ApfJniUtils.APF_INTERPRETER_VERSION_V6)
992         val dataBytes = HexDump.hexStringToByteArray(
993             "01020304050607080910111213141516171819202122232425262728293031323334353637383940"
994         )
995         val bytes1 = HexDump.hexStringToByteArray("0102")
996         val bytes2 = HexDump.hexStringToByteArray("0304")
997         val bytes3 = HexDump.hexStringToByteArray("0506")
998         val bytes4 = HexDump.hexStringToByteArray("0708")
999         val bytes5 = HexDump.hexStringToByteArray("0910")
1000         val bytes6 = HexDump.hexStringToByteArray("1112")
1001         val bytes7 = HexDump.hexStringToByteArray("1314")
1002         val bytes8 = HexDump.hexStringToByteArray("1516")
1003         val bytes9 = HexDump.hexStringToByteArray("1718")
1004         val bytes10 = HexDump.hexStringToByteArray("1920")
1005         val bytes11 = HexDump.hexStringToByteArray("2122")
1006         val bytes12 = HexDump.hexStringToByteArray("2324")
1007         val bytes13 = HexDump.hexStringToByteArray("2526")
1008         val bytes14 = HexDump.hexStringToByteArray("2728")
1009         val bytes15 = HexDump.hexStringToByteArray("2930")
1010         val bytes16 = HexDump.hexStringToByteArray("3132")
1011         val bytes17 = HexDump.hexStringToByteArray("3334")
1012         val bytesAtOddIndex = HexDump.hexStringToByteArray("0203")
1013         val notExistBytes = HexDump.hexStringToByteArray("ffff")
1014         val total17BytesList = listOf(
1015             bytes1,
1016             bytes2,
1017             bytes3,
1018             bytes4,
1019             bytes5,
1020             bytes6,
1021             bytes7,
1022             bytes8,
1023             bytes9,
1024             bytes10,
1025             bytes11,
1026             bytes12,
1027             bytes13,
1028             bytes14,
1029             bytes15,
1030             bytes16,
1031             bytes17,
1032         )
1033         val joinedBytes: ByteArray = total17BytesList.flatMap { it.toList() }.toByteArray()
1034         var program = ApfV61Generator(apfInterpreterVersion, ramSize, clampSize)
1035             .addPreloadData(dataBytes)
1036             .addJumpIfBytesAtOffsetEqualsNoneOf(0, listOf(bytes1, notExistBytes), PASS_LABEL)
1037             .addJumpIfBytesAtOffsetEqualsAnyOf(1, listOf(bytes1, bytes2), PASS_LABEL)
1038             .addJumpIfBytesAtOffsetEqualsNoneOf(2, listOf(notExistBytes), PASS_LABEL)
1039             .addJumpIfBytesAtOffsetEqualsAnyOf(3, total17BytesList, PASS_LABEL)
1040             .addJumpIfBytesAtOffsetEqualsNoneOf(4, listOf(bytesAtOddIndex), PASS_LABEL)
1041             .addJumpIfBytesAtOffsetEqualsNoneOf(6, listOf(joinedBytes), PASS_LABEL)
1042             .generate()
1043         var debugBufferSize = ramSize - program.size - Counter.totalSize()
1044         assertContentEquals(listOf(
1045             "0: data        40, ${HexDump.toHexString(dataBytes)}",
1046             "43: debugbuf    size=$debugBufferSize",
1047             "47: jbsptrne    pktofs=0, (2), PASS, @0[0102]",
1048             "52: li          r0, 0",
1049             "53: jbsne       r0, (2), PASS, ffff",
1050             "58: jbsptreq    pktofs=1, (2), PASS, { @0[0102], @2[0304] }[2]",
1051             "64: li          r0, 2",
1052             "66: jbsne       r0, (2), PASS, ffff",
1053             "71: jbsptreq    pktofs=3, (2), PASS, { @0[0102], @2[0304], @4[0506], @6[0708], " +
1054                 "@8[0910], @10[1112], @12[1314], @14[1516], @16[1718], @18[1920], @20[2122], " +
1055                 "@22[2324], @24[2526], @26[2728], @28[2930], @30[3132] }[16]",
1056             "91: jbsptreq    pktofs=3, (2), PASS, @32[3334]",
1057             "96: li          r0, 4",
1058             "98: jbsne       r0, (2), PASS, 0203",
1059             "103: li          r0, 6",
1060             "105: jbsne       r0, (34), PASS, ${HexDump.toHexString(joinedBytes)}",
1061         ), apfTestHelpers.disassembleApf(program).map{ it.trim() })
1062 
1063         val largePrefix = ByteArray(510) { 0 }
1064         program = ApfV61Generator(apfInterpreterVersion, ramSize, clampSize)
1065             .addPreloadData(largePrefix + dataBytes)
1066             .addJumpIfBytesAtOffsetEqualsAnyOf(1, listOf(bytes1, bytes2), PASS_LABEL)
1067             .generate()
1068         debugBufferSize = ramSize - program.size - Counter.totalSize()
1069         assertContentEquals(listOf(
1070             "0: data        550, ${HexDump.toHexString(largePrefix + dataBytes)}",
1071             "553: debugbuf    size=$debugBufferSize",
1072             "557: jbsptreq    pktofs=1, (2), PASS, @510[0102]",
1073             "562: li          r0, 1",
1074             "564: jbseq       r0, (2), PASS, 0304",
1075         ), apfTestHelpers.disassembleApf(program).map{ it.trim() })
1076     }
1077 
1078     @Test
testPassDropnull1079     fun testPassDrop() {
1080         var program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1081                 .addDrop()
1082                 .addPass()
1083                 .generate()
1084         apfTestHelpers.assertDrop(apfInterpreterVersion, program, testPacket)
1085 
1086         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1087                 .addCountAndDrop(Counter.DROPPED_ETH_BROADCAST)
1088                 .generate()
1089         apfTestHelpers.verifyProgramRun(
1090             apfInterpreterVersion,
1091             program,
1092             testPacket,
1093             DROPPED_ETH_BROADCAST
1094         )
1095 
1096         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1097                 .addCountAndPass(Counter.PASSED_ARP_REQUEST)
1098                 .generate()
1099         apfTestHelpers.verifyProgramRun(
1100             apfInterpreterVersion,
1101             program,
1102             testPacket,
1103             PASSED_ARP_REQUEST
1104         )
1105     }
1106 
1107     @Test
testLoadStoreCounternull1108     fun testLoadStoreCounter() {
1109         doTestLoadStoreCounter (
1110                 { mutableMapOf() },
1111                 { ApfV4Generator(APF_VERSION_3, ramSize, clampSize) }
1112         )
1113         doTestLoadStoreCounter (
1114                 { mutableMapOf(TOTAL_PACKETS to 1) },
1115                 { ApfV6Generator(apfInterpreterVersion, ramSize, clampSize) }
1116         )
1117     }
1118 
doTestLoadStoreCounternull1119     private fun doTestLoadStoreCounter(
1120             getInitialMap: () -> MutableMap<Counter, Long>,
1121             getGenerator: () -> ApfV4GeneratorBase<*>
1122     ) {
1123         val program = getGenerator()
1124                 .addIncrementCounter(PASSED_ARP_REQUEST, 2)
1125                 .addPass()
1126                 .generate()
1127         var dataRegion = ByteArray(Counter.totalSize()) { 0 }
1128         apfTestHelpers.assertVerdict(apfInterpreterVersion, PASS, program, testPacket, dataRegion)
1129         var counterMap = decodeCountersIntoMap(dataRegion)
1130         var expectedMap = getInitialMap()
1131         expectedMap[PASSED_ARP_REQUEST] = 2
1132         assertEquals(expectedMap, counterMap)
1133     }
1134 
1135     @Test
testV4CountAndPassDropCompareR0null1136     fun testV4CountAndPassDropCompareR0() {
1137         doTestCountAndPassDropCompareR0(
1138                 getGenerator = { ApfV4Generator(APF_VERSION_3, ramSize, clampSize) },
1139                 incTotal = false
1140         )
1141     }
1142 
1143     @Test
testV6CountAndPassDropCompareR0null1144     fun testV6CountAndPassDropCompareR0() {
1145         doTestCountAndPassDropCompareR0(
1146                 getGenerator = { ApfV6Generator(apfInterpreterVersion, ramSize, clampSize) },
1147                 incTotal = true
1148         )
1149     }
1150 
1151     @Test
testV61CountAndPassDropCompareR0null1152     fun testV61CountAndPassDropCompareR0() {
1153         assumeTrue(apfInterpreterVersion > ApfJniUtils.APF_INTERPRETER_VERSION_V6)
1154         doTestCountAndPassDropCompareR0(
1155             getGenerator = { ApfV61Generator(apfInterpreterVersion, ramSize, clampSize) },
1156             incTotal = true
1157         )
1158     }
1159 
doTestCountAndPassDropCompareR0null1160     private fun doTestCountAndPassDropCompareR0(
1161             getGenerator: () -> ApfV4GeneratorBase<*>,
1162             incTotal: Boolean
1163     ) {
1164         var program = getGenerator()
1165                 .addLoadImmediate(R0, 123)
1166                 .addCountAndDropIfR0Equals(123, Counter.DROPPED_ETH_BROADCAST)
1167                 .addPass()
1168                 .addCountTrampoline()
1169                 .generate()
1170         apfTestHelpers.verifyProgramRun(
1171                 apfInterpreterVersion,
1172                 program,
1173                 testPacket,
1174                 DROPPED_ETH_BROADCAST,
1175                 incTotal = incTotal
1176         )
1177 
1178         program = getGenerator()
1179                 .addLoadImmediate(R0, 123)
1180                 .addCountAndPassIfR0Equals(123, Counter.PASSED_ARP_REQUEST)
1181                 .addPass()
1182                 .addCountTrampoline()
1183                 .generate()
1184         apfTestHelpers.verifyProgramRun(
1185             apfInterpreterVersion,
1186             program,
1187             testPacket,
1188             PASSED_ARP_REQUEST,
1189             incTotal = incTotal
1190         )
1191 
1192         program = getGenerator()
1193                 .addLoadImmediate(R0, 123)
1194                 .addCountAndDropIfR0NotEquals(124, Counter.DROPPED_ETH_BROADCAST)
1195                 .addPass()
1196                 .addCountTrampoline()
1197                 .generate()
1198         apfTestHelpers.verifyProgramRun(
1199                 apfInterpreterVersion,
1200                 program,
1201                 testPacket,
1202                 DROPPED_ETH_BROADCAST,
1203                 incTotal = incTotal
1204         )
1205 
1206         program = getGenerator()
1207                 .addLoadImmediate(R0, 123)
1208                 .addCountAndPassIfR0NotEquals(124, Counter.PASSED_ARP_REQUEST)
1209                 .addPass()
1210                 .addCountTrampoline()
1211                 .generate()
1212         apfTestHelpers.verifyProgramRun(
1213             apfInterpreterVersion,
1214             program,
1215             testPacket,
1216             PASSED_ARP_REQUEST,
1217             incTotal = incTotal
1218         )
1219 
1220         program = getGenerator()
1221                 .addLoadImmediate(R0, 123)
1222                 .addCountAndDropIfR0LessThan(124, Counter.DROPPED_ETH_BROADCAST)
1223                 .addPass()
1224                 .addCountTrampoline()
1225                 .generate()
1226         apfTestHelpers.verifyProgramRun(
1227                 apfInterpreterVersion,
1228                 program,
1229                 testPacket,
1230                 DROPPED_ETH_BROADCAST,
1231                 incTotal = incTotal
1232         )
1233 
1234         program = getGenerator()
1235                 .addLoadImmediate(R0, 123)
1236                 .addCountAndPassIfR0LessThan(124, Counter.PASSED_ARP_REQUEST)
1237                 .addPass()
1238                 .addCountTrampoline()
1239                 .generate()
1240         apfTestHelpers.verifyProgramRun(
1241             apfInterpreterVersion,
1242             program,
1243             testPacket,
1244             PASSED_ARP_REQUEST,
1245             incTotal = incTotal
1246         )
1247 
1248         program = getGenerator()
1249                 .addLoadImmediate(R0, 123)
1250                 .addCountAndDropIfR0GreaterThan(122, Counter.DROPPED_ETH_BROADCAST)
1251                 .addPass()
1252                 .addCountTrampoline()
1253                 .generate()
1254         apfTestHelpers.verifyProgramRun(
1255                 apfInterpreterVersion,
1256                 program,
1257                 testPacket,
1258                 DROPPED_ETH_BROADCAST,
1259                 incTotal = incTotal
1260         )
1261 
1262         program = getGenerator()
1263                 .addLoadImmediate(R0, 123)
1264                 .addCountAndPassIfR0GreaterThan(122, Counter.PASSED_ARP_REQUEST)
1265                 .addPass()
1266                 .addCountTrampoline()
1267                 .generate()
1268         apfTestHelpers.verifyProgramRun(
1269             apfInterpreterVersion,
1270             program,
1271             testPacket,
1272             PASSED_ARP_REQUEST,
1273             incTotal = incTotal
1274         )
1275 
1276         program = getGenerator()
1277                 .addLoadImmediate(R0, 1)
1278                 .addCountAndDropIfBytesAtR0NotEqual(
1279                         byteArrayOf(5, 5), DROPPED_ETH_BROADCAST)
1280                 .addPass()
1281                 .addCountTrampoline()
1282                 .generate()
1283         apfTestHelpers.verifyProgramRun(
1284                 apfInterpreterVersion,
1285                 program,
1286                 testPacket,
1287                 DROPPED_ETH_BROADCAST,
1288                 incTotal = incTotal
1289         )
1290 
1291         program = getGenerator()
1292                 .addLoadImmediate(R0, 1)
1293                 .addCountAndPassIfBytesAtR0NotEqual(
1294                         byteArrayOf(5, 5), PASSED_ARP_REQUEST)
1295                 .addPass()
1296                 .addCountTrampoline()
1297                 .generate()
1298         apfTestHelpers.verifyProgramRun(
1299             apfInterpreterVersion,
1300             program,
1301             testPacket,
1302             PASSED_ARP_REQUEST,
1303             incTotal = incTotal
1304         )
1305 
1306         program = getGenerator()
1307                 .addLoadImmediate(R0, 1)
1308                 .addCountAndDropIfR0AnyBitsSet(0xffff, DROPPED_ETH_BROADCAST)
1309                 .addPass()
1310                 .addCountTrampoline()
1311                 .generate()
1312         apfTestHelpers.verifyProgramRun(
1313                 apfInterpreterVersion,
1314                 program,
1315                 testPacket,
1316                 DROPPED_ETH_BROADCAST,
1317                 incTotal = incTotal
1318         )
1319 
1320         program = getGenerator()
1321                 .addLoadImmediate(R0, 1)
1322                 .addCountAndPassIfR0AnyBitsSet(0xffff, PASSED_ARP_REQUEST)
1323                 .addPass()
1324                 .addCountTrampoline()
1325                 .generate()
1326         apfTestHelpers.verifyProgramRun(
1327             apfInterpreterVersion,
1328             program,
1329             testPacket,
1330             PASSED_ARP_REQUEST,
1331             incTotal = incTotal
1332         )
1333 
1334         program = getGenerator()
1335                 .addLoadImmediate(R0, 123)
1336                 .addCountAndDropIfR0IsOneOf(setOf(123), DROPPED_ETH_BROADCAST)
1337                 .addPass()
1338                 .addCountTrampoline()
1339                 .generate()
1340         apfTestHelpers.verifyProgramRun(
1341                 apfInterpreterVersion,
1342                 program,
1343                 testPacket,
1344                 DROPPED_ETH_BROADCAST,
1345                 incTotal = incTotal
1346         )
1347 
1348         program = getGenerator()
1349                 .addLoadImmediate(R0, 123)
1350                 .addCountAndPassIfR0IsOneOf(setOf(123), PASSED_ARP_REQUEST)
1351                 .addPass()
1352                 .addCountTrampoline()
1353                 .generate()
1354         apfTestHelpers.verifyProgramRun(
1355             apfInterpreterVersion,
1356             program,
1357             testPacket,
1358             PASSED_ARP_REQUEST,
1359             incTotal = incTotal
1360         )
1361 
1362         program = getGenerator()
1363                 .addLoadImmediate(R0, 123)
1364                 .addCountAndDropIfR0IsNoneOf(setOf(124), DROPPED_ETH_BROADCAST)
1365                 .addPass()
1366                 .addCountTrampoline()
1367                 .generate()
1368         apfTestHelpers.verifyProgramRun(
1369                 apfInterpreterVersion,
1370                 program,
1371                 testPacket,
1372                 DROPPED_ETH_BROADCAST,
1373                 incTotal = incTotal
1374         )
1375 
1376         program = getGenerator()
1377                 .addLoadImmediate(R0, 123)
1378                 .addCountAndPassIfR0IsNoneOf(setOf(124), PASSED_ARP_REQUEST)
1379                 .addPass()
1380                 .addCountTrampoline()
1381                 .generate()
1382         apfTestHelpers.verifyProgramRun(
1383             apfInterpreterVersion,
1384             program,
1385             testPacket,
1386             PASSED_ARP_REQUEST,
1387             incTotal = incTotal
1388         )
1389 
1390         program = getGenerator()
1391                 .addLoadImmediate(R0, 123)
1392                 .addCountAndDropIfR0IsOneOf(setOf(123, 124), DROPPED_ETH_BROADCAST)
1393                 .addPass()
1394                 .addCountTrampoline()
1395                 .generate()
1396         apfTestHelpers.verifyProgramRun(
1397                 apfInterpreterVersion,
1398                 program,
1399                 testPacket,
1400                 DROPPED_ETH_BROADCAST,
1401                 incTotal = incTotal
1402         )
1403 
1404         program = getGenerator()
1405                 .addLoadImmediate(R0, 123)
1406                 .addCountAndPassIfR0IsOneOf(setOf(123, 124), PASSED_ARP_REQUEST)
1407                 .addPass()
1408                 .addCountTrampoline()
1409                 .generate()
1410         apfTestHelpers.verifyProgramRun(
1411             apfInterpreterVersion,
1412             program,
1413             testPacket,
1414             PASSED_ARP_REQUEST,
1415             incTotal = incTotal
1416         )
1417 
1418         program = getGenerator()
1419                 .addLoadImmediate(R0, 123)
1420                 .addCountAndDropIfR0IsNoneOf(setOf(122, 124), DROPPED_ETH_BROADCAST)
1421                 .addPass()
1422                 .addCountTrampoline()
1423                 .generate()
1424         apfTestHelpers.verifyProgramRun(
1425                 apfInterpreterVersion,
1426                 program,
1427                 testPacket,
1428                 DROPPED_ETH_BROADCAST,
1429                 incTotal = incTotal
1430         )
1431 
1432         program = getGenerator()
1433                 .addLoadImmediate(R0, 123)
1434                 .addCountAndPassIfR0IsNoneOf(setOf(122, 124), PASSED_ARP_REQUEST)
1435                 .addPass()
1436                 .addCountTrampoline()
1437                 .generate()
1438         apfTestHelpers.verifyProgramRun(
1439             apfInterpreterVersion,
1440             program,
1441             testPacket,
1442             PASSED_ARP_REQUEST,
1443             incTotal = incTotal
1444         )
1445 
1446         program = getGenerator()
1447                 .addLoadImmediate(R0, 0)
1448                 .addCountAndDropIfBytesAtR0EqualsAnyOf(
1449                         listOf(byteArrayOf(1, 2), byteArrayOf(3, 4)),
1450                         DROPPED_ETH_BROADCAST
1451                 )
1452                 .addPass()
1453                 .addCountTrampoline()
1454                 .generate()
1455         apfTestHelpers.verifyProgramRun(
1456                 apfInterpreterVersion,
1457                 program,
1458                 testPacket,
1459                 DROPPED_ETH_BROADCAST,
1460                 incTotal = incTotal
1461         )
1462 
1463         program = getGenerator()
1464                 .addLoadImmediate(R0, 0)
1465                 .addCountAndPassIfBytesAtR0EqualsAnyOf(
1466                         listOf(byteArrayOf(1, 2), byteArrayOf(3, 4)),
1467                         PASSED_ARP_REQUEST
1468                 )
1469                 .addPass()
1470                 .addCountTrampoline()
1471                 .generate()
1472         apfTestHelpers.verifyProgramRun(
1473             apfInterpreterVersion,
1474             program,
1475             testPacket,
1476             PASSED_ARP_REQUEST,
1477             incTotal = incTotal
1478         )
1479 
1480         program = getGenerator()
1481                 .addLoadImmediate(R0, 0)
1482                 .addCountAndDropIfBytesAtR0EqualsNoneOf(
1483                         listOf(byteArrayOf(1, 3), byteArrayOf(3, 4)),
1484                         DROPPED_ETH_BROADCAST
1485                 )
1486                 .addPass()
1487                 .addCountTrampoline()
1488                 .generate()
1489         apfTestHelpers.verifyProgramRun(
1490                 apfInterpreterVersion,
1491                 program,
1492                 testPacket,
1493                 DROPPED_ETH_BROADCAST,
1494                 incTotal = incTotal
1495         )
1496 
1497         program = getGenerator()
1498                 .addLoadImmediate(R0, 0)
1499                 .addCountAndPassIfBytesAtR0EqualsNoneOf(
1500                         listOf(byteArrayOf(1, 3), byteArrayOf(3, 4)),
1501                         PASSED_ARP_REQUEST
1502                 )
1503                 .addPass()
1504                 .addCountTrampoline()
1505                 .generate()
1506         apfTestHelpers.verifyProgramRun(
1507             apfInterpreterVersion,
1508             program,
1509             testPacket,
1510             PASSED_ARP_REQUEST,
1511             incTotal = incTotal
1512         )
1513 
1514         program = getGenerator()
1515                 .addLoadImmediate(R0, 1)
1516                 .addCountAndDropIfBytesAtR0Equal(
1517                         byteArrayOf(2, 3), DROPPED_ETH_BROADCAST)
1518                 .addPass()
1519                 .addCountTrampoline()
1520                 .generate()
1521         apfTestHelpers.verifyProgramRun(
1522                 apfInterpreterVersion,
1523                 program,
1524                 testPacket,
1525                 DROPPED_ETH_BROADCAST,
1526                 incTotal = incTotal
1527         )
1528 
1529         program = getGenerator()
1530                 .addLoadImmediate(R0, 1)
1531                 .addCountAndPassIfBytesAtR0Equal(
1532                         byteArrayOf(2, 3), PASSED_ARP_REQUEST)
1533                 .addPass()
1534                 .addCountTrampoline()
1535                 .generate()
1536         apfTestHelpers.verifyProgramRun(
1537             apfInterpreterVersion,
1538             program,
1539             testPacket,
1540             PASSED_ARP_REQUEST,
1541             incTotal = incTotal
1542         )
1543     }
1544 
1545     @Test
testV4CountAndPassDropnull1546     fun testV4CountAndPassDrop() {
1547         var program = ApfV4Generator(APF_VERSION_3, ramSize, clampSize)
1548                 .addCountAndDrop(Counter.DROPPED_ETH_BROADCAST)
1549                 .addCountTrampoline()
1550                 .generate()
1551         apfTestHelpers.verifyProgramRun(
1552                 apfInterpreterVersion,
1553                 program,
1554                 testPacket,
1555                 DROPPED_ETH_BROADCAST,
1556                 incTotal = false
1557         )
1558 
1559         program = ApfV4Generator(APF_VERSION_3, ramSize, clampSize)
1560                 .addCountAndPass(Counter.PASSED_ARP_REQUEST)
1561                 .addCountTrampoline()
1562                 .generate()
1563         apfTestHelpers.verifyProgramRun(
1564             apfInterpreterVersion,
1565             program,
1566             testPacket,
1567             PASSED_ARP_REQUEST,
1568             incTotal = false
1569         )
1570     }
1571 
1572     @Test
testV2CountAndPassDropnull1573     fun testV2CountAndPassDrop() {
1574         var program = ApfV4Generator(APF_VERSION_2, ramSize, clampSize)
1575                 .addCountAndDrop(Counter.DROPPED_ETH_BROADCAST)
1576                 .addCountTrampoline()
1577                 .generate()
1578         var dataRegion = ByteArray(Counter.totalSize()) { 0 }
1579         apfTestHelpers.assertVerdict(apfInterpreterVersion, DROP, program, testPacket, dataRegion)
1580         assertContentEquals(ByteArray(Counter.totalSize()) { 0 }, dataRegion)
1581 
1582         program = ApfV4Generator(APF_VERSION_2, ramSize, clampSize)
1583                 .addCountAndPass(PASSED_ARP_REQUEST)
1584                 .addCountTrampoline()
1585                 .generate()
1586         dataRegion = ByteArray(Counter.totalSize()) { 0 }
1587         apfTestHelpers.assertVerdict(apfInterpreterVersion, PASS, program, testPacket, dataRegion)
1588         assertContentEquals(ByteArray(Counter.totalSize()) { 0 }, dataRegion)
1589     }
1590 
1591     @Test
testAllocateFailurenull1592     fun testAllocateFailure() {
1593         val program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1594                 // allocate size: 65535 > sizeof(apf_test_buffer): 1514, trigger allocate failure.
1595                 .addAllocate(65535)
1596                 .addDrop()
1597                 .generate()
1598         apfTestHelpers.verifyProgramRun(
1599             apfInterpreterVersion,
1600             program,
1601             testPacket,
1602             PASSED_ALLOCATE_FAILURE
1603         )
1604     }
1605 
1606     @Test
testTransmitFailurenull1607     fun testTransmitFailure() {
1608         val program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1609                 .addAllocate(14)
1610                 // len: 13 is less than ETH_HLEN, trigger transmit failure.
1611                 .addLoadImmediate(R0, 13)
1612                 .addStoreToMemory(MemorySlot.TX_BUFFER_OUTPUT_POINTER, R0)
1613                 .addTransmitWithoutChecksum()
1614                 .addDrop()
1615                 .generate()
1616         apfTestHelpers.verifyProgramRun(
1617             apfInterpreterVersion,
1618             program,
1619             testPacket,
1620             PASSED_TRANSMIT_FAILURE
1621         )
1622     }
1623 
1624     @Test
testTransmitL4null1625     fun testTransmitL4() {
1626         val etherIpv4UdpPacket = intArrayOf(
1627                 0x01, 0x00, 0x5e, 0x00, 0x00, 0xfb,
1628                 0x38, 0xca, 0x84, 0xb7, 0x7f, 0x16,
1629                 0x08, 0x00, // end of ethernet header
1630                 0x45,
1631                 0x04,
1632                 0x00, 0x3f,
1633                 0x43, 0xcd,
1634                 0x40, 0x00,
1635                 0xff,
1636                 0x11,
1637                 0x00, 0x00, // ipv4 checksum set to 0
1638                 0xc0, 0xa8, 0x01, 0x03,
1639                 0xe0, 0x00, 0x00, 0xfb, // end of ipv4 header
1640                 0x14, 0xe9,
1641                 0x14, 0xe9,
1642                 0x00, 0x2b,
1643                 0x00, 0x2b, // end of udp header. udp checksum set to udp (header + payload) size
1644                 0x00, 0x00, 0x84, 0x00, 0x00, 0x00,
1645                 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c,
1646                 0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04, 0xc0, 0xa8, 0x01,
1647                 0x09,
1648         ).map { it.toByte() }.toByteArray()
1649         val program = ApfV6Generator(etherIpv4UdpPacket, apfInterpreterVersion, ramSize, clampSize)
1650                 .addAllocate(etherIpv4UdpPacket.size)
1651                 .addDataCopy(3, etherIpv4UdpPacket.size) // arg1=src, arg2=len
1652                 .addTransmitL4(
1653                         ETH_HLEN, // ipOfs,
1654                         ETH_HLEN + IPV4_HLEN + 6, // csumOfs
1655                         ETH_HLEN + IPV4_HLEN - 8, // csumStart
1656                         IPPROTO_UDP, // partialCsum
1657                         true // isUdp
1658                 )
1659                 .generate()
1660         apfTestHelpers.assertPass(apfInterpreterVersion, program, testPacket)
1661         val transmitPackets = apfTestHelpers.consumeTransmittedPackets(1)
1662         val txBuf = ByteBuffer.wrap(transmitPackets[0])
1663         Struct.parse(EthernetHeader::class.java, txBuf)
1664         val ipv4Hdr = Struct.parse(Ipv4Header::class.java, txBuf)
1665         val udpHdr = Struct.parse(UdpHeader::class.java, txBuf)
1666         assertEquals(0x9535.toShort(), ipv4Hdr.checksum)
1667         assertEquals(0xa73d.toShort(), udpHdr.checksum)
1668     }
1669 
1670     @Test
testDnsQuestionMatchnull1671     fun testDnsQuestionMatch() {
1672         // needles = { A, B.LOCAL }
1673         val needlesMatch = intArrayOf(
1674                 0x01, 'A'.code,
1675                 0x00,
1676                 0x01, 'B'.code,
1677                 0x05, 'L'.code, 'O'.code, 'C'.code, 'A'.code, 'L'.code,
1678                 0x00,
1679                 0x00
1680         ).map { it.toByte() }.toByteArray()
1681         val udpPayload = intArrayOf(
1682                 0x00, 0x00, 0x00, 0x00, // tid = 0x00, flags = 0x00,
1683                 0x00, 0x02, // qdcount = 2
1684                 0x00, 0x00, // ancount = 0
1685                 0x00, 0x00, // nscount = 0
1686                 0x00, 0x00, // arcount = 0
1687                 0x01, 'a'.code,
1688                 0x01, 'b'.code,
1689                 0x05, 'l'.code, 'o'.code, 'c'.code, 'a'.code, 'l'.code,
1690                 0x00, // qname1 = a.b.local
1691                 0x00, 0x01, 0x00, 0x01, // type = A, class = 0x0001
1692                 0xc0, 0x0e, // qname2 = b.local (name compression)
1693                 0x00, 0x01, 0x00, 0x01 // type = A, class = 0x0001
1694         ).map { it.toByte() }.toByteArray()
1695 
1696         var program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1697                 .addLoadImmediate(R0, 0)
1698                 .addJumpIfPktAtR0ContainDnsQ(needlesMatch, 0x01, DROP_LABEL) // arg2=qtype
1699                 .addPass()
1700                 .generate()
1701         apfTestHelpers.assertDrop(apfInterpreterVersion, program, udpPayload)
1702 
1703         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1704                 .addLoadImmediate(R0, 0)
1705                 .addJumpIfPktAtR0ContainDnsQSafe(needlesMatch, 0x01, DROP_LABEL)
1706                 .addPass()
1707                 .generate()
1708         apfTestHelpers.assertDrop(apfInterpreterVersion, program, udpPayload)
1709 
1710         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1711                 .addLoadImmediate(R0, 0)
1712                 .addJumpIfPktAtR0DoesNotContainDnsQ(needlesMatch, 0x01, DROP_LABEL) // arg2=qtype
1713                 .addPass()
1714                 .generate()
1715         apfTestHelpers.assertPass(apfInterpreterVersion, program, udpPayload)
1716 
1717         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1718                 .addLoadImmediate(R0, 0)
1719                 .addJumpIfPktAtR0DoesNotContainDnsQSafe(needlesMatch, 0x01, DROP_LABEL) // arg2=qtype
1720                 .addPass()
1721                 .generate()
1722         apfTestHelpers.assertPass(apfInterpreterVersion, program, udpPayload)
1723 
1724         val badUdpPayload = intArrayOf(
1725                 0x00, 0x00, 0x00, 0x00, // tid = 0x00, flags = 0x00,
1726                 0x00, 0x02, // qdcount = 2
1727                 0x00, 0x00, // ancount = 0
1728                 0x00, 0x00, // nscount = 0
1729                 0x00, 0x00, // arcount = 0
1730                 0x01, 'a'.code,
1731                 0x01, 'b'.code,
1732                 0x05, 'l'.code, 'o'.code, 'c'.code, 'a'.code, 'l'.code,
1733                 0x00, // qname1 = a.b.local
1734                 0x00, 0x01, 0x00, 0x01, // type = A, class = 0x0001
1735                 0xc0, 0x1b, // corrupted pointer cause infinite loop
1736                 0x00, 0x01, 0x00, 0x01 // type = A, class = 0x0001
1737         ).map { it.toByte() }.toByteArray()
1738 
1739         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1740                 .addLoadImmediate(R0, 0)
1741                 .addJumpIfPktAtR0ContainDnsQ(needlesMatch, 0x01, DROP_LABEL) // arg2=qtype
1742                 .addPass()
1743                 .generate()
1744         apfTestHelpers.verifyProgramRun(
1745             apfInterpreterVersion,
1746             program,
1747             badUdpPayload,
1748             CORRUPT_DNS_PACKET,
1749             result = DROP
1750         )
1751 
1752         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1753                 .addLoadImmediate(R0, 0)
1754                 .addJumpIfPktAtR0ContainDnsQSafe(needlesMatch, 0x01, DROP_LABEL) // arg2=qtype
1755                 .addPass()
1756                 .generate()
1757         apfTestHelpers.verifyProgramRun(
1758             apfInterpreterVersion,
1759             program,
1760             badUdpPayload,
1761             CORRUPT_DNS_PACKET,
1762             result = PASS
1763         )
1764     }
1765 
1766     @Test
testDnsAnswerMatchnull1767     fun testDnsAnswerMatch() {
1768         // needles = { A, B.LOCAL }
1769         val needlesMatch = intArrayOf(
1770                 0x01, 'A'.code,
1771                 0x00,
1772                 0x01, 'B'.code,
1773                 0x05, 'L'.code, 'O'.code, 'C'.code, 'A'.code, 'L'.code,
1774                 0x00,
1775                 0x00
1776         ).map { it.toByte() }.toByteArray()
1777 
1778         val udpPayload = intArrayOf(
1779                 0x00, 0x00, 0x84, 0x00, // tid = 0x00, flags = 0x8400,
1780                 0x00, 0x00, // qdcount = 0
1781                 0x00, 0x02, // ancount = 2
1782                 0x00, 0x00, // nscount = 0
1783                 0x00, 0x00, // arcount = 0
1784                 0x01, 'a'.code,
1785                 0x01, 'b'.code,
1786                 0x05, 'l'.code, 'o'.code, 'c'.code, 'a'.code, 'l'.code,
1787                 0x00, // name1 = a.b.local
1788                 0x00, 0x01, 0x80, 0x01, // type = A, class = 0x8001
1789                 0x00, 0x00, 0x00, 0x78, // ttl = 120
1790                 0x00, 0x04, 0xc0, 0xa8, 0x01, 0x09, // rdlengh = 4, rdata = 192.168.1.9
1791                 0xc0, 0x0e, // name2 = b.local (name compression)
1792                 0x00, 0x01, 0x80, 0x01, // type = A, class = 0x8001
1793                 0x00, 0x00, 0x00, 0x78, // ttl = 120
1794                 0x00, 0x04, 0xc0, 0xa8, 0x01, 0x09 // rdlengh = 4, rdata = 192.168.1.9
1795         ).map { it.toByte() }.toByteArray()
1796 
1797         var program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1798                 .addLoadImmediate(R0, 0)
1799                 .addJumpIfPktAtR0ContainDnsA(needlesMatch, DROP_LABEL)
1800                 .addPass()
1801                 .generate()
1802         apfTestHelpers.assertDrop(apfInterpreterVersion, program, udpPayload)
1803 
1804         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1805                 .addLoadImmediate(R0, 0)
1806                 .addJumpIfPktAtR0ContainDnsASafe(needlesMatch, DROP_LABEL)
1807                 .addPass()
1808                 .generate()
1809         apfTestHelpers.assertDrop(apfInterpreterVersion, program, udpPayload)
1810 
1811         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1812                 .addLoadImmediate(R0, 0)
1813                 .addJumpIfPktAtR0DoesNotContainDnsA(needlesMatch, DROP_LABEL)
1814                 .addPass()
1815                 .generate()
1816         apfTestHelpers.assertPass(apfInterpreterVersion, program, udpPayload)
1817 
1818         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1819                 .addLoadImmediate(R0, 0)
1820                 .addJumpIfPktAtR0DoesNotContainDnsASafe(needlesMatch, DROP_LABEL)
1821                 .addPass()
1822                 .generate()
1823         apfTestHelpers.assertPass(apfInterpreterVersion, program, udpPayload)
1824 
1825         val badUdpPayload = intArrayOf(
1826                 0x00, 0x00, 0x84, 0x00, // tid = 0x00, flags = 0x8400,
1827                 0x00, 0x00, // qdcount = 0
1828                 0x00, 0x02, // ancount = 2
1829                 0x00, 0x00, // nscount = 0
1830                 0x00, 0x00, // arcount = 0
1831                 0x01, 'a'.code,
1832                 0x01, 'b'.code,
1833                 0x05, 'l'.code, 'o'.code, 'c'.code, 'a'.code, 'l'.code,
1834                 0x00, // name1 = a.b.local
1835                 0x00, 0x01, 0x80, 0x01, // type = A, class = 0x8001
1836                 0x00, 0x00, 0x00, 0x78, // ttl = 120
1837                 0x00, 0x04, 0xc0, 0xa8, 0x01, 0x09, // rdlengh = 4, rdata = 192.168.1.9
1838                 0xc0, 0x25, // corrupted pointer cause infinite loop
1839                 0x00, 0x01, 0x80, 0x01, // type = A, class = 0x8001
1840                 0x00, 0x00, 0x00, 0x78, // ttl = 120
1841                 0x00, 0x04, 0xc0, 0xa8, 0x01, 0x09 // rdlengh = 4, rdata = 192.168.1.9
1842         ).map { it.toByte() }.toByteArray()
1843 
1844         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1845                 .addLoadImmediate(R0, 0)
1846                 .addJumpIfPktAtR0ContainDnsA(needlesMatch, DROP_LABEL)
1847                 .addPass()
1848                 .generate()
1849         apfTestHelpers.verifyProgramRun(
1850             apfInterpreterVersion,
1851             program,
1852             badUdpPayload,
1853             CORRUPT_DNS_PACKET,
1854             result = DROP
1855         )
1856 
1857         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1858                 .addLoadImmediate(R0, 0)
1859                 .addJumpIfPktAtR0ContainDnsASafe(needlesMatch, DROP_LABEL)
1860                 .addPass()
1861                 .generate()
1862         apfTestHelpers.verifyProgramRun(
1863             apfInterpreterVersion,
1864             program,
1865             badUdpPayload,
1866             CORRUPT_DNS_PACKET,
1867             result = PASS
1868         )
1869     }
1870 
1871     @Test
testGetCounterValuenull1872     fun testGetCounterValue() {
1873         val counterBytes = intArrayOf(0xff, 0, 0, 0, 0x78, 0x56, 0x34, 0x12)
1874                 .map { it.toByte() }.toByteArray()
1875         assertEquals(0xff, ApfCounterTracker.getCounterValue(counterBytes, Counter.TOTAL_PACKETS))
1876     }
1877 
1878     @Test
testJumpMultipleByteSequencesMatchnull1879     fun testJumpMultipleByteSequencesMatch() {
1880         var program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1881                 .addLoadImmediate(R0, 0)
1882                 .addJumpIfBytesAtR0EqualsAnyOf(
1883                         listOf(byteArrayOf(1, 2, 3), byteArrayOf(6, 5, 4)),
1884                         DROP_LABEL
1885                 )
1886                 .addPass()
1887                 .generate()
1888         apfTestHelpers.assertDrop(apfInterpreterVersion, program, testPacket)
1889 
1890         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1891                 .addLoadImmediate(R0, 2)
1892                 .addJumpIfBytesAtR0EqualsAnyOf(
1893                         listOf(byteArrayOf(1, 2, 3), byteArrayOf(6, 5, 4)),
1894                         DROP_LABEL
1895                 )
1896                 .addPass()
1897                 .generate()
1898         apfTestHelpers.assertPass(apfInterpreterVersion, program, testPacket)
1899 
1900         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1901                 .addLoadImmediate(R0, 1)
1902                 .addJumpIfBytesAtR0EqualsNoneOf(
1903                         listOf(byteArrayOf(1, 2, 3), byteArrayOf(6, 5, 4)),
1904                         DROP_LABEL
1905                 )
1906                 .addPass()
1907                 .generate()
1908         apfTestHelpers.assertDrop(apfInterpreterVersion, program, testPacket)
1909 
1910         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1911                 .addLoadImmediate(R0, 0)
1912                 .addJumpIfBytesAtR0EqualsNoneOf(
1913                         listOf(byteArrayOf(1, 2, 3), byteArrayOf(6, 5, 4)),
1914                         DROP_LABEL
1915                 )
1916                 .addPass()
1917                 .generate()
1918         apfTestHelpers.assertPass(apfInterpreterVersion, program, testPacket)
1919     }
1920 
1921     @Test
testJumpOneOfnull1922     fun testJumpOneOf() {
1923         var program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1924                 .addLoadImmediate(R0, 255)
1925                 .addJumpIfOneOf(R0, setOf(1, 2, 3, 128, 255), DROP_LABEL)
1926                 .addPass()
1927                 .generate()
1928         apfTestHelpers.assertDrop(apfInterpreterVersion, program, testPacket)
1929 
1930         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1931                 .addLoadImmediate(R0, 254)
1932                 .addJumpIfOneOf(R0, setOf(1, 2, 3, 128, 255), DROP_LABEL)
1933                 .addPass()
1934                 .generate()
1935         apfTestHelpers.assertPass(apfInterpreterVersion, program, testPacket)
1936 
1937         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1938                 .addLoadImmediate(R0, 254)
1939                 .addJumpIfNoneOf(R0, setOf(1, 2, 3, 128, 255), DROP_LABEL)
1940                 .addPass()
1941                 .generate()
1942         apfTestHelpers.assertDrop(apfInterpreterVersion, program, testPacket)
1943 
1944         program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1945                 .addLoadImmediate(R0, 255)
1946                 .addJumpIfNoneOf(R0, setOf(1, 2, 3, 128, 255), DROP_LABEL)
1947                 .addPass()
1948                 .generate()
1949         apfTestHelpers.assertPass(apfInterpreterVersion, program, testPacket)
1950     }
1951 
1952     @Test
testDebugBuffernull1953     fun testDebugBuffer() {
1954         val program = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1955                 .addLoad8intoR0(255)
1956                 .generate()
1957         val dataRegion = ByteArray(ramSize - program.size) { 0 }
1958 
1959         apfTestHelpers.assertVerdict(apfInterpreterVersion, PASS, program, testPacket, dataRegion)
1960         // offset 3 in the data region should contain if the interpreter is APFv6 mode or not
1961         assertEquals(1, dataRegion[3])
1962     }
1963 
1964     @Test
testGetApfV6BaseProgramSizenull1965     fun testGetApfV6BaseProgramSize() {
1966         val gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1967         assertEquals(gen.baseProgramSize, gen.generate().size)
1968         assertEquals(7, gen.baseProgramSize)
1969     }
1970 
1971     @Test
testGetApfV4BaseProgramSizenull1972     fun testGetApfV4BaseProgramSize() {
1973         val gen = ApfV4Generator(apfInterpreterVersion, ramSize, clampSize)
1974         assertEquals(gen.baseProgramSize, gen.generate().size)
1975         assertEquals(0, gen.baseProgramSize)
1976     }
1977 
1978     @Test
testGetApfV6DefaultPacketHandlingSizeOverEstimatenull1979     fun testGetApfV6DefaultPacketHandlingSizeOverEstimate() {
1980         val gen = ApfV6Generator(apfInterpreterVersion, ramSize, clampSize)
1981         gen.addDefaultPacketHandling()
1982         val size = gen.programLengthOverEstimate() - gen.baseProgramSize
1983         assertEquals(2, size)
1984         assertEquals(size, gen.defaultPacketHandlingSizeOverEstimate)
1985     }
1986 
1987     @Test
testGetApfV4DefaultPacketHandlingSizeOverEstimatenull1988     fun testGetApfV4DefaultPacketHandlingSizeOverEstimate() {
1989         val gen = ApfV4Generator(apfInterpreterVersion, ramSize, clampSize)
1990         gen.addDefaultPacketHandling()
1991         val size = gen.programLengthOverEstimate() - gen.baseProgramSize
1992         assertEquals(25, size)
1993         assertEquals(size, gen.defaultPacketHandlingSizeOverEstimate)
1994     }
1995 
encodeInstructionnull1996     private fun encodeInstruction(opcode: Int, immLength: Int, register: Int): Byte {
1997         val immLengthEncoding = if (immLength == 4) 3 else immLength
1998         return opcode.shl(3).or(immLengthEncoding.shl(1)).or(register).toByte()
1999     }
2000 
ByteArraynull2001     private fun ByteArray.skipDataAndDebug(): ByteArray {
2002         assertEquals(
2003                 listOf(
2004                         encodeInstruction(14, 2, 1),
2005                         0,
2006                         0,
2007                         encodeInstruction(21, 1, 0),
2008                         48
2009                         // the actual exception buffer size is not checked here.
2010                 ),
2011                 this.take(5)
2012         )
2013         return this.drop(7).toByteArray()
2014     }
2015 }
2016