繁体   English   中英

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

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

我在c中使用libpcap来编写数据包嗅探器。 如何打印数据包中的全部数据? 我试过这样:

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

}

但此代码并未显示数据包中的全部数据,此代码的 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����

我不知道如何使它们具有人类可读性并在数据包中打印整个数据。

至少这些问题

将数组打印为没有null字符的字符串

Append 一个null 字符或限制打印。

打印数组的未分配元素

限制打印

分配外部数组边界

限制分配循环。

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

这里没有 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