Python原始IPv6套接字错误

Python原始IPv6套接字错误,python,ipv6,raw-sockets,Python,Ipv6,Raw Sockets,我在python中使用原始IPv6套接字时遇到一些问题。我通过以下方式连接: if self._socket != None: # Close out old socket first self._socket.close() self._socket = socket.socket(socket.AF_INET6, socket.SOCK_RAW) self._socket.bind((self._interface,0)) se

我在python中使用原始IPv6套接字时遇到一些问题。我通过以下方式连接:

    if self._socket != None:
        # Close out old socket first
        self._socket.close()
    self._socket = socket.socket(socket.AF_INET6, socket.SOCK_RAW)
    self._socket.bind((self._interface,0))
    self._socket.sendall(data)
其中self.\u接口是我的本地地址;特别是“fe80::fa1e:dfff:fed6:221d”。尝试此操作时,出现以下错误:

  File "raw.py", line 164, in connect
    self._socket.bind((self._interface,0))
  File "<string>", line 1, in bind
socket.error: [Errno 49] Can't assign requested address
文件“raw.py”,第164行,在connect中
self.\u socket.bind((self.\u接口,0))
文件“”,第1行,处于绑定状态
socket.error:[Errno 49]无法分配请求的地址
如果我将ipv6本地主机地址用于self.\u接口(“::1”),我实际上可以绑定地址,但无法发送任何内容:

    self._socket.sendall(data)
  File "<string>", line 1, in sendall
socket.error: [Errno 39] Destination address required
self.\u socket.sendall(数据)
文件“”,第1行,在sendall中
socket.error:[Errno 39]需要目标地址

为什么原始套接字需要目标地址?有没有人在python中使用原始IPv6套接字,可以帮助我理解为什么会发生这种情况?

我不理解您将
bind
sendall
组合在一起。据我所知,
bind
用于服务器套接字,
sendall
需要连接。你是说连接而不是绑定

无论如何,根据手册页,IPv6与INADDR_ANY的等价物是6addr_ANY_INIT。Python没有为它定义常量,但这与
'::'
(全部为零)相同

这对我(作为root用户)有效:

编辑:
哎呀,我第一次没有看到您实际上成功地将套接字绑定到了一个地址。然而,第二个问题很明显:在发送数据之前,必须先连接到某个地址。或者使用带有地址的
sendto
。这与IPv4没有什么不同。

此代码提供了一个具有二级访问权限的原始套接字。不幸的是OSX不支持socket.PF_数据包

soc = socket.socket(socket.PF_PACKET, socket.SOCK_RAW) #create the raw-socket
soc.bind(("lo0", 0))

soc.send(packet)

虽然这是一个老问题,但我想添加一个有效的答案,帮助任何后来偶然发现它的人

关键问题是:

原始套接字未绑定并连接到其他套接字。另外,sendto是正确使用的api

此外,ipv6数据包需要目标地址的4元组结构,而ipv4数据包需要2元组结构

最后,堆栈(至少在Linux mint 15上)对ipv6数据包更严格。如果您尝试发送一个空的icmpv4回显请求,python会允许它并通过有线发送一个没有意义的数据包。其中,与ipv6一样,当您尝试发送空数据包时,它只会给出“无效参数”错误。因此,在ipv6情况下也需要有效的请求。下面的示例针对ipv6执行所有操作,并向环回地址发送有效的ping回显请求

import socket

def main(dest_name):
    addrs = socket.getaddrinfo(dest_name, 0, socket.AF_INET6, 0, socket.SOL_IP)


    print addrs
    dest = addrs[0]

    # A minimal ICMP6-echo message (thanks to abarnert)
    data = '\x80\0\0\0\0\0\0\0'

    icmp = socket.getprotobyname('ipv6-icmp')
    #print icmp

    send_socket = socket.socket(socket.AF_INET6, socket.SOCK_RAW, icmp)
    print "sent to " + str(dest[4])
    send_socket.sendto(data, dest[4])
    send_socket.close()

if __name__ == '__main__':
    main('::1')

老实说,我遵循的是在Peach fuzzing框架()中创建的原始套接字类。我试图做的是创建任意数据包(从IP层和更高层次),以模糊ipv6。。。连接似乎包括IP层-我正试图任意创建它。好的。有可能创建一个原始数据包并将其连接到网络上吗?@wuntee:我认为您可以使用
sendto
:@wuntee:您可能还对sendto函数不需要您定义目标地址-IP感兴趣?如果是这样,那么我将无法在数据包中定义IP层。。。
import socket

def main(dest_name):
    addrs = socket.getaddrinfo(dest_name, 0, socket.AF_INET6, 0, socket.SOL_IP)


    print addrs
    dest = addrs[0]

    # A minimal ICMP6-echo message (thanks to abarnert)
    data = '\x80\0\0\0\0\0\0\0'

    icmp = socket.getprotobyname('ipv6-icmp')
    #print icmp

    send_socket = socket.socket(socket.AF_INET6, socket.SOCK_RAW, icmp)
    print "sent to " + str(dest[4])
    send_socket.sendto(data, dest[4])
    send_socket.close()

if __name__ == '__main__':
    main('::1')