RtNetlinkNeighborMessageTest.java revision 6193aa3305bc2aa5b7f0a983f4b08c99065cfb82
1/*
2 * Copyright (C) 2015 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 android.net.netlink.NetlinkConstants;
20import android.net.netlink.NetlinkMessage;
21import android.net.netlink.RtNetlinkNeighborMessage;
22import android.net.netlink.StructNdMsg;
23import android.net.netlink.StructNlMsgHdr;
24import android.system.OsConstants;
25import android.util.Log;
26import libcore.util.HexEncoding;
27
28import java.net.InetAddress;
29import java.net.UnknownHostException;
30import java.nio.ByteBuffer;
31import java.nio.ByteOrder;
32import junit.framework.TestCase;
33
34
35public class RtNetlinkNeighborMessageTest extends TestCase {
36    private final String TAG = "RtNetlinkNeighborMessageTest";
37
38    // Hexadecimal representation of packet capture.
39    public static final String RTM_DELNEIGH_HEX =
40            // struct nlmsghdr
41            "4c000000" +     // length = 76
42            "1d00" +         // type = 29 (RTM_DELNEIGH)
43            "0000" +         // flags
44            "00000000" +     // seqno
45            "00000000" +     // pid (0 == kernel)
46            // struct ndmsg
47            "02" +           // family
48            "00" +           // pad1
49            "0000" +         // pad2
50            "15000000" +     // interface index (21  == wlan0, on test device)
51            "0400" +         // NUD state (0x04 == NUD_STALE)
52            "00" +           // flags
53            "01" +           // type
54            // struct nlattr: NDA_DST
55            "0800" +         // length = 8
56            "0100" +         // type (1 == NDA_DST, for neighbor messages)
57            "c0a89ffe" +     // IPv4 address (== 192.168.159.254)
58            // struct nlattr: NDA_LLADDR
59            "0a00" +         // length = 10
60            "0200" +         // type (2 == NDA_LLADDR, for neighbor messages)
61            "00005e000164" + // MAC Address (== 00:00:5e:00:01:64)
62            "0000" +         // padding, for 4 byte alignment
63            // struct nlattr: NDA_PROBES
64            "0800" +         // length = 8
65            "0400" +         // type (4 == NDA_PROBES, for neighbor messages)
66            "01000000" +     // number of probes
67            // struct nlattr: NDA_CACHEINFO
68            "1400" +         // length = 20
69            "0300" +         // type (3 == NDA_CACHEINFO, for neighbor messages)
70            "05190000" +     // ndm_used, as "clock ticks ago"
71            "05190000" +     // ndm_confirmed, as "clock ticks ago"
72            "190d0000" +     // ndm_updated, as "clock ticks ago"
73            "00000000";      // ndm_refcnt
74    public static final byte[] RTM_DELNEIGH =
75            HexEncoding.decode(RTM_DELNEIGH_HEX.toCharArray(), false);
76
77    // Hexadecimal representation of packet capture.
78    public static final String RTM_NEWNEIGH_HEX =
79            // struct nlmsghdr
80            "58000000" +     // length = 88
81            "1c00" +         // type = 28 (RTM_NEWNEIGH)
82            "0000" +         // flags
83            "00000000" +     // seqno
84            "00000000" +     // pid (0 == kernel)
85            // struct ndmsg
86            "0a" +           // family
87            "00" +           // pad1
88            "0000" +         // pad2
89            "15000000" +     // interface index (21  == wlan0, on test device)
90            "0400" +         // NUD state (0x04 == NUD_STALE)
91            "80" +           // flags
92            "01" +           // type
93            // struct nlattr: NDA_DST
94            "1400" +         // length = 20
95            "0100" +         // type (1 == NDA_DST, for neighbor messages)
96            "fe8000000000000086c9b2fffe6aed4b" + // IPv6 address (== fe80::86c9:b2ff:fe6a:ed4b)
97            // struct nlattr: NDA_LLADDR
98            "0a00" +         // length = 10
99            "0200" +         // type (2 == NDA_LLADDR, for neighbor messages)
100            "84c9b26aed4b" + // MAC Address (== 84:c9:b2:6a:ed:4b)
101            "0000" +         // padding, for 4 byte alignment
102            // struct nlattr: NDA_PROBES
103            "0800" +         // length = 8
104            "0400" +         // type (4 == NDA_PROBES, for neighbor messages)
105            "01000000" +     // number of probes
106            // struct nlattr: NDA_CACHEINFO
107            "1400" +         // length = 20
108            "0300" +         // type (3 == NDA_CACHEINFO, for neighbor messages)
109            "eb0e0000" +     // ndm_used, as "clock ticks ago"
110            "861f0000" +     // ndm_confirmed, as "clock ticks ago"
111            "00000000" +     // ndm_updated, as "clock ticks ago"
112            "05000000";      // ndm_refcnt
113    public static final byte[] RTM_NEWNEIGH =
114            HexEncoding.decode(RTM_NEWNEIGH_HEX.toCharArray(), false);
115
116    // An example of the full response from an RTM_GETNEIGH query.
117    private static final String RTM_GETNEIGH_RESPONSE_HEX =
118            // <-- struct nlmsghr             -->|<-- struct ndmsg           -->|<-- struct nlattr: NDA_DST             -->|<-- NDA_LLADDR          -->|<-- NDA_PROBES -->|<-- NDA_CACHEINFO                         -->|
119            "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff020000000000000000000000000001 0a00 0200 333300000001 0000 0800 0400 00000000 1400 0300 a2280000 32110000 32110000 01000000" +
120            "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff0200000000000000000001ff000001 0a00 0200 3333ff000001 0000 0800 0400 00000000 1400 0300 0d280000 9d100000 9d100000 00000000" +
121            "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 0400 80 01 1400 0100 20010db800040ca00000000000000001 0a00 0200 84c9b26aed4b 0000 0800 0400 04000000 1400 0300 90100000 90100000 90080000 01000000" +
122            "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff0200000000000000000001ff47da19 0a00 0200 3333ff47da19 0000 0800 0400 00000000 1400 0300 a1280000 31110000 31110000 01000000" +
123            "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 14000000 4000 00 05 1400 0100 ff020000000000000000000000000016 0a00 0200 333300000016 0000 0800 0400 00000000 1400 0300 912a0000 21130000 21130000 00000000" +
124            "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 14000000 4000 00 05 1400 0100 ff0200000000000000000001ffeace3b 0a00 0200 3333ffeace3b 0000 0800 0400 00000000 1400 0300 922a0000 22130000 22130000 00000000" +
125            "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff0200000000000000000001ff5c2a83 0a00 0200 3333ff5c2a83 0000 0800 0400 00000000 1400 0300 391c0000 c9040000 c9040000 01000000" +
126            "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 01000000 4000 00 02 1400 0100 00000000000000000000000000000000 0a00 0200 000000000000 0000 0800 0400 00000000 1400 0300 cd180200 5d010200 5d010200 08000000" +
127            "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff020000000000000000000000000002 0a00 0200 333300000002 0000 0800 0400 00000000 1400 0300 352a0000 c5120000 c5120000 00000000" +
128            "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff020000000000000000000000000016 0a00 0200 333300000016 0000 0800 0400 00000000 1400 0300 982a0000 28130000 28130000 00000000" +
129            "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 0800 80 01 1400 0100 fe8000000000000086c9b2fffe6aed4b 0a00 0200 84c9b26aed4b 0000 0800 0400 00000000 1400 0300 23000000 24000000 57000000 13000000" +
130            "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 15000000 4000 00 05 1400 0100 ff0200000000000000000001ffeace3b 0a00 0200 3333ffeace3b 0000 0800 0400 00000000 1400 0300 992a0000 29130000 29130000 01000000" +
131            "58000000 1c00 0200 00000000 3e2b0000 0a 00 0000 14000000 4000 00 05 1400 0100 ff020000000000000000000000000002 0a00 0200 333300000002 0000 0800 0400 00000000 1400 0300 2e2a0000 be120000 be120000 00000000" +
132            "44000000 1c00 0200 00000000 3e2b0000 02 00 0000 18000000 4000 00 03 0800 0100 00000000                         0400 0200                   0800 0400 00000000 1400 0300 75280000 05110000 05110000 22000000";
133    public static final byte[] RTM_GETNEIGH_RESPONSE =
134            HexEncoding.decode(RTM_GETNEIGH_RESPONSE_HEX.replaceAll(" ", "").toCharArray(), false);
135
136    public void testParseRtNetlinkNeighborRtmDelNeigh() {
137        final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_DELNEIGH);
138        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
139        final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
140        assertNotNull(msg);
141        assertTrue(msg instanceof RtNetlinkNeighborMessage);
142        final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg;
143
144        final StructNlMsgHdr hdr = neighMsg.getHeader();
145        assertNotNull(hdr);
146        assertEquals(76, hdr.nlmsg_len);
147        assertEquals(NetlinkConstants.RTM_DELNEIGH, hdr.nlmsg_type);
148        assertEquals(0, hdr.nlmsg_flags);
149        assertEquals(0, hdr.nlmsg_seq);
150        assertEquals(0, hdr.nlmsg_pid);
151
152        final StructNdMsg ndmsgHdr = neighMsg.getNdHeader();
153        assertNotNull(ndmsgHdr);
154        assertEquals((byte) OsConstants.AF_INET, ndmsgHdr.ndm_family);
155        assertEquals(21, ndmsgHdr.ndm_ifindex);
156        assertEquals(StructNdMsg.NUD_STALE, ndmsgHdr.ndm_state);
157        final InetAddress destination = neighMsg.getDestination();
158        assertNotNull(destination);
159        assertEquals(InetAddress.parseNumericAddress("192.168.159.254"), destination);
160    }
161
162    public void testParseRtNetlinkNeighborRtmNewNeigh() {
163        final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_NEWNEIGH);
164        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
165        final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
166        assertNotNull(msg);
167        assertTrue(msg instanceof RtNetlinkNeighborMessage);
168        final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg;
169
170        final StructNlMsgHdr hdr = neighMsg.getHeader();
171        assertNotNull(hdr);
172        assertEquals(88, hdr.nlmsg_len);
173        assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type);
174        assertEquals(0, hdr.nlmsg_flags);
175        assertEquals(0, hdr.nlmsg_seq);
176        assertEquals(0, hdr.nlmsg_pid);
177
178        final StructNdMsg ndmsgHdr = neighMsg.getNdHeader();
179        assertNotNull(ndmsgHdr);
180        assertEquals((byte) OsConstants.AF_INET6, ndmsgHdr.ndm_family);
181        assertEquals(21, ndmsgHdr.ndm_ifindex);
182        assertEquals(StructNdMsg.NUD_STALE, ndmsgHdr.ndm_state);
183        final InetAddress destination = neighMsg.getDestination();
184        assertNotNull(destination);
185        assertEquals(InetAddress.parseNumericAddress("fe80::86c9:b2ff:fe6a:ed4b"), destination);
186    }
187
188    public void testParseRtNetlinkNeighborRtmGetNeighResponse() {
189        final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_GETNEIGH_RESPONSE);
190        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
191
192        int messageCount = 0;
193        while (byteBuffer.remaining() > 0) {
194            final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
195            assertNotNull(msg);
196            assertTrue(msg instanceof RtNetlinkNeighborMessage);
197            final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg;
198
199            final StructNlMsgHdr hdr = neighMsg.getHeader();
200            assertNotNull(hdr);
201            assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type);
202            assertEquals(StructNlMsgHdr.NLM_F_MULTI, hdr.nlmsg_flags);
203            assertEquals(0, hdr.nlmsg_seq);
204            assertEquals(11070, hdr.nlmsg_pid);
205
206            messageCount++;
207        }
208        // TODO: add more detailed spot checks.
209        assertEquals(14, messageCount);
210    }
211}
212