static void
write_pcap_ng_shb(HANDLE_OR_FILEPTR file)
{
  PCap_NG_shb shb;
  u32 btl;
  PCap_NG_option userappl = {4, 0};        // 4 = user application name
  PCap_NG_option end_of_options = {0, 0};
  userappl.length = strlen(hw_description);

  btl = sizeof(PCap_NG_shb)
    + sizeof(userappl) + round_up_32_bit(userappl.length)
    + sizeof(end_of_options)
    + sizeof(shb.block_total_length);

  shb.type                  = 0x0A0D0D0A;
  shb.block_total_length    = btl;
  shb.byte_order_magic      = 0x1A2B3C4D;
  shb.major_version         = 1;
  shb.minor_version         = 0;
  shb.section_length        = 0xffffffffFFFFFFFFULL; // "unknown"

  checked_fwrite((void*)&shb, sizeof shb, file);
  checked_fwrite((void*)&userappl, sizeof userappl, file);
  checked_fwrite((void*)hw_description, round_up_32_bit(userappl.length), file);
  checked_fwrite((void*)&end_of_options, sizeof end_of_options, file);
  checked_fwrite((void*)&btl, sizeof(btl), file);

  return;
}
// Having both if_description and if_name causes Wireshark 1.10.3 to
// display only if_description. So we only have if_name.
static void
write_pcap_idbs(HANDLE_OR_FILEPTR file, Channel_t *c, int n)
{
	int x;
	PCap_NG_option end_of_options = { 0, 0 };

	for (x = 0; x < n; x++) {
		PCap_NG_idb idb;
		PCap_NG_option if_name;
		char idb_if_name[MAX_IF_NAME];
		PCap_NG_option if_tsresol;
		/*
		TIMESTAMP PRECISION NOTICE:
		Precision is set to MILLIseconds (10^-3 seconds)
		*/
		char tsresol[4] = { 3, 0, 0, 0 }; // 10^-3 resolution, three padding bytes

		u32 block_total_length;

		if_name.code = 2;    // if_name
		if_name.length = snprintf(idb_if_name, MAX_IF_NAME, "%s:%d",
			c[x].span, c[x].timeslots[0]);
		if (if_name.length < 0 || if_name.length >= MAX_IF_NAME)
			die("interface name is too long");

		block_total_length = sizeof(idb)
			+ sizeof(PCap_NG_option) + round_up_32_bit(if_name.length)
			+ sizeof(PCap_NG_option) + sizeof(tsresol)
			+ sizeof(PCap_NG_option)
			+ sizeof(block_total_length);

		idb.type = 1;
		idb.block_total_length = block_total_length;
		idb.link_type = LINK_TYPE_MTP2;
		idb.reserved = 0;
		idb.snaplen = 279;

		if_tsresol.code = 9; // tsresol
		if_tsresol.length = 1;

		checked_fwrite((void*)&idb, sizeof(idb), file);

		checked_fwrite((void*)&if_name, sizeof(if_name), file);
		checked_fwrite((void*)&idb_if_name, round_up_32_bit(if_name.length), file);

		checked_fwrite((void*)&if_tsresol, sizeof(if_tsresol), file);
		checked_fwrite((void*)&tsresol, sizeof(tsresol), file);

		checked_fwrite((void*)&end_of_options, sizeof(end_of_options), file);

		checked_fwrite((void*)&block_total_length, sizeof block_total_length, file);
	}
}
static inline void
write_packet(HANDLE_OR_FILEPTR file,
	     u32 timestamp_hi,
	     u32 timestamp_lo,
	     u16 tag,
	     void *payload,
	     int length,
	     int format)
{
  u32 total_length;

  switch (format) {
  case PCAP_CLASSIC:
    write_classic_packet_header(file, timestamp_hi, timestamp_lo, length);
    checked_fwrite(payload, length, file);
    break;

  case PCAP_NG:
    total_length = write_ng_packet_header(file, timestamp_hi,
					  timestamp_lo, tag, length);
    checked_fwrite(payload, round_up_32_bit(length), file);
    checked_fwrite(&total_length, sizeof total_length, file);
    break;

  default:
    die("internal error");
  }
}
static u32
write_ng_packet_header(HANDLE_OR_FILEPTR file,
		       u32 timestamp_hi,
		       u32 timestamp_lo,
		       u16 tag,
		       int length)
{
  PCap_NG_epb epb;

  epb.type = 6;
  epb.block_total_length = sizeof(epb)
    + round_up_32_bit(length)
    + sizeof(epb.block_total_length);
  epb.interface_id = tag;
  epb.timestamp_hi = timestamp_hi;
  epb.timestamp_lo = timestamp_lo;
  epb.captured_len = length;
  epb.packet_len = length;

  checked_fwrite(&epb, sizeof epb, file);

  return epb.block_total_length;
}