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 using namespace lldb_private;
25 
26 //----------------------------------------------------------------------
27 // SocketAddress constructor
28 //----------------------------------------------------------------------
29 SocketAddress::SocketAddress ()
30 {
31     Clear ();
32 }
33 
34 SocketAddress::SocketAddress (const struct sockaddr &s)
35 {
36     m_socket_addr.sa = s;
37 }
38 
39 
40 SocketAddress::SocketAddress (const struct sockaddr_in &s)
41 {
42     m_socket_addr.sa_ipv4 = s;
43 }
44 
45 
46 SocketAddress::SocketAddress (const struct sockaddr_in6 &s)
47 {
48     m_socket_addr.sa_ipv6 = s;
49 }
50 
51 
52 SocketAddress::SocketAddress (const struct sockaddr_storage &s)
53 {
54     m_socket_addr.sa_storage = s;
55 }
56 
57 //----------------------------------------------------------------------
58 // SocketAddress copy constructor
59 //----------------------------------------------------------------------
60 SocketAddress::SocketAddress (const SocketAddress& rhs) :
61     m_socket_addr (rhs.m_socket_addr)
62 {
63 }
64 
65 //----------------------------------------------------------------------
66 // Destructor
67 //----------------------------------------------------------------------
68 SocketAddress::~SocketAddress()
69 {
70 }
71 
72 void
73 SocketAddress::Clear ()
74 {
75     memset (&m_socket_addr, 0, sizeof(m_socket_addr));
76 }
77 
78 bool
79 SocketAddress::IsValid () const
80 {
81     return GetLength () != 0;
82 }
83 
84 static socklen_t
85 GetFamilyLength (sa_family_t family)
86 {
87     switch (family)
88     {
89         case AF_INET:  return sizeof(struct sockaddr_in);
90         case AF_INET6: return sizeof(struct sockaddr_in6);
91     }
92     assert(0 && "Unsupported address family");
93     return 0;
94 }
95 
96 socklen_t
97 SocketAddress::GetLength () const
98 {
99 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
100     return m_socket_addr.sa.sa_len;
101 #else
102     return GetFamilyLength (GetFamily());
103 #endif
104 }
105 
106 socklen_t
107 SocketAddress::GetMaxLength ()
108 {
109     return sizeof (sockaddr_t);
110 }
111 
112 sa_family_t
113 SocketAddress::GetFamily () const
114 {
115     return m_socket_addr.sa.sa_family;
116 }
117 
118 void
119 SocketAddress::SetFamily (sa_family_t family)
120 {
121     m_socket_addr.sa.sa_family = family;
122 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
123     m_socket_addr.sa.sa_len = GetFamilyLength (family);
124 #endif
125 }
126 
127 uint16_t
128 SocketAddress::GetPort () const
129 {
130     switch (GetFamily())
131     {
132         case AF_INET:   return ntohs(m_socket_addr.sa_ipv4.sin_port);
133         case AF_INET6:  return ntohs(m_socket_addr.sa_ipv6.sin6_port);
134     }
135     return 0;
136 }
137 
138 bool
139 SocketAddress::SetPort (uint16_t port)
140 {
141     switch (GetFamily())
142     {
143         case AF_INET:
144             m_socket_addr.sa_ipv4.sin_port = htons(port);
145             return true;
146 
147         case AF_INET6:
148             m_socket_addr.sa_ipv6.sin6_port = htons(port);
149             return true;
150     }
151     return false;
152 }
153 
154 //----------------------------------------------------------------------
155 // SocketAddress assignment operator
156 //----------------------------------------------------------------------
157 const SocketAddress&
158 SocketAddress::operator=(const SocketAddress& rhs)
159 {
160     if (this != &rhs)
161         m_socket_addr = rhs.m_socket_addr;
162     return *this;
163 }
164 
165 const SocketAddress&
166 SocketAddress::operator=(const struct addrinfo *addr_info)
167 {
168     Clear();
169     if (addr_info &&
170         addr_info->ai_addr &&
171         addr_info->ai_addrlen > 0&&
172         addr_info->ai_addrlen <= sizeof m_socket_addr)
173     {
174         ::memcpy (&m_socket_addr,
175                   addr_info->ai_addr,
176                   addr_info->ai_addrlen);
177     }
178     return *this;
179 }
180 
181 const SocketAddress&
182 SocketAddress::operator=(const struct sockaddr &s)
183 {
184     m_socket_addr.sa = s;
185     return *this;
186 }
187 
188 const SocketAddress&
189 SocketAddress::operator=(const struct sockaddr_in &s)
190 {
191     m_socket_addr.sa_ipv4 = s;
192     return *this;
193 }
194 
195 const SocketAddress&
196 SocketAddress::operator=(const struct sockaddr_in6 &s)
197 {
198     m_socket_addr.sa_ipv6 = s;
199     return *this;
200 }
201 
202 const SocketAddress&
203 SocketAddress::operator=(const struct sockaddr_storage &s)
204 {
205     m_socket_addr.sa_storage = s;
206     return *this;
207 }
208 
209 bool
210 SocketAddress::getaddrinfo (const char *host,
211                             const char *service,
212                             int ai_family,
213                             int ai_socktype,
214                             int ai_protocol,
215                             int ai_flags)
216 {
217     struct addrinfo hints;
218     memset(&hints, 0, sizeof(hints));
219     hints.ai_family = ai_family;
220     hints.ai_socktype = ai_socktype;
221     hints.ai_protocol = ai_protocol;
222     hints.ai_flags = ai_flags;
223 
224     struct addrinfo *service_info_list = NULL;
225     int err = ::getaddrinfo (host, service, &hints, &service_info_list);
226     if (err == 0 && service_info_list)
227         *this = service_info_list;
228     else
229         Clear();
230 
231     :: freeaddrinfo (service_info_list);
232     return IsValid();
233 }
234 
235 
236 bool
237 SocketAddress::SetToLocalhost (sa_family_t family, uint16_t port)
238 {
239     switch (family)
240     {
241         case AF_INET:
242             SetFamily (AF_INET);
243             if (SetPort (port))
244             {
245                 m_socket_addr.sa_ipv4.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
246                 return true;
247             }
248             break;
249 
250         case AF_INET6:
251             SetFamily (AF_INET6);
252             if (SetPort (port))
253             {
254                 m_socket_addr.sa_ipv6.sin6_addr = in6addr_loopback;
255                 return true;
256             }
257             break;
258 
259     }
260     Clear();
261     return false;
262 }
263 
264 bool
265 SocketAddress::SetToAnyAddress (sa_family_t family, uint16_t port)
266 {
267     switch (family)
268     {
269         case AF_INET:
270             SetFamily (AF_INET);
271             if (SetPort (port))
272             {
273                 m_socket_addr.sa_ipv4.sin_addr.s_addr = htonl (INADDR_ANY);
274                 return true;
275             }
276             break;
277 
278         case AF_INET6:
279             SetFamily (AF_INET6);
280             if (SetPort (port))
281             {
282                 m_socket_addr.sa_ipv6.sin6_addr = in6addr_any;
283                 return true;
284             }
285             break;
286 
287     }
288     Clear();
289     return false;
290 }
291