2016-04-21 168 views
1

我構建了一個traceroute-ish工具來確定UDP數據包僅使用一個探針到達地址所需的跳數。爲此,我想從發送探測後收到的ICMP消息中提取TTL。我做以下,併成功接收到ICMP消息:從通過Python原始套接字接收到的ICMP消息中讀取TTL

data, source = in_socket.recvfrom(d_bufsize) 

但我不知道如何把data到的東西,我可以閱讀從TTL。 in_socket聲明如下:

in_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp_proto) 

這裏,icmp_proto僅僅是ICMP協議號(通過執行icmp_proto = socket.getprotobyname("icmp")獲得)。

任何幫助將不勝感激!

+0

TTL位於IP標頭中,不屬於ICMP。所以除非這個返回整個IP數據包,否則你不能這樣做。 – Barmar

+0

@Barmar:訣竅是ICMP消息包含觸發錯誤的數據報的一部分。因此,通過發送一個已知TTL的數據報,然後使用錯誤觸發數據報的包含部分來確定到達時的TTL,您應該能夠確定跳數。 – hexaflexagonal

+0

噢,我以爲你在談論接收到的數據報的TTL,而不是觸發ICMP的發送數據報的TTL。 – Barmar

回答

1

但我不知道如何將data轉成東西,我可以從中讀取 的TTL。

pyping確實是這樣:

def header2dict(self, names, struct_format, data): 
     """ unpack the raw received IP and ICMP header informations to a dict """ 
     unpacked_data = struct.unpack(struct_format, data) 
     return dict(zip(names, unpacked_data)) 
… 

      packet_data, address = current_socket.recvfrom(ICMP_MAX_RECV) 

      icmp_header = self.header2dict(
       names=[ 
        "type", "code", "checksum", 
        "packet_id", "seq_number" 
       ], 
       struct_format="!BBHHH", 
       data=packet_data[20:28] 
      ) 

      if icmp_header["packet_id"] == self.own_id: # Our packet 
       ip_header = self.header2dict(
        names=[ 
         "version", "type", "length", 
         "id", "flags", "ttl", "protocol", 
         "checksum", "src_ip", "dest_ip" 
        ], 
        struct_format="!BBHHHBBHII", 
        data=packet_data[:20] 
       ) 
       packet_size = len(packet_data) - 28 
       ip = socket.inet_ntoa(struct.pack("!I", ip_header["src_ip"])) 

的TTL然後可以從ip_header["ttl"]讀取。