如何通过套接字发送ICMP数据包?

时间:2012-03-12 00:13:39

标签: python sockets

我正在尝试通过ICMP数据包发送消息,但我不知道该怎么做。

这是我目前的代码,但显然不起作用:

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()

如果字符串“Hello!”,我必须从服务器收到答案。发送,但我不明白。 我想,那就是“你好!”字符串将封装到数据字段中:

enter image description here

2 个答案:

答案 0 :(得分:5)

为了构造ICMP数据包,您必须使用原始套接字自己创建整个数据包。 struct module对此非常有用。

其次,为了甚至首先使用原始套接字,你需要有权限这样做 - 你应该以root身份运行(我知道这是一个充分的条件,但我不是100%肯定的这是一个必要的条件)。 ping(1)可执行文件能够执行此操作,因为它是setuid可执行文件,在您运行它时以root身份运行。由于脚本无法在Linux上生成setuid,因此您必须在C中创建一个只执行Python脚本的包装器setuid程序。

答案 1 :(得分:1)

我认为SOCK_RAW只是因为您将协议字段设置为IPPROTO_ICMP而为您提供ICMP数据报!你必须自己构建数据包。

看一下ping的来源。

在GNU / Linux操作系统中有(至少)两个流行的包提供ping。一个是netkit,另一个是iputils。 (netkit-combo是一个tarball,其中包含所有netkit个实用程序:telnet,FTP,...)* BSD人员可能都有自己的。