目录
之前搞了个ipv4的php ping,今天突然想知道ipv6的要怎么实现。
主要不同
socket_create
$this->sock['ipv4'] = socket_create(AF_INET, SOCK_RAW, getprotobyname('icmp'));
$this->sock['ipv6'] = socket_create(AF_INET6, SOCK_RAW, getprotobyname('ipv6-icmp'));
协议中的类型不同
$packet = '';
$packet .= chr(8);
$packet .= chr(128);
在php中返回数据不同
这里这的不是 type = 0 和 129 的区别,具体如下:
69 0 0 60 244 129 0 0 64 1 0 0 127 0 0 1 127 0 0 1
0 0 245 21 10 233 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
129 0 30 243 186 85 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
这里可能是php的问题,ipv4的数据包会把整个ip包(包括头部)返回给你。而在ipv6中,只会返回ip包的数据部分。
遇到的一些错误
正确的是 AF_INET6 + ipv6-icmp + type=128
以下是遇到的情况,如果用 ip4的包数据发给ipv6地址,会得到各种错误:
-
设置了AF_INET6,icmp,type=8
Internet Control Message Protocol
Type: 8 (Echo (ping) request)
Code: 0
Checksum: 0x1c37 [correct]
[Checksum Status: Good]
Identifier (BE): 56264 (0xdbc8)
Identifier (LE): 51419 (0xc8db)
Sequence Number (BE): 0 (0x0000)
Sequence Number (LE): 0 (0x0000)
[No response seen]
[Expert Info (Warning/Sequence): No response seen to ICMP request]
Data (32 bytes)
Internet Control Message Protocol v6
Type: Parameter Problem (4)
Code: 1 (unrecognized Next Header type encountered)
Checksum: 0x4f57 [correct]
[Checksum Status: Good]
Pointer: 6
Internet Protocol Version 6, Src: 240e:62:9cb3:6a00:512d:ee56:2dda:e1ab, Dst: 240e:62:9cb3:6a00::1
Internet Control Message Protocol
Type: 8 (Echo (ping) request)
Code: 0
Checksum: 0x1c37 [unverified] [in ICMP error packet]
[Checksum Status: Unverified]
Identifier (BE): 56264 (0xdbc8)
Identifier (LE): 51419 (0xc8db)
Sequence Number (BE): 0 (0x0000)
Sequence Number (LE): 0 (0x0000)
Data (32 bytes)
-
设置了AF_INET6,ipv6-icmp,type=8
程序会报错,提示如下
PHP Warning: socket_sendto(): Unable to write to socket [10013]: 以一种访问权限不允许的方式做了一个访问套接字的尝试。
(之前以为这是个权限问题,现在看应该是数据格式错误导致的。或者说只有高权限才可以自定义数据包)
强行用管理员权限发,从数据抓包看是得到了一个,未知数据包,并且没有响应
Internet Control Message Protocol v6
Type: Unknown (8)
Code: 0
Checksum: 0x8f4a [correct]
[Checksum Status: Good]
[Expert Info (Note/Undecoded): Dissector for ICMPv6 Type (8) code not implemented, Contact Wireshark developers if you want this supported]
[Dissector for ICMPv6 Type (8) code not implemented, Contact Wireshark developers if you want this supported]
[Severity level: Note]
[Group: Undecoded]
Data: c2fe00010000000000000000000000000000000000000000000000000000000000000000
其他发现
-
在sendto 中,ipv6地址兼容问题
$ip = 'ff02::1';
//$ip = '['.$ip.']';
socket_sendto($this->sock['ipv6'], $packet, strlen($packet), 0, $ip, $port);
php 7.0 不能加[],加了会报错
PHP Warning: socket_sendto(): Host lookup failed [-1000]: Unknown host
php 8.0.6 中加[],也可以运行。
参考
Internet Control Message Protocol for IPv6