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