我正在尝试以 root 身份发送一个icmpv6 ping 数据包(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 代码如下(如评论中所述)
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
我不确定为什么它仍然会产生无效的论点