2010-05-21

用php校验CIDR格式的IP地址段

用libpcap抓包(比如tcpdump)的时候可以指定网段,比如用tcpdump抓192.168.1.0网段的包,使用命令 tcpdump -i eth0 net 192.168.1.0/24,但是如果你输入了 tcpdump -i eth0 net 192.168.10/22,tcpdump就会提示 tcpdump: non-network bits set in "192.168.1.0/22"

那怎么校验 192.168.1.0/22 不是合法的呢,下面的代码就可以实现

function ipvalid($ip){
 preg_match('/(.+)\/(.+)$/', $ip, $array);

    //把ip段拆分成ip和掩码
 $ip = $array[1];
 $mask = $array[2];

 //掩码最大只能是32
 if ($mask > 32){
  return false;
 }

 //掩码为0时除非ip为0.0.0.0才合法,否则不合法
 if($mask == 0){
  if ($ip != '0.0.0.0'){
   return false;
  }else{
   return true;
  }
 }

 //掩码为32时不论ip是多少都合法
 if($mask == 32){
  return true;
 }

 $longip = ip2long($ip);
 $net_mask = 0xffffffff << (32 - $mask);

 //最后验证,代码参考libcap的源码
 if (($longip & ~$net_mask) != 0){
  return false;
 }else{
  return true;
 }
}

没有评论: