读取具有特定字节顺序的 libcap 文件
Read libcap file with specific endianness
我写了一个 c-lang 程序来读取 .pcap file.What 让我感到困惑的是我读取的数据与 WireShark 的字节顺序不同。
我正在研究 X86 ach,正如我所见,它是 LittleEndian。
那么,我可以用 BigEndian 读取 .pcap 文件吗?怎么样?
代码片段:
/*
* global header
*/
typedef struct{
// fileds here
} GlobalHdr;
/*
* record (packet) header
*/
typedef struct{
// fileds here
} RecordHdr;
/*
* IP v4 header
*/
typedef struct{
// fileds here
/* the options start here, if tot_len is bigger than 5*/
} Ipv4Hdr;
/*
* UDP header
*/
typedef struct{
// fileds here
} UdpHdr;
/*
* main function
*/
int main(){
FILE *srcfile = NULL; // the .pcap file
GlobalHdr g_hdr = {0};
RecordHdr r_hdr = {0};
Ipv4Hdr ip_hdr = {0};
UdpHdr u_hdr = {0};
unsigned long fl_len = 0;
unsigned long index = 0;
unsigned char sizghdr = sizeof(GlobalHdr);
unsigned char sizrhdr = sizeof(RecordHdr);
unsigned char sizihdr = sizeof(Ipv4Hdr);
unsigned char sizuhdr = sizeof(UdpHdr);
srcfile = fopen (SRC_FILE, "r");
if(!srcfile){
PERR ("source file opening");
}
fseek (srcfile, 0, SEEK_END);
fl_len = ftell (srcfile);
fseek (srcfile, 0, SEEK_SET);
printf ("file length: %ld\n", fl_len);
// read file global header
CHECK_POSITION (sizghdr);
if(!fread (&g_hdr, sizghdr, 1, srcfile)){
PERR ("reading global header");
}
print_ghdr (&g_hdr);
// read blocks
while(1){
// read block header
CHECK_POSITION (sizrhdr);
if(!fread (&r_hdr, sizrhdr, 1, srcfile)){
PERR ("reading block header");
}
print_rhdr (&r_hdr);
// read ethernet header
CHECK_POSITION (LINK_LAYER_LEN);
fseek (srcfile, index, SEEK_SET);
// read IP header
CHECK_POSITION (sizihdr);
if(!fread (&ip_hdr, sizihdr, 1, srcfile)){
PERR ("reading ip header");
}
print_iphdr (&ip_hdr);
// read UDP header
CHECK_POSITION (sizuhdr);
if(!fread (&u_hdr, sizuhdr, 1, srcfile)){
PERR ("reading upd header");
}
print_udphdr (&u_hdr);
// read contained data
CHECK_POSITION (r_hdr.orig_len - sizrhdr
- LINK_LAYER_LEN - sizihdr - sizuhdr
);
fseek (srcfile, index, SEEK_SET);
}
// clean up
puts ("Done!");
CLEAN_UP;
return 0;
}
So, can I read the .pcap file with BigEndian?
是的。
How?
- 使用 libpcap/WinPcap,而不是编写自己的代码来阅读它,因为 libpcap/WinPcap 会为您处理 byte-order 问题;
- 查看幻数以确定文件的字节顺序是否与读取它的主机的字节顺序相同或相反,如果字节顺序相反,byte-swap 16 位和 32 位整数。
请注意,数据包 数据(某些元数据 headers 除外)按照其在网络上出现的字节顺序排列,不是主机写入数据的字节顺序。例如IP和TCP中的16位和32位整数值headers都是alwaysbig-endian,以太网类型字段也是
]
我写了一个 c-lang 程序来读取 .pcap file.What 让我感到困惑的是我读取的数据与 WireShark 的字节顺序不同。
我正在研究 X86 ach,正如我所见,它是 LittleEndian。
那么,我可以用 BigEndian 读取 .pcap 文件吗?怎么样?
代码片段:
/*
* global header
*/
typedef struct{
// fileds here
} GlobalHdr;
/*
* record (packet) header
*/
typedef struct{
// fileds here
} RecordHdr;
/*
* IP v4 header
*/
typedef struct{
// fileds here
/* the options start here, if tot_len is bigger than 5*/
} Ipv4Hdr;
/*
* UDP header
*/
typedef struct{
// fileds here
} UdpHdr;
/*
* main function
*/
int main(){
FILE *srcfile = NULL; // the .pcap file
GlobalHdr g_hdr = {0};
RecordHdr r_hdr = {0};
Ipv4Hdr ip_hdr = {0};
UdpHdr u_hdr = {0};
unsigned long fl_len = 0;
unsigned long index = 0;
unsigned char sizghdr = sizeof(GlobalHdr);
unsigned char sizrhdr = sizeof(RecordHdr);
unsigned char sizihdr = sizeof(Ipv4Hdr);
unsigned char sizuhdr = sizeof(UdpHdr);
srcfile = fopen (SRC_FILE, "r");
if(!srcfile){
PERR ("source file opening");
}
fseek (srcfile, 0, SEEK_END);
fl_len = ftell (srcfile);
fseek (srcfile, 0, SEEK_SET);
printf ("file length: %ld\n", fl_len);
// read file global header
CHECK_POSITION (sizghdr);
if(!fread (&g_hdr, sizghdr, 1, srcfile)){
PERR ("reading global header");
}
print_ghdr (&g_hdr);
// read blocks
while(1){
// read block header
CHECK_POSITION (sizrhdr);
if(!fread (&r_hdr, sizrhdr, 1, srcfile)){
PERR ("reading block header");
}
print_rhdr (&r_hdr);
// read ethernet header
CHECK_POSITION (LINK_LAYER_LEN);
fseek (srcfile, index, SEEK_SET);
// read IP header
CHECK_POSITION (sizihdr);
if(!fread (&ip_hdr, sizihdr, 1, srcfile)){
PERR ("reading ip header");
}
print_iphdr (&ip_hdr);
// read UDP header
CHECK_POSITION (sizuhdr);
if(!fread (&u_hdr, sizuhdr, 1, srcfile)){
PERR ("reading upd header");
}
print_udphdr (&u_hdr);
// read contained data
CHECK_POSITION (r_hdr.orig_len - sizrhdr
- LINK_LAYER_LEN - sizihdr - sizuhdr
);
fseek (srcfile, index, SEEK_SET);
}
// clean up
puts ("Done!");
CLEAN_UP;
return 0;
}
So, can I read the .pcap file with BigEndian?
是的。
How?
- 使用 libpcap/WinPcap,而不是编写自己的代码来阅读它,因为 libpcap/WinPcap 会为您处理 byte-order 问题;
- 查看幻数以确定文件的字节顺序是否与读取它的主机的字节顺序相同或相反,如果字节顺序相反,byte-swap 16 位和 32 位整数。
请注意,数据包 数据(某些元数据 headers 除外)按照其在网络上出现的字节顺序排列,不是主机写入数据的字节顺序。例如IP和TCP中的16位和32位整数值headers都是alwaysbig-endian,以太网类型字段也是
]