php发送icmp,ICMP协议的代码实践(php)

这篇博客展示了如何使用PHP编写一个模拟ICMP协议的函数`sendPackage`,并利用该函数实现了一个简单的ping程序。代码中包含了封装ICMP报文、设置校验和以及发送和接收ICMP报文的过程。在ping程序部分,通过向指定主机发送ICMP echo请求,并处理响应,计算出往返时间。
摘要由CSDN通过智能技术生成

1.ICMP报文的接收和发送

/**

* Created by PhpStorm.

* User: kisstheraik

* Date: 16/7/21

* Time: 上午1:01

* Description: 模拟发送ICMP报文

*/

/**

* @param $host string 主机ip

* @param $type int icmp报文类型

* @param $code int icmp报文代码

* @param $data string icmp报文数据

* @param $callbackfunc string 请求完成之后的回调函数,由上层模块决定

* @description 向主机发送icmp报文

*

* icmp 报文头 | 1字节类型 | 1字节代码 | 2字节校验和 |

*/

function sendPackage($host,$type,$code,$data,$callbackfunc){

//icmp错误信息

$g_icmp_error=null;

//封装icmp报文

//icmp头

$package=chr($type).chr($code);

$package.=chr(0).chr(0);

$package.=$data;

//设置校验和

setSum($package);

//发送报文

$socket=socket_create(AF_INET,SOCK_RAW,getprotobyname('icmp')) or die('Cannot create socket');

socket_sendto($socket,$package,strlen($package),0,$host,0);

$read = array($socket);

$write = NULL;

$except = NULL;

$select = socket_select($read, $write, $except, 0, 300 * 1000);

if ($select === NULL)

{

$g_icmp_error = "Select Error";

socket_close($socket);

return $g_icmp_error;

}

elseif ($select === 0)

{

$g_icmp_error = "Timeout";

socket_close($socket);

return $g_icmp_error;

}

socket_recvfrom($socket, $recv, 65535, 0, $host, $port);

//回调结果处理函数

call_user_func($callbackfunc,$recv);

return $g_icmp_error;

}

/**

* @param $data string 报文数据

* @description 设置icmp报文校验和

*/

function setSum(&$data){

$list=unpack('n*',$data);

$length=strlen($data);

$sum=array_sum($list);

if($length%2){

$tmp=unpack('C*',$data[$length-1]);

$sum+=$tmp[1];

}

$sum=($sum>>16)+($sum&0xffff);

$sum+=($sum>>16);

$r=pack('n*',~$sum);

$data[2]=$r[0];

$data[3]=$r[1];

}

2.ping程序

/**

* Created by PhpStorm.

* User: kisstheraik

* Date: 16/7/21

* Time: 上午12:58

* Description: 使用ICMP协议,模拟ping程序

*/

require_once('ICMP.php');

//标识符随便填的,序列号也是随便填的211

$data='Z'.'F'.chr(0).chr(211);

//ping程序凑够64byte的报文,这里包括IP首部20byte

for($i=0;$i<56;$i++){

$data.=chr(0);

}

$host='www.baidu.com';

$startTime=microtime();

$result=sendPackage($host,8,0,$data,function($message){

global $host;

global $startTime;

//按照字节解析成数组

$message = unpack('C*', $message);

$seq=$message[28];

$ttl=$message[9];

$endTime=microtime();

echo (count($message)-20)." bytes from $host: icmp_seq=$seq ttl=$ttl time=".(round((($endTime-$startTime)*1000),3))." ms".PHP_EOL;

});

if($result!=null){

echo "Error :$result";

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值