Amir reza Riahi
Amir reza Riahi

Reputation: 2450

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

I'm using libpcap in c to write a packet sniffer. 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:

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

Upvotes: 1

Views: 1809

Answers (2)

chux
chux

Reputation: 153458

At least these issues

Printing array as string without a null chracter

Append a null chracter or limit printing.

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

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

Upvotes: 3

Boris Lipschitz
Boris Lipschitz

Reputation: 1631

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:

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

Upvotes: 0

Related Questions