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