Как перехватить весь локальный http-запрос и извлечь URL с помощью c? - PullRequest
6 голосов
/ 24 апреля 2010

В каком направлении мне идти ( библиотеки , документы )?

UPDATE

Может кто-нибудь проиллюстрировать, как использовать winpcap для работы?

ОБНОВЛЕНИЕ 2

Как проверить, является ли пакет HTTP-пакетом?

Ответы [ 4 ]

15 голосов
/ 05 мая 2010

Если под «перехватом» вы имели в виду прослушивание пакетов, то, что вы должны сделать, чтобы сделать это с WinPcap, это:

  1. Найдите устройство, которое вы хотите использовать - См. Учебник WinPcap .

  2. Откройте устройство, используя pcap_open

    // Open the device
    char errorBuffer[PCAP_ERRBUF_SIZE];
    pcap_t *pcapDescriptor = pcap_open(source,                // name of the device
                                       snapshotLength,        // portion of the packet to capture
                                                              // 65536 guarantees that the whole packet will be captured on all the link layers
                                       attributes,            // 0 for no flags, 1 for promiscuous
                                       readTimeout,           // read timeout
                                       NULL,                  // authentication on the remote machine
                                       errorBuffer);          // error buffer
    
  3. Используйте функцию, которая читает пакеты из дескриптора, например pcap_loop

    int result = pcap_loop(pcapDescriptor, count, functionPointer, NULL);
    

    Это будет цикл до тех пор, пока что-то не произойдет, или цикл не будет прерван с помощью вызова специального метода. Он будет вызывать functionPointer для каждого пакета.

  4. В указанной функции реализуется нечто, анализирующее пакеты, оно должно выглядеть как pcap_handler:

    typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
             const u_char *);
    
  5. Теперь все, что вам осталось, - это проанализировать пакеты, в которых их буфер находится в const u_char*, а их длина - в поле pcap_pkthdr структура caplen.

    Предполагая, что у вас есть HTTP GET через TCP через IPv4 через Ethernet пакеты, вы можете:

    • Пропустить 14 байтов заголовка Ethernet.
    • Пропустить 20 байтов заголовка IPv4 (при условии, что вариантов IPv4 нет, если вы подозреваете, что варианты IPv4 возможны, вы можете прочитать 5-8 битов заголовка IPv4, умножить их на 4, и это будет число байтов занимает заголовок IPv4).
    • Пропустить 20 байтов заголовка TCP (при условии, что нет опций TCP, если вы подозреваете, что опции TCP возможны, вы можете прочитать 96-99 бит заголовка TCP, умножив это на 4, и это будет число байтов, которые берет заголовок TCP).
    • Остальная часть пакета должна быть текстом HTTP. Текст между первым и вторым пробелом должен быть URI. Если он слишком длинный, вам может потребоваться выполнить реконструкцию TCP, но большинство URI достаточно малы, чтобы поместиться в один пакет.

      ОБНОВЛЕНИЕ : В коде это будет выглядеть так (я написал без проверки):

      int tcp_len, url_length;
      uchar *url, *end_url, *final_url, *tcp_payload;
      
      ... /* code in http://www.winpcap.org/docs/docs_40_2/html/group__wpcap__tut6.html */
      
      /* retireve the position of the tcp header */
      ip_len = (ih->ver_ihl & 0xf) * 4;
      
      /* retireve the position of the tcp payload */
      tcp_len = (((uchar*)ih)[ip_len + 12] >> 4) * 4;
      tcpPayload = (uchar*)ih + ip_len + tcp_len;
      
      /* start of url - skip "GET " */
      url = tcpPayload + 4;
      
      /* length of url - lookfor space */
      end_url = strchr((char*)url, ' ');
      url_length = end_url - url;
      
      /* copy the url to a null terminated c string */
      final_url = (uchar*)malloc(url_length + 1);
      strncpy((char*)final_url, (char*)url, url_length);
      final_url[url_length] = '\0';
      

Вы также можете фильтровать только HTTP-трафик, используя создание и настройку BPF. См. Учебник по WinPcap . Вам, вероятно, следует использовать фильтр "tcp and dst port 80", который будет выдавать только запрос, который ваш компьютер отправляет на сервер.

Если вы не возражаете против использования C #, вы можете попробовать использовать Pcap.Net , который сделает все это для вас гораздо проще, включая разбор частей пакетов Ethernet, IPv4 и TCP .

1 голос
/ 03 мая 2010

Может показаться излишним, но сервер Squid веб-прокси / кеш делает именно это. Несколько лет назад моя компания использовала его, и мне пришлось настраивать код локально, чтобы обеспечить некоторые специальные предупреждения при обращении к определенным URL-адресам, поэтому я знаю, что он может делать то, что вы хотите. Вам просто нужно найти нужный код и вытащить его для вашего проекта. Я использовал версию 2.X, и теперь я вижу, что они до 3.X, но я подозреваю, что аспект кода не сильно изменился внутри.

Вы не сказали, является ли Windows «требованием» или «предпочтением», но в соответствии с сайтом: http://www.squid -cache.org / они могут делать оба.

1 голос
/ 24 апреля 2010

попробуй http://www.winpcap.org/

0 голосов
/ 24 апреля 2010

Возможно, вы захотите взглянуть на исходный код tcpdump, чтобы увидеть, как он работает. tcpdump - это утилита командной строки Linux, которая отслеживает и печатает сетевую активность. Для его использования вам необходим root-доступ к компьютеру.

...