From 2d0613516626960de5d7e3ea83b6386ce00dcb74 Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Sat, 23 May 2009 05:09:10 +0000 Subject: * Adds new NetworkUtil class, contains methods for handling IP resolution when located on the same subnet. (Eg, can be used to avoid NAT Loopback requirements if fully utilized.) * Adds a few new network-related methods to Util. --- OpenSim/Framework/NetworkUtil.cs | 122 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 OpenSim/Framework/NetworkUtil.cs (limited to 'OpenSim/Framework/NetworkUtil.cs') diff --git a/OpenSim/Framework/NetworkUtil.cs b/OpenSim/Framework/NetworkUtil.cs new file mode 100644 index 0000000..1abf0d8 --- /dev/null +++ b/OpenSim/Framework/NetworkUtil.cs @@ -0,0 +1,122 @@ +using System.Collections.Generic; +using System.Net.Sockets; +using System.Net; +using System.Net.NetworkInformation; + +namespace OpenSim.Framework +{ + /// + /// Handles NAT translation in a 'manner of speaking' + /// Allows you to return multiple different external + /// hostnames depending on the requestors network + /// + /// This enables standard port forwarding techniques + /// to work correctly with OpenSim. + /// + static class NetworkUtil + { + // IPv4Address, Subnet + static readonly Dictionary m_subnets = new Dictionary(); + + private static IPAddress GetExternalIPFor(IPAddress destination, string defaultHostname) + { + // Adds IPv6 Support (Not that any of the major protocols supports it...) + if (destination.AddressFamily == AddressFamily.InterNetworkV6) + { + foreach (IPAddress host in Dns.GetHostAddresses(defaultHostname)) + { + if (host.AddressFamily == AddressFamily.InterNetworkV6) + return host; + } + } + + if(destination.AddressFamily != AddressFamily.InterNetwork) + return null; + + // Check if we're accessing localhost. + foreach (IPAddress host in Dns.GetHostAddresses(Dns.GetHostName())) + { + if (host.Equals(destination)) + return destination; + } + + // Check for same LAN segment + foreach (KeyValuePair subnet in m_subnets) + { + byte[] subnetBytes = subnet.Value.GetAddressBytes(); + byte[] localBytes = subnet.Key.GetAddressBytes(); + byte[] destBytes = destination.GetAddressBytes(); + + if(subnetBytes.Length != destBytes.Length || subnetBytes.Length != localBytes.Length) + return null; + + bool valid = true; + + for(int i=0;i