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.NetlinkSocket;
20import android.net.netlink.RtNetlinkNeighborMessage;
21import android.net.netlink.StructNdMsg;
22import android.net.netlink.StructNlMsgHdr;
23import android.system.ErrnoException;
24import android.system.NetlinkSocketAddress;
25import android.system.OsConstants;
26import android.util.Log;
27import java.io.InterruptedIOException;
28import java.nio.ByteBuffer;
29import java.nio.ByteOrder;
30import junit.framework.TestCase;
31
32
33public class NetlinkSocketTest extends TestCase {
34    private final String TAG = "NetlinkSocketTest";
35
36    public void testBasicWorkingGetNeighborsQuery() throws Exception {
37        NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
38        assertNotNull(s);
39
40        s.connectToKernel();
41
42        NetlinkSocketAddress localAddr = s.getLocalAddress();
43        assertNotNull(localAddr);
44        assertEquals(0, localAddr.getGroupsMask());
45        assertTrue(0 != localAddr.getPortId());
46
47        final int TEST_SEQNO = 5;
48        final byte[] request = RtNetlinkNeighborMessage.newGetNeighborsRequest(TEST_SEQNO);
49        assertNotNull(request);
50
51        final long TIMEOUT = 500;
52        assertTrue(s.sendMessage(request, 0, request.length, TIMEOUT));
53
54        int neighMessageCount = 0;
55        int doneMessageCount = 0;
56
57        while (doneMessageCount == 0) {
58            ByteBuffer response = null;
59            response = s.recvMessage(TIMEOUT);
60            assertNotNull(response);
61            assertTrue(StructNlMsgHdr.STRUCT_SIZE <= response.limit());
62            assertEquals(0, response.position());
63            assertEquals(ByteOrder.nativeOrder(), response.order());
64
65            // Verify the messages at least appears minimally reasonable.
66            while (response.remaining() > 0) {
67                final NetlinkMessage msg = NetlinkMessage.parse(response);
68                assertNotNull(msg);
69                final StructNlMsgHdr hdr = msg.getHeader();
70                assertNotNull(hdr);
71
72                if (hdr.nlmsg_type == NetlinkConstants.NLMSG_DONE) {
73                    doneMessageCount++;
74                    continue;
75                }
76
77                assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type);
78                assertTrue(msg instanceof RtNetlinkNeighborMessage);
79                assertTrue((hdr.nlmsg_flags & StructNlMsgHdr.NLM_F_MULTI) != 0);
80                assertEquals(TEST_SEQNO, hdr.nlmsg_seq);
81                assertEquals(localAddr.getPortId(), hdr.nlmsg_pid);
82
83                neighMessageCount++;
84            }
85        }
86
87        assertEquals(1, doneMessageCount);
88        // TODO: make sure this test passes sanely in airplane mode.
89        assertTrue(neighMessageCount > 0);
90
91        s.close();
92    }
93
94    public void testRepeatedCloseCallsAreQuiet() throws Exception {
95        // Create a working NetlinkSocket.
96        NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
97        assertNotNull(s);
98        s.connectToKernel();
99        NetlinkSocketAddress localAddr = s.getLocalAddress();
100        assertNotNull(localAddr);
101        assertEquals(0, localAddr.getGroupsMask());
102        assertTrue(0 != localAddr.getPortId());
103        // Close once.
104        s.close();
105        // Test that it is closed.
106        boolean expectedErrorSeen = false;
107        try {
108            localAddr = s.getLocalAddress();
109        } catch (ErrnoException e) {
110            expectedErrorSeen = true;
111        }
112        assertTrue(expectedErrorSeen);
113        // Close once more.
114        s.close();
115    }
116}
117