Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1574a825 authored by Lorenzo Colitti's avatar Lorenzo Colitti Committed by Automerger Merge Worker
Browse files

Support serializing a StructNdOptPref64 to a ByteBuffer. am: 568b689f am:...

Support serializing a StructNdOptPref64 to a ByteBuffer. am: 568b689f am: 4735ee7a am: 55c29235 am: 1078c049

Change-Id: Ife6c8b6450c971863b8e7aec8a902a5f460077e7
parents 939cadcf 1078c049
Loading
Loading
Loading
Loading
+34 −2
Original line number Diff line number Diff line
@@ -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() {
+30 −7
Original line number Diff line number Diff line
@@ -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));
    }
}