2010-11-06 2 views

ответ

4

Посмотрите на libpcap - это очень эффективная библиотека для сетевого нюхания, которая позволяет вам точно фиксировать тип указанных вами пакетов (возможно, еще более фильтрованный по адресу источника/адресата и т. Д.). Затем вы можете проанализировать пакет и извлечь исходные и целевые IP-адреса. Связанная страница содержит документацию и несколько руководств.

Обратите внимание, что вы должны делать захват на компьютере, через который проходит трафик (источник, пункт назначения или что-то среднее), как в современных сетях Ethernet (связанных с коммутаторами), вы обычно не видите всю сеть трафик. See this Q&A от Wireshark (который по существу является графическим интерфейсом для libpcap) для возможных обходных решений.

0

Можно, конечно, открыть сокет с

socket(AF_INET, SOCK_RAW, IPPROTO_ICMP) 

Срубы адрес источника пакетов, поступающих. Для этого вам нужно будет узнать структуру дейтаграммы ICMP. См человека 7 сырец

1

Это простой цикл (С Linux), чтобы перехватить все ICMP-запрос/ответ:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 

int main(int argc, char **argv) 
{ 
     int sock; 
     int optval; 
     int ret; 
     int addrlen; 
     struct sockaddr_in sIn; 
     char *buffer; 
     char *sAddr; 
     char *dAddr; 
     int proto; 
     int type; 

     buffer = malloc(sizeof(char) * 32); 
     sAddr = malloc(sizeof(char) * 16); 
     dAddr = malloc(sizeof(char) * 16); 
     if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) != -1) { 
      setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(int)); 
      sIn.sin_family = AF_INET; 
      sIn.sin_addr.s_addr = INADDR_ANY; 
      addrlen = sizeof(sIn); 
      memset(buffer, 0, 32); 
      while ((ret = recvfrom(sock, buffer, 31, 0, (struct sockaddr *)&sIn, &addrlen)) != -1) { 
        if (ret > 20) { 
          proto = (unsigned char)buffer[9]; 
          type = (unsigned char)buffer[20]; 
          if (proto == 1 && (type == 8 || type == 0)) { 
            memset(sAddr, 0, 16); 
            memset(dAddr, 0, 16); 
            sprintf(sAddr, "%d.%d.%d.%d", 
              (unsigned char)buffer[12], 
              (unsigned char)buffer[13], 
              (unsigned char)buffer[14], 
              (unsigned char)buffer[15]); 
            sprintf(dAddr, "%d.%d.%d.%d", 
              (unsigned char)buffer[16], 
              (unsigned char)buffer[17], 
              (unsigned char)buffer[18], 
              (unsigned char)buffer[19]); 
            if (type == 8) 
              fprintf(stdout, "-> ICMP REQUEST FROM %s TO %s\n", sAddr, dAddr); 
            else 
              fprintf(stdout, "<- ICMP REPLY FROM %s TO %s\n", sAddr, dAddr); 
          } 
        } 
        memset(buffer, 0, 32); 
      } 
      close(sock); 
     } 
     free(buffer); 
     free(sAddr); 
     free(dAddr); 
     return 0; 
} 

Enjoy;)

+0

я иногда нужно выяснить внешний IP-адрес встроенное устройство, например внутренний маршрутизатор за основным NAT. Обычно в качестве диагностических инструментов доступны только ping и traceroute. Теперь, когда этот код работает на удаленном сервере, я не могу сразу увидеть, какой IP-адрес является источником запроса ICMP. Спасибо большое! –

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

  • Нет связанных вопросов^_^