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