1 /*
2 * Copyright (C) 2017 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
17 #include <iostream>
18 #include <string>
19
20 #include <fcntl.h>
21
22 #include <android-base/stringprintf.h>
23 #include <android-base/unique_fd.h>
24 #include <gtest/gtest.h>
25 #include <sys/ioctl.h>
26 #include <sys/socket.h>
27 #include <linux/if.h>
28 #include <linux/if_tun.h>
29
30 using std::cout;
31 using std::endl;
32 using std::string;
33 using android::base::StringPrintf;
34 using android::base::unique_fd;
35
36 static const short kTunModes[] = {
37 IFF_TUN,
38 IFF_TAP,
39 };
40
41 class VtsKernelTunTest : public ::testing::TestWithParam<short> {
42 public:
SetUp()43 virtual void SetUp() override {
44 tun_device_ = "/dev/tun";
45 uint32_t num = arc4random_uniform(1000);
46 ifr_name_ = StringPrintf("tun%d", num);
47 }
48
49 // Used to initialize tun device.
50 int TunInit(short flags);
51
52 string tun_device_;
53 string ifr_name_;
54 unique_fd fd_;
55 };
56
TunInit(short mode)57 int VtsKernelTunTest::TunInit(short mode) {
58 struct ifreq ifr = {
59 .ifr_flags = mode,
60 };
61 strncpy(ifr.ifr_name, ifr_name_.c_str(), IFNAMSIZ);
62 int fd = open(tun_device_.c_str(), O_RDWR | O_NONBLOCK);
63 if (fd < 0) {
64 return -1;
65 }
66 if (ioctl(fd, TUNSETIFF, (void *) &ifr) < 0) {
67 close(fd);
68 return -1;
69 }
70 return fd;
71 }
72
73 // Test opening and closing of a tun interface.
TEST_P(VtsKernelTunTest,OpenAndClose)74 TEST_P(VtsKernelTunTest, OpenAndClose) {
75 fd_ = unique_fd(TunInit(GetParam()));
76 ASSERT_TRUE(fd_ >= 0);
77 }
78
79 // Test basic read functionality of a tuen interface.
TEST_P(VtsKernelTunTest,BasicRead)80 TEST_P(VtsKernelTunTest, BasicRead) {
81 fd_ = unique_fd(TunInit(GetParam()));
82 ASSERT_TRUE(fd_ >= 0);
83
84 uint8_t test_output;
85 // Expect no packets available on this interface.
86 ASSERT_TRUE(read(fd_, &test_output, 1) < 0);
87 }
88
89 INSTANTIATE_TEST_CASE_P(Basic, VtsKernelTunTest,
90 ::testing::ValuesIn(kTunModes));
91
main(int argc,char ** argv)92 int main(int argc, char **argv) {
93 ::testing::InitGoogleTest(&argc, argv);
94 return RUN_ALL_TESTS();
95 }
96