根据原始套接字的手册页,
The IPv4 layer generates an IP header when sending a packet unless the IP_HDRINCL socket option is enabled on the socket. When it is enabled, the packet must contain an IP header. For receiving the IP header is always included in the packet.
我正在使用 python 测试 IP_HDRINCL 套接字选项,所以我生成了一个 IP header ,但在启用该选项后,不幸的是,sendto() 方法似乎不起作用,我收到以下错误
Traceback (most recent call last): File "./test.py", line 35, in s.sendto(pkt, (dip , 0 )) socket.error: [Errno 1] Operation not permitted
请记住,我正在使用 uid 0 (root) 运行程序
注意:
我不想将原始套接字与 PACKET FAMILY 一起使用,我仍然想利用内核中实现的 TCP/IP 堆栈
这是我创建的示例:
#!/usr/bin/env python
import socket
import struct
def IP():
version = 4
ihl = 5
DF = 0
Tlen = 0
ID = 0
Flag = 0
Fragment = 0
TTL = 64
Proto = socket.IPPROTO_TCP
ip_checksum = 0
SIP = socket.inet_aton("172.16.122.2")
DIP = socket.inet_aton("172.16.122.1")
ver_ihl = (version << 4) + ihl
f_f = (Flag << 13) + Fragment
ip_hdr = struct.pack("!BBHHHBBH4s4s", ver_ihl,DF,Tlen,ID,f_f,TTL,Proto,ip_checksum,SIP,DIP)
return ip_hdr
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
# the error occurs only when the IP_HDRINCL is enabled
s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
dip = "172.16.122.1"
pkt = IP() + "Hello"
s.sendto(pkt, (dip , 0 ))
最佳答案
你试过使用吗
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
代替?
您正在将协议(protocol)设置为 TCP 但未写入 header 。也许当您设置 IP_HDRINCL 选项时会进行一些验证?
关于Python 原始套接字 - IP_HDRINCL 选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29848369/