net_address_private_impl.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/private/net_address_private_impl.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <winsock2.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ws2tcpip.h> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) && !defined(OS_NACL) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <arpa/inet.h> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/socket.h> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stringprintf.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_var.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/private/ppb_net_address_private.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/var.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/thunk/thunk.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is a bit evil, but it's standard operating procedure for |s6_addr|.... 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define s6_addr16 __u6_addr.__u6_addr16 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The type of |sockaddr::sa_family|. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef ADDRESS_FAMILY sa_family_t; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define s6_addr16 u.Word 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ntohs(x) _byteswap_ushort(x) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define htons(x) _byteswap_ushort(x) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_WIN) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The net address interface doesn't have a normal C -> C++ thunk since it 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// doesn't actually have any proxy wrapping or associated objects; it's just a 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// call into base. So we implement the entire interface here, using the thunk 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// namespace so it magically gets hooked up in the proper places. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Define our own net-host-net conversion, rather than reuse the one in 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// base/sys_byteorder.h, to simplify the NaCl port. NaCl has no byte swap 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// primitives. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint16 ConvertNetEndian16(uint16 x) { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(ARCH_CPU_LITTLE_ENDIAN) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (x << 8) | (x >> 8); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return x; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kIPv4AddressSize = 4; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const size_t kIPv6AddressSize = 16; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This structure is a platform-independent representation of a network address. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// It is a private format that we embed in PP_NetAddress_Private and is NOT part 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of the stable Pepper API. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct NetAddress { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_valid; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_ipv6; // if true, IPv6, otherwise IPv4. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t port; // host order, not network order. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t flow_info; // 0 for IPv4 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t scope_id; // 0 for IPv4 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IPv4 addresses are 4 bytes. IPv6 are 16 bytes. Addresses are stored in net 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // order (big-endian), which only affects IPv6 addresses, which consist of 8 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 16-bit components. These will be byte-swapped on small-endian hosts. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8_t address[kIPv6AddressSize]; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure that sizeof(NetAddress) is the same for all compilers. This ensures 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that the alignment is the same on both sides of the NaCl proxy, which is 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// important because we serialize and deserialize PP_NetAddress_Private by 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// simply copying the raw bytes. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(sizeof(NetAddress) == 28, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress_different_for_compiler); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure the storage in |PP_NetAddress_Private| is big enough. (Do it here 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// since the data is opaque elsewhere.) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(sizeof(reinterpret_cast<PP_NetAddress_Private*>(0)->data) >= 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(NetAddress), 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_NetAddress_Private_data_too_small); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t GetAddressSize(const NetAddress* net_addr) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr->is_ipv6 ? kIPv6AddressSize : kIPv4AddressSize; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert to embedded struct if it has been initialized. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NetAddress* ToNetAddress(PP_NetAddress_Private* addr) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!addr || addr->size != sizeof(NetAddress)) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<NetAddress*>(addr->data); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const NetAddress* ToNetAddress(const PP_NetAddress_Private* addr) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ToNetAddress(const_cast<PP_NetAddress_Private*>(addr)); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Initializes the NetAddress struct embedded in a PP_NetAddress_Private struct. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Zeroes the memory, so net_addr->is_valid == false. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NetAddress* InitNetAddress(PP_NetAddress_Private* addr) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) addr->size = sizeof(NetAddress); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = ToNetAddress(addr); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(net_addr); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(net_addr, 0, sizeof(NetAddress)); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IsValid(const NetAddress* net_addr) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr && net_addr->is_valid; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_NetAddressFamily_Private GetFamily(const PP_NetAddress_Private* addr) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(addr); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_NETADDRESSFAMILY_UNSPECIFIED; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr->is_ipv6 ? 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_NETADDRESSFAMILY_IPV6 : PP_NETADDRESSFAMILY_IPV4; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint16_t GetPort(const PP_NetAddress_Private* addr) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(addr); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr->port; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool GetAddress(const PP_NetAddress_Private* addr, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* address, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t address_size) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(addr); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t net_addr_size = GetAddressSize(net_addr); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // address_size must be big enough. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net_addr_size > address_size) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(address, net_addr->address, net_addr_size); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_TRUE; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32_t GetScopeID(const PP_NetAddress_Private* addr) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(addr); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net_addr->scope_id; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool AreHostsEqual(const PP_NetAddress_Private* addr1, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_NetAddress_Private* addr2) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr1 = ToNetAddress(addr1); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr2 = ToNetAddress(addr2); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr1) || !IsValid(net_addr2)) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((net_addr1->is_ipv6 != net_addr2->is_ipv6) || 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (net_addr1->flow_info != net_addr2->flow_info) || 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (net_addr1->scope_id != net_addr2->scope_id)) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t net_addr_size = GetAddressSize(net_addr1); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < net_addr_size; i++) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net_addr1->address[i] != net_addr2->address[i]) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_TRUE; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool AreEqual(const PP_NetAddress_Private* addr1, 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_NetAddress_Private* addr2) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |AreHostsEqual()| will also validate the addresses and return false if 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // either is invalid. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!AreHostsEqual(addr1, addr2)) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AreHostsEqual has validated these net addresses. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr1 = ToNetAddress(addr1); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr2 = ToNetAddress(addr2); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FromBool(net_addr1->port == net_addr2->port); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ConvertIPv4AddressToString(const NetAddress* net_addr, 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool include_port) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string description = base::StringPrintf( 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "%u.%u.%u.%u", 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[0], net_addr->address[1], 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[2], net_addr->address[3]); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (include_port) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&description, ":%u", net_addr->port); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return description; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Format an IPv6 address for human consumption, basically according to RFC 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 5952. 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - If the scope is nonzero, it is appended to the address as "%<scope>" (this 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is not in RFC 5952, but consistent with |getnameinfo()| on Linux and 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Windows). 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - If |include_port| is true, the address (possibly including the scope) is 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enclosed in square brackets and ":<port>" is appended, i.e., the overall 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// format is "[<address>]:<port>". 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - If the address is an IPv4 address embedded IPv6 (per RFC 4291), then the 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// mixed format is used, e.g., "::ffff:192.168.1.2". This is optional per RFC 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 5952, but consistent with |getnameinfo()|. 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ConvertIPv6AddressToString(const NetAddress* net_addr, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool include_port) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string description(include_port ? "[" : ""); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint16_t* address16 = 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const uint16_t*>(net_addr->address); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IPv4 address embedded in IPv6. 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (address16[0] == 0 && address16[1] == 0 && 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address16[2] == 0 && address16[3] == 0 && 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address16[4] == 0 && 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (address16[5] == 0 || address16[5] == 0xffff)) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF( 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &description, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address16[5] == 0 ? "::%u.%u.%u.%u" : "::ffff:%u.%u.%u.%u", 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[12], 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[13], 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[14], 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->address[15]); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "Real" IPv6 addresses. 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the first longest run of 0s (of length > 1), to collapse to "::". 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int longest_start = 0; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int longest_length = 0; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int curr_start = 0; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int curr_length = 0; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 8; i++) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (address16[i] != 0) { 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_length = 0; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!curr_length) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_start = i; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curr_length++; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (curr_length > longest_length) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) longest_start = curr_start; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) longest_length = curr_length; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool need_sep = false; // Whether the next item needs a ':' to separate. 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 8;) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (longest_length > 1 && i == longest_start) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) description.append("::"); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) need_sep = false; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i += longest_length; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t v = ConvertNetEndian16(address16[i]); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&description, need_sep ? ":%x" : "%x", v); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) need_sep = true; 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i++; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Nonzero scopes, e.g., 123, are indicated by appending, e.g., "%123". 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net_addr->scope_id != 0) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&description, "%%%u", net_addr->scope_id); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (include_port) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringAppendF(&description, "]:%u", net_addr->port); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return description; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Var Describe(PP_Module /*module*/, 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct PP_NetAddress_Private* addr, 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_Bool include_port) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string str = NetAddressPrivateImpl::DescribeNetAddress( 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *addr, PP_ToBool(include_port)); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (str.empty()) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_MakeUndefined(); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return StringVar::StringToPPVar(str); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_Bool ReplacePort(const struct PP_NetAddress_Private* src_addr, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t port, 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct PP_NetAddress_Private* dest_addr) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* src_net_addr = ToNetAddress(src_addr); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(src_net_addr) || !dest_addr) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_FALSE; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest_addr->size = sizeof(NetAddress); // make sure 'size' is valid. 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* dest_net_addr = ToNetAddress(dest_addr); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *dest_net_addr = *src_net_addr; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dest_net_addr->port = port; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return PP_TRUE; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void GetAnyAddress(PP_Bool is_ipv6, PP_NetAddress_Private* addr) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (addr) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = InitNetAddress(addr); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = (is_ipv6 == PP_TRUE); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateFromIPv4Address(const uint8_t ip[4], 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t port, 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct PP_NetAddress_Private* addr) { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (addr) { 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = InitNetAddress(addr); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = false; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->port = port; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(net_addr->address, ip, kIPv4AddressSize); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateFromIPv6Address(const uint8_t ip[16], 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t scope_id, 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16_t port, 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct PP_NetAddress_Private* addr) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (addr) { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = InitNetAddress(addr); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = true; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->port = port; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->scope_id = scope_id; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(net_addr->address, ip, kIPv6AddressSize); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PPB_NetAddress_Private_0_1 net_address_private_interface_0_1 = { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreEqual, 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreHostsEqual, 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Describe, 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ReplacePort, 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetAnyAddress 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PPB_NetAddress_Private_1_0 net_address_private_interface_1_0 = { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreEqual, 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreHostsEqual, 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Describe, 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ReplacePort, 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetAnyAddress, 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetFamily, 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetPort, 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetAddress 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PPB_NetAddress_Private_1_1 net_address_private_interface_1_1 = { 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreEqual, 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &AreHostsEqual, 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Describe, 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ReplacePort, 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetAnyAddress, 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetFamily, 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetPort, 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetAddress, 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &GetScopeID, 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreateFromIPv4Address, 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &CreateFromIPv6Address 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace thunk { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPAPI_THUNK_EXPORT const PPB_NetAddress_Private_0_1* 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GetPPB_NetAddress_Private_0_1_Thunk() { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &net_address_private_interface_0_1; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPAPI_THUNK_EXPORT const PPB_NetAddress_Private_1_0* 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GetPPB_NetAddress_Private_1_0_Thunk() { 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &net_address_private_interface_1_0; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PPAPI_THUNK_EXPORT const PPB_NetAddress_Private_1_1* 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GetPPB_NetAddress_Private_1_1_Thunk() { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &net_address_private_interface_1_1; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace thunk 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For the NaCl target, all we need are the API functions and the thunk. 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_NACL) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PP_NetAddress_Private NetAddressPrivateImpl::kInvalidNetAddress = { 0 }; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NetAddressPrivateImpl::ValidateNetAddress( 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_NetAddress_Private& addr) { 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsValid(ToNetAddress(&addr)); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NetAddressPrivateImpl::SockaddrToNetAddress( 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sockaddr* sa, 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t sa_length, 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_NetAddress_Private* addr) { 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sa || sa_length == 0 || !addr) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Our platform neutral format stores ports in host order, not net order, 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so convert them here. 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = InitNetAddress(addr); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (sa->sa_family) { 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case AF_INET: { 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct sockaddr_in* addr4 = 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const struct sockaddr_in*>(sa); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = false; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->port = ConvertNetEndian16(addr4->sin_port); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(net_addr->address, &addr4->sin_addr.s_addr, kIPv4AddressSize); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case AF_INET6: { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct sockaddr_in6* addr6 = 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<const struct sockaddr_in6*>(sa); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = true; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->port = ConvertNetEndian16(addr6->sin6_port); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->flow_info = addr6->sin6_flowinfo; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->scope_id = addr6->sin6_scope_id; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(net_addr->address, addr6->sin6_addr.s6_addr, kIPv6AddressSize); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // InitNetAddress sets net_addr->is_valid to false. 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true;} 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NetAddressPrivateImpl::IPEndPointToNetAddress( 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<unsigned char>& address, 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port, 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_NetAddress_Private* addr) { 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!addr) 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetAddress* net_addr = InitNetAddress(addr); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (address.size()) { 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kIPv4AddressSize: { 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = false; 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->port = static_cast<uint16_t>(port); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::copy(address.begin(), address.end(), net_addr->address); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case kIPv6AddressSize: { 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_valid = true; 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->is_ipv6 = true; 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_addr->port = static_cast<uint16_t>(port); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::copy(address.begin(), address.end(), net_addr->address); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // InitNetAddress sets net_addr->is_valid to false. 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NetAddressPrivateImpl::NetAddressToIPEndPoint( 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_NetAddress_Private& addr, 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<unsigned char>* address, 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* port) { 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!address || !port) 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(&addr); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *port = net_addr->port; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t address_size = GetAddressSize(net_addr); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address->assign(&net_addr->address[0], &net_addr->address[address_size]); 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // !defined(OS_NACL) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string NetAddressPrivateImpl::DescribeNetAddress( 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PP_NetAddress_Private& addr, 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool include_port) { 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const NetAddress* net_addr = ToNetAddress(&addr); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsValid(net_addr)) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On Windows, |NetAddressToString()| doesn't work in the sandbox. On Mac, 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the output isn't consistent with RFC 5952, at least on Mac OS 10.6: 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |getnameinfo()| collapses length-one runs of zeros (and also doesn't 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // display the scope). 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (net_addr->is_ipv6) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ConvertIPv6AddressToString(net_addr, include_port); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ConvertIPv4AddressToString(net_addr, include_port); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ppapi 511