' ########################################################################################
' Microsoft Windows
' File: ws2ipdef.inc
' Copyright (c) 2010 Jos? Roca
' Portions Copyright (c) Microsoft Corporation.
' All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################
#IF NOT %DEF(PBX_ws2ipdef_PBI)
#DEFINE PBX_ws2ipdef_PBI
%EQUATE `WS2IPDEF_INC = 1
'/*++
'Copyright (c) Microsoft Corporation. All rights reserved.
'Module Name:
' ws2ipdef.h
'Abstract:
' This file contains TCP/IP specific information for use
' by WinSock2 compatible applications.
' Copyright (c) Microsoft Corporation. All rights reserved.
' To provide the backward compatibility, all the TCP/IP
' specific definitions that were included in the WINSOCK.H
' file are now included in WINSOCK2.H file. WS2TCPIP.H
' file includes only the definitions introduced in the
' "WinSock 2 Protocol-Specific Annex" document.
' Rev 0.3 Nov 13, 1995
' Rev 0.4 Dec 15, 1996
'Environment:
' user mode or kernel mode
'--*/
' NOTE: WS2DEF.INC must be included first.
'#ifdef _PREFAST_
'#pragma prefast(push)
'#pragma prefast(disable: 24002, "This code requires explicit usage of IPv4 address types.")
'#endif
'#ifndef WS2IPDEF_ASSERT
'#define WS2IPDEF_ASSERT(exp) ((VOID) 0)
'#endif
#INCLUDE ONCE "Legacy/System/in6addr.inc"
#INCLUDE ONCE "Legacy/System/ws2def.inc"
'//
'// Old IPv6 socket address structure (retained for sockaddr_gen definition).
'//
' // Size = 24 bytes
TYPE sockaddr_in6_old BYTE
 sin6_family AS INTEGER ' SHORT // AF_INET6
 sin6_port AS WORD ' USHORT // Transport level port number
 sin6_flowinfo AS DWORD ' ULONG // IPv6 flow information
 sin6_addr AS IN6_ADDR ' IN6_ADDR // IPv6 address
END TYPE
' // Size = 24 bytes
UNION sockaddr_gen BYTE
 Address AS sockaddr
 AddressIn AS sockaddr_in
 AddressIn6 AS sockaddr_in6_old
END UNION
'//
'// Structure to keep interface specific information
'//
' // Size = 76 bytes
TYPE INTERFACE_INFO BYTE
 iiFlags AS DWORD ' /* Interface flags */
 iiAddress AS sockaddr_gen ' /* Interface address */
 iiBroadcastAddress AS sockaddr_gen ' /* Broadcast address */
 iiNetmask AS sockaddr_gen ' /* Network mask */
END TYPE
'//
'// New structure that does not have dependency on the address size.
'//
' // Size = 28 bytes
TYPE INTERFACE_INFO_EX BYTE
 iiFlags AS DWORD ' /* Interface flags */
 iiAddress AS SOCKET_ADDRESS ' /* Interface address */
 iiBroadcastAddress AS SOCKET_ADDRESS ' /* Broadcast address */
 iiNetmask AS SOCKET_ADDRESS ' /* Network mask */
END TYPE
'//
'// Possible flags for the iiFlags - bitmask.
'//
%EQUATE `IFF_UP = &H00000001 ' /* Interface is up */
%EQUATE `IFF_BROADCAST = &H00000002 ' /* Broadcast is supported */
%EQUATE `IFF_LOOPBACK = &H00000004 ' /* this is loopback interface */
%EQUATE `IFF_POINTTOPOINT = &H00000008 ' /*this is point-to-point interface*/
%EQUATE `IFF_MULTICAST = &H00000010 ' /* multicast is supported */
'//
'// Options to use with [gs]etsockopt at the IPPROTO_IP level.
'// The values should be consistent with the IPv6 equivalents.
'//
%EQUATE `IP_OPTIONS = 1 ' // set/get IP options
%EQUATE `IP_HDRINCL = 2 ' // header is included with data
%EQUATE `IP_TOS = 3 ' // IP type of service and preced
%EQUATE `IP_TTL = 4 ' // IP time to live
%EQUATE `IP_MULTICAST_IF = 9 ' // set/get IP multicast i/f
%EQUATE `IP_MULTICAST_TTL = 10 ' // set/get IP multicast ttl
%EQUATE `IP_MULTICAST_LOOP = 11 ' // set/get IP multicast loopback
%EQUATE `IP_ADD_MEMBERSHIP = 12 ' // add an IP group membership
%EQUATE `IP_DROP_MEMBERSHIP = 13 ' // drop an IP group membership
%EQUATE `IP_DONTFRAGMENT = 14 ' // don't fragment IP datagrams
%EQUATE `IP_ADD_SOURCE_MEMBERSHIP = 15 ' // join IP group/source
%EQUATE `IP_DROP_SOURCE_MEMBERSHIP = 16 ' // leave IP group/source
%EQUATE `IP_BLOCK_SOURCE = 17 ' // block IP group/source
%EQUATE `IP_UNBLOCK_SOURCE = 18 ' // unblock IP group/source
%EQUATE `IP_PKTINFO = 19 ' // receive packet information for ipv4
%EQUATE `IP_RECEIVE_BROADCAST = 22 ' // allow/block broadcast reception
%EQUATE `IP_RECVIF = 24 ' // Receive arrival interface
%EQUATE `IP_RECVDSTADDR = 25 ' // Receive destination address
%EQUATE `IP_IFLIST = 28 ' // Enable/Disable an interface list
%EQUATE `IP_ADD_IFLIST = 29 ' // Add an interface list entry
%EQUATE `IP_DEL_IFLIST = 30 ' // Delete an interface list entry
%EQUATE `IP_UNICAST_IF = 31 ' // IP unicast interface
%EQUATE `IP_RTHDR = 32 ' // Set/get IPv6 routing header
%EQUATE `IP_RECVRTHDR = 38 ' // Receive the routing header
%EQUATE `IP_TCLASS = 39 ' // Packet traffic class.
%EQUATE `IP_RECVTCLASS = 40 ' // Receive packet traffic class.
%EQUATE `IP_ORIGINAL_ARRIVAL_IF = 47 ' // Original Arrival Interface Index.
%EQUATE `IP_UNSPECIFIED_TYPE_OF_SERVICE = -1
'#define IPV6_ADDRESS_BITS RTL_BITS_OF(IN6_ADDR)
'//
'// IPv6 socket address structure, RFC 3493.
'//
'//
'// NB: The LH version of sockaddr_in6 has the struct tag sockaddr_in6 rather
'// than sockaddr_in6_lh. This is to make sure that standard sockets apps
'// that conform to RFC 2553 (Basic Socket Interface Extensions for IPv6).
'//
'typedef struct sockaddr_in6 {
' ADDRESS_FAMILY sin6_family; // AF_INET6.
' USHORT sin6_port; // Transport level port number.
' ULONG sin6_flowinfo; // IPv6 flow information.
' IN6_ADDR sin6_addr; // IPv6 address.
' union {
' ULONG sin6_scope_id; // Set of interfaces for a scope.
' SCOPE_ID sin6_scope_struct;
' };
'} SOCKADDR_IN6_LH, *PSOCKADDR_IN6_LH, FAR *LPSOCKADDR_IN6_LH;
' // Size = 4 bytes
UNION SOCKADDR_IN6_LH_UNION BYTE
 sin6_scope_id AS DWORD ' ULONG // Set of interfaces for a scope.
 sin6_scope_struct AS SCOPE_ID ' SCOPE_ID
