Как я могу распечатать все данные пакета в c? - PullRequest
0 голосов
/ 04 августа 2020

Я использую libpcap в c для написания анализатора пакетов. Как я могу распечатать все данные в пакете? Я пробовал вот так:

#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>


void packet_process(u_char *args,const struct pcap_pkthdr *header,const u_char *packet){

        struct ether_header *eh;
        const u_char *ip_header;
        ip_header = packet + 14;
        u_char proto = *(ip_header+9);
        eh=(struct ether_header *) packet;
        const u_char *ptr = packet;
        int bytes = 0;
        char packet_content[1000];
        static int i=0;
        fprintf(stdout, "%d) len: %d\n", ++i, header->len);
        while(bytes ++ < 1000){
                packet_content[bytes-1] = *ptr;
                ptr ++;
        }
        fprintf(stdout, "%s\n\n", packet_content);
        fflush(stdout);

}

int main(int argc, char *argv[]){

    char error[PCAP_ERRBUF_SIZE];
    pcap_t *handle = pcap_open_live(argv[1], BUFSIZ, 0, -2, error);
    pcap_loop(handle, atoi(argv[2]),packet_process, NULL );
    pcap_close(handle);
    return 0;

}

, но этот код не показывает все данные в пакете, вывод этого кода был следующим:

[amirreza@localhost tmp]$ sudo ./a.out enp3s0 5
1) len: 118
0���:T����

2) len: 145
T����0���:

3) len: 118
0���:T����

4) len: 145
T����0���:

5) len: 117
0���:T����

Я не знаю, как сделать их удобочитаемыми, а также распечатать целые данные в пакете.

Ответы [ 2 ]

1 голос
/ 04 августа 2020

По крайней мере, эти проблемы

Печать массива как строка без нулевого символа

Добавить нулевой символ или ограничить печать.

Печать неназначенных элементов массива

Ограничение печати

Назначение внешних границ массива

Назначение пределов l oop.

    char packet_content[1000];
    static int i=0;
    fprintf(stdout, "%d) len: %d\n", ++i, header->len);
    int limit = header->len < 1000 ? header->len : 1000;  // add
    //while(bytes ++ < 1000){
    while(bytes ++ < limit){
            packet_content[bytes-1] = *ptr;
            ptr ++;
    }
    // fprintf(stdout, "%s\n\n", packet_content);
    fprintf(stdout, "%.*s\n\n", limit, packet_content);

Для печати данных в шестнадцатеричном формате

    // fprintf(stdout, "%s\n\n", packet_content);
    for (int i=0; i<limit; i++) {
      fprintf(stdout, " %02X", (unsigned char) packet_content[i]);
      // or since C99
      fprintf(stdout, " %02hhX", packet_content[i]);
      // or best, use unsigned packet_content[1000]
    }
    fprintf(stdout, "\n\n");

Для печати данных в смешанном формате ASCII и шестнадцатеричном формате

    for (int i=0; i<limit; i++) {
      unsigned char ch = packet_content[i];
      if (isprint(ch)) {
        fprintf(stdout, " '%c", ch);
      } else {
        fprintf(stdout, " %02X", ch);
      }
    }
    fprintf(stdout, "\n");
    
0 голосов
/ 04 августа 2020

Здесь нет pcap, чтобы проверить это, но я бы начал с чего-то очень простого, просто выгрузите все пакеты, не разбирая их, после того, как эта часть заработает, продолжите фильтрацию, синтаксический анализ и т. Д. c. Примерно так:

void dump(const void* voidbuf, int len)
{
    static int linecnt = 16;
    const unsigned char* buf = voidbuf;
    for (int i=0; i<len; i+=linecnt, putch('\n'))
    {
        for (int j=0; j<linecnt; j++, putch(' '))
        {
            static const char HEX[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
            putch(i+j<len ? HEX[buf[i+j] >> 4] : ' ');
            putch(i+j<len ? HEX[buf[i+j] & 0x0F] : ' ');
        }
        putch('|');
        putch(' ');
        for (int j=0; j<linecnt; j++)
            putch(i+j<len ? (buf[i+j]>=' ' && buf[i+j]<='z' ? buf[i+j] : '.') : ' ');
    }
}

// libpcap callback
void packet_process(u_char *args,const struct pcap_pkthdr *header,const u_char *packet)
{
    // just dump the entire thing, after you see this working properly, start working 
    // on filtering just the packets you want, and then, finally, fully parsing the 
    // packets that are out of intereset
    dump(packet, header->caplen);
}
...