Python 原始 IPv6 套接字错误
我在 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._interface 是我的本地地址;特别是“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
如果我使用我的 ipv6 本地主机地址作为 self._interface ("::1") 我实际上可以绑定该地址,但无法发送任何内容:
self._socket.sendall(data)
File "<string>", line 1, in sendall
socket.error: [Errno 39] Destination address required
Why would a raw socket need a target address ?有没有人在 python 中使用过原始 IPv6 套接字,并且可以帮助我理解为什么会发生这种情况?
I am having some problems using raw IPv6 sockets in python. I connect via:
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)
where self._interface is my local address; specifically "fe80::fa1e:dfff:fed6:221d". When trying this, I get the following error:
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
If I use my ipv6 localhost address for self._interface ("::1") I can actually bind the address, but can not send anything:
self._socket.sendall(data)
File "<string>", line 1, in sendall
socket.error: [Errno 39] Destination address required
Why would a raw socket need a destination address? Has anyone worked with raw IPv6 sockets in python, and can help me understand why this is happening?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
虽然这是一个老问题,但我想添加一个有效的答案,并帮助任何后来偶然发现它的人。
关键问题是:
原始套接字未绑定并连接到其他套接字。另外,sendto 是要使用的正确 API。
此外,ipv6 数据包需要 4 个元组结构作为目标地址,而不是 ipv4 需要两个元组结构。
最后,堆栈(至少在 Linux mint 15 上)对 ipv6 数据包更加严格。如果您尝试发送一个空的 icmpv4 echo 请求,Python 会允许它并在线上发送一个无意义的数据包。与 ipv6 的情况一样,当您尝试发送空数据包时,它只会给出“无效参数”错误。因此,如果是 ipv6,则还需要有效的请求。以下示例针对 ipv6 执行所有操作,并向环回地址发送有效的 ping echo 请求。
Although this is an old question, i thought of adding an answer that works and helps any one who stumbles upon it latter.
The key problems are:
Raw sockets are not bound and connected to other sockets. Also sendto is the correct api to use.
Moreover, 4 tuple structure for destination address is required for ipv6 packets as opposed to two tuple ones for ipv4.
Lastly, the stack (at least on Linux mint 15) is more strict on ipv6 packets. If you try sending an empty icmpv4 echo request, python allows it and sends a meaning less packet on wire. Where as in case of ipv6, it simply gives error of 'invalid argument' when you try sending an empty packet. Hence a valid request is also required in case of ipv6. Following example does that all for ipv6 and sends a valid ping echo request to loop back address.
我不明白您的
bind
和sendall
组合。根据我的理解,bind
用于服务器套接字,sendall
需要连接。您是指connect
而不是bind
吗?无论如何,根据手册页,INADDR_ANY 的 IPv6 等效项是 IN6ADDR_ANY_INIT。 Python 没有为它定义常量,但这与
'::'
相同(全为零)。这对我有用(作为root):
编辑:
哎呀,我首先没有看到您实际上设法将套接字绑定到地址。然而,你的第二个问题很明显:你必须首先连接到某个地址,然后才能发送数据。或者将
sendto
与地址一起使用。这与 IPv4 没有什么不同。I don't understand your combination of
bind
andsendall
. In my understanding,bind
is for server sockets andsendall
requires a connection. Did you meanconnect
instead ofbind
?Anyway, the IPv6 equivalent of INADDR_ANY is, according to the man page, IN6ADDR_ANY_INIT. Python does not define a constant for it, but this is the same as
'::'
(all zero).This worked for me (as root):
EDIT:
Oops, I first did not saw that you actually managed to bind the socket to an address. However your second problem is obvious: You must first connect to some address before you can send data. Or use
sendto
with an address. This is not different from IPv4.此代码提供了具有 L2 访问权限的原始套接字。不幸的是OSX不支持socket.PF_PACKET...
This code provides a raw socket with L2 access. Unfortunately OSX does not support the socket.PF_PACKET...