1.判断IP字符串是否为有效的IPv6地址
string ipv6Str = "1489:0000:00:0:872c:Error:00:0b39";
IPAddress ipAddress = IPAddress.None;
if (!IPAddress.TryParse(ipv6Str, out ipAddress) || ipAddress.AddressFamily != System.Net.Sockets.AddressFamily.InterNetworkV6)
{
System.Diagnostics.Debug.WriteLine(string.Format("字符串“{0}”非有效的IPv6地址。", ipv6Str));
}
else
{
System.Diagnostics.Debug.WriteLine(string.Format("压缩后的IPv6地址:{0}", ipAddress.ToString()));
}
2.获取压缩后的IPv6地址(零压缩、前导零压缩)
IPAddress address1 = IPAddress.Parse("1489:0000:00:0:832c:0:00:0b39");
System.Diagnostics.Debug.WriteLine("address1.ToString:" + address1.ToString());
输出结果:address1.ToString:1489::832c:0:0:b39
3.获取发起请求的客户端IP地址
调用方式: string ips = Common.GetRequestIP(Context.Request);
#region 获取发起请求的客户端IP地址
/// <summary>
/// 获取发起请求的客户端IP地址
/// </summary>
/// <param name="req">请求对象</param>
/// <returns>IP地址(多个时“, ”拼接)</returns>
public static string GetRequestIP(HttpRequest req)
{
string ip = "";
if (req == null)
{
return ip;
}
try
{
if (req.ServerVariables["HTTP_VIA"] != null) // 使用了代理服务器
{
/* 使用了代理服务器分两种情况:
* 1.使用透明代理服务器的情况:Transparent Proxies
* HTTP_X_FORWARDED_FOR = 您的真实IP,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215
*
* 2.使用普通匿名代理服务器的情况:Anonymous Proxies
* HTTP_X_FORWARDED_FOR = 代理服务器IP,经过多个代理服务器时,这个值类似如下:203.98.182.163, 203.98.182.163, 203.129.72.215
*/
ip = req.ServerVariables["HTTP_X_FORWARDED_FOR"];
// 有些客户端会因为“header_access deny”的安全设置而不发给我们IP
if (string.IsNullOrWhiteSpace(ip))
{
ip = req.ServerVariables["REMOTE_ADDR"];
}
}
else // 如果没有使用代理服务器或者得不到客户端的ip not using proxy or can't get the Client IP
{
ip = req.ServerVariables["REMOTE_ADDR"]; //While it can't get the Client IP, it will return proxy IP.
if (ip != null && ip.Equals("::1")) // ::-1是ipV6地址,实际上就是本机的意思
{
#region 获取本地IP地址
ip = "";
foreach (IPAddress ipAddress in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
{
string tempIP = "";
if (ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) //InterNetwork ipv4地址
{
tempIP = ipAddress.ToString();
}
else if (ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) //InterNetworkV6 ipv6地址
{
// 过滤掉IPv6链接本地地址、站点本地地址、IPv6DNS服务器地址
if (!ipAddress.ToString().Contains("%"))
{
tempIP = ipAddress.ToString();
}
}
if (!string.IsNullOrWhiteSpace(tempIP))
{
if (string.IsNullOrWhiteSpace(ip))
{
ip = tempIP;
}
else
{
ip = string.Format("{0}, {1}", ip, tempIP);
}
}
}
#endregion
}
}
}
catch
{
ip = req.ServerVariables["REMOTE_ADDR"];
}
return ip;
}
#endregion
4.校验IP地址格式并压缩IPv6地址
#region 校验IP地址格式并压缩IPv6地址
/// <summary>
/// 校验IP地址格式并压缩IPv6地址
/// </summary>
/// <param name="ip">待处理的IP字符串</param>
/// <param name="errStr">错误信息</param>
/// <param name="addressFamily">判断IP地址是否为指定的地址族</param>
/// <returns>处理后的IP字符串</returns>
public static string CheckIPAndCompress(string ip, out string errStr, System.Net.Sockets.AddressFamily addressFamily = System.Net.Sockets.AddressFamily.Unknown)
{
string resIP = "";
errStr = "";
try
{
IPAddress ipAddress = IPAddress.None;
if (!IPAddress.TryParse(ip, out ipAddress))
{
errStr = string.Format("IP字符串“{0}”非有效的IP地址格式。", ip);
return resIP;
}
// addressFamily参数值为Unknown时,不校验具体地址族
if (addressFamily != System.Net.Sockets.AddressFamily.Unknown && ipAddress.AddressFamily != addressFamily)
{
if (addressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
errStr = string.Format("IP字符串“{0}”非有效的IPv4地址格式。", ip);
return resIP;
}
else if (addressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
{
errStr = string.Format("IP字符串“{0}”非有效的IPv4地址格式。", ip);
return resIP;
}
}
resIP = ipAddress.ToString();
}
catch (Exception ex)
{
errStr = "执行“校验IP地址格式并压缩IPv6地址”方法时发生异常:" + ex.ToString();
}
return resIP;
}
#endregion
5.解析IP黑名单或白名单配置字符串
添加引用:using System.Net;
#region 解析白名单配置字符串,返回Host字符串集合
/// <summary>
/// 解析白名单配置字符串,返回Host字符串集合
/// </summary>
/// <param name="whiteListStr">白名单配置字符串</param>
/// <returns>Host字符串集合</returns>
private List<string> GetHostList(string whiteListStr)
{
List<string> list = new List<string>();
if (string.IsNullOrWhiteSpace(whiteListStr))
{
return list;
}
try
{
// baidu.com|localhost|192.168.1.20|192.168.1.14,15,16|192.168.1.10-13
string[] strArr = whiteListStr.Split('|');
foreach (string item in strArr)
{
// 192.168.1.10-13
if (item.Contains("-"))
{
#region 地址区间
string ipstr0 = item.Substring(0, item.LastIndexOf('.') + 1);
string ipstr1 = item.Substring(item.LastIndexOf('.') + 1);
int ipMin = Convert.ToInt32(ipstr1.Split('-')[0]);
int ipMax = Convert.ToInt32(ipstr1.Split('-')[1]);
for (int i = ipMin; i <= ipMax; i++)
{
string ip = ipstr0 + i.ToString();
if (list.Contains(ip) == false)
{
list.Add(ip);
}
}
#endregion
}
else if (item.Contains(",")) // 192.168.1.14,15,16
{
#region 同一子网多个地址
string ipstr0 = item.Substring(0, item.LastIndexOf('.') + 1);
string ipstr1 = item.Substring(item.LastIndexOf('.') + 1);
foreach (string ipStr in ipstr1.Split(','))
{
string ip = ipstr0 + ipStr;
if (list.Contains(ip) == false)
{
list.Add(ip);
}
}
#endregion
}
else
{
if (list.Contains(item) == false)
{
IPAddress ipAddress = IPAddress.None;
if (IPAddress.TryParse(item, out ipAddress))
{
list.Add(ipAddress.ToString()); // IPv6时,转标准表示法
}
else
{
list.Add(item);
}
}
}
}
}
catch
{ }
return list;
}
#endregion
6.使用Postman伪造IP,进行IP欺骗
在Headers参数中增加VIA和X_FORWARDED_FOR参数,.net或PHP等开发语言获取服务器变量时,得到的"HTTP_VIA"和"HTTP_X_FORWARDED_FOR"参数值即为所传参数值。
Java中获取的服务器变量中没有HTTP_前缀,如"X_FORWARDED_FOR"。