From 8d2a2cd5de40e2b94ef5007c32832ed9a063dc40 Mon Sep 17 00:00:00 2001 From: chai <215380520@qq.com> Date: Thu, 12 Oct 2023 22:09:49 +0800 Subject: +hazel-networking --- Tools/Hazel-Networking/Hazel/UPnP/NetUtility.cs | 158 ++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 Tools/Hazel-Networking/Hazel/UPnP/NetUtility.cs (limited to 'Tools/Hazel-Networking/Hazel/UPnP/NetUtility.cs') diff --git a/Tools/Hazel-Networking/Hazel/UPnP/NetUtility.cs b/Tools/Hazel-Networking/Hazel/UPnP/NetUtility.cs new file mode 100644 index 0000000..d856823 --- /dev/null +++ b/Tools/Hazel-Networking/Hazel/UPnP/NetUtility.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Generic; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; + +namespace Hazel.UPnP +{ + internal class NetUtility + { + private static IList GetValidNetworkInterfaces() + { + var nics = NetworkInterface.GetAllNetworkInterfaces(); + if (nics == null || nics.Length < 1) + return new NetworkInterface[0]; + + var validInterfaces = new List(nics.Length); + + NetworkInterface best = null; + foreach (NetworkInterface adapter in nics) + { + if (adapter.NetworkInterfaceType == NetworkInterfaceType.Loopback || adapter.NetworkInterfaceType == NetworkInterfaceType.Unknown) + continue; + if (!adapter.Supports(NetworkInterfaceComponent.IPv4) && !adapter.Supports(NetworkInterfaceComponent.IPv6)) + continue; + if (best == null) + best = adapter; + if (adapter.OperationalStatus != OperationalStatus.Up) + continue; + + // make sure this adapter has any ip addresses + IPInterfaceProperties properties = adapter.GetIPProperties(); + foreach (UnicastIPAddressInformation unicastAddress in properties.UnicastAddresses) + { + if (unicastAddress != null && unicastAddress.Address != null) + { + // Yes it does, add this network interface. + validInterfaces.Add(adapter); + break; + } + } + } + + if (validInterfaces.Count == 0 && best != null) + validInterfaces.Add(best); + + return validInterfaces; + } + + /// + /// Gets the addresses from all active network interfaces, but at most one per interface. + /// + /// The of the addresses to return + /// An of . + public static ICollection GetAddressesFromNetworkInterfaces(AddressFamily addressFamily) + { + var unicastAddresses = new List(); + + foreach (NetworkInterface adapter in GetValidNetworkInterfaces()) + { + IPInterfaceProperties properties = adapter.GetIPProperties(); + foreach (UnicastIPAddressInformation unicastAddress in properties.UnicastAddresses) + { + if (unicastAddress != null && unicastAddress.Address != null && unicastAddress.Address.AddressFamily == addressFamily) + { + unicastAddresses.Add(unicastAddress); + break; + } + } + } + + return unicastAddresses; + } + + /// + /// Gets my local IPv4 address (not necessarily external) and subnet mask + /// + public static IPAddress GetMyAddress(out IPAddress mask) + { + var networkInterfaces = GetValidNetworkInterfaces(); + IPInterfaceProperties properties = null; + + if (networkInterfaces.Count > 0) + properties = networkInterfaces[0]?.GetIPProperties(); + + if (properties != null) + { + foreach (UnicastIPAddressInformation unicastAddress in properties.UnicastAddresses) + { + if (unicastAddress != null && unicastAddress.Address != null && unicastAddress.Address.AddressFamily == AddressFamily.InterNetwork) + { + mask = unicastAddress.IPv4Mask; + return unicastAddress.Address; + } + } + } + + mask = null; + return null; + } + + /// + /// Gets the broadcast address for the first network interface or, if not able to, + /// the limited broadcast address. + /// + /// An for broadcasting. + public static IPAddress GetBroadcastAddress() + { + var networkInterfaces = GetValidNetworkInterfaces(); + IPInterfaceProperties properties = null; + + if (networkInterfaces.Count > 0) + properties = networkInterfaces[0]?.GetIPProperties(); + + if (properties != null) + { + foreach (UnicastIPAddressInformation unicastAddress in properties.UnicastAddresses) + { + IPAddress ipAddress = GetBroadcastAddress(unicastAddress); + if (ipAddress != null) + { + return ipAddress; + } + } + } + + return IPAddress.Broadcast; + } + + /// + /// Gets the broadcast address for the given . + /// + /// A + /// An for broadcasting, null if the + /// is not an IPv4 address. + public static IPAddress GetBroadcastAddress(UnicastIPAddressInformation unicastAddress) + { + if (unicastAddress != null && unicastAddress.Address != null && unicastAddress.Address.AddressFamily == AddressFamily.InterNetwork) + { + var mask = unicastAddress.IPv4Mask; + byte[] ipAdressBytes = unicastAddress.Address.GetAddressBytes(); + byte[] subnetMaskBytes = mask.GetAddressBytes(); + + if (ipAdressBytes.Length != subnetMaskBytes.Length) + throw new ArgumentException("Lengths of IP address and subnet mask do not match."); + + byte[] broadcastAddress = new byte[ipAdressBytes.Length]; + for (int i = 0; i < broadcastAddress.Length; i++) + { + broadcastAddress[i] = (byte)(ipAdressBytes[i] | (subnetMaskBytes[i] ^ 255)); + } + return new IPAddress(broadcastAddress); + } + + return null; + } + } +} -- cgit v1.1-26-g67d0