如何在Python中创建ICMP跟踪路由

如何在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') 
+0

您有什么问题? – Keith 2012-04-21 10:12:48

+1

你所描述的问题太广泛了(主要是说“为我做所有的工作”)。如果您发布带有例外的代码,显示例外情况并询问如何解决这些问题,则更有可能获得有用的答案。目前你的帖子甚至不包括明确的问题。你需要*提问*。 – 2012-04-21 10:39:13

如果你不想自己管理的插座,scapy是建立自己的包,并做基本的发送/与他们收到一个伟大的工具。你可以找到一个例子here如何ping,从这(并阅读一些文档),你应该能够很容易地建立自己的traceroute。

+0

谢谢,这个例子实际上是一个TCP ping,而不是一个ICMP。通过Scapys的帮助功能,我已经有了一个很好的看法,但是它对于ICMP并没有太多的帮助,但对于基于TCP/UDP的任何东西看起来都很棒。 – Jamesla 2012-04-24 12:08:35

+0

@Jamesla:实际上有很多例子,第一个是ICMP,但也有TCP和UDP ping。 Scapy可以构建L2上的任何东西,我之前用它来实现完全基于L2的协议(不管IP)。 – KillianDS 2012-04-25 07:13:04

+0

感谢您阅读并且它是一个了不起的工具,并且我已经完成了它的工作。我将使用下面的确切代码添加一个解决方案。再次感谢。 – 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%"))