2016-04-21 2 views
1

Я создаю инструмент traceroute-ish, чтобы определить количество перелетов, необходимых для UDP-пакета, для достижения адреса, используя только один зонд. Для этого я хочу извлечь TTL из сообщения ICMP, которое я получаю после отправки зонда. Я делаю следующее и успешный прием сообщения ICMP:Прочитайте TTL из сообщения ICMP, полученного через исходные сокеты Python

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 полученной дейтаграммы, а не TTL отправленной дейтаграммы, вызвавшей ICMP. – Barmar

ответ

1

Но я понятия не имею, как превратить data в то, что я могу читать ТТЛ с.

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"])) 

ТТЛ, то можно прочитать из ip_header["ttl"].

Смежные вопросы