ApfTest.java revision 7d21eaedade0e01bed665dd2e4ba15e0c217237c
19132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen/* 29132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * Copyright (C) 2012 The Android Open Source Project 39132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * 49132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * Licensed under the Apache License, Version 2.0 (the "License"); 59132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * you may not use this file except in compliance with the License. 69132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * You may obtain a copy of the License at 79132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * 89132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * http://www.apache.org/licenses/LICENSE-2.0 99132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * 109132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * Unless required by applicable law or agreed to in writing, software 119132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * distributed under the License is distributed on an "AS IS" BASIS, 129132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * See the License for the specific language governing permissions and 149132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * limitations under the License. 159132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen */ 169132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 179132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenpackage android.net.apf; 189132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 199132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport static android.system.OsConstants.*; 209132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 219132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport com.android.frameworks.servicestests.R; 229132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 237d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichiimport android.net.LinkAddress; 247d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichiimport android.net.LinkProperties; 257d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichiimport android.net.NetworkUtils; 269132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport android.net.apf.ApfCapabilities; 279132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport android.net.apf.ApfFilter; 289132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport android.net.apf.ApfGenerator; 299132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport android.net.apf.ApfGenerator.IllegalInstructionException; 309132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport android.net.apf.ApfGenerator.Register; 319132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport android.net.ip.IpManager; 326ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichiimport android.net.metrics.IpConnectivityLog; 336ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichiimport android.net.metrics.RaEvent; 349132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport android.os.ConditionVariable; 356ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichiimport android.os.Parcelable; 369132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport android.system.ErrnoException; 379132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport android.system.Os; 389132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport android.test.AndroidTestCase; 399132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport android.test.suitebuilder.annotation.LargeTest; 409132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 416ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichiimport org.mockito.ArgumentCaptor; 426ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichiimport org.mockito.Mock; 436ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichiimport org.mockito.MockitoAnnotations; 446ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichiimport static org.mockito.Mockito.atLeastOnce; 456ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichiimport static org.mockito.Mockito.verify; 466ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi 479132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport java.io.File; 489132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport java.io.FileDescriptor; 499132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport java.io.FileOutputStream; 509132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport java.io.IOException; 519132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport java.io.InputStream; 529132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport java.io.OutputStream; 539132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport java.net.InetAddress; 549132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport java.net.NetworkInterface; 559132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport java.nio.ByteBuffer; 566ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichiimport java.util.List; 579132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 589132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport libcore.io.IoUtils; 599132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenimport libcore.io.Streams; 609132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 619132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen/** 629132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * Tests for APF program generator and interpreter. 639132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * 649132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * Build, install and run with: 65961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi * runtest frameworks-services -c android.net.apf.ApfTest 669132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen */ 679132f34976f16a626c2ec1d3d90624d71e054346Paul Jensenpublic class ApfTest extends AndroidTestCase { 689132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int TIMEOUT_MS = 500; 699132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 706ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi @Mock IpConnectivityLog mLog; 716ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi 729132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen @Override 739132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen public void setUp() throws Exception { 749132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen super.setUp(); 756ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi MockitoAnnotations.initMocks(this); 769132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Load up native shared library containing APF interpreter exposed via JNI. 779132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen System.loadLibrary("servicestestsjni"); 789132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 799132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 809132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Expected return codes from APF interpreter. 819132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private final static int PASS = 1; 829132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private final static int DROP = 0; 839132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Interpreter will just accept packets without link layer headers, so pad fake packet to at 849132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // least the minimum packet size. 859132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private final static int MIN_PKT_SIZE = 15; 869132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 876ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi private final static boolean DROP_MULTICAST = true; 886ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi private final static boolean ALLOW_MULTICAST = false; 896ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi 90961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi private static String label(int code) { 91961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi switch (code) { 92961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi case PASS: return "PASS"; 93961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi case DROP: return "DROP"; 94961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi default: return "UNKNOWN"; 95961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi } 96961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi } 97961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi 98961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi private static void assertReturnCodesEqual(int expected, int got) { 99961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertEquals(label(expected), label(got)); 100961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi } 101961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi 1029132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private void assertVerdict(int expected, byte[] program, byte[] packet, int filterAge) { 103961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertReturnCodesEqual(expected, apfSimulate(program, packet, filterAge)); 104961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi } 105961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi 106961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi private void assertVerdict(int expected, byte[] program, byte[] packet) { 107961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertReturnCodesEqual(expected, apfSimulate(program, packet, 0)); 1089132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 1099132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 1109132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private void assertPass(byte[] program, byte[] packet, int filterAge) { 1119132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertVerdict(PASS, program, packet, filterAge); 1129132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 1139132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 114961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi private void assertPass(byte[] program, byte[] packet) { 115961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertVerdict(PASS, program, packet); 116961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi } 117961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi 1189132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private void assertDrop(byte[] program, byte[] packet, int filterAge) { 1199132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertVerdict(DROP, program, packet, filterAge); 1209132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 1219132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 122961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi private void assertDrop(byte[] program, byte[] packet) { 123961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertVerdict(DROP, program, packet); 124961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi } 125961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi 1269132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private void assertVerdict(int expected, ApfGenerator gen, byte[] packet, int filterAge) 1279132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen throws IllegalInstructionException { 128961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertReturnCodesEqual(expected, apfSimulate(gen.generate(), packet, filterAge)); 1299132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 1309132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 1319132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private void assertPass(ApfGenerator gen, byte[] packet, int filterAge) 1329132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen throws IllegalInstructionException { 1339132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertVerdict(PASS, gen, packet, filterAge); 1349132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 1359132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 1369132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private void assertDrop(ApfGenerator gen, byte[] packet, int filterAge) 1379132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen throws IllegalInstructionException { 1389132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertVerdict(DROP, gen, packet, filterAge); 1399132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 1409132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 1419132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private void assertPass(ApfGenerator gen) 1429132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen throws IllegalInstructionException { 1439132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertVerdict(PASS, gen, new byte[MIN_PKT_SIZE], 0); 1449132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 1459132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 1469132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private void assertDrop(ApfGenerator gen) 1479132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen throws IllegalInstructionException { 1489132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertVerdict(DROP, gen, new byte[MIN_PKT_SIZE], 0); 1499132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 1509132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 1519132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen /** 1529132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * Test each instruction by generating a program containing the instruction, 1539132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * generating bytecode for that program and running it through the 1549132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * interpreter to verify it functions correctly. 1559132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen */ 1569132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen @LargeTest 1579132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen public void testApfInstructions() throws IllegalInstructionException { 1589132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Empty program should pass because having the program counter reach the 1599132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // location immediately after the program indicates the packet should be 1609132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // passed to the AP. 1619132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ApfGenerator gen = new ApfGenerator(); 1629132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(gen); 1639132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 1649132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test jumping to pass label. 1659132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 1669132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJump(gen.PASS_LABEL); 1679132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen byte[] program = gen.generate(); 1689132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertEquals(1, program.length); 1699132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertEquals((14 << 3) | (0 << 1) | 0, program[0]); 1709132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(program, new byte[MIN_PKT_SIZE], 0); 1719132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 1729132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test jumping to drop label. 1739132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 1749132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJump(gen.DROP_LABEL); 1759132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen program = gen.generate(); 1769132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertEquals(2, program.length); 1779132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertEquals((14 << 3) | (1 << 1) | 0, program[0]); 1789132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertEquals(1, program[1]); 1799132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(program, new byte[15], 15); 1809132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 1819132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test jumping if equal to 0. 1829132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 1839132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(0, gen.DROP_LABEL); 1849132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 1859132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 1869132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test jumping if not equal to 0. 1879132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 1889132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0NotEquals(0, gen.DROP_LABEL); 1899132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(gen); 1909132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 1919132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1); 1929132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0NotEquals(0, gen.DROP_LABEL); 1939132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 1949132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 1959132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test jumping if registers equal. 1969132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 1979132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0EqualsR1(gen.DROP_LABEL); 1989132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 1999132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 2009132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test jumping if registers not equal. 2019132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 2029132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0NotEqualsR1(gen.DROP_LABEL); 2039132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(gen); 2049132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 2059132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1); 2069132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0NotEqualsR1(gen.DROP_LABEL); 2079132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 2089132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 2099132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test load immediate. 2109132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 2119132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1234567890); 2129132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); 2139132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 2149132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 2159132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test add. 2169132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 2179132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addAdd(1234567890); 2189132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); 2199132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 2209132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 2219132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test subtract. 2229132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 2239132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addAdd(-1234567890); 2249132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL); 2259132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 2269132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 2279132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test or. 2289132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 2299132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addOr(1234567890); 2309132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); 2319132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 2329132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 2339132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test and. 2349132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 2359132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1234567890); 2369132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addAnd(123456789); 2379132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890 & 123456789, gen.DROP_LABEL); 2389132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 2399132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 2409132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test left shift. 2419132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 2429132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1234567890); 2439132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLeftShift(1); 2449132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890 << 1, gen.DROP_LABEL); 2459132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 2469132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 2479132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test right shift. 2489132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 2499132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1234567890); 2509132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addRightShift(1); 2519132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890 >> 1, gen.DROP_LABEL); 2529132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 2539132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 2549132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test multiply. 2559132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 2569132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1234567890); 2579132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addMul(2); 2589132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890 * 2, gen.DROP_LABEL); 2599132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 2609132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 2619132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test divide. 2629132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 2639132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1234567890); 2649132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addDiv(2); 2659132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890 / 2, gen.DROP_LABEL); 2669132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 2679132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 2689132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test divide by zero. 2699132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 2709132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addDiv(0); 2719132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJump(gen.DROP_LABEL); 2729132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(gen); 2739132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 2749132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test add. 2759132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 2769132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 1234567890); 2779132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addAddR1(); 2789132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); 2799132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 2809132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 2819132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test subtract. 2829132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 2839132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, -1234567890); 2849132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addAddR1(); 2859132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL); 2869132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 2879132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 2889132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test or. 2899132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 2909132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 1234567890); 2919132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addOrR1(); 2929132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); 2939132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 2949132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 2959132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test and. 2969132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 2979132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1234567890); 2989132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 123456789); 2999132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addAndR1(); 3009132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890 & 123456789, gen.DROP_LABEL); 3019132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 3029132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 3039132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test left shift. 3049132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 3059132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1234567890); 3069132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 1); 3079132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLeftShiftR1(); 3089132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890 << 1, gen.DROP_LABEL); 3099132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 3109132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 3119132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test right shift. 3129132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 3139132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1234567890); 3149132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, -1); 3159132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLeftShiftR1(); 3169132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890 >> 1, gen.DROP_LABEL); 3179132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 3189132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 3199132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test multiply. 3209132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 3219132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1234567890); 3229132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 2); 3239132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addMulR1(); 3249132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890 * 2, gen.DROP_LABEL); 3259132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 3269132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 3279132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test divide. 3289132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 3299132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1234567890); 3309132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 2); 3319132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addDivR1(); 3329132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890 / 2, gen.DROP_LABEL); 3339132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 3349132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 3359132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test divide by zero. 3369132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 3379132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addDivR1(); 3389132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJump(gen.DROP_LABEL); 3399132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(gen); 3409132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 3419132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test byte load. 3429132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 3439132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoad8(Register.R0, 1); 3449132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(45, gen.DROP_LABEL); 3459132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0); 3469132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 3479132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test out of bounds load. 3489132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 3499132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoad8(Register.R0, 16); 3509132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(0, gen.DROP_LABEL); 3519132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0); 3529132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 3539132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test half-word load. 3549132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 3559132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoad16(Register.R0, 1); 3569132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals((45 << 8) | 67, gen.DROP_LABEL); 3579132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen, new byte[]{123,45,67,0,0,0,0,0,0,0,0,0,0,0,0}, 0); 3589132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 3599132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test word load. 3609132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 3619132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoad32(Register.R0, 1); 3629132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals((45 << 24) | (67 << 16) | (89 << 8) | 12, gen.DROP_LABEL); 3639132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen, new byte[]{123,45,67,89,12,0,0,0,0,0,0,0,0,0,0}, 0); 3649132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 3659132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test byte indexed load. 3669132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 3679132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 1); 3689132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoad8Indexed(Register.R0, 0); 3699132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(45, gen.DROP_LABEL); 3709132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0); 3719132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 3729132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test out of bounds indexed load. 3739132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 3749132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 8); 3759132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoad8Indexed(Register.R0, 8); 3769132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(0, gen.DROP_LABEL); 3779132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(gen, new byte[]{123,45,0,0,0,0,0,0,0,0,0,0,0,0,0}, 0); 3789132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 3799132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test half-word indexed load. 3809132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 3819132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 1); 3829132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoad16Indexed(Register.R0, 0); 3839132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals((45 << 8) | 67, gen.DROP_LABEL); 3849132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen, new byte[]{123,45,67,0,0,0,0,0,0,0,0,0,0,0,0}, 0); 3859132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 3869132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test word indexed load. 3879132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 3889132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 1); 3899132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoad32Indexed(Register.R0, 0); 3909132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals((45 << 24) | (67 << 16) | (89 << 8) | 12, gen.DROP_LABEL); 3919132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen, new byte[]{123,45,67,89,12,0,0,0,0,0,0,0,0,0,0}, 0); 3929132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 3939132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test jumping if greater than. 3949132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 3959132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0GreaterThan(0, gen.DROP_LABEL); 3969132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(gen); 3979132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 3989132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1); 3999132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0GreaterThan(0, gen.DROP_LABEL); 4009132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 4019132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 4029132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test jumping if less than. 4039132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4049132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0LessThan(0, gen.DROP_LABEL); 4059132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(gen); 4069132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4079132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0LessThan(1, gen.DROP_LABEL); 4089132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 4099132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 4109132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test jumping if any bits set. 4119132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4129132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL); 4139132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(gen); 4149132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4159132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1); 4169132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL); 4179132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 4189132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4199132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 3); 4209132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0AnyBitsSet(3, gen.DROP_LABEL); 4219132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 4229132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 4239132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test jumping if register greater than. 4249132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4259132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0GreaterThanR1(gen.DROP_LABEL); 4269132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(gen); 4279132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4289132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 2); 4299132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 1); 4309132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0GreaterThanR1(gen.DROP_LABEL); 4319132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 4329132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 4339132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test jumping if register less than. 4349132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4359132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0LessThanR1(gen.DROP_LABEL); 4369132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(gen); 4379132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4389132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 1); 4399132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0LessThanR1(gen.DROP_LABEL); 4409132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 4419132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 4429132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test jumping if any bits set in register. 4439132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4449132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 3); 4459132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL); 4469132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(gen); 4479132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4489132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 3); 4499132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1); 4509132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL); 4519132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 4529132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4539132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 3); 4549132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 3); 4559132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0AnyBitsSetR1(gen.DROP_LABEL); 4569132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 4579132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 4589132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test load from memory. 4599132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4609132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadFromMemory(Register.R0, 0); 4619132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(0, gen.DROP_LABEL); 4629132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 4639132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 4649132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test store to memory. 4659132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4669132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 1234567890); 4679132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addStoreToMemory(Register.R1, 12); 4689132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadFromMemory(Register.R0, 12); 4699132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); 4709132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 4719132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 4729132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test filter age pre-filled memory. 4739132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4749132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadFromMemory(Register.R0, gen.FILTER_AGE_MEMORY_SLOT); 4759132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); 4769132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen, new byte[MIN_PKT_SIZE], 1234567890); 4779132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 4789132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test packet size pre-filled memory. 4799132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4809132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadFromMemory(Register.R0, gen.PACKET_SIZE_MEMORY_SLOT); 4819132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(MIN_PKT_SIZE, gen.DROP_LABEL); 4829132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 4839132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 4849132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test IPv4 header size pre-filled memory. 4859132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4869132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadFromMemory(Register.R0, gen.IPV4_HEADER_SIZE_MEMORY_SLOT); 4879132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(20, gen.DROP_LABEL); 4889132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen, new byte[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x45}, 0); 4899132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 4909132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test not. 4919132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4929132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1234567890); 4939132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addNot(Register.R0); 4949132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(~1234567890, gen.DROP_LABEL); 4959132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 4969132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 4979132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test negate. 4989132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 4999132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1234567890); 5009132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addNeg(Register.R0); 5019132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(-1234567890, gen.DROP_LABEL); 5029132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 5039132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 5049132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test move. 5059132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 5069132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 1234567890); 5079132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addMove(Register.R0); 5089132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); 5099132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 5109132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 5119132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1234567890); 5129132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addMove(Register.R1); 5139132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); 5149132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 5159132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 5169132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test swap. 5179132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 5189132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R1, 1234567890); 5199132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addSwap(); 5209132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(1234567890, gen.DROP_LABEL); 5219132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 5229132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 5239132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1234567890); 5249132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addSwap(); 5259132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfR0Equals(0, gen.DROP_LABEL); 5269132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen); 5279132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 5289132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test jump if bytes not equal. 5299132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 5309132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1); 5319132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL); 5329132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen program = gen.generate(); 5339132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertEquals(6, program.length); 5349132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertEquals((13 << 3) | (1 << 1) | 0, program[0]); 5359132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertEquals(1, program[1]); 5369132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertEquals(((20 << 3) | (1 << 1) | 0) - 256, program[2]); 5379132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertEquals(1, program[3]); 5389132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertEquals(1, program[4]); 5399132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertEquals(123, program[5]); 5409132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(program, new byte[MIN_PKT_SIZE], 0); 5419132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 5429132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1); 5439132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL); 544961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi byte[] packet123 = {0,123,0,0,0,0,0,0,0,0,0,0,0,0,0}; 5459132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(gen, packet123, 0); 5469132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 5479132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL); 5489132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen, packet123, 0); 5499132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 5509132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1); 5519132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{1,2,30,4,5}, gen.DROP_LABEL); 552961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi byte[] packet12345 = {0,1,2,3,4,5,0,0,0,0,0,0,0,0,0}; 5539132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(gen, packet12345, 0); 5549132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen = new ApfGenerator(); 5559132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addLoadImmediate(Register.R0, 1); 5569132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{1,2,3,4,5}, gen.DROP_LABEL); 5579132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(gen, packet12345, 0); 5589132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 5599132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 5609132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen /** 5619132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * Generate some BPF programs, translate them to APF, then run APF and BPF programs 5629132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * over packet traces and verify both programs filter out the same packets. 5639132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen */ 5649132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen @LargeTest 5659132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen public void testApfAgainstBpf() throws Exception { 5669132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen String[] tcpdump_filters = new String[]{ "udp", "tcp", "icmp", "icmp6", "udp port 53", 5679132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen "arp", "dst 239.255.255.250", "arp or tcp or udp port 53", "net 192.168.1.0/24", 5689132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen "arp or icmp6 or portrange 53-54", "portrange 53-54 or portrange 100-50000", 5699132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen "tcp[tcpflags] & (tcp-ack|tcp-fin) != 0 and (ip[2:2] > 57 or icmp)" }; 5709132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen String pcap_filename = stageFile(R.raw.apf); 5719132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen for (String tcpdump_filter : tcpdump_filters) { 5729132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen byte[] apf_program = Bpf2Apf.convert(compileToBpf(tcpdump_filter)); 5739132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertTrue("Failed to match for filter: " + tcpdump_filter, 5749132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen compareBpfApf(tcpdump_filter, pcap_filename, apf_program)); 5759132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 5769132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 5779132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 5789132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private class MockIpManagerCallback extends IpManager.Callback { 5799132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private final ConditionVariable mGotApfProgram = new ConditionVariable(); 5809132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private byte[] mLastApfProgram; 5819132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 5829132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen @Override 5839132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen public void installPacketFilter(byte[] filter) { 5849132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen mLastApfProgram = filter; 5859132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen mGotApfProgram.open(); 5869132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 5879132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 5889132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen public void resetApfProgramWait() { 5899132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen mGotApfProgram.close(); 5909132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 5919132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 5929132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen public byte[] getApfProgram() { 5939132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertTrue(mGotApfProgram.block(TIMEOUT_MS)); 5949132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen return mLastApfProgram; 5959132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 5968995d85b9432387520c9f04a69251536754b996bLorenzo Colitti 5978995d85b9432387520c9f04a69251536754b996bLorenzo Colitti public void assertNoProgramUpdate() { 5988995d85b9432387520c9f04a69251536754b996bLorenzo Colitti assertFalse(mGotApfProgram.block(TIMEOUT_MS)); 5998995d85b9432387520c9f04a69251536754b996bLorenzo Colitti } 6009132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 6019132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6029132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static class TestApfFilter extends ApfFilter { 603961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi public final static byte[] MOCK_MAC_ADDR = {1,2,3,4,5,6}; 6049132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private FileDescriptor mWriteSocket; 6059132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6066ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi public TestApfFilter(IpManager.Callback ipManagerCallback, boolean multicastFilter, 6076ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi IpConnectivityLog log) throws Exception { 6080dc1d314709d579ccdc3fc59a5f66557f6cd319dHugo Benichi super(new ApfCapabilities(2, 1700, ARPHRD_ETHER), NetworkInterface.getByName("lo"), 6096ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi ipManagerCallback, multicastFilter, log); 6109132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 6119132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6129132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Pretend an RA packet has been received and show it to ApfFilter. 6139132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen public void pretendPacketReceived(byte[] packet) throws IOException, ErrnoException { 6149132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // ApfFilter's ReceiveThread will be waiting to read this. 6159132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen Os.write(mWriteSocket, packet, 0, packet.length); 6169132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 6179132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6189132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen @Override 6199132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen void maybeStartFilter() { 6209132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen mHardwareAddress = MOCK_MAC_ADDR; 6219132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen installNewProgramLocked(); 6229132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6239132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Create two sockets, "readSocket" and "mWriteSocket" and connect them together. 6249132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen FileDescriptor readSocket = new FileDescriptor(); 6259132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen mWriteSocket = new FileDescriptor(); 6269132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen try { 6279132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen Os.socketpair(AF_UNIX, SOCK_STREAM, 0, mWriteSocket, readSocket); 6289132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } catch (ErrnoException e) { 6299132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen fail(); 6309132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen return; 6319132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 6329132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Now pass readSocket to ReceiveThread as if it was setup to read raw RAs. 6339132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // This allows us to pretend RA packets have been recieved via pretendPacketReceived(). 6349132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen mReceiveThread = new ReceiveThread(readSocket); 6359132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen mReceiveThread.start(); 6369132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 6379132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6389132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen @Override 6399132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen public void shutdown() { 6409132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen super.shutdown(); 6419132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen IoUtils.closeQuietly(mWriteSocket); 6429132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 6439132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 6449132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6459132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ETH_HEADER_LEN = 14; 64638db976514ff2ad12d207a927219762eab179882Hugo Benichi private static final int ETH_DEST_ADDR_OFFSET = 0; 6479132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ETH_ETHERTYPE_OFFSET = 12; 648961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi private static final byte[] ETH_BROADCAST_MAC_ADDRESS = 649961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }; 6509132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6519132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int IPV4_VERSION_IHL_OFFSET = ETH_HEADER_LEN + 0; 6529132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int IPV4_PROTOCOL_OFFSET = ETH_HEADER_LEN + 9; 6539132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int IPV4_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 16; 654961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi private static final byte[] IPV4_BROADCAST_ADDRESS = 655961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi {(byte) 255, (byte) 255, (byte) 255, (byte) 255}; 6569132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6579132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int IPV6_NEXT_HEADER_OFFSET = ETH_HEADER_LEN + 6; 6589132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int IPV6_HEADER_LEN = 40; 6599132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int IPV6_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 24; 6609132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // The IPv6 all nodes address ff02::1 6619132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final byte[] IPV6_ALL_NODES_ADDRESS = 662961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; 6639132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6649132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_TYPE_OFFSET = ETH_HEADER_LEN + IPV6_HEADER_LEN; 6659132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_ROUTER_ADVERTISEMENT = 134; 6669132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_NEIGHBOR_ANNOUNCEMENT = 136; 6679132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6689132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_RA_HEADER_LEN = 16; 6699132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_RA_ROUTER_LIFETIME_OFFSET = 6709132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ETH_HEADER_LEN + IPV6_HEADER_LEN + 6; 6719132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_RA_CHECKSUM_OFFSET = 6729132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ETH_HEADER_LEN + IPV6_HEADER_LEN + 2; 6739132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_RA_OPTION_OFFSET = 6749132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ETH_HEADER_LEN + IPV6_HEADER_LEN + ICMP6_RA_HEADER_LEN; 6759132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6769132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_PREFIX_OPTION_TYPE = 3; 6779132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_PREFIX_OPTION_LEN = 32; 6789132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET = 4; 6799132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET = 8; 6809132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6819132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // From RFC6106: Recursive DNS Server option 6829132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_RDNSS_OPTION_TYPE = 25; 6839132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // From RFC6106: DNS Search List option 6849132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_DNSSL_OPTION_TYPE = 31; 6859132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6869132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // From RFC4191: Route Information option 6879132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_ROUTE_INFO_OPTION_TYPE = 24; 6889132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Above three options all have the same format: 6899132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_4_BYTE_OPTION_LEN = 8; 6909132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_4_BYTE_LIFETIME_OFFSET = 4; 6919132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int ICMP6_4_BYTE_LIFETIME_LEN = 4; 6929132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6939132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int UDP_HEADER_LEN = 8; 6949132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int UDP_DESTINATION_PORT_OFFSET = ETH_HEADER_LEN + 22; 6959132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6969132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int DHCP_CLIENT_PORT = 68; 6979132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 48; 6989132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6994fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi private static final int ARP_HEADER_OFFSET = ETH_HEADER_LEN; 700961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi private static final byte[] ARP_IPV4_REQUEST_HEADER = { 7019132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 0, 1, // Hardware type: Ethernet (1) 7029132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 8, 0, // Protocol type: IP (0x0800) 7039132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 6, // Hardware size: 6 7049132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 4, // Protocol size: 4 7059132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 0, 1 // Opcode: request (1) 7069132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen }; 707961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi private static final byte[] ARP_IPV4_REPLY_HEADER = { 70838db976514ff2ad12d207a927219762eab179882Hugo Benichi 0, 1, // Hardware type: Ethernet (1) 70938db976514ff2ad12d207a927219762eab179882Hugo Benichi 8, 0, // Protocol type: IP (0x0800) 71038db976514ff2ad12d207a927219762eab179882Hugo Benichi 6, // Hardware size: 6 71138db976514ff2ad12d207a927219762eab179882Hugo Benichi 4, // Protocol size: 4 71238db976514ff2ad12d207a927219762eab179882Hugo Benichi 0, 2 // Opcode: reply (2) 71338db976514ff2ad12d207a927219762eab179882Hugo Benichi }; 7144fc3ee5be223122792ebc0ee8a05c93d93e26a52Hugo Benichi private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24; 7159132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 716961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi private static final byte[] MOCK_IPV4_ADDR = {10, 0, 0, 1}; 7177d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi private static final byte[] MOCK_BROADCAST_IPV4_ADDR = {10, 0, 31, (byte) 255}; // prefix = 19 718961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi private static final byte[] MOCK_MULTICAST_IPV4_ADDR = {(byte) 224, 0, 0, 1}; 719961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi private static final byte[] ANOTHER_IPV4_ADDR = {10, 0, 0, 2}; 720961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi private static final byte[] IPV4_ANY_HOST_ADDR = {0, 0, 0, 0}; 7219132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 7229132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen @LargeTest 7239132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen public void testApfFilterIPv4() throws Exception { 7249132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); 7257d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19); 7267d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi LinkProperties lp = new LinkProperties(); 7277d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi lp.addLinkAddress(link); 7280dc1d314709d579ccdc3fc59a5f66557f6cd319dHugo Benichi 7296ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, mLog); 7307d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi apfFilter.setLinkProperties(lp); 7310dc1d314709d579ccdc3fc59a5f66557f6cd319dHugo Benichi 7329132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen byte[] program = ipManagerCallback.getApfProgram(); 7339132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 7349132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Verify empty packet of 100 zero bytes is passed 7359132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ByteBuffer packet = ByteBuffer.wrap(new byte[100]); 736961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, packet.array()); 7379132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 7389132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Verify unicast IPv4 packet is passed 739961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, ETH_DEST_ADDR_OFFSET, TestApfFilter.MOCK_MAC_ADDR); 7409132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); 741961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_IPV4_ADDR); 742961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, packet.array()); 743961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi 7440dc1d314709d579ccdc3fc59a5f66557f6cd319dHugo Benichi // Verify L2 unicast to IPv4 broadcast addresses is dropped (b/30231088) 745961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS); 7460dc1d314709d579ccdc3fc59a5f66557f6cd319dHugo Benichi assertDrop(program, packet.array()); 747961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_BROADCAST_IPV4_ADDR); 7487d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertDrop(program, packet.array()); 749961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi 750961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi // Verify multicast/broadcast IPv4, not DHCP to us, is dropped 751961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS); 752961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, packet.array()); 7539132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen packet.put(IPV4_VERSION_IHL_OFFSET, (byte)0x45); 754961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, packet.array()); 7559132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen packet.put(IPV4_PROTOCOL_OFFSET, (byte)IPPROTO_UDP); 756961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, packet.array()); 7579132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen packet.putShort(UDP_DESTINATION_PORT_OFFSET, (short)DHCP_CLIENT_PORT); 758961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, packet.array()); 759961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_MULTICAST_IPV4_ADDR); 760961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, packet.array()); 761961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_BROADCAST_IPV4_ADDR); 762961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, packet.array()); 763961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS); 764961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, packet.array()); 7659132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 7669132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Verify broadcast IPv4 DHCP to us is passed 767961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, DHCP_CLIENT_MAC_OFFSET, TestApfFilter.MOCK_MAC_ADDR); 768961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, packet.array()); 769961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi 770961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi // Verify unicast IPv4 DHCP to us is passed 771961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, ETH_DEST_ADDR_OFFSET, TestApfFilter.MOCK_MAC_ADDR); 772961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, packet.array()); 7739132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 7749132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen apfFilter.shutdown(); 7759132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 7769132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 7779132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen @LargeTest 7789132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen public void testApfFilterIPv6() throws Exception { 7799132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); 7806ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog); 7819132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen byte[] program = ipManagerCallback.getApfProgram(); 7829132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 7839132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Verify empty IPv6 packet is passed 7849132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ByteBuffer packet = ByteBuffer.wrap(new byte[100]); 7859132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6); 786961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, packet.array()); 7879132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 7889132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Verify empty ICMPv6 packet is passed 7899132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6); 790961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, packet.array()); 7919132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 7929132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Verify empty ICMPv6 NA packet is passed 7939132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen packet.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_NEIGHBOR_ANNOUNCEMENT); 794961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, packet.array()); 7959132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 7969132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Verify ICMPv6 NA to ff02::1 is dropped 797961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, IPV6_DEST_ADDR_OFFSET, IPV6_ALL_NODES_ADDRESS); 798961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, packet.array()); 7999132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 8009132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen apfFilter.shutdown(); 8019132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 8029132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 8039132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen @LargeTest 80411e13e2175674389ed18c2b1e1af69c5ad931e8fLorenzo Colitti public void testApfFilterMulticast() throws Exception { 805961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi final byte[] unicastIpv4Addr = {(byte)192,0,2,63}; 8067d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi final byte[] broadcastIpv4Addr = {(byte)192,0,2,(byte)255}; 807961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi final byte[] multicastIpv4Addr = {(byte)224,0,0,1}; 808961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi final byte[] multicastIpv6Addr = {(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb}; 809961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi 8107d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); 8117d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi LinkAddress link = new LinkAddress(InetAddress.getByAddress(unicastIpv4Addr), 24); 8127d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi LinkProperties lp = new LinkProperties(); 8137d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi lp.addLinkAddress(link); 8147d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi 8157d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog); 8167d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi apfFilter.setLinkProperties(lp); 8177d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi 8187d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi byte[] program = ipManagerCallback.getApfProgram(); 8197d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi 82011e13e2175674389ed18c2b1e1af69c5ad931e8fLorenzo Colitti // Construct IPv4 and IPv6 multicast packets. 821f8a01e84317fcb9d27a294e95603b846143c7fcbPaul Jensen ByteBuffer mcastv4packet = ByteBuffer.wrap(new byte[100]); 822f8a01e84317fcb9d27a294e95603b846143c7fcbPaul Jensen mcastv4packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); 823961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(mcastv4packet, IPV4_DEST_ADDR_OFFSET, multicastIpv4Addr); 824f8a01e84317fcb9d27a294e95603b846143c7fcbPaul Jensen 825f8a01e84317fcb9d27a294e95603b846143c7fcbPaul Jensen ByteBuffer mcastv6packet = ByteBuffer.wrap(new byte[100]); 826f8a01e84317fcb9d27a294e95603b846143c7fcbPaul Jensen mcastv6packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6); 827f8a01e84317fcb9d27a294e95603b846143c7fcbPaul Jensen mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_UDP); 828961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(mcastv6packet, IPV6_DEST_ADDR_OFFSET, multicastIpv6Addr); 829f8a01e84317fcb9d27a294e95603b846143c7fcbPaul Jensen 830f8a01e84317fcb9d27a294e95603b846143c7fcbPaul Jensen // Construct IPv4 broadcast packet. 831961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi ByteBuffer bcastv4packet1 = ByteBuffer.wrap(new byte[100]); 832961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi bcastv4packet1.put(ETH_BROADCAST_MAC_ADDRESS); 833961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi bcastv4packet1.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); 834961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(bcastv4packet1, IPV4_DEST_ADDR_OFFSET, multicastIpv4Addr); 835961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi 836961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi ByteBuffer bcastv4packet2 = ByteBuffer.wrap(new byte[100]); 837961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi bcastv4packet2.put(ETH_BROADCAST_MAC_ADDRESS); 838961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi bcastv4packet2.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); 839961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(bcastv4packet2, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS); 840961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi 841961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi // Construct IPv4 broadcast with L2 unicast address packet (b/30231088). 842961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi ByteBuffer bcastv4unicastl2packet = ByteBuffer.wrap(new byte[100]); 843961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi bcastv4unicastl2packet.put(TestApfFilter.MOCK_MAC_ADDR); 844961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi bcastv4unicastl2packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); 845961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(bcastv4unicastl2packet, IPV4_DEST_ADDR_OFFSET, broadcastIpv4Addr); 84611e13e2175674389ed18c2b1e1af69c5ad931e8fLorenzo Colitti 8479132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Verify initially disabled multicast filter is off 848961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, mcastv4packet.array()); 849961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, mcastv6packet.array()); 850961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, bcastv4packet1.array()); 851961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, bcastv4packet2.array()); 852961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, bcastv4unicastl2packet.array()); 8539132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 8549132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Turn on multicast filter and verify it works 8559132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ipManagerCallback.resetApfProgramWait(); 8569132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen apfFilter.setMulticastFilter(true); 8579132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen program = ipManagerCallback.getApfProgram(); 858961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, mcastv4packet.array()); 859961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, mcastv6packet.array()); 860961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, bcastv4packet1.array()); 861961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, bcastv4packet2.array()); 8627d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertDrop(program, bcastv4unicastl2packet.array()); 8639132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 8649132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Turn off multicast filter and verify it's off 8659132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ipManagerCallback.resetApfProgramWait(); 8669132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen apfFilter.setMulticastFilter(false); 8679132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen program = ipManagerCallback.getApfProgram(); 868961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, mcastv4packet.array()); 869961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, mcastv6packet.array()); 870961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, bcastv4packet1.array()); 871961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, bcastv4packet2.array()); 872961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, bcastv4unicastl2packet.array()); 8739132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 8749132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Verify it can be initialized to on 8759132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ipManagerCallback.resetApfProgramWait(); 8769132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen apfFilter.shutdown(); 8776ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, mLog); 8787d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi apfFilter.setLinkProperties(lp); 8799132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen program = ipManagerCallback.getApfProgram(); 880961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, mcastv4packet.array()); 881961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, mcastv6packet.array()); 882961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, bcastv4packet1.array()); 8837d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertDrop(program, bcastv4unicastl2packet.array()); 88411e13e2175674389ed18c2b1e1af69c5ad931e8fLorenzo Colitti 88511e13e2175674389ed18c2b1e1af69c5ad931e8fLorenzo Colitti // Verify that ICMPv6 multicast is not dropped. 886f8a01e84317fcb9d27a294e95603b846143c7fcbPaul Jensen mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6); 887961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, mcastv6packet.array()); 8889132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 8899132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen apfFilter.shutdown(); 8909132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 8919132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 89238db976514ff2ad12d207a927219762eab179882Hugo Benichi private byte[] getProgram(MockIpManagerCallback cb, ApfFilter filter, LinkProperties lp) { 89338db976514ff2ad12d207a927219762eab179882Hugo Benichi cb.resetApfProgramWait(); 89438db976514ff2ad12d207a927219762eab179882Hugo Benichi filter.setLinkProperties(lp); 89538db976514ff2ad12d207a927219762eab179882Hugo Benichi return cb.getApfProgram(); 89638db976514ff2ad12d207a927219762eab179882Hugo Benichi } 89738db976514ff2ad12d207a927219762eab179882Hugo Benichi 89838db976514ff2ad12d207a927219762eab179882Hugo Benichi private void verifyArpFilter(byte[] program, int filterResult) { 89938db976514ff2ad12d207a927219762eab179882Hugo Benichi // Verify ARP request packet 900961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, arpRequestBroadcast(MOCK_IPV4_ADDR)); 901961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertVerdict(filterResult, program, arpRequestBroadcast(ANOTHER_IPV4_ADDR)); 902961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, arpRequestBroadcast(IPV4_ANY_HOST_ADDR)); 90338db976514ff2ad12d207a927219762eab179882Hugo Benichi 90438db976514ff2ad12d207a927219762eab179882Hugo Benichi // Verify unicast ARP reply packet is always accepted. 905961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, arpReplyUnicast(MOCK_IPV4_ADDR)); 906961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, arpReplyUnicast(ANOTHER_IPV4_ADDR)); 907961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, arpReplyUnicast(IPV4_ANY_HOST_ADDR)); 90838db976514ff2ad12d207a927219762eab179882Hugo Benichi 90938db976514ff2ad12d207a927219762eab179882Hugo Benichi // Verify GARP reply packets are always filtered 910961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, garpReply()); 9119132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 9129132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 9139132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen @LargeTest 9149132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen public void testApfFilterArp() throws Exception { 9159132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); 9166ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog); 9179132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 91838db976514ff2ad12d207a927219762eab179882Hugo Benichi // Verify initially ARP request filter is off, and GARP filter is on. 91938db976514ff2ad12d207a927219762eab179882Hugo Benichi verifyArpFilter(ipManagerCallback.getApfProgram(), PASS); 9209132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 9219132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Inform ApfFilter of our address and verify ARP filtering is on 92238db976514ff2ad12d207a927219762eab179882Hugo Benichi LinkAddress linkAddress = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 24); 9239132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen LinkProperties lp = new LinkProperties(); 92438db976514ff2ad12d207a927219762eab179882Hugo Benichi assertTrue(lp.addLinkAddress(linkAddress)); 92538db976514ff2ad12d207a927219762eab179882Hugo Benichi verifyArpFilter(getProgram(ipManagerCallback, apfFilter, lp), DROP); 9269132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 9279132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Inform ApfFilter of loss of IP and verify ARP filtering is off 92838db976514ff2ad12d207a927219762eab179882Hugo Benichi verifyArpFilter(getProgram(ipManagerCallback, apfFilter, new LinkProperties()), PASS); 9299132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 9309132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen apfFilter.shutdown(); 9319132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 9329132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 93338db976514ff2ad12d207a927219762eab179882Hugo Benichi private static byte[] arpRequestBroadcast(byte[] tip) { 93438db976514ff2ad12d207a927219762eab179882Hugo Benichi ByteBuffer packet = ByteBuffer.wrap(new byte[100]); 93538db976514ff2ad12d207a927219762eab179882Hugo Benichi packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP); 936961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS); 937961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER); 938961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip); 93938db976514ff2ad12d207a927219762eab179882Hugo Benichi return packet.array(); 94038db976514ff2ad12d207a927219762eab179882Hugo Benichi } 94138db976514ff2ad12d207a927219762eab179882Hugo Benichi 94238db976514ff2ad12d207a927219762eab179882Hugo Benichi private static byte[] arpReplyUnicast(byte[] tip) { 94338db976514ff2ad12d207a927219762eab179882Hugo Benichi ByteBuffer packet = ByteBuffer.wrap(new byte[100]); 94438db976514ff2ad12d207a927219762eab179882Hugo Benichi packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP); 945961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER); 946961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip); 94738db976514ff2ad12d207a927219762eab179882Hugo Benichi return packet.array(); 94838db976514ff2ad12d207a927219762eab179882Hugo Benichi } 94938db976514ff2ad12d207a927219762eab179882Hugo Benichi 95038db976514ff2ad12d207a927219762eab179882Hugo Benichi private static byte[] garpReply() { 95138db976514ff2ad12d207a927219762eab179882Hugo Benichi ByteBuffer packet = ByteBuffer.wrap(new byte[100]); 95238db976514ff2ad12d207a927219762eab179882Hugo Benichi packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP); 953961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS); 954961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER); 955961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, IPV4_ANY_HOST_ADDR); 95638db976514ff2ad12d207a927219762eab179882Hugo Benichi return packet.array(); 95738db976514ff2ad12d207a927219762eab179882Hugo Benichi } 95838db976514ff2ad12d207a927219762eab179882Hugo Benichi 9599132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Verify that the last program pushed to the IpManager.Callback properly filters the 9609132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // given packet for the given lifetime. 9619132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private void verifyRaLifetime(MockIpManagerCallback ipManagerCallback, ByteBuffer packet, 9629132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen int lifetime) { 9639132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen byte[] program = ipManagerCallback.getApfProgram(); 9649132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 9659132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Verify new program should drop RA for 1/6th its lifetime 966961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, packet.array()); 9679132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertDrop(program, packet.array(), lifetime/6); 9689132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(program, packet.array(), lifetime/6 + 1); 9699132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen assertPass(program, packet.array(), lifetime); 9709132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 9719132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Verify RA checksum is ignored 9729132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, (short)12345); 973961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, packet.array()); 9749132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, (short)-12345); 975961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, packet.array()); 9769132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 9779132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Verify other changes to RA make it not match filter 9789132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen packet.put(0, (byte)-1); 979961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, packet.array()); 9809132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen packet.put(0, (byte)0); 981961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertDrop(program, packet.array()); 9829132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 9839132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 9849132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Test that when ApfFilter is shown the given packet, it generates a program to filter it 9859132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // for the given lifetime. 9869132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private void testRaLifetime(TestApfFilter apfFilter, MockIpManagerCallback ipManagerCallback, 9879132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ByteBuffer packet, int lifetime) throws IOException, ErrnoException { 9889132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Verify new program generated if ApfFilter witnesses RA 9899132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ipManagerCallback.resetApfProgramWait(); 9909132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen apfFilter.pretendPacketReceived(packet.array()); 9919132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ipManagerCallback.getApfProgram(); 9929132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 9939132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen verifyRaLifetime(ipManagerCallback, packet, lifetime); 9949132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 9959132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 9966ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi private void verifyRaEvent(RaEvent expected) { 9976ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi ArgumentCaptor<Parcelable> captor = ArgumentCaptor.forClass(Parcelable.class); 9986ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi verify(mLog, atLeastOnce()).log(captor.capture()); 9996ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi RaEvent got = lastRaEvent(captor.getAllValues()); 10006ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi if (!raEventEquals(expected, got)) { 10016ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi assertEquals(expected, got); // fail for printing an assertion error message. 10026ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi } 10036ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi } 10046ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi 10056ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi private RaEvent lastRaEvent(List<Parcelable> events) { 10066ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi RaEvent got = null; 10076ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi for (Parcelable ev : events) { 10086ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi if (ev instanceof RaEvent) { 10096ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi got = (RaEvent) ev; 10106ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi } 10116ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi } 10126ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi return got; 10136ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi } 10146ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi 10156ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi private boolean raEventEquals(RaEvent ev1, RaEvent ev2) { 10166ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi return (ev1 != null) && (ev2 != null) 10176ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi && (ev1.routerLifetime == ev2.routerLifetime) 10186ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi && (ev1.prefixValidLifetime == ev2.prefixValidLifetime) 10196ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi && (ev1.prefixPreferredLifetime == ev2.prefixPreferredLifetime) 10206ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi && (ev1.routeInfoLifetime == ev2.routeInfoLifetime) 10216ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi && (ev1.rdnssLifetime == ev2.rdnssLifetime) 10226ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi && (ev1.dnsslLifetime == ev2.dnsslLifetime); 10236ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi } 10246ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi 10258995d85b9432387520c9f04a69251536754b996bLorenzo Colitti private void assertInvalidRa(TestApfFilter apfFilter, MockIpManagerCallback ipManagerCallback, 10268995d85b9432387520c9f04a69251536754b996bLorenzo Colitti ByteBuffer packet) throws IOException, ErrnoException { 10278995d85b9432387520c9f04a69251536754b996bLorenzo Colitti ipManagerCallback.resetApfProgramWait(); 10288995d85b9432387520c9f04a69251536754b996bLorenzo Colitti apfFilter.pretendPacketReceived(packet.array()); 10298995d85b9432387520c9f04a69251536754b996bLorenzo Colitti ipManagerCallback.assertNoProgramUpdate(); 10308995d85b9432387520c9f04a69251536754b996bLorenzo Colitti } 10318995d85b9432387520c9f04a69251536754b996bLorenzo Colitti 10329132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen @LargeTest 10339132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen public void testApfFilterRa() throws Exception { 10349132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); 10356ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi TestApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, mLog); 10369132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen byte[] program = ipManagerCallback.getApfProgram(); 10379132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 10389132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Verify RA is passed the first time 10399132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ByteBuffer basePacket = ByteBuffer.wrap(new byte[ICMP6_RA_OPTION_OFFSET]); 10409132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen basePacket.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6); 10419132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen basePacket.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6); 10429132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen basePacket.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_ROUTER_ADVERTISEMENT); 10439132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen basePacket.putShort(ICMP6_RA_ROUTER_LIFETIME_OFFSET, (short)1000); 104411e13e2175674389ed18c2b1e1af69c5ad931e8fLorenzo Colitti basePacket.position(IPV6_DEST_ADDR_OFFSET); 104511e13e2175674389ed18c2b1e1af69c5ad931e8fLorenzo Colitti basePacket.put(IPV6_ALL_NODES_ADDRESS); 1046961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi assertPass(program, basePacket.array()); 10479132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 10489132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen testRaLifetime(apfFilter, ipManagerCallback, basePacket, 1000); 10496ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi verifyRaEvent(new RaEvent(1000, -1, -1, -1, -1, -1)); 10509132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 10518995d85b9432387520c9f04a69251536754b996bLorenzo Colitti // Ensure zero-length options cause the packet to be silently skipped. 10528995d85b9432387520c9f04a69251536754b996bLorenzo Colitti // Do this before we test other packets. http://b/29586253 10538995d85b9432387520c9f04a69251536754b996bLorenzo Colitti ByteBuffer zeroLengthOptionPacket = ByteBuffer.wrap( 10548995d85b9432387520c9f04a69251536754b996bLorenzo Colitti new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]); 10558995d85b9432387520c9f04a69251536754b996bLorenzo Colitti basePacket.clear(); 10568995d85b9432387520c9f04a69251536754b996bLorenzo Colitti zeroLengthOptionPacket.put(basePacket); 10578995d85b9432387520c9f04a69251536754b996bLorenzo Colitti zeroLengthOptionPacket.put((byte)ICMP6_PREFIX_OPTION_TYPE); 10588995d85b9432387520c9f04a69251536754b996bLorenzo Colitti zeroLengthOptionPacket.put((byte)0); 10598995d85b9432387520c9f04a69251536754b996bLorenzo Colitti assertInvalidRa(apfFilter, ipManagerCallback, zeroLengthOptionPacket); 10608995d85b9432387520c9f04a69251536754b996bLorenzo Colitti 10619132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Generate several RAs with different options and lifetimes, and verify when 10629132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // ApfFilter is shown these packets, it generates programs to filter them for the 10639132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // appropriate lifetime. 10649132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ByteBuffer prefixOptionPacket = ByteBuffer.wrap( 10659132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_LEN]); 10669132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen basePacket.clear(); 10679132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen prefixOptionPacket.put(basePacket); 10689132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen prefixOptionPacket.put((byte)ICMP6_PREFIX_OPTION_TYPE); 10699132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen prefixOptionPacket.put((byte)(ICMP6_PREFIX_OPTION_LEN / 8)); 10709132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen prefixOptionPacket.putInt( 10719132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_PREFERRED_LIFETIME_OFFSET, 100); 10729132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen prefixOptionPacket.putInt( 10739132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ICMP6_RA_OPTION_OFFSET + ICMP6_PREFIX_OPTION_VALID_LIFETIME_OFFSET, 200); 10749132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen testRaLifetime(apfFilter, ipManagerCallback, prefixOptionPacket, 100); 10756ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi verifyRaEvent(new RaEvent(1000, 200, 100, -1, -1, -1)); 10769132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 10779132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ByteBuffer rdnssOptionPacket = ByteBuffer.wrap( 10789132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]); 10799132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen basePacket.clear(); 10809132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen rdnssOptionPacket.put(basePacket); 10819132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen rdnssOptionPacket.put((byte)ICMP6_RDNSS_OPTION_TYPE); 10829132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen rdnssOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8)); 10839132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen rdnssOptionPacket.putInt( 10849132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, 300); 10859132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen testRaLifetime(apfFilter, ipManagerCallback, rdnssOptionPacket, 300); 10866ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi verifyRaEvent(new RaEvent(1000, -1, -1, -1, 300, -1)); 10879132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 10889132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ByteBuffer routeInfoOptionPacket = ByteBuffer.wrap( 10899132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]); 10909132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen basePacket.clear(); 10919132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen routeInfoOptionPacket.put(basePacket); 10929132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen routeInfoOptionPacket.put((byte)ICMP6_ROUTE_INFO_OPTION_TYPE); 10939132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen routeInfoOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8)); 10949132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen routeInfoOptionPacket.putInt( 10959132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, 400); 10969132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen testRaLifetime(apfFilter, ipManagerCallback, routeInfoOptionPacket, 400); 10976ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi verifyRaEvent(new RaEvent(1000, -1, -1, 400, -1, -1)); 10989132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 10999132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ByteBuffer dnsslOptionPacket = ByteBuffer.wrap( 11009132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen new byte[ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_OPTION_LEN]); 11019132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen basePacket.clear(); 11029132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen dnsslOptionPacket.put(basePacket); 11039132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen dnsslOptionPacket.put((byte)ICMP6_DNSSL_OPTION_TYPE); 11049132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen dnsslOptionPacket.put((byte)(ICMP6_4_BYTE_OPTION_LEN / 8)); 11059132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen dnsslOptionPacket.putInt( 11069132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen ICMP6_RA_OPTION_OFFSET + ICMP6_4_BYTE_LIFETIME_OFFSET, 2000); 11079132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Note that lifetime of 2000 will be ignored in favor of shorter 11089132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // route lifetime of 1000. 11099132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen testRaLifetime(apfFilter, ipManagerCallback, dnsslOptionPacket, 1000); 11106ccd51a338fed39217cb3a5c0f229ed547918634Hugo Benichi verifyRaEvent(new RaEvent(1000, -1, -1, -1, -1, 2000)); 11119132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 11129132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen // Verify that current program filters all five RAs: 11139132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen verifyRaLifetime(ipManagerCallback, basePacket, 1000); 11149132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen verifyRaLifetime(ipManagerCallback, prefixOptionPacket, 100); 11159132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen verifyRaLifetime(ipManagerCallback, rdnssOptionPacket, 300); 11169132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen verifyRaLifetime(ipManagerCallback, routeInfoOptionPacket, 400); 11179132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen verifyRaLifetime(ipManagerCallback, dnsslOptionPacket, 1000); 11189132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 11199132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen apfFilter.shutdown(); 11209132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 11219132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 11229132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen /** 11239132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * Stage a file for testing, i.e. make it native accessible. Given a resource ID, 11249132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * copy that resource into the app's data directory and return the path to it. 11259132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen */ 11269132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private String stageFile(int rawId) throws Exception { 11279132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen File file = new File(getContext().getFilesDir(), "staged_file"); 11289132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen new File(file.getParent()).mkdirs(); 11299132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen InputStream in = null; 11309132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen OutputStream out = null; 11319132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen try { 11329132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen in = getContext().getResources().openRawResource(rawId); 11339132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen out = new FileOutputStream(file); 11349132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen Streams.copy(in, out); 11359132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } finally { 11369132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen if (in != null) in.close(); 11379132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen if (out != null) out.close(); 11389132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 11399132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen return file.getAbsolutePath(); 11409132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen } 11419132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 1142961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi private static void put(ByteBuffer buffer, int position, byte[] bytes) { 1143961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi final int original = buffer.position(); 1144961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi buffer.position(position); 1145961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi buffer.put(bytes); 1146961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi buffer.position(original); 1147961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi } 1148961ca49fd67b39d8076ea49d12d2fda73f581399Hugo Benichi 11499132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen /** 11509132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * Call the APF interpreter the run {@code program} on {@code packet} pretending the 11519132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * filter was installed {@code filter_age} seconds ago. 11529132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen */ 11539132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private native static int apfSimulate(byte[] program, byte[] packet, int filter_age); 11549132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 11559132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen /** 11569132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * Compile a tcpdump human-readable filter (e.g. "icmp" or "tcp port 54") into a BPF 11579132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * prorgam and return a human-readable dump of the BPF program identical to "tcpdump -d". 11589132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen */ 11599132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private native static String compileToBpf(String filter); 11609132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen 11619132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen /** 11629132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * Open packet capture file {@code pcap_filename} and filter the packets using tcpdump 11639132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * human-readable filter (e.g. "icmp" or "tcp port 54") compiled to a BPF program and 11649132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * at the same time using APF program {@code apf_program}. Return {@code true} if 11659132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen * both APF and BPF programs filter out exactly the same packets. 11669132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen */ 11679132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen private native static boolean compareBpfApf(String filter, String pcap_filename, 11689132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen byte[] apf_program); 11697d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi 11707d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi public void testBytesToInt() { 11717d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertEquals(0x00000000, ApfFilter.bytesToInt(IPV4_ANY_HOST_ADDR)); 11727d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertEquals(0xffffffff, ApfFilter.bytesToInt(IPV4_BROADCAST_ADDRESS)); 11737d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertEquals(0x0a000001, ApfFilter.bytesToInt(MOCK_IPV4_ADDR)); 11747d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertEquals(0x0a000002, ApfFilter.bytesToInt(ANOTHER_IPV4_ADDR)); 11757d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertEquals(0x0a001fff, ApfFilter.bytesToInt(MOCK_BROADCAST_IPV4_ADDR)); 11767d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertEquals(0xe0000001, ApfFilter.bytesToInt(MOCK_MULTICAST_IPV4_ADDR)); 11777d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi } 11787d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi 11797d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi public void testBroadcastAddress() throws Exception { 11807d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 0)); 11817d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertEqualsIp("0.0.0.0", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 32)); 11827d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertEqualsIp("0.0.3.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 22)); 11837d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertEqualsIp("0.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 8)); 11847d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi 11857d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 0)); 11867d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertEqualsIp("10.0.0.1", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 32)); 11877d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertEqualsIp("10.0.0.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 24)); 11887d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertEqualsIp("10.0.255.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 16)); 11897d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi } 11907d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi 11917d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi public void assertEqualsIp(String expected, int got) throws Exception { 11927d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi int want = ApfFilter.bytesToInt(InetAddress.getByName(expected).getAddress()); 11937d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi assertEquals(want, got); 11947d21eaedade0e01bed665dd2e4ba15e0c217237cHugo Benichi } 11959132f34976f16a626c2ec1d3d90624d71e054346Paul Jensen} 1196