Snap for 7993599 from d913f95f132fe738872222b7b9f714a4a3f9d848 to mainline-networking-release
Change-Id: I369ab828e088ba9d26adcec13eea380c1b65dcdd
diff --git a/common/device/com/android/net/module/util/netlink/RtNetlinkAddressMessage.java b/common/device/com/android/net/module/util/netlink/RtNetlinkAddressMessage.java
index a518c76..f7b0d02 100644
--- a/common/device/com/android/net/module/util/netlink/RtNetlinkAddressMessage.java
+++ b/common/device/com/android/net/module/util/netlink/RtNetlinkAddressMessage.java
@@ -114,9 +114,10 @@
// and will overwrite the flags set above.
byteBuffer.position(baseOffset);
nlAttr = StructNlAttr.findNextAttrOfType(IFA_FLAGS, byteBuffer);
- if (nlAttr != null) {
- addrMsg.mFlags = nlAttr.getValueAsInt(0 /* default value */);
- }
+ if (nlAttr == null) return null;
+ final Integer value = nlAttr.getValueAsInteger();
+ if (value == null) return null;
+ addrMsg.mFlags = value;
return addrMsg;
}
diff --git a/common/device/com/android/net/module/util/netlink/StructNlAttr.java b/common/device/com/android/net/module/util/netlink/StructNlAttr.java
index 485e67c..a9b6495 100644
--- a/common/device/com/android/net/module/util/netlink/StructNlAttr.java
+++ b/common/device/com/android/net/module/util/netlink/StructNlAttr.java
@@ -287,14 +287,22 @@
}
/**
- * Get attribute value as Integer.
+ * Get attribute value as Integer, or null if malformed (e.g., length is not 4 bytes).
*/
- public int getValueAsInt(int defaultValue) {
+ public Integer getValueAsInteger() {
final ByteBuffer byteBuffer = getValueAsByteBuffer();
if (byteBuffer == null || byteBuffer.remaining() != Integer.BYTES) {
- return defaultValue;
+ return null;
}
- return getValueAsByteBuffer().getInt();
+ return byteBuffer.getInt();
+ }
+
+ /**
+ * Get attribute value as Int, default value if malformed.
+ */
+ public int getValueAsInt(int defaultValue) {
+ final Integer value = getValueAsInteger();
+ return (value != null) ? value : defaultValue;
}
/**
@@ -341,6 +349,7 @@
public String getValueAsString() {
if (nla_value == null) return null;
// Check the attribute value length after removing string termination flag '\0'.
+ // This assumes that all netlink strings are null-terminated.
if (nla_value.length < (nla_len - NLA_HEADERLEN - 1)) return null;
try {
diff --git a/common/device/com/android/net/module/util/structs/Ipv4Header.java b/common/device/com/android/net/module/util/structs/Ipv4Header.java
new file mode 100644
index 0000000..5249454
--- /dev/null
+++ b/common/device/com/android/net/module/util/structs/Ipv4Header.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.net.module.util.structs;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+import java.net.Inet4Address;
+
+/**
+ * L3 IPv4 header as per https://tools.ietf.org/html/rfc791.
+ * This class doesn't contain options field.
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |Version| IHL |Type of Service| Total Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Identification |Flags| Fragment Offset |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Time to Live | Protocol | Header Checksum |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Source Address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Destination Address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+public class Ipv4Header extends Struct {
+ // IP Version=IPv4, IHL is always 5(*4bytes) because options are not supported.
+ @VisibleForTesting
+ public static final byte IPHDR_VERSION_IHL = 0x45;
+
+ @Field(order = 0, type = Type.S8)
+ // version (4 bits), IHL (4 bits)
+ public final byte vi;
+ @Field(order = 1, type = Type.S8)
+ public final byte tos;
+ @Field(order = 2, type = Type.U16)
+ public final int totalLength;
+ @Field(order = 3, type = Type.S16)
+ public final short id;
+ @Field(order = 4, type = Type.S16)
+ // flags (3 bits), fragment offset (13 bits)
+ public final short flagsAndFragmentOffset;
+ @Field(order = 5, type = Type.U8)
+ public final short ttl;
+ @Field(order = 6, type = Type.S8)
+ public final byte protocol;
+ @Field(order = 7, type = Type.S16)
+ public final short checksum;
+ @Field(order = 8, type = Type.Ipv4Address)
+ public final Inet4Address srcIp;
+ @Field(order = 9, type = Type.Ipv4Address)
+ public final Inet4Address dstIp;
+
+ public Ipv4Header(final byte tos, final int totalLength, final short id,
+ final short flagsAndFragmentOffset, final short ttl, final byte protocol,
+ final short checksum, final Inet4Address srcIp, final Inet4Address dstIp) {
+ this(IPHDR_VERSION_IHL, tos, totalLength, id, flagsAndFragmentOffset, ttl,
+ protocol, checksum, srcIp, dstIp);
+ }
+
+ private Ipv4Header(final byte vi, final byte tos, final int totalLength, final short id,
+ final short flagsAndFragmentOffset, final short ttl, final byte protocol,
+ final short checksum, final Inet4Address srcIp, final Inet4Address dstIp) {
+ this.vi = vi;
+ this.tos = tos;
+ this.totalLength = totalLength;
+ this.id = id;
+ this.flagsAndFragmentOffset = flagsAndFragmentOffset;
+ this.ttl = ttl;
+ this.protocol = protocol;
+ this.checksum = checksum;
+ this.srcIp = srcIp;
+ this.dstIp = dstIp;
+ }
+}
diff --git a/common/device/com/android/net/module/util/structs/TcpHeader.java b/common/device/com/android/net/module/util/structs/TcpHeader.java
new file mode 100644
index 0000000..0c97401
--- /dev/null
+++ b/common/device/com/android/net/module/util/structs/TcpHeader.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.net.module.util.structs;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/**
+ * L4 TCP header as per https://tools.ietf.org/html/rfc793.
+ * This class does not contain option and data fields.
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Source Port | Destination Port |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Sequence Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Acknowledgment Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Data | |U|A|P|R|S|F| |
+ * | Offset| Reserved |R|C|S|S|Y|I| Window |
+ * | | |G|K|H|T|N|N| |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Checksum | Urgent Pointer |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Options | Padding |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | data |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+public class TcpHeader extends Struct {
+ @Field(order = 0, type = Type.U16)
+ public final int srcPort;
+ @Field(order = 1, type = Type.U16)
+ public final int dstPort;
+ @Field(order = 2, type = Type.U32)
+ public final long seq;
+ @Field(order = 3, type = Type.U32)
+ public final long ack;
+ @Field(order = 4, type = Type.S16)
+ // data Offset (4 bits), reserved (6 bits), control bits (6 bits)
+ // TODO: update with bitfields once class Struct supports it
+ public final short dataOffsetAndControlBits;
+ @Field(order = 5, type = Type.U16)
+ public final int window;
+ @Field(order = 6, type = Type.S16)
+ public final short checksum;
+ @Field(order = 7, type = Type.U16)
+ public final int urgentPointer;
+
+ public TcpHeader(final int srcPort, final int dstPort, final long seq, final long ack,
+ final short dataOffsetAndControlBits, final int window, final short checksum,
+ final int urgentPointer) {
+ this.srcPort = srcPort;
+ this.dstPort = dstPort;
+ this.seq = seq;
+ this.ack = ack;
+ this.dataOffsetAndControlBits = dataOffsetAndControlBits;
+ this.window = window;
+ this.checksum = checksum;
+ this.urgentPointer = urgentPointer;
+ }
+}
diff --git a/common/device/com/android/net/module/util/structs/UdpHeader.java b/common/device/com/android/net/module/util/structs/UdpHeader.java
new file mode 100644
index 0000000..8b0316b
--- /dev/null
+++ b/common/device/com/android/net/module/util/structs/UdpHeader.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.net.module.util.structs;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/**
+ * L4 UDP header as per https://tools.ietf.org/html/rfc768.
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Source Port | Destination Port |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Length | Checksum |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | data octets ...
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ...
+ */
+public class UdpHeader extends Struct {
+ @Field(order = 0, type = Type.U16)
+ public final int srcPort;
+ @Field(order = 1, type = Type.U16)
+ public final int dstPort;
+ @Field(order = 2, type = Type.U16)
+ public final int length;
+ @Field(order = 3, type = Type.S16)
+ public final short checksum;
+
+ public UdpHeader(final int srcPort, final int dstPort, final int length,
+ final short checksum) {
+ this.srcPort = srcPort;
+ this.dstPort = dstPort;
+ this.length = length;
+ this.checksum = checksum;
+ }
+}
diff --git a/common/native/bpf_map_utils/Android.bp b/common/native/bpf_map_utils/Android.bp
index e291bbc..e14c259 100644
--- a/common/native/bpf_map_utils/Android.bp
+++ b/common/native/bpf_map_utils/Android.bp
@@ -12,6 +12,10 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
cc_library_headers {
name: "bpf_map_utils",
vendor_available: true,
diff --git a/common/tests/unit/src/com/android/net/module/util/netlink/StructNlAttrTest.java b/common/tests/unit/src/com/android/net/module/util/netlink/StructNlAttrTest.java
index 72e179b..af3fac2 100644
--- a/common/tests/unit/src/com/android/net/module/util/netlink/StructNlAttrTest.java
+++ b/common/tests/unit/src/com/android/net/module/util/netlink/StructNlAttrTest.java
@@ -16,6 +16,7 @@
package com.android.net.module.util.netlink;
+import static com.android.net.module.util.netlink.RtNetlinkAddressMessage.IFA_FLAGS;
import static com.android.net.module.util.netlink.RtNetlinkLinkMessage.IFLA_ADDRESS;
import static com.android.net.module.util.netlink.RtNetlinkLinkMessage.IFLA_IFNAME;
@@ -35,6 +36,7 @@
public class StructNlAttrTest {
private static final MacAddress TEST_MAC_ADDRESS = MacAddress.fromString("00:11:22:33:44:55");
private static final String TEST_INTERFACE_NAME = "wlan0";
+ private static final int TEST_ADDR_FLAGS = 0x80;
@Test
public void testGetValueAsMacAddress() {
@@ -65,4 +67,29 @@
final String str2 = attr2.getValueAsString();
assertEquals(str2, TEST_INTERFACE_NAME);
}
+
+ @Test
+ public void testGetValueAsIntger() {
+ final StructNlAttr attr1 = new StructNlAttr(IFA_FLAGS, TEST_ADDR_FLAGS);
+ final Integer integer1 = attr1.getValueAsInteger();
+ final int int1 = attr1.getValueAsInt(0x08 /* default value */);
+ assertEquals(integer1, new Integer(TEST_ADDR_FLAGS));
+ assertEquals(int1, TEST_ADDR_FLAGS);
+
+ // Malformed attribute.
+ final byte[] malformed_int = new byte[] { (byte) 0x0, (byte) 0x0, (byte) 0x80, };
+ final StructNlAttr attr2 = new StructNlAttr(IFA_FLAGS, malformed_int);
+ final Integer integer2 = attr2.getValueAsInteger();
+ final int int2 = attr2.getValueAsInt(0x08 /* default value */);
+ assertNull(integer2);
+ assertEquals(int2, 0x08 /* default value */);
+
+ // Null attribute value.
+ final byte[] null_int = null;
+ final StructNlAttr attr3 = new StructNlAttr(IFA_FLAGS, null_int);
+ final Integer integer3 = attr3.getValueAsInteger();
+ final int int3 = attr3.getValueAsInt(0x08 /* default value */);
+ assertNull(integer3);
+ assertEquals(int3, 0x08 /* default value */);
+ }
}