1 //===-- SocketAddress.cpp ---------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Note: This file is used on Darwin by debugserver, so it needs to remain as 11 // self contained as possible, and devoid of references to LLVM unless 12 // there is compelling reason. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #if defined(_MSC_VER) 17 #define _WINSOCK_DEPRECATED_NO_WARNINGS 18 #endif 19 20 #include "lldb/Host/SocketAddress.h" 21 #include <stddef.h> 22 #include <stdio.h> 23 24 #if !defined(_WIN32) 25 #include <arpa/inet.h> 26 #endif 27 28 #include <assert.h> 29 #include <string.h> 30 31 #include "lldb/Host/PosixApi.h" 32 33 // WindowsXP needs an inet_ntop implementation 34 #ifdef _WIN32 35 36 #ifndef INET6_ADDRSTRLEN // might not be defined in older Windows SDKs 37 #define INET6_ADDRSTRLEN 46 38 #endif 39 40 // TODO: implement shortened form "::" for runs of zeros 41 const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) { 42 if (size == 0) { 43 return nullptr; 44 } 45 46 switch (af) { 47 case AF_INET: { 48 { 49 const char *formatted = inet_ntoa(*static_cast<const in_addr *>(src)); 50 if (formatted && strlen(formatted) < static_cast<size_t>(size)) { 51 return ::strcpy(dst, formatted); 52 } 53 } 54 return nullptr; 55 case AF_INET6: { 56 char tmp[INET6_ADDRSTRLEN] = {0}; 57 const uint16_t *src16 = static_cast<const uint16_t *>(src); 58 int full_size = ::snprintf( 59 tmp, sizeof(tmp), "%x:%x:%x:%x:%x:%x:%x:%x", ntohs(src16[0]), 60 ntohs(src16[1]), ntohs(src16[2]), ntohs(src16[3]), ntohs(src16[4]), 61 ntohs(src16[5]), ntohs(src16[6]), ntohs(src16[7])); 62 if (full_size < static_cast<int>(size)) { 63 return ::strcpy(dst, tmp); 64 } 65 return nullptr; 66 } 67 } 68 } 69 return nullptr; 70 } 71 #endif 72 73 using namespace lldb_private; 74 75 //---------------------------------------------------------------------- 76 // SocketAddress constructor 77 //---------------------------------------------------------------------- 78 SocketAddress::SocketAddress() { Clear(); } 79 80 SocketAddress::SocketAddress(const struct sockaddr &s) { m_socket_addr.sa = s; } 81 82 SocketAddress::SocketAddress(const struct sockaddr_in &s) { 83 m_socket_addr.sa_ipv4 = s; 84 } 85 86 SocketAddress::SocketAddress(const struct sockaddr_in6 &s) { 87 m_socket_addr.sa_ipv6 = s; 88 } 89 90 SocketAddress::SocketAddress(const struct sockaddr_storage &s) { 91 m_socket_addr.sa_storage = s; 92 } 93 94 SocketAddress::SocketAddress(const struct addrinfo *addr_info) { 95 *this = addr_info; 96 } 97 98 //---------------------------------------------------------------------- 99 // SocketAddress copy constructor 100 //---------------------------------------------------------------------- 101 SocketAddress::SocketAddress(const SocketAddress &rhs) 102 : m_socket_addr(rhs.m_socket_addr) {} 103 104 //---------------------------------------------------------------------- 105 // Destructor 106 //---------------------------------------------------------------------- 107 SocketAddress::~SocketAddress() {} 108 109 void SocketAddress::Clear() { 110 memset(&m_socket_addr, 0, sizeof(m_socket_addr)); 111 } 112 113 bool SocketAddress::IsValid() const { return GetLength() != 0; } 114 115 static socklen_t GetFamilyLength(sa_family_t family) { 116 switch (family) { 117 case AF_INET: 118 return sizeof(struct sockaddr_in); 119 case AF_INET6: 120 return sizeof(struct sockaddr_in6); 121 } 122 assert(0 && "Unsupported address family"); 123 return 0; 124 } 125 126 socklen_t SocketAddress::GetLength() const { 127 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) 128 return m_socket_addr.sa.sa_len; 129 #else 130 return GetFamilyLength(GetFamily()); 131 #endif 132 } 133 134 socklen_t SocketAddress::GetMaxLength() { return sizeof(sockaddr_t); } 135 136 sa_family_t SocketAddress::GetFamily() const { 137 return m_socket_addr.sa.sa_family; 138 } 139 140 void SocketAddress::SetFamily(sa_family_t family) { 141 m_socket_addr.sa.sa_family = family; 142 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) 143 m_socket_addr.sa.sa_len = GetFamilyLength(family); 144 #endif 145 } 146 147 std::string SocketAddress::GetIPAddress() const { 148 char str[INET6_ADDRSTRLEN] = {0}; 149 switch (GetFamily()) { 150 case AF_INET: 151 if (inet_ntop(GetFamily(), &m_socket_addr.sa_ipv4.sin_addr, str, 152 sizeof(str))) 153 return str; 154 break; 155 case AF_INET6: 156 if (inet_ntop(GetFamily(), &m_socket_addr.sa_ipv6.sin6_addr, str, 157 sizeof(str))) 158 return str; 159 break; 160 } 161 return ""; 162 } 163 164 uint16_t SocketAddress::GetPort() const { 165 switch (GetFamily()) { 166 case AF_INET: 167 return ntohs(m_socket_addr.sa_ipv4.sin_port); 168 case AF_INET6: 169 return ntohs(m_socket_addr.sa_ipv6.sin6_port); 170 } 171 return 0; 172 } 173 174 bool SocketAddress::SetPort(uint16_t port) { 175 switch (GetFamily()) { 176 case AF_INET: 177 m_socket_addr.sa_ipv4.sin_port = htons(port); 178 return true; 179 180 case AF_INET6: 181 m_socket_addr.sa_ipv6.sin6_port = htons(port); 182 return true; 183 } 184 return false; 185 } 186 187 //---------------------------------------------------------------------- 188 // SocketAddress assignment operator 189 //---------------------------------------------------------------------- 190 const SocketAddress &SocketAddress::operator=(const SocketAddress &rhs) { 191 if (this != &rhs) 192 m_socket_addr = rhs.m_socket_addr; 193 return *this; 194 } 195 196 const SocketAddress &SocketAddress:: 197 operator=(const struct addrinfo *addr_info) { 198 Clear(); 199 if (addr_info && addr_info->ai_addr && addr_info->ai_addrlen > 0 && 200 size_t(addr_info->ai_addrlen) <= sizeof m_socket_addr) { 201 ::memcpy(&m_socket_addr, addr_info->ai_addr, addr_info->ai_addrlen); 202 } 203 return *this; 204 } 205 206 const SocketAddress &SocketAddress::operator=(const struct sockaddr &s) { 207 m_socket_addr.sa = s; 208 return *this; 209 } 210 211 const SocketAddress &SocketAddress::operator=(const struct sockaddr_in &s) { 212 m_socket_addr.sa_ipv4 = s; 213 return *this; 214 } 215 216 const SocketAddress &SocketAddress::operator=(const struct sockaddr_in6 &s) { 217 m_socket_addr.sa_ipv6 = s; 218 return *this; 219 } 220 221 const SocketAddress &SocketAddress:: 222 operator=(const struct sockaddr_storage &s) { 223 m_socket_addr.sa_storage = s; 224 return *this; 225 } 226 227 bool SocketAddress::getaddrinfo(const char *host, const char *service, 228 int ai_family, int ai_socktype, int ai_protocol, 229 int ai_flags) { 230 Clear(); 231 232 auto addresses = GetAddressInfo(host, service, ai_family, ai_socktype, 233 ai_protocol, ai_flags); 234 if (!addresses.empty()) 235 *this = addresses[0]; 236 return IsValid(); 237 } 238 239 std::vector<SocketAddress> 240 SocketAddress::GetAddressInfo(const char *hostname, const char *servname, 241 int ai_family, int ai_socktype, int ai_protocol, 242 int ai_flags) { 243 std::vector<SocketAddress> addr_list; 244 245 struct addrinfo hints; 246 memset(&hints, 0, sizeof(hints)); 247 hints.ai_family = ai_family; 248 hints.ai_socktype = ai_socktype; 249 hints.ai_protocol = ai_protocol; 250 hints.ai_flags = ai_flags; 251 252 struct addrinfo *service_info_list = NULL; 253 int err = ::getaddrinfo(hostname, servname, &hints, &service_info_list); 254 if (err == 0 && service_info_list) { 255 for (struct addrinfo *service_ptr = service_info_list; service_ptr != NULL; 256 service_ptr = service_ptr->ai_next) { 257 addr_list.emplace_back(SocketAddress(service_ptr)); 258 } 259 } 260 261 if (service_info_list) 262 ::freeaddrinfo(service_info_list); 263 return addr_list; 264 } 265 266 bool SocketAddress::SetToLocalhost(sa_family_t family, uint16_t port) { 267 switch (family) { 268 case AF_INET: 269 SetFamily(AF_INET); 270 if (SetPort(port)) { 271 m_socket_addr.sa_ipv4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 272 return true; 273 } 274 break; 275 276 case AF_INET6: 277 SetFamily(AF_INET6); 278 if (SetPort(port)) { 279 m_socket_addr.sa_ipv6.sin6_addr = in6addr_loopback; 280 return true; 281 } 282 break; 283 } 284 Clear(); 285 return false; 286 } 287 288 bool SocketAddress::SetToAnyAddress(sa_family_t family, uint16_t port) { 289 switch (family) { 290 case AF_INET: 291 SetFamily(AF_INET); 292 if (SetPort(port)) { 293 m_socket_addr.sa_ipv4.sin_addr.s_addr = htonl(INADDR_ANY); 294 return true; 295 } 296 break; 297 298 case AF_INET6: 299 SetFamily(AF_INET6); 300 if (SetPort(port)) { 301 m_socket_addr.sa_ipv6.sin6_addr = in6addr_any; 302 return true; 303 } 304 break; 305 } 306 Clear(); 307 return false; 308 } 309 310 bool SocketAddress::IsAnyAddr() const { 311 return (GetFamily() == AF_INET) 312 ? m_socket_addr.sa_ipv4.sin_addr.s_addr == htonl(INADDR_ANY) 313 : 0 == memcmp(&m_socket_addr.sa_ipv6.sin6_addr, &in6addr_any, 16); 314 } 315 316 bool SocketAddress::IsLocalhost() const { 317 return (GetFamily() == AF_INET) 318 ? m_socket_addr.sa_ipv4.sin_addr.s_addr == htonl(INADDR_LOOPBACK) 319 : 0 == memcmp(&m_socket_addr.sa_ipv6.sin6_addr, &in6addr_loopback, 320 16); 321 } 322 323 bool SocketAddress::operator==(const SocketAddress &rhs) const { 324 if (GetFamily() != rhs.GetFamily()) 325 return false; 326 if (GetLength() != rhs.GetLength()) 327 return false; 328 switch (GetFamily()) { 329 case AF_INET: 330 return m_socket_addr.sa_ipv4.sin_addr.s_addr == 331 rhs.m_socket_addr.sa_ipv4.sin_addr.s_addr; 332 case AF_INET6: 333 return 0 == memcmp(&m_socket_addr.sa_ipv6.sin6_addr, 334 &rhs.m_socket_addr.sa_ipv6.sin6_addr, 16); 335 } 336 return false; 337 } 338 339 bool SocketAddress::operator!=(const SocketAddress &rhs) const { 340 return !(*this == rhs); 341 } 342