Mercurial > projects > hoofbaby
comparison deps/Platinum/ThirdParty/Neptune/Source/System/Win32/NptWin32Network.cpp @ 0:3425707ddbf6
Initial import (hopefully this mercurial stuff works...)
author | fraserofthenight |
---|---|
date | Mon, 06 Jul 2009 08:06:28 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:3425707ddbf6 |
---|---|
1 /***************************************************************** | |
2 | | |
3 | Neptune - Network :: Winsock Implementation | |
4 | | |
5 | (c) 2001-2006 Gilles Boccon-Gibod | |
6 | Author: Gilles Boccon-Gibod (bok@bok.net) | |
7 | | |
8 ****************************************************************/ | |
9 | |
10 /*---------------------------------------------------------------------- | |
11 | includes | |
12 +---------------------------------------------------------------------*/ | |
13 #define STRICT | |
14 #include <winsock2.h> | |
15 #include <ws2tcpip.h> | |
16 #include "NptNetwork.h" | |
17 #include "NptWin32Network.h" | |
18 | |
19 /*---------------------------------------------------------------------- | |
20 | static initializer | |
21 +---------------------------------------------------------------------*/ | |
22 NPT_WinsockSystem::NPT_WinsockSystem() { | |
23 WORD wVersionRequested; | |
24 WSADATA wsaData; | |
25 wVersionRequested = MAKEWORD(2, 2); | |
26 /*wVersionRequested = MAKEWORD(1, 1);*/ | |
27 WSAStartup( wVersionRequested, &wsaData ); | |
28 } | |
29 NPT_WinsockSystem::~NPT_WinsockSystem() { | |
30 WSACleanup(); | |
31 } | |
32 NPT_WinsockSystem NPT_WinsockSystem::Initializer; | |
33 | |
34 #if defined(_WIN32_WCE) | |
35 // don't use the SIO_GET_INTERFACE_LIST on Windows CE, it is | |
36 // hopelessly broken, and will crash your application. | |
37 #define NPT_NETWORK_USE_IP_HELPER_API | |
38 #else | |
39 #define NPT_NETWORK_USE_SIO_GET_INTERFACE_LIST | |
40 #endif | |
41 | |
42 #if defined(NPT_NETWORK_USE_SIO_GET_INTERFACE_LIST) | |
43 /*---------------------------------------------------------------------- | |
44 | NPT_NetworkInterface::GetNetworkInterfaces | |
45 +---------------------------------------------------------------------*/ | |
46 NPT_Result | |
47 NPT_NetworkInterface::GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& interfaces) | |
48 { | |
49 // create a socket to talk to the TCP/IP stack | |
50 SOCKET net; | |
51 if((net = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0)) == INVALID_SOCKET) { | |
52 return NPT_FAILURE; | |
53 } | |
54 | |
55 // get a list of interfaces | |
56 INTERFACE_INFO query[32]; // get up to 32 interfaces | |
57 DWORD bytes_returned; | |
58 int io_result = WSAIoctl(net, | |
59 SIO_GET_INTERFACE_LIST, | |
60 NULL, 0, | |
61 &query, sizeof(query), | |
62 &bytes_returned, | |
63 NULL, NULL); | |
64 if (io_result == SOCKET_ERROR) { | |
65 closesocket(net); | |
66 return NPT_FAILURE; | |
67 } | |
68 | |
69 // we don't need the socket anymore | |
70 closesocket(net); | |
71 | |
72 // Display interface information | |
73 int interface_count = (bytes_returned/sizeof(INTERFACE_INFO)); | |
74 unsigned int iface_index = 0; | |
75 for (int i=0; i<interface_count; i++) { | |
76 SOCKADDR_IN* address; | |
77 NPT_Flags flags = 0; | |
78 | |
79 // primary address | |
80 address = (SOCKADDR_IN*)&query[i].iiAddress; | |
81 NPT_IpAddress primary_address(ntohl(address->sin_addr.s_addr)); | |
82 | |
83 // netmask | |
84 address = (SOCKADDR_IN*)&query[i].iiNetmask; | |
85 NPT_IpAddress netmask(ntohl(address->sin_addr.s_addr)); | |
86 | |
87 // broadcast address | |
88 address = (SOCKADDR_IN*)&query[i].iiBroadcastAddress; | |
89 NPT_IpAddress broadcast_address(ntohl(address->sin_addr.s_addr)); | |
90 | |
91 { | |
92 // broadcast address is incorrect | |
93 unsigned char addr[4]; | |
94 for(int i=0; i<4; i++) { | |
95 addr[i] = (primary_address.AsBytes()[i] & netmask.AsBytes()[i]) | | |
96 ~netmask.AsBytes()[i]; | |
97 } | |
98 broadcast_address.Set(addr); | |
99 } | |
100 | |
101 // ignore interfaces that are not up | |
102 if (!(query[i].iiFlags & IFF_UP)) { | |
103 continue; | |
104 } | |
105 if (query[i].iiFlags & IFF_BROADCAST) { | |
106 flags |= NPT_NETWORK_INTERFACE_FLAG_BROADCAST; | |
107 } | |
108 if (query[i].iiFlags & IFF_MULTICAST) { | |
109 flags |= NPT_NETWORK_INTERFACE_FLAG_MULTICAST; | |
110 } | |
111 if (query[i].iiFlags & IFF_LOOPBACK) { | |
112 flags |= NPT_NETWORK_INTERFACE_FLAG_LOOPBACK; | |
113 } | |
114 if (query[i].iiFlags & IFF_POINTTOPOINT) { | |
115 flags |= NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT; | |
116 } | |
117 | |
118 // mac address (no support for this for now) | |
119 NPT_MacAddress mac; | |
120 | |
121 // create an interface object | |
122 char iface_name[5]; | |
123 iface_name[0] = 'i'; | |
124 iface_name[1] = 'f'; | |
125 iface_name[2] = '0'+(iface_index/10); | |
126 iface_name[3] = '0'+(iface_index%10); | |
127 iface_name[4] = '\0'; | |
128 NPT_NetworkInterface* iface = new NPT_NetworkInterface(iface_name, mac, flags); | |
129 | |
130 // set the interface address | |
131 NPT_NetworkInterfaceAddress iface_address( | |
132 primary_address, | |
133 broadcast_address, | |
134 NPT_IpAddress::Any, | |
135 netmask); | |
136 iface->AddAddress(iface_address); | |
137 | |
138 // add the interface to the list | |
139 interfaces.Add(iface); | |
140 | |
141 // increment the index (used for generating the name | |
142 iface_index++; | |
143 } | |
144 | |
145 return NPT_SUCCESS; | |
146 } | |
147 #elif defined(NPT_NETWORK_USE_IP_HELPER_API) | |
148 // Use the IP Helper API | |
149 #include <iphlpapi.h> | |
150 | |
151 /*---------------------------------------------------------------------- | |
152 | NPT_NetworkInterface::GetNetworkInterfaces | |
153 +---------------------------------------------------------------------*/ | |
154 NPT_Result | |
155 NPT_NetworkInterface::GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& interfaces) | |
156 { | |
157 IP_ADAPTER_ADDRESSES* iface_list = NULL; | |
158 ULONG size = sizeof(IP_ADAPTER_INFO); | |
159 | |
160 // get the interface table | |
161 for(;;) { | |
162 iface_list = (IP_ADAPTER_ADDRESSES*)malloc(size); | |
163 DWORD result = GetAdaptersAddresses(AF_INET, | |
164 0, | |
165 NULL, | |
166 iface_list, &size); | |
167 if (result == NO_ERROR) { | |
168 break; | |
169 } else { | |
170 if (result == ERROR_BUFFER_OVERFLOW) { | |
171 // free and try again | |
172 free(iface_list); | |
173 } else { | |
174 return NPT_FAILURE; | |
175 } | |
176 } | |
177 } | |
178 | |
179 // iterate over the interfaces | |
180 for (IP_ADAPTER_ADDRESSES* iface = iface_list; iface; iface = iface->Next) { | |
181 // skip this interface if it is not up | |
182 if (iface->OperStatus != IfOperStatusUp) continue; | |
183 | |
184 // get the interface type and mac address | |
185 NPT_MacAddress::Type mac_type; | |
186 switch (iface->IfType) { | |
187 case IF_TYPE_ETHERNET_CSMACD: mac_type = NPT_MacAddress::TYPE_ETHERNET; break; | |
188 case IF_TYPE_SOFTWARE_LOOPBACK: mac_type = NPT_MacAddress::TYPE_LOOPBACK; break; | |
189 case IF_TYPE_PPP: mac_type = NPT_MacAddress::TYPE_PPP; break; | |
190 default: mac_type = NPT_MacAddress::TYPE_UNKNOWN; break; | |
191 } | |
192 NPT_MacAddress mac(mac_type, iface->PhysicalAddress, iface->PhysicalAddressLength); | |
193 | |
194 // compute interface flags | |
195 NPT_Flags flags = 0; | |
196 if (!(iface->Flags & IP_ADAPTER_NO_MULTICAST)) flags |= NPT_NETWORK_INTERFACE_FLAG_MULTICAST; | |
197 if (iface->IfType == IF_TYPE_SOFTWARE_LOOPBACK) flags |= NPT_NETWORK_INTERFACE_FLAG_LOOPBACK; | |
198 if (iface->IfType == IF_TYPE_PPP) flags |= NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT; | |
199 | |
200 // compute the unicast address (only the first one is supported for now) | |
201 NPT_IpAddress primary_address; | |
202 if (iface->FirstUnicastAddress) { | |
203 if (iface->FirstUnicastAddress->Address.lpSockaddr == NULL) continue; | |
204 if (iface->FirstUnicastAddress->Address.iSockaddrLength != sizeof(SOCKADDR_IN)) continue; | |
205 SOCKADDR_IN* address = (SOCKADDR_IN*)iface->FirstUnicastAddress->Address.lpSockaddr; | |
206 if (address->sin_family != AF_INET) continue; | |
207 primary_address.Set(ntohl(address->sin_addr.s_addr)); | |
208 } | |
209 NPT_IpAddress broadcast_address; // not supported yet | |
210 NPT_IpAddress netmask; // not supported yet | |
211 | |
212 // convert the interface name to UTF-8 | |
213 unsigned int iface_name_length = (unsigned int)wcslen(iface->FriendlyName); | |
214 char* iface_name = new char[4*iface_name_length+1]; | |
215 int result = WideCharToMultiByte( | |
216 CP_UTF8, 0, iface->FriendlyName, iface_name_length, | |
217 iface_name, 4*iface_name_length+1, | |
218 NULL, NULL); | |
219 if (result > 0) { | |
220 iface_name[result] = '\0'; | |
221 } else { | |
222 iface_name[0] = '\0'; | |
223 } | |
224 | |
225 // create an interface descriptor | |
226 NPT_NetworkInterface* iface_object = new NPT_NetworkInterface(iface_name, mac, flags); | |
227 NPT_NetworkInterfaceAddress iface_address( | |
228 primary_address, | |
229 broadcast_address, | |
230 NPT_IpAddress::Any, | |
231 netmask); | |
232 iface_object->AddAddress(iface_address); | |
233 | |
234 // cleanup | |
235 delete[] iface_name; | |
236 | |
237 // add the interface to the list | |
238 interfaces.Add(iface_object); | |
239 } | |
240 | |
241 return NPT_SUCCESS; | |
242 } | |
243 #else | |
244 /*---------------------------------------------------------------------- | |
245 | NPT_NetworkInterface::GetNetworkInterfaces | |
246 +---------------------------------------------------------------------*/ | |
247 NPT_Result | |
248 NPT_NetworkInterface::GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>&) | |
249 { | |
250 return NPT_SUCCESS; | |
251 } | |
252 #endif |