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

lanyu19950316 2012-07-11 11:56:21
<?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那函数的问题,请问下应该怎么修改
...全文
271 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
lanyu19950316 2012-07-11
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

raw socket, 百度或者参考UNP.
[/Quote]
找到的都是C语言的,那个和php的不同
lanyu19950316 2012-07-11
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

通过代理服务器!

无论如何,准备接收回复的 ip 是不可伪造的
[/Quote]
我没打算接收发回来的信息
qq120848369 2012-07-11
  • 打赏
  • 举报
回复
raw socket, 百度或者参考UNP.
xuzuning 2012-07-11
  • 打赏
  • 举报
回复
通过代理服务器!

无论如何,准备接收回复的 ip 是不可伪造的
lanyu19950316 2012-07-11
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

不知道你在干什么?利用 sock 包的肯定是在用户层了
封装 ip 应该在下一层

再说你也不可能封一个伪 ip 到通讯包中。做成了,也就返回不到你这里了
写错了回信地址,人家回信时必然是“查无此人”
[/Quote]
那么怎样才可以伪造IP呢,我用的UDP的,不需要告诉别人我的真实IP
xuzuning 2012-07-11
  • 打赏
  • 举报
回复
不知道你在干什么?利用 sock 包的肯定是在用户层了
封装 ip 应该在下一层

再说你也不可能封一个伪 ip 到通讯包中。做成了,也就返回不到你这里了
写错了回信地址,人家回信时必然是“查无此人”
lanyu19950316 2012-07-11
  • 打赏
  • 举报
回复
这是个查询向指定dns服务器查询指定域名IP信息的程序,用Wireshark抓包测试可用,但是现在没有用自己的网络层,也就是IP头,我要用自己构造的IP头,

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

打错了
lanyu19950316 2012-07-11
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

get_headers
获取所有http响应的头部
[/Quote]

不是,我这个是发包到指定的dns服务器,查询数据的,和get_headers没关系
床上等您 2012-07-11
  • 打赏
  • 举报
回复
get_headers
获取所有http响应的头部
lanyu19950316 2012-07-11
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

通过代理服务器!

无论如何,准备接收回复的 ip 是不可伪造的
[/Quote]
研究了下代理服务器,通讯协议里没有指明源IP,不行啊
qq120848369 2012-07-11
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

引用 8 楼 的回复:

raw socket, 百度或者参考UNP.

找到的都是C语言的,那个和php的不同
[/Quote]

没找到设置IP选项的封装函数, 只有SOCKET级别的选项, 不知道PHP到底有没有封。
healer_kx 2012-07-11
  • 打赏
  • 举报
回复
问题是PHP能用原始套接字?

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