Skip to content
Snippets Groups Projects
Commit 4fc3f4fa authored by Chiachang Wang's avatar Chiachang Wang
Browse files

Add netlink attributes field into the InetDiagMessage

Add nlAttrs parameter to store the remaining attributes data.

As a part of follow-up work from aosp/2354202, the TCP socket
parsing can be done by using existing InetDiagMessage class.
The missing piece in the InetDiagMessage class is the possible
netlink attributes fields that may be appended after an
InetDiagMessage.

Bug: 311119352
Bug: 265877161
Test: atest NetworkStaticLibTests
Change-Id: I9c34166124fd4efba2ab211bfb537ccce5e774a4
parent e01fc685
No related branches found
No related tags found
No related merge requests found
......@@ -27,6 +27,7 @@ import static android.system.OsConstants.NETLINK_INET_DIAG;
import static com.android.net.module.util.netlink.NetlinkConstants.NLMSG_DONE;
import static com.android.net.module.util.netlink.NetlinkConstants.SOCK_DESTROY;
import static com.android.net.module.util.netlink.NetlinkConstants.SOCK_DIAG_BY_FAMILY;
import static com.android.net.module.util.netlink.NetlinkConstants.SOCKDIAG_MSG_HEADER_SIZE;
import static com.android.net.module.util.netlink.NetlinkConstants.hexify;
import static com.android.net.module.util.netlink.NetlinkConstants.stringForAddressFamily;
import static com.android.net.module.util.netlink.NetlinkConstants.stringForProtocol;
......@@ -59,6 +60,7 @@ import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
......@@ -154,7 +156,8 @@ public class InetDiagMessage extends NetlinkMessage {
}
public StructInetDiagMsg inetDiagMsg;
// The netlink attributes.
public List<StructNlAttr> nlAttrs = new ArrayList<>();
@VisibleForTesting
public InetDiagMessage(@NonNull StructNlMsgHdr header) {
super(header);
......@@ -172,6 +175,16 @@ public class InetDiagMessage extends NetlinkMessage {
if (msg.inetDiagMsg == null) {
return null;
}
final int payloadLength = header.nlmsg_len - SOCKDIAG_MSG_HEADER_SIZE;
final ByteBuffer payload = byteBuffer.slice();
while (payload.position() < payloadLength) {
final StructNlAttr attr = StructNlAttr.parse(payload);
// Stop parsing for truncated or malformed attribute
if (attr == null) return null;
msg.nlAttrs.add(attr);
}
return msg;
}
......
......@@ -32,6 +32,7 @@ import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REQUEST;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
......@@ -345,28 +346,28 @@ public class InetDiagSocketTest {
// Hexadecimal representation of InetDiagMessage
private static final String INET_DIAG_MSG_HEX1 =
// struct nlmsghdr
"58000000" + // length = 88
"1400" + // type = SOCK_DIAG_BY_FAMILY
"0200" + // flags = NLM_F_MULTI
"00000000" + // seqno
"f5220000" + // pid
"58000000" // length = 88
+ "1400" // type = SOCK_DIAG_BY_FAMILY
+ "0200" // flags = NLM_F_MULTI
+ "00000000" // seqno
+ "f5220000" // pid
// struct inet_diag_msg
"0a" + // family = AF_INET6
"01" + // idiag_state = 1
"02" + // idiag_timer = 2
"ff" + // idiag_retrans = 255
+ "0a" // family = AF_INET6
+ "01" // idiag_state = 1
+ "02" // idiag_timer = 2
+ "ff" // idiag_retrans = 255
// inet_diag_sockid
"a817" + // idiag_sport = 43031
"960f" + // idiag_dport = 38415
"20010db8000000000000000000000001" + // idiag_src = 2001:db8::1
"20010db8000000000000000000000002" + // idiag_dst = 2001:db8::2
"07000000" + // idiag_if = 7
"5800000000000000" + // idiag_cookie = 88
"04000000" + // idiag_expires = 4
"05000000" + // idiag_rqueue = 5
"06000000" + // idiag_wqueue = 6
"a3270000" + // idiag_uid = 10147
"a57e19f0"; // idiag_inode = 4028202661
+ "a817" // idiag_sport = 43031
+ "960f" // idiag_dport = 38415
+ "20010db8000000000000000000000001" // idiag_src = 2001:db8::1
+ "20010db8000000000000000000000002" // idiag_dst = 2001:db8::2
+ "07000000" // idiag_if = 7
+ "5800000000000000" // idiag_cookie = 88
+ "04000000" // idiag_expires = 4
+ "05000000" // idiag_rqueue = 5
+ "06000000" // idiag_wqueue = 6
+ "a3270000" // idiag_uid = 10147
+ "a57e19f0"; // idiag_inode = 4028202661
private void assertInetDiagMsg1(final NetlinkMessage msg) {
assertNotNull(msg);
......@@ -394,33 +395,45 @@ public class InetDiagSocketTest {
assertEquals(6, inetDiagMsg.inetDiagMsg.idiag_wqueue);
assertEquals(10147, inetDiagMsg.inetDiagMsg.idiag_uid);
assertEquals(4028202661L, inetDiagMsg.inetDiagMsg.idiag_inode);
// Verify the length of attribute list is 0 as expected since message doesn't
// take any attributes
assertEquals(0, inetDiagMsg.nlAttrs.size());
}
// Hexadecimal representation of InetDiagMessage
private static final String INET_DIAG_MSG_HEX2 =
// struct nlmsghdr
"58000000" + // length = 88
"1400" + // type = SOCK_DIAG_BY_FAMILY
"0200" + // flags = NLM_F_MULTI
"00000000" + // seqno
"f5220000" + // pid
"6C000000" // length = 108
+ "1400" // type = SOCK_DIAG_BY_FAMILY
+ "0200" // flags = NLM_F_MULTI
+ "00000000" // seqno
+ "f5220000" // pid
// struct inet_diag_msg
"0a" + // family = AF_INET6
"02" + // idiag_state = 2
"10" + // idiag_timer = 16
"20" + // idiag_retrans = 32
+ "0a" // family = AF_INET6
+ "02" // idiag_state = 2
+ "10" // idiag_timer = 16
+ "20" // idiag_retrans = 32
// inet_diag_sockid
"a845" + // idiag_sport = 43077
"01bb" + // idiag_dport = 443
"20010db8000000000000000000000003" + // idiag_src = 2001:db8::3
"20010db8000000000000000000000004" + // idiag_dst = 2001:db8::4
"08000000" + // idiag_if = 8
"6300000000000000" + // idiag_cookie = 99
"30000000" + // idiag_expires = 48
"40000000" + // idiag_rqueue = 64
"50000000" + // idiag_wqueue = 80
"39300000" + // idiag_uid = 12345
"851a0000"; // idiag_inode = 6789
+ "a845" // idiag_sport = 43077
+ "01bb" // idiag_dport = 443
+ "20010db8000000000000000000000003" // idiag_src = 2001:db8::3
+ "20010db8000000000000000000000004" // idiag_dst = 2001:db8::4
+ "08000000" // idiag_if = 8
+ "6300000000000000" // idiag_cookie = 99
+ "30000000" // idiag_expires = 48
+ "40000000" // idiag_rqueue = 64
+ "50000000" // idiag_wqueue = 80
+ "39300000" // idiag_uid = 12345
+ "851a0000" // idiag_inode = 6789
+ "0500" // len = 5
+ "0800" // type = 8
+ "00000000" // data
+ "0800" // len = 8
+ "0F00" // type = 15(INET_DIAG_MARK)
+ "850A0C00" // data, socket mark=789125
+ "0400" // len = 4
+ "0200"; // type = 2
private void assertInetDiagMsg2(final NetlinkMessage msg) {
assertNotNull(msg);
......@@ -448,6 +461,104 @@ public class InetDiagSocketTest {
assertEquals(80, inetDiagMsg.inetDiagMsg.idiag_wqueue);
assertEquals(12345, inetDiagMsg.inetDiagMsg.idiag_uid);
assertEquals(6789, inetDiagMsg.inetDiagMsg.idiag_inode);
// Verify the number of nlAttr and their content.
assertEquals(3, inetDiagMsg.nlAttrs.size());
assertEquals(5, inetDiagMsg.nlAttrs.get(0).nla_len);
assertEquals(8, inetDiagMsg.nlAttrs.get(0).nla_type);
assertArrayEquals(
HexEncoding.decode("00".toCharArray(), false),
inetDiagMsg.nlAttrs.get(0).nla_value);
assertEquals(8, inetDiagMsg.nlAttrs.get(1).nla_len);
assertEquals(15, inetDiagMsg.nlAttrs.get(1).nla_type);
assertArrayEquals(
HexEncoding.decode("850A0C00".toCharArray(), false),
inetDiagMsg.nlAttrs.get(1).nla_value);
assertEquals(4, inetDiagMsg.nlAttrs.get(2).nla_len);
assertEquals(2, inetDiagMsg.nlAttrs.get(2).nla_type);
assertNull(inetDiagMsg.nlAttrs.get(2).nla_value);
}
// Hexadecimal representation of InetDiagMessage
private static final String INET_DIAG_MSG_HEX_MALFORMED =
// struct nlmsghdr
"6E000000" // length = 110
+ "1400" // type = SOCK_DIAG_BY_FAMILY
+ "0200" // flags = NLM_F_MULTI
+ "00000000" // seqno
+ "f5220000" // pid
// struct inet_diag_msg
+ "0a" // family = AF_INET6
+ "02" // idiag_state = 2
+ "10" // idiag_timer = 16
+ "20" // idiag_retrans = 32
// inet_diag_sockid
+ "a845" // idiag_sport = 43077
+ "01bb" // idiag_dport = 443
+ "20010db8000000000000000000000005" // idiag_src = 2001:db8::5
+ "20010db8000000000000000000000006" // idiag_dst = 2001:db8::6
+ "08000000" // idiag_if = 8
+ "6300000000000000" // idiag_cookie = 99
+ "30000000" // idiag_expires = 48
+ "40000000" // idiag_rqueue = 64
+ "50000000" // idiag_wqueue = 80
+ "39300000" // idiag_uid = 12345
+ "851a0000" // idiag_inode = 6789
+ "0500" // len = 5
+ "0800" // type = 8
+ "00000000" // data
+ "0800" // len = 8
+ "0F00" // type = 15(INET_DIAG_MARK)
+ "850A0C00" // data, socket mark=789125
+ "0400" // len = 4
+ "0200" // type = 2
+ "0100" // len = 1, malformed value
+ "0100"; // type = 1
@Test
public void testParseInetDiagResponseMalformedNlAttr() throws Exception {
final ByteBuffer byteBuffer = ByteBuffer.wrap(
HexEncoding.decode((INET_DIAG_MSG_HEX_MALFORMED).toCharArray(), false));
byteBuffer.order(ByteOrder.nativeOrder());
assertNull(NetlinkMessage.parse(byteBuffer, NETLINK_INET_DIAG));
}
// Hexadecimal representation of InetDiagMessage
private static final String INET_DIAG_MSG_HEX_TRUNCATED =
// struct nlmsghdr
"5E000000" // length = 96
+ "1400" // type = SOCK_DIAG_BY_FAMILY
+ "0200" // flags = NLM_F_MULTI
+ "00000000" // seqno
+ "f5220000" // pid
// struct inet_diag_msg
+ "0a" // family = AF_INET6
+ "02" // idiag_state = 2
+ "10" // idiag_timer = 16
+ "20" // idiag_retrans = 32
// inet_diag_sockid
+ "a845" // idiag_sport = 43077
+ "01bb" // idiag_dport = 443
+ "20010db8000000000000000000000005" // idiag_src = 2001:db8::5
+ "20010db8000000000000000000000006" // idiag_dst = 2001:db8::6
+ "08000000" // idiag_if = 8
+ "6300000000000000" // idiag_cookie = 99
+ "30000000" // idiag_expires = 48
+ "40000000" // idiag_rqueue = 64
+ "50000000" // idiag_wqueue = 80
+ "39300000" // idiag_uid = 12345
+ "851a0000" // idiag_inode = 6789
+ "0800" // len = 8
+ "0100" // type = 1
+ "000000"; // data, less than the expected length
@Test
public void testParseInetDiagResponseTruncatedNlAttr() throws Exception {
final ByteBuffer byteBuffer = ByteBuffer.wrap(
HexEncoding.decode((INET_DIAG_MSG_HEX_TRUNCATED).toCharArray(), false));
byteBuffer.order(ByteOrder.nativeOrder());
assertNull(NetlinkMessage.parse(byteBuffer, NETLINK_INET_DIAG));
}
private static final byte[] INET_DIAG_MSG_BYTES =
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment