Loading src/com/android/networkstack/packets/NeighborAdvertisement.java +12 −7 Original line number Original line Diff line number Diff line Loading @@ -17,13 +17,14 @@ package com.android.networkstack.packets; package com.android.networkstack.packets; import static com.android.net.module.util.NetworkStackConstants.ETHER_HEADER_LEN; import static com.android.net.module.util.NetworkStackConstants.ETHER_HEADER_LEN; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_HEADER_MIN_LEN; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_NA_HEADER_LEN; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_TLLA; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_TLLA; import static com.android.net.module.util.NetworkStackConstants.IPV6_HEADER_LEN; import static com.android.net.module.util.NetworkStackConstants.IPV6_HEADER_LEN; import android.net.MacAddress; import android.net.MacAddress; import androidx.annotation.NonNull; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.net.module.util.Ipv6Utils; import com.android.net.module.util.Ipv6Utils; import com.android.net.module.util.Struct; import com.android.net.module.util.Struct; Loading @@ -50,12 +51,12 @@ public class NeighborAdvertisement { public final Icmpv6Header icmpv6Hdr; public final Icmpv6Header icmpv6Hdr; @NonNull @NonNull public final NaHeader naHdr; public final NaHeader naHdr; @NonNull @Nullable public final LlaOption tlla; public final LlaOption tlla; public NeighborAdvertisement(@NonNull final EthernetHeader ethHdr, public NeighborAdvertisement(@NonNull final EthernetHeader ethHdr, @NonNull final Ipv6Header ipv6Hdr, @NonNull final Icmpv6Header icmpv6Hdr, @NonNull final Ipv6Header ipv6Hdr, @NonNull final Icmpv6Header icmpv6Hdr, @NonNull final NaHeader naHdr, @NonNull final LlaOption tlla) { @NonNull final NaHeader naHdr, @Nullable final LlaOption tlla) { this.ethHdr = ethHdr; this.ethHdr = ethHdr; this.ipv6Hdr = ipv6Hdr; this.ipv6Hdr = ipv6Hdr; this.icmpv6Hdr = icmpv6Hdr; this.icmpv6Hdr = icmpv6Hdr; Loading @@ -71,7 +72,7 @@ public class NeighborAdvertisement { final int ipv6HeaderLen = Struct.getSize(Ipv6Header.class); final int ipv6HeaderLen = Struct.getSize(Ipv6Header.class); final int icmpv6HeaderLen = Struct.getSize(Icmpv6Header.class); final int icmpv6HeaderLen = Struct.getSize(Icmpv6Header.class); final int naHeaderLen = Struct.getSize(NaHeader.class); final int naHeaderLen = Struct.getSize(NaHeader.class); final int tllaOptionLen = Struct.getSize(LlaOption.class); final int tllaOptionLen = (tlla == null) ? 0 : Struct.getSize(LlaOption.class); final ByteBuffer packet = ByteBuffer.allocate(etherHeaderLen + ipv6HeaderLen final ByteBuffer packet = ByteBuffer.allocate(etherHeaderLen + ipv6HeaderLen + icmpv6HeaderLen + naHeaderLen + tllaOptionLen); + icmpv6HeaderLen + naHeaderLen + tllaOptionLen); Loading @@ -79,7 +80,9 @@ public class NeighborAdvertisement { ipv6Hdr.writeToByteBuffer(packet); ipv6Hdr.writeToByteBuffer(packet); icmpv6Hdr.writeToByteBuffer(packet); icmpv6Hdr.writeToByteBuffer(packet); naHdr.writeToByteBuffer(packet); naHdr.writeToByteBuffer(packet); if (tlla != null) { tlla.writeToByteBuffer(packet); tlla.writeToByteBuffer(packet); } packet.flip(); packet.flip(); return packet; return packet; Loading @@ -100,7 +103,7 @@ public class NeighborAdvertisement { */ */ public static NeighborAdvertisement parse(@NonNull final byte[] recvbuf, final int length) public static NeighborAdvertisement parse(@NonNull final byte[] recvbuf, final int length) throws ParseException { throws ParseException { if (length < ETHER_HEADER_LEN + IPV6_HEADER_LEN + ICMPV6_HEADER_MIN_LEN if (length < ETHER_HEADER_LEN + IPV6_HEADER_LEN + ICMPV6_NA_HEADER_LEN || recvbuf.length < length) { || recvbuf.length < length) { throw new ParseException("Invalid packet length: " + length); throw new ParseException("Invalid packet length: " + length); } } Loading @@ -111,7 +114,9 @@ public class NeighborAdvertisement { final Ipv6Header ipv6Hdr = Struct.parse(Ipv6Header.class, packet); final Ipv6Header ipv6Hdr = Struct.parse(Ipv6Header.class, packet); final Icmpv6Header icmpv6Hdr = Struct.parse(Icmpv6Header.class, packet); final Icmpv6Header icmpv6Hdr = Struct.parse(Icmpv6Header.class, packet); final NaHeader naHdr = Struct.parse(NaHeader.class, packet); final NaHeader naHdr = Struct.parse(NaHeader.class, packet); final LlaOption tlla = Struct.parse(LlaOption.class, packet); final LlaOption tlla = (packet.remaining() == 0) ? null : Struct.parse(LlaOption.class, packet); return new NeighborAdvertisement(ethHdr, ipv6Hdr, icmpv6Hdr, naHdr, tlla); return new NeighborAdvertisement(ethHdr, ipv6Hdr, icmpv6Hdr, naHdr, tlla); } } Loading src/com/android/networkstack/packets/NeighborSolicitation.java +2 −4 Original line number Original line Diff line number Diff line Loading @@ -17,8 +17,8 @@ package com.android.networkstack.packets; package com.android.networkstack.packets; import static com.android.net.module.util.NetworkStackConstants.ETHER_HEADER_LEN; import static com.android.net.module.util.NetworkStackConstants.ETHER_HEADER_LEN; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_HEADER_MIN_LEN; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_SLLA; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_SLLA; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_NS_HEADER_LEN; import static com.android.net.module.util.NetworkStackConstants.IPV6_HEADER_LEN; import static com.android.net.module.util.NetworkStackConstants.IPV6_HEADER_LEN; import android.net.MacAddress; import android.net.MacAddress; Loading @@ -43,8 +43,6 @@ import java.nio.ByteBuffer; * @hide * @hide */ */ public class NeighborSolicitation { public class NeighborSolicitation { private static final int NS_HEADER_LEN = Struct.getSize(NsHeader.class); @NonNull @NonNull public final EthernetHeader ethHdr; public final EthernetHeader ethHdr; @NonNull @NonNull Loading Loading @@ -105,7 +103,7 @@ public class NeighborSolicitation { */ */ public static NeighborSolicitation parse(@NonNull final byte[] recvbuf, final int length) public static NeighborSolicitation parse(@NonNull final byte[] recvbuf, final int length) throws ParseException { throws ParseException { if (length < ETHER_HEADER_LEN + IPV6_HEADER_LEN + ICMPV6_HEADER_MIN_LEN + NS_HEADER_LEN if (length < ETHER_HEADER_LEN + IPV6_HEADER_LEN + ICMPV6_NS_HEADER_LEN || recvbuf.length < length) { || recvbuf.length < length) { throw new ParseException("Invalid packet length: " + length); throw new ParseException("Invalid packet length: " + length); } } Loading tests/unit/src/com/android/networkstack/packets/NeighborAdvertisementTest.java +73 −10 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.networkstack.packets; import static android.system.OsConstants.ETH_P_IPV6; import static android.system.OsConstants.ETH_P_IPV6; import static android.system.OsConstants.IPPROTO_ICMPV6; import static android.system.OsConstants.IPPROTO_ICMPV6; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_TLLA; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT; import static com.android.net.module.util.NetworkStackConstants.IPV6_ADDR_ALL_ROUTERS_MULTICAST; import static com.android.net.module.util.NetworkStackConstants.IPV6_ADDR_ALL_ROUTERS_MULTICAST; import static com.android.testutils.MiscAsserts.assertThrows; import static com.android.testutils.MiscAsserts.assertThrows; Loading Loading @@ -90,6 +91,41 @@ public final class NeighborAdvertisementTest { // Link-Layer address // Link-Layer address (byte) 0xea, (byte) 0xbe, (byte) 0x11, (byte) 0x25, (byte) 0xc1, (byte) 0x25, (byte) 0xea, (byte) 0xbe, (byte) 0x11, (byte) 0x25, (byte) 0xc1, (byte) 0x25, }; }; private static final byte[] TEST_GRATUITOUS_NA_WITHOUT_TLLA = new byte[] { // dst mac address (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, // src mac address (byte) 0xea, (byte) 0xbe, (byte) 0x11, (byte) 0x25, (byte) 0xc1, (byte) 0x25, // ether type (byte) 0x86, (byte) 0xdd, // version, priority and flow label (byte) 0x60, (byte) 0x00, (byte) 0x00, (byte) 0x00, // length (byte) 0x00, (byte) 0x20, // next header (byte) 0x3a, // hop limit (byte) 0xff, // source address (byte) 0xfe, (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xdf, (byte) 0xd9, (byte) 0x50, (byte) 0xa0, (byte) 0xcc, (byte) 0x7b, (byte) 0x7d, (byte) 0x6d, // destination address (byte) 0xff, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, // ICMP type, code, checksum (byte) 0x88, (byte) 0x00, (byte) 0x3a, (byte) 0x3c, // flags (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // target address (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0xc9, (byte) 0x28, (byte) 0x25, (byte) 0x0d, (byte) 0xb9, (byte) 0x0c, (byte) 0x31, (byte) 0x78, }; private static final byte[] TEST_GRATUITOUS_NA_LESS_LENGTH = new byte[] { private static final byte[] TEST_GRATUITOUS_NA_LESS_LENGTH = new byte[] { // dst mac address // dst mac address (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, Loading @@ -115,6 +151,10 @@ public final class NeighborAdvertisementTest { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, // ICMP type, code, checksum (byte) 0x88, (byte) 0x00, (byte) 0x3a, (byte) 0x3c, // flags (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, }; }; private static final byte[] TEST_GRATUITOUS_NA_TRUNCATED = new byte[] { private static final byte[] TEST_GRATUITOUS_NA_TRUNCATED = new byte[] { // dst mac address // dst mac address Loading Loading @@ -152,7 +192,7 @@ public final class NeighborAdvertisementTest { (byte) 0xb9, (byte) 0x0c, (byte) 0x31, (byte) 0x78, (byte) 0xb9, (byte) 0x0c, (byte) 0x31, (byte) 0x78, // TLLA option // TLLA option (byte) 0x02, (byte) 0x01, (byte) 0x02, (byte) 0x01, // Link-Layer address // truncatd Link-Layer address: 4bytes (byte) 0xea, (byte) 0xbe, (byte) 0x11, (byte) 0x25, (byte) 0xea, (byte) 0xbe, (byte) 0x11, (byte) 0x25, }; }; Loading @@ -165,11 +205,8 @@ public final class NeighborAdvertisementTest { assertArrayEquals(na.array(), TEST_GRATUITOUS_NA); assertArrayEquals(na.array(), TEST_GRATUITOUS_NA); } } @Test private void assertNeighborAdvertisement(final NeighborAdvertisement na, public void testGratuitousNa_parse() throws Exception { boolean hasTllaOption) { final NeighborAdvertisement na = NeighborAdvertisement.parse(TEST_GRATUITOUS_NA, TEST_GRATUITOUS_NA.length); assertArrayEquals(TEST_SOURCE_MAC_ADDR, na.ethHdr.srcMac.toByteArray()); assertArrayEquals(TEST_SOURCE_MAC_ADDR, na.ethHdr.srcMac.toByteArray()); assertArrayEquals(TEST_DST_MAC_ADDR, na.ethHdr.dstMac.toByteArray()); assertArrayEquals(TEST_DST_MAC_ADDR, na.ethHdr.dstMac.toByteArray()); assertEquals(ETH_P_IPV6, na.ethHdr.etherType); assertEquals(ETH_P_IPV6, na.ethHdr.etherType); Loading @@ -181,19 +218,45 @@ public final class NeighborAdvertisementTest { assertEquals(0, na.icmpv6Hdr.code); assertEquals(0, na.icmpv6Hdr.code); assertEquals(0, na.naHdr.flags); assertEquals(0, na.naHdr.flags); assertEquals(TEST_TARGET_ADDR, na.naHdr.target); assertEquals(TEST_TARGET_ADDR, na.naHdr.target); assertEquals(2, na.tlla.type); if (hasTllaOption) { assertEquals(ICMPV6_ND_OPTION_TLLA, na.tlla.type); assertEquals(1, na.tlla.length); assertEquals(1, na.tlla.length); assertArrayEquals(TEST_SOURCE_MAC_ADDR, na.tlla.linkLayerAddress.toByteArray()); assertArrayEquals(TEST_SOURCE_MAC_ADDR, na.tlla.linkLayerAddress.toByteArray()); } } @Test public void testGratuitousNa_parse() throws Exception { final NeighborAdvertisement na = NeighborAdvertisement.parse(TEST_GRATUITOUS_NA, TEST_GRATUITOUS_NA.length); assertNeighborAdvertisement(na, true /* hasTllaOption */); assertArrayEquals(TEST_GRATUITOUS_NA, na.toByteBuffer().array()); assertArrayEquals(TEST_GRATUITOUS_NA, na.toByteBuffer().array()); } } @Test @Test public void testGratuitousNa_invalidByteBufferParameters() throws Exception { public void testGratuitousNa_parseWithoutTllaOption() throws Exception { final NeighborAdvertisement na = NeighborAdvertisement.parse(TEST_GRATUITOUS_NA_WITHOUT_TLLA, TEST_GRATUITOUS_NA_WITHOUT_TLLA.length); assertNeighborAdvertisement(na, false /* hasTllaOption */); assertArrayEquals(TEST_GRATUITOUS_NA_WITHOUT_TLLA, na.toByteBuffer().array()); } @Test public void testGratuitousNa_zeroPacketLength() throws Exception { assertThrows(NeighborAdvertisement.ParseException.class, assertThrows(NeighborAdvertisement.ParseException.class, () -> NeighborAdvertisement.parse(TEST_GRATUITOUS_NA, 0)); () -> NeighborAdvertisement.parse(TEST_GRATUITOUS_NA, 0)); } } @Test public void testGratuitousNa_invalidByteBufferLength() throws Exception { assertThrows(NeighborAdvertisement.ParseException.class, () -> NeighborAdvertisement.parse(TEST_GRATUITOUS_NA_TRUNCATED, TEST_GRATUITOUS_NA.length)); } @Test @Test public void testGratuitousNa_lessPacketLength() throws Exception { public void testGratuitousNa_lessPacketLength() throws Exception { assertThrows(NeighborAdvertisement.ParseException.class, assertThrows(NeighborAdvertisement.ParseException.class, Loading tests/unit/src/com/android/networkstack/packets/NeighborSolicitationTest.java +4 −1 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.networkstack.packets; import static android.system.OsConstants.ETH_P_IPV6; import static android.system.OsConstants.ETH_P_IPV6; import static android.system.OsConstants.IPPROTO_ICMPV6; import static android.system.OsConstants.IPPROTO_ICMPV6; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_SLLA; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_NEIGHBOR_SOLICITATION; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_NEIGHBOR_SOLICITATION; import static com.android.testutils.MiscAsserts.assertThrows; import static com.android.testutils.MiscAsserts.assertThrows; Loading Loading @@ -193,7 +194,7 @@ public final class NeighborSolicitationTest { (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, // slla option // slla option (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, // link-layer address // truncatd link-layer address: 4bytes (byte) 0x06, (byte) 0x5a, (byte) 0xac, (byte) 0x02, (byte) 0x06, (byte) 0x5a, (byte) 0xac, (byte) 0x02, }; }; Loading @@ -218,6 +219,8 @@ public final class NeighborSolicitationTest { assertEquals(0, ns.icmpv6Hdr.code); assertEquals(0, ns.icmpv6Hdr.code); assertEquals(TEST_TARGET_ADDR, ns.nsHdr.target); assertEquals(TEST_TARGET_ADDR, ns.nsHdr.target); if (hasSllaOption) { if (hasSllaOption) { assertEquals(ICMPV6_ND_OPTION_SLLA, ns.slla.type); assertEquals(1, ns.slla.length); assertEquals(MacAddress.fromBytes(TEST_SOURCE_MAC_ADDR), ns.slla.linkLayerAddress); assertEquals(MacAddress.fromBytes(TEST_SOURCE_MAC_ADDR), ns.slla.linkLayerAddress); } } } } Loading Loading
src/com/android/networkstack/packets/NeighborAdvertisement.java +12 −7 Original line number Original line Diff line number Diff line Loading @@ -17,13 +17,14 @@ package com.android.networkstack.packets; package com.android.networkstack.packets; import static com.android.net.module.util.NetworkStackConstants.ETHER_HEADER_LEN; import static com.android.net.module.util.NetworkStackConstants.ETHER_HEADER_LEN; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_HEADER_MIN_LEN; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_NA_HEADER_LEN; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_TLLA; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_TLLA; import static com.android.net.module.util.NetworkStackConstants.IPV6_HEADER_LEN; import static com.android.net.module.util.NetworkStackConstants.IPV6_HEADER_LEN; import android.net.MacAddress; import android.net.MacAddress; import androidx.annotation.NonNull; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.net.module.util.Ipv6Utils; import com.android.net.module.util.Ipv6Utils; import com.android.net.module.util.Struct; import com.android.net.module.util.Struct; Loading @@ -50,12 +51,12 @@ public class NeighborAdvertisement { public final Icmpv6Header icmpv6Hdr; public final Icmpv6Header icmpv6Hdr; @NonNull @NonNull public final NaHeader naHdr; public final NaHeader naHdr; @NonNull @Nullable public final LlaOption tlla; public final LlaOption tlla; public NeighborAdvertisement(@NonNull final EthernetHeader ethHdr, public NeighborAdvertisement(@NonNull final EthernetHeader ethHdr, @NonNull final Ipv6Header ipv6Hdr, @NonNull final Icmpv6Header icmpv6Hdr, @NonNull final Ipv6Header ipv6Hdr, @NonNull final Icmpv6Header icmpv6Hdr, @NonNull final NaHeader naHdr, @NonNull final LlaOption tlla) { @NonNull final NaHeader naHdr, @Nullable final LlaOption tlla) { this.ethHdr = ethHdr; this.ethHdr = ethHdr; this.ipv6Hdr = ipv6Hdr; this.ipv6Hdr = ipv6Hdr; this.icmpv6Hdr = icmpv6Hdr; this.icmpv6Hdr = icmpv6Hdr; Loading @@ -71,7 +72,7 @@ public class NeighborAdvertisement { final int ipv6HeaderLen = Struct.getSize(Ipv6Header.class); final int ipv6HeaderLen = Struct.getSize(Ipv6Header.class); final int icmpv6HeaderLen = Struct.getSize(Icmpv6Header.class); final int icmpv6HeaderLen = Struct.getSize(Icmpv6Header.class); final int naHeaderLen = Struct.getSize(NaHeader.class); final int naHeaderLen = Struct.getSize(NaHeader.class); final int tllaOptionLen = Struct.getSize(LlaOption.class); final int tllaOptionLen = (tlla == null) ? 0 : Struct.getSize(LlaOption.class); final ByteBuffer packet = ByteBuffer.allocate(etherHeaderLen + ipv6HeaderLen final ByteBuffer packet = ByteBuffer.allocate(etherHeaderLen + ipv6HeaderLen + icmpv6HeaderLen + naHeaderLen + tllaOptionLen); + icmpv6HeaderLen + naHeaderLen + tllaOptionLen); Loading @@ -79,7 +80,9 @@ public class NeighborAdvertisement { ipv6Hdr.writeToByteBuffer(packet); ipv6Hdr.writeToByteBuffer(packet); icmpv6Hdr.writeToByteBuffer(packet); icmpv6Hdr.writeToByteBuffer(packet); naHdr.writeToByteBuffer(packet); naHdr.writeToByteBuffer(packet); if (tlla != null) { tlla.writeToByteBuffer(packet); tlla.writeToByteBuffer(packet); } packet.flip(); packet.flip(); return packet; return packet; Loading @@ -100,7 +103,7 @@ public class NeighborAdvertisement { */ */ public static NeighborAdvertisement parse(@NonNull final byte[] recvbuf, final int length) public static NeighborAdvertisement parse(@NonNull final byte[] recvbuf, final int length) throws ParseException { throws ParseException { if (length < ETHER_HEADER_LEN + IPV6_HEADER_LEN + ICMPV6_HEADER_MIN_LEN if (length < ETHER_HEADER_LEN + IPV6_HEADER_LEN + ICMPV6_NA_HEADER_LEN || recvbuf.length < length) { || recvbuf.length < length) { throw new ParseException("Invalid packet length: " + length); throw new ParseException("Invalid packet length: " + length); } } Loading @@ -111,7 +114,9 @@ public class NeighborAdvertisement { final Ipv6Header ipv6Hdr = Struct.parse(Ipv6Header.class, packet); final Ipv6Header ipv6Hdr = Struct.parse(Ipv6Header.class, packet); final Icmpv6Header icmpv6Hdr = Struct.parse(Icmpv6Header.class, packet); final Icmpv6Header icmpv6Hdr = Struct.parse(Icmpv6Header.class, packet); final NaHeader naHdr = Struct.parse(NaHeader.class, packet); final NaHeader naHdr = Struct.parse(NaHeader.class, packet); final LlaOption tlla = Struct.parse(LlaOption.class, packet); final LlaOption tlla = (packet.remaining() == 0) ? null : Struct.parse(LlaOption.class, packet); return new NeighborAdvertisement(ethHdr, ipv6Hdr, icmpv6Hdr, naHdr, tlla); return new NeighborAdvertisement(ethHdr, ipv6Hdr, icmpv6Hdr, naHdr, tlla); } } Loading
src/com/android/networkstack/packets/NeighborSolicitation.java +2 −4 Original line number Original line Diff line number Diff line Loading @@ -17,8 +17,8 @@ package com.android.networkstack.packets; package com.android.networkstack.packets; import static com.android.net.module.util.NetworkStackConstants.ETHER_HEADER_LEN; import static com.android.net.module.util.NetworkStackConstants.ETHER_HEADER_LEN; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_HEADER_MIN_LEN; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_SLLA; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_SLLA; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_NS_HEADER_LEN; import static com.android.net.module.util.NetworkStackConstants.IPV6_HEADER_LEN; import static com.android.net.module.util.NetworkStackConstants.IPV6_HEADER_LEN; import android.net.MacAddress; import android.net.MacAddress; Loading @@ -43,8 +43,6 @@ import java.nio.ByteBuffer; * @hide * @hide */ */ public class NeighborSolicitation { public class NeighborSolicitation { private static final int NS_HEADER_LEN = Struct.getSize(NsHeader.class); @NonNull @NonNull public final EthernetHeader ethHdr; public final EthernetHeader ethHdr; @NonNull @NonNull Loading Loading @@ -105,7 +103,7 @@ public class NeighborSolicitation { */ */ public static NeighborSolicitation parse(@NonNull final byte[] recvbuf, final int length) public static NeighborSolicitation parse(@NonNull final byte[] recvbuf, final int length) throws ParseException { throws ParseException { if (length < ETHER_HEADER_LEN + IPV6_HEADER_LEN + ICMPV6_HEADER_MIN_LEN + NS_HEADER_LEN if (length < ETHER_HEADER_LEN + IPV6_HEADER_LEN + ICMPV6_NS_HEADER_LEN || recvbuf.length < length) { || recvbuf.length < length) { throw new ParseException("Invalid packet length: " + length); throw new ParseException("Invalid packet length: " + length); } } Loading
tests/unit/src/com/android/networkstack/packets/NeighborAdvertisementTest.java +73 −10 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.networkstack.packets; import static android.system.OsConstants.ETH_P_IPV6; import static android.system.OsConstants.ETH_P_IPV6; import static android.system.OsConstants.IPPROTO_ICMPV6; import static android.system.OsConstants.IPPROTO_ICMPV6; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_TLLA; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT; import static com.android.net.module.util.NetworkStackConstants.IPV6_ADDR_ALL_ROUTERS_MULTICAST; import static com.android.net.module.util.NetworkStackConstants.IPV6_ADDR_ALL_ROUTERS_MULTICAST; import static com.android.testutils.MiscAsserts.assertThrows; import static com.android.testutils.MiscAsserts.assertThrows; Loading Loading @@ -90,6 +91,41 @@ public final class NeighborAdvertisementTest { // Link-Layer address // Link-Layer address (byte) 0xea, (byte) 0xbe, (byte) 0x11, (byte) 0x25, (byte) 0xc1, (byte) 0x25, (byte) 0xea, (byte) 0xbe, (byte) 0x11, (byte) 0x25, (byte) 0xc1, (byte) 0x25, }; }; private static final byte[] TEST_GRATUITOUS_NA_WITHOUT_TLLA = new byte[] { // dst mac address (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, // src mac address (byte) 0xea, (byte) 0xbe, (byte) 0x11, (byte) 0x25, (byte) 0xc1, (byte) 0x25, // ether type (byte) 0x86, (byte) 0xdd, // version, priority and flow label (byte) 0x60, (byte) 0x00, (byte) 0x00, (byte) 0x00, // length (byte) 0x00, (byte) 0x20, // next header (byte) 0x3a, // hop limit (byte) 0xff, // source address (byte) 0xfe, (byte) 0x80, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xdf, (byte) 0xd9, (byte) 0x50, (byte) 0xa0, (byte) 0xcc, (byte) 0x7b, (byte) 0x7d, (byte) 0x6d, // destination address (byte) 0xff, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, // ICMP type, code, checksum (byte) 0x88, (byte) 0x00, (byte) 0x3a, (byte) 0x3c, // flags (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, // target address (byte) 0x20, (byte) 0x01, (byte) 0x0d, (byte) 0xb8, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0xc9, (byte) 0x28, (byte) 0x25, (byte) 0x0d, (byte) 0xb9, (byte) 0x0c, (byte) 0x31, (byte) 0x78, }; private static final byte[] TEST_GRATUITOUS_NA_LESS_LENGTH = new byte[] { private static final byte[] TEST_GRATUITOUS_NA_LESS_LENGTH = new byte[] { // dst mac address // dst mac address (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, Loading @@ -115,6 +151,10 @@ public final class NeighborAdvertisementTest { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, // ICMP type, code, checksum (byte) 0x88, (byte) 0x00, (byte) 0x3a, (byte) 0x3c, // flags (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, }; }; private static final byte[] TEST_GRATUITOUS_NA_TRUNCATED = new byte[] { private static final byte[] TEST_GRATUITOUS_NA_TRUNCATED = new byte[] { // dst mac address // dst mac address Loading Loading @@ -152,7 +192,7 @@ public final class NeighborAdvertisementTest { (byte) 0xb9, (byte) 0x0c, (byte) 0x31, (byte) 0x78, (byte) 0xb9, (byte) 0x0c, (byte) 0x31, (byte) 0x78, // TLLA option // TLLA option (byte) 0x02, (byte) 0x01, (byte) 0x02, (byte) 0x01, // Link-Layer address // truncatd Link-Layer address: 4bytes (byte) 0xea, (byte) 0xbe, (byte) 0x11, (byte) 0x25, (byte) 0xea, (byte) 0xbe, (byte) 0x11, (byte) 0x25, }; }; Loading @@ -165,11 +205,8 @@ public final class NeighborAdvertisementTest { assertArrayEquals(na.array(), TEST_GRATUITOUS_NA); assertArrayEquals(na.array(), TEST_GRATUITOUS_NA); } } @Test private void assertNeighborAdvertisement(final NeighborAdvertisement na, public void testGratuitousNa_parse() throws Exception { boolean hasTllaOption) { final NeighborAdvertisement na = NeighborAdvertisement.parse(TEST_GRATUITOUS_NA, TEST_GRATUITOUS_NA.length); assertArrayEquals(TEST_SOURCE_MAC_ADDR, na.ethHdr.srcMac.toByteArray()); assertArrayEquals(TEST_SOURCE_MAC_ADDR, na.ethHdr.srcMac.toByteArray()); assertArrayEquals(TEST_DST_MAC_ADDR, na.ethHdr.dstMac.toByteArray()); assertArrayEquals(TEST_DST_MAC_ADDR, na.ethHdr.dstMac.toByteArray()); assertEquals(ETH_P_IPV6, na.ethHdr.etherType); assertEquals(ETH_P_IPV6, na.ethHdr.etherType); Loading @@ -181,19 +218,45 @@ public final class NeighborAdvertisementTest { assertEquals(0, na.icmpv6Hdr.code); assertEquals(0, na.icmpv6Hdr.code); assertEquals(0, na.naHdr.flags); assertEquals(0, na.naHdr.flags); assertEquals(TEST_TARGET_ADDR, na.naHdr.target); assertEquals(TEST_TARGET_ADDR, na.naHdr.target); assertEquals(2, na.tlla.type); if (hasTllaOption) { assertEquals(ICMPV6_ND_OPTION_TLLA, na.tlla.type); assertEquals(1, na.tlla.length); assertEquals(1, na.tlla.length); assertArrayEquals(TEST_SOURCE_MAC_ADDR, na.tlla.linkLayerAddress.toByteArray()); assertArrayEquals(TEST_SOURCE_MAC_ADDR, na.tlla.linkLayerAddress.toByteArray()); } } @Test public void testGratuitousNa_parse() throws Exception { final NeighborAdvertisement na = NeighborAdvertisement.parse(TEST_GRATUITOUS_NA, TEST_GRATUITOUS_NA.length); assertNeighborAdvertisement(na, true /* hasTllaOption */); assertArrayEquals(TEST_GRATUITOUS_NA, na.toByteBuffer().array()); assertArrayEquals(TEST_GRATUITOUS_NA, na.toByteBuffer().array()); } } @Test @Test public void testGratuitousNa_invalidByteBufferParameters() throws Exception { public void testGratuitousNa_parseWithoutTllaOption() throws Exception { final NeighborAdvertisement na = NeighborAdvertisement.parse(TEST_GRATUITOUS_NA_WITHOUT_TLLA, TEST_GRATUITOUS_NA_WITHOUT_TLLA.length); assertNeighborAdvertisement(na, false /* hasTllaOption */); assertArrayEquals(TEST_GRATUITOUS_NA_WITHOUT_TLLA, na.toByteBuffer().array()); } @Test public void testGratuitousNa_zeroPacketLength() throws Exception { assertThrows(NeighborAdvertisement.ParseException.class, assertThrows(NeighborAdvertisement.ParseException.class, () -> NeighborAdvertisement.parse(TEST_GRATUITOUS_NA, 0)); () -> NeighborAdvertisement.parse(TEST_GRATUITOUS_NA, 0)); } } @Test public void testGratuitousNa_invalidByteBufferLength() throws Exception { assertThrows(NeighborAdvertisement.ParseException.class, () -> NeighborAdvertisement.parse(TEST_GRATUITOUS_NA_TRUNCATED, TEST_GRATUITOUS_NA.length)); } @Test @Test public void testGratuitousNa_lessPacketLength() throws Exception { public void testGratuitousNa_lessPacketLength() throws Exception { assertThrows(NeighborAdvertisement.ParseException.class, assertThrows(NeighborAdvertisement.ParseException.class, Loading
tests/unit/src/com/android/networkstack/packets/NeighborSolicitationTest.java +4 −1 Original line number Original line Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.networkstack.packets; import static android.system.OsConstants.ETH_P_IPV6; import static android.system.OsConstants.ETH_P_IPV6; import static android.system.OsConstants.IPPROTO_ICMPV6; import static android.system.OsConstants.IPPROTO_ICMPV6; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ND_OPTION_SLLA; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_NEIGHBOR_SOLICITATION; import static com.android.net.module.util.NetworkStackConstants.ICMPV6_NEIGHBOR_SOLICITATION; import static com.android.testutils.MiscAsserts.assertThrows; import static com.android.testutils.MiscAsserts.assertThrows; Loading Loading @@ -193,7 +194,7 @@ public final class NeighborSolicitationTest { (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, // slla option // slla option (byte) 0x01, (byte) 0x01, (byte) 0x01, (byte) 0x01, // link-layer address // truncatd link-layer address: 4bytes (byte) 0x06, (byte) 0x5a, (byte) 0xac, (byte) 0x02, (byte) 0x06, (byte) 0x5a, (byte) 0xac, (byte) 0x02, }; }; Loading @@ -218,6 +219,8 @@ public final class NeighborSolicitationTest { assertEquals(0, ns.icmpv6Hdr.code); assertEquals(0, ns.icmpv6Hdr.code); assertEquals(TEST_TARGET_ADDR, ns.nsHdr.target); assertEquals(TEST_TARGET_ADDR, ns.nsHdr.target); if (hasSllaOption) { if (hasSllaOption) { assertEquals(ICMPV6_ND_OPTION_SLLA, ns.slla.type); assertEquals(1, ns.slla.length); assertEquals(MacAddress.fromBytes(TEST_SOURCE_MAC_ADDR), ns.slla.linkLayerAddress); assertEquals(MacAddress.fromBytes(TEST_SOURCE_MAC_ADDR), ns.slla.linkLayerAddress); } } } } Loading