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 |