title: How to write pcap file from scratch, decorticating libpcap functions?
body: <p>I've got this code which is working fine to write a pcap file (with just the Ethernet protocol for the test) with libpcap:</p>
  <pre><code>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, &quot;test.pcap&quot;);
    
    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, &amp;packet_header, (const u_char*)&amp;ethernet);
    pcap_close(pd);
    pcap_dump_close(pdumper);
    return 0;
  }
  </code></pre>
  <p>But I wanted to try not using the pcap functions, so I started decorticating the functions used above.</p>
  <p>Here are the sources I found:</p>
  <p>pcap_open_dead function: <a href="http://www.wand.net.nz/trac/libtrace/browser/lib/pcap_open_dead.c?rev=808a478a2459f3cf0e8bf927fcaad371138efb20" rel="nofollow noreferrer">http://www.wand.net.nz/trac/libtrace/browser/lib/pcap_open_dead.c?rev=808a478a2459f3cf0e8bf927fcaad371138efb20</a></p>
  <p>pcap_dump_open, pcap_dump and others: <a href="http://www.opensource.apple.com/source/libpcap/libpcap-2.1/libpcap/savefile.c" rel="nofollow noreferrer">http://www.opensource.apple.com/source/libpcap/libpcap-2.1/libpcap/savefile.c</a></p>
  <p>So, here is my thought:</p>
  <p>The pcap_open_dead function is kind of useless, just instanciating a pcap_t struct (which I don't want to use in my code) and filling its values with the parameters.</p>
  <p>The pcap_dump_open, returning a pcap_dumper_t (which seems to be just like a FILE*), is just opening the file and writing the header in it (if we don't care about the errors handling). By the way, seems like its giving &quot;p-&gt;tzoff&quot; as parameter to sf_write_header, which has not been initialized in my code (and it's still working).
  About the linktype, in our case it's just equal to 1.</p>
  <p>Finally, the pcap_dump function take the pcap_dumper_t variable as first parameter, which is implicitly cast to u_char* then explicitly cast to FILE* (why not use a FILE* from the beginning?)
  Then it take a packet header and a packet data to write them into the file with fwrite.</p>
  <p>So here is what I did:</p>
  <pre><code>FILE *fd = fopen(&quot;test.pcap&quot;, &quot;w&quot;);
  
  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*)&amp;header, sizeof(header), 1, fd);
  fwrite((char*)&amp;packet_header, sizeof(struct pcap_pkthdr), 1, fd);
  fwrite((char*)&amp;ethernet, sizeof(struct ethernet), 1, fd);
  close(fd);
  </code></pre>
  <p>No need to use a pcap_t structure, I put the snaplen and linktype values directly in the pcap_file_header structure.</p>
  <p>And then I use fwrite the same way they do in the pcap functions.</p>
  <p>The header file is good, i'm able to open the file with wireshark if I just write the header in the file.
  But when I add the 2 last fwrite (to write the packet header and the packet), wireshark tells me:</p>
  <pre><code>The capture file appears to be damaged or corrupt.
  (pcap: File has 4195245-byte packet, bigger than maximum of 65535)
  </code></pre>
  <p>I can't find where is my mistake, and I don't know where he's seeing that much bytes.</p>
  <p>EDIT</p>
  <p>Instead of using an uninitialized timeval, I did :</p>
  <pre><code>packet_header.ts = (struct timeval){0};
  </code></pre>
  <p>And now that's working, but how do you explain it was working when using the pcap functions? &quot;ts&quot; was still uninitialized.</p>
  <p>And what's the meaning of this timeval? Does it make sense to set it to zero?</p>
  <p>EDIT:
  corrected magic number to 0xa1b2c3d4</p>