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:
Description: ICMP is the error- and control-message protocol used by IP and the Internet protocol family. The protocol may be accessed through a “raw socket” for network monitoring and diagnostic functions.
5.2. 7.4 ICMP socketsIt implements a user protocol receiving and sending ICMP packets by opening a raw socket with the protocol IPPROTO_ICMP . The types of ICMP packets passed to the socket can be filtered using the ICMP_FILTER socket option (or by software as done here).
Unlike the Internet Protocol (IP), ICMP is not associated with a transport layer protocol such as TCP or UDP. This makes ICMP a connectionless protocol: one device does not need to open a connection with another device before sending an ICMP message.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With