16193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline/*
26193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * Copyright (C) 2015 The Android Open Source Project
36193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline *
46193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * Licensed under the Apache License, Version 2.0 (the "License");
56193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * you may not use this file except in compliance with the License.
66193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * You may obtain a copy of the License at
76193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline *
86193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline *      http://www.apache.org/licenses/LICENSE-2.0
96193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline *
106193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * Unless required by applicable law or agreed to in writing, software
116193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * distributed under the License is distributed on an "AS IS" BASIS,
126193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * See the License for the specific language governing permissions and
146193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline * limitations under the License.
156193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline */
166193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
176193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klinepackage android.net.netlink;
186193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
196193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.NetlinkConstants;
206193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.NetlinkMessage;
216193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.RtNetlinkNeighborMessage;
226193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.StructNdMsg;
236193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.StructNlMsgHdr;
24fa8a6f6220d1a0027ba7969c2d3f72690ddc6495Hugo Benichiimport android.test.suitebuilder.annotation.SmallTest;
256193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.system.OsConstants;
266193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.util.Log;
276193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport libcore.util.HexEncoding;
286193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
299ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Klineimport java.net.Inet4Address;
30fa8a6f6220d1a0027ba7969c2d3f72690ddc6495Hugo Benichiimport java.net.InetAddress;
316193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport java.net.UnknownHostException;
326193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport java.nio.ByteBuffer;
336193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport java.nio.ByteOrder;
349ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Klineimport java.util.Arrays;
356193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport junit.framework.TestCase;
366193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
376193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
386193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klinepublic class RtNetlinkNeighborMessageTest extends TestCase {
396193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline    private final String TAG = "RtNetlinkNeighborMessageTest";
406193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
416193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline    // Hexadecimal representation of packet capture.
426193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline    public static final String RTM_DELNEIGH_HEX =
436193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            // struct nlmsghdr
446193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "4c000000" +     // length = 76
456193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "1d00" +         // type = 29 (RTM_DELNEIGH)
466193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0000" +         // flags
476193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "00000000" +     // seqno
486193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "00000000" +     // pid (0 == kernel)
496193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            // struct ndmsg
506193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "02" +           // family
516193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "00" +           // pad1
526193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0000" +         // pad2
536193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "15000000" +     // interface index (21  == wlan0, on test device)
546193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0400" +         // NUD state (0x04 == NUD_STALE)
556193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "00" +           // flags
566193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "01" +           // type
576193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            // struct nlattr: NDA_DST
586193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0800" +         // length = 8
596193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0100" +         // type (1 == NDA_DST, for neighbor messages)
606193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "c0a89ffe" +     // IPv4 address (== 192.168.159.254)
616193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            // struct nlattr: NDA_LLADDR
626193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0a00" +         // length = 10
636193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0200" +         // type (2 == NDA_LLADDR, for neighbor messages)
646193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "00005e000164" + // MAC Address (== 00:00:5e:00:01:64)
656193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0000" +         // padding, for 4 byte alignment
666193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            // struct nlattr: NDA_PROBES
676193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0800" +         // length = 8
686193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0400" +         // type (4 == NDA_PROBES, for neighbor messages)
696193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "01000000" +     // number of probes
706193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            // struct nlattr: NDA_CACHEINFO
716193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "1400" +         // length = 20
726193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0300" +         // type (3 == NDA_CACHEINFO, for neighbor messages)
736193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "05190000" +     // ndm_used, as "clock ticks ago"
746193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "05190000" +     // ndm_confirmed, as "clock ticks ago"
756193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "190d0000" +     // ndm_updated, as "clock ticks ago"
766193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "00000000";      // ndm_refcnt
776193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline    public static final byte[] RTM_DELNEIGH =
786193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            HexEncoding.decode(RTM_DELNEIGH_HEX.toCharArray(), false);
796193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
806193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline    // Hexadecimal representation of packet capture.
816193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline    public static final String RTM_NEWNEIGH_HEX =
826193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            // struct nlmsghdr
836193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "58000000" +     // length = 88
846193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "1c00" +         // type = 28 (RTM_NEWNEIGH)
856193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0000" +         // flags
866193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "00000000" +     // seqno
876193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "00000000" +     // pid (0 == kernel)
886193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            // struct ndmsg
896193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0a" +           // family
906193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "00" +           // pad1
916193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0000" +         // pad2
926193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "15000000" +     // interface index (21  == wlan0, on test device)
936193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0400" +         // NUD state (0x04 == NUD_STALE)
946193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "80" +           // flags
956193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "01" +           // type
966193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            // struct nlattr: NDA_DST
976193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "1400" +         // length = 20
986193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0100" +         // type (1 == NDA_DST, for neighbor messages)
996193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "fe8000000000000086c9b2fffe6aed4b" + // IPv6 address (== fe80::86c9:b2ff:fe6a:ed4b)
1006193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            // struct nlattr: NDA_LLADDR
1016193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0a00" +         // length = 10
1026193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0200" +         // type (2 == NDA_LLADDR, for neighbor messages)
1036193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "84c9b26aed4b" + // MAC Address (== 84:c9:b2:6a:ed:4b)
1046193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0000" +         // padding, for 4 byte alignment
1056193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            // struct nlattr: NDA_PROBES
1066193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0800" +         // length = 8
1076193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0400" +         // type (4 == NDA_PROBES, for neighbor messages)
1086193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "01000000" +     // number of probes
1096193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            // struct nlattr: NDA_CACHEINFO
1106193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "1400" +         // length = 20
1116193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "0300" +         // type (3 == NDA_CACHEINFO, for neighbor messages)
1126193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "eb0e0000" +     // ndm_used, as "clock ticks ago"
1136193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "861f0000" +     // ndm_confirmed, as "clock ticks ago"
1146193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "00000000" +     // ndm_updated, as "clock ticks ago"
1156193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "05000000";      // ndm_refcnt
1166193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline    public static final byte[] RTM_NEWNEIGH =
1176193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            HexEncoding.decode(RTM_NEWNEIGH_HEX.toCharArray(), false);
1186193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
1196193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline    // An example of the full response from an RTM_GETNEIGH query.
1206193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline    private static final String RTM_GETNEIGH_RESPONSE_HEX =
1216193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            // <-- struct nlmsghr             -->|<-- struct ndmsg           -->|<-- struct nlattr: NDA_DST             -->|<-- NDA_LLADDR          -->|<-- NDA_PROBES -->|<-- NDA_CACHEINFO                         -->|
1226193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "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" +
1236193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "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" +
1246193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "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" +
1256193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "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" +
1266193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "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" +
1276193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "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" +
1286193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "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" +
1296193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "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" +
1306193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "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" +
1316193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "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" +
1326193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "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" +
1336193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "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" +
1346193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "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" +
1356193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            "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";
1366193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline    public static final byte[] RTM_GETNEIGH_RESPONSE =
1376193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            HexEncoding.decode(RTM_GETNEIGH_RESPONSE_HEX.replaceAll(" ", "").toCharArray(), false);
1386193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
139fa8a6f6220d1a0027ba7969c2d3f72690ddc6495Hugo Benichi    @SmallTest
1409ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline    public void testParseRtmDelNeigh() {
1416193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_DELNEIGH);
1426193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
1436193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
1446193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertNotNull(msg);
1456193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertTrue(msg instanceof RtNetlinkNeighborMessage);
1466193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg;
1476193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
1486193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        final StructNlMsgHdr hdr = neighMsg.getHeader();
1496193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertNotNull(hdr);
1506193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(76, hdr.nlmsg_len);
1516193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(NetlinkConstants.RTM_DELNEIGH, hdr.nlmsg_type);
1526193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(0, hdr.nlmsg_flags);
1536193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(0, hdr.nlmsg_seq);
1546193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(0, hdr.nlmsg_pid);
1556193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
1566193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        final StructNdMsg ndmsgHdr = neighMsg.getNdHeader();
1576193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertNotNull(ndmsgHdr);
1586193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals((byte) OsConstants.AF_INET, ndmsgHdr.ndm_family);
1596193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(21, ndmsgHdr.ndm_ifindex);
1606193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(StructNdMsg.NUD_STALE, ndmsgHdr.ndm_state);
1616193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        final InetAddress destination = neighMsg.getDestination();
1626193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertNotNull(destination);
1636193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(InetAddress.parseNumericAddress("192.168.159.254"), destination);
1646193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline    }
1656193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
166fa8a6f6220d1a0027ba7969c2d3f72690ddc6495Hugo Benichi    @SmallTest
1679ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline    public void testParseRtmNewNeigh() {
1686193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_NEWNEIGH);
1696193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
1706193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
1716193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertNotNull(msg);
1726193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertTrue(msg instanceof RtNetlinkNeighborMessage);
1736193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg;
1746193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
1756193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        final StructNlMsgHdr hdr = neighMsg.getHeader();
1766193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertNotNull(hdr);
1776193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(88, hdr.nlmsg_len);
1786193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type);
1796193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(0, hdr.nlmsg_flags);
1806193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(0, hdr.nlmsg_seq);
1816193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(0, hdr.nlmsg_pid);
1826193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
1836193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        final StructNdMsg ndmsgHdr = neighMsg.getNdHeader();
1846193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertNotNull(ndmsgHdr);
1856193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals((byte) OsConstants.AF_INET6, ndmsgHdr.ndm_family);
1866193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(21, ndmsgHdr.ndm_ifindex);
1876193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(StructNdMsg.NUD_STALE, ndmsgHdr.ndm_state);
1886193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        final InetAddress destination = neighMsg.getDestination();
1896193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertNotNull(destination);
1906193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(InetAddress.parseNumericAddress("fe80::86c9:b2ff:fe6a:ed4b"), destination);
1916193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline    }
1926193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
193fa8a6f6220d1a0027ba7969c2d3f72690ddc6495Hugo Benichi    @SmallTest
1949ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline    public void testParseRtmGetNeighResponse() {
1956193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_GETNEIGH_RESPONSE);
1966193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);  // For testing.
1976193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
1986193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        int messageCount = 0;
1996193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        while (byteBuffer.remaining() > 0) {
2006193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            final NetlinkMessage msg = NetlinkMessage.parse(byteBuffer);
2016193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            assertNotNull(msg);
2026193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            assertTrue(msg instanceof RtNetlinkNeighborMessage);
2036193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            final RtNetlinkNeighborMessage neighMsg = (RtNetlinkNeighborMessage) msg;
2046193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
2056193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            final StructNlMsgHdr hdr = neighMsg.getHeader();
2066193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            assertNotNull(hdr);
2076193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type);
2086193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            assertEquals(StructNlMsgHdr.NLM_F_MULTI, hdr.nlmsg_flags);
2096193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            assertEquals(0, hdr.nlmsg_seq);
2106193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            assertEquals(11070, hdr.nlmsg_pid);
2116193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
2126193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            messageCount++;
2136193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        }
2146193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        // TODO: add more detailed spot checks.
2156193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(14, messageCount);
2166193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline    }
2179ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline
218fa8a6f6220d1a0027ba7969c2d3f72690ddc6495Hugo Benichi    @SmallTest
2199ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline    public void testCreateRtmNewNeighMessage() {
2209ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline        final int seqNo = 2635;
2219ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline        final int ifIndex = 14;
2229ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline        final byte[] llAddr =
2239ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                new byte[] { (byte) 1, (byte) 2, (byte) 3, (byte) 4, (byte) 5, (byte) 6 };
2249ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline
2259ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline        // Hexadecimal representation of our created packet.
2269ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline        final String expectedNewNeighHex =
2279ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                // struct nlmsghdr
2289ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "30000000" +     // length = 48
2299ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "1c00" +         // type = 28 (RTM_NEWNEIGH)
230cef7bc939fbc3baae5ccf78dcef63fc60e07ae21Erik Kline                "0501" +         // flags (NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE)
2319ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "4b0a0000" +     // seqno
2329ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "00000000" +     // pid (0 == kernel)
2339ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                // struct ndmsg
2349ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "02" +           // family
2359ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "00" +           // pad1
2369ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "0000" +         // pad2
2379ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "0e000000" +     // interface index (14)
2389ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "0800" +         // NUD state (0x08 == NUD_DELAY)
2399ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "00" +           // flags
2409ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "00" +           // type
2419ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                // struct nlattr: NDA_DST
2429ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "0800" +         // length = 8
2439ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "0100" +         // type (1 == NDA_DST, for neighbor messages)
2449ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "7f000001" +     // IPv4 address (== 127.0.0.1)
2459ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                // struct nlattr: NDA_LLADDR
2469ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "0a00" +         // length = 10
2479ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "0200" +         // type (2 == NDA_LLADDR, for neighbor messages)
2489ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "010203040506" + // MAC Address (== 01:02:03:04:05:06)
2499ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                "0000";          // padding, for 4 byte alignment
2509ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline        final byte[] expectedNewNeigh =
2519ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                HexEncoding.decode(expectedNewNeighHex.toCharArray(), false);
2529ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline
2539ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline        final byte[] bytes = RtNetlinkNeighborMessage.newNewNeighborMessage(
2549ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline            seqNo, Inet4Address.LOOPBACK, StructNdMsg.NUD_DELAY, ifIndex, llAddr);
2559ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline        if (!Arrays.equals(expectedNewNeigh, bytes)) {
2569ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline            assertEquals(expectedNewNeigh.length, bytes.length);
2579ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline            for (int i = 0; i < Math.min(expectedNewNeigh.length, bytes.length); i++) {
2589ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline                assertEquals(expectedNewNeigh[i], bytes[i]);
2599ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline            }
2609ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline        }
2619ce5d602cd5d732ae10efe0b648b43ddf60d65c9Erik Kline    }
2626193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline}
263