END UNION
' // Size = 28 bytes
TYPE SOCKADDR_IN6_LH BYTE
 sin6_family AS WORD ' ADDRESS_FAMILY // AF_INET6.
 sin6_port AS WORD ' USHORT // Transport level port number.
 sin6_flowinfo AS DWORD ' ULONG // IPv6 flow information.
 sin6_addr AS IN6_ADDR ' IN6_ADDR // IPv6 address.
 SOCKADDR_IN6_LH_UNION
END TYPE
MACRO sockaddr_in6 = SOCKADDR_IN6_LH
'typedef struct sockaddr_in6_w2ksp1 {
' short sin6_family; /* AF_INET6 */
' USHORT sin6_port; /* Transport level port number */
' ULONG sin6_flowinfo; /* IPv6 flow information */
' struct in6_addr sin6_addr; /* IPv6 address */
' ULONG sin6_scope_id; /* set of interfaces for a scope */
'} SOCKADDR_IN6_W2KSP1, *PSOCKADDR_IN6_W2KSP1, FAR *LPSOCKADDR_IN6_W2KSP1;
' // Size = 28 bytes
TYPE SOCKADDR_IN6_W2KSP1 BYTE
 sin6_family AS INTEGER ' short /* AF_INET6 */
 sin6_port AS WORD ' USHORT /* Transport level port number */
 sin6_flowinfo AS DWORD ' ULONG /* IPv6 flow information */
 sin6_addr AS in6_addr ' in6_addr /* IPv6 address */
 sin6_scope_id AS DWORD ' ULONG /* set of interfaces for a scope */
END TYPE
'#if (NTDDI_VERSION >= NTDDI_VISTA)
'typedef SOCKADDR_IN6_LH SOCKADDR_IN6;
'typedef SOCKADDR_IN6_LH *PSOCKADDR_IN6;
'typedef SOCKADDR_IN6_LH FAR *LPSOCKADDR_IN6;
'#elif(NTDDI_VERSION >= NTDDI_WIN2KSP1)
'typedef SOCKADDR_IN6_W2KSP1 SOCKADDR_IN6;
'typedef SOCKADDR_IN6_W2KSP1 *PSOCKADDR_IN6;
'typedef SOCKADDR_IN6_W2KSP1 FAR *LPSOCKADDR_IN6;
'#else
'typedef SOCKADDR_IN6_LH SOCKADDR_IN6;
'typedef SOCKADDR_IN6_LH *PSOCKADDR_IN6;
'typedef SOCKADDR_IN6_LH FAR *LPSOCKADDR_IN6;
'#endif
'typedef union _SOCKADDR_INET {
' SOCKADDR_IN Ipv4;
' SOCKADDR_IN6 Ipv6;
' ADDRESS_FAMILY si_family;
'} SOCKADDR_INET, *PSOCKADDR_INET;
' // Size = 28 bytes
UNION SOCKADDR_INET BYTE
 Ipv4 AS SOCKADDR_IN
 Ipv6 AS SOCKADDR_IN6
 si_family AS WORD ' ADDRESS_FAMILY
END UNION
'//
'// Structure to hold a pair of source, destination addresses.
'//
'typedef struct _sockaddr_in6_pair
'{
' PSOCKADDR_IN6 SourceAddress;
' PSOCKADDR_IN6 DestinationAddress;
'} SOCKADDR_IN6_PAIR, *PSOCKADDR_IN6_PAIR;
' // Size = 8 bytes
TYPE SOCKADDR_IN6_PAIR DWORD
 SourceAddress AS SOCKADDR_IN6 PTR ' PSOCKADDR_IN6
 DestinationAddress AS SOCKADDR_IN6 PTR ' PSOCKADDR_IN6
