summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/netlinkclient/src/android/net/netlink/NdOption.java7
-rw-r--r--common/netlinkclient/src/android/net/netlink/StructNdOptPref64.java31
-rw-r--r--tests/unit/src/android/net/netlink/StructNdOptPref64Test.java35
3 files changed, 61 insertions, 12 deletions
diff --git a/common/netlinkclient/src/android/net/netlink/NdOption.java b/common/netlinkclient/src/android/net/netlink/NdOption.java
index db262b9..ab9d2e6 100644
--- a/common/netlinkclient/src/android/net/netlink/NdOption.java
+++ b/common/netlinkclient/src/android/net/netlink/NdOption.java
@@ -30,7 +30,7 @@ public class NdOption {
public final int length;
/** Constructs a new NdOption. */
- public NdOption(byte type, int length) {
+ NdOption(byte type, int length) {
this.type = type;
this.length = length;
}
@@ -69,6 +69,11 @@ public class NdOption {
}
}
+ void writeToByteBuffer(ByteBuffer buf) {
+ buf.put(type);
+ buf.put((byte) length);
+ }
+
@Override
public String toString() {
return String.format("NdOption(%d, %d)", Byte.toUnsignedInt(type), length);
diff --git a/common/netlinkclient/src/android/net/netlink/StructNdOptPref64.java b/common/netlinkclient/src/android/net/netlink/StructNdOptPref64.java
index 653d9a1..61a8f3b 100644
--- a/common/netlinkclient/src/android/net/netlink/StructNdOptPref64.java
+++ b/common/netlinkclient/src/android/net/netlink/StructNdOptPref64.java
@@ -21,9 +21,11 @@ import android.util.Log;
import androidx.annotation.NonNull;
+import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
+import java.util.Objects;
/**
* The PREF64 router advertisement option. RFC 8781.
@@ -89,7 +91,23 @@ public class StructNdOptPref64 extends NdOption {
return (short) ((lifetime & 0xfff8) | (prefixLengthCode & 0x7));
}
- public StructNdOptPref64(@NonNull ByteBuffer buf) {
+ public StructNdOptPref64(@NonNull IpPrefix prefix, int lifetime) {
+ super((byte) TYPE, LENGTH);
+
+ Objects.requireNonNull(prefix, "prefix must not be null");
+ if (!(prefix.getAddress() instanceof Inet6Address)) {
+ throw new IllegalArgumentException("Must be an IPv6 prefix: " + prefix);
+ }
+ prefixLengthToPlc(prefix.getPrefixLength()); // Throw if the prefix length is invalid.
+ this.prefix = prefix;
+
+ if (lifetime < 0 || lifetime > 0xfff8) {
+ throw new IllegalArgumentException("Invalid lifetime " + lifetime);
+ }
+ this.lifetime = lifetime & 0xfff8;
+ }
+
+ private StructNdOptPref64(@NonNull ByteBuffer buf) {
super(buf.get(), Byte.toUnsignedInt(buf.get()));
if (type != TYPE) throw new IllegalArgumentException("Invalid type " + type);
if (length != LENGTH) throw new IllegalArgumentException("Invalid length " + length);
@@ -129,13 +147,16 @@ public class StructNdOptPref64 extends NdOption {
}
}
+ protected void writeToByteBuffer(ByteBuffer buf) {
+ super.writeToByteBuffer(buf);
+ buf.putShort(getScaledLifetimePlc(lifetime, prefixLengthToPlc(prefix.getPrefixLength())));
+ buf.put(prefix.getRawAddress(), 0, 12);
+ }
+
/** Outputs the wire format of the option to a new big-endian ByteBuffer. */
public ByteBuffer toByteBuffer() {
ByteBuffer buf = ByteBuffer.allocate(STRUCT_SIZE);
- buf.put(type);
- buf.put((byte) length);
- buf.putShort(getScaledLifetimePlc(lifetime, prefixLengthToPlc(prefix.getPrefixLength())));
- buf.put(prefix.getRawAddress(), 0, 12);
+ writeToByteBuffer(buf);
buf.flip();
return buf;
}
diff --git a/tests/unit/src/android/net/netlink/StructNdOptPref64Test.java b/tests/unit/src/android/net/netlink/StructNdOptPref64Test.java
index 550c6dd..fef103b 100644
--- a/tests/unit/src/android/net/netlink/StructNdOptPref64Test.java
+++ b/tests/unit/src/android/net/netlink/StructNdOptPref64Test.java
@@ -20,9 +20,10 @@ import static android.net.netlink.StructNdOptPref64.getScaledLifetimePlc;
import static android.net.netlink.StructNdOptPref64.plcToPrefixLength;
import static android.net.netlink.StructNdOptPref64.prefixLengthToPlc;
+import static com.android.testutils.MiscAssertsKt.assertThrows;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
-import static org.junit.Assert.fail;
import android.net.IpPrefix;
@@ -159,14 +160,11 @@ public class StructNdOptPref64Test {
}
private void assertInvalidPlc(int plc) {
- try {
- plcToPrefixLength(plc);
- fail("Invalid plc " + plc + " should have thrown exception");
- } catch (IllegalArgumentException expected) { }
+ assertThrows(IllegalArgumentException.class, () -> plcToPrefixLength(plc));
}
@Test
- public void testPrefixLengthPlc() {
+ public void testPrefixLengthToPlc() {
for (int i = 0; i < 6; i++) {
assertEquals(i, prefixLengthToPlc(plcToPrefixLength(i)));
}
@@ -175,4 +173,29 @@ public class StructNdOptPref64Test {
assertInvalidPlc(7);
assertEquals(0, prefixLengthToPlc(96));
}
+
+
+ private void assertInvalidParameters(IpPrefix prefix, int lifetime) {
+ assertThrows(IllegalArgumentException.class, () -> new StructNdOptPref64(prefix, lifetime));
+ }
+
+ @Test
+ public void testToByteBuffer() throws Exception {
+ final IpPrefix prefix1 = prefix(PREFIX1, 56);
+ final IpPrefix prefix2 = prefix(PREFIX2, 96);
+
+ StructNdOptPref64 opt = new StructNdOptPref64(prefix1, 600);
+ assertToByteBufferMatches(opt, "2602025a0064ff9b0000000000000000");
+ assertEquals(new IpPrefix("64:ff9b::/56"), opt.prefix);
+ assertEquals(600, opt.lifetime);
+
+ opt = new StructNdOptPref64(prefix2, 65519);
+ assertToByteBufferMatches(opt, "2602ffe820010db80001000200030064");
+ assertEquals(new IpPrefix("2001:db8:1:2:3:64::/96"), opt.prefix);
+ assertEquals(65512, opt.lifetime);
+
+ assertInvalidParameters(prefix1, 65535);
+ assertInvalidParameters(prefix2, -1);
+ assertInvalidParameters(prefix("1.2.3.4", 32), 600);
+ }
}