如何在Python中创建ICMP跟踪路由
我想在Python中实现基于ICMP的Traceroute。如何在Python中创建ICMP跟踪路由
我发现一个非常有用的指南(https://blogs.oracle.com/ksplice/entry/learning_by_doing_writing_your),它允许我创建一个基于UDP的Traceroute(下面的代码),所以只需要修改。我已经尝试将发送套接字更改为ICMP,但是我无法获得任何可以运行的例外情况。
注 - 下面的代码工作,但这是一个UDP跟踪路由(发送一个UDP包并接收一个ICMP包),我需要我的程序发送一个ICMP包并接收一个ICMP包。这是因为现在的防火墙比以前更聪明,并且在收到随机端口的UDP数据包后并不总是发送ICMP响应。本质上UDP套接字需要为ICMP更改。
我想这不是最常见的尝试和实现的事情,并且在网上如何做到这一点上遇到麻烦。如果有人可以提供一些见解,它将是真正的赞赏:-)
要记住的要点是,跟踪路由器通过设置TTL的工作,所以如果解决方案是使用ICMP库,那么它需要一个可配置的TTL: - )
#!/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')
如果你不想自己管理的插座,scapy是建立自己的包,并做基本的发送/与他们收到一个伟大的工具。你可以找到一个例子here如何ping,从这(并阅读一些文档),你应该能够很容易地建立自己的traceroute。
谢谢,这个例子实际上是一个TCP ping,而不是一个ICMP。通过Scapys的帮助功能,我已经有了一个很好的看法,但是它对于ICMP并没有太多的帮助,但对于基于TCP/UDP的任何东西看起来都很棒。 – Jamesla 2012-04-24 12:08:35
@Jamesla:实际上有很多例子,第一个是ICMP,但也有TCP和UDP ping。 Scapy可以构建L2上的任何东西,我之前用它来实现完全基于L2的协议(不管IP)。 – KillianDS 2012-04-25 07:13:04
感谢您阅读并且它是一个了不起的工具,并且我已经完成了它的工作。我将使用下面的确切代码添加一个解决方案。再次感谢。 – Jamesla 2012-04-26 03:35:05
这是使用Scapy的解决方案 - 感谢KillianDS。
发送平安
ans,unans=sr(IP(dst="www.google.com",ttl=X)/ICMP())
访问答复
ans.summary(lambda (s,r): r.sprintf("%IP.src%"))
您有什么问题? – Keith 2012-04-21 10:12:48
你所描述的问题太广泛了(主要是说“为我做所有的工作”)。如果您发布带有例外的代码,显示例外情况并询问如何解决这些问题,则更有可能获得有用的答案。目前你的帖子甚至不包括明确的问题。你需要*提问*。 – 2012-04-21 10:39:13