OSDN Git Service

Avoid an implication that the API is exclusively 32-bit.
[mingw/mingw-org-wsl.git] / wslapi / include / ws2tcpip.h
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