Reputation: 83
according to http://kernelnewbies.org/Linux_3.0#head-c5bcc118ee946645132a834a716ef0d7d05b282e we can now ping as an unprivileged user, and I can sort of get it to work.
using https://github.com/jedie/python-ping I modified line 210 to look like
current_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_ICMP)
as root I "echo 1000 1000 > /proc/sys/net/ipv4/ping_group_range"
my group is 1000
and I can run ping.py as myself as an ordinary user, I can see echo requests and echo replies in tcpdump
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
but ping.py doesn't see the replies, and says timeout.
Any ideas how to make this work?
edit:
I'm narrowing down the issue.
print "c", icmp_header, address, self.own_id
if icmp_header["packet_id"] == self.own_id: # Our packet
the problem is icmp_header["packet_id"] is always 8247 and self.own_id is the pid of ping.py. 8247 is 2037 in hex, which I can see quite a few time in the dump.
This is a full dump of a ping on the wire
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]
AFAICT, the icmp header might be packed wrong. however it's just a wild stab, I will stare at it some more later, in the meantime, any help would be appreciated.
Upvotes: 6
Views: 2576
Reputation: 22261
There are two things you didn't take into account:
packet_data[20:28]
but of course since the IP header is not included the 20 byte offset does not make sense. This has to become packet_data[0:8]
With this new functionality, the kernel controls the ICMP ID through the socket binding mechanism. You can let the kernel choose an ID (implicit bind) or set an ID (explicit bind). It's better to just rely on implicit bind because the kernel will guarantee to choose an ID that's free.
On line 309, the code checks to see if the reply belongs to us by checking the id against self.own_id
. But using implicit bind the kernel picks the ID for us. We could set self.own_id
to the identifier the kernel has assigned using
self.own_id = current_socket.getsockname()[1]
(put this right after self.send_one_ping
on line 221)
But in fact the check against self.own_id
is not even necessary anyway since the kernel already makes sure we only see the replies we're supposed to see.
Upvotes: 4