【发布时间】:2012-04-04 09:10:51
【问题描述】:
我正在尝试在 Python 中实现基于 ICMP 的 Traceroute。我找到了一个非常有用的指南 (https://blogs.oracle.com/ksplice/entry/learning_by_doing_writing_your),它允许我创建一个基于 UDP 的 Traceroute,所以只需要修改。但是,我环顾四周,无法更改发送套接字并使其工作。有人可以帮助我吗?
#!/usr/bin/python
import socket
def main(dest_name):
dest_addr = socket.gethostbyname(dest_name)
port = 33434
max_hops = 30
icmp = socket.getprotobyname('icmp')
udp = socket.getprotobyname('udp')
ttl = 1
while True:
recv_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
send_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, udp)
send_socket.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl)
recv_socket.bind(("", port))
send_socket.sendto("", (dest_name, port))
curr_addr = None
curr_name = None
try:
_, curr_addr = recv_socket.recvfrom(512)
curr_addr = curr_addr[0]
try:
curr_name = socket.gethostbyaddr(curr_addr)[0]
except socket.error:
curr_name = curr_addr
except socket.error:
pass
finally:
send_socket.close()
recv_socket.close()
if curr_addr is not None:
curr_host = "%s (%s)" % (curr_name, curr_addr)
else:
curr_host = "*"
print "%d\t%s" % (ttl, curr_host)
ttl += 1
if curr_addr == dest_addr or ttl > max_hops:
break
if __name__ == "__main__":
main('google.com')
【问题讨论】:
-
它是 receiving 套接字,如果你不以 root 身份运行它会导致
operation not permitted。 -
你在哪个平台上运行这个?实际上你提到的文章提到了
Because raw sockets require root privileges, traceroute is typically setuid. For our purposes, we can just run the script as root:。但是,它看起来像例如在 RHEL5 上,traceroute不是 setuid root(另请参阅 traceroute.sourceforge.net) -
是的,在 Ubuntu 上运行并以 root 身份运行,运行它没有问题,问题在于运行时的语法
-
您可以发布您收到的错误消息吗?当我之前尝试过该脚本时,它对我来说完美无缺(在 Ubuntu 上以 root 身份)。 -- 我刚刚注意到您在
#!之前有一个空格,您运行的脚本中是否也有这个空格(它应该不在那里)? -
是的,这个脚本工作正常,但是它在发送套接字上发送一个 UDP 数据包,而不是一个 ICMP 数据包。我需要将发送套接字更改为 ICMP。我在下面做了一些修改,但是 socket.setsockopts() 给出了错误 send_socket.setsockopt(socket.SOL_IP, socket.IP_TTL, ttl)。
标签: python sockets udp icmp traceroute