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.NetlinkSocket;
206193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.RtNetlinkNeighborMessage;
216193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.StructNdMsg;
226193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.net.netlink.StructNlMsgHdr;
23fa8a6f6220d1a0027ba7969c2d3f72690ddc6495Hugo Benichiimport android.test.suitebuilder.annotation.SmallTest;
246193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.system.ErrnoException;
256193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.system.NetlinkSocketAddress;
266193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.system.OsConstants;
276193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport android.util.Log;
286193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport java.io.InterruptedIOException;
296193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport java.nio.ByteBuffer;
306193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport java.nio.ByteOrder;
316193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klineimport junit.framework.TestCase;
326193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
336193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
346193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Klinepublic class NetlinkSocketTest extends TestCase {
356193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline    private final String TAG = "NetlinkSocketTest";
366193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
37fa8a6f6220d1a0027ba7969c2d3f72690ddc6495Hugo Benichi    @SmallTest
386193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline    public void testBasicWorkingGetNeighborsQuery() throws Exception {
396193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
406193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertNotNull(s);
416193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
426193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        s.connectToKernel();
436193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
446193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        NetlinkSocketAddress localAddr = s.getLocalAddress();
456193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertNotNull(localAddr);
466193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(0, localAddr.getGroupsMask());
476193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertTrue(0 != localAddr.getPortId());
486193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
496193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        final int TEST_SEQNO = 5;
506193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        final byte[] request = RtNetlinkNeighborMessage.newGetNeighborsRequest(TEST_SEQNO);
516193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertNotNull(request);
526193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
536193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        final long TIMEOUT = 500;
546193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertTrue(s.sendMessage(request, 0, request.length, TIMEOUT));
556193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
566193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        int neighMessageCount = 0;
576193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        int doneMessageCount = 0;
586193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
596193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        while (doneMessageCount == 0) {
606193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            ByteBuffer response = null;
616193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            response = s.recvMessage(TIMEOUT);
626193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            assertNotNull(response);
636193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            assertTrue(StructNlMsgHdr.STRUCT_SIZE <= response.limit());
646193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            assertEquals(0, response.position());
656193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            assertEquals(ByteOrder.nativeOrder(), response.order());
666193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
676193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            // Verify the messages at least appears minimally reasonable.
686193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            while (response.remaining() > 0) {
696193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline                final NetlinkMessage msg = NetlinkMessage.parse(response);
706193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline                assertNotNull(msg);
716193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline                final StructNlMsgHdr hdr = msg.getHeader();
726193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline                assertNotNull(hdr);
736193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
746193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline                if (hdr.nlmsg_type == NetlinkConstants.NLMSG_DONE) {
756193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline                    doneMessageCount++;
766193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline                    continue;
776193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline                }
786193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
796193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline                assertEquals(NetlinkConstants.RTM_NEWNEIGH, hdr.nlmsg_type);
806193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline                assertTrue(msg instanceof RtNetlinkNeighborMessage);
816193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline                assertTrue((hdr.nlmsg_flags & StructNlMsgHdr.NLM_F_MULTI) != 0);
826193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline                assertEquals(TEST_SEQNO, hdr.nlmsg_seq);
836193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline                assertEquals(localAddr.getPortId(), hdr.nlmsg_pid);
846193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
856193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline                neighMessageCount++;
866193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline            }
876193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        }
886193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
896193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertEquals(1, doneMessageCount);
906193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        // TODO: make sure this test passes sanely in airplane mode.
916193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        assertTrue(neighMessageCount > 0);
926193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline
936193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline        s.close();
946193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline    }
95abd3142dcae02026689b939c363329b822b7cc0aErik Kline
96fa8a6f6220d1a0027ba7969c2d3f72690ddc6495Hugo Benichi    @SmallTest
97abd3142dcae02026689b939c363329b822b7cc0aErik Kline    public void testRepeatedCloseCallsAreQuiet() throws Exception {
98abd3142dcae02026689b939c363329b822b7cc0aErik Kline        // Create a working NetlinkSocket.
99abd3142dcae02026689b939c363329b822b7cc0aErik Kline        NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
100abd3142dcae02026689b939c363329b822b7cc0aErik Kline        assertNotNull(s);
101abd3142dcae02026689b939c363329b822b7cc0aErik Kline        s.connectToKernel();
102abd3142dcae02026689b939c363329b822b7cc0aErik Kline        NetlinkSocketAddress localAddr = s.getLocalAddress();
103abd3142dcae02026689b939c363329b822b7cc0aErik Kline        assertNotNull(localAddr);
104abd3142dcae02026689b939c363329b822b7cc0aErik Kline        assertEquals(0, localAddr.getGroupsMask());
105abd3142dcae02026689b939c363329b822b7cc0aErik Kline        assertTrue(0 != localAddr.getPortId());
106abd3142dcae02026689b939c363329b822b7cc0aErik Kline        // Close once.
107abd3142dcae02026689b939c363329b822b7cc0aErik Kline        s.close();
108abd3142dcae02026689b939c363329b822b7cc0aErik Kline        // Test that it is closed.
109abd3142dcae02026689b939c363329b822b7cc0aErik Kline        boolean expectedErrorSeen = false;
110abd3142dcae02026689b939c363329b822b7cc0aErik Kline        try {
111abd3142dcae02026689b939c363329b822b7cc0aErik Kline            localAddr = s.getLocalAddress();
112abd3142dcae02026689b939c363329b822b7cc0aErik Kline        } catch (ErrnoException e) {
113abd3142dcae02026689b939c363329b822b7cc0aErik Kline            expectedErrorSeen = true;
114abd3142dcae02026689b939c363329b822b7cc0aErik Kline        }
115abd3142dcae02026689b939c363329b822b7cc0aErik Kline        assertTrue(expectedErrorSeen);
116abd3142dcae02026689b939c363329b822b7cc0aErik Kline        // Close once more.
117abd3142dcae02026689b939c363329b822b7cc0aErik Kline        s.close();
118abd3142dcae02026689b939c363329b822b7cc0aErik Kline    }
1196193aa3305bc2aa5b7f0a983f4b08c99065cfb82Erik Kline}
120