1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.net.netlink;
18 
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assume.assumeTrue;
21 
22 import android.system.OsConstants;
23 
24 import androidx.test.filters.SmallTest;
25 import androidx.test.runner.AndroidJUnit4;
26 
27 import libcore.util.HexEncoding;
28 
29 import org.junit.Test;
30 import org.junit.runner.RunWith;
31 
32 import java.net.Inet4Address;
33 import java.net.InetAddress;
34 import java.nio.ByteOrder;
35 
36 @RunWith(AndroidJUnit4.class)
37 @SmallTest
38 public class ConntrackMessageTest {
39     private static final boolean USING_LE = (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN);
40 
41     // Example 1: TCP (192.168.43.209, 44333) -> (23.211.13.26, 443)
42     public static final String CT_V4UPDATE_TCP_HEX =
43             // struct nlmsghdr
44             "50000000" +      // length = 80
45             "0001" +          // type = (1 << 8) | 0
46             "0501" +          // flags
47             "01000000" +      // seqno = 1
48             "00000000" +      // pid = 0
49             // struct nfgenmsg
50             "02" +            // nfgen_family  = AF_INET
51             "00" +            // version = NFNETLINK_V0
52             "0000" +          // res_id
53             // struct nlattr
54             "3400" +          // nla_len = 52
55             "0180" +          // nla_type = nested CTA_TUPLE_ORIG
56                 // struct nlattr
57                 "1400" +      // nla_len = 20
58                 "0180" +      // nla_type = nested CTA_TUPLE_IP
59                     "0800 0100 C0A82BD1" +  // nla_type=CTA_IP_V4_SRC, ip=192.168.43.209
60                     "0800 0200 17D30D1A" +  // nla_type=CTA_IP_V4_DST, ip=23.211.13.26
61                 // struct nlattr
62                 "1C00" +      // nla_len = 28
63                 "0280" +      // nla_type = nested CTA_TUPLE_PROTO
64                     "0500 0100 06 000000" +  // nla_type=CTA_PROTO_NUM, proto=6
65                     "0600 0200 AD2D 0000" +  // nla_type=CTA_PROTO_SRC_PORT, port=44333 (big endian)
66                     "0600 0300 01BB 0000" +  // nla_type=CTA_PROTO_DST_PORT, port=443 (big endian)
67             // struct nlattr
68             "0800" +          // nla_len = 8
69             "0700" +          // nla_type = CTA_TIMEOUT
70             "00069780";       // nla_value = 432000 (big endian)
71     public static final byte[] CT_V4UPDATE_TCP_BYTES =
72             HexEncoding.decode(CT_V4UPDATE_TCP_HEX.replaceAll(" ", "").toCharArray(), false);
73 
74     // Example 2: UDP (100.96.167.146, 37069) -> (216.58.197.10, 443)
75     public static final String CT_V4UPDATE_UDP_HEX =
76             // struct nlmsghdr
77             "50000000" +      // length = 80
78             "0001" +          // type = (1 << 8) | 0
79             "0501" +          // flags
80             "01000000" +      // seqno = 1
81             "00000000" +      // pid = 0
82             // struct nfgenmsg
83             "02" +            // nfgen_family  = AF_INET
84             "00" +            // version = NFNETLINK_V0
85             "0000" +          // res_id
86             // struct nlattr
87             "3400" +          // nla_len = 52
88             "0180" +          // nla_type = nested CTA_TUPLE_ORIG
89                 // struct nlattr
90                 "1400" +      // nla_len = 20
91                 "0180" +      // nla_type = nested CTA_TUPLE_IP
92                     "0800 0100 6460A792" +  // nla_type=CTA_IP_V4_SRC, ip=100.96.167.146
93                     "0800 0200 D83AC50A" +  // nla_type=CTA_IP_V4_DST, ip=216.58.197.10
94                 // struct nlattr
95                 "1C00" +      // nla_len = 28
96                 "0280" +      // nla_type = nested CTA_TUPLE_PROTO
97                     "0500 0100 11 000000" +  // nla_type=CTA_PROTO_NUM, proto=17
98                     "0600 0200 90CD 0000" +  // nla_type=CTA_PROTO_SRC_PORT, port=37069 (big endian)
99                     "0600 0300 01BB 0000" +  // nla_type=CTA_PROTO_DST_PORT, port=443 (big endian)
100             // struct nlattr
101             "0800" +          // nla_len = 8
102             "0700" +          // nla_type = CTA_TIMEOUT
103             "000000B4";       // nla_value = 180 (big endian)
104     public static final byte[] CT_V4UPDATE_UDP_BYTES =
105             HexEncoding.decode(CT_V4UPDATE_UDP_HEX.replaceAll(" ", "").toCharArray(), false);
106 
107     @Test
testConntrackIPv4TcpTimeoutUpdate()108     public void testConntrackIPv4TcpTimeoutUpdate() throws Exception {
109         assumeTrue(USING_LE);
110 
111         final byte[] tcp = ConntrackMessage.newIPv4TimeoutUpdateRequest(
112                 OsConstants.IPPROTO_TCP,
113                 (Inet4Address) InetAddress.getByName("192.168.43.209"), 44333,
114                 (Inet4Address) InetAddress.getByName("23.211.13.26"), 443,
115                 432000);
116         assertArrayEquals(CT_V4UPDATE_TCP_BYTES, tcp);
117     }
118 
119     @Test
testConntrackIPv4UdpTimeoutUpdate()120     public void testConntrackIPv4UdpTimeoutUpdate() throws Exception {
121         assumeTrue(USING_LE);
122 
123         final byte[] udp = ConntrackMessage.newIPv4TimeoutUpdateRequest(
124                 OsConstants.IPPROTO_UDP,
125                 (Inet4Address) InetAddress.getByName("100.96.167.146"), 37069,
126                 (Inet4Address) InetAddress.getByName("216.58.197.10"), 443,
127                 180);
128         assertArrayEquals(CT_V4UPDATE_UDP_BYTES, udp);
129     }
130 }
131