[1046] | 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
|
---|