diff --git a/staticlibs/device/com/android/net/module/util/netlink/StructNlAttr.java b/staticlibs/device/com/android/net/module/util/netlink/StructNlAttr.java index a9b6495082..43e83121d3 100644 --- a/staticlibs/device/com/android/net/module/util/netlink/StructNlAttr.java +++ b/staticlibs/device/com/android/net/module/util/netlink/StructNlAttr.java @@ -21,6 +21,8 @@ import android.net.MacAddress; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import static java.nio.ByteOrder.nativeOrder; + import java.io.UnsupportedEncodingException; import java.net.InetAddress; import java.net.UnknownHostException; @@ -152,12 +154,12 @@ public class StructNlAttr { nla_type = type; setValue(new byte[Short.BYTES]); final ByteBuffer buf = getValueAsByteBuffer(); - final ByteOrder originalOrder = buf.order(); + // ByteBuffer returned by getValueAsByteBuffer is always in native byte order. try { buf.order(order); buf.putShort(value); } finally { - buf.order(originalOrder); + buf.order(nativeOrder()); } } @@ -169,12 +171,29 @@ public class StructNlAttr { nla_type = type; setValue(new byte[Integer.BYTES]); final ByteBuffer buf = getValueAsByteBuffer(); - final ByteOrder originalOrder = buf.order(); + // ByteBuffer returned by getValueAsByteBuffer is always in native byte order. try { buf.order(order); buf.putInt(value); } finally { - buf.order(originalOrder); + buf.order(nativeOrder()); + } + } + + public StructNlAttr(short type, long value) { + this(type, value, ByteOrder.nativeOrder()); + } + + public StructNlAttr(short type, long value, ByteOrder order) { + nla_type = type; + setValue(new byte[Long.BYTES]); + final ByteBuffer buf = getValueAsByteBuffer(); + // ByteBuffer returned by getValueAsByteBuffer is always in native byte order. + try { + buf.order(order); + buf.putLong(value); + } finally { + buf.order(nativeOrder()); } } @@ -288,6 +307,7 @@ public class StructNlAttr { /** * Get attribute value as Integer, or null if malformed (e.g., length is not 4 bytes). + * The attribute value is assumed to be in native byte order. */ public Integer getValueAsInteger() { final ByteBuffer byteBuffer = getValueAsByteBuffer(); @@ -297,6 +317,18 @@ public class StructNlAttr { return byteBuffer.getInt(); } + /** + * Get attribute value as Long, or null if malformed (e.g., length is not 8 bytes). + * The attribute value is assumed to be in native byte order. + */ + public Long getValueAsLong() { + final ByteBuffer byteBuffer = getValueAsByteBuffer(); + if (byteBuffer == null || byteBuffer.remaining() != Long.BYTES) { + return null; + } + return byteBuffer.getLong(); + } + /** * Get attribute value as Int, default value if malformed. */ diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/StructNlAttrTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/StructNlAttrTest.java index af3fac2e7d..4c3fde60ed 100644 --- a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/StructNlAttrTest.java +++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/StructNlAttrTest.java @@ -92,4 +92,26 @@ public class StructNlAttrTest { assertNull(integer3); assertEquals(int3, 0x08 /* default value */); } + + @Test + public void testGetValueAsLong() { + final Long input = 1234567L; + // Not a real netlink attribute, just for testing + final StructNlAttr attr = new StructNlAttr(IFA_FLAGS, input); + + final Long output = attr.getValueAsLong(); + + assertEquals(input, output); + } + + @Test + public void testGetValueAsLong_malformed() { + final int input = 1234567; + // Not a real netlink attribute, just for testing + final StructNlAttr attr = new StructNlAttr(IFA_FLAGS, input); + + final Long output = attr.getValueAsLong(); + + assertNull(output); + } }