代码中出现一些错误 - libpcap
我正在尝试用 C 解析 pcap 文件。我不想使用 libpcap。但由于某种原因,我无法这样做。你知道我该怎么做吗?这是我的尝试:
fseek(f,24,0);
while(count<20)//reading 20 packets
{
fread(header,sizeof(struct pcap_pkthdr),1,f);
//after this I'm printing values header fields
fseek(f,ntohl(header->caplen),1);
count++;
}
输出与 libpcap 不同。
I'm trying to parse a pcap file in C. I don't want to use libpcap. But for some reason, I'm unable to. Do you know how can I do this ? Here is my attempt :
fseek(f,24,0);
while(count<20)//reading 20 packets
{
fread(header,sizeof(struct pcap_pkthdr),1,f);
//after this I'm printing values header fields
fseek(f,ntohl(header->caplen),1);
count++;
}
Output is not the same as libpcap.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
struct pcap_pkthdr
不是定义 pcap 文件中数据包标头格式的结构;它是定义提供给使用 libpcap 或 WinPcap 的程序的数据包标头格式的结构。在 pcap 文件中定义数据包标头格式的结构不出现在任何 pcap 包含文件中,因为 libpcap/WinPcap 提供了读取这些标头并根据需要将其转换为 pcap_pkthdr 的例程。 标头。与 struct pcap_pkthdr 不同,pcap 文件中的数据包标头中的时间戳始终具有 32 位“秒”字段和 32 位“微秒”字段,即使在
time_t< 的系统上也是如此。 /code> 和
struct timeval
中的tv_sec
值是 64 位。即,该结构由以下方式定义
,其中 struct pcap_sf_pkthdr 是文件中的结构。
另请注意,如果您从文件中读取
struct pcap_sf_pkthdr
,则必须进行字节交换ts.tv_sec
、ts.tv_usec
、caplen
和len
IF 文件写入的计算机的字节顺序与您读取文件的计算机的字节顺序不同。像ntohl()
这样简单的东西将无法工作 - 例如,如果您的文件是在与您正在读取它的同一台机器上写入的,则没有字节- 交换是必要的。实现该功能的唯一方法是读取文件头,而不是仅仅使用 fseek() 跳过它。如果文件头中的“幻数”值为
0xa1b2c3d4
,那么您不需要进行任何字节交换;如果它的值为0xd4c3b2a1
,则需要对文件头和struct pcap_sf_pkthdr
中的值进行字节交换。请注意,如果您在 PowerPC 等大端机器上运行,则ntohl()
和htonl()
将不会进行字节交换/Power Architecture 机器或 MIPS 机器或 IBM 大型机或......另请注意,并非所有捕获文件都将是 pcap 文件;如果它们是 pcap-NG 文件,则必须以完全不同的方式读取它们。 Libpcap 1.1 及更高版本知道如何读取 pcap-NG 文件(libpcap/WinPcap API 的功能不足以处理所有 pcap-NG 文件,但它可以处理 pcap-NG 文件等只有一个部分,并且只有来自一个网络适配器的数据包,libpcap 1.1 及更高版本可以读取这些数据包)。正如 unwind 建议的那样,我建议您使用 libpcap/WinPcap 来读取捕获文件,而不是编写自己的代码来执行此操作。
struct pcap_pkthdr
is NOT the structure that defines the format of packet headers in a pcap file; it's the structure that defines the format of packet headers as provided to programs using libpcap or WinPcap.The structure that defines the format of packet headers in a pcap file is NOT in any of the pcap include files, because libpcap/WinPcap provides routines that read those headers and transforms them as necessary to
pcap_pkthdr
headers. Unlikestruct pcap_pkthdr
, the time stamp in packet headers in a pcap file always have a 32-bit "seconds" field and a 32-bit "microseconds" field, even on systems wheretime_t
and thetv_sec
value in astruct timeval
are 64 bits.I.e., the structure is defined by
where
struct pcap_sf_pkthdr
is the structure in the file.Note also that, if you read a
struct pcap_sf_pkthdr
from a file, you will have to byte-swapts.tv_sec
,ts.tv_usec
,caplen
, andlen
IF the file was written on a machine whose byte order differs from the machine on which you're reading the file. Something as simple asntohl()
will NOT work - if, for example, your file was written on the same machine as the one on which you are reading it, no byte-swapping is necessary.The ONLY way to make that work would be to READ the file header, rather than just skipping over it with
fseek()
. If the "magic number" in the file header has the value0xa1b2c3d4
, then you do not need to do any byte swapping; if it has the value0xd4c3b2a1
, you will need to byte-swap the values in the file header and thestruct pcap_sf_pkthdr
. Note thatntohl()
andhtonl()
will NOT byte-swap if you're running on a big-endian machine such as a PowerPC/Power Architecture machine or a MIPS machine or an IBM mainframe or....Note also that not all capture files are going to be pcap files; if they're pcap-NG files, they have to be read in a completely different fashion. Libpcap 1.1 and later know how to read pcap-NG files (the libpcap/WinPcap API isn't powerful enough to handle all pcap-NG files, but it can, for example, handle pcap-NG files that only have one section and only have packets from one network adapter, and libpcap 1.1 and later can read those). I would suggest, just as unwind suggested, that you use libpcap/WinPcap to read capture files, rather than writing your own code to do it.
确保您正确处理 pcap 文件格式的字节顺序。
此外,直接从磁盘加载整个结构很少是安全的,因为编译器可以随意在结构字段之间插入填充,这将使磁盘中的字节与内存中的字节不匹配。
我建议你使用官方库,因为这样这些问题就已经得到解决了。
Make sure that you are correctly handling the endianness of the pcap file format.
Also, directly loading entire structures from disk is rarely safe, since compilers are free to insert padding between structure fields, which will make the bytes from disk not match the bytes in memory.
I would suggest you use the official library, since then those problems will already have been taken care of.
尝试这样的事情:
Try something like that: