【发布时间】:2013-11-11 08:57:48
【问题描述】:
我正在尝试发送 icmpv6 ping 数据包,以 root 身份运行(Linux 上的 python 2.7)
我知道 sendto 在 ipv4 的情况下使用两个元组结构(并且它有效)并且知道 ipv6 使用一个 4 元组结构。我仍然无法让它工作。
这会导致“无效参数”或“socket.gaierror: [Errno -2] Name or service not known”
以下是显示我正在尝试的最小示例。如果我能让它在 ipv6 的情况下与本地主机一起工作,我什至可以,即 ::1
import socket
def main(dest_name):
#dest_addr = socket.gethostbyname(dest_name)
addrs = socket.getaddrinfo(dest_name, 0, socket.AF_INET6, 0, socket.SOL_IP)
print addrs
dest = addrs[2]
port = 33434 # just some random number because of icmp
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('', (str(dest[4]), port))
send_socket.close()
if __name__ == '__main__':
main('ipv6.google.com')
我实际上尝试了 addr 列表中的每个元组,但结果都是一样的。
更新:
也尝试过使用 sendto 的参数,但无论我使用本地主机还是谷歌 ipv6 地址,都会导致参数无效
send_socket.sendto('', dest[4])
更新 2:
作为参考,工作 ipv4 代码如下(在 cmets 中询问)
def main(dest_name):
dest_addr = socket.gethostbyname(dest_name)
icmp = socket.getprotobyname('icmp')
send_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
print "sent to " + dest_name#str(dest[4])
send_socket.sendto('', (dest_addr, 0))
send_socket.close()
if __name__ == '__main__':
main('www.google.com')
更新 3:
当我以 dest[4] 作为唯一参数(没有字符串,只有元组和 NO 端口)运行 v6 版本时,以下是我的机器(Mint 15)上的输出,其中包括打印接口
sudo python test_v6.py
[(10, 1, 6, '', ('::1', 0, 0, 0)), (10, 2, 17, '', ('::1', 0, 0, 0)), (10, 3, 0, '', ('::1', 0, 0, 0))]
sent to ('::1', 0, 0, 0)
Traceback (most recent call last):
File "test_v6.py", line 18, in <module>
main('::1')
File "test_v6.py", line 14, in main
send_socket.sendto('', dest[4])
socket.error: [Errno 22] Invalid argument
我不确定为什么它仍然会产生无效参数
【问题讨论】:
-
你能展示你的工作 IPv4 代码吗?我不知道为什么你期望
str(dest[4])可以与 IPv6 的 4 元组一起工作,而它不能与 IPv4 的 2 元组一起工作。无论哪种方式,它都会创建一个 Python 元组的字符串表示,它看起来不像sendto想要的。 -
同时,请显示您得到的实际异常。当我使用
dest[4](首先使用或不使用dest[4][1] = port)尝试此代码时,它会成功获取本地主机地址,并为Google 返回ENETUNREACH错误(这是有道理的,因为我没有IPv6 互联网连接) . -
最后,您可以与 Google 建立 IPv6 TCP 连接吗?你能从 shell 中
traceroute6或ping6他们吗? -
感谢@abarnert,添加了ipv4代码
-
我只将 dest[4] 转换为字符串,当我第一次放入它时,错误是,'函数需要字符串或缓冲区,而不是元组'。我后来才意识到这是因为我不必要地附加了另一个参数“端口”。
标签: python sockets ipv6 icmp sendto