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