2016-04-21 60 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"]读取。

相关问题