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