blob: cd25898f2b1bea8cd518f55a6dfa088492649af2 [file] [log] [blame]
Peter Qiuc0beca52015-09-03 11:25:46 -07001//
2// Copyright (C) 2013 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//
Ben Chanbac5bc82013-04-12 17:15:43 -070016
17#include "shill/connection_info_reader.h"
18
19#include <netinet/in.h>
20
Ben Chan11c213f2014-09-05 08:21:06 -070021#include <base/files/file_util.h>
Ben Chanbac5bc82013-04-12 17:15:43 -070022#include <base/files/scoped_temp_dir.h>
Ben Chana0ddf462014-02-06 11:32:42 -080023#include <base/strings/stringprintf.h>
Ben Chanbac5bc82013-04-12 17:15:43 -070024#include <gmock/gmock.h>
25#include <gtest/gtest.h>
26
27using base::FilePath;
28using base::ScopedTempDir;
29using base::StringPrintf;
30using std::string;
31using std::vector;
32using testing::Return;
33
34namespace shill {
35
36namespace {
37
38// TODO(benchan): Test IPv6 addresses.
39
Paul Stewart3b30ca52015-06-16 13:13:10 -070040const char* kConnectionInfoLines[] = {
Ben Chanbac5bc82013-04-12 17:15:43 -070041 "udp 17 30 src=192.168.1.1 dst=192.168.1.2 sport=9000 dport=53 "
42 "[UNREPLIED] src=192.168.1.2 dst=192.168.1.1 sport=53 dport=9000 use=2",
43 "tcp 6 299 ESTABLISHED src=192.168.2.1 dst=192.168.2.3 sport=8000 "
44 "dport=7000 src=192.168.2.3 dst=192.168.2.1 sport=7000 dport=8000 [ASSURED] "
45 "use=2",
46};
47
48} // namespace
49
50class ConnectionInfoReaderUnderTest : public ConnectionInfoReader {
51 public:
52 // Mock out GetConnectionInfoFilePath to use a temporary created connection
53 // info file instead of the actual path in procfs (i.e.
54 // /proc/net/ip_conntrack).
Alex Vakulenko8a532292014-06-16 17:18:44 -070055 MOCK_CONST_METHOD0(GetConnectionInfoFilePath, FilePath());
Ben Chanbac5bc82013-04-12 17:15:43 -070056};
57
58class ConnectionInfoReaderTest : public testing::Test {
59 protected:
Paul Stewart3b30ca52015-06-16 13:13:10 -070060 IPAddress StringToIPv4Address(const string& address_string) {
Ben Chanbac5bc82013-04-12 17:15:43 -070061 IPAddress ip_address(IPAddress::kFamilyIPv4);
62 EXPECT_TRUE(ip_address.SetAddressFromString(address_string));
63 return ip_address;
64 }
65
Paul Stewart3b30ca52015-06-16 13:13:10 -070066 IPAddress StringToIPv6Address(const string& address_string) {
Ben Chanbac5bc82013-04-12 17:15:43 -070067 IPAddress ip_address(IPAddress::kFamilyIPv6);
68 EXPECT_TRUE(ip_address.SetAddressFromString(address_string));
69 return ip_address;
70 }
71
Paul Stewart3b30ca52015-06-16 13:13:10 -070072 void CreateConnectionInfoFile(const char** lines, size_t num_lines,
73 const FilePath& dir_path, FilePath* file_path) {
Ben Chana0ddf462014-02-06 11:32:42 -080074 ASSERT_TRUE(base::CreateTemporaryFileInDir(dir_path, file_path));
Ben Chanbac5bc82013-04-12 17:15:43 -070075 for (size_t i = 0; i < num_lines; ++i) {
76 string line = lines[i];
77 line += '\n';
Alex Vakulenko0951ccb2014-12-10 12:52:31 -080078 ASSERT_TRUE(base::AppendToFile(*file_path, line.data(), line.size()));
Ben Chanbac5bc82013-04-12 17:15:43 -070079 }
80 }
81
Paul Stewart3b30ca52015-06-16 13:13:10 -070082 void ExpectConnectionInfoEqual(const ConnectionInfo& info1,
83 const ConnectionInfo& info2) {
Ben Chanbac5bc82013-04-12 17:15:43 -070084 EXPECT_EQ(info1.protocol(), info2.protocol());
85 EXPECT_EQ(info1.time_to_expire_seconds(), info2.time_to_expire_seconds());
86 EXPECT_EQ(info1.is_unreplied(), info2.is_unreplied());
87 EXPECT_TRUE(info1.original_source_ip_address()
88 .Equals(info2.original_source_ip_address()));
89 EXPECT_EQ(info1.original_source_port(), info2.original_source_port());
90 EXPECT_TRUE(info1.original_destination_ip_address()
91 .Equals(info2.original_destination_ip_address()));
92 EXPECT_EQ(info1.original_destination_port(),
93 info2.original_destination_port());
94 EXPECT_TRUE(info1.reply_source_ip_address()
95 .Equals(info2.reply_source_ip_address()));
96 EXPECT_EQ(info1.reply_source_port(), info2.reply_source_port());
97 EXPECT_TRUE(info1.reply_destination_ip_address()
98 .Equals(info2.reply_destination_ip_address()));
99 EXPECT_EQ(info1.reply_destination_port(), info2.reply_destination_port());
100 }
101
102 ConnectionInfoReaderUnderTest reader_;
103};
104
105TEST_F(ConnectionInfoReaderTest, LoadConnectionInfo) {
106 vector<ConnectionInfo> info_list;
107 ScopedTempDir temp_dir;
108 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
109
110 // Loading a non-existent file should fail.
111 FilePath info_file("/non-existent-file");
112 EXPECT_CALL(reader_, GetConnectionInfoFilePath()).WillOnce(Return(info_file));
113 EXPECT_FALSE(reader_.LoadConnectionInfo(&info_list));
114
115 // Loading an empty file should succeed.
116 CreateConnectionInfoFile(kConnectionInfoLines, 0, temp_dir.path(),
117 &info_file);
118 EXPECT_CALL(reader_, GetConnectionInfoFilePath()).WillOnce(Return(info_file));
119 EXPECT_TRUE(reader_.LoadConnectionInfo(&info_list));
120 EXPECT_TRUE(info_list.empty());
121
122 // Loading a non-empty file should succeed.
123 CreateConnectionInfoFile(kConnectionInfoLines,
124 arraysize(kConnectionInfoLines),
125 temp_dir.path(),
126 &info_file);
127 EXPECT_CALL(reader_, GetConnectionInfoFilePath()).WillOnce(Return(info_file));
128 EXPECT_TRUE(reader_.LoadConnectionInfo(&info_list));
129 EXPECT_EQ(arraysize(kConnectionInfoLines), info_list.size());
130
131 ExpectConnectionInfoEqual(ConnectionInfo(IPPROTO_UDP,
132 30,
133 true,
134 StringToIPv4Address("192.168.1.1"),
135 9000,
136 StringToIPv4Address("192.168.1.2"),
137 53,
138 StringToIPv4Address("192.168.1.2"),
139 53,
140 StringToIPv4Address("192.168.1.1"),
141 9000),
142 info_list[0]);
143 ExpectConnectionInfoEqual(ConnectionInfo(IPPROTO_TCP,
144 299,
145 false,
146 StringToIPv4Address("192.168.2.1"),
147 8000,
148 StringToIPv4Address("192.168.2.3"),
149 7000,
150 StringToIPv4Address("192.168.2.3"),
151 7000,
152 StringToIPv4Address("192.168.2.1"),
153 8000),
154 info_list[1]);
155}
156
157TEST_F(ConnectionInfoReaderTest, ParseConnectionInfo) {
158 ConnectionInfo info;
159
160 EXPECT_FALSE(reader_.ParseConnectionInfo("", &info));
161
162 EXPECT_TRUE(reader_.ParseConnectionInfo(kConnectionInfoLines[0], &info));
163 ExpectConnectionInfoEqual(ConnectionInfo(IPPROTO_UDP,
164 30,
165 true,
166 StringToIPv4Address("192.168.1.1"),
167 9000,
168 StringToIPv4Address("192.168.1.2"),
169 53,
170 StringToIPv4Address("192.168.1.2"),
171 53,
172 StringToIPv4Address("192.168.1.1"),
173 9000),
174 info);
175}
176
177TEST_F(ConnectionInfoReaderTest, ParseProtocol) {
178 int protocol = 0;
179
180 EXPECT_FALSE(reader_.ParseProtocol("", &protocol));
181 EXPECT_FALSE(reader_.ParseProtocol("a", &protocol));
182 EXPECT_FALSE(reader_.ParseProtocol("-1", &protocol));
183 EXPECT_FALSE(reader_.ParseProtocol(StringPrintf("%d", IPPROTO_MAX),
184 &protocol));
185
186 for (int i = 0; i < IPPROTO_MAX; ++i) {
187 EXPECT_TRUE(reader_.ParseProtocol(StringPrintf("%d", i), &protocol));
188 EXPECT_EQ(i, protocol);
189 }
190}
191
192TEST_F(ConnectionInfoReaderTest, ParseTimeToExpireSeconds) {
Ben Chan7fab8972014-08-10 17:14:46 -0700193 int64_t time_to_expire = 0;
Ben Chanbac5bc82013-04-12 17:15:43 -0700194
195 EXPECT_FALSE(reader_.ParseTimeToExpireSeconds("", &time_to_expire));
196 EXPECT_FALSE(reader_.ParseTimeToExpireSeconds("a", &time_to_expire));
197 EXPECT_FALSE(reader_.ParseTimeToExpireSeconds("-1", &time_to_expire));
198
199 EXPECT_TRUE(reader_.ParseTimeToExpireSeconds("100", &time_to_expire));
200 EXPECT_EQ(100, time_to_expire);
201}
202
203TEST_F(ConnectionInfoReaderTest, ParseIPAddress) {
204 IPAddress ip_address(IPAddress::kFamilyUnknown);
205 bool is_source = false;
206
207 EXPECT_FALSE(reader_.ParseIPAddress("", &ip_address, &is_source));
208 EXPECT_FALSE(reader_.ParseIPAddress("abc", &ip_address, &is_source));
209 EXPECT_FALSE(reader_.ParseIPAddress("src=", &ip_address, &is_source));
210 EXPECT_FALSE(reader_.ParseIPAddress("src=abc", &ip_address, &is_source));
211 EXPECT_FALSE(reader_.ParseIPAddress("dst=", &ip_address, &is_source));
212 EXPECT_FALSE(reader_.ParseIPAddress("dst=abc", &ip_address, &is_source));
213
214 EXPECT_TRUE(reader_.ParseIPAddress("src=192.168.1.1",
215 &ip_address, &is_source));
216 EXPECT_TRUE(ip_address.Equals(StringToIPv4Address("192.168.1.1")));
217 EXPECT_TRUE(is_source);
218 EXPECT_TRUE(reader_.ParseIPAddress("dst=192.168.1.2",
219 &ip_address, &is_source));
220 EXPECT_TRUE(ip_address.Equals(StringToIPv4Address("192.168.1.2")));
221 EXPECT_FALSE(is_source);
222}
223
224TEST_F(ConnectionInfoReaderTest, ParsePort) {
Ben Chan7fab8972014-08-10 17:14:46 -0700225 uint16_t port = 0;
Ben Chanbac5bc82013-04-12 17:15:43 -0700226 bool is_source = false;
227
228 EXPECT_FALSE(reader_.ParsePort("", &port, &is_source));
229 EXPECT_FALSE(reader_.ParsePort("a", &port, &is_source));
230 EXPECT_FALSE(reader_.ParsePort("0", &port, &is_source));
231 EXPECT_FALSE(reader_.ParsePort("sport=", &port, &is_source));
232 EXPECT_FALSE(reader_.ParsePort("sport=a", &port, &is_source));
233 EXPECT_FALSE(reader_.ParsePort("sport=-1", &port, &is_source));
234 EXPECT_FALSE(reader_.ParsePort("sport=65536", &port, &is_source));
235 EXPECT_FALSE(reader_.ParsePort("dport=", &port, &is_source));
236 EXPECT_FALSE(reader_.ParsePort("dport=a", &port, &is_source));
237 EXPECT_FALSE(reader_.ParsePort("dport=-1", &port, &is_source));
238 EXPECT_FALSE(reader_.ParsePort("dport=65536", &port, &is_source));
239
240 EXPECT_TRUE(reader_.ParsePort("sport=53", &port, &is_source));
241 EXPECT_EQ(53, port);
242 EXPECT_TRUE(is_source);
243 EXPECT_TRUE(reader_.ParsePort("dport=80", &port, &is_source));
244 EXPECT_EQ(80, port);
245 EXPECT_FALSE(is_source);
246}
247
248} // namespace shill