1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
4 using System.Net.Sockets;
5 using static System.Net.Quic.Implementations.MsQuic.Internal.MsQuicNativeMethods;
7 namespace System.Net.Quic.Implementations.MsQuic.Internal
9 internal static class MsQuicAddressHelpers
11 internal const ushort IPv4 = 2;
12 internal const ushort IPv6 = 23;
14 internal static unsafe IPEndPoint INetToIPEndPoint(SOCKADDR_INET inetAddress)
16 if (inetAddress.si_family == IPv4)
18 return new IPEndPoint(new IPAddress(inetAddress.Ipv4.Address), (ushort)IPAddress.NetworkToHostOrder((short)inetAddress.Ipv4.sin_port));
22 return new IPEndPoint(new IPAddress(inetAddress.Ipv6.Address), (ushort)IPAddress.NetworkToHostOrder((short)inetAddress.Ipv6._port));
26 internal static SOCKADDR_INET IPEndPointToINet(IPEndPoint endpoint)
28 SOCKADDR_INET socketAddress = default;
29 byte[] buffer = endpoint.Address.GetAddressBytes();
30 if (endpoint.Address != IPAddress.Any && endpoint.Address != IPAddress.IPv6Any)
32 switch (endpoint.Address.AddressFamily)
34 case AddressFamily.InterNetwork:
35 socketAddress.Ipv4.sin_addr0 = buffer[0];
36 socketAddress.Ipv4.sin_addr1 = buffer[1];
37 socketAddress.Ipv4.sin_addr2 = buffer[2];
38 socketAddress.Ipv4.sin_addr3 = buffer[3];
39 socketAddress.Ipv4.sin_family = IPv4;
41 case AddressFamily.InterNetworkV6:
42 socketAddress.Ipv6._addr0 = buffer[0];
43 socketAddress.Ipv6._addr1 = buffer[1];
44 socketAddress.Ipv6._addr2 = buffer[2];
45 socketAddress.Ipv6._addr3 = buffer[3];
46 socketAddress.Ipv6._addr4 = buffer[4];
47 socketAddress.Ipv6._addr5 = buffer[5];
48 socketAddress.Ipv6._addr6 = buffer[6];
49 socketAddress.Ipv6._addr7 = buffer[7];
50 socketAddress.Ipv6._addr8 = buffer[8];
51 socketAddress.Ipv6._addr9 = buffer[9];
52 socketAddress.Ipv6._addr10 = buffer[10];
53 socketAddress.Ipv6._addr11 = buffer[11];
54 socketAddress.Ipv6._addr12 = buffer[12];
55 socketAddress.Ipv6._addr13 = buffer[13];
56 socketAddress.Ipv6._addr14 = buffer[14];
57 socketAddress.Ipv6._addr15 = buffer[15];
58 socketAddress.Ipv6._family = IPv6;
61 throw new ArgumentException("Only IPv4 or IPv6 are supported");
65 SetPort(endpoint.Address.AddressFamily, ref socketAddress, endpoint.Port);
69 private static void SetPort(AddressFamily addressFamily, ref SOCKADDR_INET socketAddrInet, int originalPort)
71 ushort convertedPort = (ushort)IPAddress.HostToNetworkOrder((short)originalPort);
72 switch (addressFamily)
74 case AddressFamily.InterNetwork:
75 socketAddrInet.Ipv4.sin_port = convertedPort;
77 case AddressFamily.InterNetworkV6:
79 socketAddrInet.Ipv6._port = convertedPort;