根据原始套接字的手册页面,
IPv4层在发送数据包时生成IP标头,除非已在套接字上启用IP_HDRINCL套接字选项。当其被启用时,数据包必须包含IP报头。用于接收IP标头始终包含在数据包中。
我正在使用python测试IP_HDRINCL套接字选项,所以我生成了一个IP Header,但在启用该选项后,不幸的是sendto()方法似乎不起作用,我得到了以下错误
Traceback(最后一次调用):文件"./test.py",第35行,位于s.sendto(pkt,(dip,0))socket.error:[Erno 1]不允许操作
请记住,我正在使用uid 0(根)运行程序
注:
我不想使用原始套接字和PACKET系列,我仍然想使用在内核中实现的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)
?
您正在将协议设置为TCP,但没有写入标头。也许当您设置IP_HDRINCL选项时,正在进行一些验证?
原因是您可能没有管理权限。尝试使用sudo(在Linux上)或管理员(在windows上)启动脚本。