You've already forked lidgren-network-gen3
mirror of
https://github.com/lidgren/lidgren-network-gen3.git
synced 2026-05-06 02:11:06 +09:00
276 lines
7.9 KiB
C#
276 lines
7.9 KiB
C#
/* Copyright (c) 2010 Michael Lidgren
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
|
and associated documentation files (the "Software"), to deal in the Software without
|
|
restriction, including without limitation the rights to use, copy, modify, merge, publish,
|
|
distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom
|
|
the Software is furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all copies or
|
|
substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
|
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
*/
|
|
using System;
|
|
using System.Net;
|
|
using System.Net.NetworkInformation;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Lidgren.Network
|
|
{
|
|
/// <summary>
|
|
/// Utility methods
|
|
/// </summary>
|
|
public static class NetUtility
|
|
{
|
|
private static Regex s_regIP;
|
|
|
|
/// <summary>
|
|
/// Get IP endpoint from notation (xxx.xxx.xxx.xxx) or hostname and port number
|
|
/// </summary>
|
|
public static IPEndPoint Resolve(string ipOrHost, int port)
|
|
{
|
|
IPAddress adr = Resolve(ipOrHost);
|
|
return new IPEndPoint(adr, port);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get IP address from notation (xxx.xxx.xxx.xxx) or hostname
|
|
/// </summary>
|
|
public static IPAddress Resolve(string ipOrHost)
|
|
{
|
|
if (string.IsNullOrEmpty(ipOrHost))
|
|
throw new ArgumentException("Supplied string must not be empty", "ipOrHost");
|
|
|
|
ipOrHost = ipOrHost.Trim();
|
|
|
|
if (s_regIP == null)
|
|
{
|
|
string expression = "\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b";
|
|
RegexOptions options = RegexOptions.Compiled;
|
|
s_regIP = new Regex(expression, options);
|
|
}
|
|
|
|
// is it an ip number string?
|
|
IPAddress ipAddress = null;
|
|
if (s_regIP.Match(ipOrHost).Success && IPAddress.TryParse(ipOrHost, out ipAddress))
|
|
return ipAddress;
|
|
|
|
// ok must be a host name
|
|
IPHostEntry entry;
|
|
try
|
|
{
|
|
entry = Dns.GetHostEntry(ipOrHost);
|
|
if (entry == null)
|
|
return null;
|
|
|
|
// check each entry for a valid IP address
|
|
foreach (IPAddress ipCurrent in entry.AddressList)
|
|
{
|
|
string sIP = ipCurrent.ToString();
|
|
bool isIP = s_regIP.Match(sIP).Success && IPAddress.TryParse(sIP, out ipAddress);
|
|
if (isIP)
|
|
break;
|
|
}
|
|
if (ipAddress == null)
|
|
return null;
|
|
|
|
return ipAddress;
|
|
}
|
|
catch (SocketException ex)
|
|
{
|
|
if (ex.SocketErrorCode == SocketError.HostNotFound)
|
|
{
|
|
//LogWrite(string.Format(CultureInfo.InvariantCulture, "Failed to resolve host '{0}'.", ipOrHost));
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static NetworkInterface GetNetworkInterface()
|
|
{
|
|
IPGlobalProperties computerProperties = IPGlobalProperties.GetIPGlobalProperties();
|
|
if (computerProperties == null)
|
|
return null;
|
|
|
|
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
|
|
if (nics == null || nics.Length < 1)
|
|
return null;
|
|
|
|
NetworkInterface best = null;
|
|
foreach (NetworkInterface adapter in nics)
|
|
{
|
|
if (adapter.NetworkInterfaceType == NetworkInterfaceType.Loopback || adapter.NetworkInterfaceType == NetworkInterfaceType.Unknown)
|
|
continue;
|
|
if (!adapter.Supports(NetworkInterfaceComponent.IPv4))
|
|
continue;
|
|
if (best == null)
|
|
best = adapter;
|
|
if (adapter.OperationalStatus != OperationalStatus.Up)
|
|
continue;
|
|
|
|
// A computer could have several adapters (more than one network card)
|
|
// here but just return the first one for now...
|
|
return adapter;
|
|
}
|
|
return best;
|
|
}
|
|
|
|
public static PhysicalAddress GetMacAddress()
|
|
{
|
|
NetworkInterface ni = GetNetworkInterface();
|
|
if (ni == null)
|
|
return null;
|
|
return ni.GetPhysicalAddress();
|
|
}
|
|
|
|
public static string ToHexString(long data)
|
|
{
|
|
return ToHexString(BitConverter.GetBytes(data));
|
|
}
|
|
|
|
public static string ToHexString(byte[] data)
|
|
{
|
|
char[] c = new char[data.Length * 2];
|
|
byte b;
|
|
for (int i = 0; i < data.Length; ++i)
|
|
{
|
|
b = ((byte)(data[i] >> 4));
|
|
c[i * 2] = (char)(b > 9 ? b + 0x37 : b + 0x30);
|
|
b = ((byte)(data[i] & 0xF));
|
|
c[i * 2 + 1] = (char)(b > 9 ? b + 0x37 : b + 0x30);
|
|
}
|
|
return new string(c);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets my local IP address (not necessarily external) and subnet mask
|
|
/// </summary>
|
|
public static IPAddress GetMyAddress(out IPAddress mask)
|
|
{
|
|
NetworkInterface ni = GetNetworkInterface();
|
|
if (ni == null)
|
|
{
|
|
mask = null;
|
|
return null;
|
|
}
|
|
|
|
IPInterfaceProperties properties = ni.GetIPProperties();
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if the IPEndPoint supplied is on the same subnet as this host
|
|
/// </summary>
|
|
public static bool IsLocal(IPEndPoint endpoint)
|
|
{
|
|
if (endpoint == null)
|
|
return false;
|
|
return IsLocal(endpoint.Address);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns true if the IPAddress supplied is on the same subnet as this host
|
|
/// </summary>
|
|
public static bool IsLocal(IPAddress remote)
|
|
{
|
|
IPAddress mask;
|
|
IPAddress local = GetMyAddress(out mask);
|
|
|
|
if (mask == null)
|
|
return false;
|
|
|
|
uint maskBits = BitConverter.ToUInt32(mask.GetAddressBytes(), 0);
|
|
uint remoteBits = BitConverter.ToUInt32(remote.GetAddressBytes(), 0);
|
|
uint localBits = BitConverter.ToUInt32(local.GetAddressBytes(), 0);
|
|
|
|
// compare network portions
|
|
return ((remoteBits & maskBits) == (localBits & maskBits));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns how many bits are necessary to hold a certain number
|
|
/// </summary>
|
|
[CLSCompliant(false)]
|
|
public static int BitsToHoldUInt(uint value)
|
|
{
|
|
int bits = 1;
|
|
while ((value >>= 1) != 0)
|
|
bits++;
|
|
return bits;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns how many bytes are required to hold a certain number of bits
|
|
/// </summary>
|
|
public static int BytesToHoldBits(int numBits)
|
|
{
|
|
return (numBits + 7) / 8;
|
|
}
|
|
|
|
[CLSCompliant(false)]
|
|
public static UInt32 SwapByteOrder(UInt32 value)
|
|
{
|
|
return
|
|
((value & 0xff000000) >> 24) |
|
|
((value & 0x00ff0000) >> 8) |
|
|
((value & 0x0000ff00) << 8) |
|
|
((value & 0x000000ff) << 24);
|
|
}
|
|
|
|
[CLSCompliant(false)]
|
|
public static UInt64 SwapByteOrder(UInt64 value)
|
|
{
|
|
return
|
|
((value & 0xff00000000000000L) >> 56) |
|
|
((value & 0x00ff000000000000L) >> 40) |
|
|
((value & 0x0000ff0000000000L) >> 24) |
|
|
((value & 0x000000ff00000000L) >> 8) |
|
|
((value & 0x00000000ff000000L) << 8) |
|
|
((value & 0x0000000000ff0000L) << 24) |
|
|
((value & 0x000000000000ff00L) << 40) |
|
|
((value & 0x00000000000000ffL) << 56);
|
|
}
|
|
|
|
public static bool CompareElements(byte[] one, byte[] two)
|
|
{
|
|
if (one.Length != two.Length)
|
|
return false;
|
|
for (int i = 0; i < one.Length; i++)
|
|
if (one[i] != two[i])
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
public static byte[] ToByteArray(String hexString)
|
|
{
|
|
byte[] retval = new byte[hexString.Length / 2];
|
|
for (int i = 0; i < hexString.Length; i += 2)
|
|
retval[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16);
|
|
return retval;
|
|
}
|
|
}
|
|
}
|