Python原始套接字-IP_HDRINCL选项

Python原始套接字-IP_HDRINCL选项,python,sockets,Python,Sockets,根据原始插座的手册页 IPv4层在发送数据包时生成IP报头,除非 已在套接字上启用IP_HDRINCL套接字选项。启用时, 数据包必须包含IP头。用于接收IP报头的 始终包含在包中 我正在使用python测试IP_HDRINCL套接字选项,因此我生成了一个IP头,但在启用该选项后,不幸的是sendto()方法似乎不起作用,我得到了以下错误 回溯(最近一次呼叫最后一次): 文件“/test.py”,第35行,在 s、 发送到(组件,(dip,0)) socket.error:[Errno 1]不允

根据原始插座的手册页

IPv4层在发送数据包时生成IP报头,除非 已在套接字上启用IP_HDRINCL套接字选项。启用时, 数据包必须包含IP头。用于接收IP报头的 始终包含在包中

我正在使用python测试IP_HDRINCL套接字选项,因此我生成了一个IP头,但在启用该选项后,不幸的是sendto()方法似乎不起作用,我得到了以下错误

回溯(最近一次呼叫最后一次): 文件“/test.py”,第35行,在 s、 发送到(组件,(dip,0)) socket.error:[Errno 1]不允许操作

请记住,我正在使用uid 0(根)运行程序

注:

我不想将原始套接字与数据包系列一起使用,我仍然希望利用内核中实现的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 ))
#/usr/bin/env python
导入套接字
导入结构
def IP():
版本=4
国际人道主义法=5
DF=0
Tlen=0
ID=0
标志=0
片段=0
TTL=64
Proto=socket.IPPROTO\u TCP
ip_校验和=0
SIP=socket.inet_aton(“172.16.122.2”)
DIP=插座内线(“172.16.122.1”)
你有没有试过使用
s=socket.socket(socket.AF\u INET,socket.SOCK\u RAW,socket.IPPROTO\u RAW)
而不是


您正在将协议设置为TCP,但未写入标头。可能在设置IP_HDRINCL选项时正在进行验证?

原因是您可能没有管理员权限。请尝试使用sudo(在Linux上)或管理员(在windows上)启动脚本。

根据原始套接字手册页面,“IPPROTO_RAW的协议意味着启用了IP_HDRINCL”,所以它是一样的,我只是使用了它,它工作了,非常感谢。换句话说,您可以使用IPPROTO_RAW告诉内核不要包含IP头