1 /**
2  * WinPR: Windows Portable Runtime
3  * Windows Sockets (Winsock)
4  *
5  * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef WINPR_WINSOCK_H
21 #define WINPR_WINSOCK_H
22 
23 #include <winpr/winpr.h>
24 #include <winpr/wtypes.h>
25 #include <winpr/windows.h>
26 
27 #ifdef _WIN32
28 
29 #define _accept accept
30 #define _bind bind
31 #define _connect connect
32 #define _ioctlsocket ioctlsocket
33 #define _getpeername getpeername
34 #define _getsockname getsockname
35 #define _getsockopt getsockopt
36 #define _htonl htonl
37 #define _htons htons
38 #define _inet_addr inet_addr
39 #define _inet_ntoa inet_ntoa
40 #define _listen listen
41 #define _ntohl ntohl
42 #define _ntohs ntohs
43 #define _recv recv
44 #define _recvfrom recvfrom
45 #define _select select
46 #define _send send
47 #define _sendto sendto
48 #define _setsockopt setsockopt
49 #define _shutdown shutdown
50 #define _socket socket
51 #define _gethostbyaddr gethostbyaddr
52 #define _gethostbyname gethostbyname
53 #define _gethostname gethostname
54 #define _getservbyport getservbyport
55 #define _getservbyname getservbyname
56 #define _getprotobynumber getprotobynumber
57 #define _getprotobyname getprotobyname
58 
59 #define _IFF_UP IFF_UP
60 #define _IFF_BROADCAST IFF_BROADCAST
61 #define _IFF_LOOPBACK IFF_LOOPBACK
62 #define _IFF_POINTTOPOINT IFF_POINTTOPOINT
63 #define _IFF_MULTICAST IFF_MULTICAST
64 
65 #if (_WIN32_WINNT < 0x0600)
66 
67 WINPR_API PCSTR winpr_inet_ntop(INT Family, PVOID pAddr, PSTR pStringBuf, size_t StringBufSize);
68 WINPR_API INT winpr_inet_pton(INT Family, PCSTR pszAddrString, PVOID pAddrBuf);
69 
70 #define inet_ntop winpr_inet_ntop
71 #define inet_pton winpr_inet_pton
72 
73 #endif /* (_WIN32_WINNT < 0x0600) */
74 
75 #else /* _WIN32 */
76 
77 #include <netdb.h>
78 #include <unistd.h>
79 #include <sys/un.h>
80 #include <sys/ioctl.h>
81 #include <sys/socket.h>
82 #include <arpa/inet.h>
83 #include <netinet/in.h>
84 #include <netinet/tcp.h>
85 #include <net/if.h>
86 
87 #include <winpr/io.h>
88 #include <winpr/error.h>
89 #include <winpr/platform.h>
90 
91 #define WSAEVENT HANDLE
92 #define LPWSAEVENT LPHANDLE
93 #define WSAOVERLAPPED OVERLAPPED
94 typedef OVERLAPPED* LPWSAOVERLAPPED;
95 
96 typedef UINT_PTR SOCKET;
97 typedef struct sockaddr_storage SOCKADDR_STORAGE;
98 
99 #ifndef INVALID_SOCKET
100 #define INVALID_SOCKET (SOCKET)(~0)
101 #endif
102 
103 #define WSADESCRIPTION_LEN 256
104 #define WSASYS_STATUS_LEN 128
105 
106 #define FD_READ_BIT 0
107 #define FD_READ (1 << FD_READ_BIT)
108 
109 #define FD_WRITE_BIT 1
110 #define FD_WRITE (1 << FD_WRITE_BIT)
111 
112 #define FD_OOB_BIT 2
113 #define FD_OOB (1 << FD_OOB_BIT)
114 
115 #define FD_ACCEPT_BIT 3
116 #define FD_ACCEPT (1 << FD_ACCEPT_BIT)
117 
118 #define FD_CONNECT_BIT 4
119 #define FD_CONNECT (1 << FD_CONNECT_BIT)
120 
121 #define FD_CLOSE_BIT 5
122 #define FD_CLOSE (1 << FD_CLOSE_BIT)
123 
124 #define FD_QOS_BIT 6
125 #define FD_QOS (1 << FD_QOS_BIT)
126 
127 #define FD_GROUP_QOS_BIT 7
128 #define FD_GROUP_QOS (1 << FD_GROUP_QOS_BIT)
129 
130 #define FD_ROUTING_INTERFACE_CHANGE_BIT 8
131 #define FD_ROUTING_INTERFACE_CHANGE (1 << FD_ROUTING_INTERFACE_CHANGE_BIT)
132 
133 #define FD_ADDRESS_LIST_CHANGE_BIT 9
134 #define FD_ADDRESS_LIST_CHANGE (1 << FD_ADDRESS_LIST_CHANGE_BIT)
135 
136 #define FD_MAX_EVENTS 10
137 #define FD_ALL_EVENTS ((1 << FD_MAX_EVENTS) - 1)
138 
139 #define SD_RECEIVE 0
140 #define SD_SEND 1
141 #define SD_BOTH 2
142 
143 #define SOCKET_ERROR (-1)
144 
145 typedef struct WSAData
146 {
147 	WORD wVersion;
148 	WORD wHighVersion;
149 #ifdef _M_AMD64
150 	unsigned short iMaxSockets;
151 	unsigned short iMaxUdpDg;
152 	char* lpVendorInfo;
153 	char szDescription[WSADESCRIPTION_LEN + 1];
154 	char szSystemStatus[WSASYS_STATUS_LEN + 1];
155 #else
156 	char szDescription[WSADESCRIPTION_LEN + 1];
157 	char szSystemStatus[WSASYS_STATUS_LEN + 1];
158 	unsigned short iMaxSockets;
159 	unsigned short iMaxUdpDg;
160 	char* lpVendorInfo;
161 #endif
162 } WSADATA, *LPWSADATA;
163 
164 #ifndef MAKEWORD
165 #define MAKEWORD(a, b) \
166 	((WORD)(((BYTE)((DWORD_PTR)(a)&0xFF)) | (((WORD)((BYTE)((DWORD_PTR)(b)&0xFF))) << 8)))
167 #endif
168 
169 typedef struct in6_addr IN6_ADDR;
170 typedef struct in6_addr* PIN6_ADDR;
171 typedef struct in6_addr* LPIN6_ADDR;
172 
173 struct sockaddr_in6_old
174 {
175 	SHORT sin6_family;
176 	USHORT sin6_port;
177 	ULONG sin6_flowinfo;
178 	IN6_ADDR sin6_addr;
179 };
180 
181 typedef union sockaddr_gen {
182 	struct sockaddr Address;
183 	struct sockaddr_in AddressIn;
184 	struct sockaddr_in6_old AddressIn6;
185 } sockaddr_gen;
186 
187 #define _IFF_UP 0x00000001
188 #define _IFF_BROADCAST 0x00000002
189 #define _IFF_LOOPBACK 0x00000004
190 #define _IFF_POINTTOPOINT 0x00000008
191 #define _IFF_MULTICAST 0x00000010
192 
193 struct _INTERFACE_INFO
194 {
195 	ULONG iiFlags;
196 	sockaddr_gen iiAddress;
197 	sockaddr_gen iiBroadcastAddress;
198 	sockaddr_gen iiNetmask;
199 };
200 typedef struct _INTERFACE_INFO INTERFACE_INFO;
201 typedef INTERFACE_INFO* LPINTERFACE_INFO;
202 
203 #define MAX_PROTOCOL_CHAIN 7
204 #define WSAPROTOCOL_LEN 255
205 
206 typedef struct _WSAPROTOCOLCHAIN
207 {
208 	int ChainLen;
209 	DWORD ChainEntries[MAX_PROTOCOL_CHAIN];
210 } WSAPROTOCOLCHAIN, *LPWSAPROTOCOLCHAIN;
211 
212 typedef struct _WSAPROTOCOL_INFOA
213 {
214 	DWORD dwServiceFlags1;
215 	DWORD dwServiceFlags2;
216 	DWORD dwServiceFlags3;
217 	DWORD dwServiceFlags4;
218 	DWORD dwProviderFlags;
219 	GUID ProviderId;
220 	DWORD dwCatalogEntryId;
221 	WSAPROTOCOLCHAIN ProtocolChain;
222 	int iVersion;
223 	int iAddressFamily;
224 	int iMaxSockAddr;
225 	int iMinSockAddr;
226 	int iSocketType;
227 	int iProtocol;
228 	int iProtocolMaxOffset;
229 	int iNetworkByteOrder;
230 	int iSecurityScheme;
231 	DWORD dwMessageSize;
232 	DWORD dwProviderReserved;
233 	CHAR szProtocol[WSAPROTOCOL_LEN + 1];
234 } WSAPROTOCOL_INFOA, *LPWSAPROTOCOL_INFOA;
235 
236 typedef struct _WSAPROTOCOL_INFOW
237 {
238 	DWORD dwServiceFlags1;
239 	DWORD dwServiceFlags2;
240 	DWORD dwServiceFlags3;
241 	DWORD dwServiceFlags4;
242 	DWORD dwProviderFlags;
243 	GUID ProviderId;
244 	DWORD dwCatalogEntryId;
245 	WSAPROTOCOLCHAIN ProtocolChain;
246 	int iVersion;
247 	int iAddressFamily;
248 	int iMaxSockAddr;
249 	int iMinSockAddr;
250 	int iSocketType;
251 	int iProtocol;
252 	int iProtocolMaxOffset;
253 	int iNetworkByteOrder;
254 	int iSecurityScheme;
255 	DWORD dwMessageSize;
256 	DWORD dwProviderReserved;
257 	WCHAR szProtocol[WSAPROTOCOL_LEN + 1];
258 } WSAPROTOCOL_INFOW, *LPWSAPROTOCOL_INFOW;
259 
260 typedef void(CALLBACK* LPWSAOVERLAPPED_COMPLETION_ROUTINE)(DWORD dwError, DWORD cbTransferred,
261                                                            LPWSAOVERLAPPED lpOverlapped,
262                                                            DWORD dwFlags);
263 
264 typedef UINT32 GROUP;
265 #define SG_UNCONSTRAINED_GROUP 0x01
266 #define SG_CONSTRAINED_GROUP 0x02
267 
268 #define SIO_GET_INTERFACE_LIST _IOR('t', 127, ULONG)
269 #define SIO_GET_INTERFACE_LIST_EX _IOR('t', 126, ULONG)
270 #define SIO_SET_MULTICAST_FILTER _IOW('t', 125, ULONG)
271 #define SIO_GET_MULTICAST_FILTER _IOW('t', 124 | IOC_IN, ULONG)
272 #define SIOCSIPMSFILTER SIO_SET_MULTICAST_FILTER
273 #define SIOCGIPMSFILTER SIO_GET_MULTICAST_FILTER
274 
275 #ifdef UNICODE
276 #define WSAPROTOCOL_INFO WSAPROTOCOL_INFOW
277 #define LPWSAPROTOCOL_INFO LPWSAPROTOCOL_INFOW
278 #else
279 #define WSAPROTOCOL_INFO WSAPROTOCOL_INFOA
280 #define LPWSAPROTOCOL_INFO LPWSAPROTOCOL_INFOA
281 #endif
282 
283 #ifdef __cplusplus
284 extern "C"
285 {
286 #endif
287 
288 	WINPR_API int WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData);
289 	WINPR_API int WSACleanup(void);
290 
291 	WINPR_API void WSASetLastError(int iError);
292 	WINPR_API int WSAGetLastError(void);
293 
294 	WINPR_API HANDLE WSACreateEvent(void);
295 	WINPR_API BOOL WSASetEvent(HANDLE hEvent);
296 	WINPR_API BOOL WSAResetEvent(HANDLE hEvent);
297 	WINPR_API BOOL WSACloseEvent(HANDLE hEvent);
298 
299 	WINPR_API int WSAEventSelect(SOCKET s, WSAEVENT hEventObject, LONG lNetworkEvents);
300 
301 	WINPR_API DWORD WSAWaitForMultipleEvents(DWORD cEvents, const HANDLE* lphEvents, BOOL fWaitAll,
302 	                                         DWORD dwTimeout, BOOL fAlertable);
303 
304 	WINPR_API SOCKET WSASocketA(int af, int type, int protocol, LPWSAPROTOCOL_INFOA lpProtocolInfo,
305 	                            GROUP g, DWORD dwFlags);
306 	WINPR_API SOCKET WSASocketW(int af, int type, int protocol, LPWSAPROTOCOL_INFOW lpProtocolInfo,
307 	                            GROUP g, DWORD dwFlags);
308 
309 	WINPR_API int WSAIoctl(SOCKET s, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer,
310 	                       LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned,
311 	                       LPWSAOVERLAPPED lpOverlapped,
312 	                       LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
313 
314 	WINPR_API SOCKET _accept(SOCKET s, struct sockaddr* addr, int* addrlen);
315 	WINPR_API int _bind(SOCKET s, const struct sockaddr* addr, int namelen);
316 	WINPR_API int closesocket(SOCKET s);
317 	WINPR_API int _connect(SOCKET s, const struct sockaddr* name, int namelen);
318 	WINPR_API int _ioctlsocket(SOCKET s, long cmd, u_long* argp);
319 	WINPR_API int _getpeername(SOCKET s, struct sockaddr* name, int* namelen);
320 	WINPR_API int _getsockname(SOCKET s, struct sockaddr* name, int* namelen);
321 	WINPR_API int _getsockopt(SOCKET s, int level, int optname, char* optval, int* optlen);
322 	WINPR_API u_long _htonl(u_long hostlong);
323 	WINPR_API u_short _htons(u_short hostshort);
324 	WINPR_API unsigned long _inet_addr(const char* cp);
325 	WINPR_API char* _inet_ntoa(struct in_addr in);
326 	WINPR_API int _listen(SOCKET s, int backlog);
327 	WINPR_API u_long _ntohl(u_long netlong);
328 	WINPR_API u_short _ntohs(u_short netshort);
329 	WINPR_API int _recv(SOCKET s, char* buf, int len, int flags);
330 	WINPR_API int _winsock_recvfrom(SOCKET s, char* buf, int len, int flags, struct sockaddr* from,
331 	                        int* fromlen);
332 	WINPR_API int _select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds,
333 	                      const struct timeval* timeout);
334 	WINPR_API int _send(SOCKET s, const char* buf, int len, int flags);
335 	WINPR_API int _sendto(SOCKET s, const char* buf, int len, int flags, const struct sockaddr* to,
336 	                      int tolen);
337 	WINPR_API int _setsockopt(SOCKET s, int level, int optname, const char* optval, int optlen);
338 	WINPR_API int _shutdown(SOCKET s, int how);
339 	WINPR_API SOCKET _socket(int af, int type, int protocol);
340 	WINPR_API struct hostent* _gethostbyaddr(const char* addr, int len, int type);
341 	WINPR_API struct hostent* _gethostbyname(const char* name);
342 	WINPR_API int _gethostname(char* name, int namelen);
343 	WINPR_API struct servent* _getservbyport(int port, const char* proto);
344 	WINPR_API struct servent* _getservbyname(const char* name, const char* proto);
345 	WINPR_API struct protoent* _getprotobynumber(int number);
346 	WINPR_API struct protoent* _getprotobyname(const char* name);
347 
348 #ifdef __cplusplus
349 }
350 #endif
351 
352 #ifdef UNICODE
353 #define WSASocket WSASocketW
354 #else
355 #define WSASocket WSASocketA
356 #endif
357 
358 #endif /* _WIN32 */
359 
360 #endif /* WINPR_WINSOCK_H */
361