gpt4 book ai didi

c - 如何从头开始编写 pcap 文件,decorticating libpcap 函数?

转载 作者:太空宇宙 更新时间:2023-11-04 05:53:24 24 4
gpt4 key购买 nike

我有这段代码可以很好地使用 libpcap 编写 pcap 文件(仅使用用于测试的以太网协议(protocol)):

struct ethernet {
u_char mac1[6];
u_char mac2[6];
u_short protocol;
};

int main() {
pcap_t *pd;
pcap_dumper_t *pdumper;

pd = pcap_open_dead(DLT_EN10MB, 65535);
pdumper = pcap_dump_open(pd, "test.pcap");

struct pcap_pkthdr packet_header;
struct timeval ts;

packet_header.ts = ts;
packet_header.caplen = sizeof(struct ethernet);
packet_header.len = sizeof(struct ethernet);

struct ethernet ethernet;

bzero(ethernet.mac1, 6);
bzero(ethernet.mac2, 6);
ethernet.protocol = 8977; // randomly choose
pcap_dump((u_char*)pdumper, &packet_header, (const u_char*)&ethernet);
pcap_close(pd);
pcap_dump_close(pdumper);
return 0;
}

但是我想尽量不用pcap函数,所以我开始decorticate上面用到的函数。

以下是我找到的资源:

pcap_open_dead 函数:http://www.wand.net.nz/trac/libtrace/browser/lib/pcap_open_dead.c?rev=808a478a2459f3cf0e8bf927fcaad371138efb20

pcap_dump_open、pcap_dump 和其他:http://www.opensource.apple.com/source/libpcap/libpcap-2.1/libpcap/savefile.c

所以,这是我的想法:

pcap_open_dead 函数有点无用,只是实例化一个 pcap_t 结构(我不想在我的代码中使用它)并用参数填充它的值。

pcap_dump_open 返回一个 pcap_dumper_t(看起来就像一个 FILE*),只是打开文件并在其中写入文件头(如果我们不关心错误处理)。顺便说一句,它似乎将“p->tzoff”作为参数传递给 sf_write_header,它尚未在我的代码中初始化(但它仍在工作)。关于链接类型,在我们的例子中它正好等于 1。

最后,pcap_dump 函数将 pcap_dumper_t 变量作为第一个参数,隐式转换为 u_char*,然后显式转换为 FILE*(为什么不从一开始就使用 FILE*?)然后用fwrite把一个包头和一个包数据写入文件。

这就是我所做的:

FILE *fd = fopen("test.pcap", "w");

struct pcap_file_header header;

header.magic = 0xa1b2c3d4;
header.version_major = 2;
header.version_minor = 4;
header.thiszone = 0;
header.sigfigs = 0;
header.snaplen = 65535;
header.linktype = DLT_EN10MB;

struct pcap_pkthdr packet_header;
struct timeval ts;

packet_header.ts = ts;
packet_header.caplen = sizeof(struct ethernet);
packet_header.len = sizeof(struct ethernet);

struct ethernet ethernet;

bzero(ethernet.mac1, 6);
bzero(ethernet.mac2, 6);
ethernet.protocol = 8977;

fwrite((char*)&header, sizeof(header), 1, fd);
fwrite((char*)&packet_header, sizeof(struct pcap_pkthdr), 1, fd);
fwrite((char*)&ethernet, sizeof(struct ethernet), 1, fd);
close(fd);

不需要使用pcap_t结构,我直接把snaplen和linktype值放在pcap_file_header结构中。

然后我像在 pcap 函数中一样使用 fwrite。

头文件很好,只要在文件中写入头文件就可以用wireshark打开文件。但是当我添加 2 最后一个 fwrite(写入数据包 header 和数据包)时,wireshark 告诉我:

The capture file appears to be damaged or corrupt.
(pcap: File has 4195245-byte packet, bigger than maximum of 65535)

我找不到我的错误在哪里,我不知道他在哪里看到那么多字节。

编辑

我没有使用未初始化的时间间隔,而是:

packet_header.ts = (struct timeval){0};

现在可以正常工作了,但是您如何解释它在使用 pcap 函数时可以正常工作? “ts”仍未初始化。

这个时间间隔是什么意思?将其设置为零是否有意义?

编辑:将魔数(Magic Number)更正为 0xa1b2c3d4

最佳答案

struct pcap_pkthdr packet_header;

这是提供给程序的包头格式。它不一定是存储在文件中的数据包 header 的格式;它包含一个 struct timeval ,其大小取决于是否 time_t是 32 位还是 64 位。

你需要的是:

struct pcap_timeval {
bpf_int32 tv_sec; /* seconds */
bpf_int32 tv_usec; /* microseconds */
};
struct pcap_sf_pkthdr {
struct pcap_timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */

};

并使用struct pcap_sf_pkthdr反而。写作 struct pcap_pkthdr文件的结构将在任何系统上产生无效的 pcap 文件 tv_sectv_usec领域struct timeval不是 32 位;在任何 64 位系统上可能都是这种情况。在这种情况下,您很可能会遇到类似“已损坏或已损坏”的错误。

至于时间戳的含义,在实际捕获中,它表示数据包被捕获代码路径的任何部分看到时间戳的时间,这是对时间的近似值数据包到达捕获它的机器。这是一个 UN*X 时间戳,所以 tv_sec是自 1970 年 1 月 1 日 00:00:00 UTC 以来的秒数,tv_usec是从那一秒开始的微秒计数。

关于c - 如何从头开始编写 pcap 文件,decorticating libpcap 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33522705/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com