1// Copyright (c) 2012 The Chromium 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 "net/base/net_util.h"
6
7#include <string.h>
8
9#include <ostream>
10
11#include "base/files/file_path.h"
12#include "base/format_macros.h"
13#include "base/scoped_native_library.h"
14#include "base/strings/string_number_conversions.h"
15#include "base/strings/string_util.h"
16#include "base/strings/stringprintf.h"
17#include "base/strings/utf_string_conversions.h"
18#include "base/sys_byteorder.h"
19#include "base/time/time.h"
20#include "testing/gtest/include/gtest/gtest.h"
21#include "url/gurl.h"
22
23#if defined(OS_WIN)
24#include <iphlpapi.h>
25#include <objbase.h>
26#include "base/win/windows_version.h"
27#include "net/base/net_util_win.h"
28#elif !defined(OS_ANDROID)
29#include <net/if.h>
30#endif  // OS_WIN
31
32using base::ASCIIToUTF16;
33using base::WideToUTF16;
34
35namespace net {
36
37namespace {
38
39struct HeaderCase {
40  const char* header_name;
41  const char* expected;
42};
43
44struct CompliantHostCase {
45  const char* host;
46  const char* desired_tld;
47  bool expected_output;
48};
49
50// Fills in sockaddr for the given 32-bit address (IPv4.)
51// |bytes| should be an array of length 4.
52void MakeIPv4Address(const uint8* bytes, int port, SockaddrStorage* storage) {
53  memset(&storage->addr_storage, 0, sizeof(storage->addr_storage));
54  storage->addr_len = sizeof(struct sockaddr_in);
55  struct sockaddr_in* addr4 = reinterpret_cast<sockaddr_in*>(storage->addr);
56  addr4->sin_port = base::HostToNet16(port);
57  addr4->sin_family = AF_INET;
58  memcpy(&addr4->sin_addr, bytes, 4);
59}
60
61// Fills in sockaddr for the given 128-bit address (IPv6.)
62// |bytes| should be an array of length 16.
63void MakeIPv6Address(const uint8* bytes, int port, SockaddrStorage* storage) {
64  memset(&storage->addr_storage, 0, sizeof(storage->addr_storage));
65  storage->addr_len = sizeof(struct sockaddr_in6);
66  struct sockaddr_in6* addr6 = reinterpret_cast<sockaddr_in6*>(storage->addr);
67  addr6->sin6_port = base::HostToNet16(port);
68  addr6->sin6_family = AF_INET6;
69  memcpy(&addr6->sin6_addr, bytes, 16);
70}
71
72// Helper to strignize an IP number (used to define expectations).
73std::string DumpIPNumber(const IPAddressNumber& v) {
74  std::string out;
75  for (size_t i = 0; i < v.size(); ++i) {
76    if (i != 0)
77      out.append(",");
78    out.append(base::IntToString(static_cast<int>(v[i])));
79  }
80  return out;
81}
82
83}  // anonymous namespace
84
85TEST(NetUtilTest, GetIdentityFromURL) {
86  struct {
87    const char* input_url;
88    const char* expected_username;
89    const char* expected_password;
90  } tests[] = {
91    {
92      "http://username:password@google.com",
93      "username",
94      "password",
95    },
96    { // Test for http://crbug.com/19200
97      "http://username:p@ssword@google.com",
98      "username",
99      "p@ssword",
100    },
101    { // Special URL characters should be unescaped.
102      "http://username:p%3fa%26s%2fs%23@google.com",
103      "username",
104      "p?a&s/s#",
105    },
106    { // Username contains %20.
107      "http://use rname:password@google.com",
108      "use rname",
109      "password",
110    },
111    { // Keep %00 as is.
112      "http://use%00rname:password@google.com",
113      "use%00rname",
114      "password",
115    },
116    { // Use a '+' in the username.
117      "http://use+rname:password@google.com",
118      "use+rname",
119      "password",
120    },
121    { // Use a '&' in the password.
122      "http://username:p&ssword@google.com",
123      "username",
124      "p&ssword",
125    },
126  };
127  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
128    SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i,
129                                    tests[i].input_url));
130    GURL url(tests[i].input_url);
131
132    base::string16 username, password;
133    GetIdentityFromURL(url, &username, &password);
134
135    EXPECT_EQ(ASCIIToUTF16(tests[i].expected_username), username);
136    EXPECT_EQ(ASCIIToUTF16(tests[i].expected_password), password);
137  }
138}
139
140// Try extracting a username which was encoded with UTF8.
141TEST(NetUtilTest, GetIdentityFromURL_UTF8) {
142  GURL url(WideToUTF16(L"http://foo:\x4f60\x597d@blah.com"));
143
144  EXPECT_EQ("foo", url.username());
145  EXPECT_EQ("%E4%BD%A0%E5%A5%BD", url.password());
146
147  // Extract the unescaped identity.
148  base::string16 username, password;
149  GetIdentityFromURL(url, &username, &password);
150
151  // Verify that it was decoded as UTF8.
152  EXPECT_EQ(ASCIIToUTF16("foo"), username);
153  EXPECT_EQ(WideToUTF16(L"\x4f60\x597d"), password);
154}
155
156// Just a bunch of fake headers.
157const char* google_headers =
158    "HTTP/1.1 200 OK\n"
159    "Content-TYPE: text/html; charset=utf-8\n"
160    "Content-disposition: attachment; filename=\"download.pdf\"\n"
161    "Content-Length: 378557\n"
162    "X-Google-Google1: 314159265\n"
163    "X-Google-Google2: aaaa2:7783,bbb21:9441\n"
164    "X-Google-Google4: home\n"
165    "Transfer-Encoding: chunked\n"
166    "Set-Cookie: HEHE_AT=6666x66beef666x6-66xx6666x66; Path=/mail\n"
167    "Set-Cookie: HEHE_HELP=owned:0;Path=/\n"
168    "Set-Cookie: S=gmail=Xxx-beefbeefbeef_beefb:gmail_yj=beefbeef000beefbee"
169       "fbee:gmproxy=bee-fbeefbe; Domain=.google.com; Path=/\n"
170    "X-Google-Google2: /one/two/three/four/five/six/seven-height/nine:9411\n"
171    "Server: GFE/1.3\n"
172    "Transfer-Encoding: chunked\n"
173    "Date: Mon, 13 Nov 2006 21:38:09 GMT\n"
174    "Expires: Tue, 14 Nov 2006 19:23:58 GMT\n"
175    "X-Malformed: bla; arg=test\"\n"
176    "X-Malformed2: bla; arg=\n"
177    "X-Test: bla; arg1=val1; arg2=val2";
178
179TEST(NetUtilTest, GetSpecificHeader) {
180  const HeaderCase tests[] = {
181    {"content-type", "text/html; charset=utf-8"},
182    {"CONTENT-LENGTH", "378557"},
183    {"Date", "Mon, 13 Nov 2006 21:38:09 GMT"},
184    {"Bad-Header", ""},
185    {"", ""},
186  };
187
188  // Test first with google_headers.
189  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
190    std::string result =
191        GetSpecificHeader(google_headers, tests[i].header_name);
192    EXPECT_EQ(result, tests[i].expected);
193  }
194
195  // Test again with empty headers.
196  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
197    std::string result = GetSpecificHeader(std::string(), tests[i].header_name);
198    EXPECT_EQ(result, std::string());
199  }
200}
201
202TEST(NetUtilTest, CompliantHost) {
203  const CompliantHostCase compliant_host_cases[] = {
204    {"", "", false},
205    {"a", "", true},
206    {"-", "", false},
207    {".", "", false},
208    {"9", "", true},
209    {"9a", "", true},
210    {"a.", "", true},
211    {"a.a", "", true},
212    {"9.a", "", true},
213    {"a.9", "", true},
214    {"_9a", "", false},
215    {"-9a", "", false},
216    {"-9a", "a", true},
217    {"a.a9", "", true},
218    {"a.-a9", "", false},
219    {"a+9a", "", false},
220    {"-a.a9", "", true},
221    {"1-.a-b", "", true},
222    {"1_.a-b", "", false},
223    {"1-2.a_b", "", true},
224    {"a.b.c.d.e", "", true},
225    {"1.2.3.4.5", "", true},
226    {"1.2.3.4.5.", "", true},
227  };
228
229  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(compliant_host_cases); ++i) {
230    EXPECT_EQ(compliant_host_cases[i].expected_output,
231        IsCanonicalizedHostCompliant(compliant_host_cases[i].host,
232                                     compliant_host_cases[i].desired_tld));
233  }
234}
235
236TEST(NetUtilTest, ParseHostAndPort) {
237  const struct {
238    const char* input;
239    bool success;
240    const char* expected_host;
241    int expected_port;
242  } tests[] = {
243    // Valid inputs:
244    {"foo:10", true, "foo", 10},
245    {"foo", true, "foo", -1},
246    {
247      "[1080:0:0:0:8:800:200C:4171]:11",
248      true,
249      "1080:0:0:0:8:800:200C:4171",
250      11
251    },
252    {
253      "[1080:0:0:0:8:800:200C:4171]",
254      true,
255      "1080:0:0:0:8:800:200C:4171",
256      -1
257    },
258
259    // Because no validation is done on the host, the following are accepted,
260    // even though they are invalid names.
261    {"]", true, "]", -1},
262    {"::1", true, ":", 1},
263    // Invalid inputs:
264    {"foo:bar", false, "", -1},
265    {"foo:", false, "", -1},
266    {":", false, "", -1},
267    {":80", false, "", -1},
268    {"", false, "", -1},
269    {"porttoolong:300000", false, "", -1},
270    {"usrname@host", false, "", -1},
271    {"usrname:password@host", false, "", -1},
272    {":password@host", false, "", -1},
273    {":password@host:80", false, "", -1},
274    {":password@host", false, "", -1},
275    {"@host", false, "", -1},
276    {"[", false, "", -1},
277    {"[]", false, "", -1},
278  };
279
280  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
281    std::string host;
282    int port;
283    bool ok = ParseHostAndPort(tests[i].input, &host, &port);
284
285    EXPECT_EQ(tests[i].success, ok);
286
287    if (tests[i].success) {
288      EXPECT_EQ(tests[i].expected_host, host);
289      EXPECT_EQ(tests[i].expected_port, port);
290    }
291  }
292}
293
294TEST(NetUtilTest, GetHostAndPort) {
295  const struct {
296    GURL url;
297    const char* expected_host_and_port;
298  } tests[] = {
299    { GURL("http://www.foo.com/x"), "www.foo.com:80"},
300    { GURL("http://www.foo.com:21/x"), "www.foo.com:21"},
301
302    // For IPv6 literals should always include the brackets.
303    { GURL("http://[1::2]/x"), "[1::2]:80"},
304    { GURL("http://[::a]:33/x"), "[::a]:33"},
305  };
306  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
307    std::string host_and_port = GetHostAndPort(tests[i].url);
308    EXPECT_EQ(std::string(tests[i].expected_host_and_port), host_and_port);
309  }
310}
311
312TEST(NetUtilTest, GetHostAndOptionalPort) {
313  const struct {
314    GURL url;
315    const char* expected_host_and_port;
316  } tests[] = {
317    { GURL("http://www.foo.com/x"), "www.foo.com"},
318    { GURL("http://www.foo.com:21/x"), "www.foo.com:21"},
319
320    // For IPv6 literals should always include the brackets.
321    { GURL("http://[1::2]/x"), "[1::2]"},
322    { GURL("http://[::a]:33/x"), "[::a]:33"},
323  };
324  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
325    std::string host_and_port = GetHostAndOptionalPort(tests[i].url);
326    EXPECT_EQ(std::string(tests[i].expected_host_and_port), host_and_port);
327  }
328}
329
330TEST(NetUtilTest, IPAddressToString) {
331  uint8 addr1[4] = {0, 0, 0, 0};
332  EXPECT_EQ("0.0.0.0", IPAddressToString(addr1, sizeof(addr1)));
333
334  uint8 addr2[4] = {192, 168, 0, 1};
335  EXPECT_EQ("192.168.0.1", IPAddressToString(addr2, sizeof(addr2)));
336
337  uint8 addr3[16] = {0xFE, 0xDC, 0xBA, 0x98};
338  EXPECT_EQ("fedc:ba98::", IPAddressToString(addr3, sizeof(addr3)));
339}
340
341TEST(NetUtilTest, IPAddressToStringWithPort) {
342  uint8 addr1[4] = {0, 0, 0, 0};
343  EXPECT_EQ("0.0.0.0:3", IPAddressToStringWithPort(addr1, sizeof(addr1), 3));
344
345  uint8 addr2[4] = {192, 168, 0, 1};
346  EXPECT_EQ("192.168.0.1:99",
347            IPAddressToStringWithPort(addr2, sizeof(addr2), 99));
348
349  uint8 addr3[16] = {0xFE, 0xDC, 0xBA, 0x98};
350  EXPECT_EQ("[fedc:ba98::]:8080",
351            IPAddressToStringWithPort(addr3, sizeof(addr3), 8080));
352}
353
354TEST(NetUtilTest, NetAddressToString_IPv4) {
355  const struct {
356    uint8 addr[4];
357    const char* result;
358  } tests[] = {
359    {{0, 0, 0, 0}, "0.0.0.0"},
360    {{127, 0, 0, 1}, "127.0.0.1"},
361    {{192, 168, 0, 1}, "192.168.0.1"},
362  };
363
364  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
365    SockaddrStorage storage;
366    MakeIPv4Address(tests[i].addr, 80, &storage);
367    std::string result = NetAddressToString(storage.addr, storage.addr_len);
368    EXPECT_EQ(std::string(tests[i].result), result);
369  }
370}
371
372TEST(NetUtilTest, NetAddressToString_IPv6) {
373  const struct {
374    uint8 addr[16];
375    const char* result;
376  } tests[] = {
377    {{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0xFE, 0xDC, 0xBA,
378      0x98, 0x76, 0x54, 0x32, 0x10},
379     "fedc:ba98:7654:3210:fedc:ba98:7654:3210"},
380  };
381
382  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
383    SockaddrStorage storage;
384    MakeIPv6Address(tests[i].addr, 80, &storage);
385    EXPECT_EQ(std::string(tests[i].result),
386        NetAddressToString(storage.addr, storage.addr_len));
387  }
388}
389
390TEST(NetUtilTest, NetAddressToStringWithPort_IPv4) {
391  uint8 addr[] = {127, 0, 0, 1};
392  SockaddrStorage storage;
393  MakeIPv4Address(addr, 166, &storage);
394  std::string result = NetAddressToStringWithPort(storage.addr,
395                                                  storage.addr_len);
396  EXPECT_EQ("127.0.0.1:166", result);
397}
398
399TEST(NetUtilTest, NetAddressToStringWithPort_IPv6) {
400  uint8 addr[] = {
401      0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0xFE, 0xDC, 0xBA,
402      0x98, 0x76, 0x54, 0x32, 0x10
403  };
404  SockaddrStorage storage;
405  MakeIPv6Address(addr, 361, &storage);
406  std::string result = NetAddressToStringWithPort(storage.addr,
407                                                  storage.addr_len);
408
409  // May fail on systems that don't support IPv6.
410  if (!result.empty())
411    EXPECT_EQ("[fedc:ba98:7654:3210:fedc:ba98:7654:3210]:361", result);
412}
413
414TEST(NetUtilTest, GetHostName) {
415  // We can't check the result of GetHostName() directly, since the result
416  // will differ across machines. Our goal here is to simply exercise the
417  // code path, and check that things "look about right".
418  std::string hostname = GetHostName();
419  EXPECT_FALSE(hostname.empty());
420}
421
422TEST(NetUtilTest, SimplifyUrlForRequest) {
423  struct {
424    const char* input_url;
425    const char* expected_simplified_url;
426  } tests[] = {
427    {
428      // Reference section should be stripped.
429      "http://www.google.com:78/foobar?query=1#hash",
430      "http://www.google.com:78/foobar?query=1",
431    },
432    {
433      // Reference section can itself contain #.
434      "http://192.168.0.1?query=1#hash#10#11#13#14",
435      "http://192.168.0.1?query=1",
436    },
437    { // Strip username/password.
438      "http://user:pass@google.com",
439      "http://google.com/",
440    },
441    { // Strip both the reference and the username/password.
442      "http://user:pass@google.com:80/sup?yo#X#X",
443      "http://google.com/sup?yo",
444    },
445    { // Try an HTTPS URL -- strip both the reference and the username/password.
446      "https://user:pass@google.com:80/sup?yo#X#X",
447      "https://google.com:80/sup?yo",
448    },
449    { // Try an FTP URL -- strip both the reference and the username/password.
450      "ftp://user:pass@google.com:80/sup?yo#X#X",
451      "ftp://google.com:80/sup?yo",
452    },
453    { // Try a nonstandard URL
454      "foobar://user:pass@google.com:80/sup?yo#X#X",
455      "foobar://user:pass@google.com:80/sup?yo",
456    },
457  };
458  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
459    SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s", i,
460                                    tests[i].input_url));
461    GURL input_url(GURL(tests[i].input_url));
462    GURL expected_url(GURL(tests[i].expected_simplified_url));
463    EXPECT_EQ(expected_url, SimplifyUrlForRequest(input_url));
464  }
465}
466
467TEST(NetUtilTest, SetExplicitlyAllowedPortsTest) {
468  std::string invalid[] = { "1,2,a", "'1','2'", "1, 2, 3", "1 0,11,12" };
469  std::string valid[] = { "", "1", "1,2", "1,2,3", "10,11,12,13" };
470
471  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(invalid); ++i) {
472    SetExplicitlyAllowedPorts(invalid[i]);
473    EXPECT_EQ(0, static_cast<int>(GetCountOfExplicitlyAllowedPorts()));
474  }
475
476  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(valid); ++i) {
477    SetExplicitlyAllowedPorts(valid[i]);
478    EXPECT_EQ(i, GetCountOfExplicitlyAllowedPorts());
479  }
480}
481
482TEST(NetUtilTest, GetHostOrSpecFromURL) {
483  EXPECT_EQ("example.com",
484            GetHostOrSpecFromURL(GURL("http://example.com/test")));
485  EXPECT_EQ("example.com",
486            GetHostOrSpecFromURL(GURL("http://example.com./test")));
487  EXPECT_EQ("file:///tmp/test.html",
488            GetHostOrSpecFromURL(GURL("file:///tmp/test.html")));
489}
490
491TEST(NetUtilTest, GetAddressFamily) {
492  IPAddressNumber number;
493  EXPECT_TRUE(ParseIPLiteralToNumber("192.168.0.1", &number));
494  EXPECT_EQ(ADDRESS_FAMILY_IPV4, GetAddressFamily(number));
495  EXPECT_TRUE(ParseIPLiteralToNumber("1:abcd::3:4:ff", &number));
496  EXPECT_EQ(ADDRESS_FAMILY_IPV6, GetAddressFamily(number));
497}
498
499// Test that invalid IP literals fail to parse.
500TEST(NetUtilTest, ParseIPLiteralToNumber_FailParse) {
501  IPAddressNumber number;
502
503  EXPECT_FALSE(ParseIPLiteralToNumber("bad value", &number));
504  EXPECT_FALSE(ParseIPLiteralToNumber("bad:value", &number));
505  EXPECT_FALSE(ParseIPLiteralToNumber(std::string(), &number));
506  EXPECT_FALSE(ParseIPLiteralToNumber("192.168.0.1:30", &number));
507  EXPECT_FALSE(ParseIPLiteralToNumber("  192.168.0.1  ", &number));
508  EXPECT_FALSE(ParseIPLiteralToNumber("[::1]", &number));
509}
510
511// Test parsing an IPv4 literal.
512TEST(NetUtilTest, ParseIPLiteralToNumber_IPv4) {
513  IPAddressNumber number;
514  EXPECT_TRUE(ParseIPLiteralToNumber("192.168.0.1", &number));
515  EXPECT_EQ("192,168,0,1", DumpIPNumber(number));
516  EXPECT_EQ("192.168.0.1", IPAddressToString(number));
517}
518
519// Test parsing an IPv6 literal.
520TEST(NetUtilTest, ParseIPLiteralToNumber_IPv6) {
521  IPAddressNumber number;
522  EXPECT_TRUE(ParseIPLiteralToNumber("1:abcd::3:4:ff", &number));
523  EXPECT_EQ("0,1,171,205,0,0,0,0,0,0,0,3,0,4,0,255", DumpIPNumber(number));
524  EXPECT_EQ("1:abcd::3:4:ff", IPAddressToString(number));
525}
526
527// Test mapping an IPv4 address to an IPv6 address.
528TEST(NetUtilTest, ConvertIPv4NumberToIPv6Number) {
529  IPAddressNumber ipv4_number;
530  EXPECT_TRUE(ParseIPLiteralToNumber("192.168.0.1", &ipv4_number));
531
532  IPAddressNumber ipv6_number =
533      ConvertIPv4NumberToIPv6Number(ipv4_number);
534
535  // ::ffff:192.168.0.1
536  EXPECT_EQ("0,0,0,0,0,0,0,0,0,0,255,255,192,168,0,1",
537            DumpIPNumber(ipv6_number));
538  EXPECT_EQ("::ffff:c0a8:1", IPAddressToString(ipv6_number));
539}
540
541TEST(NetUtilTest, ParseURLHostnameToNumber_FailParse) {
542  IPAddressNumber number;
543
544  EXPECT_FALSE(ParseURLHostnameToNumber("bad value", &number));
545  EXPECT_FALSE(ParseURLHostnameToNumber("bad:value", &number));
546  EXPECT_FALSE(ParseURLHostnameToNumber(std::string(), &number));
547  EXPECT_FALSE(ParseURLHostnameToNumber("192.168.0.1:30", &number));
548  EXPECT_FALSE(ParseURLHostnameToNumber("  192.168.0.1  ", &number));
549  EXPECT_FALSE(ParseURLHostnameToNumber("::1", &number));
550}
551
552TEST(NetUtilTest, ParseURLHostnameToNumber_IPv4) {
553  IPAddressNumber number;
554  EXPECT_TRUE(ParseURLHostnameToNumber("192.168.0.1", &number));
555  EXPECT_EQ("192,168,0,1", DumpIPNumber(number));
556  EXPECT_EQ("192.168.0.1", IPAddressToString(number));
557}
558
559TEST(NetUtilTest, ParseURLHostnameToNumber_IPv6) {
560  IPAddressNumber number;
561  EXPECT_TRUE(ParseURLHostnameToNumber("[1:abcd::3:4:ff]", &number));
562  EXPECT_EQ("0,1,171,205,0,0,0,0,0,0,0,3,0,4,0,255", DumpIPNumber(number));
563  EXPECT_EQ("1:abcd::3:4:ff", IPAddressToString(number));
564}
565
566TEST(NetUtilTest, IsIPv4Mapped) {
567  IPAddressNumber ipv4_number;
568  EXPECT_TRUE(ParseIPLiteralToNumber("192.168.0.1", &ipv4_number));
569  EXPECT_FALSE(IsIPv4Mapped(ipv4_number));
570
571  IPAddressNumber ipv6_number;
572  EXPECT_TRUE(ParseIPLiteralToNumber("::1", &ipv4_number));
573  EXPECT_FALSE(IsIPv4Mapped(ipv6_number));
574
575  IPAddressNumber ipv4mapped_number;
576  EXPECT_TRUE(ParseIPLiteralToNumber("::ffff:0101:1", &ipv4mapped_number));
577  EXPECT_TRUE(IsIPv4Mapped(ipv4mapped_number));
578}
579
580TEST(NetUtilTest, ConvertIPv4MappedToIPv4) {
581  IPAddressNumber ipv4mapped_number;
582  EXPECT_TRUE(ParseIPLiteralToNumber("::ffff:0101:1", &ipv4mapped_number));
583  IPAddressNumber expected;
584  EXPECT_TRUE(ParseIPLiteralToNumber("1.1.0.1", &expected));
585  IPAddressNumber result = ConvertIPv4MappedToIPv4(ipv4mapped_number);
586  EXPECT_EQ(expected, result);
587}
588
589// Test parsing invalid CIDR notation literals.
590TEST(NetUtilTest, ParseCIDRBlock_Invalid) {
591  const char* bad_literals[] = {
592      "foobar",
593      "",
594      "192.168.0.1",
595      "::1",
596      "/",
597      "/1",
598      "1",
599      "192.168.1.1/-1",
600      "192.168.1.1/33",
601      "::1/-3",
602      "a::3/129",
603      "::1/x",
604      "192.168.0.1//11"
605  };
606
607  for (size_t i = 0; i < arraysize(bad_literals); ++i) {
608    IPAddressNumber ip_number;
609    size_t prefix_length_in_bits;
610
611    EXPECT_FALSE(ParseCIDRBlock(bad_literals[i],
612                                     &ip_number,
613                                     &prefix_length_in_bits));
614  }
615}
616
617// Test parsing a valid CIDR notation literal.
618TEST(NetUtilTest, ParseCIDRBlock_Valid) {
619  IPAddressNumber ip_number;
620  size_t prefix_length_in_bits;
621
622  EXPECT_TRUE(ParseCIDRBlock("192.168.0.1/11",
623                                  &ip_number,
624                                  &prefix_length_in_bits));
625
626  EXPECT_EQ("192,168,0,1", DumpIPNumber(ip_number));
627  EXPECT_EQ(11u, prefix_length_in_bits);
628}
629
630TEST(NetUtilTest, IPNumberMatchesPrefix) {
631  struct {
632    const char* cidr_literal;
633    const char* ip_literal;
634    bool expected_to_match;
635  } tests[] = {
636    // IPv4 prefix with IPv4 inputs.
637    {
638      "10.10.1.32/27",
639      "10.10.1.44",
640      true
641    },
642    {
643      "10.10.1.32/27",
644      "10.10.1.90",
645      false
646    },
647    {
648      "10.10.1.32/27",
649      "10.10.1.90",
650      false
651    },
652
653    // IPv6 prefix with IPv6 inputs.
654    {
655      "2001:db8::/32",
656      "2001:DB8:3:4::5",
657      true
658    },
659    {
660      "2001:db8::/32",
661      "2001:c8::",
662      false
663    },
664
665    // IPv6 prefix with IPv4 inputs.
666    {
667      "2001:db8::/33",
668      "192.168.0.1",
669      false
670    },
671    {
672      "::ffff:192.168.0.1/112",
673      "192.168.33.77",
674      true
675    },
676
677    // IPv4 prefix with IPv6 inputs.
678    {
679      "10.11.33.44/16",
680      "::ffff:0a0b:89",
681      true
682    },
683    {
684      "10.11.33.44/16",
685      "::ffff:10.12.33.44",
686      false
687    },
688  };
689  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
690    SCOPED_TRACE(base::StringPrintf("Test[%" PRIuS "]: %s, %s", i,
691                                    tests[i].cidr_literal,
692                                    tests[i].ip_literal));
693
694    IPAddressNumber ip_number;
695    EXPECT_TRUE(ParseIPLiteralToNumber(tests[i].ip_literal, &ip_number));
696
697    IPAddressNumber ip_prefix;
698    size_t prefix_length_in_bits;
699
700    EXPECT_TRUE(ParseCIDRBlock(tests[i].cidr_literal,
701                               &ip_prefix,
702                               &prefix_length_in_bits));
703
704    EXPECT_EQ(tests[i].expected_to_match,
705              IPNumberMatchesPrefix(ip_number,
706                                    ip_prefix,
707                                    prefix_length_in_bits));
708  }
709}
710
711TEST(NetUtilTest, IsLocalhost) {
712  EXPECT_TRUE(net::IsLocalhost("localhost"));
713  EXPECT_TRUE(net::IsLocalhost("localhost.localdomain"));
714  EXPECT_TRUE(net::IsLocalhost("localhost6"));
715  EXPECT_TRUE(net::IsLocalhost("localhost6.localdomain6"));
716  EXPECT_TRUE(net::IsLocalhost("127.0.0.1"));
717  EXPECT_TRUE(net::IsLocalhost("127.0.1.0"));
718  EXPECT_TRUE(net::IsLocalhost("127.1.0.0"));
719  EXPECT_TRUE(net::IsLocalhost("127.0.0.255"));
720  EXPECT_TRUE(net::IsLocalhost("127.0.255.0"));
721  EXPECT_TRUE(net::IsLocalhost("127.255.0.0"));
722  EXPECT_TRUE(net::IsLocalhost("::1"));
723  EXPECT_TRUE(net::IsLocalhost("0:0:0:0:0:0:0:1"));
724
725  EXPECT_FALSE(net::IsLocalhost("localhostx"));
726  EXPECT_FALSE(net::IsLocalhost("foo.localdomain"));
727  EXPECT_FALSE(net::IsLocalhost("localhost6x"));
728  EXPECT_FALSE(net::IsLocalhost("localhost.localdomain6"));
729  EXPECT_FALSE(net::IsLocalhost("localhost6.localdomain"));
730  EXPECT_FALSE(net::IsLocalhost("127.0.0.1.1"));
731  EXPECT_FALSE(net::IsLocalhost(".127.0.0.255"));
732  EXPECT_FALSE(net::IsLocalhost("::2"));
733  EXPECT_FALSE(net::IsLocalhost("::1:1"));
734  EXPECT_FALSE(net::IsLocalhost("0:0:0:0:1:0:0:1"));
735  EXPECT_FALSE(net::IsLocalhost("::1:1"));
736  EXPECT_FALSE(net::IsLocalhost("0:0:0:0:0:0:0:0:1"));
737}
738
739// Verify GetNetworkList().
740TEST(NetUtilTest, GetNetworkList) {
741  NetworkInterfaceList list;
742  ASSERT_TRUE(GetNetworkList(&list, INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES));
743  for (NetworkInterfaceList::iterator it = list.begin();
744       it != list.end(); ++it) {
745    // Verify that the names are not empty.
746    EXPECT_FALSE(it->name.empty());
747    EXPECT_FALSE(it->friendly_name.empty());
748
749    // Verify that the address is correct.
750    EXPECT_TRUE(it->address.size() == kIPv4AddressSize ||
751                it->address.size() == kIPv6AddressSize)
752        << "Invalid address of size " << it->address.size();
753    bool all_zeroes = true;
754    for (size_t i = 0; i < it->address.size(); ++i) {
755      if (it->address[i] != 0) {
756        all_zeroes = false;
757        break;
758      }
759    }
760    EXPECT_FALSE(all_zeroes);
761    EXPECT_GT(it->network_prefix, 1u);
762    EXPECT_LE(it->network_prefix, it->address.size() * 8);
763
764#if defined(OS_WIN)
765    // On Windows |name| is NET_LUID.
766    base::ScopedNativeLibrary phlpapi_lib(
767        base::FilePath(FILE_PATH_LITERAL("iphlpapi.dll")));
768    ASSERT_TRUE(phlpapi_lib.is_valid());
769    typedef NETIO_STATUS (WINAPI* ConvertInterfaceIndexToLuid)(NET_IFINDEX,
770                                                               PNET_LUID);
771    ConvertInterfaceIndexToLuid interface_to_luid =
772        reinterpret_cast<ConvertInterfaceIndexToLuid>(
773            phlpapi_lib.GetFunctionPointer("ConvertInterfaceIndexToLuid"));
774
775    typedef NETIO_STATUS (WINAPI* ConvertInterfaceLuidToGuid)(NET_LUID*,
776                                                              GUID*);
777    ConvertInterfaceLuidToGuid luid_to_guid =
778        reinterpret_cast<ConvertInterfaceLuidToGuid>(
779            phlpapi_lib.GetFunctionPointer("ConvertInterfaceLuidToGuid"));
780
781    if (interface_to_luid && luid_to_guid) {
782      NET_LUID luid;
783      EXPECT_EQ(interface_to_luid(it->interface_index, &luid), NO_ERROR);
784      GUID guid;
785      EXPECT_EQ(luid_to_guid(&luid, &guid), NO_ERROR);
786      LPOLESTR name;
787      StringFromCLSID(guid, &name);
788      EXPECT_STREQ(base::UTF8ToWide(it->name).c_str(), name);
789      CoTaskMemFree(name);
790      continue;
791    } else {
792      EXPECT_LT(base::win::GetVersion(), base::win::VERSION_VISTA);
793      EXPECT_LT(it->interface_index, 1u << 24u);  // Must fit 0.x.x.x.
794      EXPECT_NE(it->interface_index, 0u);  // 0 means to use default.
795    }
796    if (it->type == NetworkChangeNotifier::CONNECTION_WIFI) {
797      EXPECT_NE(WIFI_PHY_LAYER_PROTOCOL_NONE, GetWifiPHYLayerProtocol());
798    }
799#elif !defined(OS_ANDROID)
800    char name[IF_NAMESIZE];
801    EXPECT_TRUE(if_indextoname(it->interface_index, name));
802    EXPECT_STREQ(it->name.c_str(), name);
803#endif
804  }
805}
806
807namespace {
808
809#if defined(OS_WIN)
810bool read_int_or_bool(DWORD data_size,
811                      PVOID data) {
812  switch (data_size) {
813    case 1:
814      return !!*reinterpret_cast<uint8*>(data);
815    case 4:
816      return !!*reinterpret_cast<uint32*>(data);
817    default:
818      LOG(FATAL) << "That is not a type I know!";
819      return false;
820  }
821}
822
823int GetWifiOptions() {
824  const internal::WlanApi& wlanapi = internal::WlanApi::GetInstance();
825  if (!wlanapi.initialized)
826    return -1;
827
828  internal::WlanHandle client;
829  DWORD cur_version = 0;
830  const DWORD kMaxClientVersion = 2;
831  DWORD result = wlanapi.OpenHandle(
832      kMaxClientVersion, &cur_version, &client);
833  if (result != ERROR_SUCCESS)
834    return -1;
835
836  WLAN_INTERFACE_INFO_LIST* interface_list_ptr = NULL;
837  result = wlanapi.enum_interfaces_func(client.Get(), NULL,
838                                        &interface_list_ptr);
839  if (result != ERROR_SUCCESS)
840    return -1;
841  scoped_ptr<WLAN_INTERFACE_INFO_LIST, internal::WlanApiDeleter> interface_list(
842      interface_list_ptr);
843
844  for (unsigned i = 0; i < interface_list->dwNumberOfItems; ++i) {
845    WLAN_INTERFACE_INFO* info = &interface_list->InterfaceInfo[i];
846    DWORD data_size;
847    PVOID data;
848    int options = 0;
849    result = wlanapi.query_interface_func(
850        client.Get(),
851        &info->InterfaceGuid,
852        wlan_intf_opcode_background_scan_enabled,
853        NULL,
854        &data_size,
855        &data,
856        NULL);
857    if (result != ERROR_SUCCESS)
858      continue;
859    if (!read_int_or_bool(data_size, data)) {
860      options |= WIFI_OPTIONS_DISABLE_SCAN;
861    }
862    internal::WlanApi::GetInstance().free_memory_func(data);
863
864    result = wlanapi.query_interface_func(
865        client.Get(),
866        &info->InterfaceGuid,
867        wlan_intf_opcode_media_streaming_mode,
868        NULL,
869        &data_size,
870        &data,
871        NULL);
872    if (result != ERROR_SUCCESS)
873      continue;
874    if (read_int_or_bool(data_size, data)) {
875      options |= WIFI_OPTIONS_MEDIA_STREAMING_MODE;
876    }
877    internal::WlanApi::GetInstance().free_memory_func(data);
878
879    // Just the the options from the first succesful
880    // interface.
881    return options;
882  }
883
884  // No wifi interface found.
885  return -1;
886}
887
888#else  // OS_WIN
889
890int GetWifiOptions() {
891  // Not supported.
892  return -1;
893}
894
895#endif  // OS_WIN
896
897void TryChangeWifiOptions(int options) {
898  int previous_options = GetWifiOptions();
899  scoped_ptr<ScopedWifiOptions> scoped_options = SetWifiOptions(options);
900  EXPECT_EQ(previous_options | options, GetWifiOptions());
901  scoped_options.reset();
902  EXPECT_EQ(previous_options, GetWifiOptions());
903}
904
905};  // namespace
906
907// Test SetWifiOptions().
908TEST(NetUtilTest, SetWifiOptionsTest) {
909  TryChangeWifiOptions(0);
910  TryChangeWifiOptions(WIFI_OPTIONS_DISABLE_SCAN);
911  TryChangeWifiOptions(WIFI_OPTIONS_MEDIA_STREAMING_MODE);
912  TryChangeWifiOptions(WIFI_OPTIONS_DISABLE_SCAN |
913                       WIFI_OPTIONS_MEDIA_STREAMING_MODE);
914}
915
916struct NonUniqueNameTestData {
917  bool is_unique;
918  const char* hostname;
919};
920
921// Google Test pretty-printer.
922void PrintTo(const NonUniqueNameTestData& data, std::ostream* os) {
923  ASSERT_TRUE(data.hostname);
924  *os << " hostname: " << testing::PrintToString(data.hostname)
925      << "; is_unique: " << testing::PrintToString(data.is_unique);
926}
927
928const NonUniqueNameTestData kNonUniqueNameTestData[] = {
929    // Domains under ICANN-assigned domains.
930    { true, "google.com" },
931    { true, "google.co.uk" },
932    // Domains under private registries.
933    { true, "appspot.com" },
934    { true, "test.appspot.com" },
935    // Unreserved IPv4 addresses (in various forms).
936    { true, "8.8.8.8" },
937    { true, "99.64.0.0" },
938    { true, "212.15.0.0" },
939    { true, "212.15" },
940    { true, "212.15.0" },
941    { true, "3557752832" },
942    // Reserved IPv4 addresses (in various forms).
943    { false, "192.168.0.0" },
944    { false, "192.168.0.6" },
945    { false, "10.0.0.5" },
946    { false, "10.0" },
947    { false, "10.0.0" },
948    { false, "3232235526" },
949    // Unreserved IPv6 addresses.
950    { true, "FFC0:ba98:7654:3210:FEDC:BA98:7654:3210" },
951    { true, "2000:ba98:7654:2301:EFCD:BA98:7654:3210" },
952    // Reserved IPv6 addresses.
953    { false, "::192.9.5.5" },
954    { false, "FEED::BEEF" },
955    { false, "FEC0:ba98:7654:3210:FEDC:BA98:7654:3210" },
956    // 'internal'/non-IANA assigned domains.
957    { false, "intranet" },
958    { false, "intranet." },
959    { false, "intranet.example" },
960    { false, "host.intranet.example" },
961    // gTLDs under discussion, but not yet assigned.
962    { false, "intranet.corp" },
963    { false, "example.tech" },
964    { false, "intranet.internal" },
965    // Invalid host names are treated as unique - but expected to be
966    // filtered out before then.
967    { true, "junk)(£)$*!@~#" },
968    { true, "w$w.example.com" },
969    { true, "nocolonsallowed:example" },
970    { true, "[::4.5.6.9]" },
971};
972
973class NetUtilNonUniqueNameTest
974    : public testing::TestWithParam<NonUniqueNameTestData> {
975 public:
976  virtual ~NetUtilNonUniqueNameTest() {}
977
978 protected:
979  bool IsUnique(const std::string& hostname) {
980    return !IsHostnameNonUnique(hostname);
981  }
982};
983
984// Test that internal/non-unique names are properly identified as such, but
985// that IP addresses and hosts beneath registry-controlled domains are flagged
986// as unique names.
987TEST_P(NetUtilNonUniqueNameTest, IsHostnameNonUnique) {
988  const NonUniqueNameTestData& test_data = GetParam();
989
990  EXPECT_EQ(test_data.is_unique, IsUnique(test_data.hostname));
991}
992
993INSTANTIATE_TEST_CASE_P(, NetUtilNonUniqueNameTest,
994                        testing::ValuesIn(kNonUniqueNameTestData));
995
996}  // namespace net
997