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