mirror of https://github.com/UMSKT/xpmgr.git
901 lines
27 KiB
C
901 lines
27 KiB
C
/*++
|
|
|
|
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
|
|
|
|
--*/
|
|
|
|
#ifndef _WS2IPDEF_
|
|
#define _WS2IPDEF_
|
|
|
|
#if _MSC_VER > 1000
|
|
#pragma once
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#pragma warning(push)
|
|
#pragma warning(disable:4201)
|
|
#pragma warning(disable:4127) // conditional expression is constant
|
|
|
|
#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
|
|
|
|
#ifdef _MSC_VER
|
|
#define WS2TCPIP_INLINE __inline
|
|
#else
|
|
#define WS2TCPIP_INLINE extern inline /* GNU style */
|
|
#endif
|
|
|
|
#include <in6addr.h>
|
|
|
|
//
|
|
// Old IPv6 socket address structure (retained for sockaddr_gen definition).
|
|
//
|
|
|
|
struct sockaddr_in6_old {
|
|
SHORT sin6_family; // AF_INET6.
|
|
USHORT sin6_port; // Transport level port number.
|
|
ULONG sin6_flowinfo; // IPv6 flow information.
|
|
IN6_ADDR sin6_addr; // IPv6 address.
|
|
};
|
|
|
|
typedef union sockaddr_gen {
|
|
struct sockaddr Address;
|
|
struct sockaddr_in AddressIn;
|
|
struct sockaddr_in6_old AddressIn6;
|
|
} sockaddr_gen;
|
|
|
|
//
|
|
// Structure to keep interface specific information
|
|
//
|
|
|
|
typedef struct _INTERFACE_INFO {
|
|
ULONG iiFlags; // Interface flags.
|
|
sockaddr_gen iiAddress; // Interface address.
|
|
sockaddr_gen iiBroadcastAddress; // Broadcast address.
|
|
sockaddr_gen iiNetmask; // Network mask.
|
|
} INTERFACE_INFO, FAR *LPINTERFACE_INFO;
|
|
|
|
//
|
|
// New structure that does not have dependency on the address size.
|
|
//
|
|
|
|
typedef struct _INTERFACE_INFO_EX {
|
|
ULONG iiFlags; // Interface flags.
|
|
SOCKET_ADDRESS iiAddress; // Interface address.
|
|
SOCKET_ADDRESS iiBroadcastAddress; // Broadcast address.
|
|
SOCKET_ADDRESS iiNetmask; // Network mask.
|
|
} INTERFACE_INFO_EX, FAR *LPINTERFACE_INFO_EX;
|
|
|
|
//
|
|
// Possible flags for the iiFlags - bitmask.
|
|
//
|
|
|
|
#define IFF_UP 0x00000001 // Interface is up.
|
|
#define IFF_BROADCAST 0x00000002 // Broadcast is supported.
|
|
#define IFF_LOOPBACK 0x00000004 // This is loopback interface.
|
|
#define IFF_POINTTOPOINT 0x00000008 // This is point-to-point interface.
|
|
#define IFF_MULTICAST 0x00000010 // Multicast is supported.
|
|
|
|
|
|
//
|
|
// Options to use with [gs]etsockopt at the IPPROTO_IP level.
|
|
// The values should be consistent with the IPv6 equivalents.
|
|
//
|
|
#define IP_OPTIONS 1 // Set/get IP options.
|
|
#define IP_HDRINCL 2 // Header is included with data.
|
|
#define IP_TOS 3 // IP type of service.
|
|
#define IP_TTL 4 // IP TTL (hop limit).
|
|
#define IP_MULTICAST_IF 9 // IP multicast interface.
|
|
#define IP_MULTICAST_TTL 10 // IP multicast TTL (hop limit).
|
|
#define IP_MULTICAST_LOOP 11 // IP multicast loopback.
|
|
#define IP_ADD_MEMBERSHIP 12 // Add an IP group membership.
|
|
#define IP_DROP_MEMBERSHIP 13 // Drop an IP group membership.
|
|
#define IP_DONTFRAGMENT 14 // Don't fragment IP datagrams.
|
|
#define IP_ADD_SOURCE_MEMBERSHIP 15 // Join IP group/source.
|
|
#define IP_DROP_SOURCE_MEMBERSHIP 16 // Leave IP group/source.
|
|
#define IP_BLOCK_SOURCE 17 // Block IP group/source.
|
|
#define IP_UNBLOCK_SOURCE 18 // Unblock IP group/source.
|
|
#define IP_PKTINFO 19 // Receive packet information.
|
|
#define IP_HOPLIMIT 21 // Receive packet hop limit.
|
|
#define IP_RECEIVE_BROADCAST 22 // Allow/block broadcast reception.
|
|
#define IP_RECVIF 24 // Receive arrival interface.
|
|
#define IP_RECVDSTADDR 25 // Receive destination address.
|
|
#define IP_IFLIST 28 // Enable/Disable an interface list.
|
|
#define IP_ADD_IFLIST 29 // Add an interface list entry.
|
|
#define IP_DEL_IFLIST 30 // Delete an interface list entry.
|
|
#define IP_UNICAST_IF 31 // IP unicast interface.
|
|
#define IP_RTHDR 32 // Set/get IPv6 routing header.
|
|
#define IP_RECVRTHDR 38 // Receive the routing header.
|
|
#define IP_TCLASS 39 // Packet traffic class.
|
|
#define IP_RECVTCLASS 40 // Receive packet traffic class.
|
|
#define IP_ORIGINAL_ARRIVAL_IF 47 // Original Arrival Interface Index.
|
|
|
|
#define 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;
|
|
|
|
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;
|
|
|
|
#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;
|
|
|
|
//
|
|
// 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;
|
|
|
|
//
|
|
// 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.
|
|
//
|
|
|
|
#define IN6ADDR_ANY_INIT { 0 }
|
|
|
|
#define 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 \
|
|
}
|
|
|
|
#define IN6ADDR_ALLNODESONLINK_INIT { \
|
|
0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 \
|
|
}
|
|
|
|
#define IN6ADDR_ALLROUTERSONLINK_INIT { \
|
|
0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 \
|
|
}
|
|
|
|
#define IN6ADDR_ALLMLDV2ROUTERSONLINK_INIT { \
|
|
0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16 \
|
|
}
|
|
|
|
#define IN6ADDR_TEREDOINITIALLINKLOCALADDRESS_INIT { \
|
|
0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
|
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe \
|
|
}
|
|
|
|
//
|
|
// 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' \
|
|
}
|
|
|
|
//
|
|
// 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 \
|
|
}
|
|
|
|
#define IN6ADDR_LINKLOCALPREFIX_INIT { 0xfe, 0x80, }
|
|
|
|
#define IN6ADDR_MULTICASTPREFIX_INIT { 0xff, 0x00, }
|
|
|
|
#define IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_INIT { \
|
|
0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
|
0x00, 0x00, 0x00, 0x01, 0xff, \
|
|
}
|
|
|
|
#define IN6ADDR_V4MAPPEDPREFIX_INIT { \
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
|
0x00, 0x00, 0xff, 0xff, \
|
|
}
|
|
|
|
#define IN6ADDR_6TO4PREFIX_INIT { 0x20, 0x02, }
|
|
|
|
#define IN6ADDR_TEREDOPREFIX_INIT { 0x20, 0x01, 0x00, 0x00, }
|
|
|
|
#define IN6ADDR_TEREDOPREFIX_INIT_OLD { 0x3f, 0xfe, 0x83, 0x1f, }
|
|
|
|
#define IN6ADDR_LINKLOCALPREFIX_LENGTH 64
|
|
|
|
#define IN6ADDR_MULTICASTPREFIX_LENGTH 8
|
|
|
|
#define IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_LENGTH 104
|
|
|
|
#define IN6ADDR_V4MAPPEDPREFIX_LENGTH 96
|
|
|
|
#define IN6ADDR_6TO4PREFIX_LENGTH 16
|
|
|
|
#define 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)
|
|
{
|
|
__int64 UNALIGNED *a;
|
|
__int64 UNALIGNED *b;
|
|
|
|
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));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
WS2TCPIP_INLINE
|
|
BOOLEAN
|
|
IN6_IS_ADDR_MULTICAST(CONST IN6_ADDR *a)
|
|
{
|
|
return (BOOLEAN)(a->s6_bytes[0] == 0xff);
|
|
}
|
|
|
|
//
|
|
// 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));
|
|
}
|
|
|
|
//
|
|
// 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));
|
|
}
|
|
|
|
//
|
|
// 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));
|
|
}
|
|
|
|
//
|
|
// 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));
|
|
}
|
|
|
|
WS2TCPIP_INLINE
|
|
BOOLEAN
|
|
IN6_IS_ADDR_LINKLOCAL(CONST IN6_ADDR *a)
|
|
{
|
|
return (BOOLEAN)((a->s6_bytes[0] == 0xfe) &&
|
|
((a->s6_bytes[1] & 0xc0) == 0x80));
|
|
}
|
|
|
|
WS2TCPIP_INLINE
|
|
BOOLEAN
|
|
IN6_IS_ADDR_SITELOCAL(CONST IN6_ADDR *a)
|
|
{
|
|
return (BOOLEAN)((a->s6_bytes[0] == 0xfe) &&
|
|
((a->s6_bytes[1] & 0xc0) == 0xc0));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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))));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
WS2TCPIP_INLINE
|
|
VOID
|
|
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));
|
|
}
|
|
|
|
WS2TCPIP_INLINE
|
|
VOID
|
|
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;
|
|
}
|
|
|
|
WS2TCPIP_INLINE
|
|
VOID
|
|
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;
|
|
}
|
|
|
|
WS2TCPIP_INLINE
|
|
VOID
|
|
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;
|
|
}
|
|
|
|
WS2TCPIP_INLINE
|
|
BOOLEAN
|
|
IN6ADDR_ISANY(CONST SOCKADDR_IN6 *a)
|
|
{
|
|
WS2IPDEF_ASSERT(a->sin6_family == AF_INET6);
|
|
return IN6_IS_ADDR_UNSPECIFIED(&a->sin6_addr);
|
|
}
|
|
|
|
WS2TCPIP_INLINE
|
|
BOOLEAN
|
|
IN6ADDR_ISLOOPBACK(CONST SOCKADDR_IN6 *a)
|
|
{
|
|
WS2IPDEF_ASSERT(a->sin6_family == AF_INET6);
|
|
return IN6_IS_ADDR_LOOPBACK(&a->sin6_addr);
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|
|
#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
|
|
|
|
//
|
|
// Protocol independent ioctls for setting and retrieving multicast filters.
|
|
//
|
|
#define SIOCSMSFILTER _IOW('t', 126, ULONG)
|
|
#define SIOCGMSFILTER _IOW('t', 127 | IOC_IN, ULONG)
|
|
|
|
#if (NTDDI_VERSION >= NTDDI_VISTASP1)
|
|
|
|
#define IDEAL_SEND_BACKLOG_IOCTLS
|
|
|
|
//
|
|
// 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)
|
|
|
|
#endif
|
|
|
|
//
|
|
// Protocol independent multicast source filter options.
|
|
//
|
|
#define MCAST_JOIN_GROUP 41 // Join all sources for a group.
|
|
#define MCAST_LEAVE_GROUP 42 // Drop all sources for a group.
|
|
#define MCAST_BLOCK_SOURCE 43 // Block IP group/source.
|
|
#define MCAST_UNBLOCK_SOURCE 44 // Unblock IP group/source.
|
|
#define MCAST_JOIN_SOURCE_GROUP 45 // Join IP group/source.
|
|
#define MCAST_LEAVE_SOURCE_GROUP 46 // Leave IP group/source.
|
|
|
|
//
|
|
// Definitions of MCAST_INCLUDE and MCAST_EXCLUDE for multicast source filter.
|
|
//
|
|
typedef enum {
|
|
MCAST_INCLUDE = 0,
|
|
MCAST_EXCLUDE
|
|
} MULTICAST_MODE_TYPE;
|
|
|
|
//
|
|
// Structure for IP_MREQ (used by IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP).
|
|
//
|
|
typedef struct ip_mreq {
|
|
IN_ADDR imr_multiaddr; // IP multicast address of group.
|
|
IN_ADDR imr_interface; // Local IP address of interface.
|
|
} IP_MREQ, *PIP_MREQ;
|
|
|
|
//
|
|
// Structure for IP_MREQ_SOURCE (used by IP_BLOCK_SOURCE, IP_UNBLOCK_SOURCE
|
|
// etc.).
|
|
//
|
|
typedef struct ip_mreq_source {
|
|
IN_ADDR imr_multiaddr; // IP multicast address of group.
|
|
IN_ADDR imr_sourceaddr; // IP address of source.
|
|
IN_ADDR imr_interface; // Local IP address of interface.
|
|
} IP_MREQ_SOURCE, *PIP_MREQ_SOURCE;
|
|
|
|
//
|
|
// Structure for IP_MSFILTER (used by SIOCSIPMSFILTER and SIOCGIPMSFILTER).
|
|
//
|
|
typedef struct ip_msfilter {
|
|
IN_ADDR imsf_multiaddr; // IP multicast address of group.
|
|
IN_ADDR imsf_interface; // Local IP address of interface.
|
|
MULTICAST_MODE_TYPE imsf_fmode; // Filter mode.
|
|
ULONG imsf_numsrc; // Number of sources in src_list.
|
|
IN_ADDR imsf_slist[1]; // Start of source list.
|
|
} IP_MSFILTER, *PIP_MSFILTER;
|
|
|
|
#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.
|
|
//
|
|
#define IPV6_HOPOPTS 1 // Set/get IPv6 hop-by-hop options.
|
|
#define IPV6_HDRINCL 2 // Header is included with data.
|
|
#define IPV6_UNICAST_HOPS 4 // IP unicast hop limit.
|
|
#define IPV6_MULTICAST_IF 9 // IP multicast interface.
|
|
#define IPV6_MULTICAST_HOPS 10 // IP multicast hop limit.
|
|
#define IPV6_MULTICAST_LOOP 11 // IP multicast loopback.
|
|
#define IPV6_ADD_MEMBERSHIP 12 // Add an IP group membership.
|
|
#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
|
|
#define IPV6_DROP_MEMBERSHIP 13 // Drop an IP group membership.
|
|
#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
|
|
#define IPV6_DONTFRAG 14 // Don't fragment IP datagrams.
|
|
#define IPV6_PKTINFO 19 // Receive packet information.
|
|
#define IPV6_HOPLIMIT 21 // Receive packet hop limit.
|
|
#define IPV6_PROTECTION_LEVEL 23 // Set/get IPv6 protection level.
|
|
#define IPV6_RECVIF 24 // Receive arrival interface.
|
|
#define IPV6_RECVDSTADDR 25 // Receive destination address.
|
|
#define IPV6_CHECKSUM 26 // Offset to checksum for raw IP socket send.
|
|
#define IPV6_V6ONLY 27 // Treat wildcard bind as AF_INET6-only.
|
|
#define IPV6_IFLIST 28 // Enable/Disable an interface list.
|
|
#define IPV6_ADD_IFLIST 29 // Add an interface list entry.
|
|
#define IPV6_DEL_IFLIST 30 // Delete an interface list entry.
|
|
#define IPV6_UNICAST_IF 31 // IP unicast interface.
|
|
#define IPV6_RTHDR 32 // Set/get IPv6 routing header.
|
|
#define IPV6_RECVRTHDR 38 // Receive the routing header.
|
|
#define IPV6_TCLASS 39 // Packet traffic class.
|
|
#define IPV6_RECVTCLASS 40 // Receive packet traffic class.
|
|
|
|
#define IP_UNSPECIFIED_HOP_LIMIT -1
|
|
|
|
#define IP_PROTECTION_LEVEL IPV6_PROTECTION_LEVEL
|
|
//
|
|
// Values of IPV6_PROTECTION_LEVEL.
|
|
//
|
|
#define PROTECTION_LEVEL_UNRESTRICTED 10 // For peer-to-peer apps.
|
|
#define PROTECTION_LEVEL_EDGERESTRICTED 20 // Same as unrestricted. Except for
|
|
// Teredo.
|
|
#define 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).
|
|
//
|
|
typedef struct ipv6_mreq {
|
|
IN6_ADDR ipv6mr_multiaddr; // IPv6 multicast address.
|
|
ULONG ipv6mr_interface; // Interface index.
|
|
} IPV6_MREQ, *PIPV6_MREQ;
|
|
|
|
#if (NTDDI_VERSION >= NTDDI_WINXP)
|
|
//
|
|
// Structure for GROUP_REQ used by protocol independent source filters
|
|
// (MCAST_JOIN_GROUP and MCAST_LEAVE_GROUP).
|
|
//
|
|
typedef struct group_req {
|
|
ULONG gr_interface; // Interface index.
|
|
SOCKADDR_STORAGE gr_group; // Multicast address.
|
|
} GROUP_REQ, *PGROUP_REQ;
|
|
|
|
//
|
|
// Structure for GROUP_SOURCE_REQ used by protocol independent source filters
|
|
// (MCAST_JOIN_SOURCE_GROUP, MCAST_LEAVE_SOURCE_GROUP etc.).
|
|
//
|
|
typedef struct group_source_req {
|
|
ULONG gsr_interface; // Interface index.
|
|
SOCKADDR_STORAGE gsr_group; // Group address.
|
|
SOCKADDR_STORAGE gsr_source; // Source address.
|
|
} GROUP_SOURCE_REQ, *PGROUP_SOURCE_REQ;
|
|
|
|
//
|
|
// Structure for GROUP_FILTER used by protocol independent source filters
|
|
// (SIOCSMSFILTER and SIOCGMSFILTER).
|
|
//
|
|
typedef struct group_filter {
|
|
ULONG gf_interface; // Interface index.
|
|
SOCKADDR_STORAGE gf_group; // Multicast address.
|
|
MULTICAST_MODE_TYPE gf_fmode; // Filter mode.
|
|
ULONG gf_numsrc; // Number of sources.
|
|
SOCKADDR_STORAGE gf_slist[1]; // Source address.
|
|
} GROUP_FILTER, *PGROUP_FILTER;
|
|
|
|
#define GROUP_FILTER_SIZE(numsrc) \
|
|
(sizeof(GROUP_FILTER) - sizeof(SOCKADDR_STORAGE) \
|
|
+ (numsrc) * sizeof(SOCKADDR_STORAGE))
|
|
#endif
|
|
|
|
//
|
|
// Structure for IP_PKTINFO option.
|
|
//
|
|
typedef struct in_pktinfo {
|
|
IN_ADDR ipi_addr; // Source/destination IPv4 address.
|
|
ULONG ipi_ifindex; // Send/receive interface index.
|
|
} IN_PKTINFO, *PIN_PKTINFO;
|
|
|
|
C_ASSERT(sizeof(IN_PKTINFO) == 8);
|
|
|
|
//
|
|
// Structure for IPV6_PKTINFO option.
|
|
//
|
|
typedef struct in6_pktinfo {
|
|
IN6_ADDR ipi6_addr; // Source/destination IPv6 address.
|
|
ULONG ipi6_ifindex; // Send/receive interface index.
|
|
} IN6_PKTINFO, *PIN6_PKTINFO;
|
|
|
|
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
|
|
//
|
|
#define INET_ADDRSTRLEN 22
|
|
#define 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.
|
|
//
|
|
#define TCP_OFFLOAD_NO_PREFERENCE 0
|
|
#define TCP_OFFLOAD_NOT_PREFERRED 1
|
|
#define TCP_OFFLOAD_PREFERRED 2
|
|
|
|
// TCP_NODELAY 0x0001
|
|
#define TCP_EXPEDITED_1122 0x0002
|
|
#define TCP_KEEPALIVE 3
|
|
#define TCP_MAXSEG 4
|
|
#define TCP_MAXRT 5
|
|
#define TCP_STDURG 6
|
|
#define TCP_NOURG 7
|
|
#define TCP_ATMARK 8
|
|
#define TCP_NOSYNRETRIES 9
|
|
#define TCP_TIMESTAMPS 10
|
|
#define TCP_OFFLOAD_PREFERENCE 11
|
|
#define TCP_CONGESTION_ALGORITHM 12
|
|
#define TCP_DELAY_FIN_ACK 13
|
|
|
|
#ifdef _PREFAST_
|
|
#pragma prefast(pop)
|
|
#endif
|
|
|
|
#pragma warning(pop)
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|