blob: eed96218cc3e9198195ddc65617d137bf021b922 [file] [log] [blame]
Ben Chanbac5bc82013-04-12 17:15:43 -07001// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/connection_info_reader.h"
6
7#include <netinet/in.h>
8
9#include <base/file_util.h>
10#include <base/files/scoped_temp_dir.h>
Ben Chana0ddf462014-02-06 11:32:42 -080011#include <base/strings/stringprintf.h>
Ben Chanbac5bc82013-04-12 17:15:43 -070012#include <gmock/gmock.h>
13#include <gtest/gtest.h>
14
15using base::FilePath;
16using base::ScopedTempDir;
17using base::StringPrintf;
18using std::string;
19using std::vector;
20using testing::Return;
21
22namespace shill {
23
24namespace {
25
26// TODO(benchan): Test IPv6 addresses.
27
28const char *kConnectionInfoLines[] = {
29 "udp 17 30 src=192.168.1.1 dst=192.168.1.2 sport=9000 dport=53 "
30 "[UNREPLIED] src=192.168.1.2 dst=192.168.1.1 sport=53 dport=9000 use=2",
31 "tcp 6 299 ESTABLISHED src=192.168.2.1 dst=192.168.2.3 sport=8000 "
32 "dport=7000 src=192.168.2.3 dst=192.168.2.1 sport=7000 dport=8000 [ASSURED] "
33 "use=2",
34};
35
36} // namespace
37
38class ConnectionInfoReaderUnderTest : public ConnectionInfoReader {
39 public:
40 // Mock out GetConnectionInfoFilePath to use a temporary created connection
41 // info file instead of the actual path in procfs (i.e.
42 // /proc/net/ip_conntrack).
Alex Vakulenko8a532292014-06-16 17:18:44 -070043 MOCK_CONST_METHOD0(GetConnectionInfoFilePath, FilePath());
Ben Chanbac5bc82013-04-12 17:15:43 -070044};
45
46class ConnectionInfoReaderTest : public testing::Test {
47 protected:
48 IPAddress StringToIPv4Address(const string &address_string) {
49 IPAddress ip_address(IPAddress::kFamilyIPv4);
50 EXPECT_TRUE(ip_address.SetAddressFromString(address_string));
51 return ip_address;
52 }
53
54 IPAddress StringToIPv6Address(const string &address_string) {
55 IPAddress ip_address(IPAddress::kFamilyIPv6);
56 EXPECT_TRUE(ip_address.SetAddressFromString(address_string));
57 return ip_address;
58 }
59
60 void CreateConnectionInfoFile(const char **lines, size_t num_lines,
61 const FilePath &dir_path, FilePath *file_path) {
Ben Chana0ddf462014-02-06 11:32:42 -080062 ASSERT_TRUE(base::CreateTemporaryFileInDir(dir_path, file_path));
Ben Chanbac5bc82013-04-12 17:15:43 -070063 for (size_t i = 0; i < num_lines; ++i) {
64 string line = lines[i];
65 line += '\n';
66 ASSERT_EQ(line.size(),
Ben Chan6fbf64f2014-05-21 18:07:01 -070067 base::AppendToFile(*file_path, line.data(), line.size()));
Ben Chanbac5bc82013-04-12 17:15:43 -070068 }
69 }
70
71 void ExpectConnectionInfoEqual(const ConnectionInfo &info1,
72 const ConnectionInfo &info2) {
73 EXPECT_EQ(info1.protocol(), info2.protocol());
74 EXPECT_EQ(info1.time_to_expire_seconds(), info2.time_to_expire_seconds());
75 EXPECT_EQ(info1.is_unreplied(), info2.is_unreplied());
76 EXPECT_TRUE(info1.original_source_ip_address()
77 .Equals(info2.original_source_ip_address()));
78 EXPECT_EQ(info1.original_source_port(), info2.original_source_port());
79 EXPECT_TRUE(info1.original_destination_ip_address()
80 .Equals(info2.original_destination_ip_address()));
81 EXPECT_EQ(info1.original_destination_port(),
82 info2.original_destination_port());
83 EXPECT_TRUE(info1.reply_source_ip_address()
84 .Equals(info2.reply_source_ip_address()));
85 EXPECT_EQ(info1.reply_source_port(), info2.reply_source_port());
86 EXPECT_TRUE(info1.reply_destination_ip_address()
87 .Equals(info2.reply_destination_ip_address()));
88 EXPECT_EQ(info1.reply_destination_port(), info2.reply_destination_port());
89 }
90
91 ConnectionInfoReaderUnderTest reader_;
92};
93
94TEST_F(ConnectionInfoReaderTest, LoadConnectionInfo) {
95 vector<ConnectionInfo> info_list;
96 ScopedTempDir temp_dir;
97 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
98
99 // Loading a non-existent file should fail.
100 FilePath info_file("/non-existent-file");
101 EXPECT_CALL(reader_, GetConnectionInfoFilePath()).WillOnce(Return(info_file));
102 EXPECT_FALSE(reader_.LoadConnectionInfo(&info_list));
103
104 // Loading an empty file should succeed.
105 CreateConnectionInfoFile(kConnectionInfoLines, 0, temp_dir.path(),
106 &info_file);
107 EXPECT_CALL(reader_, GetConnectionInfoFilePath()).WillOnce(Return(info_file));
108 EXPECT_TRUE(reader_.LoadConnectionInfo(&info_list));
109 EXPECT_TRUE(info_list.empty());
110
111 // Loading a non-empty file should succeed.
112 CreateConnectionInfoFile(kConnectionInfoLines,
113 arraysize(kConnectionInfoLines),
114 temp_dir.path(),
115 &info_file);
116 EXPECT_CALL(reader_, GetConnectionInfoFilePath()).WillOnce(Return(info_file));
117 EXPECT_TRUE(reader_.LoadConnectionInfo(&info_list));
118 EXPECT_EQ(arraysize(kConnectionInfoLines), info_list.size());
119
120 ExpectConnectionInfoEqual(ConnectionInfo(IPPROTO_UDP,
121 30,
122 true,
123 StringToIPv4Address("192.168.1.1"),
124 9000,
125 StringToIPv4Address("192.168.1.2"),
126 53,
127 StringToIPv4Address("192.168.1.2"),
128 53,
129 StringToIPv4Address("192.168.1.1"),
130 9000),
131 info_list[0]);
132 ExpectConnectionInfoEqual(ConnectionInfo(IPPROTO_TCP,
133 299,
134 false,
135 StringToIPv4Address("192.168.2.1"),
136 8000,
137 StringToIPv4Address("192.168.2.3"),
138 7000,
139 StringToIPv4Address("192.168.2.3"),
140 7000,
141 StringToIPv4Address("192.168.2.1"),
142 8000),
143 info_list[1]);
144}
145
146TEST_F(ConnectionInfoReaderTest, ParseConnectionInfo) {
147 ConnectionInfo info;
148
149 EXPECT_FALSE(reader_.ParseConnectionInfo("", &info));
150
151 EXPECT_TRUE(reader_.ParseConnectionInfo(kConnectionInfoLines[0], &info));
152 ExpectConnectionInfoEqual(ConnectionInfo(IPPROTO_UDP,
153 30,
154 true,
155 StringToIPv4Address("192.168.1.1"),
156 9000,
157 StringToIPv4Address("192.168.1.2"),
158 53,
159 StringToIPv4Address("192.168.1.2"),
160 53,
161 StringToIPv4Address("192.168.1.1"),
162 9000),
163 info);
164}
165
166TEST_F(ConnectionInfoReaderTest, ParseProtocol) {
167 int protocol = 0;
168
169 EXPECT_FALSE(reader_.ParseProtocol("", &protocol));
170 EXPECT_FALSE(reader_.ParseProtocol("a", &protocol));
171 EXPECT_FALSE(reader_.ParseProtocol("-1", &protocol));
172 EXPECT_FALSE(reader_.ParseProtocol(StringPrintf("%d", IPPROTO_MAX),
173 &protocol));
174
175 for (int i = 0; i < IPPROTO_MAX; ++i) {
176 EXPECT_TRUE(reader_.ParseProtocol(StringPrintf("%d", i), &protocol));
177 EXPECT_EQ(i, protocol);
178 }
179}
180
181TEST_F(ConnectionInfoReaderTest, ParseTimeToExpireSeconds) {
Ben Chan7fab8972014-08-10 17:14:46 -0700182 int64_t time_to_expire = 0;
Ben Chanbac5bc82013-04-12 17:15:43 -0700183
184 EXPECT_FALSE(reader_.ParseTimeToExpireSeconds("", &time_to_expire));
185 EXPECT_FALSE(reader_.ParseTimeToExpireSeconds("a", &time_to_expire));
186 EXPECT_FALSE(reader_.ParseTimeToExpireSeconds("-1", &time_to_expire));
187
188 EXPECT_TRUE(reader_.ParseTimeToExpireSeconds("100", &time_to_expire));
189 EXPECT_EQ(100, time_to_expire);
190}
191
192TEST_F(ConnectionInfoReaderTest, ParseIPAddress) {
193 IPAddress ip_address(IPAddress::kFamilyUnknown);
194 bool is_source = false;
195
196 EXPECT_FALSE(reader_.ParseIPAddress("", &ip_address, &is_source));
197 EXPECT_FALSE(reader_.ParseIPAddress("abc", &ip_address, &is_source));
198 EXPECT_FALSE(reader_.ParseIPAddress("src=", &ip_address, &is_source));
199 EXPECT_FALSE(reader_.ParseIPAddress("src=abc", &ip_address, &is_source));
200 EXPECT_FALSE(reader_.ParseIPAddress("dst=", &ip_address, &is_source));
201 EXPECT_FALSE(reader_.ParseIPAddress("dst=abc", &ip_address, &is_source));
202
203 EXPECT_TRUE(reader_.ParseIPAddress("src=192.168.1.1",
204 &ip_address, &is_source));
205 EXPECT_TRUE(ip_address.Equals(StringToIPv4Address("192.168.1.1")));
206 EXPECT_TRUE(is_source);
207 EXPECT_TRUE(reader_.ParseIPAddress("dst=192.168.1.2",
208 &ip_address, &is_source));
209 EXPECT_TRUE(ip_address.Equals(StringToIPv4Address("192.168.1.2")));
210 EXPECT_FALSE(is_source);
211}
212
213TEST_F(ConnectionInfoReaderTest, ParsePort) {
Ben Chan7fab8972014-08-10 17:14:46 -0700214 uint16_t port = 0;
Ben Chanbac5bc82013-04-12 17:15:43 -0700215 bool is_source = false;
216
217 EXPECT_FALSE(reader_.ParsePort("", &port, &is_source));
218 EXPECT_FALSE(reader_.ParsePort("a", &port, &is_source));
219 EXPECT_FALSE(reader_.ParsePort("0", &port, &is_source));
220 EXPECT_FALSE(reader_.ParsePort("sport=", &port, &is_source));
221 EXPECT_FALSE(reader_.ParsePort("sport=a", &port, &is_source));
222 EXPECT_FALSE(reader_.ParsePort("sport=-1", &port, &is_source));
223 EXPECT_FALSE(reader_.ParsePort("sport=65536", &port, &is_source));
224 EXPECT_FALSE(reader_.ParsePort("dport=", &port, &is_source));
225 EXPECT_FALSE(reader_.ParsePort("dport=a", &port, &is_source));
226 EXPECT_FALSE(reader_.ParsePort("dport=-1", &port, &is_source));
227 EXPECT_FALSE(reader_.ParsePort("dport=65536", &port, &is_source));
228
229 EXPECT_TRUE(reader_.ParsePort("sport=53", &port, &is_source));
230 EXPECT_EQ(53, port);
231 EXPECT_TRUE(is_source);
232 EXPECT_TRUE(reader_.ParsePort("dport=80", &port, &is_source));
233 EXPECT_EQ(80, port);
234 EXPECT_FALSE(is_source);
235}
236
237} // namespace shill