Loading services/net/java/android/net/apf/ApfFilter.java +63 −35 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.net.apf; import static android.system.OsConstants.*; import android.os.SystemClock; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.NetworkUtils; import android.net.apf.ApfGenerator; Loading @@ -44,6 +45,7 @@ import com.android.internal.util.IndentingPrintWriter; import java.io.FileDescriptor; import java.io.IOException; import java.lang.Thread; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.NetworkInterface; Loading Loading @@ -230,6 +232,9 @@ public class ApfFilter { // Our IPv4 address, if we have just one, otherwise null. @GuardedBy("this") private byte[] mIPv4Address; // The subnet prefix length of our IPv4 network. Only valid if mIPv4Address is not null. @GuardedBy("this") private int mIPv4PrefixLength; @VisibleForTesting ApfFilter(ApfCapabilities apfCapabilities, NetworkInterface networkInterface, Loading Loading @@ -365,26 +370,6 @@ public class ApfFilter { // Can't be static because it's in a non-static inner class. // TODO: Make this static once RA is its own class. private int uint8(byte b) { return b & 0xff; } private int uint16(short s) { return s & 0xffff; } private long uint32(int i) { return i & 0xffffffffL; } private long getUint16(ByteBuffer buffer, int position) { return uint16(buffer.getShort(position)); } private long getUint32(ByteBuffer buffer, int position) { return uint32(buffer.getInt(position)); } private void prefixOptionToString(StringBuffer sb, int offset) { String prefix = IPv6AddresstoString(offset + 16); int length = uint8(mPacket.get(offset + 2)); Loading Loading @@ -780,7 +765,10 @@ public class ApfFilter { // If IPv4 broadcast packet, drop regardless of L2 (b/30231088). gen.addLoad32(Register.R0, IPV4_DEST_ADDR_OFFSET); gen.addJumpIfR0Equals(IPV4_BROADCAST_ADDRESS, gen.DROP_LABEL); // TODO: also filter subnet broadcast address. if (mIPv4Address != null && mIPv4PrefixLength < 31) { int broadcastAddr = ipv4BroadcastAddress(mIPv4Address, mIPv4PrefixLength); gen.addJumpIfR0Equals(broadcastAddr, gen.DROP_LABEL); } // If L2 broadcast packet, drop. gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET); Loading Loading @@ -1078,26 +1066,32 @@ public class ApfFilter { } } // Find the single IPv4 address if there is one, otherwise return null. private static byte[] findIPv4Address(LinkProperties lp) { byte[] ipv4Address = null; for (InetAddress inetAddr : lp.getAddresses()) { byte[] addr = inetAddr.getAddress(); if (addr.length != 4) continue; // More than one IPv4 address, abort if (ipv4Address != null && !Arrays.equals(ipv4Address, addr)) return null; ipv4Address = addr; /** Find the single IPv4 LinkAddress if there is one, otherwise return null. */ private static LinkAddress findIPv4LinkAddress(LinkProperties lp) { LinkAddress ipv4Address = null; for (LinkAddress address : lp.getLinkAddresses()) { if (!(address.getAddress() instanceof Inet4Address)) { continue; } if (ipv4Address != null && !ipv4Address.isSameAddressAs(address)) { // More than one IPv4 address, abort. return null; } ipv4Address = address; } return ipv4Address; } public synchronized void setLinkProperties(LinkProperties lp) { // NOTE: Do not keep a copy of LinkProperties as it would further duplicate state. byte[] ipv4Address = findIPv4Address(lp); // If ipv4Address is the same as mIPv4Address, then there's no change, just return. if (Arrays.equals(ipv4Address, mIPv4Address)) return; // Otherwise update mIPv4Address and install new program. mIPv4Address = ipv4Address; final LinkAddress ipv4Address = findIPv4LinkAddress(lp); final byte[] addr = (ipv4Address != null) ? ipv4Address.getAddress().getAddress() : null; final int prefix = (ipv4Address != null) ? ipv4Address.getPrefixLength() : 0; if ((prefix == mIPv4PrefixLength) && Arrays.equals(addr, mIPv4Address)) { return; } mIPv4Address = addr; mIPv4PrefixLength = prefix; installNewProgramLocked(); } Loading Loading @@ -1143,4 +1137,38 @@ public class ApfFilter { pw.decreaseIndent(); } } private static int uint8(byte b) { return b & 0xff; } private static int uint16(short s) { return s & 0xffff; } private static long uint32(int i) { return i & 0xffffffffL; } private static long getUint16(ByteBuffer buffer, int position) { return uint16(buffer.getShort(position)); } private static long getUint32(ByteBuffer buffer, int position) { return uint32(buffer.getInt(position)); } // TODO: move to android.net.NetworkUtils @VisibleForTesting public static int ipv4BroadcastAddress(byte[] addrBytes, int prefixLength) { return bytesToInt(addrBytes) | (int) (uint32(-1) >>> prefixLength); } @VisibleForTesting public static int bytesToInt(byte[] addrBytes) { return (uint8(addrBytes[0]) << 24) + (uint8(addrBytes[1]) << 16) + (uint8(addrBytes[2]) << 8) + (uint8(addrBytes[3])); } } services/tests/servicestests/src/android/net/apf/ApfTest.java +49 −11 Original line number Diff line number Diff line Loading @@ -20,6 +20,9 @@ import static android.system.OsConstants.*; import com.android.frameworks.servicestests.R; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.NetworkUtils; import android.net.apf.ApfCapabilities; import android.net.apf.ApfFilter; import android.net.apf.ApfGenerator; Loading @@ -28,8 +31,6 @@ import android.net.apf.ApfGenerator.Register; import android.net.ip.IpManager; import android.net.metrics.IpConnectivityLog; import android.net.metrics.RaEvent; import android.net.LinkAddress; import android.net.LinkProperties; import android.os.ConditionVariable; import android.os.Parcelable; import android.system.ErrnoException; Loading Loading @@ -713,7 +714,7 @@ 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 = {10, 0, 0, 1}; private static final byte[] MOCK_BROADCAST_IPV4_ADDR = {10, 0, (byte) 255, (byte) 255}; private static final byte[] MOCK_BROADCAST_IPV4_ADDR = {10, 0, 31, (byte) 255}; // prefix = 19 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}; Loading @@ -721,8 +722,12 @@ public class ApfTest extends AndroidTestCase { @LargeTest public void testApfFilterIPv4() throws Exception { MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19); LinkProperties lp = new LinkProperties(); lp.addLinkAddress(link); ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, mLog); apfFilter.setLinkProperties(lp); byte[] program = ipManagerCallback.getApfProgram(); Loading @@ -740,7 +745,7 @@ public class ApfTest extends AndroidTestCase { put(packet, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS); assertDrop(program, packet.array()); put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_BROADCAST_IPV4_ADDR); assertPass(program, packet.array()); assertDrop(program, packet.array()); // Verify multicast/broadcast IPv4, not DHCP to us, is dropped put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS); Loading Loading @@ -797,15 +802,21 @@ public class ApfTest extends AndroidTestCase { @LargeTest public void testApfFilterMulticast() throws Exception { MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); 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[] broadcastIpv4Addr = {(byte)192,0,2,(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}; MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); LinkAddress link = new LinkAddress(InetAddress.getByAddress(unicastIpv4Addr), 24); LinkProperties lp = new LinkProperties(); lp.addLinkAddress(link); ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog); apfFilter.setLinkProperties(lp); byte[] program = ipManagerCallback.getApfProgram(); // Construct IPv4 and IPv6 multicast packets. ByteBuffer mcastv4packet = ByteBuffer.wrap(new byte[100]); mcastv4packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); Loading Loading @@ -848,7 +859,7 @@ public class ApfTest extends AndroidTestCase { assertDrop(program, mcastv6packet.array()); assertDrop(program, bcastv4packet1.array()); assertDrop(program, bcastv4packet2.array()); assertPass(program, bcastv4unicastl2packet.array()); assertDrop(program, bcastv4unicastl2packet.array()); // Turn off multicast filter and verify it's off ipManagerCallback.resetApfProgramWait(); Loading @@ -864,11 +875,12 @@ public class ApfTest extends AndroidTestCase { ipManagerCallback.resetApfProgramWait(); apfFilter.shutdown(); apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, mLog); apfFilter.setLinkProperties(lp); program = ipManagerCallback.getApfProgram(); assertDrop(program, mcastv4packet.array()); assertDrop(program, mcastv6packet.array()); assertDrop(program, bcastv4packet1.array()); assertPass(program, bcastv4unicastl2packet.array()); assertDrop(program, bcastv4unicastl2packet.array()); // Verify that ICMPv6 multicast is not dropped. mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6); Loading Loading @@ -1154,4 +1166,30 @@ public class ApfTest extends AndroidTestCase { */ private native static boolean compareBpfApf(String filter, String pcap_filename, byte[] apf_program); public void testBytesToInt() { assertEquals(0x00000000, ApfFilter.bytesToInt(IPV4_ANY_HOST_ADDR)); assertEquals(0xffffffff, ApfFilter.bytesToInt(IPV4_BROADCAST_ADDRESS)); assertEquals(0x0a000001, ApfFilter.bytesToInt(MOCK_IPV4_ADDR)); assertEquals(0x0a000002, ApfFilter.bytesToInt(ANOTHER_IPV4_ADDR)); assertEquals(0x0a001fff, ApfFilter.bytesToInt(MOCK_BROADCAST_IPV4_ADDR)); assertEquals(0xe0000001, ApfFilter.bytesToInt(MOCK_MULTICAST_IPV4_ADDR)); } public void testBroadcastAddress() throws Exception { assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 0)); assertEqualsIp("0.0.0.0", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 32)); assertEqualsIp("0.0.3.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 22)); assertEqualsIp("0.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 8)); assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 0)); assertEqualsIp("10.0.0.1", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 32)); assertEqualsIp("10.0.0.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 24)); assertEqualsIp("10.0.255.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 16)); } public void assertEqualsIp(String expected, int got) throws Exception { int want = ApfFilter.bytesToInt(InetAddress.getByName(expected).getAddress()); assertEquals(want, got); } } Loading
services/net/java/android/net/apf/ApfFilter.java +63 −35 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.net.apf; import static android.system.OsConstants.*; import android.os.SystemClock; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.NetworkUtils; import android.net.apf.ApfGenerator; Loading @@ -44,6 +45,7 @@ import com.android.internal.util.IndentingPrintWriter; import java.io.FileDescriptor; import java.io.IOException; import java.lang.Thread; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.NetworkInterface; Loading Loading @@ -230,6 +232,9 @@ public class ApfFilter { // Our IPv4 address, if we have just one, otherwise null. @GuardedBy("this") private byte[] mIPv4Address; // The subnet prefix length of our IPv4 network. Only valid if mIPv4Address is not null. @GuardedBy("this") private int mIPv4PrefixLength; @VisibleForTesting ApfFilter(ApfCapabilities apfCapabilities, NetworkInterface networkInterface, Loading Loading @@ -365,26 +370,6 @@ public class ApfFilter { // Can't be static because it's in a non-static inner class. // TODO: Make this static once RA is its own class. private int uint8(byte b) { return b & 0xff; } private int uint16(short s) { return s & 0xffff; } private long uint32(int i) { return i & 0xffffffffL; } private long getUint16(ByteBuffer buffer, int position) { return uint16(buffer.getShort(position)); } private long getUint32(ByteBuffer buffer, int position) { return uint32(buffer.getInt(position)); } private void prefixOptionToString(StringBuffer sb, int offset) { String prefix = IPv6AddresstoString(offset + 16); int length = uint8(mPacket.get(offset + 2)); Loading Loading @@ -780,7 +765,10 @@ public class ApfFilter { // If IPv4 broadcast packet, drop regardless of L2 (b/30231088). gen.addLoad32(Register.R0, IPV4_DEST_ADDR_OFFSET); gen.addJumpIfR0Equals(IPV4_BROADCAST_ADDRESS, gen.DROP_LABEL); // TODO: also filter subnet broadcast address. if (mIPv4Address != null && mIPv4PrefixLength < 31) { int broadcastAddr = ipv4BroadcastAddress(mIPv4Address, mIPv4PrefixLength); gen.addJumpIfR0Equals(broadcastAddr, gen.DROP_LABEL); } // If L2 broadcast packet, drop. gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET); Loading Loading @@ -1078,26 +1066,32 @@ public class ApfFilter { } } // Find the single IPv4 address if there is one, otherwise return null. private static byte[] findIPv4Address(LinkProperties lp) { byte[] ipv4Address = null; for (InetAddress inetAddr : lp.getAddresses()) { byte[] addr = inetAddr.getAddress(); if (addr.length != 4) continue; // More than one IPv4 address, abort if (ipv4Address != null && !Arrays.equals(ipv4Address, addr)) return null; ipv4Address = addr; /** Find the single IPv4 LinkAddress if there is one, otherwise return null. */ private static LinkAddress findIPv4LinkAddress(LinkProperties lp) { LinkAddress ipv4Address = null; for (LinkAddress address : lp.getLinkAddresses()) { if (!(address.getAddress() instanceof Inet4Address)) { continue; } if (ipv4Address != null && !ipv4Address.isSameAddressAs(address)) { // More than one IPv4 address, abort. return null; } ipv4Address = address; } return ipv4Address; } public synchronized void setLinkProperties(LinkProperties lp) { // NOTE: Do not keep a copy of LinkProperties as it would further duplicate state. byte[] ipv4Address = findIPv4Address(lp); // If ipv4Address is the same as mIPv4Address, then there's no change, just return. if (Arrays.equals(ipv4Address, mIPv4Address)) return; // Otherwise update mIPv4Address and install new program. mIPv4Address = ipv4Address; final LinkAddress ipv4Address = findIPv4LinkAddress(lp); final byte[] addr = (ipv4Address != null) ? ipv4Address.getAddress().getAddress() : null; final int prefix = (ipv4Address != null) ? ipv4Address.getPrefixLength() : 0; if ((prefix == mIPv4PrefixLength) && Arrays.equals(addr, mIPv4Address)) { return; } mIPv4Address = addr; mIPv4PrefixLength = prefix; installNewProgramLocked(); } Loading Loading @@ -1143,4 +1137,38 @@ public class ApfFilter { pw.decreaseIndent(); } } private static int uint8(byte b) { return b & 0xff; } private static int uint16(short s) { return s & 0xffff; } private static long uint32(int i) { return i & 0xffffffffL; } private static long getUint16(ByteBuffer buffer, int position) { return uint16(buffer.getShort(position)); } private static long getUint32(ByteBuffer buffer, int position) { return uint32(buffer.getInt(position)); } // TODO: move to android.net.NetworkUtils @VisibleForTesting public static int ipv4BroadcastAddress(byte[] addrBytes, int prefixLength) { return bytesToInt(addrBytes) | (int) (uint32(-1) >>> prefixLength); } @VisibleForTesting public static int bytesToInt(byte[] addrBytes) { return (uint8(addrBytes[0]) << 24) + (uint8(addrBytes[1]) << 16) + (uint8(addrBytes[2]) << 8) + (uint8(addrBytes[3])); } }
services/tests/servicestests/src/android/net/apf/ApfTest.java +49 −11 Original line number Diff line number Diff line Loading @@ -20,6 +20,9 @@ import static android.system.OsConstants.*; import com.android.frameworks.servicestests.R; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.NetworkUtils; import android.net.apf.ApfCapabilities; import android.net.apf.ApfFilter; import android.net.apf.ApfGenerator; Loading @@ -28,8 +31,6 @@ import android.net.apf.ApfGenerator.Register; import android.net.ip.IpManager; import android.net.metrics.IpConnectivityLog; import android.net.metrics.RaEvent; import android.net.LinkAddress; import android.net.LinkProperties; import android.os.ConditionVariable; import android.os.Parcelable; import android.system.ErrnoException; Loading Loading @@ -713,7 +714,7 @@ 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 = {10, 0, 0, 1}; private static final byte[] MOCK_BROADCAST_IPV4_ADDR = {10, 0, (byte) 255, (byte) 255}; private static final byte[] MOCK_BROADCAST_IPV4_ADDR = {10, 0, 31, (byte) 255}; // prefix = 19 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}; Loading @@ -721,8 +722,12 @@ public class ApfTest extends AndroidTestCase { @LargeTest public void testApfFilterIPv4() throws Exception { MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19); LinkProperties lp = new LinkProperties(); lp.addLinkAddress(link); ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, mLog); apfFilter.setLinkProperties(lp); byte[] program = ipManagerCallback.getApfProgram(); Loading @@ -740,7 +745,7 @@ public class ApfTest extends AndroidTestCase { put(packet, IPV4_DEST_ADDR_OFFSET, IPV4_BROADCAST_ADDRESS); assertDrop(program, packet.array()); put(packet, IPV4_DEST_ADDR_OFFSET, MOCK_BROADCAST_IPV4_ADDR); assertPass(program, packet.array()); assertDrop(program, packet.array()); // Verify multicast/broadcast IPv4, not DHCP to us, is dropped put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS); Loading Loading @@ -797,15 +802,21 @@ public class ApfTest extends AndroidTestCase { @LargeTest public void testApfFilterMulticast() throws Exception { MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); 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[] broadcastIpv4Addr = {(byte)192,0,2,(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}; MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); LinkAddress link = new LinkAddress(InetAddress.getByAddress(unicastIpv4Addr), 24); LinkProperties lp = new LinkProperties(); lp.addLinkAddress(link); ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog); apfFilter.setLinkProperties(lp); byte[] program = ipManagerCallback.getApfProgram(); // Construct IPv4 and IPv6 multicast packets. ByteBuffer mcastv4packet = ByteBuffer.wrap(new byte[100]); mcastv4packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_IP); Loading Loading @@ -848,7 +859,7 @@ public class ApfTest extends AndroidTestCase { assertDrop(program, mcastv6packet.array()); assertDrop(program, bcastv4packet1.array()); assertDrop(program, bcastv4packet2.array()); assertPass(program, bcastv4unicastl2packet.array()); assertDrop(program, bcastv4unicastl2packet.array()); // Turn off multicast filter and verify it's off ipManagerCallback.resetApfProgramWait(); Loading @@ -864,11 +875,12 @@ public class ApfTest extends AndroidTestCase { ipManagerCallback.resetApfProgramWait(); apfFilter.shutdown(); apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, mLog); apfFilter.setLinkProperties(lp); program = ipManagerCallback.getApfProgram(); assertDrop(program, mcastv4packet.array()); assertDrop(program, mcastv6packet.array()); assertDrop(program, bcastv4packet1.array()); assertPass(program, bcastv4unicastl2packet.array()); assertDrop(program, bcastv4unicastl2packet.array()); // Verify that ICMPv6 multicast is not dropped. mcastv6packet.put(IPV6_NEXT_HEADER_OFFSET, (byte)IPPROTO_ICMPV6); Loading Loading @@ -1154,4 +1166,30 @@ public class ApfTest extends AndroidTestCase { */ private native static boolean compareBpfApf(String filter, String pcap_filename, byte[] apf_program); public void testBytesToInt() { assertEquals(0x00000000, ApfFilter.bytesToInt(IPV4_ANY_HOST_ADDR)); assertEquals(0xffffffff, ApfFilter.bytesToInt(IPV4_BROADCAST_ADDRESS)); assertEquals(0x0a000001, ApfFilter.bytesToInt(MOCK_IPV4_ADDR)); assertEquals(0x0a000002, ApfFilter.bytesToInt(ANOTHER_IPV4_ADDR)); assertEquals(0x0a001fff, ApfFilter.bytesToInt(MOCK_BROADCAST_IPV4_ADDR)); assertEquals(0xe0000001, ApfFilter.bytesToInt(MOCK_MULTICAST_IPV4_ADDR)); } public void testBroadcastAddress() throws Exception { assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 0)); assertEqualsIp("0.0.0.0", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 32)); assertEqualsIp("0.0.3.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 22)); assertEqualsIp("0.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 8)); assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 0)); assertEqualsIp("10.0.0.1", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 32)); assertEqualsIp("10.0.0.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 24)); assertEqualsIp("10.0.255.255", ApfFilter.ipv4BroadcastAddress(MOCK_IPV4_ADDR, 16)); } public void assertEqualsIp(String expected, int got) throws Exception { int want = ApfFilter.bytesToInt(InetAddress.getByName(expected).getAddress()); assertEquals(want, got); } }