简体   繁体   English

如何在 c 中打印数据包的全部数据?

[英]How can I print whole data of a packet in c?

I'm using libpcap in c to write a packet sniffer.我在c中使用libpcap来编写数据包嗅探器。 How can I print whole data in the packet?如何打印数据包中的全部数据? I'v tried this way:我试过这样:

#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;

}

but this code does not show whole data in packet, the output of this code was this:但此代码并未显示数据包中的全部数据,此代码的 output 是这样的:

[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����

I don't know how make them human readable and also print whole data in the packet.我不知道如何使它们具有人类可读性并在数据包中打印整个数据。

At least these issues至少这些问题

Printing array as string without a null chracter将数组打印为没有null字符的字符串

Append a null chracter or limit printing. Append 一个null 字符或限制打印。

Printing unassigned elements of an array打印数组的未分配元素

Limit printing限制打印

Assigning outside array bounds分配外部数组边界

Limit assignment loop.限制分配循环。

    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);

To print data as hexadecimal以十六进制打印数据

    // 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");

To print data as in mixed ASCII and hexadecimal以混合 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");
    

Don't have pcap here to test it, but i'd start from something really simple, just dump the entire packets, without parsing them, after this part works, proceed with filtering, parsing, etc. Something like this:这里没有 pcap 来测试它,但我会从非常简单的东西开始,只是转储整个数据包,而不解析它们,在这部分工作之后,继续过滤、解析等。像这样的东西:

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM