che*_*sty 5 python sockets ping icmp
根据 http://kernelnewbies.org/Linux_3.0#head-c5bcc118ee946645132a834a716ef0d7d05b282e, 我们现在可以作为非特权用户ping,我可以让它运行起来.
使用https://github.com/jedie/python-ping我修改了210行的样子
current_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,socket.IPPROTO_ICMP)
作为root我"echo 1000 1000>/proc/sys/net/ipv4/ping_group_range"
我的团队是1000
我可以像普通用户一样运行ping.py,我可以在tcpdump中看到echo请求和echo回复
18:33:24.840291 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 269)
127.0.0.1 > 127.0.0.1: ICMP echo request, id 38, seq 0, length 249
18:33:24.840309 IP (tos 0x0, ttl 64, id 37939, offset 0, flags [none], proto ICMP (1), length 269)
127.0.0.1 > 127.0.0.1: ICMP echo reply, id 38, seq 0, length 249
Run Code Online (Sandbox Code Playgroud)
但ping.py没有看到回复,并说超时.
任何想法如何使这项工作?
编辑:
我正在缩小这个问题.
print "c", icmp_header, address, self.own_id
if icmp_header["packet_id"] == self.own_id: # Our packet
Run Code Online (Sandbox Code Playgroud)
问题是icmp_header ["packet_id"]总是8247而self.own_id是ping.py的pid.8247是十六进制的2037,我可以在转储中看到很多次.
这是电线上ping的完全转储
19:25:15.513285 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 283: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto ICMP (1), length 269)
127.0.0.1 > 127.0.0.1: ICMP echo request, id 70, seq 2, length 249
0x0000: 4500 010d 0000 4000 4001 3bee 7f00 0001 E.....@.@.;.....
0x0010: 7f00 0001 0800 d932 0046 0002 5b36 362c .......2.F..[66,
0x0020: 2036 372c 2036 382c 2036 392c 2037 302c .67,.68,.69,.70,
0x0030: 2037 312c 2037 322c 2037 332c 2037 342c .71,.72,.73,.74,
0x0040: 2037 352c 2037 362c 2037 372c 2037 382c .75,.76,.77,.78,
0x0050: 2037 392c 2038 302c 2038 312c 2038 322c .79,.80,.81,.82,
0x0060: 2038 332c 2038 342c 2038 352c 2038 362c .83,.84,.85,.86,
0x0070: 2038 372c 2038 382c 2038 392c 2039 302c .87,.88,.89,.90,
0x0080: 2039 312c 2039 322c 2039 332c 2039 342c .91,.92,.93,.94,
0x0090: 2039 352c 2039 362c 2039 372c 2039 382c .95,.96,.97,.98,
0x00a0: 2039 392c 2031 3030 2c20 3130 312c 2031 .99,.100,.101,.1
0x00b0: 3032 2c20 3130 332c 2031 3034 2c20 3130 02,.103,.104,.10
0x00c0: 352c 2031 3036 2c20 3130 372c 2031 3038 5,.106,.107,.108
0x00d0: 2c20 3130 392c 2031 3130 2c20 3131 312c ,.109,.110,.111,
0x00e0: 2031 3132 2c20 3131 332c 2031 3134 2c20 .112,.113,.114,.
0x00f0: 3131 352c 2031 3136 2c20 3131 372c 2031 115,.116,.117,.1
0x0100: 3138 2c20 3131 392c 2031 3230 5d 18,.119,.120]
19:25:15.513300 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 283: (tos 0x0, ttl 64, id 37971, offset 0, flags [none], proto ICMP (1), length 269)
127.0.0.1 > 127.0.0.1: ICMP echo reply, id 70, seq 2, length 249
0x0000: 4500 010d 9453 0000 4001 e79a 7f00 0001 E....S..@.......
0x0010: 7f00 0001 0000 e132 0046 0002 5b36 362c .......2.F..[66,
0x0020: 2036 372c 2036 382c 2036 392c 2037 302c .67,.68,.69,.70,
0x0030: 2037 312c 2037 322c 2037 332c 2037 342c .71,.72,.73,.74,
0x0040: 2037 352c 2037 362c 2037 372c 2037 382c .75,.76,.77,.78,
0x0050: 2037 392c 2038 302c 2038 312c 2038 322c .79,.80,.81,.82,
0x0060: 2038 332c 2038 342c 2038 352c 2038 362c .83,.84,.85,.86,
0x0070: 2038 372c 2038 382c 2038 392c 2039 302c .87,.88,.89,.90,
0x0080: 2039 312c 2039 322c 2039 332c 2039 342c .91,.92,.93,.94,
0x0090: 2039 352c 2039 362c 2039 372c 2039 382c .95,.96,.97,.98,
0x00a0: 2039 392c 2031 3030 2c20 3130 312c 2031 .99,.100,.101,.1
0x00b0: 3032 2c20 3130 332c 2031 3034 2c20 3130 02,.103,.104,.10
0x00c0: 352c 2031 3036 2c20 3130 372c 2031 3038 5,.106,.107,.108
0x00d0: 2c20 3130 392c 2031 3130 2c20 3131 312c ,.109,.110,.111,
0x00e0: 2031 3132 2c20 3131 332c 2031 3134 2c20 .112,.113,.114,.
0x00f0: 3131 352c 2031 3136 2c20 3131 372c 2031 115,.116,.117,.1
0x0100: 3138 2c20 3131 392c 2031 3230 5d 18,.119,.120]
Run Code Online (Sandbox Code Playgroud)
AFAICT,icmp标题可能包装错误.然而,这只是一次狂野的刺伤,我会稍后盯着它,与此同时,任何帮助都会受到赞赏.
有两件事你没有考虑到:
packet_data[20:28]但当然,由于不包含 IP 标头,因此 20 字节偏移量没有意义。这必须成为packet_data[0:8]有了这个新功能,内核通过套接字绑定机制控制 ICMP ID。您可以让内核选择一个ID(隐式绑定)或设置一个ID(显式绑定)。最好只依赖隐式绑定,因为内核将保证选择一个空闲的 ID。
在第 309 行,代码通过检查 id 来检查回复是否属于我们self.own_id。但是使用隐式绑定,内核会为我们选择 ID。我们可以设置self.own_id为内核分配的标识符
self.own_id = current_socket.getsockname()[1]
Run Code Online (Sandbox Code Playgroud)
(将其放在self.send_one_ping第 221 行之后)
但事实上,无论如何检查self.own_id都没有必要,因为内核已经确保我们只看到我们应该看到的回复。
| 归档时间: |
|
| 查看次数: |
1647 次 |
| 最近记录: |