C - 将结构写入文件(.pcap)

Kai*_*aan 10 c io fopen struct pcap

我正在尝试编写.pcap文件,这可以在Wireshark中使用.为了做到这一点,我有几个结构,我需要写入文件的各种数据类型.(见代码)

所以,我创建结构实例,填写数据,使用FILE*fp = fopen("test.pcap","w"),然后我不确定如何正确地将它写入文件.我相信我应该使用memcpy,但我不确定最好的方法.我过去主要使用C++库来执行此操作.有什么建议?

typedef struct pcap_hdr_s {
        uint32_t magic_number;   /* magic number */
        uint16_t version_major;  /* major version number */
        uint16_t version_minor;  /* minor version number */
        int32_t  thiszone;       /* GMT to local correction */
        uint32_t sigfigs;        /* accuracy of timestamps */
        uint32_t snaplen;        /* max length of captured packets, in octets */
        uint32_t network;        /* data link type */
} pcap_hdr_t;

typedef struct pcaprec_hdr_s {
   uint32_t ts_sec;         /* timestamp seconds */
   uint32_t ts_usec;        /* timestamp microseconds */
   uint32_t incl_len;       /* number of octets of packet saved in file */
   uint32_t orig_len;       /* actual length of packet */
} pcaprec_hdr_t;

typedef struct ethernet_hdr_s {
   uint8_t dst[6];    /* destination host address */
   uint8_t src[6];    /* source host address */
   uint16_t type;     /* IP? ARP? RARP? etc */
} ethernet_hdr_t;

typedef struct ip_hdr_s {
   uint8_t  ip_hl:4, /* both fields are 4 bits */
            ip_v:4;
   uint8_t        ip_tos;
   uint16_t       ip_len;
   uint16_t       ip_id;
   uint16_t       ip_off;
   uint8_t        ip_ttl;
   uint8_t        ip_p;
   uint16_t       ip_sum;
   uint32_t ip_src;
   uint32_t ip_dst;
}ip_hdr_t;

typedef struct udp_header
{
  uint16_t src;
  uint16_t dst;
  uint16_t length;
  uint16_t checksum;
} udp_header_t;
Run Code Online (Sandbox Code Playgroud)

小智 16

使用libpcap或WinPcap - pcap_open_dead()得到一个"假" pcap_t用于pcap_dump_open()指定链路层头类型(用于以太网,使用DLT_EN10MB)和快照长度(使用65535),pcap_dump_open()打开文件进行写入,pcap_dump()写出数据包,以及pcap_dump_close()关闭文件. MUCH比直接更容易使用fopen(),fwrite()以及fclose()(这是什么的libpcap/WinPcap的使用"引擎盖下").

并且,是的,您必须使数据包中的字节顺序正确.字节顺序取决于协议; 对于type以太网报头中的字段,以及IP,TCP和UDP报头中的所有多字节字段,它们必须采用大端顺序.(pcap文件中的幻数与此无关 - 它仅指示文件头和每个数据包记录头中字段的字节顺序,而不是数据包中字段的字节顺序,以及到期对于它在Linux中实现的方式,Linux USB中数据包开始时的元数据捕获.分组数据应该看起来与"在线上"完全一样.)


kar*_*lip 4

使用fwrite()。您需要检查此信息,但我认为.pcap文件是以二进制模式编写的。

例子:

pcaprec_hdr_t pcaprec_hdr;
// fill pcaprec_hdr with valid info

FILE* pFile = NULL;
pFile = fopen ("myfile.pcap" , "wb"); // open for writing in binary mode

fwrite (&pcaprec_hdr, 1, sizeof(pcaprec_hdr_t) , pFile);

fclose(pFile);
Run Code Online (Sandbox Code Playgroud)

  • “你认为他们已经知道了。但是他们知道吗?” 是的,他们确实这么做了。它们是该文件格式的第一个实现。 (2认同)