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