using System;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using Vanara.InteropServices;
#pragma warning disable IDE1006 // Naming Styles
namespace Vanara.PInvoke
{
public static partial class Ws2_32
{
/// Flags that indicate options used in the GetAddrInfoW function.
[PInvokeData("ws2def.h", MSDNShortId = "a4896eac-68ae-4a08-8647-36be65fe4478")]
[Flags]
public enum ADDRINFO_FLAGS : uint
{
/// The socket address will be used in a call to the bindfunction.
AI_PASSIVE = 0x01,
/// The canonical name is returned in the first ai_canonname member.
AI_CANONNAME = 0x02,
/// The nodename parameter passed to the GetAddrInfoW function must be a numeric string.
AI_NUMERICHOST = 0x04,
/// Servicename must be a numeric port number.
AI_NUMERICSERV = 0x08,
///
/// If this bit is set, a request is made for IPv6 addresses and IPv4 addresses with AI_V4MAPPED.
/// This option is supported on Windows Vista and later.
///
AI_ALL = 0x0100,
///
/// The GetAddrInfoW will resolve only if a global address is configured. The IPv6 and IPv4 loopback address is not considered a
/// valid global address. This option is only supported on Windows Vista and later.
///
AI_ADDRCONFIG = 0x0400,
///
/// If the GetAddrInfoW request for an IPv6 addresses fails, a name service request is made for IPv4 addresses and these
/// addresses are converted to IPv4-mapped IPv6 address format.
/// This option is supported on Windows Vista and later.
///
AI_V4MAPPED = 0x0800,
///
/// The address information can be from a non-authoritative namespace provider.
/// This option is only supported on Windows Vista and later for the NS_EMAIL namespace.
///
AI_NON_AUTHORITATIVE = 0x04000,
///
/// The address information is from a secure channel.
/// This option is only supported on Windows Vista and later for the NS_EMAIL namespace.
///
AI_SECURE = 0x08000,
///
/// The address information is for a preferred name for a user.
/// This option is only supported on Windows Vista and later for the NS_EMAIL namespace.
///
AI_RETURN_PREFERRED_NAMES = 0x010000,
///
/// If a flat name (single label) is specified, GetAddrInfoW will return the fully qualified domain name that the name
/// eventually resolved to. The fully qualified domain name is returned in the ai_canonname member.
///
/// This is different than AI_CANONNAME bit flag that returns the canonical name registered in DNS which may be different than
/// the fully qualified domain name that the flat name resolved to.
///
///
/// Only one of the AI_FQDN and AI_CANONNAME bits can be set. The GetAddrInfoW function will fail if both flags are present with EAI_BADFLAGS.
///
/// This option is supported on Windows 7, Windows Server 2008 R2, and later.
///
AI_FQDN = 0x00020000,
///
/// A hint to the namespace provider that the hostname being queried is being used in a file share scenario. The namespace
/// provider may ignore this hint.
/// This option is supported on Windows 7, Windows Server 2008 R2, and later.
///
AI_FILESERVER = 0x00040000,
///
/// Disable the automatic International Domain Name encoding using Punycode in the name resolution functions called by the
/// GetAddrInfoW function.
/// This option is supported on Windows 8, Windows Server 2012, and later.
///
AI_DISABLE_IDN_ENCODING = 0x00080000,
/// Indicates this is extended ADDRINFOEX(2/..) struct
AI_EXTENDED = 0x80000000,
/// Request resolution handle
AI_RESOLUTION_HANDLE = 0x40000000,
}
/// Protocols. The IPv6 defines are specified in RFC 2292.
[PInvokeData("ws2def.h")]
public enum IPPROTO
{
///
IPPROTO_IP = 0,
///
IPPROTO_HOPOPTS = 0,
///
/// The Internet Control Message Protocol (ICMP). This is a possible value when the af parameter is AF_UNSPEC, AF_INET, or
/// AF_INET6 and the type parameter is SOCK_RAW or unspecified.
/// This protocol value is supported on Windows XP and later.
///
IPPROTO_ICMP = 1,
///
/// The Internet Group Management Protocol (IGMP). This is a possible value when the af parameter is AF_UNSPEC, AF_INET, or
/// AF_INET6 and the type parameter is SOCK_RAW or unspecified.
/// This protocol value is supported on Windows XP and later.
///
IPPROTO_IGMP = 2,
///
/// The Bluetooth Radio Frequency Communications (Bluetooth RFCOMM) protocol. This is a possible value when the af parameter is
/// AF_BTH and the type parameter is SOCK_STREAM.
/// This protocol value is supported on Windows XP with SP2 or later.
///
IPPROTO_GGP = 3,
///
IPPROTO_IPV4 = 4,
///
IPPROTO_ST = 5,
///
/// The Transmission Control Protocol (TCP). This is a possible value when the af parameter is AF_INET or AF_INET6 and the type
/// parameter is SOCK_STREAM.
///
IPPROTO_TCP = 6,
///
IPPROTO_CBT = 7,
///
IPPROTO_EGP = 8,
///
IPPROTO_IGP = 9,
///
IPPROTO_PUP = 12,
///
/// The User Datagram Protocol (UDP). This is a possible value when the af parameter is AF_INET or AF_INET6 and the type
/// parameter is SOCK_DGRAM.
///
IPPROTO_UDP = 17,
///
IPPROTO_IDP = 22,
///
IPPROTO_RDP = 27,
///
IPPROTO_IPV6 = 41,
///
IPPROTO_ROUTING = 43,
///
IPPROTO_FRAGMENT = 44,
///
IPPROTO_ESP = 50,
///
IPPROTO_AH = 51,
///
/// The Internet Control Message Protocol Version 6 (ICMPv6). This is a possible value when the af parameter is AF_UNSPEC,
/// AF_INET, or AF_INET6 and the type parameter is SOCK_RAW or unspecified.
/// This protocol value is supported on Windows XP and later.
///
IPPROTO_ICMPV6 = 58,
///
IPPROTO_NONE = 59,
///
IPPROTO_DSTOPTS = 60,
///
IPPROTO_ND = 77,
///
IPPROTO_ICLFXBM = 78,
///
IPPROTO_PIM = 103,
///
/// The PGM protocol for reliable multicast. This is a possible value when the af parameter is AF_INET and the type parameter is
/// SOCK_RDM. On the Windows SDK released for Windows Vista and later, this protocol is also called IPPROTO_PGM.
/// This protocol value is only supported if the Reliable Multicast Protocol is installed.
///
IPPROTO_PGM = 113,
///
IPPROTO_L2TP = 115,
///
IPPROTO_SCTP = 132,
///
IPPROTO_RAW = 255,
///
IPPROTO_MAX = 256,
///
IPPROTO_RESERVED_RAW = 257,
///
IPPROTO_RESERVED_IPSEC = 258,
///
IPPROTO_RESERVED_IPSECOFFLOAD = 259,
///
IPPROTO_RESERVED_WNV = 260,
///
IPPROTO_RESERVED_MAX = 261
}
/// Customize processing of the GetNameInfoW function.
[PInvokeData("ws2def.h", MSDNShortId = "5630a49a-c182-440c-ad54-6ff3ba4274c6")]
public enum NI
{
/// Results in local hosts having only their Relative Distinguished Name (RDN) returned in the pNodeBuffer parameter.
NI_NOFQDN = 0x01 /* Only return nodename portion for local hosts */,
///
/// Returns the numeric form of the host name instead of its name. The numeric form of the host name is also returned if the
/// host name cannot be resolved by DNS.
///
NI_NUMERICHOST = 0x02 /* Return numeric form of the host's address */,
/// A host name that cannot be resolved by the DNS results in an error.
NI_NAMEREQD = 0x04 /* Error if the host's name not in DNS */,
///
/// Returns the port number of the service instead of its name. Also, if a host name is not found for an IP address (127.0.0.2,
/// for example), the hostname is returned as the IP address.
///
NI_NUMERICSERV = 0x08 /* Return numeric form of the service (port #) */,
///
/// Indicates that the service is a datagram service. This flag is necessary for the few services that provide different port
/// numbers for UDP and TCP service.
///
NI_DGRAM = 0x10 /* Service is a datagram service */,
}
/// The scope of the IPv6 transport address.
[PInvokeData("ws2def.h")]
public enum SCOPE_LEVEL
{
/// The transport address has interface-local scope.
ScopeLevelInterface = 1,
/// The transport address has link-local scope.
ScopeLevelLink = 2,
/// The transport address has subnet-local scope.
ScopeLevelSubnet = 3,
/// The transport address has admin-local scope.
ScopeLevelAdmin = 4,
/// The transport address has site-local scope.
ScopeLevelSite = 5,
/// The transport address has organization-local scope.
ScopeLevelOrganization = 8,
/// The transport address has global scope.
ScopeLevelGlobal = 14,
/// The scope level count.
ScopeLevelCount = 16
}
/// Gets the size, in bytes, of a given a number of address.
/// The address count.
/// The size, in bytes, required to hold the structure. This does not include allocation for the addresses pointed to by each .
[PInvokeData("ws2def.h")]
public static SizeT SIZEOF_SOCKET_ADDRESS_LIST(SizeT AddressCount) => Marshal.OffsetOf(typeof(SOCKET_ADDRESS_LIST), "Address").ToInt32() + Marshal.SizeOf(typeof(SOCKET_ADDRESS)) * AddressCount;
#if x64
public static readonly SizeT MAX_NATURAL_ALIGNMENT = sizeof(ulong);
#else
/// The maximum natural alignment
public static readonly SizeT MAX_NATURAL_ALIGNMENT = sizeof(uint);
#endif
[StructLayout(LayoutKind.Sequential)]
private struct AlignedStruct where T : struct
{
private readonly byte b;
public readonly T type;
}
/// Returns the alignment in bytes of the specified type as a value of type .
/// The type for which to get the alignment.
/// The alignment in bytes of the specified type.
public static SizeT TYPE_ALIGNMENT() where T : struct => Marshal.OffsetOf(typeof(AlignedStruct), "type").ToInt64();
/// Returns the alignment in bytes of padding as a value of type .
/// The padding length.
/// The alignment in bytes.
public static SizeT WSA_CMSGDATA_ALIGN(SizeT length) => (length + MAX_NATURAL_ALIGNMENT-1) & (~(MAX_NATURAL_ALIGNMENT-1));
/// Returns the alignment in bytes of WSACMSGHDR with padding as a value of type .
/// The padding length.
/// The alignment in bytes.
public static SizeT WSA_CMSGHDR_ALIGN(SizeT length) =>
(length + TYPE_ALIGNMENT()-1) & (~(TYPE_ALIGNMENT()-1));
///
/// Returns a pointer to the first byte of data (what is referred to as the cmsg_data member though it is not defined in the structure).
///
/// The WSACMSGHDR instance.
/// The pointer.
public static unsafe byte* WSA_CMSG_DATA(WSACMSGHDR* cmsg) => (byte*)cmsg + WSA_CMSGDATA_ALIGN(Marshal.SizeOf(typeof(WSACMSGHDR)));
///
/// Returns the first ancillary data object, or a null if there is no ancillary data in the control buffer of the WSAMSG structure.
///
/// The message.
/// The first ancillary data object, or a null.
public static unsafe WSACMSGHDR* WSA_CMSG_FIRSTHDR(in WSAMSG msg) =>
(msg.Control.len >= Marshal.SizeOf(typeof(WSACMSGHDR))) ? (WSACMSGHDR*)msg.Control.buf : default;
/// Returns the value to store in cmsg_len given the amount of data.
/// The length.
/// The data length.
public static SizeT WSA_CMSG_LEN(SizeT length) => WSA_CMSGDATA_ALIGN(Marshal.SizeOf(typeof(WSACMSGHDR))) + length;
/// Returns the next ancillary data object, or a null if there are no more data objects.
/// The message.
/// The message header.
/// The next header.
public static unsafe WSACMSGHDR* WSA_CMSG_NXTHDR(in WSAMSG msg, WSACMSGHDR* cmsg)
{
if (cmsg is null)
return WSA_CMSG_FIRSTHDR(msg);
unsafe
{
var len = (byte*)cmsg + WSA_CMSGHDR_ALIGN(cmsg->cmsg_len) + Marshal.SizeOf(typeof(WSACMSGHDR));
return len > (byte*)msg.Control.buf + msg.Control.len ? null : (WSACMSGHDR*)((byte*)cmsg + WSA_CMSGHDR_ALIGN(cmsg->cmsg_len));
}
}
/// Returns total size of an ancillary data object given the amount of data. Used to allocate the correct amount of space.
/// The length.
/// Total size
public static SizeT WSA_CMSG_SPACE(SizeT length) => WSA_CMSGDATA_ALIGN(Marshal.SizeOf(typeof(WSACMSGHDR)) + WSA_CMSGHDR_ALIGN(length));
///
/// The addrinfoex2 structure is used by the GetAddrInfoEx function to hold host address information when both a canonical name and
/// a fully qualified domain name have been requested.
///
// https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-addrinfoex2w typedef struct addrinfoex2W { int ai_flags; int
// ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; PWSTR ai_canonname; struct sockaddr *ai_addr; void *ai_blob;
// size_t ai_bloblen; LPGUID ai_provider; struct addrinfoex2W *ai_next; int ai_version; PWSTR ai_fqdn; } ADDRINFOEX2W,
// *PADDRINFOEX2W, *LPADDRINFOEX2W;
[PInvokeData("ws2def.h", MSDNShortId = "9CB33347-A838-473D-B5CD-1149D6632CF2")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct ADDRINFOEX2W
{
///
/// Flags that indicate options used in the GetAddrInfoEx function.
///
/// Supported values for the ai_flags member are defined in the Winsock2.h include file and can be a combination of the
/// following options.
///
///
///
/// Value
/// Meaning
///
/// -
/// AI_PASSIVE 0x01
/// The socket address will be used in a call to the bindfunction.
///
/// -
/// AI_CANONNAME 0x02
/// The canonical name is returned in the first ai_canonname member.
///
/// -
/// AI_NUMERICHOST 0x04
/// The nodename parameter passed to the GetAddrInfoEx function must be a numeric string.
///
/// -
/// AI_ALL 0x0100
///
/// If this bit is set, a request is made for IPv6 addresses and IPv4 addresses with AI_V4MAPPED. This option is supported on
/// Windows Vista and later.
///
///
/// -
/// AI_ADDRCONFIG 0x0400
///
/// The GetAddrInfoEx will resolve only if a global address is configured. The IPv6 and IPv4 loopback address is not considered
/// a valid global address. This option is supported on Windows Vista and later.
///
///
/// -
/// AI_V4MAPPED 0x0800
///
/// If the GetAddrInfoEx request for an IPv6 addresses fails, a name service request is made for IPv4 addresses and these
/// addresses are converted to IPv4-mapped IPv6 address format. This option is supported on Windows Vista and later.
///
///
/// -
/// AI_NON_AUTHORITATIVE 0x04000
///
/// The address information is from non-authoritative results. When this option is set in the pHints parameter of GetAddrInfoEx,
/// the NS_EMAIL namespace provider returns both authoritative and non-authoritative results. If this option is not set, then
/// only authoritative results are returned. This option is only supported on Windows Vista and later for the NS_EMAIL namespace.
///
///
/// -
/// AI_SECURE 0x08000
///
/// The address information is from a secure channel. If the AI_SECURE bit is set, the NS_EMAIL namespace provider will return
/// results that were obtained with enhanced security to minimize possible spoofing. When this option is set in the pHints
/// parameter of GetAddrInfoEx, the NS_EMAIL namespace provider returns only results that were obtained with enhanced security
/// to minimize possible spoofing. This option is only supported on Windows Vista and later for the NS_EMAIL namespace.
///
///
/// -
/// AI_RETURN_PREFERRED_NAMES 0x010000
///
/// The address information is for a preferred names for publication with a specific namespace. When this option is set in the
/// pHints parameter of GetAddrInfoEx, no name should be provided in the pName parameter and the NS_EMAIL namespace provider
/// will return preferred names for publication. This option is only supported on Windows Vista and later for the NS_EMAIL namespace.
///
///
/// -
/// AI_FQDN 0x00020000
///
/// The fully qualified domain name is returned in the first ai_fqdn member. When this option is set in the pHints parameter of
/// GetAddrInfoEx and a flat name (single label) is specified in the pName parameter, the fully qualified domain name that the
/// name eventually resolved to will be returned. This option is supported on Windows 7, Windows Server 2008 R2, and later.
///
///
/// -
/// AI_FILESERVER 0x00040000
///
/// A hint to the namespace provider that the hostname being queried is being used in a file share scenario. The namespace
/// provider may ignore this hint. This option is supported on Windows 7, Windows Server 2008 R2, and later.
///
///
/// -
/// AI_DISABLE_IDN_ENCODING 0x00080000
///
/// Disable the automatic International Domain Name encoding using Punycode in the name resolution functions called by the
/// GetAddrInfoEx function. This option is supported on Windows 8, Windows Server 2012, and later.
///
///
///
///
public ADDRINFO_FLAGS ai_flags;
private uint _ai_family;
///
/// Type: int
/// The address family. Possible values for the address family are defined in the Winsock2.h include file.
///
/// On the Windows SDK released for Windows Vista and later,, the organization of header files has changed and the possible
/// values for the address family are defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically
/// included in Winsock2.h, and should never be used directly.
///
///
/// The values currently supported are AF_INET or AF_INET6, which are the Internet address family formats for IPv4
/// and IPv6. Other options for address family ( AF_NETBIOS for use with NetBIOS, for example) are supported if a Windows
/// Sockets service provider for the address family is installed. Note that the values for the AF_ address family and PF_
/// protocol family constants are identical (for example, AF_UNSPEC and PF_UNSPEC), so either constant can be used.
///
/// The table below lists common values for the address family although many other values are possible.
///
///
/// Value
/// Meaning
///
/// -
/// AF_UNSPEC 0
/// The address family is unspecified.
///
/// -
/// AF_INET 2
/// The Internet Protocol version 4 (IPv4) address family.
///
/// -
/// AF_NETBIOS 17
/// The NetBIOS address family. This address family is only supported if a Windows Sockets provider for NetBIOS is installed.
///
/// -
/// AF_INET6 23
/// The Internet Protocol version 6 (IPv6) address family.
///
/// -
/// AF_IRDA 26
///
/// The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared
/// port and driver installed.
///
///
/// -
/// AF_BTH 32
///
/// The Bluetooth address family. This address family is only supported if a Bluetooth adapter is installed on Windows Server
/// 2003 or later.
///
///
///
///
public ADDRESS_FAMILY ai_family { get => (ADDRESS_FAMILY)_ai_family; set => _ai_family = (ushort)value; }
///
/// The socket type. Possible values for the socket type are defined in the Winsock2.h include file.
/// The following table lists the possible values for the socket type supported for Windows Sockets 2:
///
///
/// Value
/// Meaning
///
/// -
/// SOCK_STREAM 1
///
/// Provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. Uses the
/// Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6). If the ai_family member is
/// AF_IRDA, then SOCK_STREAM is the only supported socket type.
///
///
/// -
/// SOCK_DGRAM 2
///
/// Supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. Uses the User
/// Datagram Protocol (UDP) for the Internet address family (AF_INET or AF_INET6).
///
///
/// -
/// SOCK_RAW 3
///
/// Provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To manipulate the IPv4
/// header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the IPV6_HDRINCL socket
/// option must be set on the socket.
///
///
/// -
/// SOCK_RDM 4
///
/// Provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) multicast protocol
/// implementation in Windows, often referred to as reliable multicast programming.
///
///
/// -
/// SOCK_SEQPACKET 5
/// Provides a pseudo-stream packet based on datagrams.
///
///
///
/// In Windows Sockets 2, new socket types were introduced. An application can dynamically discover the attributes of each
/// available transport protocol through the WSAEnumProtocols function. So an application can determine the possible socket type
/// and protocol options for an address family and use this information when specifying this parameter. Socket type definitions
/// in the Winsock2.h and Ws2def.h header files will be periodically updated as new socket types, address families, and
/// protocols are defined.
///
/// In Windows Sockets 1.1, the only possible socket types are SOCK_DATAGRAM and SOCK_STREAM.
///
public SOCK ai_socktype;
///
///
/// The protocol type. The possible options are specific to the address family and socket type specified. Possible values for
/// the ai_protocol are defined in Winsock2.h and the Wsrm.h header files.
///
///
/// On the Windows SDK released for Windows Vista and later,, the organization of header files has changed and this member can
/// be one of the values from the IPPROTO enumeration type defined in the Ws2def.h header file. Note that the Ws2def.h
/// header file is automatically included in Winsock2.h, and should never be used directly.
///
///
/// If a value of 0 is specified for ai_protocol, the caller does not wish to specify a protocol and the service provider
/// will choose the ai_protocol to use. For protocols other than IPv4 and IPv6, set ai_protocol to zero.
///
/// The following table lists common values for the ai_protocol member although many other values are possible.
///
///
/// Value
/// Meaning
///
/// -
/// IPPROTO_TCP 6
///
/// The Transmission Control Protocol (TCP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the
/// ai_socktype member is SOCK_STREAM.
///
///
/// -
/// IPPROTO_UDP 17
///
/// The User Datagram Protocol (UDP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the type
/// parameter is SOCK_DGRAM.
///
///
/// -
/// IPPROTO_RM 113
///
/// The PGM protocol for reliable multicast. This is a possible value when the ai_family member is AF_INET and the ai_socktype
/// member is SOCK_RDM. On the Windows SDK released for Windows Vista and later, this value is also called IPPROTO_PGM.
///
///
///
/// If the ai_family member is AF_IRDA, then the ai_protocol must be 0.
///
public IPPROTO ai_protocol;
/// The length, in bytes, of the buffer pointed to by the ai_addr member.
public SizeT ai_addrlen;
/// The canonical name for the host.
public StrPtrUni ai_canonname;
///
/// A pointer to a sockaddr structure. The ai_addr member in each returned addrinfoex2 structure points to a
/// filled-in socket address structure. The length, in bytes, of each returned addrinfoex2 structure is specified in the
/// ai_addrlen member.
///
public IntPtr ai_addr;
///
/// A pointer to data that is used to return provider-specific namespace information that is associated with the name beyond a
/// list of addresses. The length, in bytes, of the buffer pointed to by ai_blob must be specified in the
/// ai_bloblen member.
///
public IntPtr ai_blob;
/// The length, in bytes, of the ai_blob member.
public SizeT ai_bloblen;
/// A pointer to the GUID of a specific namespace provider.
public GuidPtr ai_provider;
///
/// A pointer to the next structure in a linked list. This parameter is set to NULL in the last addrinfoex2
/// structure of a linked list.
///
public IntPtr ai_next;
/// The version number of this structure. The value currently used for this version of the structure is 2.
public int ai_version;
/// The fully qualified domain name for the host.
public StrPtrUni ai_fqdn;
///
/// Type: struct sockaddr*
///
/// A pointer to a sockaddr structure. The ai_addr member in each returned ADDRINFOW structure points to a filled-in
/// socket address structure. The length, in bytes, of each returned ADDRINFOW structure is specified in the
/// ai_addrlen member.
///
///
public SOCKADDR addr => new(ai_addr, false, ai_addrlen);
///
public override string ToString() => $"{ai_fqdn}::{ai_canonname}:{ai_flags},{ai_family},{ai_socktype},{ai_protocol},{addr}";
}
/// The addrinfoex structure is used by the GetAddrInfoEx function to hold host address information.
///
///
/// The addrinfoex structure is used by the GetAddrInfoEx function to hold host address information. The addrinfoex
/// structure is an enhanced version of the addrinfo and addrinfoW structures. The extra structure members are for blob data and the
/// GUID for the namespace provider. The blob data is used to return additional provider-specific namespace information associated
/// with a name. The format of data in the ai_blob member is specific to a particular namespace provider. Currently, blob
/// data is used by the NS_EMAIL namespace provider to supply additional information.
///
///
/// The addrinfoex structure is an enhanced version of the addrinfo and addrinfoW structure used with GetAddrInfoEx function.
/// The GetAddrInfoEx function allows specifying the namespace provider to resolve the query. For use with the IPv6 and IPv4
/// protocol, name resolution can be by the Domain Name System (DNS), a local hosts file, an email provider (the NS_EMAIL
/// namespace), or by other naming mechanisms.
///
///
/// When UNICODE or _UNICODE is defined, addrinfoex is defined to addrinfoexW, the Unicode version of this structure.
/// The string parameters are defined to the PWSTR data type and the addrinfoexW structure is used.
///
///
/// When UNICODE or _UNICODE is not defined, addrinfoex is defined to addrinfoexA, the ANSI version of this structure.
/// The string parameters are of the PCSTR data type and the addrinfoexA structure is used.
///
///
/// Upon a successful call to GetAddrInfoEx, a linked list of addrinfoex structures is returned in the ppResult parameter
/// passed to the GetAddrInfoEx function. The list can be processed by following the pointer provided in the ai_next
/// member of each returned addrinfoex structure until a NULL pointer is encountered. In each returned
/// addrinfoex structure, the ai_family, ai_socktype, and ai_protocol members correspond to respective
/// arguments in a socket or WSASocket function call. Also, the ai_addr member in each returned addrinfoex structure
/// points to a filled-in socket address structure, the length of which is specified in its ai_addrlen member.
///
/// Examples
/// The following example demonstrates the use of the addrinfoex structure.
///
/// Note Ensure that the development environment targets the newest version of Ws2tcpip.h which includes structure and
/// function definitions for ADDRINFOEX and GetAddrInfoEx, respectively.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-addrinfoexa typedef struct addrinfoexA { int ai_flags; int
// ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; char *ai_canonname; struct sockaddr *ai_addr; void *ai_blob;
// size_t ai_bloblen; LPGUID ai_provider; struct addrinfoexA *ai_next; } ADDRINFOEXA, *PADDRINFOEXA, *LPADDRINFOEXA;
[PInvokeData("ws2def.h", MSDNShortId = "1077e03d-a1a4-45ab-a5d2-29a67e03f5df")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public unsafe struct ADDRINFOEXW
{
///
/// Type: int
/// Flags that indicate options used in the GetAddrInfoEx function.
///
/// Supported values for the ai_flags member are defined in the Winsock2.h include file and can be a combination of the
/// following options.
///
///
///
/// Value
/// Meaning
///
/// -
/// AI_PASSIVE 0x01
/// The socket address will be used in a call to the bindfunction.
///
/// -
/// AI_CANONNAME 0x02
///
/// The canonical name is returned in the first ai_canonname member. When both the AI_CANONNAME and AI_FQDN bits are set, an
/// addrinfoex2 structure is returned not the addrinfoex structure.
///
///
/// -
/// AI_NUMERICHOST 0x04
/// The nodename parameter passed to the GetAddrInfoEx function must be a numeric string.
///
/// -
/// AI_ALL 0x0100
///
/// If this bit is set, a request is made for IPv6 addresses and IPv4 addresses with AI_V4MAPPED. This option is supported on
/// Windows Vista and later.
///
///
/// -
/// AI_ADDRCONFIG 0x0400
///
/// The GetAddrInfoEx will resolve only if a global address is configured. The IPv6 and IPv4 loopback address is not considered
/// a valid global address. This option is only supported on Windows Vista and later.
///
///
/// -
/// AI_V4MAPPED 0x0800
///
/// If the GetAddrInfoEx request for an IPv6 addresses fails, a name service request is made for IPv4 addresses and these
/// addresses are converted to IPv4-mapped IPv6 address format. This option is supported on Windows Vista and later.
///
///
/// -
/// AI_NON_AUTHORITATIVE 0x04000
///
/// The address information is from non-authoritative results. When this option is set in the pHints parameter of GetAddrInfoEx,
/// the NS_EMAIL namespace provider returns both authoritative and non-authoritative results. If this option is not set, then
/// only authoritative results are returned. In the ppResults parameter returned by GetAddrInfoEx, this flag is set in the
/// ai_flags member of the addrinfoex structure for non-authoritative results. This option is only supported on Windows Vista
/// and later for the NS_EMAIL namespace.
///
///
/// -
/// AI_SECURE 0x08000
///
/// The address information is from a secure channel. If the AI_SECURE bit is set, the NS_EMAIL namespace provider will return
/// results that were obtained with enhanced security to minimize possible spoofing. When this option is set in the pHints
/// parameter of GetAddrInfoEx, the NS_EMAIL namespace provider returns only results that were obtained with enhanced security
/// to minimize possible spoofing. In the ppResults parameter returned by GetAddrInfoEx, this flag is set in the ai_flags member
/// of the addrinfoex structure for results returned with enhanced security to minimize possible spoofing. This option is only
/// supported on Windows Vista and later for the NS_EMAIL namespace.
///
///
/// -
/// AI_RETURN_PREFERRED_NAMES 0x010000
///
/// The address information is for a preferred names for publication with a specific namespace. When this option is set in the
/// pHints parameter of GetAddrInfoEx, no name should be provided in the pName parameter and the NS_EMAIL namespace provider
/// will return preferred names for publication. In the ppResults parameter returned by GetAddrInfoEx, this flag is set in the
/// ai_flags member of the addrinfoex structure for results returned for preferred names for publication. This option is only
/// supported on Windows Vista and later for the NS_EMAIL namespace.
///
///
/// -
/// AI_FQDN 0x00020000
///
/// The fully qualified domain name is returned in the first ai_canonicalname member. When this option is set in the pHints
/// parameter of GetAddrInfoEx and a flat name (single label) is specified in the pName parameter, the fully qualified domain
/// name that the name eventually resolved to will be returned. When both the AI_CANONNAME and AI_FQDN bits are set, an
/// addrinfoex2 structure is returned not the addrinfoex structure. This option is supported on Windows 7, Windows Server 2008
/// R2, and later.
///
///
/// -
/// AI_FILESERVER 0x00040000
///
/// A hint to the namespace provider that the hostname being queried is being used in a file share scenario. The namespace
/// provider may ignore this hint. This option is supported on Windows 7, Windows Server 2008 R2, and later.
///
///
/// -
/// AI_DISABLE_IDN_ENCODING 0x00080000
///
/// Disable the automatic International Domain Name encoding using Punycode in the name resolution functions called by the
/// GetAddrInfoEx function. This option is supported on Windows 8, Windows Server 2012, and later.
///
///
///
///
public ADDRINFO_FLAGS ai_flags;
private uint _ai_family;
///
/// Type: int
/// The address family. Possible values for the address family are defined in the Winsock2.h include file.
///
/// On the Windows SDK released for Windows Vista and later,, the organization of header files has changed and the possible
/// values for the address family are defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically
/// included in Winsock2.h, and should never be used directly.
///
///
/// The values currently supported are AF_INET or AF_INET6, which are the Internet address family formats for IPv4
/// and IPv6. Other options for address family ( AF_NETBIOS for use with NetBIOS, for example) are supported if a Windows
/// Sockets service provider for the address family is installed. Note that the values for the AF_ address family and PF_
/// protocol family constants are identical (for example, AF_UNSPEC and PF_UNSPEC), so either constant can be used.
///
/// The table below lists common values for the address family although many other values are possible.
///
///
/// Value
/// Meaning
///
/// -
/// AF_UNSPEC 0
/// The address family is unspecified.
///
/// -
/// AF_INET 2
/// The Internet Protocol version 4 (IPv4) address family.
///
/// -
/// AF_NETBIOS 17
/// The NetBIOS address family. This address family is only supported if a Windows Sockets provider for NetBIOS is installed.
///
/// -
/// AF_INET6 23
/// The Internet Protocol version 6 (IPv6) address family.
///
/// -
/// AF_IRDA 26
///
/// The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared
/// port and driver installed.
///
///
/// -
/// AF_BTH 32
///
/// The Bluetooth address family. This address family is only supported if a Bluetooth adapter is installed on Windows Server
/// 2003 or later.
///
///
///
///
public ADDRESS_FAMILY ai_family { get => (ADDRESS_FAMILY)_ai_family; set => _ai_family = (ushort)value; }
///
/// Type: int
/// The socket type. Possible values for the socket type are defined in the Winsock2.h include file.
/// The following table lists the possible values for the socket type supported for Windows Sockets 2:
///
///
/// Value
/// Meaning
///
/// -
/// SOCK_STREAM 1
///
/// Provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. Uses the
/// Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6). If the ai_family member is
/// AF_IRDA, then SOCK_STREAM is the only supported socket type.
///
///
/// -
/// SOCK_DGRAM 2
///
/// Supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. Uses the User
/// Datagram Protocol (UDP) for the Internet address family (AF_INET or AF_INET6).
///
///
/// -
/// SOCK_RAW 3
///
/// Provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To manipulate the IPv4
/// header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the IPV6_HDRINCL socket
/// option must be set on the socket.
///
///
/// -
/// SOCK_RDM 4
///
/// Provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) multicast protocol
/// implementation in Windows, often referred to as reliable multicast programming.
///
///
/// -
/// SOCK_SEQPACKET 5
/// Provides a pseudo-stream packet based on datagrams.
///
///
///
/// In Windows Sockets 2, new socket types were introduced. An application can dynamically discover the attributes of each
/// available transport protocol through the WSAEnumProtocols function. So an application can determine the possible socket type
/// and protocol options for an address family and use this information when specifying this parameter. Socket type definitions
/// in the Winsock2.h and Ws2def.h header files will be periodically updated as new socket types, address families, and
/// protocols are defined.
///
/// In Windows Sockets 1.1, the only possible socket types are SOCK_DATAGRAM and SOCK_STREAM.
///
public SOCK ai_socktype;
///
/// Type: int
///
/// The protocol type. The possible options are specific to the address family and socket type specified. Possible values for
/// the ai_protocol are defined in Winsock2.h and the Wsrm.h header files.
///
///
/// On the Windows SDK released for Windows Vista and later,, the organization of header files has changed and this member can
/// be one of the values from the IPPROTO enumeration type defined in the Ws2def.h header file. Note that the Ws2def.h
/// header file is automatically included in Winsock2.h, and should never be used directly.
///
///
/// If a value of 0 is specified for ai_protocol, the caller does not wish to specify a protocol and the service provider
/// will choose the ai_protocol to use. For protocols other than IPv4 and IPv6, set ai_protocol to zero.
///
/// The following table lists common values for the ai_protocol member although many other values are possible.
///
///
/// Value
/// Meaning
///
/// -
/// IPPROTO_TCP 6
///
/// The Transmission Control Protocol (TCP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the
/// ai_socktype member is SOCK_STREAM.
///
///
/// -
/// IPPROTO_UDP 17
///
/// The User Datagram Protocol (UDP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the type
/// parameter is SOCK_DGRAM.
///
///
/// -
/// IPPROTO_RM 113
///
/// The PGM protocol for reliable multicast. This is a possible value when the ai_family member is AF_INET and the ai_socktype
/// member is SOCK_RDM. On the Windows SDK released for Windows Vista and later, this value is also called IPPROTO_PGM.
///
///
///
/// If the ai_family member is AF_IRDA, then the ai_protocol must be 0.
///
public IPPROTO ai_protocol;
///
/// Type: size_t
/// The length, in bytes, of the buffer pointed to by the ai_addr member.
///
public SizeT ai_addrlen;
///
/// Type: PCTSTR
/// The canonical name for the host.
///
public StrPtrUni ai_canonname;
///
/// Type: struct sockaddr*
///
/// A pointer to a sockaddr structure. The ai_addr member in each returned addrinfoex structure points to a
/// filled-in socket address structure. The length, in bytes, of each returned addrinfoex structure is specified in the
/// ai_addrlen member.
///
///
public IntPtr ai_addr;
///
/// Type: void*
///
/// A pointer to data that is used to return provider-specific namespace information that is associated with the name beyond a
/// list of addresses. The length, in bytes, of the buffer pointed to by ai_blob must be specified in the
/// ai_bloblen member.
///
///
public IntPtr ai_blob;
///
/// Type: size_t
/// The length, in bytes, of the ai_blob member.
///
public SizeT ai_bloblen;
///
/// Type: LPGUID
/// A pointer to the GUID of a specific namespace provider.
///
public Guid* ai_provider;
///
/// Type: struct addrinfoex*
///
/// A pointer to the next structure in a linked list. This parameter is set to NULL in the last addrinfoex
/// structure of a linked list.
///
///
public IntPtr ai_next;
///
/// Type: struct sockaddr*
///
/// A pointer to a sockaddr structure. The ai_addr member in each returned ADDRINFOW structure points to a filled-in
/// socket address structure. The length, in bytes, of each returned ADDRINFOW structure is specified in the
/// ai_addrlen member.
///
///
public SOCKADDR addr => new(ai_addr, false, ai_addrlen);
///
public override string ToString() => $"{ai_canonname}:{ai_flags},{ai_family},{ai_socktype},{ai_protocol},{addr}";
}
///
/// The addrinfoex2 structure is used by the GetAddrInfoEx function to hold host address information when both a canonical
/// name and a fully qualified domain name have been requested.
///
///
/// The addrinfoex2 structure is supported on Windows 8 and Windows Server 2012
///
/// The addrinfoex2 structure is used by the GetAddrInfoEx function to hold host address information when both the
/// AI_FQDN and AI_CANONNAME bits are set in the ai_flags member of the optional addrinfoex structure provided
/// in the hints parameter to the GetAddrInfoEx function. The addrinfoex2 structure is an enhanced version of the
/// addrinfoex structure that can return both the canonical name and the fully qualified domain name for the host. The extra
/// structure members are for a version number of the structure and the fully qualified domain name for the host.
///
///
/// The addrinfoex2 structure used with GetAddrInfoEx function is an enhanced version of the addrinfo and addrinfoW
/// structures used with the getaddrinfo and GetAddrInfoW functions. The GetAddrInfoEx function allows specifying the
/// namespace provider to resolve the query. For use with the IPv6 and IPv4 protocol, name resolution can be by the Domain Name
/// System (DNS), a local hosts file, an email provider (the NS_EMAIL namespace), or by other naming mechanisms.
///
///
/// The blob data in tha ai_blob member is used to return additional provider-specific namespace information associated with
/// a name. The format of data in the ai_blob member is specific to a particular namespace provider. Currently, blob data is
/// used by the NS_EMAIL namespace provider to supply additional information.
///
///
/// When UNICODE or _UNICODE is defined, addrinfoex2 is defined to addrinfoex2W, the Unicode version of this
/// structure. The string parameters are defined to the PWSTR data type and the addrinfoex2W structure is used.
///
///
/// When UNICODE or _UNICODE is not defined, addrinfoex2 is defined to addrinfoex2A, the ANSI version of this
/// structure. The string parameters are of the char * data type and the addrinfoex2A structure is used.
///
///
/// Upon a successful call to GetAddrInfoEx, a linked list of addrinfoex2 structures is returned in the ppResult parameter
/// passed to the GetAddrInfoEx function. The list can be processed by following the pointer provided in the ai_next
/// member of each returned addrinfoex2 structure until a NULL pointer is encountered. In each returned
/// addrinfoex2 structure, the ai_family, ai_socktype, and ai_protocol members correspond to respective
/// arguments in a socket or WSASocket function call. Also, the ai_addr member in each returned addrinfoex2 structure
/// points to a filled-in socket address structure, the length of which is specified in its ai_addrlen member.
///
///
/// The addrinfo structure is used by the getaddrinfo function to hold host address information.
///
/// The addrinfo structure is used by the ANSI getaddrinfo function to hold host address information.
/// The addrinfoW structure is the version of this structure used by the Unicode GetAddrInfoW function.
///
/// Macros in the Ws2tcpip.h header file define a ADDRINFOT structure and a mixed-case function name of GetAddrInfo.
/// The GetAddrInfo function should be called with the nodename and servname parameters of a pointer of type TCHAR and
/// the hints and res parameters of a pointer of type ADDRINFOT. When UNICODE or _UNICODE is not defined, ADDRINFOT is
/// defined to the addrinfo structure and GetAddrInfo is defined to getaddrinfo, the ANSI version of this function.
/// When UNICODE or _UNICODE is defined, ADDRINFOT is defined to the addrinfoW structure and GetAddrInfo is defined to
/// GetAddrInfoW, the Unicode version of this function.
///
///
/// Upon a successful call to getaddrinfo, a linked list of addrinfo structures is returned in the res parameter passed to
/// the getaddrinfo function. The list can be processed by following the pointer provided in the ai_next member of
/// each returned addrinfo structure until a NULL pointer is encountered. In each returned addrinfo structure,
/// the ai_family, ai_socktype, and ai_protocol members correspond to respective arguments in a socket or
/// WSASocket function call. Also, the ai_addr member in each returned addrinfo structure points to a filled-in socket
/// address structure, the length of which is specified in its ai_addrlen member.
///
/// Support for getaddrinfo and the addrinfo struct on older versions of Windows
///
/// The getaddrinfo function that uses the addrinfo structure was added to the Ws2_32.dll on Windows XP and later. The
/// addrinfo structure is defined in the Ws2tcpip.h header file included with the Platform SDK released for Windows XP and
/// later and the Windows SDK released for Windows Vista and later.
///
///
/// To execute an application that uses the getaddrinfo function and the addrinfo structure on earlier versions of Windows
/// (Windows 2000), then you need to include the Ws2tcpip.h and Wspiapi.h files. When the Wspiapi.h include file is added, the
/// getaddrinfo function is defined to the WspiapiGetAddrInfo inline function in the Wspiapi.h file. At runtime, the
/// WspiapiGetAddrInfo function is implemented in such a way that if the Ws2_32.dll or the Wship6.dll (the file containing
/// getaddrinfo in the IPv6 Technology Preview for Windows 2000) does not include getaddrinfo, then a version of
/// getaddrinfo is implemented inline based on code in the Wspiapi.h header file. This inline code will be used on older
/// Windows platforms that do not natively support the getaddrinfo function.
///
///
/// The IPv6 protocol is supported on Windows 2000 when the IPv6 Technology Preview for Windows 2000 is installed. Otherwise
/// getaddrinfo support on versions of Windows earlier than Windows XP is limited to handling IPv4 name resolution.
///
///
/// The GetAddrInfoW function that uses the addrinfoW structure is the Unicode version of the getaddrinfo function and associated
/// addrinfo structure. The GetAddrInfoW function was added to the Ws2_32.dll in Windows XP with Service Pack 2 (SP2).
/// The GetAddrInfoW function and the addrinfoW structure cannot be used on versions of Windows earlier than Windows
/// XP with SP2.
///
/// Examples
/// The following code example shows the use of the addrinfo structure.
///
// https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-addrinfoa typedef struct addrinfo { int ai_flags; int
// ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; char *ai_canonname; struct sockaddr *ai_addr; struct addrinfo
// *ai_next; } ADDRINFOA, *PADDRINFOA;
[PInvokeData("ws2def.h", MSDNShortId = "4df914ab-59b0-4110-bc81-59e5f6722b8d")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct ADDRINFOW
{
///
/// Type: int
/// Flags that indicate options used in the getaddrinfo function.
///
/// Supported values for the ai_flags member are defined in the Ws2def.h header file on the Windows SDK for Windows 7 and
/// later. These values are defined in the Ws2tcpip.h header file on the Windows SDK for Windows Server 2008 and Windows Vista.
/// These values are defined in the Ws2tcpip.h header file on the Platform SDK for Windows Server 2003, and Windows XP.
/// Supported values for the ai_flags member can be a combination of the following options.
///
///
///
/// Value
/// Meaning
///
/// -
/// AI_PASSIVE 0x01
/// The socket address will be used in a call to the bindfunction.
///
/// -
/// AI_CANONNAME 0x02
/// The canonical name is returned in the first ai_canonname member.
///
/// -
/// AI_NUMERICHOST 0x04
/// The nodename parameter passed to the getaddrinfo function must be a numeric string.
///
/// -
/// AI_ALL 0x0100
///
/// If this bit is set, a request is made for IPv6 addresses and IPv4 addresses with AI_V4MAPPED. This option is supported on
/// Windows Vista and later.
///
///
/// -
/// AI_ADDRCONFIG 0x0400
///
/// The getaddrinfo will resolve only if a global address is configured. The IPv6 and IPv4 loopback address is not considered a
/// valid global address. This option is supported on Windows Vista and later.
///
///
/// -
/// AI_V4MAPPED 0x0800
///
/// If the getaddrinfo request for IPv6 addresses fails, a name service request is made for IPv4 addresses and these addresses
/// are converted to IPv4-mapped IPv6 address format. This option is supported on Windows Vista and later.
///
///
/// -
/// AI_NON_AUTHORITATIVE 0x04000
///
/// The address information can be from a non-authoritative namespace provider. This option is only supported on Windows Vista
/// and later for the NS_EMAIL namespace.
///
///
/// -
/// AI_SECURE 0x08000
///
/// The address information is from a secure channel. This option is only supported on Windows Vista and later for the NS_EMAIL namespace.
///
///
/// -
/// AI_RETURN_PREFERRED_NAMES 0x010000
///
/// The address information is for a preferred name for a user. This option is only supported on Windows Vista and later for the
/// NS_EMAIL namespace.
///
///
/// -
/// AI_FQDN 0x00020000
///
/// If a flat name (single label) is specified, getaddrinfo will return the fully qualified domain name that the name eventually
/// resolved to. The fully qualified domain name is returned in the ai_canonname member. This is different than AI_CANONNAME bit
/// flag that returns the canonical name registered in DNS which may be different than the fully qualified domain name that the
/// flat name resolved to. Only one of the AI_FQDN and AI_CANONNAME bits can be set. The getaddrinfo function will fail if both
/// flags are present with EAI_BADFLAGS. This option is supported on Windows 7, Windows Server 2008 R2, and later.
///
///
/// -
/// AI_FILESERVER 0x00040000
///
/// A hint to the namespace provider that the hostname being queried is being used in a file share scenario. The namespace
/// provider may ignore this hint. This option is supported on Windows 7, Windows Server 2008 R2, and later.
///
///
///
///
public ADDRINFO_FLAGS ai_flags;
private uint _ai_family;
///
/// Type: int
/// The address family. Possible values for the address family are defined in the Winsock2.h include file.
///
/// On the Windows SDK released for Windows Vista and later,, the organization of header files has changed and the possible
/// values for the address family are defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically
/// included in Winsock2.h, and should never be used directly.
///
///
/// The values currently supported are AF_INET or AF_INET6, which are the Internet address family formats for IPv4
/// and IPv6. Other options for address family ( AF_NETBIOS for use with NetBIOS, for example) are supported if a Windows
/// Sockets service provider for the address family is installed. Note that the values for the AF_ address family and PF_
/// protocol family constants are identical (for example, AF_UNSPEC and PF_UNSPEC), so either constant can be used.
///
/// The table below lists common values for the address family although many other values are possible.
///
///
/// Value
/// Meaning
///
/// -
/// AF_UNSPEC 0
/// The address family is unspecified.
///
/// -
/// AF_INET 2
/// The Internet Protocol version 4 (IPv4) address family.
///
/// -
/// AF_NETBIOS 17
/// The NetBIOS address family. This address family is only supported if a Windows Sockets provider for NetBIOS is installed.
///
/// -
/// AF_INET6 23
/// The Internet Protocol version 6 (IPv6) address family.
///
/// -
/// AF_IRDA 26
///
/// The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared
/// port and driver installed.
///
///
/// -
/// AF_BTH 32
///
/// The Bluetooth address family. This address family is only supported if a Bluetooth adapter is installed on Windows Server
/// 2003 or later.
///
///
///
///
public ADDRESS_FAMILY ai_family { get => (ADDRESS_FAMILY)_ai_family; set => _ai_family = (ushort)value; }
///
/// Type: int
/// The socket type. Possible values for the socket type are defined in the Winsock2.h header file.
/// The following table lists the possible values for the socket type supported for Windows Sockets 2:
///
///
/// Value
/// Meaning
///
/// -
/// SOCK_STREAM 1
///
/// Provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. Uses the
/// Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6). If the ai_family member is
/// AF_IRDA, then SOCK_STREAM is the only supported socket type.
///
///
/// -
/// SOCK_DGRAM 2
///
/// Supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. Uses the User
/// Datagram Protocol (UDP) for the Internet address family (AF_INET or AF_INET6).
///
///
/// -
/// SOCK_RAW 3
///
/// Provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To manipulate the IPv4
/// header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the IPV6_HDRINCL socket
/// option must be set on the socket.
///
///
/// -
/// SOCK_RDM 4
///
/// Provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) multicast protocol
/// implementation in Windows, often referred to as reliable multicast programming.
///
///
/// -
/// SOCK_SEQPACKET 5
/// Provides a pseudo-stream packet based on datagrams.
///
///
///
/// In Windows Sockets 2, new socket types were introduced. An application can dynamically discover the attributes of each
/// available transport protocol through the WSAEnumProtocols function. So an application can determine the possible socket type
/// and protocol options for an address family and use this information when specifying this parameter. Socket type definitions
/// in the Winsock2.h and Ws2def.h header files will be periodically updated as new socket types, address families, and
/// protocols are defined.
///
/// In Windows Sockets 1.1, the only possible socket types are SOCK_DATAGRAM and SOCK_STREAM.
///
public SOCK ai_socktype;
///
/// Type: int
///
/// The protocol type. The possible options are specific to the address family and socket type specified. Possible values for
/// the ai_protocol are defined in the Winsock2.h and Wsrm.h header files.
///
///
/// On the Windows SDK released for Windows Vista and later, the organization of header files has changed and this member can be
/// one of the values from the IPPROTO enumeration type defined in the Ws2def.h header file. Note that the Ws2def.h
/// header file is automatically included in Winsock2.h, and should never be used directly.
///
///
/// If a value of 0 is specified for ai_protocol, the caller does not wish to specify a protocol and the service provider
/// will choose the ai_protocol to use. For protocols other than IPv4 and IPv6, set ai_protocol to zero.
///
/// The following table lists common values for the ai_protocol member although many other values are possible.
///
///
/// Value
/// Meaning
///
/// -
/// IPPROTO_TCP 6
///
/// The Transmission Control Protocol (TCP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the
/// ai_socktype member is SOCK_STREAM.
///
///
/// -
/// IPPROTO_UDP 17
///
/// The User Datagram Protocol (UDP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the type
/// parameter is SOCK_DGRAM.
///
///
/// -
/// IPPROTO_RM 113
///
/// The PGM protocol for reliable multicast. This is a possible value when the ai_family member is AF_INET and the ai_socktype
/// member is SOCK_RDM. On the Windows SDK released for Windows Vista and later, this value is also called IPPROTO_PGM.
///
///
///
/// If the ai_family member is AF_IRDA, then the ai_protocol must be 0.
///
public IPPROTO ai_protocol;
///
/// Type: size_t
/// The length, in bytes, of the buffer pointed to by the ai_addr member.
///
public SizeT ai_addrlen;
///
/// Type: char*
/// The canonical name for the host.
///
public StrPtrUni ai_canonname;
///
/// Type: struct sockaddr*
///
/// A pointer to a sockaddr structure. The ai_addr member in each returned addrinfo structure points to a
/// filled-in socket address structure. The length, in bytes, of each returned addrinfo structure is specified in the
/// ai_addrlen member.
///
///
public IntPtr ai_addr;
///
/// Type: struct addrinfo*
///
/// A pointer to the next structure in a linked list. This parameter is set to NULL in the last addrinfo structure
/// of a linked list.
///
///
public IntPtr ai_next;
///
/// Type: struct sockaddr*
///
/// A pointer to a sockaddr structure. The ai_addr member in each returned ADDRINFOW structure points to a filled-in
/// socket address structure. The length, in bytes, of each returned ADDRINFOW structure is specified in the
/// ai_addrlen member.
///
///
public SOCKADDR addr => new(ai_addr, false, ai_addrlen);
///
public override string ToString() => $"{ai_canonname}:{ai_flags},{ai_family},{ai_socktype},{ai_protocol},{addr}";
}
/// The scope identifier for the IPv6 transport address.
[PInvokeData("ws2def.h")]
[StructLayout(LayoutKind.Sequential)]
public struct SCOPE_ID
{
/// A ULONG representation of the IPv6 scope identifier.
public uint Value;
///
///
/// The zone index that identifies the zone to which the transport address pertains. Zones of the different scopes are
/// instantiated as follows:
///
///
/// - Each interface on a node comprises a single zone of interface-local scope.
/// - Each link, and the interfaces attached to that link, comprise a single zone of link-local scope.
/// - There is a single zone of global scope that comprises all of the links and interfaces in the Internet.
/// - The boundaries of zones of scope other than interface-local, link-local, and global are defined by network administrators.
///
/// A value of zero specifies the default zone.
///
/// The zone index.
public uint Zone
{
get => BitHelper.GetBits(Value, 0, 28);
set => BitHelper.SetBits(ref Value, 0, 28, value);
}
///
///
/// The scope of the IPv6 transport address. This scope must be the same as the IPv6 scope value that is embedded in the IPv6
/// transport address. This member can be one of the following:
///
/// ScopeLevelInterface
/// The transport address has interface-local scope.
/// ScopeLevelLink
/// The transport address has link-local scope.
/// ScopeLevelSubnet
/// The transport address has subnet-local scope.
/// ScopeLevelAdmin
/// The transport address has admin-local scope.
/// ScopeLevelSite
/// The transport address has site-local scope.
/// ScopeLevelOrganization
/// The transport address has organization-local scope.
/// ScopeLevelGlobal
/// The transport address has global scope.
///
/// The level.
public byte Level
{
get => (byte)BitHelper.GetBits(Value, 28, 4);
set => BitHelper.SetBits(ref Value, 28, 4, value);
}
}
/// The SOCKADDR_IN structure specifies a transport address and port for the AF_INET address family.
///
/// All of the data in the SOCKADDR_IN structure, except for the address family, must be specified in network-byte-order (big-endian).
///
// https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-sockaddr_in typedef struct sockaddr_in { #if ... short
// sin_family; #else ADDRESS_FAMILY sin_family; #endif USHORT sin_port; IN_ADDR sin_addr; CHAR sin_zero[8]; } SOCKADDR_IN, *PSOCKADDR_IN;
[PInvokeData("ws2def.h", MSDNShortId = "96379562-403f-451c-ac7a-f0eec34bfe5e")]
[StructLayout(LayoutKind.Sequential, Pack = 2)]
public struct SOCKADDR_IN
{
/// The address family for the transport address. This member should always be set to AF_INET.
public ADDRESS_FAMILY sin_family;
/// A transport protocol port number.
public ushort sin_port;
/// An IN_ADDR structure that contains an IPv4 transport address.
public IN_ADDR sin_addr;
/// Reserved for system use. A WSK application should set the contents of this array to zero.
public ulong sin_zero;
/// Initializes a new instance of the struct.
/// An IN_ADDR structure that contains an IPv4 transport address.
/// A transport protocol port number.
public SOCKADDR_IN(IN_ADDR addr, ushort port = 0)
{
sin_family = ADDRESS_FAMILY.AF_INET;
sin_port = port;
sin_addr = addr;
sin_zero = 0;
}
/// Performs an implicit conversion from to .
/// The addr.
/// The resulting instance from the conversion.
public static implicit operator SOCKADDR_IN(IN_ADDR addr) => new(addr);
/// Performs an explicit conversion from to .
/// The ipv4 address.
/// The resulting instance from the conversion.
public static explicit operator SOCKADDR_IN6(SOCKADDR_IN ipv4) => new(ipv4);
/// Converts to string.
/// A that represents this instance.
public override string ToString() => $"{sin_addr}:{sin_port}";
}
/// The SOCKADDR_STORAGE structure is a generic structure that specifies a transport address.
///
/// A WSK application typically does not directly access any of the members of the SOCKADDR_STORAGE structure except for the
/// ss_family member. Instead, a pointer to a SOCKADDR_STORAGE structure is normally cast to a pointer to the specific
/// SOCKADDR structure type that corresponds to a particular address family.
///
// https://docs.microsoft.com/ja-jp/windows/desktop/api/ws2def/ns-ws2def-sockaddr_storage_lh typedef struct sockaddr_storage {
// ADDRESS_FAMILY ss_family; CHAR __ss_pad1[_SS_PAD1SIZE]; __int64 __ss_align; CHAR __ss_pad2[_SS_PAD2SIZE]; } SOCKADDR_STORAGE_LH,
// *PSOCKADDR_STORAGE_LH, *LPSOCKADDR_STORAGE_LH;
[PInvokeData("ws2def.h", MSDNShortId = "27e56c1a-ce11-4cdb-9be8-25ed2f94fb37")]
[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct SOCKADDR_STORAGE
{
///
/// The address family for the transport address. For more information about supported address families, see WSK Address Families.
///
public ADDRESS_FAMILY ss_family;
/// A padding of 6 bytes that puts the __ss_align member on an eight-byte boundary within the structure.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
public byte[] __ss_pad1;
/// A 64-bit value that forces the structure to be 8-byte aligned.
public long __ss_align;
/// A padding of an additional 112 bytes that brings the total size of the SOCKADDR_STORAGE structure to 128 bytes.
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 112)]
public byte[] __ss_pad2;
/// Performs an explicit conversion from to .
/// The address.
/// The resulting instance from the conversion.
public static explicit operator SOCKADDR_STORAGE(in SOCKADDR_IN6 addr)
{
using var mem = SafeHGlobalHandle.CreateFromStructure(addr);
mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE));
return mem.ToStructure();
}
/// Performs an explicit conversion from to .
/// The address.
/// The resulting instance from the conversion.
public static explicit operator SOCKADDR_STORAGE(in SOCKADDR_IN addr)
{
using var mem = SafeHGlobalHandle.CreateFromStructure(addr);
mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE));
return mem.ToStructure();
}
/// Performs an explicit conversion from to .
/// The address.
/// The resulting instance from the conversion.
public static explicit operator SOCKADDR_STORAGE(SOCKADDR addr)
{
using var mem = new SafeHGlobalHandle(addr.GetAddressBytes());
mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE));
return mem.ToStructure();
}
/// Performs an explicit conversion from to .
/// The address.
/// The resulting instance from the conversion.
public static explicit operator SOCKADDR_STORAGE(IPAddress addr)
{
using var mem = new SafeHGlobalHandle(addr.GetAddressBytes());
mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE));
return mem.ToStructure();
}
/// Performs an explicit conversion from to .
/// The address.
/// The resulting instance from the conversion.
public static explicit operator SOCKADDR_STORAGE(SOCKADDR_INET addr)
{
using var mem = SafeHGlobalHandle.CreateFromStructure(addr);
mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE));
return mem.ToStructure();
}
/// Performs an explicit conversion from to .
/// The addr.
/// The resulting instance from the conversion.
public static explicit operator SOCKADDR(SOCKADDR_STORAGE addr) => SOCKADDR.CreateFromStructure(addr);
/// Performs an explicit conversion from to .
/// The addr.
/// The resulting instance from the conversion.
public static explicit operator SOCKADDR_IN(SOCKADDR_STORAGE addr) => (SOCKADDR_IN)SOCKADDR.CreateFromStructure(addr);
/// Performs an explicit conversion from to .
/// The addr.
/// The resulting instance from the conversion.
public static explicit operator SOCKADDR_IN6(SOCKADDR_STORAGE addr) => (SOCKADDR_IN6)SOCKADDR.CreateFromStructure(addr);
/// Performs an explicit conversion from to .
/// The addr.
/// The resulting instance from the conversion.
public static explicit operator SOCKADDR_INET(SOCKADDR_STORAGE addr) => (SOCKADDR_INET)SOCKADDR.CreateFromStructure(addr);
}
/// The SOCKET_ADDRESS structure stores protocol-specific address information.
///
///
/// The SOCKADDR structure pointed to by the lpSockaddr member varies depending on the protocol or address family selected.
/// For example, the sockaddr_in6 structure is used for an IPv6 socket address while the sockaddr_in4 structure is
/// used for an IPv4 socket address. The address family is the first member of all of the SOCKADDR structures. The address
/// family is used to determine which structure is used.
///
///
/// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files
/// has changed and the SOCKET_ADDRESS structure is defined in the Ws2def.h header file. Note that the Ws2def.h header file
/// is automatically included in Winsock2.h, and should never be used directly.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-socket_address typedef struct _SOCKET_ADDRESS { LPSOCKADDR
// lpSockaddr; INT iSockaddrLength; } SOCKET_ADDRESS, *PSOCKET_ADDRESS, *LPSOCKET_ADDRESS;
[PInvokeData("ws2def.h", MSDNShortId = "37fbcb96-a859-4eca-8928-8051f95407b9")]
[StructLayout(LayoutKind.Sequential,
#if x64
Size = 16)]
#else
Size = 8)]
#endif
public struct SOCKET_ADDRESS
{
/// A pointer to a socket address represented as a SOCKADDR structure.
public IntPtr lpSockaddr;
/// The length, in bytes, of the socket address.
public int iSockaddrLength;
/// Gets the from this instance.
/// The value pointed to by this instance.
public SOCKADDR_INET GetSOCKADDR() => lpSockaddr.ToStructure();
/// Converts to string.
/// A that represents this instance.
public override string ToString() => GetSOCKADDR().ToString();
}
/// The SOCKET_ADDRESS_LIST structure defines a variable-sized list of transport addresses.
///
///
/// A WSK application passes a buffer to the WskControlSocket function when the WSK application queries the current list of local
/// transport addresses that match a socket's address family. If the call to the WskControlSocket function succeeds, the
/// buffer contains a SOCKET_ADDRESS_LIST structure followed by the SOCKADDR structures for each of the local transport addresses
/// that match the socket's address family. The WSK subsystem fills in the Address array and sets the iAddressCount
/// member to the number of entries in the array. The lpSockaddr pointers in each of the SOCKET_ADDRESS structures in the
/// array point to the specific SOCKADDR structure type that corresponds to the address family that the WSK application specified
/// when it created the socket.
///
/// For more information about querying the current list of local transport addresses, see SIO_ADDRESS_LIST_QUERY.
///
// https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-socket_address_list typedef struct _SOCKET_ADDRESS_LIST { INT
// iAddressCount; SOCKET_ADDRESS Address[1]; } SOCKET_ADDRESS_LIST, *PSOCKET_ADDRESS_LIST, *LPSOCKET_ADDRESS_LIST;
[PInvokeData("ws2def.h", MSDNShortId = "b005200b-b0c2-4f19-8765-cd26fbfc0cff")]
[VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(iAddressCount))]
[StructLayout(LayoutKind.Sequential)]
public struct SOCKET_ADDRESS_LIST
{
/// The number of transport addresses in the list.
public int iAddressCount;
/// A variable-sized array of SOCKET_ADDRESS structures. The SOCKET_ADDRESS structure is defined as follows:
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public SOCKET_ADDRESS[] Address;
/// Packs this instance into a single memory block so that it can be passed as a pointer to other API methods.
///
/// A instance that contains this structure and all memeroy assigned to its elements.
///
public SafeCoTaskMemStruct Pack()
{
var addrOffset = Marshal.OffsetOf(typeof(SOCKET_ADDRESS_LIST), "Address").ToInt32();
var eosOffset = addrOffset + iAddressCount * Marshal.SizeOf(typeof(SOCKET_ADDRESS));
var cbAddressList = eosOffset + Address.Sum(a => a.iSockaddrLength);
var addressList = new SafeCoTaskMemStruct(cbAddressList);
((IntPtr)addressList).Write(iAddressCount);
var newAddr = new SOCKET_ADDRESS[iAddressCount];
var ptr = ((IntPtr)addressList).Offset(eosOffset);
for (int i = 0; i < iAddressCount; i++)
{
newAddr[i] = new SOCKET_ADDRESS { iSockaddrLength = Address[i].iSockaddrLength, lpSockaddr = ptr };
Address[i].lpSockaddr.CopyTo(ptr, Address[i].iSockaddrLength);
ptr = ptr.Offset(Address[i].iSockaddrLength);
}
((IntPtr)addressList).Write(newAddr, addrOffset);
return addressList;
}
}
///
/// The SOCKET_PROCESSOR_AFFINITY structure contains the association between a socket and an RSS processor core and NUMA node..
///
///
///
/// The SOCKET_PROCESSOR_AFFINITY structure is supported on Windows 8, and Windows Server 2012, and later versions of the
/// operating system.
///
///
/// The SIO_QUERY_RSS_PROCESSOR_INFO IOCTL is used to determine the association between a socket and an RSS processor core and NUMA
/// node. This IOCTL returns a SOCKET_PROCESSOR_AFFINITY structure that contains the processor number and the NUMA node ID.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-socket_processor_affinity typedef struct
// _SOCKET_PROCESSOR_AFFINITY { PROCESSOR_NUMBER Processor; USHORT NumaNodeId; USHORT Reserved; } SOCKET_PROCESSOR_AFFINITY, *PSOCKET_PROCESSOR_AFFINITY;
[PInvokeData("ws2def.h", MSDNShortId = "CB1E9F79-C6BD-40C2-8D0F-36B24B1BBBF4")]
[StructLayout(LayoutKind.Sequential)]
public struct SOCKET_PROCESSOR_AFFINITY
{
///
/// A structure to represent a system wide processor number. This PROCESSOR_NUMBER structure contains a group number and
/// relative processor number within the group.
///
public Kernel32.PROCESSOR_NUMBER Processor;
/// The NUMA node ID.
public ushort NumaNodeId;
/// A value reserved for future use.
public ushort Reserved;
}
/// The WSABUF structure enables the creation or manipulation of a data buffer used by some Winsock functions.
// https://docs.microsoft.com/en-us/windows/desktop/api/ws2def/ns-ws2def-_wsabuf typedef struct _WSABUF { ULONG len; CHAR *buf; }
// WSABUF, *LPWSABUF;
[PInvokeData("ws2def.h", MSDNShortId = "a012c3ba-67fd-4fcf-84d1-85e9d495c29c")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct WSABUF
{
/// The length of the buffer, in bytes.
public uint len;
/// A pointer to the buffer.
public IntPtr buf;
}
/// The CMSGHDR structure defines the header for a control data object that is associated with a datagram.
///
/// The control information data that is associated with a datagram is made up of one or more control data objects. Each object
/// begins with a CMSGHDR structure.
///
// https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-wsacmsghdr typedef struct _WSACMSGHDR { SIZE_T cmsg_len; INT
// cmsg_level; INT cmsg_type; } WSACMSGHDR, *PWSACMSGHDR, *LPWSACMSGHDR;
[PInvokeData("ws2def.h", MSDNShortId = "NS:ws2def._WSACMSGHDR")]
[StructLayout(LayoutKind.Sequential)]
public struct WSACMSGHDR
{
///
/// The number of bytes from the beginning of the CMSGHDR structure to the end of the control data.
/// Note The value of the cmsg_len member does not account for any padding that may follow the control data.
///
public SizeT cmsg_len;
/// The protocol that originated the control information.
public int cmsg_level;
/// The protocol-specific type of control information.
public int cmsg_type;
}
///
/// The WSAMSG structure is used with the WSARecvMsg and WSASendMsg functions to store address and optional control
/// information about connected and unconnected sockets as well as an array of buffers used to store message data.
///
///
///
/// In the Microsoft Windows Software Development Kit (SDK), the version of this structure for use on Windows Vistais defined with
/// the data type for the dwBufferCount and dwFlags members as a ULONG. When compiling an application if the
/// target platform is Windows Vista and later ( NTDDI_VERSION >= NTDDI_LONGHORN, _WIN32_WINNT >= 0x0600, or WINVER
/// >= 0x0600), the data type for the dwBufferCount and dwFlags members is a ULONG.
///
///
/// Windows Server 2003 and Windows XP: When compiling an application, the data type for the dwBufferCount and
/// dwFlags members is a DWORD.
///
///
/// On the Windows SDK released for Windows Vista and later, the WSAMSG structure is defined in the Ws2def.h header file.
/// Note that the Ws2def.h header file is automatically included in Winsock2.h, and should never be used directly
///
///
/// If the datagram or control data is truncated during the transmission, the function being used in association with the
/// WSAMSG structure returns SOCKET_ERROR and a call to the WSAGetLastError function returns WSAEMSGSIZE. It is up to the
/// application to determine what was truncated by checking for MSG_TRUNC and/or MSG_CTRUNC flags.
///
/// Use of the Control Member
///
/// The following table summarizes the various uses of control data available for use in the Control member for IPv4 and IPv6.
///
///
///
/// Protocol
/// cmsg_level
/// cmsg_type
/// Description
///
/// -
/// IPv4
/// IPPROTO_IP
/// IP_ORIGINAL_ARRIVAL_IF
///
/// Receives the original IPv4 arrival interface where the packet was received for datagram sockets. This control data is used by
/// firewalls when a Teredo, 6to4, or ISATAP tunnel is used for IPv4 NAT traversal. The cmsg_data[] member in the WSAMSG structure
/// is a ULONG that contains the IF_INDEX defined in the Ifdef.h header file. For more information, see the IPPROTO_IP Socket
/// Options for the IP_ORIGINAL_ARRIVAL_IF socket option. Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP:
/// The IP_ORIGINAL_ARRIVAL_IF cmsg_type is not supported.
///
///
/// -
/// IPv4
/// IPPROTO_IP
/// IP_PKTINFO
/// Specifies/receives packet information for an IPv4 socket. For more information, see the IP_PKTINFO socket option.
///
/// -
/// IPv6
/// IPPROTO_IPV6
/// IPV6_DSTOPTS
/// Specifies/receives destination options.
///
/// -
/// IPv6
/// IPPROTO_IPV6
/// IPV6_HOPLIMIT
/// Specifies/receives hop limit. For more information, see the IPPROTO_IPV6 Socket Options for the IPV6_HOPLIMIT socket option.
///
/// -
/// IPv6
/// IPPROTO_IPV6
/// IPV6_HOPOPTS
/// Specifies/receives hop-by-hop options.
///
/// -
/// IPv6
/// IPPROTO_IPV6
/// IPV6_NEXTHOP
/// Specifies next-hop address.
///
/// -
/// IPv6
/// IPPROTO_IPV6
/// IPV6_PKTINFO
/// Specifies/receives packet information for an IPv6 socket. For more information, see the IPV6_PKTINFO socket option.
///
/// -
/// IPv6
/// IPPROTO_IPV6
/// IPV6_RTHDR
/// Specifies/receives routing header.
///
///
///
/// Control data is made up of one or more control data objects, each beginning with a WSACMSGHDR structure, defined as the following.
///
///
/// Note The transport, not the application, fills out the header information in the WSACMSGHDR structure. The
/// application simply sets the needed socket options and provides the adequate buffer size.
///
/// The members of the WSACMSGHDR structure are as follows:
///
///
/// Term
/// Description
///
/// -
/// cmsg_len
///
/// The number of bytes of data starting from the beginning of the WSACMSGHDR to the end of data (excluding padding bytes that may
/// follow data).
///
///
/// -
/// cmsg_level
/// The protocol that originated the control information.
///
/// -
/// cmsg_type
/// The protocol-specific type of control information.
///
///
/// The following macros are used to navigate the data objects:
///
/// Returns a pointer to the first control data object. Returns a NULL pointer if there is no control data in the
/// WSAMSG structure, such as when the Control member is a NULL pointer.
///
///
/// Returns a pointer to the next control data object, or NULL if there are no more data objects. If the pcmsg parameter is
/// NULL, a pointer to the first control data object is returned.
///
///
/// Returns a pointer to the first byte of data (referred to as the cmsg_data member, though it is not defined in the structure).
///
///
/// Returns the total size of a control data object, given the amount of data. Used to allocate the correct amount of buffer space.
/// Includes alignment padding.
///
/// Returns the value in cmsg_len given the amount of data. Includes alignment padding.
///
// https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-wsamsg typedef struct _WSAMSG { LPSOCKADDR name; INT namelen;
// LPWSABUF lpBuffers; #if ... ULONG dwBufferCount; #else DWORD dwBufferCount; #endif WSABUF Control; #if ... ULONG dwFlags; #else
// DWORD dwFlags; #endif } WSAMSG, *PWSAMSG, *LPWSAMSG;
[PInvokeData("ws2def.h", MSDNShortId = "105a6e2c-1edf-4ec0-a1c2-ac0bcafeda30")]
[StructLayout(LayoutKind.Sequential)]
public struct WSAMSG
{
///
/// Type: LPSOCKADDR
///
/// A pointer to a SOCKET_ADDRESS structure that stores information about the remote address. Used only with unconnected sockets.
///
///
public IntPtr name;
///
/// Type: INT
///
/// The length, in bytes, of the SOCKET_ADDRESS structure pointed to in the pAddr member. Used only with unconnected sockets.
///
///
public int namelen;
///
/// Type: LPWSABUF
///
/// An array of WSABUF structures used to receive the message data. The capability of the lpBuffers member to contain
/// multiple buffers enables the use of scatter/gather I/O.
///
///
public IntPtr lpBuffers;
///
/// Type: DWORD
/// The number of buffers pointed to in the lpBuffers member.
///
public uint dwBufferCount;
///
/// Type: WSABUF
/// A structure of WSABUF type used to specify optional control data. See Remarks.
///
public WSABUF Control;
///
/// Type: DWORD
///
/// One or more control flags, specified as the logical OR of values. The possible values for dwFlags member on
/// input are defined in the Winsock2.h header file. The possible values for dwFlags member on output are defined in the
/// Ws2def.h header file which is automatically included by the Winsock2.h header file.
///
///
///
/// Flags on input
/// Meaning
///
/// -
/// MSG_PEEK
///
/// Peek at the incoming data. The data is copied into the buffer, but is not removed from the input queue. This flag is valid
/// only for non-overlapped sockets.
///
///
///
///
///
/// Flag returned
/// Meaning
///
/// -
/// MSG_BCAST
/// The datagram was received as a link-layer broadcast or with a destination IP address that is a broadcast address.
///
/// -
/// MSG_MCAST
/// The datagram was received with a destination IP address that is a multicast address.
///
/// -
/// MSG_TRUNC
/// The datagram was truncated. More data was present than the process allocated room for.
///
/// -
/// MSG_CTRUNC
/// The control (ancillary) data was truncated. More control data was present than the process allocated room for.
///
///
///
public MsgFlags dwFlags;
}
///
///
/// Some of the socket IOCTL opcodes for Windows Sockets 2 are summarized in the following table. More detailed information is in
/// the Winsock reference on Winsock IOCTLs and the WSPIoctl function. There are other new protocol-specific IOCTL
/// opcodes that can be found in the protocol-specific annex.
///
/// A complete list of Winsock IOCTLs are available in the Winsock reference.
///
// https://docs.microsoft.com/en-us/windows/win32/winsock/summary-of-socket-ioctl-opcodes-2
[PInvokeData("ws2def.h", MSDNShortId = "fb6447b4-28f5-4ab7-bbdc-5a57ed38a994")]
public static class WinSockIOControlCode
{
///
/// Determine the amount of data that can be read atomically from socket s. The lpvOutBuffer parameter points at an unsigned long
/// in which WSAIoctl stores the result.
///
/// If the socket passed in the s parameter is stream oriented(for example, type SOCK_STREAM), FIONREAD returns the total amount
/// of data that can be read in a single receive operation; this is normally the same as the total amount of data queued on the
/// socket(since a data stream is byte-oriented, this is not guaranteed).
///
///
/// If the socket passed in the s parameter is message oriented(for example, type SOCK_DGRAM), FIONREAD returns the reports the
/// total number of bytes available to read, not the size of the first datagram(message) queued on the socket.
///
///
public static readonly uint FIONREAD = _IOR('f', 127); /* get # bytes to read */
///
/// Enable or disable non-blocking mode on socket s. The lpvInBuffer parameter points at an unsigned long (QoS), which is nonzero
/// if non-blocking mode is to be enabled and zero if it is to be disabled. When a socket is created, it operates in blocking
/// mode (that is, non-blocking mode is disabled). This is consistent with BSD sockets.
///
/// The WSAAsyncSelect or WSAEventSelect routine automatically sets a socket to non-blocking mode.If WSAAsyncSelect or
/// WSAEventSelect has been issued on a socket, then any attempt to use WSAIoctl to set the socket back to blocking mode will
/// fail with WSAEINVAL. To set the socket back to blocking mode, an application must first disable WSAAsyncSelect by calling
/// WSAAsyncSelect with the lEvent parameter equal to zero, or disable WSAEventSelect by calling WSAEventSelect with the
/// lNetworkEvents parameter equal to zero.
///
///
public static readonly uint FIONBIO = _IOW('f', 126); /* set/clear non-blocking i/o */
/// Enable notification for when data is waiting to be received.
public static readonly uint FIOASYNC = _IOW('f', 125); /* set/clear async i/o */
/// Requests notification of changes in information reported through SIO_ADDRESS_LIST_QUERY
public static readonly uint SIO_ADDRESS_LIST_CHANGE = _WSAIO(IOC_WS2, 23);
///
/// Obtains a list of local transport addresses of the socket's protocol family to which the application can bind. The list of
/// addresses varies based on address family and some addresses are excluded from the list.
///
[CorrespondingType(typeof(SOCKET_ADDRESS), CorrespondingAction.Get)]
public static readonly uint SIO_ADDRESS_LIST_QUERY = _WSAIOR(IOC_WS2, 22);
///
/// Allows application developers to sort a list of IPv6 and IPv4 destination addresses to determine the best available address
/// for making a connection.
///
[CorrespondingType(typeof(SOCKET_ADDRESS_LIST), CorrespondingAction.GetSet)]
public static readonly uint SIO_ADDRESS_LIST_SORT = _WSAIORW(IOC_WS2, 25);
/// Associates the socket with the specified handle of a companion interface.
public static readonly uint SIO_ASSOCIATE_HANDLE = _WSAIOW(IOC_WS2, 1);
/// Enables circular queuing.
public static readonly uint SIO_ENABLE_CIRCULAR_QUEUEING = _WSAIO(IOC_WS2, 2);
/// Requests the route to the specified address to be discovered.
[CorrespondingType(typeof(SOCKADDR), CorrespondingAction.Set)]
public static readonly uint SIO_FIND_ROUTE = _WSAIOR(IOC_WS2, 3);
/// Discards current contents of the sending queue.
public static readonly uint SIO_FLUSH = _WSAIO(IOC_WS2, 4);
/// Retrieves the protocol-specific broadcast address to be used in WSPSendTo.
[CorrespondingType(typeof(SOCKADDR), CorrespondingAction.Get)]
public static readonly uint SIO_GET_BROADCAST_ADDRESS = _WSAIOR(IOC_WS2, 5);
/// Gets the function pointer for the WSASendMsg function obtained at run time.
public static readonly uint SIO_GET_EXTENSION_FUNCTION_POINTER = _WSAIORW(IOC_WS2, 6);
/// Reserved.
[CorrespondingType(typeof(QOS), CorrespondingAction.Get)]
public static readonly uint SIO_GET_GROUP_QOS = _WSAIORW(IOC_WS2, 8);
/// Retrieves current flow specifications for the socket.
[CorrespondingType(typeof(QOS), CorrespondingAction.Get)]
public static readonly uint SIO_GET_QOS = _WSAIORW(IOC_WS2, 7);
/// Specifies the scope over which multicast transmissions will occur.
[CorrespondingType(typeof(int), CorrespondingAction.Set)]
public static readonly uint SIO_MULTICAST_SCOPE = _WSAIOW(IOC_WS2, 10);
/// Controls whether data sent in a multipoint session will also be received by the same socket on the local host.
[CorrespondingType(typeof(BOOL), CorrespondingAction.Set)]
public static readonly uint SIO_MULTIPOINT_LOOPBACK = _WSAIOW(IOC_WS2, 9);
/// Queries the association between a socket and an RSS processor core and NUMA node.
[CorrespondingType(typeof(SOCKET_PROCESSOR_AFFINITY), CorrespondingAction.Get)]
public static readonly uint SIO_QUERY_RSS_PROCESSOR_INFO = _WSAIOR(IOC_WS2, 37);
/// Obtains socket descriptor of the next provider in the chain on which current socket depends in regards to PnP.
[CorrespondingType(typeof(SOCKET), CorrespondingAction.Get)]
public static readonly uint SIO_QUERY_TARGET_PNP_HANDLE = _WSAIOR(IOC_WS2, 24);
///
/// Requests notification of changes in information reported through SIO_ROUTING_INTERFACE_QUERY for the specified address.
///
[CorrespondingType(typeof(SOCKADDR), CorrespondingAction.Set)]
public static readonly uint SIO_ROUTING_INTERFACE_CHANGE = _WSAIOW(IOC_WS2, 21);
/// Obtains the address of the local interface that should be used to send to the specified address.
[CorrespondingType(typeof(SOCKADDR), CorrespondingAction.GetSet)]
public static readonly uint SIO_ROUTING_INTERFACE_QUERY = _WSAIORW(IOC_WS2, 20);
/// Reserved.
[CorrespondingType(typeof(QOS), CorrespondingAction.Set)]
public static readonly uint SIO_SET_GROUP_QOS = _WSAIOW(IOC_WS2, 12);
/// Establishes new flow specifications for the socket.
[CorrespondingType(typeof(QOS), CorrespondingAction.Set)]
public static readonly uint SIO_SET_QOS = _WSAIOW(IOC_WS2, 11);
/// Obtains a corresponding handle for socket s that is valid in the context of a companion interface.
[CorrespondingType(typeof(int), CorrespondingAction.Set)]
public static readonly uint SIO_TRANSLATE_HANDLE = _WSAIORW(IOC_WS2, 13);
/// set high watermark
public static readonly uint SIOCSHIWAT = _IOW('s', 0); /* set high watermark */
/// get high watermark
public static readonly uint SIOCGHIWAT = _IOR('s', 1); /* get high watermark */
/// set low watermark
public static readonly uint SIOCSLOWAT = _IOW('s', 2); /* set low watermark */
/// get low watermark
public static readonly uint SIOCGLOWAT = _IOR('s', 3); /* get low watermark */
///
/// Determine whether or not all OOB data has been read. This applies only to a socket of stream-style (for example, type
/// SOCK_STREAM) that has been configured for inline reception of any OOB data (SO_OOBINLINE). If no OOB data is waiting to be
/// read, the operation returns TRUE. Otherwise, it returns FALSE, and the next receive operation performed on the socket will
/// retrieve some or all of the data preceding the mark; the application should use the SIOCATMARK operation to determine whether
/// any remains. If there is any normal data preceding the urgent (out of band) data, it will be received in order. (Note that
/// recv operations will never mix OOB and normal data in the same call.) lpvOutBuffer points at a BOOL in which WSAIoctl stores
/// the result.
///
public static readonly uint SIOCATMARK = _IOR('s', 7); /* at oob mark? */
private const uint IOCPARM_MASK = 0x7f; /* parameters must be < 128 bytes */
private const uint IOC_VOID = 0x20000000; /* no parameters */
private const uint IOC_OUT = 0x40000000; /* copy out parameters */
private const uint IOC_IN = 0x80000000; /* copy in parameters */
private const uint IOC_INOUT = IOC_IN|IOC_OUT;
private const uint IOC_PROTOCOL = 0x10000000;
private const uint IOC_UNIX = 0x00000000;
private const uint IOC_VENDOR = 0x18000000;
private const uint IOC_WS2 = 0x08000000;
private const uint IOC_WSK = IOC_WS2 | 0x07000000;
private static uint _IO(uint x, uint y) => (IOC_VOID|((x)<<8)|(y));
private static uint _IOR(uint x, uint y) => (IOC_OUT|((sizeof(uint)&IOCPARM_MASK)<<16)|((x)<<8)|(y));
private static uint _IOW(uint x, uint y) => (IOC_IN|((sizeof(uint)&IOCPARM_MASK)<<16)|((x)<<8)|(y));
private static uint _WSAIO(uint x, uint y) => IOC_VOID | (x) | (y);
private static uint _WSAIOR(uint x, uint y) => IOC_OUT | (x) | (y);
private static uint _WSAIORW(uint x, uint y) => IOC_INOUT | (x) | (y);
private static uint _WSAIOW(uint x, uint y) => IOC_IN | (x) | (y);
}
}
}