diff options
author | Lorenzo Colitti <lorenzo@google.com> | 2020-04-18 10:16:06 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-04-18 10:16:06 +0000 |
commit | 873b22e76a73c49e9a31479f3735458e96dca6fc (patch) | |
tree | 37b324eaf91ac21288c93ad845fadb3e5580a170 | |
parent | 9ea216f71808926baac2990d237558ffc357e8f7 (diff) | |
parent | 52e7aac6b49485a55ed27df57dfef8542941e979 (diff) |
Support serializing a StructNdOptPref64 to a ByteBuffer. am: 3841078baa am: 52e7aac6b4
Change-Id: I3f0902e1f2c329e0c3cb98f58c80ed3f8d4ee93b
-rw-r--r-- | common/netlinkclient/src/android/net/netlink/StructNdOptPref64.java | 36 | ||||
-rw-r--r-- | tests/unit/src/android/net/netlink/StructNdOptPref64Test.java | 37 |
2 files changed, 64 insertions, 9 deletions
diff --git a/common/netlinkclient/src/android/net/netlink/StructNdOptPref64.java b/common/netlinkclient/src/android/net/netlink/StructNdOptPref64.java index 5cce3da..653d9a1 100644 --- a/common/netlinkclient/src/android/net/netlink/StructNdOptPref64.java +++ b/common/netlinkclient/src/android/net/netlink/StructNdOptPref64.java @@ -44,6 +44,7 @@ import java.nio.ByteBuffer; public class StructNdOptPref64 extends NdOption { public static final int STRUCT_SIZE = 16; public static final int TYPE = 38; + public static final byte LENGTH = 2; private static final String TAG = StructNdOptPref64.class.getSimpleName(); @@ -55,7 +56,7 @@ public class StructNdOptPref64 extends NdOption { /** The NAT64 prefix. */ public final IpPrefix prefix; - int plcToPrefixLength(int plc) { + static int plcToPrefixLength(int plc) { switch (plc) { case 0: return 96; case 1: return 64; @@ -68,10 +69,30 @@ public class StructNdOptPref64 extends NdOption { } } + static int prefixLengthToPlc(int prefixLength) { + switch (prefixLength) { + case 96: return 0; + case 64: return 1; + case 56: return 2; + case 48: return 3; + case 40: return 4; + case 32: return 5; + default: + throw new IllegalArgumentException("Invalid prefix length " + prefixLength); + } + } + + /** + * Returns the 2-byte "scaled lifetime and prefix length code" field: 13-bit lifetime, 3-bit PLC + */ + static short getScaledLifetimePlc(int lifetime, int prefixLengthCode) { + return (short) ((lifetime & 0xfff8) | (prefixLengthCode & 0x7)); + } + public StructNdOptPref64(@NonNull ByteBuffer buf) { super(buf.get(), Byte.toUnsignedInt(buf.get())); if (type != TYPE) throw new IllegalArgumentException("Invalid type " + type); - if (length != 2) throw new IllegalArgumentException("Invalid length " + length); + if (length != LENGTH) throw new IllegalArgumentException("Invalid length " + length); int scaledLifetimePlc = Short.toUnsignedInt(buf.getShort()); lifetime = scaledLifetimePlc & 0xfff8; @@ -108,6 +129,17 @@ public class StructNdOptPref64 extends NdOption { } } + /** 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); + buf.flip(); + return buf; + } + @Override @NonNull public String toString() { diff --git a/tests/unit/src/android/net/netlink/StructNdOptPref64Test.java b/tests/unit/src/android/net/netlink/StructNdOptPref64Test.java index 3d36d9b..550c6dd 100644 --- a/tests/unit/src/android/net/netlink/StructNdOptPref64Test.java +++ b/tests/unit/src/android/net/netlink/StructNdOptPref64Test.java @@ -16,8 +16,13 @@ package android.net.netlink; +import static android.net.netlink.StructNdOptPref64.getScaledLifetimePlc; +import static android.net.netlink.StructNdOptPref64.plcToPrefixLength; +import static android.net.netlink.StructNdOptPref64.prefixLengthToPlc; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; import android.net.IpPrefix; @@ -57,11 +62,9 @@ public class StructNdOptPref64Test { assertEquals(prefix, opt.prefix); } - /** - * Returns the 2-byte "scaled lifetime and prefix length code" field: 13-bit lifetime, 3-bit PLC - */ - private short getPref64ScaledLifetimePlc(int lifetime, int prefixLengthCode) { - return (short) ((lifetime & 0xfff8) | (prefixLengthCode & 0x7)); + private void assertToByteBufferMatches(StructNdOptPref64 opt, String expected) { + String actual = HexEncoding.encodeToString(opt.toByteBuffer().array(), false /*upperCase*/); + assertEquals(expected, actual); } private ByteBuffer makeNdOptPref64(int lifetime, byte[] prefix, int prefixLengthCode) { @@ -69,8 +72,8 @@ public class StructNdOptPref64Test { ByteBuffer buf = ByteBuffer.allocate(16) .put((byte) StructNdOptPref64.TYPE) - .put((byte) 2) // len=2 (16 bytes) - .putShort(getPref64ScaledLifetimePlc(lifetime, prefixLengthCode)) + .put((byte) StructNdOptPref64.LENGTH) + .putShort(getScaledLifetimePlc(lifetime, prefixLengthCode)) .put(prefix, 0, 12); buf.flip(); @@ -85,6 +88,7 @@ public class StructNdOptPref64Test { byte[] rawBytes = HexEncoding.decode(hexBytes); StructNdOptPref64 opt = StructNdOptPref64.parse(ByteBuffer.wrap(rawBytes)); assertPref64OptMatches(136, prefix("2001:db8:3:4:5:6::", 96), opt); + assertToByteBufferMatches(opt, hexBytes); hexBytes = "2602" // type=38, len=2 (16 bytes) + "2752" // lifetime=10064, PLC=2 (/56) @@ -92,6 +96,7 @@ public class StructNdOptPref64Test { rawBytes = HexEncoding.decode(hexBytes); opt = StructNdOptPref64.parse(ByteBuffer.wrap(rawBytes)); assertPref64OptMatches(10064, prefix("64:ff9b::", 56), opt); + assertToByteBufferMatches(opt, hexBytes); } @Test @@ -152,4 +157,22 @@ public class StructNdOptPref64Test { assertPref64OptMatches(600, prefix(PREFIX1, 40), opt); assertEquals("NdOptPref64(64:ff9b::/40, 600)", opt.toString()); } + + private void assertInvalidPlc(int plc) { + try { + plcToPrefixLength(plc); + fail("Invalid plc " + plc + " should have thrown exception"); + } catch (IllegalArgumentException expected) { } + } + + @Test + public void testPrefixLengthPlc() { + for (int i = 0; i < 6; i++) { + assertEquals(i, prefixLengthToPlc(plcToPrefixLength(i))); + } + assertInvalidPlc(-1); + assertInvalidPlc(6); + assertInvalidPlc(7); + assertEquals(0, prefixLengthToPlc(96)); + } } |