1 /***********************************************************************\
2 *                              ws2tcpip.d                               *
3 *                                                                       *
4 *                       Windows API header module                       *
5 *                                                                       *
6 *                 Translated from MinGW Windows headers                 *
7 *                                                                       *
8 *                       Placed into public domain                       *
9 \***********************************************************************/
10 
11 module win32.ws2tcpip;
12 
13 import win32.w32api;
14 //import win32.winbase;
15 import win32.windef;
16 //import win32.basetyps;
17 import win32.winsock2;
18 
19 enum {
20 	IP_OPTIONS					= 1,
21 
22 	IP_HDRINCL					= 2,
23 	IP_TOS						= 3,
24 	IP_TTL						= 4,
25 	IP_MULTICAST_IF				= 9,
26 	IP_MULTICAST_TTL			= 10,
27 	IP_MULTICAST_LOOP			= 11,
28 	IP_ADD_MEMBERSHIP			= 12,
29 	IP_DROP_MEMBERSHIP			= 13,
30 	IP_DONTFRAGMENT				= 14,
31 	IP_ADD_SOURCE_MEMBERSHIP	= 15,
32 	IP_DROP_SOURCE_MEMBERSHIP	= 16,
33 	IP_BLOCK_SOURCE				= 17,
34 	IP_UNBLOCK_SOURCE			= 18,
35 	IP_PKTINFO					= 19
36 }	
37 
38 enum {
39 	IPV6_UNICAST_HOPS		= 4,
40 	IPV6_MULTICAST_IF		= 9,
41 	IPV6_MULTICAST_HOPS		= 10,
42 	IPV6_MULTICAST_LOOP		= 11,
43 	IPV6_ADD_MEMBERSHIP		= 12,
44 	IPV6_DROP_MEMBERSHIP	= 13,
45 	IPV6_JOIN_GROUP			= IPV6_ADD_MEMBERSHIP,
46 	IPV6_LEAVE_GROUP		= IPV6_DROP_MEMBERSHIP,
47 	IPV6_PKTINFO			= 19
48 }
49 
50 const IP_DEFAULT_MULTICAST_TTL = 1;
51 const IP_DEFAULT_MULTICAST_LOOP = 1;
52 const IP_MAX_MEMBERSHIPS = 20;
53 
54 const TCP_EXPEDITED_1122 = 2;
55 
56 const UDP_NOCHECKSUM = 1;
57 
58 enum {
59 	IFF_UP				= 1,
60 	IFF_BROADCAST		= 2,
61 	IFF_LOOPBACK		= 4,
62 	IFF_POINTTOPOINT	= 8,
63 	IFF_MULTICAST		= 16
64 }
65 
66 const SIO_GET_INTERFACE_LIST = _IOR!('t', 127, u_long);
67 
68 const INET_ADDRSTRLEN	= 16;
69 const INET6_ADDRSTRLEN	= 46;
70 
71 const NI_MAXHOST	= 1025;
72 const NI_MAXSERV	= 32;
73 
74 const NI_NOFQDN			= 0x01;
75 const NI_NUMERICHOST	= 0x02;
76 const NI_NAMEREQD		= 0x04;
77 const NI_NUMERICSERV	= 0x08;
78 const NI_DGRAM			= 0x10;
79 
80 const AI_PASSIVE		= 1;
81 const AI_CANONNAME		= 2;
82 const AI_NUMERICHOST	= 4;
83 
84 const EAI_AGAIN		= WSATRY_AGAIN;
85 const EAI_BADFLAGS	= WSAEINVAL;
86 const EAI_FAIL		= WSANO_RECOVERY;
87 const EAI_FAMILY	= WSAEAFNOSUPPORT;
88 const EAI_MEMORY	= WSA_NOT_ENOUGH_MEMORY;
89 const EAI_NODATA	= WSANO_DATA;
90 const EAI_NONAME	= WSAHOST_NOT_FOUND;
91 const EAI_SERVICE	= WSATYPE_NOT_FOUND;
92 const EAI_SOCKTYPE	= WSAESOCKTNOSUPPORT;
93 
94 struct ip_mreq {
95 	IN_ADDR imr_multiaddr;
96 	IN_ADDR imr_interface;
97 }
98 
99 struct ip_mreq_source {
100 	IN_ADDR imr_multiaddr;
101 	IN_ADDR imr_sourceaddr;
102 	IN_ADDR imr_interface;
103 }
104 
105 struct ip_msfilter {
106 	IN_ADDR		imsf_multiaddr;
107 	IN_ADDR		imsf_interface;
108 	u_long		imsf_fmode;
109 	u_long		imsf_numsrc;
110 	IN_ADDR[1]	imsf_slist;
111 }
112 
113 template IP_MSFILTER_SIZE(ULONG numsrc) {
114 	const DWORD IP_MSFILTER_SIZE = ip_msfilter.sizeof - IN_ADDR.sizeof + numsrc * IN_ADDR.sizeof;
115 }
116 
117 struct IN_PKTINFO {
118 	IN_ADDR	ipi_addr;
119 	UINT	ipi_ifindex;
120 }
121 
122 struct IN6_ADDR {
123 	union {
124 		u_char[16]	_S6_u8;
125 		u_short[8]	_S6_u16;
126 		u_long[4]	_S6_u32;
127 	}
128 }
129 alias IN6_ADDR* PIN6_ADDR, LPIN6_ADDR;
130 
131 struct SOCKADDR_IN6 {
132 	short sin6_family;
133 	u_short sin6_port;
134 	u_long sin6_flowinfo;
135 	IN6_ADDR sin6_addr;
136 	u_long sin6_scope_id;
137 };
138 alias SOCKADDR_IN6* PSOCKADDR_IN6, LPSOCKADDR_IN6;
139 
140 extern IN6_ADDR in6addr_any;
141 extern IN6_ADDR in6addr_loopback;
142 
143 /+ TODO: 
144 #define IN6_ARE_ADDR_EQUAL(a, b)	\
145     (memcmp ((void*)(a), (void*)(b), sizeof (struct in6_addr)) == 0)
146 
147 #define IN6_IS_ADDR_UNSPECIFIED(_addr) \
148 	(   (((const u_long *)(_addr))[0] == 0)	\
149 	 && (((const u_long *)(_addr))[1] == 0)	\
150 	 && (((const u_long *)(_addr))[2] == 0)	\
151 	 && (((const u_long *)(_addr))[3] == 0))
152 
153 #define IN6_IS_ADDR_LOOPBACK(_addr) \
154 	(   (((const u_long *)(_addr))[0] == 0)	\
155 	 && (((const u_long *)(_addr))[1] == 0)	\
156 	 && (((const u_long *)(_addr))[2] == 0)	\
157 	 && (((const u_long *)(_addr))[3] == 0x01000000))
158 
159 #define IN6_IS_ADDR_MULTICAST(_addr) (((const u_char *) (_addr))[0] == 0xff)
160 
161 #define IN6_IS_ADDR_LINKLOCAL(_addr) \
162 	(   (((const u_char *)(_addr))[0] == 0xfe)	\
163 	 && ((((const u_char *)(_addr))[1] & 0xc0) == 0x80))
164 
165 #define IN6_IS_ADDR_SITELOCAL(_addr) \
166 	(   (((const u_char *)(_addr))[0] == 0xfe)	\
167 	 && ((((const u_char *)(_addr))[1] & 0xc0) == 0xc0))
168 
169 #define IN6_IS_ADDR_V4MAPPED(_addr) \
170 	(   (((const u_long *)(_addr))[0] == 0)		\
171 	 && (((const u_long *)(_addr))[1] == 0)		\
172 	 && (((const u_long *)(_addr))[2] == 0xffff0000))
173 
174 #define IN6_IS_ADDR_V4COMPAT(_addr) \
175 	(   (((const u_long *)(_addr))[0] == 0)		\
176 	 && (((const u_long *)(_addr))[1] == 0)		\
177 	 && (((const u_long *)(_addr))[2] == 0)		\
178 	 && (((const u_long *)(_addr))[3] != 0)		\
179 	 && (((const u_long *)(_addr))[3] != 0x01000000))
180 
181 #define IN6_IS_ADDR_MC_NODELOCAL(_addr)	\
182 	(   IN6_IS_ADDR_MULTICAST(_addr)		\
183 	 && ((((const u_char *)(_addr))[1] & 0xf) == 0x1)) 
184 
185 #define IN6_IS_ADDR_MC_LINKLOCAL(_addr)	\
186 	(   IN6_IS_ADDR_MULTICAST (_addr)		\
187 	 && ((((const u_char *)(_addr))[1] & 0xf) == 0x2))
188 
189 #define IN6_IS_ADDR_MC_SITELOCAL(_addr)	\
190 	(   IN6_IS_ADDR_MULTICAST(_addr)		\
191 	 && ((((const u_char *)(_addr))[1] & 0xf) == 0x5))
192 
193 #define IN6_IS_ADDR_MC_ORGLOCAL(_addr)	\
194 	(   IN6_IS_ADDR_MULTICAST(_addr)		\
195 	 && ((((const u_char *)(_addr))[1] & 0xf) == 0x8))
196 
197 #define IN6_IS_ADDR_MC_GLOBAL(_addr)	\
198 	(   IN6_IS_ADDR_MULTICAST(_addr)	\
199 	 && ((((const u_char *)(_addr))[1] & 0xf) == 0xe))
200 +/
201 
202 alias int socklen_t;
203 
204 struct IPV6_MREG {
205 	IN6_ADDR	ipv6mr_multiaddr;
206 	uint		ipv6mr_interface;
207 }
208 
209 struct IN6_PKTINFO {
210 	IN6_ADDR	ipi6_addr;
211 	UINT		ipi6_ifindex;
212 }
213 
214 struct addrinfo {
215 	int			ai_flags;
216 	int			ai_family;
217 	int			ai_socktype;
218 	int			ai_protocol;
219 	size_t		ai_addrlen;
220 	char*		ai_canonname;
221 	SOCKADDR*	ai_addr;
222 	addrinfo*	ai_next;
223 }
224 
225 extern(Windows) {
226 	static if (_WIN32_WINNT >= 0x0501) {
227 		void freeaddrinfo(addrinfo*);
228 		int getaddrinfo (CPtr!(char), CPtr!(char), CPtr!(addrinfo), addrinfo**);
229 		int getnameinfo(CPtr!(SOCKADDR), socklen_t, char*, DWORD, char*, DWORD, int);
230 	}
231 }
232 
233 /+ TODO
234 static __inline char*
235 gai_strerrorA(int ecode)
236 {
237 	static char message[1024+1];
238 	DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM
239 	              | FORMAT_MESSAGE_IGNORE_INSERTS
240 		      | FORMAT_MESSAGE_MAX_WIDTH_MASK;
241 	DWORD dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
242   	FormatMessageA(dwFlags, NULL, ecode, dwLanguageId, (LPSTR)message, 1024, NULL);
243 	return message;
244 }
245 static __inline WCHAR*
246 gai_strerrorW(int ecode)
247 {
248 	static WCHAR message[1024+1];
249 	DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM
250 	              | FORMAT_MESSAGE_IGNORE_INSERTS
251 		      | FORMAT_MESSAGE_MAX_WIDTH_MASK;
252 	DWORD dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
253   	FormatMessageW(dwFlags, NULL, ecode, dwLanguageId, (LPWSTR)message, 1024, NULL);
254 	return message;
255 }
256 #ifdef UNICODE
257 #define gai_strerror gai_strerrorW
258 #else
259 #define gai_strerror gai_strerrorA
260 #endif
261 +/
262 
263 extern(Windows) {
264 	INT getnameinfo(SOCKADDR* pSockaddr, socklen_t SockaddrLength,
265 		PCHAR pNodeBuffer, DWORD NodeBufferSize, PCHAR pServiceBuffer,
266 		DWORD ServiceBufferSize, INT Flags);
267 
268 	static if (_WIN32_WINNT >= 0x0502) {
269 		INT GetNameInfoW(SOCKADDR* pSockaddr, socklen_t SockaddrLength,
270 			PWCHAR pNodeBuffer, DWORD NodeBufferSize, PWCHAR pServiceBuffer,
271 			DWORD ServiceBufferSize, INT Flags);
272 
273 		alias getnameinfo GetNameInfoA;
274 
275 		version(Unicode) {
276 			alias GetNameInfoW GetNameInfo;
277 		} else {
278 			alias GetNameInfoA GetNameInfo;
279 		}
280 	}
281 }