【发布时间】:2010-12-03 05:11:01
【问题描述】:
我正在抓取用户IP地址,然后我想确定该IP地址是否在可访问范围内。
我正在做的是,在我的 PHP 脚本中,我使用“ip2long”函数并将其与允许的 IP 地址范围进行比较。
我知道这不是一个干净的方法......有没有人有更好的主意?
任何帮助表示赞赏。
谢谢, 阿米特
【问题讨论】:
我正在抓取用户IP地址,然后我想确定该IP地址是否在可访问范围内。
我正在做的是,在我的 PHP 脚本中,我使用“ip2long”函数并将其与允许的 IP 地址范围进行比较。
我知道这不是一个干净的方法......有没有人有更好的主意?
任何帮助表示赞赏。
谢谢, 阿米特
【问题讨论】:
至少,您需要将前 N 位与已知私有或已知未使用的网络块进行比较。其中最少的是RFC 1918 private networks:
10/8
172.16/12
192.168/16
(这个符号意味着如果你屏蔽掉前 8 位并得到“10”,它在第一个私有块中。12 位 == 172.16 是第二个,等等)
您可以检测到更多块。
最简单的例子是127/8,都是loopback addresses。你可能知道 127.0.0.1,但实际上所有 127.x.y.z 地址都是指你机器上的环回接口。
一个更模糊的例子是 5/8,它被分配但从未在广泛的 Internet 上使用,所以它被 Hamachi 占用。但是,如果您的程序有可能在可以访问 Hamachi 网络的机器上运行,那么您在测试时要小心。
您可能想要忽略的另一组地址是各种multicast 范围。您应该只向那些发送 UDP 数据包,而不是 TCP 连接。
如果你想变得更加积极,你可以及时了解IANA 发布的最新分配,忽略尚未分配的块中的 IP。不过,您会希望经常更新该列表。
【讨论】:
PHP 几乎可以为您做所有事情:
filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4| FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE);
如果 IP 在私有或保留范围内,则返回 false,如果范围可访问,则返回 IP。你可以想出这样的东西来总是返回一个布尔值:
function isAccessibleRangeIP($ip)
{
return (bool) filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4| FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE);
}
【讨论】: