// %BANNER_BEGIN% // --------------------------------------------------------------------- // %COPYRIGHT_BEGIN% // Copyright (c) 2022-2023 Magic Leap, Inc. All Rights Reserved. // Use of this file is governed by the Magic Leap 2 Software License Agreement, located here: https://www.magicleap.com/software-license-agreement-ml2 // Terms and conditions applicable to third-party materials accompanying this distribution may also be found in the top-level NOTICE file appearing herein. // %COPYRIGHT_END% // --------------------------------------------------------------------- // %BANNER_END% using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; using UnityEngine; namespace MagicLeap.Spectator { public class NetworkHelper { public static bool TryGetLocalIPAddress(out IPAddress ipAddress, bool isDevice = false, bool verbose = false) { HashSet addresses = new(); try { addresses.UnionWith(NetworkInterface.GetAllNetworkInterfaces(). Where(x => x.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || x.NetworkInterfaceType == NetworkInterfaceType.Ethernet). Select(x => x.GetIPProperties().UnicastAddresses).SelectMany(x => x. Where(y => y.Address.AddressFamily == AddressFamily.InterNetwork). Select(z => z.Address))); } catch (Exception ex) { Debug.LogWarning($"NetworkHelper: TryGetLocalIPAddress() - NetworkInterface: {ex.Message}"); } #if !UNITY_EDITOR_OSX try { addresses.UnionWith(Dns.GetHostEntry(Dns.GetHostName()).AddressList. Where(x => x.AddressFamily == AddressFamily.InterNetwork)); } catch (Exception ex) { Debug.LogWarning($"NetworkHelper: TryGetLocalIPAddress() - Dns: {ex.Message}"); } #endif if (verbose) { foreach (var address in addresses) Debug.Log($"NetworkHelper: TryGetLocalIPAddress() - Found: {address}"); } var localIP = addresses.Where(IsIPAddressPrivate); if (isDevice) localIP = localIP.Where(x => x.ToString() != "192.168.168.3"); if (verbose) { foreach (var address in localIP) Debug.Log($"NetworkHelper: TryGetLocalIPAddress() - Local: {address}"); } ipAddress = localIP.FirstOrDefault(); return ipAddress != null; } public static bool IsIPAddressPrivate(IPAddress address) { byte[] ipParts = address.GetAddressBytes(); return ipParts[0] == 10 || (ipParts[0] == 192 && ipParts[1] == 168) || (ipParts[0] == 172 && ipParts[1] >= 16 && ipParts[1] <= 31); } public static IPAddress GetBroadcastAddress(IPAddress address, IPAddress subnetMask) { uint ipAddress = BitConverter.ToUInt32(address.GetAddressBytes(), 0); uint ipMaskV4 = BitConverter.ToUInt32(subnetMask.GetAddressBytes(), 0); uint broadCastIpAddress = ipAddress | ~ipMaskV4; return new IPAddress(BitConverter.GetBytes(broadCastIpAddress)); } public static bool VerifyConnection(IPAddress address, TcpClient socketConnection) { // Check if connection originated from the same local network IPEndPoint ipEndPoint = socketConnection.Client.RemoteEndPoint as IPEndPoint; IPAddress remoteIP = ipEndPoint.Address; IPAddress subnetMask = GetSubnetMask(address); if (subnetMask == null) { Debug.LogError("NetworkHelper - VerifyConnection(): Could not retrieve current subnet mask"); return false; } IPAddress currentNetworkAddress = GetNetworkAddress(address, subnetMask); IPAddress remoteNetworkAddress = GetNetworkAddress(remoteIP, subnetMask); return remoteNetworkAddress.Equals(currentNetworkAddress); } public static IPAddress GetNetworkAddress(IPAddress ipAddress, IPAddress subnetMask) { byte[] ipBytes = ipAddress.GetAddressBytes(); byte[] maskBytes = subnetMask.GetAddressBytes(); byte[] networkBytes = new byte[ipBytes.Length]; for (int i = 0; i < ipBytes.Length; i++) { networkBytes[i] = (byte)(ipBytes[i] & maskBytes[i]); } return new IPAddress(networkBytes); } public static IPAddress GetSubnetMask(IPAddress ipAddress) { NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); foreach (NetworkInterface networkInterface in networkInterfaces) { if (networkInterface.OperationalStatus == OperationalStatus.Up) { foreach (UnicastIPAddressInformation ip in networkInterface.GetIPProperties().UnicastAddresses) { if (ip.Address.Equals(ipAddress)) { return ip.IPv4Mask; } } } } return null; } public static string CleanupIP(string ip) { ip = new string(ip.ToCharArray().Where(c => !char.IsWhiteSpace(c)).ToArray()); if (string.IsNullOrWhiteSpace(ip)) return ip; string[] splitValues = ip.Split('.'); if (splitValues.Length != 4) return ip; byte tempForParsing; if (!splitValues.All(r => byte.TryParse(r, out tempForParsing))) return ip; string cleaned = string.Join(".", Array.ConvertAll(Array.ConvertAll(splitValues, r=> byte.Parse(r)), i => i.ToString())); return cleaned; } public static bool ValidateIPv4(string ip) { if (string.IsNullOrWhiteSpace(ip)) return false; string[] splitValues = ip.Split('.'); if (splitValues.Length != 4) return false; byte tempForParsing; return splitValues.All(r => byte.TryParse(r, out tempForParsing)); } public static int CompareIps(string ip1, string ip2) { bool thisValid = ValidateIPv4(ip1); bool otherValid = ValidateIPv4(ip2); if (!thisValid && !otherValid) return ip1.CompareTo(ip2); if (!thisValid) return 1; if (!otherValid) return -1; string[] comp_this = ip1.Split("."); string[] comp_other = ip2.Split("."); for (int i = 0; i < 4; ++i) { byte thisnumber = byte.Parse(comp_this[i]); byte othernumber = byte.Parse(comp_other[i]); if (thisnumber != othernumber) return thisnumber.CompareTo(othernumber); } return 0; } } }