using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using Sunfish.Config;
using Sunfish.Web;
namespace Sunfish.Net;
/// <summary>Una direccion local util para dar a otros equipos.</summary>
public sealed record LocalAddress(string Interface, NetworkInterfaceType Type, IPAddress Address);
public static class LocalAddresses
{
/// <summary>Direcciones de las interfaces activas, sin loopback (IPv4 primero).</summary>
public static List<LocalAddress> Get()
{
var result = new List<LocalAddress>();
NetworkInterface[] interfaces;
try
{
interfaces = NetworkInterface.GetAllNetworkInterfaces();
}
catch (NetworkInformationException)
{
return result;
}
foreach (var nic in interfaces)
{
if (nic.OperationalStatus != OperationalStatus.Up || nic.NetworkInterfaceType == NetworkInterfaceType.Loopback)
continue;
foreach (var unicast in nic.GetIPProperties().UnicastAddresses)
{
var address = unicast.Address;
if (IPAddress.IsLoopback(address))
continue;
if (address.AddressFamily == AddressFamily.InterNetworkV6 && address.IsIPv6LinkLocal)
continue;
if (address.AddressFamily is AddressFamily.InterNetwork or AddressFamily.InterNetworkV6)
result.Add(new LocalAddress(nic.Name, nic.NetworkInterfaceType, address));
}
}
return result.OrderBy(a => a.Address.AddressFamily == AddressFamily.InterNetwork ? 0 : 1).ToList();
}
/// <summary>URL de un share en una direccion: http://192.168.1.10:8080/fotos/</summary>
public static string HttpUrl(IPAddress address, int port, ShareConfig? share = null)
{
string host = address.AddressFamily == AddressFamily.InterNetworkV6 ? $"[{address}]" : address.ToString();
string path = "/";
if (share is not null && share.Location != "/")
path = "/" + string.Join('/', share.Location.Split('/', StringSplitOptions.RemoveEmptyEntries).Select(HtmlBuilder.UrlSegment)) + "/";
return port == 80 ? $"http://{host}{path}" : $"http://{host}:{port}{path}";
}
/// <summary>URL FTP de un share: ftp://192.168.1.10:2121/fotos/</summary>
public static string FtpUrl(IPAddress address, int port, ShareConfig? share = null)
{
string http = HttpUrl(address, 80, share);
string rest = http["http://".Length..];
int slash = rest.IndexOf('/');
string host = rest[..slash];
return port == 21 ? $"ftp://{host}{rest[slash..]}" : $"ftp://{host}:{port}{rest[slash..]}";
}
}