1 /*****************************************************************
2 |
3 | Neptune - Network :: BSD Implementation
4 |
5 | (c) 2001-2005 Gilles Boccon-Gibod
6 | Author: Gilles Boccon-Gibod (bok@bok.net)
7 |
8 ****************************************************************/
9
10 /*----------------------------------------------------------------------
11 | includes
12 +---------------------------------------------------------------------*/
13 #if (defined(_WIN32) || defined(_WIN32_WCE) || defined(_XBOX)) && !defined(__SYMBIAN32__)
14 #if !defined(__WINSOCK__)
15 #define __WINSOCK__
16 #endif
17 #endif
18
19 #if defined(__WINSOCK__) && !defined(_XBOX)
20 #define STRICT
21 #define NPT_WIN32_USE_WINSOCK2
22 #ifdef NPT_WIN32_USE_WINSOCK2
23 /* it is important to include this in this order, because winsock.h and ws2tcpip.h */
24 /* have different definitions for the same preprocessor symbols, such as IP_ADD_MEMBERSHIP */
25 #include <winsock2.h>
26 #include <ws2tcpip.h>
27 #else
28 #include <winsock.h>
29 #endif
30 #include <windows.h>
31
32 // force a reference to the initializer so that the linker does not optimize it out
33 #include "NptWin32Network.h" // we need this for the static initializer
34 static NPT_WinsockSystem& WinsockInitializer = NPT_WinsockSystem::Initializer;
35
36 #else
37
38 #include <sys/types.h>
39 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <netdb.h>
42 #include <errno.h>
43
44 #endif
45
46 #include "NptConfig.h"
47 #include "NptTypes.h"
48 #include "NptNetwork.h"
49 #include "NptUtils.h"
50 #include "NptConstants.h"
51 #include "NptResults.h"
52 #include "NptSockets.h"
53
54 #if defined(NPT_CONFIG_HAVE_GETADDRINFO)
55 /*----------------------------------------------------------------------
56 | constants
57 +---------------------------------------------------------------------*/
58 const unsigned int NPT_BSD_NETWORK_MAX_ADDR_LIST_LENGTH = 1024;
59
60 /*----------------------------------------------------------------------
61 | IPv6 support
62 +---------------------------------------------------------------------*/
63 #if defined(NPT_CONFIG_ENABLE_IPV6)
64 #include <arpa/inet.h>
65 #endif
66
67 /*----------------------------------------------------------------------
68 | MapGetAddrInfoErrorCode
69 +---------------------------------------------------------------------*/
70 static NPT_Result
MapGetAddrInfoErrorCode(int)71 MapGetAddrInfoErrorCode(int /*error_code*/)
72 {
73 return NPT_ERROR_HOST_UNKNOWN;
74 }
75
76 /*----------------------------------------------------------------------
77 | NPT_NetworkNameResolver::Resolve
78 +---------------------------------------------------------------------*/
79 NPT_Result
Resolve(const char * name,NPT_List<NPT_IpAddress> & addresses,NPT_Timeout)80 NPT_NetworkNameResolver::Resolve(const char* name,
81 NPT_List<NPT_IpAddress>& addresses,
82 NPT_Timeout /*timeout*/)
83 {
84 // empty the list first
85 addresses.Clear();
86
87
88 // get the addr list
89
90 //struct addrinfo hints;
91 //NPT_SetMemory(&hints, 0, sizeof(hints));
92 //hints.ai_family = PF_UNSPEC;
93 //hints.ai_socktype = SOCK_STREAM;
94 //hints.ai_flags = AI_DEFAULT;
95 struct addrinfo *infos = NULL;
96 int result = getaddrinfo(name, /* hostname */
97 NULL, /* servname */
98 NULL, /* hints */
99 &infos /* res */);
100 if (result != 0) {
101 return MapGetAddrInfoErrorCode(result);
102 }
103
104 for (struct addrinfo* info = infos;
105 info && addresses.GetItemCount() < NPT_BSD_NETWORK_MAX_ADDR_LIST_LENGTH;
106 info = info->ai_next) {
107 unsigned int expected_length;
108 if (info->ai_family == AF_INET) {
109 expected_length = sizeof(struct sockaddr_in);
110 #if defined(NPT_CONFIG_ENABLE_IPV6)
111 } else if (info->ai_family == AF_INET6) {
112 expected_length = sizeof(struct sockaddr_in6);
113 #endif
114 } else {
115 continue;
116 }
117 if ((unsigned int)info->ai_addrlen < expected_length) continue;
118 if (info->ai_protocol != 0 && info->ai_protocol != IPPROTO_TCP) continue;
119
120 if (info->ai_family == AF_INET) {
121 struct sockaddr_in* inet_addr = (struct sockaddr_in*)info->ai_addr;
122 NPT_IpAddress address(ntohl(inet_addr->sin_addr.s_addr));
123 addresses.Add(address);
124 }
125 #if defined(NPT_CONFIG_ENABLE_IPV6)
126 else if (info->ai_family == AF_INET6) {
127 struct sockaddr_in6* inet_addr = (struct sockaddr_in6*)info->ai_addr;
128 NPT_IpAddress address(NPT_IpAddress::IPV6, inet_addr->sin6_addr.s6_addr, 16, inet_addr->sin6_scope_id);
129 addresses.Add(address);
130 }
131 #endif
132 }
133 freeaddrinfo(infos);
134
135 return NPT_SUCCESS;
136 }
137 #endif
138