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
17package android.net.netlink;
18
19import static org.junit.Assert.assertArrayEquals;
20import static org.junit.Assume.assumeTrue;
21
22import android.system.OsConstants;
23import libcore.util.HexEncoding;
24
25import android.support.test.filters.SmallTest;
26import android.support.test.runner.AndroidJUnit4;
27import org.junit.runner.RunWith;
28import org.junit.Test;
29
30import java.net.Inet4Address;
31import java.net.InetAddress;
32import java.nio.ByteBuffer;
33import java.nio.ByteOrder;
34import java.util.Arrays;
35
36
37@RunWith(AndroidJUnit4.class)
38@SmallTest
39public class ConntrackMessageTest {
40    private static final boolean USING_LE = (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN);
41
42    // Example 1: TCP (192.168.43.209, 44333) -> (23.211.13.26, 443)
43    public static final String CT_V4UPDATE_TCP_HEX =
44            // struct nlmsghdr
45            "50000000" +      // length = 80
46            "0001" +          // type = (1 << 8) | 0
47            "0501" +          // flags
48            "01000000" +      // seqno = 1
49            "00000000" +      // pid = 0
50            // struct nfgenmsg
51            "02" +            // nfgen_family  = AF_INET
52            "00" +            // version = NFNETLINK_V0
53            "0000" +          // res_id
54            // struct nlattr
55            "3400" +          // nla_len = 52
56            "0180" +          // nla_type = nested CTA_TUPLE_ORIG
57                // struct nlattr
58                "1400" +      // nla_len = 20
59                "0180" +      // nla_type = nested CTA_TUPLE_IP
60                    "0800 0100 C0A82BD1" +  // nla_type=CTA_IP_V4_SRC, ip=192.168.43.209
61                    "0800 0200 17D30D1A" +  // nla_type=CTA_IP_V4_DST, ip=23.211.13.26
62                // struct nlattr
63                "1C00" +      // nla_len = 28
64                "0280" +      // nla_type = nested CTA_TUPLE_PROTO
65                    "0500 0100 06 000000" +  // nla_type=CTA_PROTO_NUM, proto=6
66                    "0600 0200 AD2D 0000" +  // nla_type=CTA_PROTO_SRC_PORT, port=44333 (big endian)
67                    "0600 0300 01BB 0000" +  // nla_type=CTA_PROTO_DST_PORT, port=443 (big endian)
68            // struct nlattr
69            "0800" +          // nla_len = 8
70            "0700" +          // nla_type = CTA_TIMEOUT
71            "00069780";       // nla_value = 432000 (big endian)
72    public static final byte[] CT_V4UPDATE_TCP_BYTES =
73            HexEncoding.decode(CT_V4UPDATE_TCP_HEX.replaceAll(" ", "").toCharArray(), false);
74
75    // Example 2: UDP (100.96.167.146, 37069) -> (216.58.197.10, 443)
76    public static final String CT_V4UPDATE_UDP_HEX =
77            // struct nlmsghdr
78            "50000000" +      // length = 80
79            "0001" +          // type = (1 << 8) | 0
80            "0501" +          // flags
81            "01000000" +      // seqno = 1
82            "00000000" +      // pid = 0
83            // struct nfgenmsg
84            "02" +            // nfgen_family  = AF_INET
85            "00" +            // version = NFNETLINK_V0
86            "0000" +          // res_id
87            // struct nlattr
88            "3400" +          // nla_len = 52
89            "0180" +          // nla_type = nested CTA_TUPLE_ORIG
90                // struct nlattr
91                "1400" +      // nla_len = 20
92                "0180" +      // nla_type = nested CTA_TUPLE_IP
93                    "0800 0100 6460A792" +  // nla_type=CTA_IP_V4_SRC, ip=100.96.167.146
94                    "0800 0200 D83AC50A" +  // nla_type=CTA_IP_V4_DST, ip=216.58.197.10
95                // struct nlattr
96                "1C00" +      // nla_len = 28
97                "0280" +      // nla_type = nested CTA_TUPLE_PROTO
98                    "0500 0100 11 000000" +  // nla_type=CTA_PROTO_NUM, proto=17
99                    "0600 0200 90CD 0000" +  // nla_type=CTA_PROTO_SRC_PORT, port=37069 (big endian)
100                    "0600 0300 01BB 0000" +  // nla_type=CTA_PROTO_DST_PORT, port=443 (big endian)
101            // struct nlattr
102            "0800" +          // nla_len = 8
103            "0700" +          // nla_type = CTA_TIMEOUT
104            "000000B4";       // nla_value = 180 (big endian)
105    public static final byte[] CT_V4UPDATE_UDP_BYTES =
106            HexEncoding.decode(CT_V4UPDATE_UDP_HEX.replaceAll(" ", "").toCharArray(), false);
107
108    @Test
109    public void testConntrackIPv4TcpTimeoutUpdate() throws Exception {
110        assumeTrue(USING_LE);
111
112        final byte[] tcp = ConntrackMessage.newIPv4TimeoutUpdateRequest(
113                OsConstants.IPPROTO_TCP,
114                (Inet4Address) InetAddress.getByName("192.168.43.209"), 44333,
115                (Inet4Address) InetAddress.getByName("23.211.13.26"), 443,
116                432000);
117        assertArrayEquals(CT_V4UPDATE_TCP_BYTES, tcp);
118    }
119
120    @Test
121    public void testConntrackIPv4UdpTimeoutUpdate() throws Exception {
122        assumeTrue(USING_LE);
123
124        final byte[] udp = ConntrackMessage.newIPv4TimeoutUpdateRequest(
125                OsConstants.IPPROTO_UDP,
126                (Inet4Address) InetAddress.getByName("100.96.167.146"), 37069,
127                (Inet4Address) InetAddress.getByName("216.58.197.10"), 443,
128                180);
129        assertArrayEquals(CT_V4UPDATE_UDP_BYTES, udp);
130    }
131}
132