ICMP协议的代码实践(php)

1.ICMP报文的接收和发送

<?php
/**
 * 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程序

<?php
/**
 * 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";

}

 

转载于:https://my.oschina.net/lovezfy/blog/717381

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值