blob: cb02bd7e60ada61fd0bf3c293d4c719e24ed8cc0 [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
Ben Chan11c213f2014-09-05 08:21:06 -07009#include <base/files/file_util.h>
Ben Chanbac5bc82013-04-12 17:15:43 -070010#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
Paul Stewart3b30ca52015-06-16 13:13:10 -070028const char* kConnectionInfoLines[] = {
Ben Chanbac5bc82013-04-12 17:15:43 -070029 "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:
Paul Stewart3b30ca52015-06-16 13:13:10 -070048 IPAddress StringToIPv4Address(const string& address_string) {
Ben Chanbac5bc82013-04-12 17:15:43 -070049 IPAddress ip_address(IPAddress::kFamilyIPv4);
50 EXPECT_TRUE(ip_address.SetAddressFromString(address_string));
51 return ip_address;
52 }
53
Paul Stewart3b30ca52015-06-16 13:13:10 -070054 IPAddress StringToIPv6Address(const string& address_string) {
Ben Chanbac5bc82013-04-12 17:15:43 -070055 IPAddress ip_address(IPAddress::kFamilyIPv6);
56 EXPECT_TRUE(ip_address.SetAddressFromString(address_string));
57 return ip_address;
58 }
59
Paul Stewart3b30ca52015-06-16 13:13:10 -070060 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';
Alex Vakulenko0951ccb2014-12-10 12:52:31 -080066 ASSERT_TRUE(base::AppendToFile(*file_path, line.data(), line.size()));
Ben Chanbac5bc82013-04-12 17:15:43 -070067 }
68 }
69
Paul Stewart3b30ca52015-06-16 13:13:10 -070070 void ExpectConnectionInfoEqual(const ConnectionInfo& info1,
71 const ConnectionInfo& info2) {
Ben Chanbac5bc82013-04-12 17:15:43 -070072 EXPECT_EQ(info1.protocol(), info2.protocol());
73 EXPECT_EQ(info1.time_to_expire_seconds(), info2.time_to_expire_seconds());
74 EXPECT_EQ(info1.is_unreplied(), info2.is_unreplied());
75 EXPECT_TRUE(info1.original_source_ip_address()
76 .Equals(info2.original_source_ip_address()));
77 EXPECT_EQ(info1.original_source_port(), info2.original_source_port());
78 EXPECT_TRUE(info1.original_destination_ip_address()
79 .Equals(info2.original_destination_ip_address()));
80 EXPECT_EQ(info1.original_destination_port(),
81 info2.original_destination_port());
82 EXPECT_TRUE(info1.reply_source_ip_address()
83 .Equals(info2.reply_source_ip_address()));
84 EXPECT_EQ(info1.reply_source_port(), info2.reply_source_port());
85 EXPECT_TRUE(info1.reply_destination_ip_address()
86 .Equals(info2.reply_destination_ip_address()));
87 EXPECT_EQ(info1.reply_destination_port(), info2.reply_destination_port());
88 }
89
90 ConnectionInfoReaderUnderTest reader_;
91};
92
93TEST_F(ConnectionInfoReaderTest, LoadConnectionInfo) {
94 vector<ConnectionInfo> info_list;
95 ScopedTempDir temp_dir;
96 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
97
98 // Loading a non-existent file should fail.
99 FilePath info_file("/non-existent-file");
100 EXPECT_CALL(reader_, GetConnectionInfoFilePath()).WillOnce(Return(info_file));
101 EXPECT_FALSE(reader_.LoadConnectionInfo(&info_list));
102
103 // Loading an empty file should succeed.
104 CreateConnectionInfoFile(kConnectionInfoLines, 0, temp_dir.path(),
105 &info_file);
106 EXPECT_CALL(reader_, GetConnectionInfoFilePath()).WillOnce(Return(info_file));
107 EXPECT_TRUE(reader_.LoadConnectionInfo(&info_list));
108 EXPECT_TRUE(info_list.empty());
109
110 // Loading a non-empty file should succeed.
111 CreateConnectionInfoFile(kConnectionInfoLines,
112 arraysize(kConnectionInfoLines),
113 temp_dir.path(),
114 &info_file);
115 EXPECT_CALL(reader_, GetConnectionInfoFilePath()).WillOnce(Return(info_file));
116 EXPECT_TRUE(reader_.LoadConnectionInfo(&info_list));
117 EXPECT_EQ(arraysize(kConnectionInfoLines), info_list.size());
118
119 ExpectConnectionInfoEqual(ConnectionInfo(IPPROTO_UDP,
120 30,
121 true,
122 StringToIPv4Address("192.168.1.1"),
123 9000,
124 StringToIPv4Address("192.168.1.2"),
125 53,
126 StringToIPv4Address("192.168.1.2"),
127 53,
128 StringToIPv4Address("192.168.1.1"),
129 9000),
130 info_list[0]);
131 ExpectConnectionInfoEqual(ConnectionInfo(IPPROTO_TCP,
132 299,
133 false,
134 StringToIPv4Address("192.168.2.1"),
135 8000,
136 StringToIPv4Address("192.168.2.3"),
137 7000,
138 StringToIPv4Address("192.168.2.3"),
139 7000,
140 StringToIPv4Address("192.168.2.1"),
141 8000),
142 info_list[1]);
143}
144
145TEST_F(ConnectionInfoReaderTest, ParseConnectionInfo) {
146 ConnectionInfo info;
147
148 EXPECT_FALSE(reader_.ParseConnectionInfo("", &info));
149
150 EXPECT_TRUE(reader_.ParseConnectionInfo(kConnectionInfoLines[0], &info));
151 ExpectConnectionInfoEqual(ConnectionInfo(IPPROTO_UDP,
152 30,
153 true,
154 StringToIPv4Address("192.168.1.1"),
155 9000,
156 StringToIPv4Address("192.168.1.2"),
157 53,
158 StringToIPv4Address("192.168.1.2"),
159 53,
160 StringToIPv4Address("192.168.1.1"),
161 9000),
162 info);
163}
164
165TEST_F(ConnectionInfoReaderTest, ParseProtocol) {
166 int protocol = 0;
167
168 EXPECT_FALSE(reader_.ParseProtocol("", &protocol));
169 EXPECT_FALSE(reader_.ParseProtocol("a", &protocol));
170 EXPECT_FALSE(reader_.ParseProtocol("-1", &protocol));
171 EXPECT_FALSE(reader_.ParseProtocol(StringPrintf("%d", IPPROTO_MAX),
172 &protocol));
173
174 for (int i = 0; i < IPPROTO_MAX; ++i) {
175 EXPECT_TRUE(reader_.ParseProtocol(StringPrintf("%d", i), &protocol));
176 EXPECT_EQ(i, protocol);
177 }
178}
179
180TEST_F(ConnectionInfoReaderTest, ParseTimeToExpireSeconds) {
Ben Chan7fab8972014-08-10 17:14:46 -0700181 int64_t time_to_expire = 0;
Ben Chanbac5bc82013-04-12 17:15:43 -0700182
183 EXPECT_FALSE(reader_.ParseTimeToExpireSeconds("", &time_to_expire));
184 EXPECT_FALSE(reader_.ParseTimeToExpireSeconds("a", &time_to_expire));
185 EXPECT_FALSE(reader_.ParseTimeToExpireSeconds("-1", &time_to_expire));
186
187 EXPECT_TRUE(reader_.ParseTimeToExpireSeconds("100", &time_to_expire));
188 EXPECT_EQ(100, time_to_expire);
189}
190
191TEST_F(ConnectionInfoReaderTest, ParseIPAddress) {
192 IPAddress ip_address(IPAddress::kFamilyUnknown);
193 bool is_source = false;
194
195 EXPECT_FALSE(reader_.ParseIPAddress("", &ip_address, &is_source));
196 EXPECT_FALSE(reader_.ParseIPAddress("abc", &ip_address, &is_source));
197 EXPECT_FALSE(reader_.ParseIPAddress("src=", &ip_address, &is_source));
198 EXPECT_FALSE(reader_.ParseIPAddress("src=abc", &ip_address, &is_source));
199 EXPECT_FALSE(reader_.ParseIPAddress("dst=", &ip_address, &is_source));
200 EXPECT_FALSE(reader_.ParseIPAddress("dst=abc", &ip_address, &is_source));
201
202 EXPECT_TRUE(reader_.ParseIPAddress("src=192.168.1.1",
203 &ip_address, &is_source));
204 EXPECT_TRUE(ip_address.Equals(StringToIPv4Address("192.168.1.1")));
205 EXPECT_TRUE(is_source);
206 EXPECT_TRUE(reader_.ParseIPAddress("dst=192.168.1.2",
207 &ip_address, &is_source));
208 EXPECT_TRUE(ip_address.Equals(StringToIPv4Address("192.168.1.2")));
209 EXPECT_FALSE(is_source);
210}
211
212TEST_F(ConnectionInfoReaderTest, ParsePort) {
Ben Chan7fab8972014-08-10 17:14:46 -0700213 uint16_t port = 0;
Ben Chanbac5bc82013-04-12 17:15:43 -0700214 bool is_source = false;
215
216 EXPECT_FALSE(reader_.ParsePort("", &port, &is_source));
217 EXPECT_FALSE(reader_.ParsePort("a", &port, &is_source));
218 EXPECT_FALSE(reader_.ParsePort("0", &port, &is_source));
219 EXPECT_FALSE(reader_.ParsePort("sport=", &port, &is_source));
220 EXPECT_FALSE(reader_.ParsePort("sport=a", &port, &is_source));
221 EXPECT_FALSE(reader_.ParsePort("sport=-1", &port, &is_source));
222 EXPECT_FALSE(reader_.ParsePort("sport=65536", &port, &is_source));
223 EXPECT_FALSE(reader_.ParsePort("dport=", &port, &is_source));
224 EXPECT_FALSE(reader_.ParsePort("dport=a", &port, &is_source));
225 EXPECT_FALSE(reader_.ParsePort("dport=-1", &port, &is_source));
226 EXPECT_FALSE(reader_.ParsePort("dport=65536", &port, &is_source));
227
228 EXPECT_TRUE(reader_.ParsePort("sport=53", &port, &is_source));
229 EXPECT_EQ(53, port);
230 EXPECT_TRUE(is_source);
231 EXPECT_TRUE(reader_.ParsePort("dport=80", &port, &is_source));
232 EXPECT_EQ(80, port);
233 EXPECT_FALSE(is_source);
234}
235
236} // namespace shill