]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Host/common/SocketAddress.cpp
Merge ACPICA 20160930.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Host / common / SocketAddress.cpp
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                     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 //----------------------------------------------------------------------
82 SocketAddress::SocketAddress ()
83 {
84     Clear ();
85 }
86
87 SocketAddress::SocketAddress (const struct sockaddr &s)
88 {
89     m_socket_addr.sa = s;
90 }
91
92
93 SocketAddress::SocketAddress (const struct sockaddr_in &s)
94 {
95     m_socket_addr.sa_ipv4 = s;
96 }
97
98
99 SocketAddress::SocketAddress (const struct sockaddr_in6 &s)
100 {
101     m_socket_addr.sa_ipv6 = s;
102 }
103
104
105 SocketAddress::SocketAddress (const struct sockaddr_storage &s)
106 {
107     m_socket_addr.sa_storage = s;
108 }
109
110 //----------------------------------------------------------------------
111 // SocketAddress copy constructor
112 //----------------------------------------------------------------------
113 SocketAddress::SocketAddress (const SocketAddress& rhs) :
114     m_socket_addr (rhs.m_socket_addr)
115 {
116 }
117
118 //----------------------------------------------------------------------
119 // Destructor
120 //----------------------------------------------------------------------
121 SocketAddress::~SocketAddress()
122 {
123 }
124
125 void
126 SocketAddress::Clear ()
127 {
128     memset (&m_socket_addr, 0, sizeof(m_socket_addr));
129 }
130
131 bool
132 SocketAddress::IsValid () const
133 {
134     return GetLength () != 0;
135 }
136
137 static socklen_t 
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
150 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
160 SocketAddress::GetMaxLength ()
161 {
162     return sizeof (sockaddr_t);
163 }
164
165 sa_family_t
166 SocketAddress::GetFamily () const
167 {
168     return m_socket_addr.sa.sa_family;
169 }
170
171 void
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
181 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
201 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
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&
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&
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&
255 SocketAddress::operator=(const struct sockaddr &s)
256 {
257     m_socket_addr.sa = s;
258     return *this;
259 }
260
261 const SocketAddress&
262 SocketAddress::operator=(const struct sockaddr_in &s)
263 {
264     m_socket_addr.sa_ipv4 = s;
265     return *this;
266 }
267
268 const SocketAddress&
269 SocketAddress::operator=(const struct sockaddr_in6 &s)
270 {
271     m_socket_addr.sa_ipv6 = s;
272     return *this;
273 }
274
275 const SocketAddress&
276 SocketAddress::operator=(const struct sockaddr_storage &s)
277 {
278     m_socket_addr.sa_storage = s;
279     return *this;
280 }
281
282 bool
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     if (service_info_list)
309         ::freeaddrinfo(service_info_list);
310
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 }