SocketAddress.cpp revision 276479
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
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    return 0;
94}
95
96socklen_t
97SocketAddress::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
106socklen_t
107SocketAddress::GetMaxLength ()
108{
109    return sizeof (sockaddr_t);
110}
111
112sa_family_t
113SocketAddress::GetFamily () const
114{
115    return m_socket_addr.sa.sa_family;
116}
117
118void
119SocketAddress::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
127uint16_t
128SocketAddress::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
138bool
139SocketAddress::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//----------------------------------------------------------------------
157const SocketAddress&
158SocketAddress::operator=(const SocketAddress& rhs)
159{
160    if (this != &rhs)
161        m_socket_addr = rhs.m_socket_addr;
162    return *this;
163}
164
165const SocketAddress&
166SocketAddress::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
181const SocketAddress&
182SocketAddress::operator=(const struct sockaddr &s)
183{
184    m_socket_addr.sa = s;
185    return *this;
186}
187
188const SocketAddress&
189SocketAddress::operator=(const struct sockaddr_in &s)
190{
191    m_socket_addr.sa_ipv4 = s;
192    return *this;
193}
194
195const SocketAddress&
196SocketAddress::operator=(const struct sockaddr_in6 &s)
197{
198    m_socket_addr.sa_ipv6 = s;
199    return *this;
200}
201
202const SocketAddress&
203SocketAddress::operator=(const struct sockaddr_storage &s)
204{
205    m_socket_addr.sa_storage = s;
206    return *this;
207}
208
209bool
210SocketAddress::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
236bool
237SocketAddress::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
264bool
265SocketAddress::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