Merge "Add netlink attributes field into the InetDiagMessage" into main

This commit is contained in:
Chiachang Wang 2023-12-25 03:09:42 +00:00 • committed by Gerrit Code Review
commit 504f6d6c90
2 changed files with 165 additions and 41 deletions

View file

@ -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;
}

View file

@ -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 =