Heim  >  Artikel  >  Backend-Entwicklung  >  请问php怎么使用自己构造的IP包头

请问php怎么使用自己构造的IP包头

WBOY
WBOYOriginal
2016-06-13 10:32:59902Durchsuche

请教php如何使用自己构造的IP包头

PHP code
<!--Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--><?php //数据$dns_id = "\x80\xc1";$dns_flags = "\x01\x00";$dns_count_queries = "\x00\x01";$dns_count_answers = "\x00\x00";$dns_count_auth_rr = "\x00\x00";$dns_count_add_rr = "\x00\x00";$dns_qry_name = "\x02\x69\x70\x02\x63\x6e\x00";$dns_qry_type = "\x00\x01";$dns_qry_class = "\x00\x01";$dns = $dns_id . $dns_flags . $dns_count_queries . $dns_count_answers . $dns_count_auth_rr . $dns_count_add_rr . $dns_qry_name . $dns_qry_type . $dns_qry_class;//IP头$ip_version = "\x45"; //4位版本$ip_hdr_len = ""; // 4位首部长度$ip_dsfield = "\x00"; //8位服务类型$ip_len = pack('n*',28 + strlen($dns)); //16位总长度$ip_id = "\x55\xf0"; //16位标识$ip_flags = "\x00"; //3位标识$ip_frag_offset = "\x00"; // 13位偏移$ip_ttl = "\x80"; //8位生存时间$ip_proto = "\x11"; //8位协议$ip_src = ipto16("192.168.1.100"); //32位源IP$ip_dst = ipto16("8.8.4.4"); //32位目的IP$ip_checksum = ipchecksum($ip_version,$ip_hdr_len,$ip_dsfield,$ip_len,$ip_id,$ip_flags,$ip_frag_offset,$ip_ttl,$ip_proto,$ip_src,$ip_dst); //16位首部效验和$ip_header = $ip_version . $ip_hdr_len . $ip_dsfield . $ip_len . $ip_id . $ip_flags . $ip_frag_offset . $ip_ttl . $ip_proto . $ip_checksum . $ip_src . $ip_dst;//UDP头$udp_srcport = "\xfc\x39"; //16位源端口$udp_dstport = "\x00\x35"; //16位目的端口$udp_length = pack('n*',8 + strlen($dns)); //16位UDP长度$udp_checksum = udpchecksum($ip_src,$ip_dst,$ip_proto,$udp_length,$udp_srcport,$udp_dstport,$dns); //16位UDP效验和$udp = $udp_srcport . $udp_dstport . $udp_length . $udp_checksum;//$buf = $ip_header . $udp . $dns;$buf = $udp . $dns;function send($host,$port,$buf,$dns_flags){//    $socket = socket_create(AF_INET, SOCK_PACKET, getprotobyname("ip"));    $socket = socket_create(AF_INET, SOCK_RAM,1);    $timeout = array('sec'=>1,'usec'=>500000);//    socket_set_option($socket,IPPROTO_IP,IP_HDRINCL,SO_RCVTIMEO,$timeout);    socket_set_option($socket,SOL_SOCKET,SO_RCVTIMEO,$timeout);//    while(1)        socket_sendto($socket, $buf, strlen($buf), 0, $host, $port);}function udpchecksum($ip_src,$ip_dst,$ip_proto,$udp_length,$udp_srcport,$udp_dstport,$dns){    $data = $ip_src . $ip_dst . "\x00" . $ip_proto . $udp_length . $udp_srcport . $udp_dstport . $udp_length . "\x00\x00" . $dns;    if (strlen($data)%2)    $data .= "\x00";    $bit = unpack('n*', $data);    $sum = array_sum($bit);    while ($sum >> 16)        $sum = ($sum >> 16) + ($sum & 0xffff);    return pack('n*', ~$sum);}function ipchecksum($ip_version,$ip_hdr_len,$ip_dsfield,$ip_len,$ip_id,$ip_flags,$ip_frag_offset,$ip_ttl,$ip_proto,$ip_src,$ip_dst){    $data = $ip_version . $ip_hdr_len . $ip_dsfield . $ip_len . $ip_id . $ip_flags . $ip_frag_offset . $ip_ttl . $ip_proto . "\x00\x00" . $ip_src . $ip_dst;    $bit = unpack('n*', $data);    $sum = array_sum($bit);    while ($sum >> 16)        $sum = ($sum >> 16) + ($sum & 0xffff);    return pack('n*', ~$sum);}function ipto16($ip){    $tmp = explode(".",$ip);    $ip = "";    foreach($tmp as $a => $b)    {        $tmp = dechex($b);        if (strlen($tmp)==1)            $tmp = "0" . $tmp;        $ip .= $tmp;    }    $ip = pack("h*",$ip);    return $ip;}send("8.8.4.4",53,$buf,$dns_flags);


这是个查询向指定dns服务器查询指定域名IP信息的程序,用Wireshark抓包测试可用,但是现在没有用自己的网络层,也就是IP头,我要用自己构造的IP头,

$buf = $ip_header . $udp . $dns;
//$buf = $udp . $dns;
改成
$buf = $ip_header . $udp . $dns;
//$buf = $udp . $dns;
结果还是不行,应该是send那函数的问题,请问下应该怎么修改

------解决方案--------------------
不知道你在干什么?利用 sock 包的肯定是在用户层了
封装 ip 应该在下一层
Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:在PHP下 给MYSQL变量报错Nächster Artikel:PHP 编码有关问题