|
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_MREG; |
|
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 |