Reputation: 2450
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
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
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