Reputation: 730
I'm trying to send a message through ICMP packets but I don't know how to do it.
This is the code I currently have, but obviously doesn't work:
s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)
s.setsockopt(IPPROTO_IP, IP_HDRINCL, 1)
s.settimeout(3.0)
s.sendto("Hello!" + "\r\n", (server, 7))
msg = s.recvfrom(buff_size)
s.close()
I have to receive an answer from server if string "Hello!" is sent, but I don't get it. I suppose, that "Hello!" string will be encapsulated into Data field:
Upvotes: 5
Views: 11732
Reputation: 400204
In order to construct an ICMP packet, you have to create the whole packet yourself using a raw socket. The struct
module is useful for this.
Secondly, in order to even use raw sockets in the first place, you need to have permission to do so—you should be running as root (I know this is a sufficient condition, but I'm not 100% certain that it's a necessary condition). The ping(1)
executable is able to do this because it's a setuid executable that runs as root when you run it. Since scripts cannot be made setuid on Linux, you'll have to make a wrapper setuid program in C that just executes your Python script.
Upvotes: 6
Reputation: 58558
I don't think that SOCK_RAW
is going an ICMP datagram for you just because you set the protocol field to IPPROTO_ICMP
! You have to construct the packet yourself.
Take a look at the source of ping.
There are (at least) two popular packages that provide ping
in GNU/Linux operating systems. One is netkit
and the other iputils
. (netkit-combo
is a tarball which has all the netkit
utilities in one: telnet, FTP, ...) The *BSD guys probably have their own.
Upvotes: 1