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