Извлечение полезной нагрузки Tcp и правильный IP-адрес - PullRequest
0 голосов
/ 12 января 2012

Я пытаюсь извлечь полезную нагрузку tcp из пакета, и вот минимальный случай обратного вызова захвата:

void capture_callback (u_char *hdr , const struct pcap_pkthdr* pkthdr , const u_char* buff)
{
    struct ether_header *eptr = (struct ether_header *) buff;
    buff += sizeof (ether_header); /* jump over ethernet header: 14 bytes */

    if ( ntohs (eptr->ether_type) == ETHERTYPE_IP )
    {
        struct ip *iph;
        struct tcphdr *tcp_header;

        iph = (struct ip *) buff;
        buff += sizeof (ip); /* jump over ip header */

        if ( iph->ip_p == IPPROTO_TCP )
        {
            tcp_header = (struct tcphdr *) buff;
            buff += sizeof (tcphdr); /* jump over tcp header */

            cout << inet_ntoa (iph->ip_src) << ":" << ntohs (tcp_header->th_sport) <<
                        " --> " << inet_ntoa(iph->ip_dst) << ":" << ntohs (tcp_header->th_dport) << endl;

        }

    }
}
  1. Но здесь что-то пошло не так, IP-адрес источника и назначенияодинаковы.

  2. И кроме того, как я могу распечатать полезную нагрузку?Поскольку я не могу просто преобразовать массив без знака в массив символов явно, который заканчивается на "\ 0", это может привести к ошибкам.

    192.168.56.1: 48065 -> 192.168.56.1:80

    192.168.56.80: 80 -> 192.168.56.80:48065

РЕДАКТИРОВАТЬ

---------------------

Спасибо Celeda, я решил проблему с IP-адресом, разделив вызов inet_ntoa:

    cout << "IP: " << inet_ntoa (iph->ip_src) << ":" << ntohs (tcp_header->th_sport) <<
                " --> ";
    cout << inet_ntoa(iph->ip_dst) << ":" << ntohs (tcp_header->th_dport) << endl;

А теперь вторая часть, я использую:

cout << hex << buff << endl;

Для протокола HTTP, и я не вижу ничего подобного "GET /", но несколько пустых строк

РЕДАКТИРОВАТЬ 2

--------------------------

На данный момент я не уверен в параметрах TCP, я проверю больше документов о деталях, но сейчас это работает хорошо.

    if ( iph->ip_p == IPPROTO_TCP )
    {
        tcp_header = (struct tcphdr *) buff;
        buff += tcp_header->th_off * 4;

        cout << "IP: " << inet_ntoa (iph->ip_src) << ":" << ntohs (tcp_header->th_sport) <<
                    " --> ";
        cout << inet_ntoa(iph->ip_dst) << ":" << ntohs (tcp_header->th_dport) << endl;

        for ( int i = 0 ; i < iph->ip_len - iph->ip_off * 4; i ++ )
        {
            if ( isascii (buff[i]) )
            {
                cout << buff[i];
            }
        }
        cout << endl << "-----------" << endl;

    }

1 Ответ

1 голос
/ 12 января 2012
  1. inet_ntoa() использует статический буфер.Вы перезаписываете буфер, вызывая его дважды.Вместо этого используйте inet_ntop().

  2. Полезные данные могут быть двоичными данными.Как вы хотите распечатать это?Как шестнадцатеричный дамп или что-то в этом роде?Просто просмотрите полезную нагрузку и напечатайте байты как шестнадцатеричные по одному для упрощенного шестнадцатеричного дампа.Или, если вы уверены, что это данные для печати, вы можете вывести их непосредственно на выход с помощью любой функции, например fwrite(), которая позволяет указать длину строки для записи.

РЕДАКТИРОВАТЬ ДОПОЛНИТЕЛЬНУЮ ИНФОРМАЦИЮ В ВОПРОСЕ

«Дополнительные символы», которые вы видите перед данными HTTP, звучат как параметры TCP, которые вы пытаетесь интерпретировать как данные полезной нагрузки.Обязательно правильно рассчитайте размер заголовка TCP, когда на него наведет указатель buff.Это 4 байта * th_off.Пока вы это делаете, вы должны сделать то же самое для IP-заголовка, используя ip_hl, потому что IP-заголовок также не всегда равен 20 байтам.

Впоследствии, конечное условие в вашем цикле for является неправильным,Во-первых, ip_off (смещение фрагмента) в него не входит, а во-вторых, ip_hl и tcp_off измеряются в единицах по 4 байта, а не в байтах.

Сравните то, что выВы узнаете, как Wireshark декодирует тот же пакет, и вы сможете легко диагностировать любое дальнейшее расхождение.

...