Kactung
Kactung

Reputation: 730

How to send ICMP packet through sockets?

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:

enter image description here

Upvotes: 5

Views: 11732

Answers (2)

Adam Rosenfield
Adam Rosenfield

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

Kaz
Kaz

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

Related Questions