Python Raw套接字 - IP_HDRINCL选项

时间:2015-04-24 13:09:00

标签: python sockets

根据原始套接字的手册页,

  

IPv4层在发送数据包时生成IP头,除非          套接字上启用了IP_HDRINCL套接字选项。启用时,          数据包必须包含IP标头。用于接收IP头是          总是包含在数据包中。

我正在使用python来测试IP_HDRINCL套接字选项,所以我已经生成了一个IP Header但是在启用该选项之后,遗憾的是sendto()方法似乎没有工作,我得到了以下错误

  

追踪(最近一次通话):       文件“./test.py”,第35行,in       s.sendto(pkt,(dip,0))       socket.error:[Errno 1]不允许操作

请记住,我正在使用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 ))

2 个答案:

答案 0 :(得分:1)

你试过用过吗? s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW),而不是

您已将协议设置为TCP但未写入标头。也许当您设置IP_HDRINCL选项时,会进行一些验证吗?

答案 1 :(得分:0)

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