END TYPE
'//
'// Macro that works for both IPv4 and IPv6
'//
'#define SS_PORT(ssp) (((PSOCKADDR_IN)(ssp))->sin_port)
'#if (NTDDI_VERSION >= NTDDI_WIN2KSP1)
'//
'// N.B. These addresses are in network byte order.
'//
%EQUATE `IN6ADDR_ANY_INIT = 0
'#define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
MACRO IN6ADDR_LOOPBACK_INIT = 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
'#define IN6ADDR_ALLNODESONNODE_INIT { \
' 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 \
'}
MACRO IN6ADDR_ALLNODESONNODE_INIT = &Hff, &H01, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H01
'#define IN6ADDR_ALLNODESONLINK_INIT { \
' 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 \
'}
MACRO IN6ADDR_ALLNODESONLINK_INIT = &Hff, &H02, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H01
'#define IN6ADDR_ALLROUTERSONLINK_INIT { \
' 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 \
'}
MACRO IN6ADDR_ALLROUTERSONLINK_INIT = &Hff, &H02, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H02
'#define IN6ADDR_ALLMLDV2ROUTERSONLINK_INIT { \
' 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16 \
'}
MACRO IN6ADDR_ALLMLDV2ROUTERSONLINK_INIT = &Hff, &H02, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H16
'#define IN6ADDR_TEREDOINITIALLINKLOCALADDRESS_INIT { \
' 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
' 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe \
'}
MACRO IN6ADDR_TEREDOINITIALLINKLOCALADDRESS_INIT = &Hfe, &H80, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &Hff, &Hff, &Hff, &Hff, &Hff, &Hfe
'//
'// The old link local address for XP-SP2/Win2K3 machines.
'//
'#define IN6ADDR_TEREDOOLDLINKLOCALADDRESSXP_INIT { \
' 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
' 0x00, 0x00, 'T', 'E', 'R', 'E', 'D', 'O' \
'}
MACRO IN6ADDR_TEREDOOLDLINKLOCALADDRESSXP_INIT = &Hfe, &H80, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H54, &H45, &H52, &H45, &H44, &H4f
'//
'// The old link local address for Vista Beta-2 and earlier machines.
'//
'#define IN6ADDR_TEREDOOLDLINKLOCALADDRESSVISTA_INIT { \
' 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
' 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff \
'}
MACRO IN6ADDR_TEREDOOLDLINKLOCALADDRESSVISTA_INIT = &Hfe, &H80, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &Hff, &Hff, &Hff, &Hff, &Hff, &Hff
'#define IN6ADDR_LINKLOCALPREFIX_INIT { 0xfe, 0x80, }
MACRO IN6ADDR_LINKLOCALPREFIX_INIT = &Hfe, &H80,
'#define IN6ADDR_MULTICASTPREFIX_INIT { 0xff, 0x00, }
MACRO IN6ADDR_MULTICASTPREFIX_INIT = &Hff, &H00,
'#define IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_INIT { \
' 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
' 0x00, 0x00, 0x00, 0x01, 0xff, \
'}
MACRO IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_INIT = &Hff, &H02, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H01, &Hff,
'#define IN6ADDR_V4MAPPEDPREFIX_INIT { \
' 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
' 0x00, 0x00, 0xff, 0xff, \
'}
MACRO IN6ADDR_V4MAPPEDPREFIX_INIT = &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &H00, &Hff, &Hff,
'#define IN6ADDR_6TO4PREFIX_INIT { 0x20, 0x02, }
MACRO IN6ADDR_6TO4PREFIX_INIT = &H20, &H02,
'#define IN6ADDR_TEREDOPREFIX_INIT { 0x20, 0x01, 0x00, 0x00, }
MACRO IN6ADDR_TEREDOPREFIX_INIT = &H20, &H01, &H00, &H00,
'#define IN6ADDR_TEREDOPREFIX_INIT_OLD { 0x3f, 0xfe, 0x83, 0x1f, }
MACRO IN6ADDR_TEREDOPREFIX_INIT_OLD = &H3f, &Hfe, &H83, &H1f,
%EQUATE `IN6ADDR_LINKLOCALPREFIX_LENGTH = 64
%EQUATE `IN6ADDR_MULTICASTPREFIX_LENGTH = 8
%EQUATE `IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_LENGTH = 104
%EQUATE `IN6ADDR_V4MAPPEDPREFIX_LENGTH = 96
%EQUATE `IN6ADDR_6TO4PREFIX_LENGTH = 16
%EQUATE `IN6ADDR_TEREDOPREFIX_LENGTH = 32
'#ifdef __cplusplus
'extern "C" {
'#endif
'//
'// N.B. These addresses are in network byte order.
'//
'extern CONST SCOPE_ID scopeid_unspecified;
'extern CONST IN_ADDR in4addr_any;
'extern CONST IN_ADDR in4addr_loopback;
'extern CONST IN_ADDR in4addr_broadcast;
'extern CONST IN_ADDR in4addr_allnodesonlink;
'extern CONST IN_ADDR in4addr_allroutersonlink;
'extern CONST IN_ADDR in4addr_alligmpv3routersonlink;
'extern CONST IN_ADDR in4addr_allteredohostsonlink;
'extern CONST IN_ADDR in4addr_linklocalprefix;
'extern CONST IN_ADDR in4addr_multicastprefix;
'extern CONST IN6_ADDR in6addr_any;
'extern CONST IN6_ADDR in6addr_loopback;
'extern CONST IN6_ADDR in6addr_allnodesonnode;
'extern CONST IN6_ADDR in6addr_allnodesonlink;
'extern CONST IN6_ADDR in6addr_allroutersonlink;
'extern CONST IN6_ADDR in6addr_allmldv2routersonlink;
'extern CONST IN6_ADDR in6addr_teredoinitiallinklocaladdress;
'extern CONST IN6_ADDR in6addr_linklocalprefix;
'extern CONST IN6_ADDR in6addr_multicastprefix;
'extern CONST IN6_ADDR in6addr_solicitednodemulticastprefix;
'extern CONST IN6_ADDR in6addr_v4mappedprefix;
'extern CONST IN6_ADDR in6addr_6to4prefix;
'extern CONST IN6_ADDR in6addr_teredoprefix;
'extern CONST IN6_ADDR in6addr_teredoprefix_old;
'#ifdef __cplusplus
'}
'#endif
'#ifndef __midl
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_ADDR_EQUAL(CONST IN6_ADDR *x, CONST IN6_ADDR *y)
'{
' a = (__int64 UNALIGNED *)x;
' b = (__int64 UNALIGNED *)y;
' return (BOOLEAN)((a[1] == b[1]) && (a[0] == b[0]));
'}
'//
'// RFC 3542 uses IN6_ARE_ADDR_EQUAL().
'//
'#define IN6_ARE_ADDR_EQUAL IN6_ADDR_EQUAL
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_UNSPECIFIED(CONST IN6_ADDR *a)
'{
' //
' // We can't use the in6addr_any variable, since that would
' // require existing callers to link with a specific library.
' //
' return (BOOLEAN)((a->s6_words[0] == 0) &&
' (a->s6_words[1] == 0) &&
' (a->s6_words[2] == 0) &&
' (a->s6_words[3] == 0) &&
' (a->s6_words[4] == 0) &&
' (a->s6_words[5] == 0) &&
' (a->s6_words[6] == 0) &&
' (a->s6_words[7] == 0));
'}
FUNCTION IN6_IS_ADDR_UNSPECIFIED (BYREF a AS in6_addr) AS LONG
 IF a.Word(0) = 0 AND a.Word(1) = 0 AND a.Word(2) = 0 AND a.Word(3) = 0 AND a.Word(4) = 0 AND a.Word(5) = 0 AND a.Word(6) = 0 AND a.Word(7) = 0 THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_LOOPBACK(CONST IN6_ADDR *a)
'{
' //
' // We can't use the in6addr_loopback variable, since that would
' // require existing callers to link with a specific library.
' //
' return (BOOLEAN)((a->s6_words[0] == 0) &&
' (a->s6_words[1] == 0) &&
' (a->s6_words[2] == 0) &&
' (a->s6_words[3] == 0) &&
' (a->s6_words[4] == 0) &&
' (a->s6_words[5] == 0) &&
' (a->s6_words[6] == 0) &&
' (a->s6_words[7] == 0x0100));
'}
FUNCTION IN6_IS_ADDR_LOOPBACK (BYREF a AS in6_addr) AS LONG
 IF a.Word(0) = 0 AND a.Word(1) = 0 AND a.Word(2) = 0 AND a.Word(3) = 0 AND a.Word(4) = 0 AND a.Word(5) = 0 AND a.Word(6) = 0 AND a.Word(7) = &H0100 THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_MULTICAST(CONST IN6_ADDR *a)
'{
' return (BOOLEAN)(a->s6_bytes[0] == 0xff);
'}
FUNCTION IN6_IS_ADDR_MULTICAST (BYREF a AS in6_addr) AS LONG
 IF a.Byte(0) = &Hff THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'//
'// Does the address have a format prefix
'// that indicates it uses EUI-64 interface identifiers?
'//
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_EUI64(CONST IN6_ADDR *a)
'{
' //
' // Format prefixes 001 through 111, except for multicast.
' //
' return (BOOLEAN)(((a->s6_bytes[0] & 0xe0) != 0) &&
' !IN6_IS_ADDR_MULTICAST(a));
'}
FUNCTION IN6_IS_ADDR_EUI64 (BYREF a AS in6_addr) AS LONG
 IF ((a.Byte(0) AND &He0) <> 0) AND NOT IN6_IS_ADDR_MULTICAST(a) THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'//
'// Is this the subnet router anycast address?
'// See RFC 2373.
'//
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_SUBNET_ROUTER_ANYCAST(CONST IN6_ADDR *a)
'{
' return (BOOLEAN)(IN6_IS_ADDR_EUI64(a) &&
' (a->s6_words[4] == 0) &&
' (a->s6_words[5] == 0) &&
' (a->s6_words[6] == 0) &&
' (a->s6_words[7] == 0));
'}
FUNCTION IN6_IS_ADDR_SUBNET_ROUTER_ANYCAST (BYREF a AS in6_addr) AS LONG
 IF IN6_IS_ADDR_EUI64(a) AND (a.Word(4) = 0) AND (a.Word(5) = 0) AND (a.Word(6) = 0) AND (a.Word(7) = 0) THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'//
'// Is this a subnet reserved anycast address?
'// See RFC 2526. It talks about non-EUI-64
'// addresses as well, but IMHO that part
'// of the RFC doesn't make sense. For example,
'// it shouldn't apply to multicast or v4-compatible
'// addresses.
'//
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_SUBNET_RESERVED_ANYCAST(CONST IN6_ADDR *a)
'{
' return (BOOLEAN)(IN6_IS_ADDR_EUI64(a) &&
' (a->s6_words[4] == 0xfffd) &&
' (a->s6_words[5] == 0xffff) &&
' (a->s6_words[6] == 0xffff) &&
' ((a->s6_words[7] & 0x80ff) == 0x80ff));
'}
FUNCTION IN6_IS_ADDR_SUBNET_RESERVED_ANYCAST (BYREF a AS in6_addr) AS LONG
 IF IN6_IS_ADDR_EUI64(a) AND (a.Word(4) = &Hfffd) AND (a.Word(5) = &Hffff) AND (a.Word(6) = &Hffff) AND ((a.Word(7) AND &H80ff) = &H80ff) THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'//
'// As best we can tell from simple inspection,
'// is this an anycast address?
'//
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_ANYCAST(CONST IN6_ADDR *a)
'{
' return (IN6_IS_ADDR_SUBNET_RESERVED_ANYCAST(a) ||
' IN6_IS_ADDR_SUBNET_ROUTER_ANYCAST(a));
'}
FUNCTION IN6_IS_ADDR_ANYCAST (BYREF a AS in6_addr) AS LONG
 FUNCTION = IN6_IS_ADDR_SUBNET_RESERVED_ANYCAST(a) OR IN6_IS_ADDR_SUBNET_ROUTER_ANYCAST(a)
END FUNCTION
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_LINKLOCAL(CONST IN6_ADDR *a)
'{
' return (BOOLEAN)((a->s6_bytes[0] == 0xfe) &&
' ((a->s6_bytes[1] & 0xc0) == 0x80));
'}
FUNCTION IN6_IS_ADDR_LINKLOCAL (BYREF a AS in6_addr) AS LONG
 IF a.Byte(0) = &Hfe AND (a.Byte(1) AND &Hc0 = &H80) THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_SITELOCAL(CONST IN6_ADDR *a)
'{
' return (BOOLEAN)((a->s6_bytes[0] == 0xfe) &&
' ((a->s6_bytes[1] & 0xc0) == 0xc0));
'}
FUNCTION IN6_IS_ADDR_SITELOCAL (BYREF a AS in6_addr) AS LONG
 IF a.Byte(0) = &Hfe AND (a.Byte(1) AND &Hc0 = &Hc0) THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_GLOBAL(CONST IN6_ADDR *a)
'{
' //
' // Check the format prefix and exclude addresses
' // whose high 4 bits are all zero or all one.
' // This is a cheap way of excluding v4-compatible,
' // v4-mapped, loopback, multicast, link-local, site-local.
' //
' ULONG High = (a->s6_bytes[0] & 0xf0);
' return (BOOLEAN)((High != 0) && (High != 0xf0));
'}
FUNCTION IN6_IS_ADDR_GLOBAL (BYREF a AS in6_addr) AS LONG
 LOCAL High AS DWORD
 High = (a.byte(0) AND &Hf0)
 FUNCTION = (High <> 0) AND (High <> &Hf0)
END FUNCTION
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_V4MAPPED(CONST IN6_ADDR *a)
'{
' return (BOOLEAN)((a->s6_words[0] == 0) &&
' (a->s6_words[1] == 0) &&
' (a->s6_words[2] == 0) &&
' (a->s6_words[3] == 0) &&
' (a->s6_words[4] == 0) &&
' (a->s6_words[5] == 0xffff));
'}
FUNCTION IN6_IS_ADDR_V4MAPPED (BYREF a AS in6_addr) AS LONG
 IF a.Word(0) = 0 AND a.Word(1) = 0 AND a.Word(2) = 0 AND a.Word(3) = 0 AND a.Word(4) = 0 AND a.Word(5) = &Hffff THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_V4COMPAT(CONST IN6_ADDR *a)
'{
' return (BOOLEAN)((a->s6_words[0] == 0) &&
' (a->s6_words[1] == 0) &&
' (a->s6_words[2] == 0) &&
' (a->s6_words[3] == 0) &&
' (a->s6_words[4] == 0) &&
' (a->s6_words[5] == 0) &&
' !((a->s6_words[6] == 0) &&
' (a->s6_addr[14] == 0) &&
' ((a->s6_addr[15] == 0) || (a->s6_addr[15] == 1))));
'}
FUNCTION IN6_IS_ADDR_V4COMPAT (BYREF a AS in6_addr) AS LONG
 IF a.Word(0) = 0 AND a.Word(1) = 0 AND a.Word(2) = 0 AND a.Word(3) = 0 AND a.Word(4) = 0 AND a.Word(5) = 0 AND NOT ((a.Word(6) = 0) AND (a.Byte(14) = 0) AND ((a.Byte(15) = 0) OR (a.Byte(15) = 1))) THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_V4TRANSLATED(CONST IN6_ADDR *a)
'{
' return (BOOLEAN)((a->s6_words[0] == 0) &&
' (a->s6_words[1] == 0) &&
' (a->s6_words[2] == 0) &&
' (a->s6_words[3] == 0) &&
' (a->s6_words[4] == 0xffff) &&
' (a->s6_words[5] == 0));
'}
FUNCTION IN6_IS_ADDR_V4TRANSLATED (BYREF a AS in6_addr) AS LONG
 IF a.Word(0) = 0 AND a.Word(1) = 0 AND a.Word(2) = 0 AND a.Word(3) = 0 AND a.Word(4) = &Hffff AND a.Word(5) = 0 THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_MC_NODELOCAL(CONST IN6_ADDR *a)
'{
' return (BOOLEAN)(IN6_IS_ADDR_MULTICAST(a) &&
' ((a->s6_bytes[1] & 0xf) == 1));
'}
FUNCTION IN6_IS_ADDR_MC_NODELOCAL (BYREF a AS in6_addr) AS LONG
 IF ISTRUE IN6_IS_ADDR_MULTICAST(a) AND ((a.Byte(1) AND &Hf) = 1) THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_MC_LINKLOCAL(CONST IN6_ADDR *a)
'{
' return (BOOLEAN)(IN6_IS_ADDR_MULTICAST(a) &&
' ((a->s6_bytes[1] & 0xf) == 2));
'}
FUNCTION IN6_IS_ADDR_MC_LINKLOCAL (BYREF a AS in6_addr) AS LONG
 IF ISTRUE IN6_IS_ADDR_MULTICAST(a) AND ((a.Byte(1) AND &Hf) = 2) THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_MC_SITELOCAL(CONST IN6_ADDR *a)
'{
' return (BOOLEAN)(IN6_IS_ADDR_MULTICAST(a) &&
' ((a->s6_bytes[1] & 0xf) == 5));
'}
FUNCTION IN6_IS_ADDR_MC_SITELOCAL (BYREF a AS in6_addr) AS LONG
 IF ISTRUE IN6_IS_ADDR_MULTICAST(a) AND ((a.Byte(1) AND &Hf) = 5) THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_MC_ORGLOCAL(CONST IN6_ADDR *a)
'{
' return (BOOLEAN)(IN6_IS_ADDR_MULTICAST(a) &&
' ((a->s6_bytes[1] & 0xf) == 8));
'}
FUNCTION IN6_IS_ADDR_MC_ORGLOCAL (BYREF a AS in6_addr) AS LONG
 IF ISTRUE IN6_IS_ADDR_MULTICAST(a) AND ((a.Byte(1) AND &Hf) = 8) THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'WS2TCPIP_INLINE
'BOOLEAN
'IN6_IS_ADDR_MC_GLOBAL(CONST IN6_ADDR *a)
'{
' return (BOOLEAN)(IN6_IS_ADDR_MULTICAST(a) &&
' ((a->s6_bytes[1] & 0xf) == 0xe));
'}
FUNCTION IN6_IS_ADDR_MC_GLOBAL (BYREF a AS in6_addr) AS LONG
 IF ISTRUE IN6_IS_ADDR_MULTICAST(a) AND ((a.Byte(1) AND &Hf) = &He) THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'WS2TCPIP_INLINE
'IN6_SET_ADDR_UNSPECIFIED(PIN6_ADDR a)
'{
' //
' // We can't use the in6addr_any variable, since that would
' // require existing callers to link with a specific library.
' //
' memset(a->s6_bytes, 0, sizeof(IN6_ADDR));
'}
SUB IN6_SET_ADDR_UNSPECIFIED (BYREF a AS in6_addr)
 RESET a
END SUB
'WS2TCPIP_INLINE
'IN6_SET_ADDR_LOOPBACK(PIN6_ADDR a)
'{
' //
' // We can't use the in6addr_loopback variable, since that would
' // require existing callers to link with a specific library.
' //
' memset(a->s6_bytes, 0, sizeof(IN6_ADDR));
' a->s6_bytes[15] = 1;
'}
SUB IN6_SET_ADDR_LOOPBACK (BYREF a AS in6_addr)
 RESET a
 a.byte(15) = 1
END SUB
'WS2TCPIP_INLINE
'IN6ADDR_SETANY(PSOCKADDR_IN6 a)
'{
' a->sin6_family = AF_INET6;
' a->sin6_port = 0;
' a->sin6_flowinfo = 0;
' IN6_SET_ADDR_UNSPECIFIED(&a->sin6_addr);
' a->sin6_scope_id = 0;
'}
SUB IN6ADDR_SETANY (BYREF a AS SOCKADDR_IN6)
 a.sin6_family = %AF_INET6
 a.sin6_port = 0
 a.sin6_flowinfo = 0
 IN6_SET_ADDR_UNSPECIFIED(a.sin6_addr)
 a.sin6_scope_id = 0
END SUB
'WS2TCPIP_INLINE
'IN6ADDR_SETLOOPBACK(PSOCKADDR_IN6 a)
'{
' a->sin6_family = AF_INET6;
' a->sin6_port = 0;
' a->sin6_flowinfo = 0;
' IN6_SET_ADDR_LOOPBACK(&a->sin6_addr);
' a->sin6_scope_id = 0;
'}
SUB IN6ADDR_SETLOOPBACK (BYREF a AS SOCKADDR_IN6)
 a.sin6_family = %AF_INET6
 a.sin6_port = 0
 a.sin6_flowinfo = 0
 IN6_SET_ADDR_LOOPBACK(a.sin6_addr)
 a.sin6_scope_id = 0
END SUB
'WS2TCPIP_INLINE
'BOOLEAN
'IN6ADDR_ISANY(CONST SOCKADDR_IN6 *a)
'{
' WS2IPDEF_ASSERT(a->sin6_family == AF_INET6);
' return IN6_IS_ADDR_UNSPECIFIED(&a->sin6_addr);
'}
FUNCTION IN6ADDR_ISANY (BYREF a AS SOCKADDR_IN6) AS LONG
 IF a.sin6_family = %AF_INET6 AND ISTRUE IN6_IS_ADDR_UNSPECIFIED(a.sin6_addr) THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'WS2TCPIP_INLINE
'BOOLEAN
'IN6ADDR_ISLOOPBACK(CONST SOCKADDR_IN6 *a)
'{
' WS2IPDEF_ASSERT(a->sin6_family == AF_INET6);
' return IN6_IS_ADDR_LOOPBACK(&a->sin6_addr);
'}
FUNCTION IN6ADDR_ISLOOPBACK (BYREF a AS SOCKADDR_IN6) AS LONG
 IF a.sin6_family = %AF_INET6 AND ISTRUE IN6_IS_ADDR_LOOPBACK(a.sin6_addr) THEN FUNCTION = 1 ' %TRUE
END FUNCTION
'WS2TCPIP_INLINE
'BOOLEAN
'IN6ADDR_ISEQUAL(CONST SOCKADDR_IN6 *a, CONST SOCKADDR_IN6 *b)
'{
' WS2IPDEF_ASSERT(a->sin6_family == AF_INET6);
' return (BOOLEAN)(a->sin6_scope_id == b->sin6_scope_id &&
' IN6_ADDR_EQUAL(&a->sin6_addr, &b->sin6_addr));
FUNCTION IN6ADDR_ISEQUAL (BYREF a AS SOCKADDR_IN6, BYREF b AS SOCKADDR_IN6) AS LONG
 IF a.sin6_family <> %AF_INET6 THEN EXIT FUNCTION
 FUNCTION = (a.sin6_scope_id = b.sin6_scope_id AND a.sin6_addr = b.sin6_addr)
END FUNCTION
'WS2TCPIP_INLINE
'BOOLEAN
'IN6ADDR_ISUNSPECIFIED(CONST SOCKADDR_IN6 *a)
'{
' WS2IPDEF_ASSERT(a->sin6_family == AF_INET6);
' return (BOOLEAN)(a->sin6_scope_id == 0 &&
' IN6_IS_ADDR_UNSPECIFIED(&a->sin6_addr));
'}
FUNCTION IN6ADDR_ISUNSPECIFIED (BYREF a AS SOCKADDR_IN6) AS LONG
 IF a.sin6_family <> %AF_INET6 THEN EXIT FUNCTION
 FUNCTION = (a.sin6_scope_id = 0 AND IN6_IS_ADDR_UNSPECIFIED(a.sin6_addr))
END FUNCTION
'#endif // __midl
'#endif // (NTDDI_VERSION >= NTDDI_WIN2KSP1)
'//
'// TCP/IP specific Ioctl codes.
'//
'#define SIO_GET_INTERFACE_LIST _IOR('t', 127, ULONG)
'#define SIO_GET_INTERFACE_LIST_EX _IOR('t', 126, ULONG)
'#define SIO_SET_MULTICAST_FILTER _IOW('t', 125, ULONG)
'#define SIO_GET_MULTICAST_FILTER _IOW('t', 124 | IOC_IN, ULONG)
'#define SIOCSIPMSFILTER SIO_SET_MULTICAST_FILTER
'#define SIOCGIPMSFILTER SIO_GET_MULTICAST_FILTER
%EQUATE `SIO_GET_INTERFACE_LIST = &H4004747F
%EQUATE `SIO_GET_INTERFACE_LIST_EX = &H4004747E
%EQUATE `SIO_SET_MULTICAST_FILTER = &H8004747D
%EQUATE `SIO_GET_MULTICAST_FILTER = &H8004747C
%EQUATE `SIOCSIPMSFILTER = %SIO_SET_MULTICAST_FILTER
%EQUATE `SIOCGIPMSFILTER = %SIO_GET_MULTICAST_FILTER
'//
'// Protocol independent ioctls for setting and retrieving multicast filters.
'//
'#define SIOCSMSFILTER _IOW('t', 126, ULONG)
'#define SIOCGMSFILTER _IOW('t', 127 | IOC_IN, ULONG)
%EQUATE `SIOCSMSFILTER = &H8004747E
%EQUATE `SIOCGMSFILTER = &H8004747F
'#if (NTDDI_VERSION >= NTDDI_VISTASP1)
'#define IDEAL_SEND_BACKLOG_IOCTLS
%EQUATE `IDEAL_SEND_BACKLOG_IOCTLS = 1
'//
'// Query and change notification ioctls for the ideal send backlog size
'// for a given connection. Clients should use the wrappers defined in
'// ws2tcpip.h rather than using these ioctls directly.
'//
'#define SIO_IDEAL_SEND_BACKLOG_QUERY _IOR('t', 123, ULONG)
'#define SIO_IDEAL_SEND_BACKLOG_CHANGE _IO('t', 122)
%EQUATE `SIO_IDEAL_SEND_BACKLOG_QUERY = &H4004747B
%EQUATE `SIO_IDEAL_SEND_BACKLOG_CHANGE = &H2000747A
'#endif
'//
'// Protocol independent multicast source filter options.
'//
%EQUATE `MCAST_JOIN_GROUP = 41 ' // Join all sources for a group.
%EQUATE `MCAST_LEAVE_GROUP = 42 ' // Drop all sources for a group.
%EQUATE `MCAST_BLOCK_SOURCE = 43 ' // Block IP group/source.
%EQUATE `MCAST_UNBLOCK_SOURCE = 44 ' // Unblock IP group/source.
%EQUATE `MCAST_JOIN_SOURCE_GROUP = 45 ' // Join IP group/source.
%EQUATE `MCAST_LEAVE_SOURCE_GROUP = 46 ' // Leave IP group/source.
'//
'// Definitions of MCAST_INCLUDE and MCAST_EXCLUDE for multicast source filter.
'//
' enum MULTICAST_MODE_TYPE
%EQUATE `MCAST_INCLUDE = 0
%EQUATE `MCAST_EXCLUDE = 1
'//
'// Structure for IP_MREQ (used by IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP).
'//
' // Size = 8 bytes
TYPE IP_MREQ BYTE
 imr_multiaddr AS IN_ADDR ' // IP multicast address of group.
 imr_interface AS IN_ADDR ' // Local IP address of interface.
