I am trying to write a .pcap file, which is something that can be used in Wireshark. In order to do that, I have a couple of structs with various data types I need to write
Here's my understanding of what Guy Harris is suggesting. So, as per Kyslik's request, we have:
#include <libpcap/pcap.h>
/* Ethernet/IP/SCTP INIT chunk */
static const unsigned char pkt1[82] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00, /* ......E. */
0x00, 0x44, 0x55, 0xb1, 0x00, 0x00, 0x40, 0x84, /* .DU...@. */
0x26, 0x83, 0x7f, 0x00, 0x00, 0x01, 0x7f, 0x00, /* &....... */
0x00, 0x01, 0x00, 0x01, 0x1f, 0x90, 0x00, 0x00, /* ........ */
0x00, 0x00, 0x68, 0xe5, 0x88, 0x1b, 0x01, 0x00, /* ..h..... */
0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, /* .$...... */
0xa0, 0x00, 0x00, 0x04, 0xff, 0xff, 0x00, 0x00, /* ........ */
0x16, 0x2e, 0x80, 0x00, 0x00, 0x04, 0xc0, 0x00, /* ........ */
0x00, 0x04, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x05, /* ........ */
0x00, 0x00 /* .. */
};
int main(int argc, char *argv[]) {
pcap_t *handle = pcap_open_dead(DLT_EN10MB, 1 << 16);
pcap_dumper_t *dumper = pcap_dump_open(handle, "/tmp/pktcap/cap.pcap");
struct pcap_pkthdr pcap_hdr;
pcap_hdr.caplen = sizeof(pkt1);
pcap_hdr.len = pcap_hdr.caplen;
pcap_dump((u_char *)dumper, &pcap_hdr, pkt1);
pcap_dump_close(dumper);
return 0;
}
Use libpcap or WinPcap - pcap_open_dead()
to get a "fake" pcap_t
to use with pcap_dump_open()
to specify the link-layer header type (for Ethernet, use DLT_EN10MB
) and snapshot length (use 65535), pcap_dump_open()
to open the file for writing, pcap_dump()
to write out a packet, and pcap_dump_close()
to close the file. MUCH easier than directly using fopen()
, fwrite()
, and fclose()
(which are what libpcap/WinPcap use "under the hood").
And, yes, you have to get the byte order in the packets correct. The byte order depends on the protocol; for the type
field in the Ethernet header, and for all multi-byte fields in IP, TCP, and UDP headers, they have to be in big-endian order. (The magic number in the pcap file is irrelevant to this - it only indicates the byte order of the fields in the file header and the per-packet record header, NOT the byte order of the fields in the packet, as well as, due to the way it's implemented in Linux, the meta-data at the beginning of packets in Linux USB captures. The packet data is supposed to look exactly as it would "on the wire".)
Use fwrite(). You need to check this info but I think .pcap files are written in binary mode.
Example:
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);