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.