END TYPE
'//
'// Structure for IP_MREQ_SOURCE (used by IP_BLOCK_SOURCE, IP_UNBLOCK_SOURCE
'// etc.).
'//
' // Size = 12 bytes
TYPE IP_MREQ_SOURCE BYTE
 imr_multiaddr AS IN_ADDR ' // IP multicast address of group.
 imr_sourceaddr AS IN_ADDR ' // IP address of source.
 imr_interface AS IN_ADDR ' // Local IP address of interface.
END TYPE
'//
'// Structure for IP_MSFILTER (used by SIOCSIPMSFILTER and SIOCGIPMSFILTER).
'//
' // Size = 20 bytes
TYPE IP_MSFILTER BYTE
 imsf_multiaddr AS IN_ADDR ' IN_ADDR // IP multicast address of group.
 imsf_interface AS IN_ADDR ' IN_ADDR // Local IP address of interface.
 imsf_fmode AS LONG ' MULTICAST_MODE_TYPE // Filter mode.
 imsf_numsrc AS DWORD ' ULONG // Number of sources in src_list.
 imsf_slist(0) AS IN_ADDR ' variabe length array // Start of source list.
END TYPE
'#define IP_MSFILTER_SIZE(NumSources) \
' (sizeof(IP_MSFILTER) - sizeof(IN_ADDR) + (NumSources) * sizeof(IN_ADDR))
'//
'// Options to use with [gs]etsockopt at the IPPROTO_IPV6 level.
'// These are specified in RFCs 3493 and 3542.
'// The values should be consistent with the IPv6 equivalents.
'//
%EQUATE `IPV6_HOPOPTS = 1 ' // Set/get IPv6 hop-by-hop options.
%EQUATE `IPV6_HDRINCL = 2 ' // Header is included with data.
%EQUATE `IPV6_UNICAST_HOPS = 4 ' // IP unicast hop limit.
%EQUATE `IPV6_MULTICAST_IF = 9 ' // IP multicast interface.
%EQUATE `IPV6_MULTICAST_HOPS = 10 ' // IP multicast hop limit.
%EQUATE `IPV6_MULTICAST_LOOP = 11 ' // IP multicast loopback.
%EQUATE `IPV6_ADD_MEMBERSHIP = 12 ' // Add an IP group membership.
%EQUATE `IPV6_JOIN_GROUP = %IPV6_ADD_MEMBERSHIP
%EQUATE `IPV6_DROP_MEMBERSHIP = 13 ' // Drop an IP group membership.
%EQUATE `IPV6_LEAVE_GROUP = %IPV6_DROP_MEMBERSHIP
%EQUATE `IPV6_DONTFRAG = 14 ' // Don't fragment IP datagrams.
%EQUATE `IPV6_PKTINFO = 19 ' // Receive packet information.
%EQUATE `IPV6_HOPLIMIT = 21 ' // Receive packet hop limit.
%EQUATE `IPV6_PROTECTION_LEVEL = 23 ' // Set/get IPv6 protection level.
%EQUATE `IPV6_RECVIF = 24 ' // Receive arrival interface.
%EQUATE `IPV6_RECVDSTADDR = 25 ' // Receive destination address.
%EQUATE `IPV6_CHECKSUM = 26 ' // Offset to checksum for raw IP socket send.
%EQUATE `IPV6_V6ONLY = 27 ' // Treat wildcard bind as AF_INET6-only.
%EQUATE `IPV6_IFLIST = 28 ' // Enable/Disable an interface list.
%EQUATE `IPV6_ADD_IFLIST = 29 ' // Add an interface list entry.
%EQUATE `IPV6_DEL_IFLIST = 30 ' // Delete an interface list entry.
%EQUATE `IPV6_UNICAST_IF = 31 ' // IP unicast interface.
%EQUATE `IPV6_RTHDR = 32 ' // Set/get IPv6 routing header.
%EQUATE `IPV6_RECVRTHDR = 38 ' // Receive the routing header.
%EQUATE `IPV6_TCLASS = 39 ' // Packet traffic class.
%EQUATE `IPV6_RECVTCLASS = 40 ' // Receive packet traffic class.
%EQUATE `IP_UNSPECIFIED_HOP_LIMIT = -1
%EQUATE `IP_PROTECTION_LEVEL = %IPV6_PROTECTION_LEVEL
'//
'// Values of IPV6_PROTECTION_LEVEL.
'//
%EQUATE `PROTECTION_LEVEL_UNRESTRICTED = 10 ' // For peer-to-peer apps.
%EQUATE `PROTECTION_LEVEL_EDGERESTRICTED = 20 ' // Same as unrestricted. Except for Teredo.
%EQUATE `PROTECTION_LEVEL_RESTRICTED = 30 ' // For Intranet apps.
'#if (NTDDI_VERSION < NTDDI_VISTA)
'#define PROTECTION_LEVEL_DEFAULT PROTECTION_LEVEL_EDGERESTRICTED
'#else
'#define PROTECTION_LEVEL_DEFAULT ((UINT)-1)
'#endif
'//
'// Structure for IPV6_JOIN_GROUP and IPV6_LEAVE_GROUP (also,
'// IPV6_ADD_MEMBERSHIP and IPV6_DROP_MEMBERSHIP).
'//
' // Size = 20 bytes
TYPE IPV6_MREQ BYTE
 ipv6mr_multiaddr AS IN6_ADDR ' IN6_ADDR // IPv6 multicast address.
 ipv6mr_interface AS DWORD ' ULONG // Interface index.
END TYPE
'#if (NTDDI_VERSION >= NTDDI_WINXP)
'//
'// Structure for GROUP_REQ used by protocol independent source filters
'// (MCAST_JOIN_GROUP and MCAST_LEAVE_GROUP).
'//
' // Size = 136 bytes
TYPE GROUP_REQ QWORD FILL ' Must be 8 byte aligned
 gr_interface AS DWORD ' ULONG // Interface index.
 gr_group AS SOCKADDR_STORAGE ' SOCKADDR_STORAGE // Multicast address.
END TYPE
'//
'// Structure for GROUP_SOURCE_REQ used by protocol independent source filters
'// (MCAST_JOIN_SOURCE_GROUP, MCAST_LEAVE_SOURCE_GROUP etc.).
'//
' // Size = 264 bytes
TYPE GROUP_SOURCE_REQ QWORD FILL ' Must be 8 byte aligned
 gsr_interface AS DWORD ' ULONG // Interface index.
 gsr_group AS SOCKADDR_STORAGE ' SOCKADDR_STORAGE // Group address.
 gsr_source AS SOCKADDR_STORAGE ' SOCKADDR_STORAGE // Source address.
END TYPE
'//
'// Structure for GROUP_FILTER used by protocol independent source filters
'// (SIOCSMSFILTER and SIOCGMSFILTER).
'//
' // Size = 272 bytes
TYPE GROUP_FILTER QWORD FILL ' Must be 8 byte aligned
 gf_interface AS DWORD ' ULONG // Interface index.
 gf_group AS SOCKADDR_STORAGE ' SOCKADDR_STORAGE // Multicast address.
 gf_fmode AS LONG ' MULTICAST_MODE_TYPE // Filter mode.
 gf_numsrc AS DWORD ' ULONG // Number of sources.
 gf_slist(0) AS SOCKADDR_STORAGE ' variable length array // Source address.
END TYPE
'#define GROUP_FILTER_SIZE(numsrc) \
' (sizeof(GROUP_FILTER) - sizeof(SOCKADDR_STORAGE) \
' + (numsrc) * sizeof(SOCKADDR_STORAGE))
'#endif
'//
'// Structure for IP_PKTINFO option.
'//
' // Size = 8 bytes
TYPE IN_PKTINFO BYTE
 ipi_addr AS IN_ADDR ' IN_ADDR // Source/destination IPv4 address.
 ipi_ifindex AS DWORD ' ULONG // Send/receive interface index.
END TYPE
'C_ASSERT(sizeof(IN_PKTINFO) == 8);
'//
'// Structure for IPV6_PKTINFO option.
'//
' // Size = 20 bytes
TYPE IN6_PKTINFO BYTE
 ipi6_addr AS IN6_ADDR ' IN6_ADDR // Source/destination IPv6 address.
 ipi6_ifindex AS DWORD ' ULONG // Send/receive interface index.
END TYPE
'C_ASSERT(sizeof(IN6_PKTINFO) == 20);
'//
'// Maximum length of address literals (potentially including a port number)
'// generated by any address-to-string conversion routine. This length can
'// be used when declaring buffers used with getnameinfo, WSAAddressToString,
'// inet_ntoa, etc. We just provide one define, rather than one per api,
'// to avoid confusion.
'//
'// The totals are derived from the following data:
'// 15: IPv4 address
'// 45: IPv6 address including embedded IPv4 address
'// 11: Scope Id
'// 2: Brackets around IPv6 address when port is present
'// 6: Port (including colon)
'// 1: Terminating null byte
'//
%EQUATE `INET_ADDRSTRLEN = 22
%EQUATE `INET6_ADDRSTRLEN = 65
'//
'// Options to use with [gs]etsockopt at the IPPROTO_TCP level.
'// TCP_NODELAY is defined in ws2def.h for historical reasons.
'//
'//
'// Offload preferences supported.
'//
%EQUATE `TCP_OFFLOAD_NO_PREFERENCE = 0
%EQUATE `TCP_OFFLOAD_NOT_PREFERRED = 1
%EQUATE `TCP_OFFLOAD_PREFERRED = 2
'// TCP_NODELAY 0x0001
%EQUATE `TCP_EXPEDITED_1122 = &H0002
%EQUATE `TCP_KEEPALIVE = 3
%EQUATE `TCP_MAXSEG = 4
%EQUATE `TCP_MAXRT = 5
%EQUATE `TCP_STDURG = 6
%EQUATE `TCP_NOURG = 7
%EQUATE `TCP_ATMARK = 8
%EQUATE `TCP_NOSYNRETRIES = 9
%EQUATE `TCP_TIMESTAMPS = 10
%EQUATE `TCP_OFFLOAD_PREFERENCE = 11
%EQUATE `TCP_CONGESTION_ALGORITHM = 12
%EQUATE `TCP_DELAY_FIN_ACK = 13
'#ifdef _PREFAST_
'#pragma prefast(pop)
'#endif
'#pragma warning(pop)
#ENDIF
