1//
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//
16
17#include "shill/socket_info_reader.h"
18
19#include <base/files/file_util.h>
20#include <base/files/scoped_temp_dir.h>
21#include <base/strings/stringprintf.h>
22#include <gmock/gmock.h>
23#include <gtest/gtest.h>
24
25using base::FilePath;
26using base::ScopedTempDir;
27using std::string;
28using std::vector;
29using testing::Return;
30
31namespace shill {
32
33namespace {
34
35const char kIPv4AddressAllZeros[] = "0.0.0.0";
36const char kIPv4AddressAllOnes[] = "255.255.255.255";
37const char kIPv4Address_127_0_0_1[] = "127.0.0.1";
38const char kIPv4Address_192_168_1_10[] = "192.168.1.10";
39const char kIPv6AddressAllZeros[] = "0000:0000:0000:0000:0000:0000:0000:0000";
40const char kIPv6AddressAllOnes[] = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff";
41const char kIPv6AddressPattern1[] = "0123:4567:89ab:cdef:ffee:ddcc:bbaa:9988";
42
43const char* kIPv4SocketInfoLines[] = {
44    "  sl  local_address rem_address   st tx_queue rx_queue tr tm->when "
45    "retrnsmt   uid  timeout inode                                      ",
46    "   0: 0100007F:0019 00000000:0000 0A 0000000A:00000005 00:00000000 "
47    "00000000     0        0 36948 1 0000000000000000 100 0 0 10 -1     ",
48    "   1: 0A01A8C0:0050 0100007F:03FC 01 00000000:00000000 00:00000000 "
49    "00000000 65534        0 2787034 1 0000000000000000 100 0 0 10 -1   ",
50};
51const char* kIPv6SocketInfoLines[] = {
52    "  sl  local_address                         "
53    "remote_address                        st tx_queue rx_queue tr tm->when "
54    "retrnsmt   uid  timeout inode",
55    "   0: 67452301EFCDAB89CCDDEEFF8899AABB:0019 "
56    "00000000000000000000000000000000:0000 0A 0000000A:00000005 00:00000000 "
57    "00000000     0        0 36412 1 0000000000000000 100 0 0 2 -1",
58    "   1: 00000000000000000000000000000000:0050 "
59    "67452301EFCDAB89CCDDEEFF8899AABB:03FC 01 00000000:00000000 00:00000000 "
60    "00000000     0        0 36412 1 0000000000000000 100 0 0 2 -1",
61};
62
63}  // namespace
64
65class SocketInfoReaderUnderTest : public SocketInfoReader {
66 public:
67  // Mock out GetTcpv4SocketInfoFilePath and GetTcpv6SocketInfoFilePath to
68  // use a temporary created socket info file instead of the actual path
69  // in procfs (i.e. /proc/net/tcp and /proc/net/tcp6).
70  MOCK_CONST_METHOD0(GetTcpv4SocketInfoFilePath, FilePath());
71  MOCK_CONST_METHOD0(GetTcpv6SocketInfoFilePath, FilePath());
72};
73
74class SocketInfoReaderTest : public testing::Test {
75 protected:
76  IPAddress StringToIPv4Address(const string& address_string) {
77    IPAddress ip_address(IPAddress::kFamilyIPv4);
78    EXPECT_TRUE(ip_address.SetAddressFromString(address_string));
79    return ip_address;
80  }
81
82  IPAddress StringToIPv6Address(const string& address_string) {
83    IPAddress ip_address(IPAddress::kFamilyIPv6);
84    EXPECT_TRUE(ip_address.SetAddressFromString(address_string));
85    return ip_address;
86  }
87
88  void CreateSocketInfoFile(const char** lines, size_t num_lines,
89                            const FilePath& dir_path, FilePath* file_path) {
90    ASSERT_TRUE(base::CreateTemporaryFileInDir(dir_path, file_path));
91    for (size_t i = 0; i < num_lines; ++i) {
92      string line = lines[i];
93      line += '\n';
94      ASSERT_TRUE(base::AppendToFile(*file_path, line.data(), line.size()));
95    }
96  }
97
98  void ExpectSocketInfoEqual(const SocketInfo& info1, const SocketInfo& info2) {
99    EXPECT_EQ(info1.connection_state(), info2.connection_state());
100    EXPECT_TRUE(info1.local_ip_address().Equals(info2.local_ip_address()));
101    EXPECT_EQ(info1.local_port(), info2.local_port());
102    EXPECT_TRUE(info1.remote_ip_address().Equals(info2.remote_ip_address()));
103    EXPECT_EQ(info1.remote_port(), info2.remote_port());
104    EXPECT_EQ(info1.transmit_queue_value(), info2.transmit_queue_value());
105    EXPECT_EQ(info1.receive_queue_value(), info2.receive_queue_value());
106    EXPECT_EQ(info1.timer_state(), info2.timer_state());
107  }
108
109  SocketInfoReaderUnderTest reader_;
110};
111
112TEST_F(SocketInfoReaderTest, LoadTcpSocketInfo) {
113  FilePath invalid_path("/non-existent-file"), v4_path, v6_path;
114  ScopedTempDir temp_dir;
115  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
116  CreateSocketInfoFile(kIPv4SocketInfoLines, 2, temp_dir.path(), &v4_path);
117  CreateSocketInfoFile(kIPv6SocketInfoLines, 2, temp_dir.path(), &v6_path);
118
119  SocketInfo v4_info(SocketInfo::kConnectionStateListen,
120                     StringToIPv4Address(kIPv4Address_127_0_0_1),
121                     25,
122                     StringToIPv4Address(kIPv4AddressAllZeros),
123                     0,
124                     10,
125                     5,
126                     SocketInfo::kTimerStateNoTimerPending);
127  SocketInfo v6_info(SocketInfo::kConnectionStateListen,
128                     StringToIPv6Address(kIPv6AddressPattern1),
129                     25,
130                     StringToIPv6Address(kIPv6AddressAllZeros),
131                     0,
132                     10,
133                     5,
134                     SocketInfo::kTimerStateNoTimerPending);
135
136  vector<SocketInfo> info_list;
137  EXPECT_CALL(reader_, GetTcpv4SocketInfoFilePath())
138      .WillOnce(Return(invalid_path));
139  EXPECT_CALL(reader_, GetTcpv6SocketInfoFilePath())
140      .WillOnce(Return(invalid_path));
141  EXPECT_FALSE(reader_.LoadTcpSocketInfo(&info_list));
142
143  EXPECT_CALL(reader_, GetTcpv4SocketInfoFilePath())
144      .WillOnce(Return(v4_path));
145  EXPECT_CALL(reader_, GetTcpv6SocketInfoFilePath())
146      .WillOnce(Return(invalid_path));
147  EXPECT_TRUE(reader_.LoadTcpSocketInfo(&info_list));
148  EXPECT_EQ(1, info_list.size());
149  ExpectSocketInfoEqual(v4_info, info_list[0]);
150
151  EXPECT_CALL(reader_, GetTcpv4SocketInfoFilePath())
152      .WillOnce(Return(invalid_path));
153  EXPECT_CALL(reader_, GetTcpv6SocketInfoFilePath())
154      .WillOnce(Return(v6_path));
155  EXPECT_TRUE(reader_.LoadTcpSocketInfo(&info_list));
156  EXPECT_EQ(1, info_list.size());
157  ExpectSocketInfoEqual(v6_info, info_list[0]);
158
159  EXPECT_CALL(reader_, GetTcpv4SocketInfoFilePath())
160      .WillOnce(Return(v4_path));
161  EXPECT_CALL(reader_, GetTcpv6SocketInfoFilePath())
162      .WillOnce(Return(v6_path));
163  EXPECT_TRUE(reader_.LoadTcpSocketInfo(&info_list));
164  EXPECT_EQ(2, info_list.size());
165  ExpectSocketInfoEqual(v4_info, info_list[0]);
166  ExpectSocketInfoEqual(v6_info, info_list[1]);
167}
168
169TEST_F(SocketInfoReaderTest, AppendSocketInfo) {
170  FilePath file_path("/non-existent-file");
171  vector<SocketInfo> info_list;
172
173  EXPECT_FALSE(reader_.AppendSocketInfo(file_path, &info_list));
174  EXPECT_TRUE(info_list.empty());
175
176  ScopedTempDir temp_dir;
177  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
178
179  CreateSocketInfoFile(kIPv4SocketInfoLines, 1, temp_dir.path(), &file_path);
180  EXPECT_TRUE(reader_.AppendSocketInfo(file_path, &info_list));
181  EXPECT_TRUE(info_list.empty());
182
183  SocketInfo v4_info1(SocketInfo::kConnectionStateListen,
184                      StringToIPv4Address(kIPv4Address_127_0_0_1),
185                      25,
186                      StringToIPv4Address(kIPv4AddressAllZeros),
187                      0,
188                      10,
189                      5,
190                      SocketInfo::kTimerStateNoTimerPending);
191  SocketInfo v4_info2(SocketInfo::kConnectionStateEstablished,
192                      StringToIPv4Address(kIPv4Address_192_168_1_10),
193                      80,
194                      StringToIPv4Address(kIPv4Address_127_0_0_1),
195                      1020,
196                      0,
197                      0,
198                      SocketInfo::kTimerStateNoTimerPending);
199  SocketInfo v6_info1(SocketInfo::kConnectionStateListen,
200                      StringToIPv6Address(kIPv6AddressPattern1),
201                      25,
202                      StringToIPv6Address(kIPv6AddressAllZeros),
203                      0,
204                      10,
205                      5,
206                      SocketInfo::kTimerStateNoTimerPending);
207  SocketInfo v6_info2(SocketInfo::kConnectionStateEstablished,
208                      StringToIPv6Address(kIPv6AddressAllZeros),
209                      80,
210                      StringToIPv6Address(kIPv6AddressPattern1),
211                      1020,
212                      0,
213                      0,
214                      SocketInfo::kTimerStateNoTimerPending);
215
216  CreateSocketInfoFile(kIPv4SocketInfoLines, arraysize(kIPv4SocketInfoLines),
217                       temp_dir.path(), &file_path);
218  EXPECT_TRUE(reader_.AppendSocketInfo(file_path, &info_list));
219  EXPECT_EQ(arraysize(kIPv4SocketInfoLines) - 1, info_list.size());
220  ExpectSocketInfoEqual(v4_info1, info_list[0]);
221  ExpectSocketInfoEqual(v4_info2, info_list[1]);
222
223  CreateSocketInfoFile(kIPv6SocketInfoLines, arraysize(kIPv6SocketInfoLines),
224                       temp_dir.path(), &file_path);
225  EXPECT_TRUE(reader_.AppendSocketInfo(file_path, &info_list));
226  EXPECT_EQ(
227      arraysize(kIPv4SocketInfoLines) + arraysize(kIPv6SocketInfoLines) - 2,
228      info_list.size());
229  ExpectSocketInfoEqual(v4_info1, info_list[0]);
230  ExpectSocketInfoEqual(v4_info2, info_list[1]);
231  ExpectSocketInfoEqual(v6_info1, info_list[2]);
232  ExpectSocketInfoEqual(v6_info2, info_list[3]);
233}
234
235TEST_F(SocketInfoReaderTest, ParseSocketInfo) {
236  SocketInfo info;
237
238  EXPECT_FALSE(reader_.ParseSocketInfo("", &info));
239  EXPECT_FALSE(reader_.ParseSocketInfo(kIPv4SocketInfoLines[0], &info));
240
241  EXPECT_TRUE(reader_.ParseSocketInfo(kIPv4SocketInfoLines[1], &info));
242  ExpectSocketInfoEqual(SocketInfo(SocketInfo::kConnectionStateListen,
243                                   StringToIPv4Address(kIPv4Address_127_0_0_1),
244                                   25,
245                                   StringToIPv4Address(kIPv4AddressAllZeros),
246                                   0,
247                                   10,
248                                   5,
249                                   SocketInfo::kTimerStateNoTimerPending),
250                        info);
251}
252
253TEST_F(SocketInfoReaderTest, ParseIPAddressAndPort) {
254  IPAddress ip_address(IPAddress::kFamilyUnknown);
255  uint16_t port = 0;
256
257  EXPECT_FALSE(reader_.ParseIPAddressAndPort("", &ip_address, &port));
258  EXPECT_FALSE(reader_.ParseIPAddressAndPort("00000000", &ip_address, &port));
259  EXPECT_FALSE(reader_.ParseIPAddressAndPort("00000000:", &ip_address, &port));
260  EXPECT_FALSE(reader_.ParseIPAddressAndPort(":0000", &ip_address, &port));
261  EXPECT_FALSE(reader_.ParseIPAddressAndPort(
262      "0000000Y:0000", &ip_address, &port));
263  EXPECT_FALSE(reader_.ParseIPAddressAndPort(
264      "00000000:000Y", &ip_address, &port));
265
266  EXPECT_FALSE(reader_.ParseIPAddressAndPort(
267      "00000000000000000000000000000000", &ip_address, &port));
268  EXPECT_FALSE(reader_.ParseIPAddressAndPort(
269      "00000000000000000000000000000000:", &ip_address, &port));
270  EXPECT_FALSE(reader_.ParseIPAddressAndPort(
271      "00000000000000000000000000000000Y:0000", &ip_address, &port));
272  EXPECT_FALSE(reader_.ParseIPAddressAndPort(
273      "000000000000000000000000000000000:000Y", &ip_address, &port));
274
275  EXPECT_TRUE(reader_.ParseIPAddressAndPort(
276      "0a01A8c0:0050", &ip_address, &port));
277  EXPECT_TRUE(ip_address.Equals(
278      StringToIPv4Address(kIPv4Address_192_168_1_10)));
279  EXPECT_EQ(80, port);
280
281  EXPECT_TRUE(reader_.ParseIPAddressAndPort(
282      "67452301efcdab89CCDDEEFF8899AABB:1F90", &ip_address, &port));
283  EXPECT_TRUE(ip_address.Equals(StringToIPv6Address(kIPv6AddressPattern1)));
284  EXPECT_EQ(8080, port);
285}
286
287TEST_F(SocketInfoReaderTest, ParseIPAddress) {
288  IPAddress ip_address(IPAddress::kFamilyUnknown);
289
290  EXPECT_FALSE(reader_.ParseIPAddress("", &ip_address));
291  EXPECT_FALSE(reader_.ParseIPAddress("0", &ip_address));
292  EXPECT_FALSE(reader_.ParseIPAddress("00", &ip_address));
293  EXPECT_FALSE(reader_.ParseIPAddress("0000000Y", &ip_address));
294  EXPECT_FALSE(reader_.ParseIPAddress("0000000000000000000000000000000Y",
295                                      &ip_address));
296
297  EXPECT_TRUE(reader_.ParseIPAddress("00000000", &ip_address));
298  EXPECT_TRUE(ip_address.Equals(StringToIPv4Address(kIPv4AddressAllZeros)));
299
300  EXPECT_TRUE(reader_.ParseIPAddress("0100007F", &ip_address));
301  EXPECT_TRUE(ip_address.Equals(StringToIPv4Address(kIPv4Address_127_0_0_1)));
302
303  EXPECT_TRUE(reader_.ParseIPAddress("0a01A8c0", &ip_address));
304  EXPECT_TRUE(ip_address.Equals(
305      StringToIPv4Address(kIPv4Address_192_168_1_10)));
306
307  EXPECT_TRUE(reader_.ParseIPAddress("ffffffff", &ip_address));
308  EXPECT_TRUE(ip_address.Equals(
309      StringToIPv4Address(kIPv4AddressAllOnes)));
310
311  EXPECT_TRUE(reader_.ParseIPAddress("00000000000000000000000000000000",
312                                     &ip_address));
313  EXPECT_TRUE(ip_address.Equals(StringToIPv6Address(kIPv6AddressAllZeros)));
314
315  EXPECT_TRUE(reader_.ParseIPAddress("67452301efcdab89CCDDEEFF8899AABB",
316                                     &ip_address));
317  EXPECT_TRUE(ip_address.Equals(StringToIPv6Address(kIPv6AddressPattern1)));
318
319  EXPECT_TRUE(reader_.ParseIPAddress("ffffffffffffffffffffffffffffffff",
320                                     &ip_address));
321  EXPECT_TRUE(ip_address.Equals(StringToIPv6Address(kIPv6AddressAllOnes)));
322}
323
324TEST_F(SocketInfoReaderTest, ParsePort) {
325  uint16_t port = 0;
326
327  EXPECT_FALSE(reader_.ParsePort("", &port));
328  EXPECT_FALSE(reader_.ParsePort("0", &port));
329  EXPECT_FALSE(reader_.ParsePort("00", &port));
330  EXPECT_FALSE(reader_.ParsePort("000", &port));
331  EXPECT_FALSE(reader_.ParsePort("000Y", &port));
332
333  EXPECT_TRUE(reader_.ParsePort("0000", &port));
334  EXPECT_EQ(0, port);
335
336  EXPECT_TRUE(reader_.ParsePort("0050", &port));
337  EXPECT_EQ(80, port);
338
339  EXPECT_TRUE(reader_.ParsePort("abCD", &port));
340  EXPECT_EQ(43981, port);
341
342  EXPECT_TRUE(reader_.ParsePort("ffff", &port));
343  EXPECT_EQ(65535, port);
344}
345
346TEST_F(SocketInfoReaderTest, ParseTransimitAndReceiveQueueValues) {
347  uint64_t transmit_queue_value = 0, receive_queue_value = 0;
348
349  EXPECT_FALSE(reader_.ParseTransimitAndReceiveQueueValues(
350      "", &transmit_queue_value, &receive_queue_value));
351  EXPECT_FALSE(reader_.ParseTransimitAndReceiveQueueValues(
352      "00000000", &transmit_queue_value, &receive_queue_value));
353  EXPECT_FALSE(reader_.ParseTransimitAndReceiveQueueValues(
354      "00000000:", &transmit_queue_value, &receive_queue_value));
355  EXPECT_FALSE(reader_.ParseTransimitAndReceiveQueueValues(
356      ":00000000", &transmit_queue_value, &receive_queue_value));
357  EXPECT_FALSE(reader_.ParseTransimitAndReceiveQueueValues(
358      "0000000Y:00000000", &transmit_queue_value, &receive_queue_value));
359  EXPECT_FALSE(reader_.ParseTransimitAndReceiveQueueValues(
360      "00000000:0000000Y", &transmit_queue_value, &receive_queue_value));
361
362  EXPECT_TRUE(reader_.ParseTransimitAndReceiveQueueValues(
363      "00000001:FFFFFFFF", &transmit_queue_value, &receive_queue_value));
364  EXPECT_EQ(1, transmit_queue_value);
365  EXPECT_EQ(0xffffffff, receive_queue_value);
366}
367
368TEST_F(SocketInfoReaderTest, ParseConnectionState) {
369  SocketInfo::ConnectionState connection_state =
370      SocketInfo::kConnectionStateUnknown;
371
372  EXPECT_FALSE(reader_.ParseConnectionState("", &connection_state));
373  EXPECT_FALSE(reader_.ParseConnectionState("0", &connection_state));
374  EXPECT_FALSE(reader_.ParseConnectionState("X", &connection_state));
375
376  EXPECT_TRUE(reader_.ParseConnectionState("00", &connection_state));
377  EXPECT_EQ(SocketInfo::kConnectionStateUnknown, connection_state);
378  EXPECT_TRUE(reader_.ParseConnectionState("01", &connection_state));
379  EXPECT_EQ(SocketInfo::kConnectionStateEstablished, connection_state);
380  EXPECT_TRUE(reader_.ParseConnectionState("02", &connection_state));
381  EXPECT_EQ(SocketInfo::kConnectionStateSynSent, connection_state);
382  EXPECT_TRUE(reader_.ParseConnectionState("03", &connection_state));
383  EXPECT_EQ(SocketInfo::kConnectionStateSynRecv, connection_state);
384  EXPECT_TRUE(reader_.ParseConnectionState("04", &connection_state));
385  EXPECT_EQ(SocketInfo::kConnectionStateFinWait1, connection_state);
386  EXPECT_TRUE(reader_.ParseConnectionState("05", &connection_state));
387  EXPECT_EQ(SocketInfo::kConnectionStateFinWait2, connection_state);
388  EXPECT_TRUE(reader_.ParseConnectionState("06", &connection_state));
389  EXPECT_EQ(SocketInfo::kConnectionStateTimeWait, connection_state);
390  EXPECT_TRUE(reader_.ParseConnectionState("07", &connection_state));
391  EXPECT_EQ(SocketInfo::kConnectionStateClose, connection_state);
392  EXPECT_TRUE(reader_.ParseConnectionState("08", &connection_state));
393  EXPECT_EQ(SocketInfo::kConnectionStateCloseWait, connection_state);
394  EXPECT_TRUE(reader_.ParseConnectionState("09", &connection_state));
395  EXPECT_EQ(SocketInfo::kConnectionStateLastAck, connection_state);
396  EXPECT_TRUE(reader_.ParseConnectionState("0A", &connection_state));
397  EXPECT_EQ(SocketInfo::kConnectionStateListen, connection_state);
398  EXPECT_TRUE(reader_.ParseConnectionState("0B", &connection_state));
399  EXPECT_EQ(SocketInfo::kConnectionStateClosing, connection_state);
400
401  for (int i = SocketInfo::kConnectionStateMax; i < 256; ++i) {
402    EXPECT_TRUE(reader_.ParseConnectionState(
403        base::StringPrintf("%02X", i), &connection_state));
404    EXPECT_EQ(SocketInfo::kConnectionStateUnknown, connection_state);
405  }
406}
407
408TEST_F(SocketInfoReaderTest, ParseTimerState) {
409  SocketInfo::TimerState timer_state = SocketInfo::kTimerStateUnknown;
410
411  EXPECT_FALSE(reader_.ParseTimerState("", &timer_state));
412  EXPECT_FALSE(reader_.ParseTimerState("0", &timer_state));
413  EXPECT_FALSE(reader_.ParseTimerState("X", &timer_state));
414  EXPECT_FALSE(reader_.ParseTimerState("00", &timer_state));
415
416  EXPECT_TRUE(reader_.ParseTimerState("00:00000000", &timer_state));
417  EXPECT_EQ(SocketInfo::kTimerStateNoTimerPending, timer_state);
418  EXPECT_TRUE(reader_.ParseTimerState("01:00000000", &timer_state));
419  EXPECT_EQ(SocketInfo::kTimerStateRetransmitTimerPending, timer_state);
420  EXPECT_TRUE(reader_.ParseTimerState("02:00000000", &timer_state));
421  EXPECT_EQ(SocketInfo::kTimerStateAnotherTimerPending, timer_state);
422  EXPECT_TRUE(reader_.ParseTimerState("03:00000000", &timer_state));
423  EXPECT_EQ(SocketInfo::kTimerStateInTimeWaitState, timer_state);
424  EXPECT_TRUE(reader_.ParseTimerState("04:00000000", &timer_state));
425  EXPECT_EQ(SocketInfo::kTimerStateZeroWindowProbeTimerPending, timer_state);
426
427  for (int i = SocketInfo::kTimerStateMax; i < 256; ++i) {
428    EXPECT_TRUE(reader_.ParseTimerState(
429        base::StringPrintf("%02X:00000000", i), &timer_state));
430    EXPECT_EQ(SocketInfo::kTimerStateUnknown, timer_state);
431  }
432}
433
434}  // namespace shill
435