1 | /*
|
---|
2 | * ws2tcpip.h : TCP/IP specific extensions in Windows Sockets 2
|
---|
3 | *
|
---|
4 | * Portions Copyright (c) 1980, 1983, 1988, 1993
|
---|
5 | * The Regents of the University of California. All rights reserved.
|
---|
6 | *
|
---|
7 | */
|
---|
8 |
|
---|
9 | #ifndef _WS2TCPIP_H
|
---|
10 | #define _WS2TCPIP_H
|
---|
11 | #if __GNUC__ >=3
|
---|
12 | #pragma GCC system_header
|
---|
13 | #endif
|
---|
14 |
|
---|
15 | #if (defined _WINSOCK_H && !defined _WINSOCK2_H)
|
---|
16 | #error "ws2tcpip.h is not compatible with winsock.h. Include winsock2.h instead."
|
---|
17 | #endif
|
---|
18 |
|
---|
19 | #include <winsock2.h>
|
---|
20 | #ifdef __cplusplus
|
---|
21 | extern "C" {
|
---|
22 | #endif
|
---|
23 |
|
---|
24 | /*
|
---|
25 | * The IP_* macros are also defined in winsock.h, but some values are different there.
|
---|
26 | * The values defined in winsock.h for 1.1 and used in wsock32.dll are consistent
|
---|
27 | * with the original values Steve Deering defined in his document "IP Multicast Extensions
|
---|
28 | * for 4.3BSD UNIX related systems (MULTICAST 1.2 Release)." However, these conflicted with
|
---|
29 | * the definitions for some IPPROTO_IP level socket options already assigned by BSD,
|
---|
30 | * so Berkeley changed all the values by adding 7. WinSock2 (ws2_32.dll) uses
|
---|
31 | * the BSD 4.4 compatible values defined here.
|
---|
32 | *
|
---|
33 | * See also: msdn kb article Q257460
|
---|
34 | * http://support.microsoft.com/support/kb/articles/Q257/4/60.asp
|
---|
35 | */
|
---|
36 |
|
---|
37 | /* This is also defined in winsock.h; value hasn't changed */
|
---|
38 | #define IP_OPTIONS 1
|
---|
39 |
|
---|
40 | #define IP_HDRINCL 2
|
---|
41 | /*
|
---|
42 | * These are also be defined in winsock.h,
|
---|
43 | * but values have changed for WinSock2 interface
|
---|
44 | */
|
---|
45 | #define IP_TOS 3 /* old (winsock 1.1) value 8 */
|
---|
46 | #define IP_TTL 4 /* old value 7 */
|
---|
47 | #define IP_MULTICAST_IF 9 /* old value 2 */
|
---|
48 | #define IP_MULTICAST_TTL 10 /* old value 3 */
|
---|
49 | #define IP_MULTICAST_LOOP 11 /* old value 4 */
|
---|
50 | #define IP_ADD_MEMBERSHIP 12 /* old value 5 */
|
---|
51 | #define IP_DROP_MEMBERSHIP 13 /* old value 6 */
|
---|
52 | #define IP_DONTFRAGMENT 14 /* old value 9 */
|
---|
53 | #define IP_ADD_SOURCE_MEMBERSHIP 15
|
---|
54 | #define IP_DROP_SOURCE_MEMBERSHIP 16
|
---|
55 | #define IP_BLOCK_SOURCE 17
|
---|
56 | #define IP_UNBLOCK_SOURCE 18
|
---|
57 | #define IP_PKTINFO 19
|
---|
58 |
|
---|
59 | /*
|
---|
60 | * As with BSD implementation, IPPROTO_IPV6 level socket options have
|
---|
61 | * same values as IPv4 counterparts.
|
---|
62 | */
|
---|
63 | #define IPV6_UNICAST_HOPS 4
|
---|
64 | #define IPV6_MULTICAST_IF 9
|
---|
65 | #define IPV6_MULTICAST_HOPS 10
|
---|
66 | #define IPV6_MULTICAST_LOOP 11
|
---|
67 | #define IPV6_ADD_MEMBERSHIP 12
|
---|
68 | #define IPV6_DROP_MEMBERSHIP 13
|
---|
69 | #define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
|
---|
70 | #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
|
---|
71 | #define IPV6_PKTINFO 19
|
---|
72 |
|
---|
73 | #define IP_DEFAULT_MULTICAST_TTL 1
|
---|
74 | #define IP_DEFAULT_MULTICAST_LOOP 1
|
---|
75 | #define IP_MAX_MEMBERSHIPS 20
|
---|
76 |
|
---|
77 | #define TCP_EXPEDITED_1122 2
|
---|
78 |
|
---|
79 | #define UDP_NOCHECKSUM 1
|
---|
80 |
|
---|
81 | /* INTERFACE_INFO iiFlags */
|
---|
82 | #define IFF_UP 1
|
---|
83 | #define IFF_BROADCAST 2
|
---|
84 | #define IFF_LOOPBACK 4
|
---|
85 | #define IFF_POINTTOPOINT 8
|
---|
86 | #define IFF_MULTICAST 16
|
---|
87 |
|
---|
88 | #define SIO_GET_INTERFACE_LIST _IOR('t', 127, u_long)
|
---|
89 |
|
---|
90 | #define INET_ADDRSTRLEN 16
|
---|
91 | #define INET6_ADDRSTRLEN 46
|
---|
92 |
|
---|
93 | /* getnameinfo constants */
|
---|
94 | #define NI_MAXHOST 1025
|
---|
95 | #define NI_MAXSERV 32
|
---|
96 |
|
---|
97 | #define NI_NOFQDN 0x01
|
---|
98 | #define NI_NUMERICHOST 0x02
|
---|
99 | #define NI_NAMEREQD 0x04
|
---|
100 | #define NI_NUMERICSERV 0x08
|
---|
101 | #define NI_DGRAM 0x10
|
---|
102 |
|
---|
103 | /* getaddrinfo constants */
|
---|
104 | #define AI_PASSIVE 1
|
---|
105 | #define AI_CANONNAME 2
|
---|
106 | #define AI_NUMERICHOST 4
|
---|
107 |
|
---|
108 | /* getaddrinfo error codes */
|
---|
109 | #define EAI_AGAIN WSATRY_AGAIN
|
---|
110 | #define EAI_BADFLAGS WSAEINVAL
|
---|
111 | #define EAI_FAIL WSANO_RECOVERY
|
---|
112 | #define EAI_FAMILY WSAEAFNOSUPPORT
|
---|
113 | #define EAI_MEMORY WSA_NOT_ENOUGH_MEMORY
|
---|
114 | #define EAI_NODATA WSANO_DATA
|
---|
115 | #define EAI_NONAME WSAHOST_NOT_FOUND
|
---|
116 | #define EAI_SERVICE WSATYPE_NOT_FOUND
|
---|
117 | #define EAI_SOCKTYPE WSAESOCKTNOSUPPORT
|
---|
118 |
|
---|
119 | /*
|
---|
120 | * ip_mreq also in winsock.h for WinSock1.1,
|
---|
121 | * but online msdn docs say it is defined here for WinSock2.
|
---|
122 | */
|
---|
123 |
|
---|
124 | struct ip_mreq {
|
---|
125 | struct in_addr imr_multiaddr;
|
---|
126 | struct in_addr imr_interface;
|
---|
127 | };
|
---|
128 |
|
---|
129 | struct ip_mreq_source {
|
---|
130 | struct in_addr imr_multiaddr;
|
---|
131 | struct in_addr imr_sourceaddr;
|
---|
132 | struct in_addr imr_interface;
|
---|
133 | };
|
---|
134 |
|
---|
135 | struct ip_msfilter {
|
---|
136 | struct in_addr imsf_multiaddr;
|
---|
137 | struct in_addr imsf_interface;
|
---|
138 | u_long imsf_fmode;
|
---|
139 | u_long imsf_numsrc;
|
---|
140 | struct in_addr imsf_slist[1];
|
---|
141 | };
|
---|
142 |
|
---|
143 | #define IP_MSFILTER_SIZE(numsrc) \
|
---|
144 | (sizeof(struct ip_msfilter) - sizeof(struct in_addr) \
|
---|
145 | + (numsrc) * sizeof(struct in_addr))
|
---|
146 |
|
---|
147 | struct in_pktinfo {
|
---|
148 | IN_ADDR ipi_addr;
|
---|
149 | UINT ipi_ifindex;
|
---|
150 | };
|
---|
151 | typedef struct in_pktinfo IN_PKTINFO;
|
---|
152 |
|
---|
153 |
|
---|
154 | /* ipv6 */
|
---|
155 | /* These require XP or .NET Server or use of add-on IPv6 stacks on NT 4
|
---|
156 | or higher */
|
---|
157 |
|
---|
158 | /* This is based on the example given in RFC 2553 with stdint types
|
---|
159 | changed to BSD types. For now, use these field names until there
|
---|
160 | is some consistency in MS docs. In this file, we only use the
|
---|
161 | in6_addr structure start address, with casts to get the right offsets
|
---|
162 | when testing addresses */
|
---|
163 |
|
---|
164 | struct in6_addr {
|
---|
165 | union {
|
---|
166 | u_char _S6_u8[16];
|
---|
167 | u_short _S6_u16[8];
|
---|
168 | u_long _S6_u32[4];
|
---|
169 | } _S6_un;
|
---|
170 | };
|
---|
171 | /* s6_addr is the standard name */
|
---|
172 | #define s6_addr _S6_un._S6_u8
|
---|
173 |
|
---|
174 | /* These are GLIBC names */
|
---|
175 | #define s6_addr16 _S6_un._S6_u16
|
---|
176 | #define s6_addr32 _S6_un._S6_u32
|
---|
177 |
|
---|
178 | /* These are used in some MS code */
|
---|
179 | #define in_addr6 in6_addr
|
---|
180 | #define _s6_bytes _S6_un._S6_u8
|
---|
181 | #define _s6_words _S6_un._S6_u16
|
---|
182 |
|
---|
183 | typedef struct in6_addr IN6_ADDR, *PIN6_ADDR, *LPIN6_ADDR;
|
---|
184 |
|
---|
185 | struct sockaddr_in6 {
|
---|
186 | short sin6_family; /* AF_INET6 */
|
---|
187 | u_short sin6_port; /* transport layer port # */
|
---|
188 | u_long sin6_flowinfo; /* IPv6 traffic class & flow info */
|
---|
189 | struct in6_addr sin6_addr; /* IPv6 address */
|
---|
190 | u_long sin6_scope_id; /* set of interfaces for a scope */
|
---|
191 | };
|
---|
192 | typedef struct sockaddr_in6 SOCKADDR_IN6, *PSOCKADDR_IN6, *LPSOCKADDR_IN6;
|
---|
193 |
|
---|
194 | extern const struct in6_addr in6addr_any;
|
---|
195 | extern const struct in6_addr in6addr_loopback;
|
---|
196 | /* the above can get initialised using: */
|
---|
197 | #define IN6ADDR_ANY_INIT { 0 }
|
---|
198 | #define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
|
---|
199 |
|
---|
200 | /* Described in RFC 2292, but not in 2553 */
|
---|
201 | /* int IN6_ARE_ADDR_EQUAL(const struct in6_addr * a, const struct in6_addr * b) */
|
---|
202 | #define IN6_ARE_ADDR_EQUAL(a, b) \
|
---|
203 | (memcmp ((void*)(a), (void*)(b), sizeof (struct in6_addr)) == 0)
|
---|
204 |
|
---|
205 |
|
---|
206 | /* Address Testing Macros
|
---|
207 |
|
---|
208 | These macro functions all take const struct in6_addr* as arg.
|
---|
209 | Static inlines would allow type checking, but RFC 2553 says they
|
---|
210 | macros.
|
---|
211 | NB: These are written specifically for little endian host */
|
---|
212 |
|
---|
213 | #define IN6_IS_ADDR_UNSPECIFIED(_addr) \
|
---|
214 | ( (((const u_long *)(_addr))[0] == 0) \
|
---|
215 | && (((const u_long *)(_addr))[1] == 0) \
|
---|
216 | && (((const u_long *)(_addr))[2] == 0) \
|
---|
217 | && (((const u_long *)(_addr))[3] == 0))
|
---|
218 |
|
---|
219 | #define IN6_IS_ADDR_LOOPBACK(_addr) \
|
---|
220 | ( (((const u_long *)(_addr))[0] == 0) \
|
---|
221 | && (((const u_long *)(_addr))[1] == 0) \
|
---|
222 | && (((const u_long *)(_addr))[2] == 0) \
|
---|
223 | && (((const u_long *)(_addr))[3] == 0x01000000)) /* Note byte order reversed */
|
---|
224 | /* (((const u_long *)(_addr))[3] == ntohl(1)) */
|
---|
225 |
|
---|
226 | #define IN6_IS_ADDR_MULTICAST(_addr) (((const u_char *) (_addr))[0] == 0xff)
|
---|
227 |
|
---|
228 | #define IN6_IS_ADDR_LINKLOCAL(_addr) \
|
---|
229 | ( (((const u_char *)(_addr))[0] == 0xfe) \
|
---|
230 | && ((((const u_char *)(_addr))[1] & 0xc0) == 0x80))
|
---|
231 |
|
---|
232 | #define IN6_IS_ADDR_SITELOCAL(_addr) \
|
---|
233 | ( (((const u_char *)(_addr))[0] == 0xfe) \
|
---|
234 | && ((((const u_char *)(_addr))[1] & 0xc0) == 0xc0))
|
---|
235 |
|
---|
236 | #define IN6_IS_ADDR_V4MAPPED(_addr) \
|
---|
237 | ( (((const u_long *)(_addr))[0] == 0) \
|
---|
238 | && (((const u_long *)(_addr))[1] == 0) \
|
---|
239 | && (((const u_long *)(_addr))[2] == 0xffff0000)) /* Note byte order reversed */
|
---|
240 | /* (((const u_long *)(_addr))[2] == ntohl(0x0000ffff))) */
|
---|
241 |
|
---|
242 | #define IN6_IS_ADDR_V4COMPAT(_addr) \
|
---|
243 | ( (((const u_long *)(_addr))[0] == 0) \
|
---|
244 | && (((const u_long *)(_addr))[1] == 0) \
|
---|
245 | && (((const u_long *)(_addr))[2] == 0) \
|
---|
246 | && (((const u_long *)(_addr))[3] != 0) \
|
---|
247 | && (((const u_long *)(_addr))[3] != 0x01000000)) /* Note byte order reversed */
|
---|
248 | /* (ntohl (((const u_long *)(_addr))[3]) > 1 ) */
|
---|
249 |
|
---|
250 |
|
---|
251 | #define IN6_IS_ADDR_MC_NODELOCAL(_addr) \
|
---|
252 | ( IN6_IS_ADDR_MULTICAST(_addr) \
|
---|
253 | && ((((const u_char *)(_addr))[1] & 0xf) == 0x1))
|
---|
254 |
|
---|
255 | #define IN6_IS_ADDR_MC_LINKLOCAL(_addr) \
|
---|
256 | ( IN6_IS_ADDR_MULTICAST (_addr) \
|
---|
257 | && ((((const u_char *)(_addr))[1] & 0xf) == 0x2))
|
---|
258 |
|
---|
259 | #define IN6_IS_ADDR_MC_SITELOCAL(_addr) \
|
---|
260 | ( IN6_IS_ADDR_MULTICAST(_addr) \
|
---|
261 | && ((((const u_char *)(_addr))[1] & 0xf) == 0x5))
|
---|
262 |
|
---|
263 | #define IN6_IS_ADDR_MC_ORGLOCAL(_addr) \
|
---|
264 | ( IN6_IS_ADDR_MULTICAST(_addr) \
|
---|
265 | && ((((const u_char *)(_addr))[1] & 0xf) == 0x8))
|
---|
266 |
|
---|
267 | #define IN6_IS_ADDR_MC_GLOBAL(_addr) \
|
---|
268 | ( IN6_IS_ADDR_MULTICAST(_addr) \
|
---|
269 | && ((((const u_char *)(_addr))[1] & 0xf) == 0xe))
|
---|
270 |
|
---|
271 |
|
---|
272 | typedef int socklen_t;
|
---|
273 |
|
---|
274 | struct ipv6_mreq {
|
---|
275 | struct in6_addr ipv6mr_multiaddr;
|
---|
276 | unsigned int ipv6mr_interface;
|
---|
277 | };
|
---|
278 | typedef struct ipv6_mreq IPV6_MREQ;
|
---|
279 |
|
---|
280 | struct in6_pktinfo {
|
---|
281 | IN6_ADDR ipi6_addr;
|
---|
282 | UINT ipi6_ifindex;
|
---|
283 | };
|
---|
284 | typedef struct in6_pktinfo IN6_PKTINFO;
|
---|
285 |
|
---|
286 | struct addrinfo {
|
---|
287 | int ai_flags;
|
---|
288 | int ai_family;
|
---|
289 | int ai_socktype;
|
---|
290 | int ai_protocol;
|
---|
291 | size_t ai_addrlen;
|
---|
292 | char *ai_canonname;
|
---|
293 | struct sockaddr *ai_addr;
|
---|
294 | struct addrinfo *ai_next;
|
---|
295 | };
|
---|
296 |
|
---|
297 | #if (_WIN32_WINNT >= 0x0501)
|
---|
298 | void WSAAPI freeaddrinfo (struct addrinfo*);
|
---|
299 | int WSAAPI getaddrinfo (const char*,const char*,const struct addrinfo*,
|
---|
300 | struct addrinfo**);
|
---|
301 | int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD,
|
---|
302 | char*,DWORD,int);
|
---|
303 | #else
|
---|
304 | /* FIXME: Need WS protocol-independent API helpers. */
|
---|
305 | #endif
|
---|
306 |
|
---|
307 | static __inline char*
|
---|
308 | gai_strerrorA(int ecode)
|
---|
309 | {
|
---|
310 | static char message[1024+1];
|
---|
311 | DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM
|
---|
312 | | FORMAT_MESSAGE_IGNORE_INSERTS
|
---|
313 | | FORMAT_MESSAGE_MAX_WIDTH_MASK;
|
---|
314 | DWORD dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
|
---|
315 | FormatMessageA(dwFlags, NULL, ecode, dwLanguageId, (LPSTR)message, 1024, NULL);
|
---|
316 | return message;
|
---|
317 | }
|
---|
318 | static __inline WCHAR*
|
---|
319 | gai_strerrorW(int ecode)
|
---|
320 | {
|
---|
321 | static WCHAR message[1024+1];
|
---|
322 | DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM
|
---|
323 | | FORMAT_MESSAGE_IGNORE_INSERTS
|
---|
324 | | FORMAT_MESSAGE_MAX_WIDTH_MASK;
|
---|
325 | DWORD dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
|
---|
326 | FormatMessageW(dwFlags, NULL, ecode, dwLanguageId, (LPWSTR)message, 1024, NULL);
|
---|
327 | return message;
|
---|
328 | }
|
---|
329 | #ifdef UNICODE
|
---|
330 | #define gai_strerror gai_strerrorW
|
---|
331 | #else
|
---|
332 | #define gai_strerror gai_strerrorA
|
---|
333 | #endif
|
---|
334 |
|
---|
335 | /* Some older IPv4/IPv6 compatibility stuff */
|
---|
336 |
|
---|
337 | /* This struct lacks sin6_scope_id; retained for use in sockaddr_gen */
|
---|
338 | struct sockaddr_in6_old {
|
---|
339 | short sin6_family;
|
---|
340 | u_short sin6_port;
|
---|
341 | u_long sin6_flowinfo;
|
---|
342 | struct in6_addr sin6_addr;
|
---|
343 | };
|
---|
344 |
|
---|
345 | typedef union sockaddr_gen{
|
---|
346 | struct sockaddr Address;
|
---|
347 | struct sockaddr_in AddressIn;
|
---|
348 | struct sockaddr_in6_old AddressIn6;
|
---|
349 | } sockaddr_gen;
|
---|
350 |
|
---|
351 |
|
---|
352 | typedef struct _INTERFACE_INFO {
|
---|
353 | u_long iiFlags;
|
---|
354 | sockaddr_gen iiAddress;
|
---|
355 | sockaddr_gen iiBroadcastAddress;
|
---|
356 | sockaddr_gen iiNetmask;
|
---|
357 | } INTERFACE_INFO, *LPINTERFACE_INFO;
|
---|
358 |
|
---|
359 | /*
|
---|
360 | The definition above can cause problems on NT4,prior to sp4.
|
---|
361 | To workaround, include the following struct and typedef and
|
---|
362 | #define INTERFACE_INFO OLD_INTERFACE_INFO
|
---|
363 | See: FIX: WSAIoctl SIO_GET_INTERFACE_LIST Option Problem
|
---|
364 | (Q181520) in MSDN KB.
|
---|
365 |
|
---|
366 | The old definition causes problems on newer NT and on XP.
|
---|
367 |
|
---|
368 | typedef struct _OLD_INTERFACE_INFO {
|
---|
369 | u_long iiFlags;
|
---|
370 | struct sockaddr iiAddress;
|
---|
371 | struct sockaddr iiBroadcastAddress;
|
---|
372 | struct sockaddr iiNetmask;
|
---|
373 | } OLD_INTERFACE_INFO;
|
---|
374 | */
|
---|
375 |
|
---|
376 | #ifdef __cplusplus
|
---|
377 | }
|
---|
378 | #endif
|
---|
379 | #endif
|
---|