xref: /reactos/sdk/include/psdk/mstcpip.h (revision c2c66aff)
1 #pragma once
2 
3 #ifdef __cplusplus
4 extern "C" {
5 #endif
6 
7 #ifndef ASSERT
8 #define MSTCPIP_ASSERT_UNDEFINED
9 #define ASSERT(exp) ((VOID) 0)
10 #endif
11 
12 #ifdef _MSC_VER
13 #define MSTCPIP_INLINE __inline
14 #else
15 #define MSTCPIP_INLINE static inline
16 #endif
17 
18 #include <nldef.h>
19 
20 struct tcp_keepalive {
21   ULONG onoff;
22   ULONG keepalivetime;
23   ULONG keepaliveinterval;
24 };
25 
26 #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
27 #define SIO_RCVALL_MCAST _WSAIOW(IOC_VENDOR,2)
28 #define SIO_RCVALL_IGMPMCAST _WSAIOW(IOC_VENDOR,3)
29 #define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
30 #define SIO_ABSORB_RTRALERT _WSAIOW(IOC_VENDOR,5)
31 #define SIO_UCAST_IF _WSAIOW(IOC_VENDOR,6)
32 #define SIO_LIMIT_BROADCASTS _WSAIOW(IOC_VENDOR,7)
33 #define SIO_INDEX_BIND _WSAIOW(IOC_VENDOR,8)
34 #define SIO_INDEX_MCASTIF _WSAIOW(IOC_VENDOR,9)
35 #define SIO_INDEX_ADD_MCAST _WSAIOW(IOC_VENDOR,10)
36 #define SIO_INDEX_DEL_MCAST _WSAIOW(IOC_VENDOR,11)
37 #define SIO_RCVALL_MCAST_IF _WSAIOW(IOC_VENDOR,13)
38 #define SIO_RCVALL_IF _WSAIOW(IOC_VENDOR,14)
39 
40 typedef enum {
41   RCVALL_OFF = 0,
42   RCVALL_ON = 1,
43   RCVALL_SOCKETLEVELONLY = 2,
44   RCVALL_IPLEVEL = 3,
45 } RCVALL_VALUE, *PRCVALL_VALUE;
46 
47 #define RCVALL_MAX RCVALL_IPLEVEL
48 
49 typedef struct {
50   RCVALL_VALUE Mode;
51   ULONG Interface;
52 } RCVALL_IF, *PRCVALL_IF;
53 
54 #if (NTDDI_VERSION >= NTDDI_WIN7)
55 DEFINE_GUID(SOCKET_DEFAULT2_QM_POLICY, 0xaec2ef9c, 0x3a4d, 0x4d3e, 0x88, 0x42, 0x23, 0x99, 0x42, 0xe3, 0x9a, 0x47);
56 #endif
57 
58 #define SIO_ACQUIRE_PORT_RESERVATION _WSAIOW(IOC_VENDOR, 100)
59 #define SIO_RELEASE_PORT_RESERVATION _WSAIOW(IOC_VENDOR, 101)
60 #define SIO_ASSOCIATE_PORT_RESERVATION _WSAIOW(IOC_VENDOR, 102)
61 
62 typedef struct _INET_PORT_RANGE {
63   USHORT StartPort;
64   USHORT NumberOfPorts;
65 } INET_PORT_RANGE, *PINET_PORT_RANGE;
66 typedef struct _INET_PORT_RANGE INET_PORT_RESERVATION, *PINET_PORT_RESERVATION;
67 
68 typedef struct {
69   ULONG64 Token;
70 } INET_PORT_RESERVATION_TOKEN, *PINET_PORT_RESERVATION_TOKEN;
71 
72 #define INVALID_PORT_RESERVATION_TOKEN ((ULONG64)0)
73 
74 typedef struct {
75 #ifdef __cplusplus
76   INET_PORT_RESERVATION Reservation;
77   INET_PORT_RESERVATION_TOKEN Token;
78 #else
79   INET_PORT_RESERVATION;
80   INET_PORT_RESERVATION_TOKEN;
81 #endif
82 } INET_PORT_RESERVATION_INSTANCE, *PINET_PORT_RESERVATION_INSTANCE;
83 
84 typedef struct {
85   ULONG AssignmentCount;
86   ULONG OwningPid;
87 } INET_PORT_RESERVATION_INFORMATION, *PINET_PORT_RESERVATION_INFORMATION;
88 
89 #ifdef _WS2DEF_
90 
91 #if (NTDDI_VERSION >= NTDDI_VISTA)
92 
93 #define _SECURE_SOCKET_TYPES_DEFINED_
94 
95 #define SIO_SET_SECURITY             _WSAIOW(IOC_VENDOR, 200)
96 #define SIO_QUERY_SECURITY           _WSAIORW(IOC_VENDOR, 201)
97 #define SIO_SET_PEER_TARGET_NAME     _WSAIOW(IOC_VENDOR, 202)
98 #define SIO_DELETE_PEER_TARGET_NAME  _WSAIOW(IOC_VENDOR, 203)
99 
100 #define SIO_SOCKET_USAGE_NOTIFICATION _WSAIOW(IOC_VENDOR, 204)
101 
102 typedef enum _SOCKET_USAGE_TYPE {
103   SYSTEM_CRITICAL_SOCKET = 1
104 }SOCKET_USAGE_TYPE;
105 
106 typedef enum _SOCKET_SECURITY_PROTOCOL {
107   SOCKET_SECURITY_PROTOCOL_DEFAULT,
108   SOCKET_SECURITY_PROTOCOL_IPSEC,
109 #if (NTDDI_VERSION >= NTDDI_WIN7)
110   SOCKET_SECURITY_PROTOCOL_IPSEC2,
111 #endif
112   SOCKET_SECURITY_PROTOCOL_INVALID
113 } SOCKET_SECURITY_PROTOCOL;
114 
115 #define SOCKET_SETTINGS_GUARANTEE_ENCRYPTION  0x1
116 #define SOCKET_SETTINGS_ALLOW_INSECURE  0x2
117 
118 typedef struct _SOCKET_SECURITY_SETTINGS {
119   SOCKET_SECURITY_PROTOCOL SecurityProtocol;
120   ULONG SecurityFlags;
121 } SOCKET_SECURITY_SETTINGS;
122 
123 #define SOCKET_SETTINGS_IPSEC_SKIP_FILTER_INSTANTIATION            0x1
124 
125 #if (NTDDI_VERSION >= NTDDI_WIN7)
126 
127 #define SOCKET_SETTINGS_IPSEC_OPTIONAL_PEER_NAME_VERIFICATION      0x2
128 #define SOCKET_SETTINGS_IPSEC_ALLOW_FIRST_INBOUND_PKT_UNENCRYPTED  0x4
129 #define SOCKET_SETTINGS_IPSEC_PEER_NAME_IS_RAW_FORMAT              0x8
130 
131 #endif /* (NTDDI_VERSION >= NTDDI_WIN7) */
132 
133 typedef struct _SOCKET_SECURITY_SETTINGS_IPSEC {
134   SOCKET_SECURITY_PROTOCOL SecurityProtocol;
135   ULONG SecurityFlags;
136   ULONG IpsecFlags;
137   GUID AuthipMMPolicyKey;
138   GUID AuthipQMPolicyKey;
139   GUID Reserved;
140   UINT64 Reserved2;
141   ULONG UserNameStringLen;
142   ULONG DomainNameStringLen;
143   ULONG PasswordStringLen;
144   wchar_t AllStrings[0];
145 } SOCKET_SECURITY_SETTINGS_IPSEC;
146 
147 typedef struct _SOCKET_PEER_TARGET_NAME {
148   SOCKET_SECURITY_PROTOCOL SecurityProtocol;
149   SOCKADDR_STORAGE PeerAddress;
150   ULONG PeerTargetNameStringLen;
151   wchar_t AllStrings[0];
152 } SOCKET_PEER_TARGET_NAME;
153 
154 typedef struct _SOCKET_SECURITY_QUERY_TEMPLATE {
155   SOCKET_SECURITY_PROTOCOL SecurityProtocol;
156   SOCKADDR_STORAGE PeerAddress;
157   ULONG PeerTokenAccessMask;
158 } SOCKET_SECURITY_QUERY_TEMPLATE;
159 
160 #if (NTDDI_VERSION >= NTDDI_WIN7)
161 
162 #define SOCKET_QUERY_IPSEC2_ABORT_CONNECTION_ON_FIELD_CHANGE 0x1
163 
164 #define SOCKET_QUERY_IPSEC2_FIELD_MASK_MM_SA_ID 0x1
165 #define SOCKET_QUERY_IPSEC2_FIELD_MASK_QM_SA_ID 0x2
166 
167 typedef struct _SOCKET_SECURITY_QUERY_TEMPLATE_IPSEC2 {
168   SOCKET_SECURITY_PROTOCOL SecurityProtocol;
169   SOCKADDR_STORAGE PeerAddress;
170   ULONG PeerTokenAccessMask;
171   ULONG Flags;
172   ULONG FieldMask;
173 } SOCKET_SECURITY_QUERY_TEMPLATE_IPSEC2;
174 
175 #endif /* (NTDDI_VERSION >= NTDDI_WIN7) */
176 
177 #define SOCKET_INFO_CONNECTION_SECURED  0x1
178 #define SOCKET_INFO_CONNECTION_ENCRYPTED  0x2
179 #define SOCKET_INFO_CONNECTION_IMPERSONATED 0x4
180 
181 typedef struct _SOCKET_SECURITY_QUERY_INFO {
182   SOCKET_SECURITY_PROTOCOL SecurityProtocol;
183   ULONG Flags;
184   UINT64 PeerApplicationAccessTokenHandle;
185   UINT64 PeerMachineAccessTokenHandle;
186 } SOCKET_SECURITY_QUERY_INFO;
187 
188 #if (NTDDI_VERSION >= NTDDI_WIN7)
189 typedef struct _SOCKET_SECURITY_QUERY_INFO_IPSEC2 {
190   SOCKET_SECURITY_PROTOCOL SecurityProtocol;
191   ULONG Flags;
192   UINT64 PeerApplicationAccessTokenHandle;
193   UINT64 PeerMachineAccessTokenHandle;
194   UINT64 MmSaId;
195   UINT64 QmSaId;
196   UINT32 NegotiationWinerr;
197   GUID SaLookupContext;
198 } SOCKET_SECURITY_QUERY_INFO_IPSEC2;
199 #endif
200 
201 #define SIO_QUERY_WFP_ALE_ENDPOINT_HANDLE _WSAIOR(IOC_VENDOR, 205)
202 #define SIO_QUERY_RSS_SCALABILITY_INFO _WSAIOR(IOC_VENDOR, 210)
203 
204 typedef struct _RSS_SCALABILITY_INFO {
205   BOOLEAN RssEnabled;
206 } RSS_SCALABILITY_INFO, *PRSS_SCALABILITY_INFO;
207 
208 #endif /* (NTDDI_VERSION >= NTDDI_VISTA) */
209 
210 #define IN4_CLASSA(i) (((LONG)(i) & 0x00000080) == 0)
211 #define IN4_CLASSB(i) (((LONG)(i) & 0x000000c0) == 0x00000080)
212 #define IN4_CLASSC(i) (((LONG)(i) & 0x000000e0) == 0x000000c0)
213 #define IN4_CLASSD(i) (((LONG)(i) & 0x000000f0) == 0x000000e0)
214 #define IN4_MULTICAST(i) IN4_CLASSD(i)
215 
216 #define IN4ADDR_ANY INADDR_ANY
217 #define IN4ADDR_LOOPBACK 0x0100007f
218 #define IN4ADDR_BROADCAST INADDR_BROADCAST
219 #define IN4ADDR_NONE INADDR_NONE
220 #define IN4ADDR_ANY_INIT { 0 }
221 #define IN4ADDR_LOOPBACK_INIT { 0x7f, 0, 0, 1 }
222 #define IN4ADDR_BROADCAST_INIT { 0xff, 0xff, 0xff, 0xff }
223 #define IN4ADDR_ALLNODESONLINK_INIT { 0xe0, 0, 0, 1 }
224 #define IN4ADDR_ALLROUTERSONLINK_INIT { 0xe0, 0, 0, 2 }
225 #define IN4ADDR_ALLIGMPV3ROUTERSONLINK_INIT { 0xe0, 0, 0, 0x16 }
226 #define IN4ADDR_ALLTEREDONODESONLINK_INIT { 0xe0, 0, 0, 0xfd }
227 #define IN4ADDR_LINKLOCALPREFIX_INIT { 0xa9, 0xfe, }
228 #define IN4ADDR_MULTICASTPREFIX_INIT { 0xe0, }
229 
230 #define IN4ADDR_LOOPBACKPREFIX_LENGTH 8
231 #define IN4ADDR_LINKLOCALPREFIX_LENGTH 16
232 #define IN4ADDR_MULTICASTPREFIX_LENGTH 4
233 
234 #if (NTDDI_VERSION >= NTDDI_WIN2KSP1)
235 
236 MSTCPIP_INLINE
237 BOOLEAN
IN4_ADDR_EQUAL(_In_ CONST IN_ADDR * a,_In_ CONST IN_ADDR * b)238 IN4_ADDR_EQUAL(
239   _In_ CONST IN_ADDR *a,
240   _In_ CONST IN_ADDR *b)
241 {
242   return (BOOLEAN)(a->s_addr == b->s_addr);
243 }
244 
245 MSTCPIP_INLINE
246 BOOLEAN
IN4_UNALIGNED_ADDR_EQUAL(_In_ CONST IN_ADDR UNALIGNED * a,_In_ CONST IN_ADDR UNALIGNED * b)247 IN4_UNALIGNED_ADDR_EQUAL(
248   _In_ CONST IN_ADDR UNALIGNED *a,
249   _In_ CONST IN_ADDR UNALIGNED *b)
250 {
251   return (BOOLEAN)(a->s_addr == b->s_addr);
252 }
253 
254 MSTCPIP_INLINE
255 BOOLEAN
IN4_IS_ADDR_UNSPECIFIED(_In_ CONST IN_ADDR * a)256 IN4_IS_ADDR_UNSPECIFIED(
257   _In_ CONST IN_ADDR *a)
258 {
259   return (BOOLEAN)(a->s_addr == IN4ADDR_ANY);
260 }
261 
262 MSTCPIP_INLINE
263 BOOLEAN
IN4_IS_UNALIGNED_ADDR_UNSPECIFIED(_In_ CONST IN_ADDR UNALIGNED * a)264 IN4_IS_UNALIGNED_ADDR_UNSPECIFIED(
265   _In_ CONST IN_ADDR UNALIGNED *a)
266 {
267   return (BOOLEAN)(a->s_addr == IN4ADDR_ANY);
268 }
269 
270 MSTCPIP_INLINE
271 BOOLEAN
IN4_IS_ADDR_LOOPBACK(_In_ CONST IN_ADDR * a)272 IN4_IS_ADDR_LOOPBACK(
273   _In_ CONST IN_ADDR *a)
274 {
275   return (BOOLEAN)(*((PUCHAR) a) == 0x7f);
276 }
277 
278 MSTCPIP_INLINE
279 BOOLEAN
IN4_IS_UNALIGNED_ADDR_LOOPBACK(_In_ CONST IN_ADDR UNALIGNED * a)280 IN4_IS_UNALIGNED_ADDR_LOOPBACK(
281   _In_ CONST IN_ADDR UNALIGNED *a)
282 {
283   return (BOOLEAN)(*((PUCHAR) a) == 0x7f);
284 }
285 
286 MSTCPIP_INLINE
287 BOOLEAN
IN4_IS_ADDR_BROADCAST(_In_ CONST IN_ADDR * a)288 IN4_IS_ADDR_BROADCAST(
289   _In_ CONST IN_ADDR *a)
290 {
291   return (BOOLEAN)(a->s_addr == IN4ADDR_BROADCAST);
292 }
293 
294 MSTCPIP_INLINE
295 BOOLEAN
IN4_IS_UNALIGNED_ADDR_BROADCAST(_In_ CONST IN_ADDR UNALIGNED * a)296 IN4_IS_UNALIGNED_ADDR_BROADCAST(
297   _In_ CONST IN_ADDR UNALIGNED *a)
298 {
299   return (BOOLEAN)(a->s_addr == IN4ADDR_BROADCAST);
300 }
301 
302 MSTCPIP_INLINE
303 BOOLEAN
IN4_IS_ADDR_MULTICAST(_In_ CONST IN_ADDR * a)304 IN4_IS_ADDR_MULTICAST(
305   _In_ CONST IN_ADDR *a)
306 {
307   return (BOOLEAN)IN4_MULTICAST(a->s_addr);
308 }
309 
310 MSTCPIP_INLINE
311 BOOLEAN
IN4_IS_UNALIGNED_ADDR_MULTICAST(_In_ CONST IN_ADDR UNALIGNED * a)312 IN4_IS_UNALIGNED_ADDR_MULTICAST(
313   _In_ CONST IN_ADDR UNALIGNED *a)
314 {
315   return (BOOLEAN)IN4_MULTICAST(a->s_addr);
316 }
317 
318 MSTCPIP_INLINE
319 BOOLEAN
IN4_IS_ADDR_LINKLOCAL(_In_ CONST IN_ADDR * a)320 IN4_IS_ADDR_LINKLOCAL(
321   _In_ CONST IN_ADDR *a)
322 {
323   return (BOOLEAN)((a->s_addr & 0xffff) == 0xfea9);
324 }
325 
326 MSTCPIP_INLINE
327 BOOLEAN
IN4_IS_UNALIGNED_ADDR_LINKLOCAL(_In_ CONST IN_ADDR UNALIGNED * a)328 IN4_IS_UNALIGNED_ADDR_LINKLOCAL(
329   _In_ CONST IN_ADDR UNALIGNED *a)
330 {
331   return (BOOLEAN)((a->s_addr & 0xffff) == 0xfea9); // 169.254/16
332 }
333 
334 MSTCPIP_INLINE
335 BOOLEAN
IN4_IS_ADDR_SITELOCAL(_In_ CONST IN_ADDR * a)336 IN4_IS_ADDR_SITELOCAL(
337   _In_ CONST IN_ADDR *a)
338 {
339   UNREFERENCED_PARAMETER(a);
340   return FALSE;
341 }
342 #define IN4_IS_UNALIGNED_ADDR_SITELOCAL IN4_IS_ADDR_SITELOCAL
343 
344 MSTCPIP_INLINE
345 BOOLEAN
IN4_IS_ADDR_RFC1918(_In_ CONST IN_ADDR * a)346 IN4_IS_ADDR_RFC1918(
347   _In_ CONST IN_ADDR *a)
348 {
349   return (BOOLEAN)(((a->s_addr & 0x00ff) == 0x0a) ||
350                    ((a->s_addr & 0xf0ff) == 0x10ac) ||
351                    ((a->s_addr & 0xffff) == 0xa8c0));
352 }
353 
354 MSTCPIP_INLINE
355 BOOLEAN
IN4_IS_UNALIGNED_ADDR_RFC1918(_In_ CONST IN_ADDR UNALIGNED * a)356 IN4_IS_UNALIGNED_ADDR_RFC1918(
357   _In_ CONST IN_ADDR UNALIGNED *a)
358 {
359   IN_ADDR Ipv4Address = *a;
360   return IN4_IS_ADDR_RFC1918(&Ipv4Address);
361 }
362 
363 MSTCPIP_INLINE
364 BOOLEAN
IN4_IS_ADDR_MC_LINKLOCAL(_In_ CONST IN_ADDR * a)365 IN4_IS_ADDR_MC_LINKLOCAL(
366   _In_ CONST IN_ADDR *a)
367 {
368   return (BOOLEAN)((a->s_addr & 0xffffff) == 0xe0);
369 }
370 
371 MSTCPIP_INLINE
372 BOOLEAN
IN4_IS_ADDR_MC_ADMINLOCAL(_In_ CONST IN_ADDR * a)373 IN4_IS_ADDR_MC_ADMINLOCAL(
374   _In_ CONST IN_ADDR *a)
375 {
376   return (BOOLEAN)((a->s_addr & 0xffff) == 0xffef);
377 }
378 
379 MSTCPIP_INLINE
380 BOOLEAN
IN4_IS_ADDR_MC_SITELOCAL(_In_ CONST IN_ADDR * a)381 IN4_IS_ADDR_MC_SITELOCAL(
382   _In_ CONST IN_ADDR *a)
383 {
384   return (BOOLEAN)((a->s_addr & 0xff) == 0xef) &&
385                   !IN4_IS_ADDR_MC_ADMINLOCAL(a);
386 }
387 
388 MSTCPIP_INLINE
389 VOID
IN4ADDR_SETSOCKADDR(_Out_ PSOCKADDR_IN a,_In_ CONST IN_ADDR * addr,_In_ USHORT port)390 IN4ADDR_SETSOCKADDR(
391   _Out_ PSOCKADDR_IN a,
392   _In_ CONST IN_ADDR *addr,
393   _In_ USHORT port)
394 {
395   a->sin_family = AF_INET;
396   a->sin_port = port;
397   a->sin_addr = *addr;
398   memset(a->sin_zero, 0, sizeof(a->sin_zero));
399 }
400 
401 MSTCPIP_INLINE
402 VOID
IN4ADDR_SETANY(_Out_ PSOCKADDR_IN a)403 IN4ADDR_SETANY(
404   _Out_ PSOCKADDR_IN a)
405 {
406   a->sin_family = AF_INET;
407   a->sin_port = 0;
408   a->sin_addr.s_addr = IN4ADDR_ANY;
409   memset(a->sin_zero, 0, sizeof(a->sin_zero));
410 }
411 
412 MSTCPIP_INLINE
413 VOID
IN4ADDR_SETLOOPBACK(_Out_ PSOCKADDR_IN a)414 IN4ADDR_SETLOOPBACK(
415   _Out_ PSOCKADDR_IN a)
416 {
417   a->sin_family = AF_INET;
418   a->sin_port = 0;
419   a->sin_addr.s_addr = IN4ADDR_LOOPBACK;
420   memset(a->sin_zero, 0, sizeof(a->sin_zero));
421 }
422 
423 MSTCPIP_INLINE
424 BOOLEAN
IN4ADDR_ISANY(_In_ CONST SOCKADDR_IN * a)425 IN4ADDR_ISANY(
426   _In_ CONST SOCKADDR_IN *a)
427 {
428   ASSERT(a->sin_family == AF_INET);
429   return IN4_IS_ADDR_UNSPECIFIED(&a->sin_addr);
430 }
431 
432 MSTCPIP_INLINE
433 BOOLEAN
IN4ADDR_ISLOOPBACK(_In_ CONST SOCKADDR_IN * a)434 IN4ADDR_ISLOOPBACK(
435   _In_ CONST SOCKADDR_IN *a)
436 {
437   ASSERT(a->sin_family == AF_INET);
438   return IN4_IS_ADDR_LOOPBACK(&a->sin_addr);
439 }
440 
441 MSTCPIP_INLINE
442 SCOPE_ID
IN4ADDR_SCOPE_ID(_In_ CONST SOCKADDR_IN * a)443 IN4ADDR_SCOPE_ID(
444   _In_ CONST SOCKADDR_IN *a)
445 {
446   SCOPE_ID UnspecifiedScopeId = {{{0}}};
447   UNREFERENCED_PARAMETER(a);
448   return UnspecifiedScopeId;
449 }
450 
451 MSTCPIP_INLINE
452 BOOLEAN
IN4ADDR_ISEQUAL(_In_ CONST SOCKADDR_IN * a,_In_ CONST SOCKADDR_IN * b)453 IN4ADDR_ISEQUAL(
454   _In_ CONST SOCKADDR_IN *a,
455   _In_ CONST SOCKADDR_IN *b)
456 {
457   ASSERT(a->sin_family == AF_INET);
458   return (BOOLEAN)(IN4ADDR_SCOPE_ID(a).Value == IN4ADDR_SCOPE_ID(b).Value &&
459                    IN4_ADDR_EQUAL(&a->sin_addr, &b->sin_addr));
460 }
461 
462 MSTCPIP_INLINE
463 BOOLEAN
IN4ADDR_ISUNSPECIFIED(_In_ CONST SOCKADDR_IN * a)464 IN4ADDR_ISUNSPECIFIED(
465   _In_ CONST SOCKADDR_IN *a)
466 {
467   ASSERT(a->sin_family == AF_INET);
468   return (BOOLEAN)(IN4ADDR_SCOPE_ID(a).Value == 0 &&
469                    IN4_IS_ADDR_UNSPECIFIED(&a->sin_addr));
470 }
471 
472 #define INET_IS_ALIGNED(Pointer, Type) \
473    (((ULONG_PTR)Pointer & (TYPE_ALIGNMENT(Type)-1)) == 0)
474 
475 MSTCPIP_INLINE
476 SCOPE_LEVEL
Ipv4UnicastAddressScope(_In_ CONST UCHAR * Address)477 Ipv4UnicastAddressScope(
478   _In_ CONST UCHAR *Address)
479 {
480   IN_ADDR Ipv4Address;
481 
482   if (!INET_IS_ALIGNED(Address, IN_ADDR)) {
483       Ipv4Address = *(CONST IN_ADDR UNALIGNED *)Address;
484       Address = (CONST UCHAR *) &Ipv4Address;
485   }
486   if (IN4_IS_ADDR_LINKLOCAL((PIN_ADDR) Address) ||
487       IN4_IS_ADDR_LOOPBACK((PIN_ADDR) Address)) {
488       return ScopeLevelLink;
489   }
490   return ScopeLevelGlobal;
491 }
492 
493 MSTCPIP_INLINE
494 SCOPE_LEVEL
Ipv4MulticastAddressScope(_In_ CONST UCHAR * Address)495 Ipv4MulticastAddressScope(
496   _In_ CONST UCHAR *Address)
497 {
498   IN_ADDR Ipv4Address;
499 
500   if (!INET_IS_ALIGNED(Address, IN_ADDR)) {
501     Ipv4Address = *(CONST IN_ADDR UNALIGNED *)Address;
502     Address = (CONST UCHAR *) &Ipv4Address;
503   }
504   if (IN4_IS_ADDR_MC_LINKLOCAL((PIN_ADDR) Address)) {
505     return ScopeLevelLink;
506   } else if (IN4_IS_ADDR_MC_ADMINLOCAL((PIN_ADDR) Address)) {
507     return ScopeLevelAdmin;
508   } else if (IN4_IS_ADDR_MC_SITELOCAL((PIN_ADDR) Address)) {
509     return ScopeLevelSite;
510   } else {
511     return ScopeLevelGlobal;
512   }
513 }
514 
515 MSTCPIP_INLINE
516 SCOPE_LEVEL
Ipv4AddressScope(_In_ CONST UCHAR * Address)517 Ipv4AddressScope(
518   _In_ CONST UCHAR *Address)
519 {
520   CONST IN_ADDR Ipv4Address = *(CONST IN_ADDR UNALIGNED *)Address;
521 
522   if (IN4_IS_ADDR_BROADCAST(&Ipv4Address)) {
523     return ScopeLevelLink;
524   } else if (IN4_IS_ADDR_MULTICAST(&Ipv4Address)) {
525     return Ipv4MulticastAddressScope((UCHAR *) &Ipv4Address);
526   } else {
527     return Ipv4UnicastAddressScope((UCHAR *) &Ipv4Address);
528   }
529 }
530 
531 MSTCPIP_INLINE
532 NL_ADDRESS_TYPE
Ipv4AddressType(_In_ CONST UCHAR * Address)533 Ipv4AddressType(
534   _In_ CONST UCHAR *Address)
535 {
536   IN_ADDR Ipv4Address = *(CONST IN_ADDR UNALIGNED *) Address;
537 
538   if (IN4_IS_ADDR_MULTICAST(&Ipv4Address)) {
539     return NlatMulticast;
540   }
541   if (IN4_IS_ADDR_BROADCAST(&Ipv4Address)) {
542     return NlatBroadcast;
543   }
544   if (IN4_IS_ADDR_UNSPECIFIED(&Ipv4Address)) {
545     return NlatUnspecified;
546   }
547   if (((Ipv4Address.s_addr & 0x000000ff) == 0) ||
548     ((Ipv4Address.s_addr & 0x000000f0) == 240)) {
549     return NlatInvalid;
550   }
551   return NlatUnicast;
552 }
553 
554 MSTCPIP_INLINE
555 VOID
IN4_UNCANONICALIZE_SCOPE_ID(_In_ CONST IN_ADDR * Address,_Inout_ SCOPE_ID * ScopeId)556 IN4_UNCANONICALIZE_SCOPE_ID(
557   _In_ CONST IN_ADDR *Address,
558   _Inout_ SCOPE_ID *ScopeId)
559 {
560   SCOPE_LEVEL ScopeLevel = Ipv4AddressScope((CONST UCHAR *)Address);
561 
562   if ((IN4_IS_ADDR_LOOPBACK(Address)) || (ScopeLevel == ScopeLevelGlobal)) {
563     ScopeId->Value = 0;
564   }
565   if ((SCOPE_LEVEL)ScopeId->Level == ScopeLevel) {
566     ScopeId->Level = 0;
567   }
568 }
569 
570 MSTCPIP_INLINE
571 BOOLEAN
IN4_IS_ADDR_6TO4ELIGIBLE(_In_ CONST IN_ADDR * a)572 IN4_IS_ADDR_6TO4ELIGIBLE(
573   _In_ CONST IN_ADDR *a)
574 {
575   return (BOOLEAN)((Ipv4AddressType((CONST UCHAR *) a) == NlatUnicast) &&
576                    !(IN4_IS_ADDR_LOOPBACK(a) ||
577                      IN4_IS_ADDR_LINKLOCAL(a) ||
578                      IN4_IS_ADDR_SITELOCAL(a) ||
579                      IN4_IS_ADDR_RFC1918(a)));
580 }
581 
582 MSTCPIP_INLINE
583 BOOLEAN
IN4_IS_UNALIGNED_ADDR_6TO4ELIGIBLE(_In_ CONST IN_ADDR UNALIGNED * a)584 IN4_IS_UNALIGNED_ADDR_6TO4ELIGIBLE(
585   _In_ CONST IN_ADDR UNALIGNED *a)
586 {
587   IN_ADDR Ipv4Address = *a;
588   return IN4_IS_ADDR_6TO4ELIGIBLE(&Ipv4Address);
589 }
590 
591 #endif /* (NTDDI_VERSION >= NTDDI_WIN2KSP1) */
592 
593 #endif /* _WS2DEF_ */
594 
595 #ifdef _WS2IPDEF_
596 
597 MSTCPIP_INLINE
598 BOOLEAN
IN6_PREFIX_EQUAL(_In_ CONST IN6_ADDR * a,_In_ CONST IN6_ADDR * b,_In_ UINT8 len)599 IN6_PREFIX_EQUAL(
600   _In_ CONST IN6_ADDR *a,
601   _In_ CONST IN6_ADDR *b,
602   _In_ UINT8 len)
603 {
604   UINT8 Bytes = len / 8;
605   UINT8 Bits = len % 8;
606   UINT8 Mask = 0xff << (8 - Bits);
607 
608   ASSERT(len <= (sizeof(IN6_ADDR) * 8));
609   return (BOOLEAN) (((memcmp(a, b, Bytes)) == 0) && ((Bits == 0) ||
610                     ((a->s6_bytes[Bytes] | Mask) == (b->s6_bytes[Bytes] | Mask))));
611 }
612 
613 MSTCPIP_INLINE
614 BOOLEAN
IN6_IS_ADDR_ALLNODESONNODE(_In_ CONST IN6_ADDR * a)615 IN6_IS_ADDR_ALLNODESONNODE(
616   _In_ CONST IN6_ADDR *a)
617 {
618   return IN6_ADDR_EQUAL(a, &in6addr_allnodesonnode);
619 }
620 
621 MSTCPIP_INLINE
622 BOOLEAN
IN6_IS_ADDR_ALLNODESONLINK(_In_ CONST IN6_ADDR * a)623 IN6_IS_ADDR_ALLNODESONLINK(
624   _In_ CONST IN6_ADDR *a)
625 {
626   return IN6_ADDR_EQUAL(a, &in6addr_allnodesonlink);
627 }
628 
629 MSTCPIP_INLINE
630 BOOLEAN
IN6_IS_ADDR_ALLROUTERSONLINK(_In_ CONST IN6_ADDR * a)631 IN6_IS_ADDR_ALLROUTERSONLINK(
632   _In_ CONST IN6_ADDR *a)
633 {
634   return IN6_ADDR_EQUAL(a, &in6addr_allroutersonlink);
635 }
636 
637 MSTCPIP_INLINE
638 BOOLEAN
IN6_IS_ADDR_SOLICITEDNODE(_In_ CONST IN6_ADDR * a)639 IN6_IS_ADDR_SOLICITEDNODE(
640   _In_ CONST IN6_ADDR *a)
641 {
642   return IN6_PREFIX_EQUAL(a, &in6addr_solicitednodemulticastprefix,
643                           IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_LENGTH);
644 }
645 
646 MSTCPIP_INLINE
647 BOOLEAN
IN6_IS_ADDR_ISATAP(_In_ CONST IN6_ADDR * a)648 IN6_IS_ADDR_ISATAP(
649   _In_ CONST IN6_ADDR *a)
650 {
651   return (BOOLEAN)(((a->s6_words[4] & 0xfffd) == 0x0000) &&
652                    (a->s6_words[5] == 0xfe5e));
653 }
654 
655 MSTCPIP_INLINE
656 BOOLEAN
IN6_IS_ADDR_6TO4(_In_ CONST IN6_ADDR * a)657 IN6_IS_ADDR_6TO4(
658   _In_ CONST IN6_ADDR *a)
659 {
660   C_ASSERT(IN6ADDR_6TO4PREFIX_LENGTH == RTL_BITS_OF(USHORT));
661   return (BOOLEAN)(a->s6_words[0] == in6addr_6to4prefix.s6_words[0]);
662 }
663 
664 MSTCPIP_INLINE
665 BOOLEAN
IN6_IS_ADDR_TEREDO(_In_ CONST IN6_ADDR * a)666 IN6_IS_ADDR_TEREDO(
667   _In_ CONST IN6_ADDR *a)
668 {
669   C_ASSERT(IN6ADDR_TEREDOPREFIX_LENGTH == 2 * RTL_BITS_OF(USHORT));
670   return (BOOLEAN)
671       (((a->s6_words[0] == in6addr_teredoprefix.s6_words[0]) &&
672         (a->s6_words[1] == in6addr_teredoprefix.s6_words[1])) ||
673        ((a->s6_words[0] == in6addr_teredoprefix_old.s6_words[0]) &&
674         (a->s6_words[1] == in6addr_teredoprefix_old.s6_words[1])));
675 }
676 
677 MSTCPIP_INLINE
678 BOOLEAN
IN6ADDR_ISV4MAPPED(_In_ CONST SOCKADDR_IN6 * a)679 IN6ADDR_ISV4MAPPED(
680   _In_ CONST SOCKADDR_IN6 *a)
681 {
682   ASSERT(a->sin6_family == AF_INET6);
683   return IN6_IS_ADDR_V4MAPPED(&a->sin6_addr);
684 }
685 
686 MSTCPIP_INLINE
687 BOOLEAN
IN6ADDR_ISISATAP(_In_ CONST SOCKADDR_IN6 * a)688 IN6ADDR_ISISATAP(
689   _In_ CONST SOCKADDR_IN6 *a)
690 {
691   ASSERT(a->sin6_family == AF_INET6);
692   return IN6_IS_ADDR_ISATAP(&a->sin6_addr);
693 }
694 
695 MSTCPIP_INLINE
696 BOOLEAN
IN6ADDR_IS6TO4(_In_ CONST SOCKADDR_IN6 * a)697 IN6ADDR_IS6TO4(
698   _In_ CONST SOCKADDR_IN6 *a)
699 {
700   ASSERT(a->sin6_family == AF_INET6);
701   return IN6_IS_ADDR_6TO4(&a->sin6_addr);
702 }
703 
704 MSTCPIP_INLINE
705 BOOLEAN
IN6ADDR_ISTEREDO(_In_ CONST SOCKADDR_IN6 * a)706 IN6ADDR_ISTEREDO(
707   _In_ CONST SOCKADDR_IN6 *a)
708 {
709   ASSERT(a->sin6_family == AF_INET6);
710   return IN6_IS_ADDR_TEREDO(&a->sin6_addr);
711 }
712 
713 MSTCPIP_INLINE
714 CONST UCHAR*
IN6_GET_ADDR_V4MAPPED(_In_ CONST IN6_ADDR * Ipv6Address)715 IN6_GET_ADDR_V4MAPPED(
716   _In_ CONST IN6_ADDR *Ipv6Address)
717 {
718   return (CONST UCHAR *) (Ipv6Address->s6_words + 6);
719 }
720 
721 MSTCPIP_INLINE
722 CONST UCHAR*
IN6_GET_ADDR_V4COMPAT(_In_ CONST IN6_ADDR * Ipv6Address)723 IN6_GET_ADDR_V4COMPAT(
724   _In_ CONST IN6_ADDR *Ipv6Address)
725 {
726   return (CONST UCHAR *) (Ipv6Address->s6_words + 6);
727 }
728 
729 MSTCPIP_INLINE
730 CONST UCHAR*
IN6_EXTRACT_V4ADDR_FROM_ISATAP(_In_ CONST IN6_ADDR * Ipv6Address)731 IN6_EXTRACT_V4ADDR_FROM_ISATAP(
732   _In_ CONST IN6_ADDR *Ipv6Address)
733 {
734   return (CONST UCHAR *) (Ipv6Address->s6_words + 6);
735 }
736 
737 MSTCPIP_INLINE
738 CONST UCHAR*
IN6_EXTRACT_V4ADDR_FROM_6TO4(_In_ CONST IN6_ADDR * Ipv6Address)739 IN6_EXTRACT_V4ADDR_FROM_6TO4(
740   _In_ CONST IN6_ADDR *Ipv6Address)
741 {
742   return (CONST UCHAR *) (Ipv6Address->s6_words + 1);
743 }
744 
745 MSTCPIP_INLINE
746 VOID
IN6_SET_ADDR_V4MAPPED(_Out_ PIN6_ADDR a6,_In_ CONST IN_ADDR * a4)747 IN6_SET_ADDR_V4MAPPED(
748   _Out_ PIN6_ADDR a6,
749   _In_ CONST IN_ADDR* a4)
750 {
751   *a6 = in6addr_v4mappedprefix;
752   a6->s6_bytes[12] = ((CONST UCHAR *) a4)[0];
753   a6->s6_bytes[13] = ((CONST UCHAR *) a4)[1];
754   a6->s6_bytes[14] = ((CONST UCHAR *) a4)[2];
755   a6->s6_bytes[15] = ((CONST UCHAR *) a4)[3];
756 }
757 
758 MSTCPIP_INLINE
759 VOID
IN6_SET_ADDR_V4COMPAT(_Out_ PIN6_ADDR a6,_In_ CONST IN_ADDR * a4)760 IN6_SET_ADDR_V4COMPAT(
761   _Out_ PIN6_ADDR a6,
762   _In_ CONST IN_ADDR* a4)
763 {
764   *a6 = in6addr_any;
765   a6->s6_bytes[12] = ((CONST UCHAR *) a4)[0];
766   a6->s6_bytes[13] = ((CONST UCHAR *) a4)[1];
767   a6->s6_bytes[14] = ((CONST UCHAR *) a4)[2];
768   a6->s6_bytes[15] = ((CONST UCHAR *) a4)[3];
769 }
770 
771 MSTCPIP_INLINE
772 VOID
IN6_SET_ADDR_SOLICITEDNODE(_Out_ PIN6_ADDR Multicast,_In_ CONST IN6_ADDR * Unicast)773 IN6_SET_ADDR_SOLICITEDNODE(
774   _Out_ PIN6_ADDR Multicast,
775   _In_ CONST IN6_ADDR *Unicast)
776 {
777   *Multicast = in6addr_solicitednodemulticastprefix;
778   Multicast->s6_bytes[13] = Unicast->s6_bytes[13];
779   Multicast->s6_bytes[14] = Unicast->s6_bytes[14];
780   Multicast->s6_bytes[15] = Unicast->s6_bytes[15];
781 }
782 
783 MSTCPIP_INLINE
784 VOID
IN6_SET_ISATAP_IDENTIFIER(_Inout_ IN6_ADDR * Ipv6Address,_In_ CONST IN_ADDR * Ipv4Address)785 IN6_SET_ISATAP_IDENTIFIER(
786   _Inout_ IN6_ADDR *Ipv6Address,
787   _In_ CONST IN_ADDR *Ipv4Address)
788 {
789   if (IN4_IS_ADDR_6TO4ELIGIBLE(Ipv4Address)) {
790     Ipv6Address->s6_words[4] = 0x0002;
791   } else {
792     Ipv6Address->s6_words[4] = 0x0000;
793   }
794   Ipv6Address->s6_words[5] = 0xFE5E;
795   *((UNALIGNED IN_ADDR *) (Ipv6Address->s6_words + 6)) = *Ipv4Address;
796 }
797 
798 MSTCPIP_INLINE
799 VOID
IN6_SET_6TO4_PREFIX(_Inout_ IN6_ADDR * Ipv6Address,_In_ CONST IN_ADDR * Ipv4Address)800 IN6_SET_6TO4_PREFIX(
801   _Inout_ IN6_ADDR *Ipv6Address,
802   _In_ CONST IN_ADDR *Ipv4Address)
803 {
804   Ipv6Address->s6_words[0] = 0x0220;
805   *((UNALIGNED IN_ADDR *) (Ipv6Address->s6_words + 1)) = *Ipv4Address;
806   Ipv6Address->s6_words[3] = 0x0000;
807 }
808 
809 MSTCPIP_INLINE
810 SCOPE_LEVEL
Ipv6UnicastAddressScope(_In_ CONST UCHAR * Address)811 Ipv6UnicastAddressScope(
812   _In_ CONST UCHAR *Address)
813 {
814   IN6_ADDR Ipv6Address;
815 
816   if (!INET_IS_ALIGNED(Address, IN6_ADDR)) {
817     Ipv6Address = *(CONST IN6_ADDR UNALIGNED *)Address;
818     Address = (CONST UCHAR *) &Ipv6Address;
819   }
820   if (IN6_IS_ADDR_LINKLOCAL((PIN6_ADDR) Address) ||
821     IN6_IS_ADDR_LOOPBACK((PIN6_ADDR) Address)) {
822     return ScopeLevelLink;
823   } else if (IN6_IS_ADDR_SITELOCAL((PIN6_ADDR) Address)) {
824     return ScopeLevelSite;
825   } else {
826     return ScopeLevelGlobal;
827   }
828 }
829 
830 MSTCPIP_INLINE
831 SCOPE_LEVEL
IN6_MULTICAST_SCOPE(_In_ CONST UCHAR * Address)832 IN6_MULTICAST_SCOPE(
833   _In_ CONST UCHAR *Address)
834 {
835   PIN6_ADDR Ipv6Address = (PIN6_ADDR) Address;
836   return (SCOPE_LEVEL)(Ipv6Address->s6_bytes[1] & 0xf);
837 }
838 
839 MSTCPIP_INLINE
840 SCOPE_LEVEL
Ipv6AddressScope(_In_ CONST UCHAR * Address)841 Ipv6AddressScope(
842   _In_ CONST UCHAR *Address)
843 {
844   if (IN6_IS_ADDR_MULTICAST((CONST IN6_ADDR *) Address)) {
845     return IN6_MULTICAST_SCOPE(Address);
846   } else {
847     return Ipv6UnicastAddressScope(Address);
848   }
849 }
850 
851 MSTCPIP_INLINE
852 NL_ADDRESS_TYPE
Ipv6AddressType(_In_ CONST UCHAR * Address)853 Ipv6AddressType(
854   _In_ CONST UCHAR *Address)
855 {
856   CONST IN6_ADDR *Ipv6Address = (CONST IN6_ADDR *) Address;
857   CONST UCHAR *Ipv4Address;
858 
859   if (IN6_IS_ADDR_MULTICAST(Ipv6Address)) {
860     return NlatMulticast;
861   }
862   if (IN6_IS_ADDR_UNSPECIFIED(Ipv6Address)) {
863     return NlatUnspecified;
864   }
865   if (IN6_IS_ADDR_ISATAP(Ipv6Address) || IN6_IS_ADDR_V4COMPAT(Ipv6Address) ||
866       IN6_IS_ADDR_V4MAPPED(Ipv6Address) || IN6_IS_ADDR_V4TRANSLATED(Ipv6Address)) {
867     Ipv4Address = IN6_EXTRACT_V4ADDR_FROM_ISATAP(Ipv6Address);
868   } else if (IN6_IS_ADDR_6TO4(Ipv6Address)) {
869   Ipv4Address = IN6_EXTRACT_V4ADDR_FROM_6TO4(Ipv6Address);
870   } else {
871     return NlatUnicast;
872   }
873   if (Ipv4AddressType(Ipv4Address) != NlatUnicast) {
874     return NlatInvalid;
875   }
876   return NlatUnicast;
877 }
878 
879 MSTCPIP_INLINE
880 VOID
IN6_UNCANONICALIZE_SCOPE_ID(_In_ CONST IN6_ADDR * Address,_Inout_ SCOPE_ID * ScopeId)881 IN6_UNCANONICALIZE_SCOPE_ID(
882   _In_ CONST IN6_ADDR *Address,
883   _Inout_ SCOPE_ID *ScopeId)
884 {
885   SCOPE_LEVEL ScopeLevel = Ipv6AddressScope((CONST UCHAR *)Address);
886 
887   if ((IN6_IS_ADDR_LOOPBACK(Address)) || (ScopeLevel == ScopeLevelGlobal)) {
888       ScopeId->Value = 0;
889   }
890   if ((SCOPE_LEVEL)ScopeId->Level == ScopeLevel) {
891     ScopeId->Level = 0;
892   }
893 }
894 
895 #if (NTDDI_VERSION >= NTDDI_VISTA)
896 
897 MSTCPIP_INLINE
898 VOID
IN6ADDR_SETSOCKADDR(_Out_ PSOCKADDR_IN6 a,_In_ CONST IN6_ADDR * addr,_In_ SCOPE_ID scope,_In_ USHORT port)899 IN6ADDR_SETSOCKADDR(
900   _Out_ PSOCKADDR_IN6 a,
901   _In_ CONST IN6_ADDR *addr,
902   _In_ SCOPE_ID scope,
903   _In_ USHORT port)
904 {
905   a->sin6_family = AF_INET6;
906   a->sin6_port = port;
907   a->sin6_flowinfo = 0;
908   RtlCopyMemory(&a->sin6_addr, addr, sizeof(IN6_ADDR));
909   a->sin6_scope_struct = scope;
910   IN6_UNCANONICALIZE_SCOPE_ID(&a->sin6_addr, &a->sin6_scope_struct);
911 }
912 
913 MSTCPIP_INLINE
914 VOID
IN6ADDR_SETV4MAPPED(_Out_ PSOCKADDR_IN6 a6,_In_ CONST IN_ADDR * a4,_In_ SCOPE_ID scope,_In_ USHORT port)915 IN6ADDR_SETV4MAPPED(
916   _Out_ PSOCKADDR_IN6 a6,
917   _In_ CONST IN_ADDR* a4,
918   _In_ SCOPE_ID scope,
919   _In_ USHORT port)
920 {
921   a6->sin6_family = AF_INET6;
922   a6->sin6_port = port;
923   a6->sin6_flowinfo = 0;
924   IN6_SET_ADDR_V4MAPPED(&a6->sin6_addr, a4);
925   a6->sin6_scope_struct = scope;
926   IN4_UNCANONICALIZE_SCOPE_ID(a4, &a6->sin6_scope_struct);
927 }
928 
929 #endif /* (NTDDI_VERSION >= NTDDI_VISTA) */
930 
931 MSTCPIP_INLINE
932 BOOLEAN
INET_ADDR_EQUAL(_In_ ADDRESS_FAMILY af,_In_ CONST VOID * a,_In_ CONST VOID * b)933 INET_ADDR_EQUAL(
934   _In_ ADDRESS_FAMILY af,
935   _In_ CONST VOID* a,
936   _In_ CONST VOID* b)
937 {
938   if (af == AF_INET6) {
939     return IN6_ADDR_EQUAL((CONST IN6_ADDR*)a, (CONST IN6_ADDR*)b);
940   } else {
941     ASSERT(af == AF_INET);
942     return IN4_ADDR_EQUAL((CONST IN_ADDR*)a, (CONST IN_ADDR*)b);
943   }
944 }
945 
946 MSTCPIP_INLINE
947 BOOLEAN
INET_UNALIGNED_ADDR_EQUAL(_In_ ADDRESS_FAMILY af,_In_ CONST VOID * a,_In_ CONST VOID * b)948 INET_UNALIGNED_ADDR_EQUAL(
949   _In_ ADDRESS_FAMILY af,
950   _In_ CONST VOID* a,
951   _In_ CONST VOID* b)
952 {
953   if (af == AF_INET6) {
954     return IN6_ADDR_EQUAL((CONST IN6_ADDR*)a, (CONST IN6_ADDR*)b);
955   } else {
956     ASSERT(af == AF_INET);
957     return IN4_UNALIGNED_ADDR_EQUAL((CONST IN_ADDR*)a, (CONST IN_ADDR*)b);
958   }
959 }
960 
961 MSTCPIP_INLINE
962 BOOLEAN
INET_IS_ADDR_UNSPECIFIED(_In_ ADDRESS_FAMILY af,_In_ CONST VOID * a)963 INET_IS_ADDR_UNSPECIFIED(
964   _In_ ADDRESS_FAMILY af,
965   _In_ CONST VOID* a)
966 {
967   if (af == AF_INET6) {
968     return IN6_IS_ADDR_UNSPECIFIED((CONST IN6_ADDR*)a);
969   } else {
970     ASSERT(af == AF_INET);
971     return IN4_IS_ADDR_UNSPECIFIED((CONST IN_ADDR*)a);
972   }
973 }
974 
975 MSTCPIP_INLINE
976 BOOLEAN
INET_IS_UNALIGNED_ADDR_UNSPECIFIED(_In_ ADDRESS_FAMILY af,_In_ CONST VOID * a)977 INET_IS_UNALIGNED_ADDR_UNSPECIFIED(
978   _In_ ADDRESS_FAMILY af,
979   _In_ CONST VOID* a)
980 {
981   if (af == AF_INET6) {
982     return IN6_IS_ADDR_UNSPECIFIED((CONST IN6_ADDR*)a);
983   } else {
984     ASSERT(af == AF_INET);
985     return IN4_IS_UNALIGNED_ADDR_UNSPECIFIED((CONST IN_ADDR UNALIGNED*)a);
986   }
987 }
988 
989 MSTCPIP_INLINE
990 BOOLEAN
INET_IS_ADDR_LOOPBACK(_In_ ADDRESS_FAMILY af,_In_ CONST VOID * a)991 INET_IS_ADDR_LOOPBACK(
992   _In_ ADDRESS_FAMILY af,
993   _In_ CONST VOID* a)
994 {
995   if (af == AF_INET6) {
996     return IN6_IS_ADDR_LOOPBACK((CONST IN6_ADDR*)a);
997   } else {
998     ASSERT(af == AF_INET);
999     return IN4_IS_ADDR_LOOPBACK((CONST IN_ADDR*)a);
1000   }
1001 }
1002 
1003 MSTCPIP_INLINE
1004 BOOLEAN
INET_IS_ADDR_BROADCAST(_In_ ADDRESS_FAMILY af,_In_ CONST VOID * a)1005 INET_IS_ADDR_BROADCAST(
1006   _In_ ADDRESS_FAMILY af,
1007   _In_ CONST VOID* a)
1008 {
1009   if (af == AF_INET6) {
1010     return FALSE;
1011   } else {
1012     ASSERT(af == AF_INET);
1013     return IN4_IS_ADDR_BROADCAST((CONST IN_ADDR*)a);
1014   }
1015 }
1016 
1017 MSTCPIP_INLINE
1018 BOOLEAN
INET_IS_ADDR_MULTICAST(_In_ ADDRESS_FAMILY af,_In_ CONST VOID * a)1019 INET_IS_ADDR_MULTICAST(
1020   _In_ ADDRESS_FAMILY af,
1021   _In_ CONST VOID* a)
1022 {
1023   if (af == AF_INET6) {
1024     return IN6_IS_ADDR_MULTICAST((CONST IN6_ADDR*)a);
1025   } else {
1026     ASSERT(af == AF_INET);
1027     return IN4_IS_ADDR_MULTICAST((CONST IN_ADDR*)a);
1028   }
1029 }
1030 
1031 MSTCPIP_INLINE
1032 CONST UCHAR*
INET_ADDR_UNSPECIFIED(_In_ ADDRESS_FAMILY af)1033 INET_ADDR_UNSPECIFIED(
1034   _In_ ADDRESS_FAMILY af)
1035 {
1036   if (af == AF_INET6) {
1037     return (CONST UCHAR*)&in6addr_any;
1038   } else {
1039     ASSERT(af == AF_INET);
1040     return (CONST UCHAR*)&in4addr_any;
1041   }
1042 }
1043 
1044 MSTCPIP_INLINE
1045 VOID
INET_SET_ADDRESS(_In_ ADDRESS_FAMILY Family,_Out_ PUCHAR Address,_In_ CONST UCHAR * Value)1046 INET_SET_ADDRESS(
1047   _In_ ADDRESS_FAMILY Family,
1048   _Out_ PUCHAR Address,
1049   _In_ CONST UCHAR *Value)
1050 {
1051   if (Family == AF_INET6) {
1052     *((PIN6_ADDR)Address) = *((PIN6_ADDR)Value);
1053   } else {
1054     ASSERT(Family == AF_INET);
1055     *((PIN_ADDR)Address) = *((PIN_ADDR)Value);
1056   }
1057 }
1058 
1059 MSTCPIP_INLINE
1060 SIZE_T
INET_ADDR_LENGTH(_In_ ADDRESS_FAMILY af)1061 INET_ADDR_LENGTH(
1062   _In_ ADDRESS_FAMILY af)
1063 {
1064   if (af == AF_INET6) {
1065     return sizeof(IN6_ADDR);
1066   } else {
1067     ASSERT(af == AF_INET);
1068     return sizeof(IN_ADDR);
1069   }
1070 }
1071 
1072 MSTCPIP_INLINE
1073 SIZE_T
INET_SOCKADDR_LENGTH(_In_ ADDRESS_FAMILY af)1074 INET_SOCKADDR_LENGTH(
1075   _In_ ADDRESS_FAMILY af)
1076 {
1077   if (af == AF_INET6) {
1078     return sizeof(SOCKADDR_IN6);
1079   } else {
1080     ASSERT(af == AF_INET);
1081     return sizeof(SOCKADDR_IN);
1082   }
1083 }
1084 
1085 #if (NTDDI_VERSION >= NTDDI_VISTA)
1086 MSTCPIP_INLINE
1087 VOID
INETADDR_SETSOCKADDR(_In_ ADDRESS_FAMILY af,_Out_ PSOCKADDR a,_In_ CONST VOID * addr,_In_ SCOPE_ID scope,_In_ USHORT port)1088 INETADDR_SETSOCKADDR(
1089   _In_ ADDRESS_FAMILY af,
1090   _Out_ PSOCKADDR a,
1091   _In_ CONST VOID* addr,
1092   _In_ SCOPE_ID scope,
1093   _In_ USHORT port)
1094 {
1095   if (af == AF_INET6) {
1096     IN6ADDR_SETSOCKADDR((PSOCKADDR_IN6) a, (CONST IN6_ADDR *) addr, scope, port);
1097   } else {
1098     CONST IN_ADDR addr4 = *((IN_ADDR UNALIGNED *) addr);
1099     ASSERT(af == AF_INET);
1100     IN4ADDR_SETSOCKADDR((PSOCKADDR_IN) a, (CONST IN_ADDR *) &addr4, port);
1101   }
1102 }
1103 #endif /* (NTDDI_VERSION >= NTDDI_VISTA) */
1104 
1105 MSTCPIP_INLINE
1106 VOID
INETADDR_SETANY(_Inout_ PSOCKADDR a)1107 INETADDR_SETANY(
1108   _Inout_ PSOCKADDR a)
1109 {
1110   if (a->sa_family == AF_INET6) {
1111     IN6ADDR_SETANY((PSOCKADDR_IN6)a);
1112   } else {
1113     ASSERT(a->sa_family == AF_INET);
1114     IN4ADDR_SETANY((PSOCKADDR_IN)a);
1115   }
1116 }
1117 
1118 MSTCPIP_INLINE
1119 VOID
INETADDR_SETLOOPBACK(_Inout_ PSOCKADDR a)1120 INETADDR_SETLOOPBACK(
1121   _Inout_ PSOCKADDR a)
1122 {
1123   if (a->sa_family == AF_INET6) {
1124     IN6ADDR_SETLOOPBACK((PSOCKADDR_IN6)a);
1125   } else {
1126     ASSERT(a->sa_family == AF_INET);
1127     IN4ADDR_SETLOOPBACK((PSOCKADDR_IN)a);
1128   }
1129 }
1130 
1131 MSTCPIP_INLINE
1132 BOOLEAN
INETADDR_ISANY(_In_ CONST SOCKADDR * a)1133 INETADDR_ISANY(
1134   _In_ CONST SOCKADDR *a)
1135 {
1136   if (a->sa_family == AF_INET6) {
1137     return IN6ADDR_ISANY((CONST SOCKADDR_IN6*)a);
1138   } else {
1139     ASSERT(a->sa_family == AF_INET);
1140     return IN4ADDR_ISANY((CONST SOCKADDR_IN*)a);
1141   }
1142 }
1143 
1144 MSTCPIP_INLINE
1145 BOOLEAN
INETADDR_ISLOOPBACK(_In_ CONST SOCKADDR * a)1146 INETADDR_ISLOOPBACK(
1147   _In_ CONST SOCKADDR *a)
1148 {
1149   if (a->sa_family == AF_INET6) {
1150     return IN6ADDR_ISLOOPBACK((CONST SOCKADDR_IN6*)a);
1151   } else {
1152     ASSERT(a->sa_family == AF_INET);
1153     return IN4ADDR_ISLOOPBACK((CONST SOCKADDR_IN*)a);
1154   }
1155 }
1156 
1157 MSTCPIP_INLINE
1158 BOOLEAN
INETADDR_ISV4MAPPED(_In_ CONST SOCKADDR * a)1159 INETADDR_ISV4MAPPED(
1160   _In_ CONST SOCKADDR *a)
1161 {
1162   if (a->sa_family == AF_INET6) {
1163     return IN6ADDR_ISV4MAPPED((CONST SOCKADDR_IN6*)a);
1164   } else {
1165     return FALSE;
1166   }
1167 }
1168 
1169 MSTCPIP_INLINE
1170 BOOLEAN
NL_ADDR_EQUAL(_In_ ADDRESS_FAMILY af,_In_ SCOPE_ID sa,_In_ CONST UCHAR * aa,_In_ SCOPE_ID sb,_In_ CONST UCHAR * ab)1171 NL_ADDR_EQUAL(
1172   _In_ ADDRESS_FAMILY af,
1173   _In_ SCOPE_ID sa,
1174   _In_ CONST UCHAR* aa,
1175   _In_ SCOPE_ID sb,
1176   _In_ CONST UCHAR* ab)
1177 {
1178   return (BOOLEAN)((sa.Value == sb.Value) && INET_ADDR_EQUAL(af, aa, ab));
1179 }
1180 
1181 MSTCPIP_INLINE
1182 BOOLEAN
NL_IS_ADDR_UNSPECIFIED(_In_ ADDRESS_FAMILY af,_In_ SCOPE_ID s,_In_ CONST UCHAR * a)1183 NL_IS_ADDR_UNSPECIFIED(
1184   _In_ ADDRESS_FAMILY af,
1185   _In_ SCOPE_ID s,
1186   _In_ CONST UCHAR* a)
1187 {
1188   return (BOOLEAN)((s.Value == 0) && INET_IS_ADDR_UNSPECIFIED(af, a));
1189 }
1190 
1191 MSTCPIP_INLINE
1192 BOOLEAN
INETADDR_ISEQUAL(_In_ CONST SOCKADDR * a,_In_ CONST SOCKADDR * b)1193 INETADDR_ISEQUAL(
1194   _In_ CONST SOCKADDR *a,
1195   _In_ CONST SOCKADDR *b)
1196 {
1197   if (a->sa_family == AF_INET6) {
1198     return (BOOLEAN) (b->sa_family == AF_INET6 &&
1199            IN6ADDR_ISEQUAL((CONST SOCKADDR_IN6*)a, (CONST SOCKADDR_IN6*)b));
1200   } else {
1201     ASSERT(a->sa_family == AF_INET);
1202     return (BOOLEAN) (b->sa_family == AF_INET &&
1203            IN4ADDR_ISEQUAL((CONST SOCKADDR_IN*)a, (CONST SOCKADDR_IN*)b));
1204   }
1205 }
1206 
1207 MSTCPIP_INLINE
1208 BOOLEAN
INETADDR_ISUNSPECIFIED(_In_ CONST SOCKADDR * a)1209 INETADDR_ISUNSPECIFIED(
1210   _In_ CONST SOCKADDR *a)
1211 {
1212   if (a->sa_family == AF_INET6) {
1213     return IN6ADDR_ISUNSPECIFIED((CONST SOCKADDR_IN6*)a);
1214   } else {
1215     ASSERT(a->sa_family == AF_INET);
1216     return IN4ADDR_ISUNSPECIFIED((CONST SOCKADDR_IN*)a);
1217   }
1218 }
1219 
1220 #if (NTDDI_VERSION >= NTDDI_VISTA)
1221 MSTCPIP_INLINE
1222 SCOPE_ID
INETADDR_SCOPE_ID(_In_ CONST SOCKADDR * a)1223 INETADDR_SCOPE_ID(
1224   _In_ CONST SOCKADDR *a)
1225 {
1226   if (a->sa_family == AF_INET6) {
1227     return ((CONST SOCKADDR_IN6*)a)->sin6_scope_struct;
1228   } else {
1229     ASSERT(a->sa_family == AF_INET);
1230     return IN4ADDR_SCOPE_ID((CONST SOCKADDR_IN*)a);
1231   }
1232 }
1233 #endif
1234 
1235 MSTCPIP_INLINE
1236 USHORT
INETADDR_PORT(_In_ CONST SOCKADDR * a)1237 INETADDR_PORT(
1238   _In_ CONST SOCKADDR *a)
1239 {
1240   if (a->sa_family == AF_INET6) {
1241     return ((CONST SOCKADDR_IN6*)a)->sin6_port;
1242   } else {
1243     ASSERT(a->sa_family == AF_INET);
1244     return ((CONST SOCKADDR_IN*)a)->sin_port;
1245   }
1246 }
1247 
1248 MSTCPIP_INLINE
1249 PUCHAR
INETADDR_ADDRESS(_In_ CONST SOCKADDR * a)1250 INETADDR_ADDRESS(
1251   _In_ CONST SOCKADDR* a)
1252 {
1253   if (a->sa_family == AF_INET6) {
1254     return (PUCHAR)&((PSOCKADDR_IN6)a)->sin6_addr;
1255   } else {
1256     ASSERT(a->sa_family == AF_INET);
1257     return (PUCHAR)&((PSOCKADDR_IN)a)->sin_addr;
1258   }
1259 }
1260 
1261 MSTCPIP_INLINE
1262 VOID
INETADDR_SET_PORT(_Inout_ PSOCKADDR a,_In_ USHORT Port)1263 INETADDR_SET_PORT(
1264   _Inout_ PSOCKADDR a,
1265   _In_ USHORT Port)
1266 {
1267   SS_PORT(a) = Port;
1268 }
1269 
1270 MSTCPIP_INLINE
1271 VOID
INETADDR_SET_ADDRESS(_Inout_ PSOCKADDR a,_In_ CONST UCHAR * Address)1272 INETADDR_SET_ADDRESS(
1273   _Inout_ PSOCKADDR a,
1274   _In_ CONST UCHAR *Address)
1275 {
1276   if (a->sa_family == AF_INET6) {
1277     ((PSOCKADDR_IN6)a)->sin6_addr = *((CONST IN6_ADDR*)Address);
1278   } else {
1279     ASSERT(a->sa_family == AF_INET);
1280     ((PSOCKADDR_IN)a)->sin_addr = *((CONST IN_ADDR*)Address);
1281   }
1282 }
1283 
1284 MSTCPIP_INLINE
1285 VOID
INET_UNCANONICALIZE_SCOPE_ID(_In_ ADDRESS_FAMILY AddressFamily,_In_ CONST UCHAR * Address,_Inout_ SCOPE_ID * ScopeId)1286 INET_UNCANONICALIZE_SCOPE_ID(
1287   _In_ ADDRESS_FAMILY AddressFamily,
1288   _In_ CONST UCHAR *Address,
1289   _Inout_ SCOPE_ID *ScopeId)
1290 {
1291   if (AddressFamily == AF_INET6) {
1292     IN6_UNCANONICALIZE_SCOPE_ID((CONST IN6_ADDR*) Address, ScopeId);
1293   } else {
1294     IN4_UNCANONICALIZE_SCOPE_ID((CONST IN_ADDR*) Address, ScopeId);
1295   }
1296 }
1297 
1298 #endif /* _WS2IPDEF_ */
1299 
1300 #ifndef __IP2STRING__
1301 #define __IP2STRING__
1302 
1303 #if (NTDDI_VERSION >= NTDDI_VISTA)
1304 
1305 #ifdef _WS2DEF_
1306 
1307 NTSYSAPI
1308 PSTR
1309 NTAPI
1310 RtlIpv4AddressToStringA(
1311   _In_ const struct in_addr *Addr,
1312   _Out_writes_(16) PSTR S);
1313 
1314 NTSYSAPI
1315 LONG
1316 NTAPI
1317 RtlIpv4AddressToStringExA(
1318   _In_ const struct in_addr *Address,
1319   _In_ USHORT Port,
1320   _Out_writes_to_(*AddressStringLength, *AddressStringLength) PSTR AddressString,
1321   _Inout_ PULONG AddressStringLength);
1322 
1323 NTSYSAPI
1324 PWSTR
1325 NTAPI
1326 RtlIpv4AddressToStringW(
1327   _In_ const struct in_addr *Addr,
1328   _Out_writes_(16) PWSTR S);
1329 
1330 NTSYSAPI
1331 LONG
1332 NTAPI
1333 RtlIpv4AddressToStringExW(
1334   _In_ const struct in_addr *Address,
1335   _In_ USHORT Port,
1336   _Out_writes_to_(*AddressStringLength, *AddressStringLength) PWSTR AddressString,
1337   _Inout_ PULONG AddressStringLength);
1338 
1339 NTSYSAPI
1340 LONG
1341 NTAPI
1342 RtlIpv4StringToAddressA(
1343   _In_ PCSTR String,
1344   _In_ BOOLEAN Strict,
1345   _Out_ PCSTR *Terminator,
1346   _Out_ struct in_addr *Addr);
1347 
1348 NTSYSAPI
1349 LONG
1350 NTAPI
1351 RtlIpv4StringToAddressExA(
1352   _In_ PCSTR AddressString,
1353   _In_ BOOLEAN Strict,
1354   _Out_ struct in_addr *Address,
1355   _Out_ PUSHORT Port);
1356 
1357 NTSYSAPI
1358 LONG
1359 NTAPI
1360 RtlIpv4StringToAddressW(
1361   _In_ PCWSTR String,
1362   _In_ BOOLEAN Strict,
1363   _Out_ PCWSTR *Terminator,
1364   _Out_ struct in_addr *Addr);
1365 
1366 NTSYSAPI
1367 LONG
1368 NTAPI
1369 RtlIpv4StringToAddressExW(
1370   _In_ PCWSTR AddressString,
1371   _In_ BOOLEAN Strict,
1372   _Out_ struct in_addr *Address,
1373   _Out_ PUSHORT Port);
1374 
1375 #ifdef UNICODE
1376 #define RtlIpv4AddressToString RtlIpv4AddressToStringW
1377 #define RtlIpv4StringToAddress RtlIpv4StringToAddressW
1378 #define RtlIpv4AddressToStringEx RtlIpv4AddressToStringExW
1379 #define RtlIpv4StringToAddressEx RtlIpv4StringToAddressExW
1380 #else
1381 #define RtlIpv4AddressToString RtlIpv4AddressToStringA
1382 #define RtlIpv4StringToAddress RtlIpv4StringToAddressA
1383 #define RtlIpv4AddressToStringEx RtlIpv4AddressToStringExA
1384 #define RtlIpv4StringToAddressEx RtlIpv4StringToAddressExA
1385 #endif
1386 
1387 #endif /* _WS2DEF_ */
1388 
1389 #ifdef _WS2IPDEF_
1390 
1391 NTSYSAPI
1392 PSTR
1393 NTAPI
1394 RtlIpv6AddressToStringA(
1395   _In_ const struct in6_addr *Addr,
1396   _Out_writes_(46) PSTR S);
1397 
1398 NTSYSAPI
1399 LONG
1400 NTAPI
1401 RtlIpv6AddressToStringExA(
1402   _In_ const struct in6_addr *Address,
1403   _In_ ULONG ScopeId,
1404   _In_ USHORT Port,
1405   _Out_writes_to_(*AddressStringLength, *AddressStringLength) PSTR AddressString,
1406   _Inout_ PULONG AddressStringLength);
1407 
1408 NTSYSAPI
1409 PWSTR
1410 NTAPI
1411 RtlIpv6AddressToStringW(
1412   _In_ const struct in6_addr *Addr,
1413   _Out_writes_(46) PWSTR S);
1414 
1415 NTSYSAPI
1416 LONG
1417 NTAPI
1418 RtlIpv6AddressToStringExW(
1419   _In_ const struct in6_addr *Address,
1420   _In_ ULONG ScopeId,
1421   _In_ USHORT Port,
1422   _Out_writes_to_(*AddressStringLength, *AddressStringLength) PWSTR AddressString,
1423   _Inout_ PULONG AddressStringLength);
1424 
1425 NTSYSAPI
1426 LONG
1427 NTAPI
1428 RtlIpv6StringToAddressA(
1429   _In_ PCSTR S,
1430   _Out_ PCSTR *Terminator,
1431   _Out_ struct in6_addr *Addr);
1432 
1433 NTSYSAPI
1434 LONG
1435 NTAPI
1436 RtlIpv6StringToAddressExA(
1437   _In_ PCSTR AddressString,
1438   _Out_ struct in6_addr *Address,
1439   _Out_ PULONG ScopeId,
1440   _Out_ PUSHORT Port);
1441 
1442 NTSYSAPI
1443 LONG
1444 NTAPI
1445 RtlIpv6StringToAddressW(
1446   _In_ PCWSTR S,
1447   _Out_ PCWSTR *Terminator,
1448   _Out_ struct in6_addr *Addr);
1449 
1450 NTSYSAPI
1451 LONG
1452 NTAPI
1453 RtlIpv6StringToAddressExW(
1454   _In_ PCWSTR AddressString,
1455   _Out_ struct in6_addr *Address,
1456   _Out_ PULONG ScopeId,
1457   _Out_ PUSHORT Port);
1458 
1459 #ifdef UNICODE
1460 #define RtlIpv6AddressToString RtlIpv6AddressToStringW
1461 #define RtlIpv6StringToAddress RtlIpv6StringToAddressW
1462 #define RtlIpv6StringToAddressEx RtlIpv6StringToAddressExW
1463 #define RtlIpv6AddressToStringEx RtlIpv6AddressToStringExW
1464 #else
1465 #define RtlIpv6AddressToString RtlIpv6AddressToStringA
1466 #define RtlIpv6StringToAddress RtlIpv6StringToAddressA
1467 #define RtlIpv6StringToAddressEx RtlIpv6StringToAddressExA
1468 #define RtlIpv6AddressToStringEx RtlIpv6AddressToStringExA
1469 #endif
1470 
1471 #endif /* __WS2IPDEF__ */
1472 
1473 #ifdef _WS2DEF_
1474 
1475 union _DL_EUI48;
1476 typedef union _DL_EUI48 DL_EUI48, *PDL_EUI48;
1477 
1478 NTSYSAPI
1479 PSTR
1480 NTAPI
1481 RtlEthernetAddressToStringA(
1482   _In_ const DL_EUI48 *Addr,
1483   _Out_writes_(18) PSTR S);
1484 
1485 NTSYSAPI
1486 PWSTR
1487 NTAPI
1488 RtlEthernetAddressToStringW(
1489   _In_ const DL_EUI48 *Addr,
1490   _Out_writes_(18) PWSTR S);
1491 
1492 NTSYSAPI
1493 LONG
1494 NTAPI
1495 RtlEthernetStringToAddressA(
1496   _In_ PCSTR S,
1497   _Out_ PCSTR *Terminator,
1498   _Out_ DL_EUI48 *Addr);
1499 
1500 NTSYSAPI
1501 LONG
1502 NTAPI
1503 RtlEthernetStringToAddressW(
1504   _In_ PCWSTR S,
1505   _Out_ LPCWSTR *Terminator,
1506   _Out_ DL_EUI48 *Addr);
1507 
1508 #ifdef UNICODE
1509 #define RtlEthernetAddressToString RtlEthernetAddressToStringW
1510 #define RtlEthernetStringToAddress RtlEthernetStringToAddressW
1511 #else
1512 #define RtlEthernetAddressToString RtlEthernetAddressToStringA
1513 #define RtlEthernetStringToAddress RtlEthernetStringToAddressA
1514 #endif
1515 
1516 #endif /* _WS2DEF_ */
1517 
1518 #endif /* (NTDDI >= NTDDI_VISTA) */
1519 
1520 #endif /* __IP2STRING__ */
1521 
1522 #ifdef __cplusplus
1523 }
1524 #endif
1525