Loading services/net/java/android/net/apf/ApfFilter.java +4 −4 Original line number Diff line number Diff line Loading @@ -171,8 +171,8 @@ public class ApfFilter { private static final int ETH_HEADER_LEN = 14; private static final int ETH_DEST_ADDR_OFFSET = 0; private static final int ETH_ETHERTYPE_OFFSET = 12; private static final byte[] ETH_BROADCAST_MAC_ADDRESS = new byte[]{ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }; private static final byte[] ETH_BROADCAST_MAC_ADDRESS = {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }; // TODO: Make these offsets relative to end of link-layer header; don't include ETH_HEADER_LEN. private static final int IPV4_FRAGMENT_OFFSET_OFFSET = ETH_HEADER_LEN + 6; // Endianness is not an issue for this constant because the APF interpreter always operates in Loading @@ -188,7 +188,7 @@ public class ApfFilter { private static final int IPV6_HEADER_LEN = 40; // The IPv6 all nodes address ff02::1 private static final byte[] IPV6_ALL_NODES_ADDRESS = new byte[]{ (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; private static final int ICMP6_TYPE_OFFSET = ETH_HEADER_LEN + IPV6_HEADER_LEN; private static final int ICMP6_NEIGHBOR_ANNOUNCEMENT = 136; Loading @@ -206,7 +206,7 @@ public class ApfFilter { private static final int ARP_OPCODE_OFFSET = ARP_HEADER_OFFSET + 6; private static final short ARP_OPCODE_REQUEST = 1; private static final short ARP_OPCODE_REPLY = 2; private static final byte[] ARP_IPV4_HEADER = new byte[]{ private static final byte[] ARP_IPV4_HEADER = { 0, 1, // Hardware type: Ethernet (1) 8, 0, // Protocol type: IP (0x0800) 6, // Hardware size: 6 Loading services/tests/servicestests/src/android/net/apf/ApfTest.java +146 −83 Original line number Diff line number Diff line Loading @@ -61,7 +61,7 @@ import libcore.io.Streams; * Tests for APF program generator and interpreter. * * Build, install and run with: * runtest frameworks-services -c com.android.server.ApfTest * runtest frameworks-services -c android.net.apf.ApfTest */ public class ApfTest extends AndroidTestCase { private static final int TIMEOUT_MS = 500; Loading @@ -86,21 +86,45 @@ public class ApfTest extends AndroidTestCase { private final static boolean DROP_MULTICAST = true; private final static boolean ALLOW_MULTICAST = false; private static String label(int code) { switch (code) { case PASS: return "PASS"; case DROP: return "DROP"; default: return "UNKNOWN"; } } private static void assertReturnCodesEqual(int expected, int got) { assertEquals(label(expected), label(got)); } private void assertVerdict(int expected, byte[] program, byte[] packet, int filterAge) { assertEquals(expected, apfSimulate(program, packet, filterAge)); assertReturnCodesEqual(expected, apfSimulate(program, packet, filterAge)); } private void assertVerdict(int expected, byte[] program, byte[] packet) { assertReturnCodesEqual(expected, apfSimulate(program, packet, 0)); } private void assertPass(byte[] program, byte[] packet, int filterAge) { assertVerdict(PASS, program, packet, filterAge); } private void assertPass(byte[] program, byte[] packet) { assertVerdict(PASS, program, packet); } private void assertDrop(byte[] program, byte[] packet, int filterAge) { assertVerdict(DROP, program, packet, filterAge); } private void assertDrop(byte[] program, byte[] packet) { assertVerdict(DROP, program, packet); } private void assertVerdict(int expected, ApfGenerator gen, byte[] packet, int filterAge) throws IllegalInstructionException { assertEquals(expected, apfSimulate(gen.generate(), packet, filterAge)); assertReturnCodesEqual(expected, apfSimulate(gen.generate(), packet, filterAge)); } private void assertPass(ApfGenerator gen, byte[] packet, int filterAge) Loading Loading @@ -516,7 +540,7 @@ public class ApfTest extends AndroidTestCase { gen = new ApfGenerator(); gen.addLoadImmediate(Register.R0, 1); gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL); byte[] packet123 = new byte[]{0,123,0,0,0,0,0,0,0,0,0,0,0,0,0}; byte[] packet123 = {0,123,0,0,0,0,0,0,0,0,0,0,0,0,0}; assertPass(gen, packet123, 0); gen = new ApfGenerator(); gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL); Loading @@ -524,7 +548,7 @@ public class ApfTest extends AndroidTestCase { gen = new ApfGenerator(); gen.addLoadImmediate(Register.R0, 1); gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{1,2,30,4,5}, gen.DROP_LABEL); byte[] packet12345 = new byte[]{0,1,2,3,4,5,0,0,0,0,0,0,0,0,0}; byte[] packet12345 = {0,1,2,3,4,5,0,0,0,0,0,0,0,0,0}; assertDrop(gen, packet12345, 0); gen = new ApfGenerator(); gen.addLoadImmediate(Register.R0, 1); Loading Loading @@ -575,7 +599,7 @@ public class ApfTest extends AndroidTestCase { } private static class TestApfFilter extends ApfFilter { public final static byte[] MOCK_MAC_ADDR = new byte[]{1,2,3,4,5,6}; public final static byte[] MOCK_MAC_ADDR = {1,2,3,4,5,6}; private FileDescriptor mWriteSocket; public TestApfFilter(IpManager.Callback ipManagerCallback, boolean multicastFilter, Loading Loading @@ -620,19 +644,21 @@ public class ApfTest extends AndroidTestCase { private static final int ETH_HEADER_LEN = 14; private static final int ETH_DEST_ADDR_OFFSET = 0; private static final int ETH_ETHERTYPE_OFFSET = 12; private static final byte[] ETH_BROADCAST_MAC_ADDRESS = new byte[]{ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }; private static final byte[] ETH_BROADCAST_MAC_ADDRESS = {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }; private static final int IPV4_VERSION_IHL_OFFSET = ETH_HEADER_LEN + 0; private static final int IPV4_PROTOCOL_OFFSET = ETH_HEADER_LEN + 9; private static final int IPV4_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 16; private static final byte[] IPV4_BROADCAST_ADDRESS = {(byte) 255, (byte) 255, (byte) 255, (byte) 255}; private static final int IPV6_NEXT_HEADER_OFFSET = ETH_HEADER_LEN + 6; private static final int IPV6_HEADER_LEN = 40; private static final int IPV6_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 24; // The IPv6 all nodes address ff02::1 private static final byte[] IPV6_ALL_NODES_ADDRESS = new byte[]{ (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; private static final int ICMP6_TYPE_OFFSET = ETH_HEADER_LEN + IPV6_HEADER_LEN; private static final int ICMP6_ROUTER_ADVERTISEMENT = 134; Loading Loading @@ -670,14 +696,14 @@ public class ApfTest extends AndroidTestCase { private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 48; private static final int ARP_HEADER_OFFSET = ETH_HEADER_LEN; private static final byte[] ARP_IPV4_REQUEST_HEADER = new byte[]{ private static final byte[] ARP_IPV4_REQUEST_HEADER = { 0, 1, // Hardware type: Ethernet (1) 8, 0, // Protocol type: IP (0x0800) 6, // Hardware size: 6 4, // Protocol size: 4 0, 1 // Opcode: request (1) }; private static final byte[] ARP_IPV4_REPLY_HEADER = new byte[]{ private static final byte[] ARP_IPV4_REPLY_HEADER = { 0, 1, // Hardware type: Ethernet (1) 8, 0, // Protocol type: IP (0x0800) 6, // Hardware size: 6 Loading @@ -686,9 +712,11 @@ public class ApfTest extends AndroidTestCase { }; private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24; private static final byte[] MOCK_IPV4_ADDR = new byte[]{10, 0, 0, 1}; private static final byte[] ANOTHER_IPV4_ADDR = new byte[]{10, 0, 0, 2}; private static final byte[] IPV4_ANY_HOST_ADDR = new byte[]{0, 0, 0, 0}; private static final byte[] MOCK_IPV4_ADDR = {10, 0, 0, 1}; private static final byte[] MOCK_BROADCAST_IPV4_ADDR = {10, 0, (byte) 255, (byte) 255}; private static final byte[] MOCK_MULTICAST_IPV4_ADDR = {(byte) 224, 0, 0, 1}; private static final byte[] ANOTHER_IPV4_ADDR = {10, 0, 0, 2}; private static final byte[] IPV4_ANY_HOST_ADDR = {0, 0, 0, 0}; @LargeTest public void testApfFilterIPv4() throws Exception { Loading @@ -698,26 +726,43 @@ public class ApfTest extends AndroidTestCase { // Verify empty packet of 100 zero bytes is passed ByteBuffer packet = ByteBuffer.wrap(new byte[100]); assertPass(program, packet.array(), 0); assertPass(program, packet.array()); // Verify unicast IPv4 packet is passed put(packet, ETH_DEST_ADDR_OFFSET, TestApfFilter.MOCK_MAC_ADDR); packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); assertPass(program, packet.array(), 0); // Verify broadcast IPv4, not DHCP to us, is dropped packet.put(ETH_BROADCAST_MAC_ADDRESS); assertDrop(program, packet.array(), 0); put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_IPV4_ADDR); assertPass(program, packet.array()); // Verify L2 unicast to IPv4 broadcast addresses is passed (b/30231088) put(packet, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS); assertPass(program, packet.array()); put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_BROADCAST_IPV4_ADDR); assertPass(program, packet.array()); // Verify multicast/broadcast IPv4, not DHCP to us, is dropped put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS); assertDrop(program, packet.array()); packet.put(IPV4_VERSION_IHL_OFFSET, (byte)0x45); assertDrop(program, packet.array(), 0); assertDrop(program, packet.array()); packet.put(IPV4_PROTOCOL_OFFSET, (byte)IPPROTO_UDP); assertDrop(program, packet.array(), 0); assertDrop(program, packet.array()); packet.putShort(UDP_DESTINATION_PORT_OFFSET, (short)DHCP_CLIENT_PORT); assertDrop(program, packet.array(), 0); assertDrop(program, packet.array()); put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_MULTICAST_IPV4_ADDR); assertDrop(program, packet.array()); put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_BROADCAST_IPV4_ADDR); assertDrop(program, packet.array()); put(packet, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS); assertDrop(program, packet.array()); // Verify broadcast IPv4 DHCP to us is passed packet.position(DHCP_CLIENT_MAC_OFFSET); packet.put(TestApfFilter.MOCK_MAC_ADDR); assertPass(program, packet.array(), 0); put(packet, DHCP_CLIENT_MAC_OFFSET, TestApfFilter.MOCK_MAC_ADDR); assertPass(program, packet.array()); // Verify unicast IPv4 DHCP to us is passed put(packet, ETH_DEST_ADDR_OFFSET, TestApfFilter.MOCK_MAC_ADDR); assertPass(program, packet.array()); apfFilter.shutdown(); } Loading @@ -731,20 +776,19 @@ public class ApfTest extends AndroidTestCase { // Verify empty IPv6 packet is passed ByteBuffer packet = ByteBuffer.wrap(new byte[100]); packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6); assertPass(program, packet.array(), 0); assertPass(program, packet.array()); // Verify empty ICMPv6 packet is passed packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6); assertPass(program, packet.array(), 0); assertPass(program, packet.array()); // Verify empty ICMPv6 NA packet is passed packet.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_NEIGHBOR_ANNOUNCEMENT); assertPass(program, packet.array(), 0); assertPass(program, packet.array()); // Verify ICMPv6 NA to ff02::1 is dropped packet.position(IPV6_DEST_ADDR_OFFSET); packet.put(IPV6_ALL_NODES_ADDRESS); assertDrop(program, packet.array(), 0); put(packet, IPV6_DEST_ADDR_OFFSET, IPV6_ALL_NODES_ADDRESS); assertDrop(program, packet.array()); apfFilter.shutdown(); } Loading @@ -755,58 +799,78 @@ public class ApfTest extends AndroidTestCase { ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog); byte[] program = ipManagerCallback.getApfProgram(); final byte[] unicastIpv4Addr = {(byte)192,0,2,63}; final byte[] broadcastIpv4Addr = {(byte)192,0,(byte)255,(byte)255}; final byte[] multicastIpv4Addr = {(byte)224,0,0,1}; final byte[] multicastIpv6Addr = {(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb}; // Construct IPv4 and IPv6 multicast packets. ByteBuffer mcastv4packet = ByteBuffer.wrap(new byte[100]); mcastv4packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); mcastv4packet.position(IPV4_DEST_ADDR_OFFSET); mcastv4packet.put(new byte[]{(byte)224,0,0,1}); put(mcastv4packet, IPV4_DEST_ADDR_OFFSET, multicastIpv4Addr); ByteBuffer mcastv6packet = ByteBuffer.wrap(new byte[100]); mcastv6packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6); mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_UDP); mcastv6packet.position(IPV6_DEST_ADDR_OFFSET); mcastv6packet.put(new byte[]{(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb}); put(mcastv6packet, IPV6_DEST_ADDR_OFFSET, multicastIpv6Addr); // Construct IPv4 broadcast packet. ByteBuffer bcastv4packet = ByteBuffer.wrap(new byte[100]); bcastv4packet.put(ETH_BROADCAST_MAC_ADDRESS); bcastv4packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); bcastv4packet.position(IPV4_DEST_ADDR_OFFSET); bcastv4packet.put(new byte[]{(byte)192,(byte)0,(byte)2,(byte)63}); ByteBuffer bcastv4packet1 = ByteBuffer.wrap(new byte[100]); bcastv4packet1.put(ETH_BROADCAST_MAC_ADDRESS); bcastv4packet1.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); put(bcastv4packet1, IPV4_DEST_ADDR_OFFSET, multicastIpv4Addr); ByteBuffer bcastv4packet2 = ByteBuffer.wrap(new byte[100]); bcastv4packet2.put(ETH_BROADCAST_MAC_ADDRESS); bcastv4packet2.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); put(bcastv4packet2, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS); // Construct IPv4 broadcast with L2 unicast address packet (b/30231088). ByteBuffer bcastv4unicastl2packet = ByteBuffer.wrap(new byte[100]); bcastv4unicastl2packet.put(TestApfFilter.MOCK_MAC_ADDR); bcastv4unicastl2packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); put(bcastv4unicastl2packet, IPV4_DEST_ADDR_OFFSET, broadcastIpv4Addr); // Verify initially disabled multicast filter is off assertPass(program, bcastv4packet.array(), 0); assertPass(program, mcastv4packet.array(), 0); assertPass(program, mcastv6packet.array(), 0); assertPass(program, mcastv4packet.array()); assertPass(program, mcastv6packet.array()); assertPass(program, bcastv4packet1.array()); assertPass(program, bcastv4packet2.array()); assertPass(program, bcastv4unicastl2packet.array()); // Turn on multicast filter and verify it works ipManagerCallback.resetApfProgramWait(); apfFilter.setMulticastFilter(true); program = ipManagerCallback.getApfProgram(); assertDrop(program, bcastv4packet.array(), 0); assertDrop(program, mcastv4packet.array(), 0); assertDrop(program, mcastv6packet.array(), 0); assertDrop(program, mcastv4packet.array()); assertDrop(program, mcastv6packet.array()); assertDrop(program, bcastv4packet1.array()); assertDrop(program, bcastv4packet2.array()); assertPass(program, bcastv4unicastl2packet.array()); // Turn off multicast filter and verify it's off ipManagerCallback.resetApfProgramWait(); apfFilter.setMulticastFilter(false); program = ipManagerCallback.getApfProgram(); assertPass(program, bcastv4packet.array(), 0); assertPass(program, mcastv4packet.array(), 0); assertPass(program, mcastv6packet.array(), 0); assertPass(program, mcastv4packet.array()); assertPass(program, mcastv6packet.array()); assertPass(program, bcastv4packet1.array()); assertPass(program, bcastv4packet2.array()); assertPass(program, bcastv4unicastl2packet.array()); // Verify it can be initialized to on ipManagerCallback.resetApfProgramWait(); apfFilter.shutdown(); apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, mLog); program = ipManagerCallback.getApfProgram(); assertDrop(program, bcastv4packet.array(), 0); assertDrop(program, mcastv4packet.array(), 0); assertDrop(program, mcastv6packet.array(), 0); assertDrop(program, mcastv4packet.array()); assertDrop(program, mcastv6packet.array()); assertDrop(program, bcastv4packet1.array()); assertPass(program, bcastv4unicastl2packet.array()); // Verify that ICMPv6 multicast is not dropped. mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6); assertPass(program, mcastv6packet.array(), 0); assertPass(program, mcastv6packet.array()); apfFilter.shutdown(); } Loading @@ -819,17 +883,17 @@ public class ApfTest extends AndroidTestCase { private void verifyArpFilter(byte[] program, int filterResult) { // Verify ARP request packet assertPass(program, arpRequestBroadcast(MOCK_IPV4_ADDR), 0); assertVerdict(filterResult, program, arpRequestBroadcast(ANOTHER_IPV4_ADDR), 0); assertDrop(program, arpRequestBroadcast(IPV4_ANY_HOST_ADDR), 0); assertPass(program, arpRequestBroadcast(MOCK_IPV4_ADDR)); assertVerdict(filterResult, program, arpRequestBroadcast(ANOTHER_IPV4_ADDR)); assertDrop(program, arpRequestBroadcast(IPV4_ANY_HOST_ADDR)); // Verify unicast ARP reply packet is always accepted. assertPass(program, arpReplyUnicast(MOCK_IPV4_ADDR), 0); assertPass(program, arpReplyUnicast(ANOTHER_IPV4_ADDR), 0); assertPass(program, arpReplyUnicast(IPV4_ANY_HOST_ADDR), 0); assertPass(program, arpReplyUnicast(MOCK_IPV4_ADDR)); assertPass(program, arpReplyUnicast(ANOTHER_IPV4_ADDR)); assertPass(program, arpReplyUnicast(IPV4_ANY_HOST_ADDR)); // Verify GARP reply packets are always filtered assertDrop(program, garpReply(), 0); assertDrop(program, garpReply()); } @LargeTest Loading @@ -855,34 +919,26 @@ public class ApfTest extends AndroidTestCase { private static byte[] arpRequestBroadcast(byte[] tip) { ByteBuffer packet = ByteBuffer.wrap(new byte[100]); packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP); packet.position(ETH_DEST_ADDR_OFFSET); packet.put(ETH_BROADCAST_MAC_ADDRESS); packet.position(ARP_HEADER_OFFSET); packet.put(ARP_IPV4_REQUEST_HEADER); packet.position(ARP_TARGET_IP_ADDRESS_OFFSET); packet.put(tip); put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS); put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER); put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip); return packet.array(); } private static byte[] arpReplyUnicast(byte[] tip) { ByteBuffer packet = ByteBuffer.wrap(new byte[100]); packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP); packet.position(ARP_HEADER_OFFSET); packet.put(ARP_IPV4_REPLY_HEADER); packet.position(ARP_TARGET_IP_ADDRESS_OFFSET); packet.put(tip); put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER); put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip); return packet.array(); } private static byte[] garpReply() { ByteBuffer packet = ByteBuffer.wrap(new byte[100]); packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP); packet.position(ETH_DEST_ADDR_OFFSET); packet.put(ETH_BROADCAST_MAC_ADDRESS); packet.position(ARP_HEADER_OFFSET); packet.put(ARP_IPV4_REPLY_HEADER); packet.position(ARP_TARGET_IP_ADDRESS_OFFSET); packet.put(IPV4_ANY_HOST_ADDR); put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS); put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER); put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, IPV4_ANY_HOST_ADDR); return packet.array(); } Loading @@ -893,22 +949,22 @@ public class ApfTest extends AndroidTestCase { byte[] program = ipManagerCallback.getApfProgram(); // Verify new program should drop RA for 1/6th its lifetime assertDrop(program, packet.array(), 0); assertDrop(program, packet.array()); assertDrop(program, packet.array(), lifetime/6); assertPass(program, packet.array(), lifetime/6 + 1); assertPass(program, packet.array(), lifetime); // Verify RA checksum is ignored packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, (short)12345); assertDrop(program, packet.array(), 0); assertDrop(program, packet.array()); packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, (short)-12345); assertDrop(program, packet.array(), 0); assertDrop(program, packet.array()); // Verify other changes to RA make it not match filter packet.put(0, (byte)-1); assertPass(program, packet.array(), 0); assertPass(program, packet.array()); packet.put(0, (byte)0); assertDrop(program, packet.array(), 0); assertDrop(program, packet.array()); } // Test that when ApfFilter is shown the given packet, it generates a program to filter it Loading Loading @@ -973,7 +1029,7 @@ public class ApfTest extends AndroidTestCase { basePacket.putShort(ICMP6_RA_ROUTER_LIFETIME_OFFSET, (short)1000); basePacket.position(IPV6_DEST_ADDR_OFFSET); basePacket.put(IPV6_ALL_NODES_ADDRESS); assertPass(program, basePacket.array(), 0); assertPass(program, basePacket.array()); testRaLifetime(apfFilter, ipManagerCallback, basePacket, 1000); verifyRaEvent(new RaEvent(1000, -1, -1, -1, -1, -1)); Loading Loading @@ -1069,6 +1125,13 @@ public class ApfTest extends AndroidTestCase { return file.getAbsolutePath(); } private static void put(ByteBuffer buffer, int position, byte[] bytes) { final int original = buffer.position(); buffer.position(position); buffer.put(bytes); buffer.position(original); } /** * Call the APF interpreter the run {@code program} on {@code packet} pretending the * filter was installed {@code filter_age} seconds ago. Loading Loading
services/net/java/android/net/apf/ApfFilter.java +4 −4 Original line number Diff line number Diff line Loading @@ -171,8 +171,8 @@ public class ApfFilter { private static final int ETH_HEADER_LEN = 14; private static final int ETH_DEST_ADDR_OFFSET = 0; private static final int ETH_ETHERTYPE_OFFSET = 12; private static final byte[] ETH_BROADCAST_MAC_ADDRESS = new byte[]{ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }; private static final byte[] ETH_BROADCAST_MAC_ADDRESS = {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }; // TODO: Make these offsets relative to end of link-layer header; don't include ETH_HEADER_LEN. private static final int IPV4_FRAGMENT_OFFSET_OFFSET = ETH_HEADER_LEN + 6; // Endianness is not an issue for this constant because the APF interpreter always operates in Loading @@ -188,7 +188,7 @@ public class ApfFilter { private static final int IPV6_HEADER_LEN = 40; // The IPv6 all nodes address ff02::1 private static final byte[] IPV6_ALL_NODES_ADDRESS = new byte[]{ (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; private static final int ICMP6_TYPE_OFFSET = ETH_HEADER_LEN + IPV6_HEADER_LEN; private static final int ICMP6_NEIGHBOR_ANNOUNCEMENT = 136; Loading @@ -206,7 +206,7 @@ public class ApfFilter { private static final int ARP_OPCODE_OFFSET = ARP_HEADER_OFFSET + 6; private static final short ARP_OPCODE_REQUEST = 1; private static final short ARP_OPCODE_REPLY = 2; private static final byte[] ARP_IPV4_HEADER = new byte[]{ private static final byte[] ARP_IPV4_HEADER = { 0, 1, // Hardware type: Ethernet (1) 8, 0, // Protocol type: IP (0x0800) 6, // Hardware size: 6 Loading
services/tests/servicestests/src/android/net/apf/ApfTest.java +146 −83 Original line number Diff line number Diff line Loading @@ -61,7 +61,7 @@ import libcore.io.Streams; * Tests for APF program generator and interpreter. * * Build, install and run with: * runtest frameworks-services -c com.android.server.ApfTest * runtest frameworks-services -c android.net.apf.ApfTest */ public class ApfTest extends AndroidTestCase { private static final int TIMEOUT_MS = 500; Loading @@ -86,21 +86,45 @@ public class ApfTest extends AndroidTestCase { private final static boolean DROP_MULTICAST = true; private final static boolean ALLOW_MULTICAST = false; private static String label(int code) { switch (code) { case PASS: return "PASS"; case DROP: return "DROP"; default: return "UNKNOWN"; } } private static void assertReturnCodesEqual(int expected, int got) { assertEquals(label(expected), label(got)); } private void assertVerdict(int expected, byte[] program, byte[] packet, int filterAge) { assertEquals(expected, apfSimulate(program, packet, filterAge)); assertReturnCodesEqual(expected, apfSimulate(program, packet, filterAge)); } private void assertVerdict(int expected, byte[] program, byte[] packet) { assertReturnCodesEqual(expected, apfSimulate(program, packet, 0)); } private void assertPass(byte[] program, byte[] packet, int filterAge) { assertVerdict(PASS, program, packet, filterAge); } private void assertPass(byte[] program, byte[] packet) { assertVerdict(PASS, program, packet); } private void assertDrop(byte[] program, byte[] packet, int filterAge) { assertVerdict(DROP, program, packet, filterAge); } private void assertDrop(byte[] program, byte[] packet) { assertVerdict(DROP, program, packet); } private void assertVerdict(int expected, ApfGenerator gen, byte[] packet, int filterAge) throws IllegalInstructionException { assertEquals(expected, apfSimulate(gen.generate(), packet, filterAge)); assertReturnCodesEqual(expected, apfSimulate(gen.generate(), packet, filterAge)); } private void assertPass(ApfGenerator gen, byte[] packet, int filterAge) Loading Loading @@ -516,7 +540,7 @@ public class ApfTest extends AndroidTestCase { gen = new ApfGenerator(); gen.addLoadImmediate(Register.R0, 1); gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL); byte[] packet123 = new byte[]{0,123,0,0,0,0,0,0,0,0,0,0,0,0,0}; byte[] packet123 = {0,123,0,0,0,0,0,0,0,0,0,0,0,0,0}; assertPass(gen, packet123, 0); gen = new ApfGenerator(); gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{123}, gen.DROP_LABEL); Loading @@ -524,7 +548,7 @@ public class ApfTest extends AndroidTestCase { gen = new ApfGenerator(); gen.addLoadImmediate(Register.R0, 1); gen.addJumpIfBytesNotEqual(Register.R0, new byte[]{1,2,30,4,5}, gen.DROP_LABEL); byte[] packet12345 = new byte[]{0,1,2,3,4,5,0,0,0,0,0,0,0,0,0}; byte[] packet12345 = {0,1,2,3,4,5,0,0,0,0,0,0,0,0,0}; assertDrop(gen, packet12345, 0); gen = new ApfGenerator(); gen.addLoadImmediate(Register.R0, 1); Loading Loading @@ -575,7 +599,7 @@ public class ApfTest extends AndroidTestCase { } private static class TestApfFilter extends ApfFilter { public final static byte[] MOCK_MAC_ADDR = new byte[]{1,2,3,4,5,6}; public final static byte[] MOCK_MAC_ADDR = {1,2,3,4,5,6}; private FileDescriptor mWriteSocket; public TestApfFilter(IpManager.Callback ipManagerCallback, boolean multicastFilter, Loading Loading @@ -620,19 +644,21 @@ public class ApfTest extends AndroidTestCase { private static final int ETH_HEADER_LEN = 14; private static final int ETH_DEST_ADDR_OFFSET = 0; private static final int ETH_ETHERTYPE_OFFSET = 12; private static final byte[] ETH_BROADCAST_MAC_ADDRESS = new byte[]{ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }; private static final byte[] ETH_BROADCAST_MAC_ADDRESS = {(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff }; private static final int IPV4_VERSION_IHL_OFFSET = ETH_HEADER_LEN + 0; private static final int IPV4_PROTOCOL_OFFSET = ETH_HEADER_LEN + 9; private static final int IPV4_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 16; private static final byte[] IPV4_BROADCAST_ADDRESS = {(byte) 255, (byte) 255, (byte) 255, (byte) 255}; private static final int IPV6_NEXT_HEADER_OFFSET = ETH_HEADER_LEN + 6; private static final int IPV6_HEADER_LEN = 40; private static final int IPV6_DEST_ADDR_OFFSET = ETH_HEADER_LEN + 24; // The IPv6 all nodes address ff02::1 private static final byte[] IPV6_ALL_NODES_ADDRESS = new byte[]{ (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; { (byte) 0xff, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; private static final int ICMP6_TYPE_OFFSET = ETH_HEADER_LEN + IPV6_HEADER_LEN; private static final int ICMP6_ROUTER_ADVERTISEMENT = 134; Loading Loading @@ -670,14 +696,14 @@ public class ApfTest extends AndroidTestCase { private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 48; private static final int ARP_HEADER_OFFSET = ETH_HEADER_LEN; private static final byte[] ARP_IPV4_REQUEST_HEADER = new byte[]{ private static final byte[] ARP_IPV4_REQUEST_HEADER = { 0, 1, // Hardware type: Ethernet (1) 8, 0, // Protocol type: IP (0x0800) 6, // Hardware size: 6 4, // Protocol size: 4 0, 1 // Opcode: request (1) }; private static final byte[] ARP_IPV4_REPLY_HEADER = new byte[]{ private static final byte[] ARP_IPV4_REPLY_HEADER = { 0, 1, // Hardware type: Ethernet (1) 8, 0, // Protocol type: IP (0x0800) 6, // Hardware size: 6 Loading @@ -686,9 +712,11 @@ public class ApfTest extends AndroidTestCase { }; private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24; private static final byte[] MOCK_IPV4_ADDR = new byte[]{10, 0, 0, 1}; private static final byte[] ANOTHER_IPV4_ADDR = new byte[]{10, 0, 0, 2}; private static final byte[] IPV4_ANY_HOST_ADDR = new byte[]{0, 0, 0, 0}; private static final byte[] MOCK_IPV4_ADDR = {10, 0, 0, 1}; private static final byte[] MOCK_BROADCAST_IPV4_ADDR = {10, 0, (byte) 255, (byte) 255}; private static final byte[] MOCK_MULTICAST_IPV4_ADDR = {(byte) 224, 0, 0, 1}; private static final byte[] ANOTHER_IPV4_ADDR = {10, 0, 0, 2}; private static final byte[] IPV4_ANY_HOST_ADDR = {0, 0, 0, 0}; @LargeTest public void testApfFilterIPv4() throws Exception { Loading @@ -698,26 +726,43 @@ public class ApfTest extends AndroidTestCase { // Verify empty packet of 100 zero bytes is passed ByteBuffer packet = ByteBuffer.wrap(new byte[100]); assertPass(program, packet.array(), 0); assertPass(program, packet.array()); // Verify unicast IPv4 packet is passed put(packet, ETH_DEST_ADDR_OFFSET, TestApfFilter.MOCK_MAC_ADDR); packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); assertPass(program, packet.array(), 0); // Verify broadcast IPv4, not DHCP to us, is dropped packet.put(ETH_BROADCAST_MAC_ADDRESS); assertDrop(program, packet.array(), 0); put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_IPV4_ADDR); assertPass(program, packet.array()); // Verify L2 unicast to IPv4 broadcast addresses is passed (b/30231088) put(packet, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS); assertPass(program, packet.array()); put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_BROADCAST_IPV4_ADDR); assertPass(program, packet.array()); // Verify multicast/broadcast IPv4, not DHCP to us, is dropped put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS); assertDrop(program, packet.array()); packet.put(IPV4_VERSION_IHL_OFFSET, (byte)0x45); assertDrop(program, packet.array(), 0); assertDrop(program, packet.array()); packet.put(IPV4_PROTOCOL_OFFSET, (byte)IPPROTO_UDP); assertDrop(program, packet.array(), 0); assertDrop(program, packet.array()); packet.putShort(UDP_DESTINATION_PORT_OFFSET, (short)DHCP_CLIENT_PORT); assertDrop(program, packet.array(), 0); assertDrop(program, packet.array()); put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_MULTICAST_IPV4_ADDR); assertDrop(program, packet.array()); put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_BROADCAST_IPV4_ADDR); assertDrop(program, packet.array()); put(packet, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS); assertDrop(program, packet.array()); // Verify broadcast IPv4 DHCP to us is passed packet.position(DHCP_CLIENT_MAC_OFFSET); packet.put(TestApfFilter.MOCK_MAC_ADDR); assertPass(program, packet.array(), 0); put(packet, DHCP_CLIENT_MAC_OFFSET, TestApfFilter.MOCK_MAC_ADDR); assertPass(program, packet.array()); // Verify unicast IPv4 DHCP to us is passed put(packet, ETH_DEST_ADDR_OFFSET, TestApfFilter.MOCK_MAC_ADDR); assertPass(program, packet.array()); apfFilter.shutdown(); } Loading @@ -731,20 +776,19 @@ public class ApfTest extends AndroidTestCase { // Verify empty IPv6 packet is passed ByteBuffer packet = ByteBuffer.wrap(new byte[100]); packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6); assertPass(program, packet.array(), 0); assertPass(program, packet.array()); // Verify empty ICMPv6 packet is passed packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6); assertPass(program, packet.array(), 0); assertPass(program, packet.array()); // Verify empty ICMPv6 NA packet is passed packet.put(ICMP6_TYPE_OFFSET, (byte)ICMP6_NEIGHBOR_ANNOUNCEMENT); assertPass(program, packet.array(), 0); assertPass(program, packet.array()); // Verify ICMPv6 NA to ff02::1 is dropped packet.position(IPV6_DEST_ADDR_OFFSET); packet.put(IPV6_ALL_NODES_ADDRESS); assertDrop(program, packet.array(), 0); put(packet, IPV6_DEST_ADDR_OFFSET, IPV6_ALL_NODES_ADDRESS); assertDrop(program, packet.array()); apfFilter.shutdown(); } Loading @@ -755,58 +799,78 @@ public class ApfTest extends AndroidTestCase { ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog); byte[] program = ipManagerCallback.getApfProgram(); final byte[] unicastIpv4Addr = {(byte)192,0,2,63}; final byte[] broadcastIpv4Addr = {(byte)192,0,(byte)255,(byte)255}; final byte[] multicastIpv4Addr = {(byte)224,0,0,1}; final byte[] multicastIpv6Addr = {(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb}; // Construct IPv4 and IPv6 multicast packets. ByteBuffer mcastv4packet = ByteBuffer.wrap(new byte[100]); mcastv4packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); mcastv4packet.position(IPV4_DEST_ADDR_OFFSET); mcastv4packet.put(new byte[]{(byte)224,0,0,1}); put(mcastv4packet, IPV4_DEST_ADDR_OFFSET, multicastIpv4Addr); ByteBuffer mcastv6packet = ByteBuffer.wrap(new byte[100]); mcastv6packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IPV6); mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_UDP); mcastv6packet.position(IPV6_DEST_ADDR_OFFSET); mcastv6packet.put(new byte[]{(byte)0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,(byte)0xfb}); put(mcastv6packet, IPV6_DEST_ADDR_OFFSET, multicastIpv6Addr); // Construct IPv4 broadcast packet. ByteBuffer bcastv4packet = ByteBuffer.wrap(new byte[100]); bcastv4packet.put(ETH_BROADCAST_MAC_ADDRESS); bcastv4packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); bcastv4packet.position(IPV4_DEST_ADDR_OFFSET); bcastv4packet.put(new byte[]{(byte)192,(byte)0,(byte)2,(byte)63}); ByteBuffer bcastv4packet1 = ByteBuffer.wrap(new byte[100]); bcastv4packet1.put(ETH_BROADCAST_MAC_ADDRESS); bcastv4packet1.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); put(bcastv4packet1, IPV4_DEST_ADDR_OFFSET, multicastIpv4Addr); ByteBuffer bcastv4packet2 = ByteBuffer.wrap(new byte[100]); bcastv4packet2.put(ETH_BROADCAST_MAC_ADDRESS); bcastv4packet2.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); put(bcastv4packet2, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS); // Construct IPv4 broadcast with L2 unicast address packet (b/30231088). ByteBuffer bcastv4unicastl2packet = ByteBuffer.wrap(new byte[100]); bcastv4unicastl2packet.put(TestApfFilter.MOCK_MAC_ADDR); bcastv4unicastl2packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); put(bcastv4unicastl2packet, IPV4_DEST_ADDR_OFFSET, broadcastIpv4Addr); // Verify initially disabled multicast filter is off assertPass(program, bcastv4packet.array(), 0); assertPass(program, mcastv4packet.array(), 0); assertPass(program, mcastv6packet.array(), 0); assertPass(program, mcastv4packet.array()); assertPass(program, mcastv6packet.array()); assertPass(program, bcastv4packet1.array()); assertPass(program, bcastv4packet2.array()); assertPass(program, bcastv4unicastl2packet.array()); // Turn on multicast filter and verify it works ipManagerCallback.resetApfProgramWait(); apfFilter.setMulticastFilter(true); program = ipManagerCallback.getApfProgram(); assertDrop(program, bcastv4packet.array(), 0); assertDrop(program, mcastv4packet.array(), 0); assertDrop(program, mcastv6packet.array(), 0); assertDrop(program, mcastv4packet.array()); assertDrop(program, mcastv6packet.array()); assertDrop(program, bcastv4packet1.array()); assertDrop(program, bcastv4packet2.array()); assertPass(program, bcastv4unicastl2packet.array()); // Turn off multicast filter and verify it's off ipManagerCallback.resetApfProgramWait(); apfFilter.setMulticastFilter(false); program = ipManagerCallback.getApfProgram(); assertPass(program, bcastv4packet.array(), 0); assertPass(program, mcastv4packet.array(), 0); assertPass(program, mcastv6packet.array(), 0); assertPass(program, mcastv4packet.array()); assertPass(program, mcastv6packet.array()); assertPass(program, bcastv4packet1.array()); assertPass(program, bcastv4packet2.array()); assertPass(program, bcastv4unicastl2packet.array()); // Verify it can be initialized to on ipManagerCallback.resetApfProgramWait(); apfFilter.shutdown(); apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, mLog); program = ipManagerCallback.getApfProgram(); assertDrop(program, bcastv4packet.array(), 0); assertDrop(program, mcastv4packet.array(), 0); assertDrop(program, mcastv6packet.array(), 0); assertDrop(program, mcastv4packet.array()); assertDrop(program, mcastv6packet.array()); assertDrop(program, bcastv4packet1.array()); assertPass(program, bcastv4unicastl2packet.array()); // Verify that ICMPv6 multicast is not dropped. mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6); assertPass(program, mcastv6packet.array(), 0); assertPass(program, mcastv6packet.array()); apfFilter.shutdown(); } Loading @@ -819,17 +883,17 @@ public class ApfTest extends AndroidTestCase { private void verifyArpFilter(byte[] program, int filterResult) { // Verify ARP request packet assertPass(program, arpRequestBroadcast(MOCK_IPV4_ADDR), 0); assertVerdict(filterResult, program, arpRequestBroadcast(ANOTHER_IPV4_ADDR), 0); assertDrop(program, arpRequestBroadcast(IPV4_ANY_HOST_ADDR), 0); assertPass(program, arpRequestBroadcast(MOCK_IPV4_ADDR)); assertVerdict(filterResult, program, arpRequestBroadcast(ANOTHER_IPV4_ADDR)); assertDrop(program, arpRequestBroadcast(IPV4_ANY_HOST_ADDR)); // Verify unicast ARP reply packet is always accepted. assertPass(program, arpReplyUnicast(MOCK_IPV4_ADDR), 0); assertPass(program, arpReplyUnicast(ANOTHER_IPV4_ADDR), 0); assertPass(program, arpReplyUnicast(IPV4_ANY_HOST_ADDR), 0); assertPass(program, arpReplyUnicast(MOCK_IPV4_ADDR)); assertPass(program, arpReplyUnicast(ANOTHER_IPV4_ADDR)); assertPass(program, arpReplyUnicast(IPV4_ANY_HOST_ADDR)); // Verify GARP reply packets are always filtered assertDrop(program, garpReply(), 0); assertDrop(program, garpReply()); } @LargeTest Loading @@ -855,34 +919,26 @@ public class ApfTest extends AndroidTestCase { private static byte[] arpRequestBroadcast(byte[] tip) { ByteBuffer packet = ByteBuffer.wrap(new byte[100]); packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP); packet.position(ETH_DEST_ADDR_OFFSET); packet.put(ETH_BROADCAST_MAC_ADDRESS); packet.position(ARP_HEADER_OFFSET); packet.put(ARP_IPV4_REQUEST_HEADER); packet.position(ARP_TARGET_IP_ADDRESS_OFFSET); packet.put(tip); put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS); put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER); put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip); return packet.array(); } private static byte[] arpReplyUnicast(byte[] tip) { ByteBuffer packet = ByteBuffer.wrap(new byte[100]); packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP); packet.position(ARP_HEADER_OFFSET); packet.put(ARP_IPV4_REPLY_HEADER); packet.position(ARP_TARGET_IP_ADDRESS_OFFSET); packet.put(tip); put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER); put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip); return packet.array(); } private static byte[] garpReply() { ByteBuffer packet = ByteBuffer.wrap(new byte[100]); packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP); packet.position(ETH_DEST_ADDR_OFFSET); packet.put(ETH_BROADCAST_MAC_ADDRESS); packet.position(ARP_HEADER_OFFSET); packet.put(ARP_IPV4_REPLY_HEADER); packet.position(ARP_TARGET_IP_ADDRESS_OFFSET); packet.put(IPV4_ANY_HOST_ADDR); put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS); put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER); put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, IPV4_ANY_HOST_ADDR); return packet.array(); } Loading @@ -893,22 +949,22 @@ public class ApfTest extends AndroidTestCase { byte[] program = ipManagerCallback.getApfProgram(); // Verify new program should drop RA for 1/6th its lifetime assertDrop(program, packet.array(), 0); assertDrop(program, packet.array()); assertDrop(program, packet.array(), lifetime/6); assertPass(program, packet.array(), lifetime/6 + 1); assertPass(program, packet.array(), lifetime); // Verify RA checksum is ignored packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, (short)12345); assertDrop(program, packet.array(), 0); assertDrop(program, packet.array()); packet.putShort(ICMP6_RA_CHECKSUM_OFFSET, (short)-12345); assertDrop(program, packet.array(), 0); assertDrop(program, packet.array()); // Verify other changes to RA make it not match filter packet.put(0, (byte)-1); assertPass(program, packet.array(), 0); assertPass(program, packet.array()); packet.put(0, (byte)0); assertDrop(program, packet.array(), 0); assertDrop(program, packet.array()); } // Test that when ApfFilter is shown the given packet, it generates a program to filter it Loading Loading @@ -973,7 +1029,7 @@ public class ApfTest extends AndroidTestCase { basePacket.putShort(ICMP6_RA_ROUTER_LIFETIME_OFFSET, (short)1000); basePacket.position(IPV6_DEST_ADDR_OFFSET); basePacket.put(IPV6_ALL_NODES_ADDRESS); assertPass(program, basePacket.array(), 0); assertPass(program, basePacket.array()); testRaLifetime(apfFilter, ipManagerCallback, basePacket, 1000); verifyRaEvent(new RaEvent(1000, -1, -1, -1, -1, -1)); Loading Loading @@ -1069,6 +1125,13 @@ public class ApfTest extends AndroidTestCase { return file.getAbsolutePath(); } private static void put(ByteBuffer buffer, int position, byte[] bytes) { final int original = buffer.position(); buffer.position(position); buffer.put(bytes); buffer.position(original); } /** * Call the APF interpreter the run {@code program} on {@code packet} pretending the * filter was installed {@code filter_age} seconds ago. Loading