You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
7.2 KiB
C#

1 year ago
using Microsoft.AspNetCore.Http;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
namespace Admin.Core.Common
{
public static class IpHelper
{
/// <summary>
/// 获取当前IP地址
/// </summary>
/// <param name="preferredNetworks"></param>
/// <returns></returns>
public static string GetCurrentIp(string preferredNetworks)
{
var instanceIp = "127.0.0.1";
try
{
// 获取可用网卡
var nics = NetworkInterface.GetAllNetworkInterfaces()?.Where(network => network.OperationalStatus == OperationalStatus.Up);
// 获取所有可用网卡IP信息
var ipCollection = nics?.Select(x => x.GetIPProperties())?.SelectMany(x => x.UnicastAddresses);
foreach (var ipadd in ipCollection)
{
if (!IPAddress.IsLoopback(ipadd.Address) && ipadd.Address.AddressFamily == AddressFamily.InterNetwork)
{
if (string.IsNullOrEmpty(preferredNetworks))
{
instanceIp = ipadd.Address.ToString();
break;
}
if (!ipadd.Address.ToString().StartsWith(preferredNetworks)) continue;
instanceIp = ipadd.Address.ToString();
break;
}
}
}
catch
{
// ignored
}
if (!instanceIp.IsNotEmptyOrNull() || Encoding.Default.GetByteCount(instanceIp) < 9)
{
instanceIp = "127.0.0.1";
}
return instanceIp;
}
public static string GetIpAddr(HttpContext httpContext)
{
var request = httpContext.Request;
if (request == null)
{
return "unknown";
}
string ip = request.Headers["x-forwarded-for"];
if (string.ReferenceEquals(ip, null) || ip.Length == 0 || "unknown".Equals(ip.ToLower()))
{
ip = request.Headers["Proxy-Client-IP"];
}
if (string.ReferenceEquals(ip, null) || ip.Length == 0 || "unknown".Equals(ip.ToLower()))
{
ip = request.Headers["X-Forwarded-For"];
}
if (string.ReferenceEquals(ip, null) || ip.Length == 0 || "unknown".Equals(ip.ToLower()))
{
ip = request.Headers["WL-Proxy-Client-IP"];
}
if (string.ReferenceEquals(ip, null) || ip.Length == 0 || "unknown".Equals(ip.ToLower()))
{
ip = request.Headers["X-Real-IP"];
}
if (!ip.IsNotEmptyOrNull() || Encoding.Default.GetByteCount(ip) < 9)
{
return "127.0.0.1";
}
return "0:0:0:0:0:0:0:1".Equals(ip) ? "127.0.0.1" : ip;
}
public static bool InternalIp(string ip)
{
sbyte[] addr = TextToNumericFormatV4(ip);
return InternalIp(addr) || "127.0.0.1".Equals(ip);
}
private static bool InternalIp(sbyte[] addr)
{
if (addr.IsNotEmptyOrNull() || addr.Length < 2)
{
return true;
}
sbyte b0 = addr[0];
sbyte b1 = addr[1];
const sbyte SECTION_1 = 0x0A;
sbyte SECTION_2 = unchecked((sbyte)0xAC);
sbyte SECTION_3 = (sbyte)0x10;
sbyte SECTION_4 = (sbyte)0x1F;
sbyte SECTION_5 = unchecked((sbyte)0xC0);
sbyte SECTION_6 = unchecked((sbyte)0xA8);
if (b0 == SECTION_1) return true;
if (b0 == SECTION_2 && b1 >= SECTION_3 && b1 <= SECTION_4) return true;
if (b0 == SECTION_5 && b1 == SECTION_6) return true;
return false;
}
/// <summary>
/// 将IPv4地址转换成字节
/// </summary>
/// <param name="text"> IPv4地址 </param>
/// <returns> byte 字节 </returns>
public static sbyte[] TextToNumericFormatV4(string text)
{
if (text.Length == 0)
{
return null;
}
sbyte[] bytes = new sbyte[4];
string[] elements = text.Split('.');
try
{
long l;
int i;
switch (elements.Length)
{
case 1:
l = long.Parse(elements[0]);
if ((l < 0L) || (l > 4294967295L))
{
return null;
}
bytes[0] = (sbyte)(int)(l >> 24 & 0xFF);
bytes[1] = (sbyte)(int)((l & 0xFFFFFF) >> 16 & 0xFF);
bytes[2] = (sbyte)(int)((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (sbyte)(int)(l & 0xFF);
break;
case 2:
l = int.Parse(elements[0]);
if ((l < 0L) || (l > 255L))
{
return null;
}
bytes[0] = (sbyte)(int)(l & 0xFF);
l = int.Parse(elements[1]);
if ((l < 0L) || (l > 16777215L))
{
return null;
}
bytes[1] = (sbyte)(int)(l >> 16 & 0xFF);
bytes[2] = (sbyte)(int)((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (sbyte)(int)(l & 0xFF);
break;
case 3:
for (i = 0; i < 2; ++i)
{
l = int.Parse(elements[i]);
if ((l < 0L) || (l > 255L))
{
return null;
}
bytes[i] = (sbyte)(int)(l & 0xFF);
}
l = int.Parse(elements[2]);
if ((l < 0L) || (l > 65535L))
{
return null;
}
bytes[2] = (sbyte)(int)(l >> 8 & 0xFF);
bytes[3] = (sbyte)(int)(l & 0xFF);
break;
case 4:
for (i = 0; i < 4; ++i)
{
l = int.Parse(elements[i]);
if ((l < 0L) || (l > 255L))
{
return null;
}
bytes[i] = (sbyte)(int)(l & 0xFF);
}
break;
default:
return null;
}
}
catch (System.FormatException)
{
return null;
}
return bytes;
}
}
}