/// <summary> /// Reads the unmanaged sockaddr structure returned by a WinAPI function /// </summary> /// <param name="pSockaddrStructure">pointer to the unmanaged sockaddr structure</param> /// <returns>IP address and port number</returns> private static IPEndPoint ReadSockAddrStorageStructure(SOCKADDR_STORAGE sockAddrStorageStructure) { short sAddressFamily = sockAddrStorageStructure.ss_family; AddressFamily addressFamily = (AddressFamily)sAddressFamily; int sockAddrSructureSize; IPEndPoint ipEndPointAny; switch (addressFamily) { case AddressFamily.InterNetwork: // IP v4 address sockAddrSructureSize = 8; var socketAddress = new SocketAddress(AddressFamily.InterNetwork, sockAddrSructureSize); socketAddress[0] = 2; socketAddress[1] = 0; for (int i = 2; i < sockAddrSructureSize; i++) { socketAddress[i] = sockAddrStorageStructure.__ss_pad1[i - 2]; } ipEndPointAny = new IPEndPoint(IPAddress.Any, 0); return((IPEndPoint)ipEndPointAny.Create(socketAddress)); default: throw new ArgumentOutOfRangeException(nameof(sockAddrStorageStructure), "Unknown address family"); } }
//******************************************************************************************** // Function: GetPreferredAddress // // Description: This function sorts a list of Ipv4 & Ipv6 addresses, and returns the "best" address that stack determines // //******************************************************************************************** static Win32Error GetPreferredAddress(SOCKADDR_IN6[] pAddrList, out SOCKADDR_STORAGE pPreferredAddr) { Win32Error dwErr = Win32Error.ERROR_SUCCESS; pPreferredAddr = default; // Initialize WinSock using var wsa = SafeWSA.Initialize(); // create socket var socketIoctl = WSASocket(ADDRESS_FAMILY.AF_INET6, SOCK.SOCK_DGRAM, 0, IntPtr.Zero, 0, WSA_FLAG.WSA_FLAG_OVERLAPPED); if (socketIoctl == SOCKET.INVALID_SOCKET) { dwErr = WSAGetLastError(); Console.Write("WSASocket failed, (dwErr = {0}).", dwErr); return(dwErr); } var numElement = pAddrList.Length; var pSockAddrList = Array.ConvertAll(pAddrList, v6 => new SOCKADDR(v6)); var pSocketAddrList = new SOCKET_ADDRESS_LIST { iAddressCount = numElement, Address = Array.ConvertAll(pSockAddrList, sa => new SOCKET_ADDRESS { iSockaddrLength = sa.Size, lpSockaddr = sa.DangerousGetHandle() }) }; // sort addresses using var ppSocketAddrList = SafeHGlobalHandle.CreateFromStructure(pSocketAddrList); uint dwSize = 4U + (uint)(Marshal.SizeOf <SOCKET_ADDRESS>() * pSocketAddrList.iAddressCount); dwErr = WSAIoctl(socketIoctl, WinSockIOControlCode.SIO_ADDRESS_LIST_SORT, ppSocketAddrList, dwSize, ppSocketAddrList, dwSize, out var dwBytes); pSocketAddrList = ppSocketAddrList.ToStructure <SOCKET_ADDRESS_LIST>(); if (dwErr == SOCKET_ERROR) { dwErr = WSAGetLastError(); Console.Write("WSAIoctl sort address failed, (dwErr = {0}).", dwErr); return(dwErr); } var pBestAddress = new IPAddress(pSocketAddrList.Address[0].lpSockaddr.ToArray <byte>(pSocketAddrList.Address[0].iSockaddrLength)); pPreferredAddr = (SOCKADDR_STORAGE)(pBestAddress.IsIPv4MappedToIPv6 ? pBestAddress.MapToIPv4() : pBestAddress); if (socketIoctl != SOCKET.INVALID_SOCKET) { closesocket(socketIoctl); socketIoctl = SOCKET.INVALID_SOCKET; } return(dwErr); }
//******************************************************************************************** // Function: ConvertStringToSockAddr // // Description: Converts destination hostname or URL to IP address // //******************************************************************************************** static HRESULT ConvertStringToSockAddr([In] string destIPAddr, out SOCKADDR_STORAGE socketAddress) { const int NO_ERROR = 0; HRESULT hr = HRESULT.S_OK; socketAddress = default; //Intialize socket, to use GetAddrInfoW() using var wsa = SafeWSA.Initialize(); //This do--while(false) loop is used to break in between based on error conditions do { //get Destination IP address from Destination address string hostname or URL var dwErr = GetAddrInfoW(destIPAddr, default, default, out var result);
private static SOCKADDR_STORAGE CreateSockAddrStorageStructure(int port) { var result = new SOCKADDR_STORAGE(); result.ss_family = (short)AddressFamily.InterNetwork; var ipEndPoint = new IPEndPoint(IPAddress.Any, port); var socketAddress = ipEndPoint.Serialize(); result.__ss_pad1 = new byte[6]; for (var i = 0; i < result.__ss_pad1.Length; i++) { result.__ss_pad1[i] = socketAddress[i + 2]; } return(result); }
/// <summary> /// Reads the unmanaged sockaddr structure returned by a WinAPI function /// </summary> /// <param name="pSockaddrStructure">pointer to the unmanaged sockaddr structure</param> /// <returns>IP address and port number</returns> private static IPEndPoint ReadSockAddrStorageStructure(SOCKADDR_STORAGE sockAddrStorageStructure) { short sAddressFamily = sockAddrStorageStructure.ss_family; AddressFamily addressFamily = (AddressFamily)sAddressFamily; int sockAddrSructureSize; IPEndPoint ipEndPointAny; switch (addressFamily) { case AddressFamily.InterNetwork: // IP v4 address sockAddrSructureSize = 8; var socketAddress = new SocketAddress(AddressFamily.InterNetwork, sockAddrSructureSize); socketAddress[0] = 2; socketAddress[1] = 0; for (int i = 2; i < sockAddrSructureSize; i++) { socketAddress[i] = sockAddrStorageStructure.__ss_pad1[i - 2]; } ipEndPointAny = new IPEndPoint(IPAddress.Any, 0); return (IPEndPoint)ipEndPointAny.Create(socketAddress); default: throw new ArgumentOutOfRangeException(nameof(sockAddrStorageStructure), "Unknown address family"); } }
private static SOCKADDR_STORAGE CreateSockAddrStorageStructure(int port) { var result = new SOCKADDR_STORAGE(); result.ss_family = (short)AddressFamily.InterNetwork; var ipEndPoint = new IPEndPoint(IPAddress.Any, port); var socketAddress = ipEndPoint.Serialize(); result.__ss_pad1 = new byte[6]; for (var i = 0; i < result.__ss_pad1.Length; i++) { result.__ss_pad1[i] = socketAddress[i + 2]; } return result; }