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