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 "ppapi/tests/test_net_address_private.h" 6 7 #include <string.h> 8 9 #include "ppapi/cpp/private/net_address_private.h" 10 #include "ppapi/c/private/ppb_net_address_private.h" 11 #include "ppapi/tests/test_utils.h" 12 #include "ppapi/tests/testing_instance.h" 13 14 using pp::NetAddressPrivate; 15 16 namespace { 17 18 PP_NetAddress_Private MakeIPv4NetAddress(const uint8_t host[4], int port) { 19 PP_NetAddress_Private addr; 20 NetAddressPrivate::CreateFromIPv4Address(host, port, &addr); 21 return addr; 22 } 23 24 PP_NetAddress_Private MakeIPv6NetAddress(const uint16_t host[8], uint16_t port, 25 uint32_t scope_id) { 26 PP_NetAddress_Private addr = PP_NetAddress_Private(); 27 uint8_t ip[16]; 28 for(int i = 0; i < 8; ++i) { 29 ip[i * 2] = host[i] >> 8; 30 ip[i * 2 + 1] = host[i] & 0xff; 31 } 32 NetAddressPrivate::CreateFromIPv6Address(ip, scope_id, port, &addr); 33 return addr; 34 } 35 36 } // namespace 37 38 REGISTER_TEST_CASE(NetAddressPrivate); 39 40 TestNetAddressPrivate::TestNetAddressPrivate(TestingInstance* instance) 41 : TestCase(instance) { 42 } 43 44 bool TestNetAddressPrivate::Init() { 45 return NetAddressPrivate::IsAvailable(); 46 } 47 48 void TestNetAddressPrivate::RunTests(const std::string& filter) { 49 RUN_TEST(AreEqual, filter); 50 RUN_TEST(AreHostsEqual, filter); 51 RUN_TEST(Describe, filter); 52 RUN_TEST(ReplacePort, filter); 53 RUN_TEST(GetAnyAddress, filter); 54 RUN_TEST(DescribeIPv6, filter); 55 RUN_TEST(GetFamily, filter); 56 RUN_TEST(GetPort, filter); 57 RUN_TEST(GetAddress, filter); 58 RUN_TEST(GetScopeID, filter); 59 } 60 61 std::string TestNetAddressPrivate::TestAreEqual() { 62 // No comparisons should ever be done with invalid addresses. 63 PP_NetAddress_Private invalid = PP_NetAddress_Private(); 64 ASSERT_FALSE(NetAddressPrivate::AreEqual(invalid, invalid)); 65 66 uint8_t localhost_ip[4] = { 127, 0, 0, 1 }; 67 PP_NetAddress_Private localhost_80 = MakeIPv4NetAddress(localhost_ip, 80); 68 ASSERT_TRUE(NetAddressPrivate::AreEqual(localhost_80, localhost_80)); 69 ASSERT_FALSE(NetAddressPrivate::AreEqual(localhost_80, invalid)); 70 71 PP_NetAddress_Private localhost_1234 = MakeIPv4NetAddress(localhost_ip, 1234); 72 ASSERT_FALSE(NetAddressPrivate::AreEqual(localhost_80, localhost_1234)); 73 74 uint8_t other_ip[4] = { 192, 168, 0, 1 }; 75 PP_NetAddress_Private other_80 = MakeIPv4NetAddress(other_ip, 80); 76 ASSERT_FALSE(NetAddressPrivate::AreEqual(localhost_80, other_80)); 77 78 PASS(); 79 } 80 81 std::string TestNetAddressPrivate::TestAreHostsEqual() { 82 // No comparisons should ever be done with invalid addresses. 83 PP_NetAddress_Private invalid = PP_NetAddress_Private(); 84 ASSERT_FALSE(NetAddressPrivate::AreHostsEqual(invalid, invalid)); 85 86 uint8_t localhost_ip[4] = { 127, 0, 0, 1 }; 87 PP_NetAddress_Private localhost_80 = MakeIPv4NetAddress(localhost_ip, 80); 88 ASSERT_TRUE(NetAddressPrivate::AreHostsEqual(localhost_80, localhost_80)); 89 ASSERT_FALSE(NetAddressPrivate::AreHostsEqual(localhost_80, invalid)); 90 91 PP_NetAddress_Private localhost_1234 = MakeIPv4NetAddress(localhost_ip, 1234); 92 ASSERT_TRUE(NetAddressPrivate::AreHostsEqual(localhost_80, localhost_1234)); 93 94 uint8_t other_ip[4] = { 192, 168, 0, 1 }; 95 PP_NetAddress_Private other_80 = MakeIPv4NetAddress(other_ip, 80); 96 ASSERT_FALSE(NetAddressPrivate::AreHostsEqual(localhost_80, other_80)); 97 98 PASS(); 99 } 100 101 std::string TestNetAddressPrivate::TestDescribe() { 102 PP_NetAddress_Private invalid = PP_NetAddress_Private(); 103 ASSERT_EQ("", NetAddressPrivate::Describe(invalid, false)); 104 ASSERT_EQ("", NetAddressPrivate::Describe(invalid, true)); 105 106 uint8_t localhost_ip[4] = { 127, 0, 0, 1 }; 107 PP_NetAddress_Private localhost_80 = MakeIPv4NetAddress(localhost_ip, 80); 108 ASSERT_EQ("127.0.0.1", NetAddressPrivate::Describe(localhost_80, false)); 109 ASSERT_EQ("127.0.0.1:80", NetAddressPrivate::Describe(localhost_80, true)); 110 111 PP_NetAddress_Private localhost_1234 = MakeIPv4NetAddress(localhost_ip, 1234); 112 ASSERT_EQ("127.0.0.1", NetAddressPrivate::Describe(localhost_1234, false)); 113 ASSERT_EQ("127.0.0.1:1234", NetAddressPrivate::Describe(localhost_1234, 114 true)); 115 116 uint8_t other_ip[4] = { 192, 168, 0, 1 }; 117 PP_NetAddress_Private other_80 = MakeIPv4NetAddress(other_ip, 80); 118 ASSERT_EQ("192.168.0.1", NetAddressPrivate::Describe(other_80, false)); 119 ASSERT_EQ("192.168.0.1:80", NetAddressPrivate::Describe(other_80, true)); 120 121 PASS(); 122 } 123 124 std::string TestNetAddressPrivate::TestReplacePort() { 125 // Assume that |AreEqual()| works correctly. 126 PP_NetAddress_Private result = PP_NetAddress_Private(); 127 128 PP_NetAddress_Private invalid = PP_NetAddress_Private(); 129 ASSERT_FALSE(NetAddressPrivate::ReplacePort(invalid, 1234, &result)); 130 131 uint8_t localhost_ip[4] = { 127, 0, 0, 1 }; 132 PP_NetAddress_Private localhost_80 = MakeIPv4NetAddress(localhost_ip, 80); 133 ASSERT_TRUE(NetAddressPrivate::ReplacePort(localhost_80, 1234, &result)); 134 PP_NetAddress_Private localhost_1234 = MakeIPv4NetAddress(localhost_ip, 1234); 135 ASSERT_TRUE(NetAddressPrivate::AreEqual(result, localhost_1234)); 136 137 // Test that having the out param being the same as the in param works 138 // properly. 139 ASSERT_TRUE(NetAddressPrivate::ReplacePort(result, 80, &result)); 140 ASSERT_TRUE(NetAddressPrivate::AreEqual(result, localhost_80)); 141 142 PASS(); 143 } 144 145 std::string TestNetAddressPrivate::TestGetAnyAddress() { 146 // Just make sure it doesn't crash and such. 147 PP_NetAddress_Private result = PP_NetAddress_Private(); 148 149 NetAddressPrivate::GetAnyAddress(false, &result); 150 ASSERT_TRUE(NetAddressPrivate::AreEqual(result, result)); 151 152 NetAddressPrivate::GetAnyAddress(true, &result); 153 ASSERT_TRUE(NetAddressPrivate::AreEqual(result, result)); 154 155 PASS(); 156 } 157 158 // TODO(viettrungluu): More IPv6 tests needed. 159 160 std::string TestNetAddressPrivate::TestDescribeIPv6() { 161 static const struct { 162 uint16_t address[8]; 163 uint16_t port; 164 uint32_t scope; 165 const char* expected_without_port; 166 const char* expected_with_port; 167 } test_cases[] = { 168 { // Generic test case (unique longest run of zeros to collapse). 169 { 0x12, 0xabcd, 0, 0x0001, 0, 0, 0, 0xcdef }, 12, 0, 170 "12:abcd:0:1::cdef", "[12:abcd:0:1::cdef]:12" 171 }, 172 { // Non-zero scope. 173 { 0x1234, 0xabcd, 0, 0x0001, 0, 0, 0, 0xcdef }, 1234, 789, 174 "1234:abcd:0:1::cdef%789", "[1234:abcd:0:1::cdef%789]:1234" 175 }, 176 { // Ignore the first (non-longest) run of zeros. 177 { 0, 0, 0, 0x0123, 0, 0, 0, 0 }, 123, 0, 178 "0:0:0:123::", "[0:0:0:123::]:123" 179 }, 180 { // Collapse the first (equally-longest) run of zeros. 181 { 0x1234, 0xabcd, 0, 0, 0xff, 0, 0, 0xcdef }, 123, 0, 182 "1234:abcd::ff:0:0:cdef", "[1234:abcd::ff:0:0:cdef]:123" 183 }, 184 { // Don't collapse "runs" of zeros of length 1. 185 { 0, 0xa, 1, 2, 3, 0, 5, 0 }, 123, 0, 186 "0:a:1:2:3:0:5:0", "[0:a:1:2:3:0:5:0]:123" 187 }, 188 { // Collapse a run of zeros at the beginning. 189 { 0, 0, 0, 2, 3, 0, 0, 0 }, 123, 0, 190 "::2:3:0:0:0", "[::2:3:0:0:0]:123" 191 }, 192 { // Collapse a run of zeros at the end. 193 { 0, 0xa, 1, 2, 3, 0, 0, 0 }, 123, 0, 194 "0:a:1:2:3::", "[0:a:1:2:3::]:123" 195 }, 196 { // IPv4 192.168.1.2 embedded in IPv6 in the deprecated way. 197 { 0, 0, 0, 0, 0, 0, 0xc0a8, 0x102 }, 123, 0, 198 "::192.168.1.2", "[::192.168.1.2]:123" 199 }, 200 { // ... with non-zero scope. 201 { 0, 0, 0, 0, 0, 0, 0xc0a8, 0x102 }, 123, 789, 202 "::192.168.1.2%789", "[::192.168.1.2%789]:123" 203 }, 204 { // IPv4 192.168.1.2 embedded in IPv6. 205 { 0, 0, 0, 0, 0, 0xffff, 0xc0a8, 0x102 }, 123, 0, 206 "::ffff:192.168.1.2", "[::ffff:192.168.1.2]:123" 207 }, 208 { // ... with non-zero scope. 209 { 0, 0, 0, 0, 0, 0xffff, 0xc0a8, 0x102 }, 123, 789, 210 "::ffff:192.168.1.2%789", "[::ffff:192.168.1.2%789]:123" 211 }, 212 { // *Not* IPv4 embedded in IPv6. 213 { 0, 0, 0, 0, 0, 0x1234, 0xc0a8, 0x102 }, 123, 0, 214 "::1234:c0a8:102", "[::1234:c0a8:102]:123" 215 } 216 }; 217 218 for (size_t i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); i++) { 219 PP_NetAddress_Private addr = MakeIPv6NetAddress(test_cases[i].address, 220 test_cases[i].port, 221 test_cases[i].scope); 222 ASSERT_EQ(test_cases[i].expected_without_port, 223 NetAddressPrivate::Describe(addr, false)); 224 ASSERT_EQ(test_cases[i].expected_with_port, 225 NetAddressPrivate::Describe(addr, true)); 226 } 227 228 PASS(); 229 } 230 231 std::string TestNetAddressPrivate::TestGetFamily() { 232 uint8_t localhost_ip[4] = { 127, 0, 0, 1 }; 233 PP_NetAddress_Private ipv4 = MakeIPv4NetAddress(localhost_ip, 80); 234 ASSERT_EQ(NetAddressPrivate::GetFamily(ipv4), 235 PP_NETADDRESSFAMILY_PRIVATE_IPV4); 236 237 uint16_t ipv6_address[8] = { 0x1234, 0xabcd, 0, 0, 0xff, 0, 0, 0xcdef }; 238 PP_NetAddress_Private ipv6 = MakeIPv6NetAddress(ipv6_address, 123, 0); 239 ASSERT_EQ(NetAddressPrivate::GetFamily(ipv6), 240 PP_NETADDRESSFAMILY_PRIVATE_IPV6); 241 242 PASS(); 243 } 244 245 std::string TestNetAddressPrivate::TestGetPort() { 246 uint8_t localhost_ip[4] = { 127, 0, 0, 1 }; 247 PP_NetAddress_Private localhost_80 = MakeIPv4NetAddress(localhost_ip, 80); 248 ASSERT_EQ(NetAddressPrivate::GetPort(localhost_80), 80); 249 250 uint16_t ipv6_address[8] = { 0x1234, 0xabcd, 0, 0, 0xff, 0, 0, 0xcdef }; 251 252 PP_NetAddress_Private port_123 = MakeIPv6NetAddress(ipv6_address, 123, 0); 253 ASSERT_EQ(NetAddressPrivate::GetPort(port_123), 123); 254 255 PP_NetAddress_Private port_FFFF = MakeIPv6NetAddress(ipv6_address, 256 0xFFFF, 257 0); 258 ASSERT_EQ(NetAddressPrivate::GetPort(port_FFFF), 0xFFFF); 259 260 PASS(); 261 } 262 263 std::string TestNetAddressPrivate::TestGetAddress() { 264 const int addr_storage_len = 16; 265 unsigned char addr_storage[addr_storage_len]; 266 267 const uint8_t ipv4_addr[4] = { 127, 0, 0, 1 }; 268 PP_NetAddress_Private localhost_80 = MakeIPv4NetAddress(ipv4_addr, 80); 269 memset(addr_storage, 0, addr_storage_len); 270 ASSERT_TRUE(NetAddressPrivate::GetAddress(localhost_80, 271 addr_storage, 272 addr_storage_len)); 273 ASSERT_EQ(memcmp(addr_storage, &ipv4_addr, 4), 0); 274 275 // Insufficient storage for address. 276 ASSERT_FALSE(NetAddressPrivate::GetAddress(localhost_80, 277 addr_storage, 278 1)); 279 280 uint16_t ipv6_address[8] = { 0x1234, 0xabcd, 0, 0, 0xff, 0, 0, 0xcdef }; 281 PP_NetAddress_Private ipv6_addr = MakeIPv6NetAddress(ipv6_address, 282 123, 283 0); 284 285 // Ensure the ipv6 address is transformed properly into network order. 286 uint8_t ipv6_bytes[16]; 287 for(int i = 0; i < 8; ++i) { 288 ipv6_bytes[i * 2] = ipv6_address[i] >> 8; 289 ipv6_bytes[i * 2 + 1] = ipv6_address[i] & 0xFF; 290 } 291 292 memset(addr_storage, 0, addr_storage_len); 293 ASSERT_TRUE(NetAddressPrivate::GetAddress(ipv6_addr, 294 addr_storage, 295 addr_storage_len)); 296 ASSERT_EQ(memcmp(addr_storage, ipv6_bytes, 16), 0); 297 298 // Insufficient storage for address. 299 ASSERT_FALSE(NetAddressPrivate::GetAddress(ipv6_addr, 300 addr_storage, 301 1)); 302 303 PASS(); 304 } 305 306 std::string TestNetAddressPrivate::TestGetScopeID() { 307 uint8_t localhost_ip[4] = { 127, 0, 0, 1 }; 308 PP_NetAddress_Private ipv4 = MakeIPv4NetAddress(localhost_ip, 80); 309 ASSERT_EQ(NetAddressPrivate::GetScopeID(ipv4), 0); 310 311 uint16_t ipv6_address[8] = { 0x1234, 0xabcd, 0, 0, 0xff, 0, 0, 0xcdef }; 312 313 PP_NetAddress_Private ipv6_123 = MakeIPv6NetAddress(ipv6_address, 0, 123); 314 ASSERT_EQ(NetAddressPrivate::GetScopeID(ipv6_123), 123); 315 316 PP_NetAddress_Private ipv6_max = 317 MakeIPv6NetAddress(ipv6_address, 0, 0xFFFFFFFF); 318 ASSERT_EQ(NetAddressPrivate::GetScopeID(ipv6_max), 0xFFFFFFFF); 319 320 PASS(); 321 } 322