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