2012-04-21 121 views
3

我想在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

回答

0

如果你不想自己管理的插座,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

2

這是使用Scapy的解決方案 - 感謝KillianDS。

發送平安

ans,unans=sr(IP(dst="www.google.com",ttl=X)/ICMP()) 

訪問答覆

ans.summary(lambda (s,r): r.sprintf("%IP.src%"))