diff --git a/PInvoke/Ws2_32/ws2ipdef.cs b/PInvoke/Ws2_32/ws2ipdef.cs index 6619db44..39dc018b 100644 --- a/PInvoke/Ws2_32/ws2ipdef.cs +++ b/PInvoke/Ws2_32/ws2ipdef.cs @@ -3,6 +3,7 @@ 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 @@ -190,6 +191,163 @@ namespace Vanara.PInvoke public SOCKADDR_STORAGE[] gf_slist; } + /// + /// The in_pktinfo structure is used to store received packet address information, and is used by Windows to return + /// information about received packets and also allows specifying the local IPv4 address to use for sending packets. + /// + /// + /// + /// If the IP_PKTINFO socket option is set on a socket of type SOCK_DGRAM or SOCK_RAW, one of the control data objects + /// returned by the LPFN_WSARECVMSG (WSARecvMsg) function will contain an in_pktinfo structure used to store received packet + /// address information. + /// + /// + /// On an IPv4 socket of type SOCK_DGRAM or SOCK_RAW, an application can specific the local IP address to use for + /// sending with the WSASendMsg function. One of the control data objects passed in the WSAMSG structure to the WSASendMsg + /// function may contain an in_pktinfo structure used to specify the local IPv4 address to use for sending. + /// + /// + /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files + /// has changed and the in_pktinfo structure is defined in the Ws2ipdef.h header file which is automatically included + /// in the Ws2tcpip.h header file. The Ws2ipdef.h header files should never be used directly. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-in_pktinfo typedef struct in_pktinfo { IN_ADDR ipi_addr; + // ULONG ipi_ifindex; } IN_PKTINFO, *PIN_PKTINFO; + [PInvokeData("ws2ipdef.h", MSDNShortId = "NS:ws2ipdef.in_pktinfo")] + [StructLayout(LayoutKind.Sequential)] + public struct IN_PKTINFO + { + /// + /// The destination IPv4 address from the IP header of the received packet when used with the LPFN_WSARECVMSG (WSARecvMsg) + /// function. The local source IPv4 address to set in the IP header when used with the WSASendMsg function. + /// + public IN_ADDR ipi_addr; + + /// + /// The interface on which the packet was received when used with the LPFN_WSARECVMSG (WSARecvMsg) function. The interface on + /// which the packet should be sent when used with the WSASendMsg function. + /// + public uint ipi_ifindex; + } + + /// + /// The in6_pktinfo structure is used to store received IPv6 packet address information, and is used by Windows to return + /// information about received packets and also allows specifying the local IPv6 address to use for sending packets. + /// + /// + /// + /// If the IPV6_PKTINFO socket option is set on a socket of type SOCK_DGRAM or SOCK_RAW, one of the control data + /// objects returned by the LPFN_WSARECVMSG (WSARecvMsg) function will contain an in6_pktinfo structure used to store received + /// packet address information. + /// + /// + /// On an IPv6 socket of type SOCK_DGRAM or SOCK_RAW, an application can specific the local IP source address to use + /// for sending with the WSASendMsg function. One of the control data objects passed in the WSAMSG structure to the WSASendMsg + /// function may contain an in6_pktinfo structure used to specify the local IPv6 address to use for sending. + /// + /// + /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files + /// has changed and the in6_pktinfo structure is defined in the Ws2ipdef.h header file which is automatically included + /// in the Ws2tcpip.h header file. The Ws2ipdef.h header files should never be used directly. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-in6_pktinfo typedef struct in6_pktinfo { IN6_ADDR + // ipi6_addr; ULONG ipi6_ifindex; } IN6_PKTINFO, *PIN6_PKTINFO; + [PInvokeData("ws2ipdef.h", MSDNShortId = "NS:ws2ipdef.in6_pktinfo")] + [StructLayout(LayoutKind.Sequential)] + public struct IN6_PKTINFO + { + /// + /// The destination IPv6 address from the IP header of the received packet when used with the LPFN_WSARECVMSG (WSARecvMsg) + /// function. The local source IPv6 address to set in the IP header when used with the WSASendMsg function. + /// + public IN6_ADDR ipi6_addr; + + /// + /// The interface on which the packet was received when used with the LPFN_WSARECVMSG (WSARecvMsg) function. The interface on + /// which the packet should be sent when used with the WSASendMsg function. + /// + public uint ipi6_ifindex; + } + + /// The ip_mreq structure provides multicast group information for IPv4 addresses. + /// + /// + /// The ip_mreq structure is used with IPv4 addresses. The ip_mreq structure is used with the IP_ADD_MEMBERSHIP and + /// IP_DROP_MEMBERSHIP socket options. + /// + /// + /// The ip_mreq structure and related structures used for IPv4 multicast programming are based on IETF recommendations in + /// sections 4 and 8.1 of RFC 3768. For more information, see http://www.ietf.org/rfc/rfc3678.txt. + /// + /// + /// For more configurable multicast capabilities with IPv4, use the ip_mreq_source structure. See Multicast Programming for more information. + /// + /// + /// On Windows Vista and later, a set of socket options are available for multicast programming that support IPv6 and IPv4 addresses. + /// These socket options are IP agnostic and can be used on both IPv6 and IPv4. These IP agnostic options use the GROUP_REQ and the + /// GROUP_SOURCE_REQ structures and are the preferred socket options for multicast programming on Windows Vista and later. + /// + /// The ip_mreq structure is the IPv4 equivalent of the IPv6-based ipv6_mreq structure. + /// + /// The imr_interface member can be an interface index. Any IP address in the 0.x.x.x block (first octet of 0) except for the + /// IP address of 0.0.0.0 is treated as an interface index. An interface index is a 24-bit number. The 0.0.0.0/8 IPv4 address block + /// is not used (this range is reserved). The GetAdaptersAddresses function can be used to obtain interface index information to use + /// for the imr_interface member. + /// + /// + /// It is recommended that a local IPv4 address or interface index always be specified in the imr_interface member of the + /// ip_mreq structure, rather than use the default interface. This is particularly important on computers with multiple + /// network interfaces and multiple public IPv4 addresses. + /// + /// + /// The default interface used for IPv4 multicast is determined by the networking stack in Windows. An application can determine the + /// default interface used for IPv4 multicast using the GetIpForwardTable function to retrieve the IPv4 routing table. The network + /// interface with the lowest value for the routing metric for a destination IP address of 224.0.0.0 is the default interface for + /// IPv4 multicast. The routing table can also be displayed from the command prompt with the following command: + /// + /// route print + /// + /// The IP_MULTICAST_IF socket option can be used to set the default interface to send IPv4 multicast packets. This socket option + /// does not change the default interface used to receive IPv4 multicast packets. + /// + /// + /// A typical IPv4 multicast application would use the IP_ADD_MEMBERSHIP socket option with the ip_mreq structure to join a + /// multicast group and listen for multicast packets on a specific interface. The IP_MULTICAST_IF socket option would be used + /// to set the interface to send IPv4 multicast packets to the multicast group. The most common scenario would be a multicast + /// application that listens and sends on the same interface for a multicast group. Multiple sockets might be used by a multicast + /// application with one socket for listening and one or more sockets for sending. + /// + /// + /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files + /// has changed and the ip_mreq structure is defined in the Ws2ipdef.h header file which is automatically included in + /// the Ws2tcpip.h header file. The Ws2ipdef.h header files should never be used directly. + /// + /// + /// Note The IP_MREQ and PIP_MREQ derived structures are only defined on the Windows SDK released with Windows + /// Vista and later. The ip_mreq structure should be used on earlier versions of the Windows SDK. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-ip_mreq typedef struct ip_mreq { IN_ADDR imr_multiaddr; + // IN_ADDR imr_interface; } IP_MREQ, *PIP_MREQ; + [PInvokeData("ws2ipdef.h", MSDNShortId = "NS:ws2ipdef.ip_mreq")] + [StructLayout(LayoutKind.Sequential)] + public struct IP_MREQ + { + /// The address of the IPv4 multicast group. + public IN_ADDR imr_multiaddr; + + /// + /// + /// The local IPv4 address of the interface or the interface index on which the multicast group should be joined or dropped. This + /// value is in network byte order. If this member specifies an IPv4 address of 0.0.0.0, the default IPv4 multicast interface is used. + /// + /// To use an interface index of 1 would be the same as an IP address of 0.0.0.1. + /// + public IN_ADDR imr_interface; + } + /// The ip_msfilter structure provides multicast filtering parameters for IPv4 addresses. /// /// @@ -286,6 +444,77 @@ namespace Vanara.PInvoke public IN_ADDR[] imsf_slist; } + /// The ipv6_mreq structure provides multicast group information for IPv6 addresses. + /// + /// + /// The ipv6_mreq structure is used with IPv6 addresses. The ipv6_mreq structure is used with the IPV6_ADD_MEMBERSHIP, + /// IPV6_DROP_MEMBERSHIP, IPV6_JOIN_GROUP, and IPV6_LEAVE_GROUP socket options. The IPV6_JOIN_GROUP and + /// IPV6_ADD_MEMBERSHIP socket options are defined to be the same. The IPV6_LEAVE_GROUP and IPV6_DROP_MEMBERSHIP + /// socket options are defined to be the same. + /// + /// + /// On Windows Vista and later, a set of socket options are available for multicast programming that support IPv6 and IPv4 addresses. + /// These socket options are IP agnostic and can be used on both IPv6 and IPv4. These IP agnostic options use the GROUP_REQ and the + /// GROUP_SOURCE_REQ structures and are the preferred socket options for multicast programming on Windows Vista and later. + /// + /// The ipv6_mreq structure is the IPv6 equivalent of the IPv4-based ip_mreq structure. + /// + /// The GetAdaptersAddresses function can be used to obtain interface index information required for the ipv6mr_interface member. + /// + /// + /// The ipv6_mreq structure and the IPPROTO_IPV6 level socket options that use this structure are only valid on + /// datagram and raw sockets (the socket type must be SOCK_DGRAM or SOCK_RAW). + /// + /// + /// It is recommended that a local IPv6 interface index always be specified in the ipv6mr_interface member of the + /// ipv6_mreq structure, rather than use the default interface. This is particularly important on computers with multiple + /// network interfaces and multiple public IPv6 addresses. + /// + /// + /// The default interface used for IPv6 multicast is determined by the networking stack in Windows. On Windows Vista and later, an + /// application can determine the default interface used for IPv6 multicast using the GetIpForwardTable2 function to retrieve the + /// IPv6 routing table. The network interface with the lowest value for the routing metric for a destination IPv6 multicast address + /// (the FF00::/8 IPv6 address block) is the default interface for IPv6 multicast. The routing table can also be displayed from the + /// command prompt with the following command: + /// + /// route print + /// + /// The IPV6_MULTICAST_IF socket option can be used to set the default interface to send IPv6 multicast packets. This socket option + /// does not change the default interface used to receive IPv6 multicast packets. + /// + /// + /// A typical IPv6 multicast application would use the IPV6_ADD_MEMBERSHIP or IPV6_JOIN_GROUP socket option with the + /// ipv6_mreq structure to join a multicast group and listen for multicast packets on a specific interface. The + /// IPV6_MULTICAST_IF socket option would be used to set the interface to send IPv6 multicast packets to the multicast group. + /// The most common scenario would be a multicast application that listens and sends on the same interface for a multicast group. + /// Multiple sockets might be used by a multicast application with one socket for listening and one or more sockets for sending. + /// + /// + /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files + /// has changed and the ipv6_mreq structure is defined in the Ws2ipdef.h header file which is automatically included in + /// the Ws2tcpip.h header file. The Ws2ipdef.h header files should never be used directly. + /// + /// + /// Note The PIP6_MREQ derived structure is only defined on the Windows SDK released with Windows Vista and later. The + /// GROUP_REQ and the GROUP_SOURCE_REQ structures and are the preferred socket options for multicast programming on Windows Vista and later. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-ipv6_mreq typedef struct ipv6_mreq { IN6_ADDR + // ipv6mr_multiaddr; ULONG ipv6mr_interface; } IPV6_MREQ, *PIPV6_MREQ; + [PInvokeData("ws2ipdef.h", MSDNShortId = "NS:ws2ipdef.ipv6_mreq")] + [StructLayout(LayoutKind.Sequential)] + public struct IPV6_MREQ + { + /// The address of the IPv6 multicast group. + public IN6_ADDR ipv6mr_multiaddr; + + /// + /// The interface index of the local interface on which the multicast group should be joined or dropped. If this member specifies + /// an interface index of 0, the default multicast interface is used. + /// + public uint ipv6mr_interface; + } + /// The SOCKADDR_IN6 structure specifies a transport address and port for the AF_INET6 address family. /// /// @@ -350,7 +579,7 @@ namespace Vanara.PInvoke /// Performs an implicit conversion from to . /// The address. /// The resulting instance from the conversion. - public static implicit operator SOCKADDR_IN6(IN6_ADDR addr) => new SOCKADDR_IN6(addr, 0); + public static implicit operator SOCKADDR_IN6(IN6_ADDR addr) => new(addr, 0); /// public override string ToString() => $"{sin6_addr}" + (sin6_scope_id == 0 ? "" : "%" + sin6_scope_id.ToString()) + $":{sin6_port}"; @@ -377,10 +606,10 @@ namespace Vanara.PInvoke public struct SOCKADDR_IN6_PAIR { /// The source address - private IntPtr _SourceAddress; + private readonly IntPtr _SourceAddress; /// The destination address - private IntPtr _DestinationAddress; + private readonly IntPtr _DestinationAddress; /// /// A pointer to an IP source address represented as a SOCKADDR_IN6 structure. The address family is in host byte order and the @@ -400,7 +629,8 @@ namespace Vanara.PInvoke /// The unmanaged value. /// The resulting instance from the conversion. public static implicit operator SOCKADDR_IN6_PAIR_NATIVE(SOCKADDR_IN6_PAIR unmgd) => - new SOCKADDR_IN6_PAIR_NATIVE { SourceAddress = unmgd.SourceAddress, DestinationAddress = unmgd.DestinationAddress }; + new() + { SourceAddress = unmgd.SourceAddress, DestinationAddress = unmgd.DestinationAddress }; /// Converts to string. /// A that represents this instance. @@ -497,6 +727,9 @@ namespace Vanara.PInvoke [FieldOffset(0)] public ADDRESS_FAMILY si_family; + /// Gets the size of the actual address (not necessarily the size of the structure). + public int Size => si_family == ADDRESS_FAMILY.AF_INET ? Marshal.SizeOf(typeof(SOCKADDR_IN)) : Marshal.SizeOf(typeof(SOCKADDR_IN6)); + /// Specifies whether this instance is equal to the specified object. /// The object to test for equality. /// if is equal to this instance. @@ -515,12 +748,12 @@ namespace Vanara.PInvoke /// Performs an implicit conversion from to . /// The address. /// The resulting instance from the conversion. - public static implicit operator SOCKADDR_INET(SOCKADDR_IN address) => new SOCKADDR_INET { Ipv4 = address }; + public static implicit operator SOCKADDR_INET(SOCKADDR_IN address) => new() { Ipv4 = address }; /// Performs an implicit conversion from to . /// The address. /// The resulting instance from the conversion. - public static implicit operator SOCKADDR_INET(SOCKADDR_IN6 address) => new SOCKADDR_INET { Ipv6 = address }; + public static implicit operator SOCKADDR_INET(SOCKADDR_IN6 address) => new() { Ipv6 = address }; /// Converts to string. /// A that represents this instance.