blob: 19ee00036b612328b5b19f2a0ca1f79ffa08c354 [file] [log] [blame]
Erik Kline6193aa32015-01-20 12:28:26 +09001/*
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;
Erik Kline9ce5d602015-05-16 21:10:29 +090029import java.net.Inet4Address;
Erik Kline6193aa32015-01-20 12:28:26 +090030import java.net.UnknownHostException;
31import java.nio.ByteBuffer;
32import java.nio.ByteOrder;
Erik Kline9ce5d602015-05-16 21:10:29 +090033import java.util.Arrays;
Erik Kline6193aa32015-01-20 12:28:26 +090034import junit.framework.TestCase;
35
36
37public class RtNetlinkNeighborMessageTest extends TestCase {
38 private final String TAG = "RtNetlinkNeighborMessageTest";
39
40 // Hexadecimal representation of packet capture.
41 public static final String RTM_DELNEIGH_HEX =
42 // struct nlmsghdr
43 "4c000000" + // length = 76
44 "1d00" + // type = 29 (RTM_DELNEIGH)
45 "0000" + // flags
46 "00000000" + // seqno
47 "00000000" + // pid (0 == kernel)
48 // struct ndmsg
49 "02" + // family
50 "00" + // pad1
51 "0000" + // pad2
52 "15000000" + // interface index (21 == wlan0, on test device)
53 "0400" + // NUD state (0x04 == NUD_STALE)
54 "00" + // flags
55 "01" + // type
56 // struct nlattr: NDA_DST
57 "0800" + // length = 8
58 "0100" + // type (1 == NDA_DST, for neighbor messages)
59 "c0a89ffe" + // IPv4 address (== 192.168.159.254)
60 // struct nlattr: NDA_LLADDR
61 "0a00" + // length = 10
62 "0200" + // type (2 == NDA_LLADDR, for neighbor messages)
63 "00005e000164" + // MAC Address (== 00:00:5e:00:01:64)
64 "0000" + // padding, for 4 byte alignment
65 // struct nlattr: NDA_PROBES
66 "0800" + // length = 8
67 "0400" + // type (4 == NDA_PROBES, for neighbor messages)
68 "01000000" + // number of probes
69 // struct nlattr: NDA_CACHEINFO
70 "1400" + // length = 20
71 "0300" + // type (3 == NDA_CACHEINFO, for neighbor messages)
72 "05190000" + // ndm_used, as "clock ticks ago"
73 "05190000" + // ndm_confirmed, as "clock ticks ago"
74 "190d0000" + // ndm_updated, as "clock ticks ago"
75 "00000000"; // ndm_refcnt
76 public static final byte[] RTM_DELNEIGH =
77 HexEncoding.decode(RTM_DELNEIGH_HEX.toCharArray(), false);
78
79 // Hexadecimal representation of packet capture.
80 public static final String RTM_NEWNEIGH_HEX =
81 // struct nlmsghdr
82 "58000000" + // length = 88
83 "1c00" + // type = 28 (RTM_NEWNEIGH)
84 "0000" + // flags
85 "00000000" + // seqno
86 "00000000" + // pid (0 == kernel)
87 // struct ndmsg
88 "0a" + // family
89 "00" + // pad1
90 "0000" + // pad2
91 "15000000" + // interface index (21 == wlan0, on test device)
92 "0400" + // NUD state (0x04 == NUD_STALE)
93 "80" + // flags
94 "01" + // type
95 // struct nlattr: NDA_DST
96 "1400" + // length = 20
97 "0100" + // type (1 == NDA_DST, for neighbor messages)
98 "fe8000000000000086c9b2fffe6aed4b" + // IPv6 address (== fe80::86c9:b2ff:fe6a:ed4b)
99 // struct nlattr: NDA_LLADDR
100 "0a00" + // length = 10
101 "0200" + // type (2 == NDA_LLADDR, for neighbor messages)
102 "84c9b26aed4b" + // MAC Address (== 84:c9:b2:6a:ed:4b)
103 "0000" + // padding, for 4 byte alignment
104 // struct nlattr: NDA_PROBES
105 "0800" + // length = 8
106 "0400" + // type (4 == NDA_PROBES, for neighbor messages)
107 "01000000" + // number of probes
108 // struct nlattr: NDA_CACHEINFO
109 "1400" + // length = 20
110 "0300" + // type (3 == NDA_CACHEINFO, for neighbor messages)
111 "eb0e0000" + // ndm_used, as "clock ticks ago"
112 "861f0000" + // ndm_confirmed, as "clock ticks ago"
113 "00000000" + // ndm_updated, as "clock ticks ago"
114 "05000000"; // ndm_refcnt
115 public static final byte[] RTM_NEWNEIGH =
116 HexEncoding.decode(RTM_NEWNEIGH_HEX.toCharArray(), false);
117
118 // An example of the full response from an RTM_GETNEIGH query.
119 private static final String RTM_GETNEIGH_RESPONSE_HEX =
120 // <-- struct nlmsghr -->|<-- struct ndmsg -->|<-- struct nlattr: NDA_DST -->|<-- NDA_LLADDR -->|<-- NDA_PROBES -->|<-- NDA_CACHEINFO -->|
121 "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" +
122 "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" +
123 "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" +
124 "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" +
125 "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" +
126 "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" +
127 "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" +
128 "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" +
129 "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" +
130 "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" +
131 "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" +
132 "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" +
133 "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" +
134 "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";
135 public static final byte[] RTM_GETNEIGH_RESPONSE =
136 HexEncoding.decode(RTM_GETNEIGH_RESPONSE_HEX.replaceAll(" ", "").toCharArray(), false);
137
Erik Kline9ce5d602015-05-16 21:10:29 +0900138 public void testParseRtmDelNeigh() {
Erik Kline6193aa32015-01-20 12:28:26 +0900139 final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_DELNEIGH);
140 byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
141 final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
142 assertNotNull(msg);
143 assertTrue(msg instanceof RtNetlinkNeighborMessage);
144 final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg;
145
146 final StructNlMsgHdr hdr = neighMsg.getHeader();
147 assertNotNull(hdr);
148 assertEquals(76, hdr.nlmsg_len);
149 assertEquals(NetlinkConstants.RTM_DELNEIGH, hdr.nlmsg_type);
150 assertEquals(0, hdr.nlmsg_flags);
151 assertEquals(0, hdr.nlmsg_seq);
152 assertEquals(0, hdr.nlmsg_pid);
153
154 final StructNdMsg ndmsgHdr = neighMsg.getNdHeader();
155 assertNotNull(ndmsgHdr);
156 assertEquals((byte) OsConstants.AF_INET, ndmsgHdr.ndm_family);
157 assertEquals(21, ndmsgHdr.ndm_ifindex);
158 assertEquals(StructNdMsg.NUD_STALE, ndmsgHdr.ndm_state);
159 final InetAddress destination = neighMsg.getDestination();
160 assertNotNull(destination);
161 assertEquals(InetAddress.parseNumericAddress("192.168.159.254"), destination);
162 }
163
Erik Kline9ce5d602015-05-16 21:10:29 +0900164 public void testParseRtmNewNeigh() {
Erik Kline6193aa32015-01-20 12:28:26 +0900165 final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_NEWNEIGH);
166 byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
167 final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
168 assertNotNull(msg);
169 assertTrue(msg instanceof RtNetlinkNeighborMessage);
170 final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg;
171
172 final StructNlMsgHdr hdr = neighMsg.getHeader();
173 assertNotNull(hdr);
174 assertEquals(88, hdr.nlmsg_len);
175 assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type);
176 assertEquals(0, hdr.nlmsg_flags);
177 assertEquals(0, hdr.nlmsg_seq);
178 assertEquals(0, hdr.nlmsg_pid);
179
180 final StructNdMsg ndmsgHdr = neighMsg.getNdHeader();
181 assertNotNull(ndmsgHdr);
182 assertEquals((byte) OsConstants.AF_INET6, ndmsgHdr.ndm_family);
183 assertEquals(21, ndmsgHdr.ndm_ifindex);
184 assertEquals(StructNdMsg.NUD_STALE, ndmsgHdr.ndm_state);
185 final InetAddress destination = neighMsg.getDestination();
186 assertNotNull(destination);
187 assertEquals(InetAddress.parseNumericAddress("fe80::86c9:b2ff:fe6a:ed4b"), destination);
188 }
189
Erik Kline9ce5d602015-05-16 21:10:29 +0900190 public void testParseRtmGetNeighResponse() {
Erik Kline6193aa32015-01-20 12:28:26 +0900191 final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_GETNEIGH_RESPONSE);
192 byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
193
194 int messageCount = 0;
195 while (byteBuffer.remaining() > 0) {
196 final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
197 assertNotNull(msg);
198 assertTrue(msg instanceof RtNetlinkNeighborMessage);
199 final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg;
200
201 final StructNlMsgHdr hdr = neighMsg.getHeader();
202 assertNotNull(hdr);
203 assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type);
204 assertEquals(StructNlMsgHdr.NLM_F_MULTI, hdr.nlmsg_flags);
205 assertEquals(0, hdr.nlmsg_seq);
206 assertEquals(11070, hdr.nlmsg_pid);
207
208 messageCount++;
209 }
210 // TODO: add more detailed spot checks.
211 assertEquals(14, messageCount);
212 }
Erik Kline9ce5d602015-05-16 21:10:29 +0900213
214 public void testCreateRtmNewNeighMessage() {
215 final int seqNo = 2635;
216 final int ifIndex = 14;
217 final byte[] llAddr =
218 new byte[] { (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6 };
219
220 // Hexadecimal representation of our created packet.
221 final String expectedNewNeighHex =
222 // struct nlmsghdr
223 "30000000" + // length = 48
224 "1c00" + // type = 28 (RTM_NEWNEIGH)
Erik Klinecef7bc92015-05-19 14:17:11 +0900225 "0501" + // flags (NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE)
Erik Kline9ce5d602015-05-16 21:10:29 +0900226 "4b0a0000" + // seqno
227 "00000000" + // pid (0 == kernel)
228 // struct ndmsg
229 "02" + // family
230 "00" + // pad1
231 "0000" + // pad2
232 "0e000000" + // interface index (14)
233 "0800" + // NUD state (0x08 == NUD_DELAY)
234 "00" + // flags
235 "00" + // type
236 // struct nlattr: NDA_DST
237 "0800" + // length = 8
238 "0100" + // type (1 == NDA_DST, for neighbor messages)
239 "7f000001" + // IPv4 address (== 127.0.0.1)
240 // struct nlattr: NDA_LLADDR
241 "0a00" + // length = 10
242 "0200" + // type (2 == NDA_LLADDR, for neighbor messages)
243 "010203040506" + // MAC Address (== 01:02:03:04:05:06)
244 "0000"; // padding, for 4 byte alignment
245 final byte[] expectedNewNeigh =
246 HexEncoding.decode(expectedNewNeighHex.toCharArray(), false);
247
248 final byte[] bytes = RtNetlinkNeighborMessage.newNewNeighborMessage(
249 seqNo, Inet4Address.LOOPBACK, StructNdMsg.NUD_DELAY, ifIndex, llAddr);
250 if (!Arrays.equals(expectedNewNeigh, bytes)) {
251 assertEquals(expectedNewNeigh.length, bytes.length);
252 for (int i = 0; i < Math.min(expectedNewNeigh.length, bytes.length); i++) {
253 assertEquals(expectedNewNeigh[i], bytes[i]);
254 }
255 }
256 }
Erik Kline6193aa32015-01-20 12:28:26 +0900257}