82 lines
3.6 KiB
C#
82 lines
3.6 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.NetworkInformation;
|
|
using System.Net.Sockets;
|
|
|
|
namespace AMWD.Common.Utilities
|
|
{
|
|
/// <summary>
|
|
/// Provides some network utils.
|
|
/// </summary>
|
|
public static class NetworkHelper
|
|
{
|
|
/// <summary>
|
|
/// Tries to resolve a <paramref name="hostname"/> into an <see cref="IPAddress"/> to connect to.
|
|
/// </summary>
|
|
/// <param name="hostname">The hostname to resolve.</param>
|
|
/// <param name="addressFamily">An address family to use (available: <see cref="AddressFamily.InterNetwork"/> and <see cref="AddressFamily.InterNetworkV6"/>).</param>
|
|
/// <param name="fallback">The fallback ip address when resolving failed.</param>
|
|
/// <returns>The resolved <see cref="IPAddress"/> to connect to or <paramref name="fallback"/> value.</returns>
|
|
public static IPAddress ResolveHost(string hostname, AddressFamily addressFamily = AddressFamily.Unspecified, IPAddress fallback = null)
|
|
{
|
|
if (IPAddress.TryParse(hostname, out var ipAddress))
|
|
{
|
|
if (ipAddress.AddressFamily != AddressFamily.InterNetwork && ipAddress.AddressFamily != AddressFamily.InterNetworkV6)
|
|
return fallback;
|
|
|
|
if (addressFamily != AddressFamily.Unspecified && ipAddress.AddressFamily != addressFamily)
|
|
return fallback;
|
|
|
|
return ipAddress;
|
|
}
|
|
|
|
return Dns.GetHostAddresses(hostname)
|
|
.Where(a => a.AddressFamily == AddressFamily.InterNetwork || a.AddressFamily == AddressFamily.InterNetworkV6)
|
|
.Where(a => addressFamily == AddressFamily.Unspecified || a.AddressFamily == addressFamily)
|
|
.OrderBy(a => a.AddressFamily)
|
|
.FirstOrDefault() ?? fallback;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tries to resolve a <paramref name="iface"/> into an <see cref="IPAddress"/> to bind (listen) on.
|
|
/// </summary>
|
|
/// <param name="iface">The interface name to resolve.</param>
|
|
/// <param name="addressFamily">An address family to use (available: <see cref="AddressFamily.InterNetwork"/> and <see cref="AddressFamily.InterNetworkV6"/>).</param>
|
|
/// <param name="fallback">The fallback ip address when resolving failed.</param>
|
|
/// <returns>The resolved <see cref="IPAddress"/> to bind on or <paramref name="fallback"/> value.</returns>
|
|
public static IPAddress ResolveInterface(string iface, AddressFamily addressFamily = AddressFamily.Unspecified, IPAddress fallback = null)
|
|
{
|
|
if (IPAddress.TryParse(iface, out var ipAddress))
|
|
{
|
|
if (ipAddress.AddressFamily != AddressFamily.InterNetwork && ipAddress.AddressFamily != AddressFamily.InterNetworkV6)
|
|
return fallback;
|
|
|
|
if (addressFamily != AddressFamily.Unspecified && ipAddress.AddressFamily != addressFamily)
|
|
return fallback;
|
|
|
|
return ipAddress;
|
|
}
|
|
|
|
try
|
|
{
|
|
return Dns.GetHostAddresses(iface)
|
|
.Where(a => a.AddressFamily == AddressFamily.InterNetwork || a.AddressFamily == AddressFamily.InterNetworkV6)
|
|
.Where(a => addressFamily == AddressFamily.Unspecified || a.AddressFamily == addressFamily)
|
|
.OrderBy(a => a.AddressFamily)
|
|
.FirstOrDefault() ?? fallback;
|
|
}
|
|
catch (SocketException)
|
|
{
|
|
return NetworkInterface.GetAllNetworkInterfaces()
|
|
.Where(nic => nic.Name.Equals(iface, StringComparison.OrdinalIgnoreCase))
|
|
.SelectMany(nic => nic.GetIPProperties().UnicastAddresses.Select(ai => ai.Address))
|
|
.Where(a => a.AddressFamily == AddressFamily.InterNetwork || a.AddressFamily == AddressFamily.InterNetworkV6)
|
|
.Where(a => addressFamily == AddressFamily.Unspecified || a.AddressFamily == addressFamily)
|
|
.OrderBy(a => a.AddressFamily)
|
|
.FirstOrDefault() ?? fallback;
|
|
}
|
|
}
|
|
}
|
|
}
|