aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2016-03-04 08:52:48 -0500
committerMichael Mann <mmann78@netscape.net>2016-03-06 12:53:36 +0000
commitf2de3c7778c8712ddeef877055db4cba82a9b40a (patch)
treed255ae50f4120d28efae497c5aeac0657e3af290
parent32d60ac2f55f38f2d29a57fea8be008432846367 (diff)
Improve wiretap block capabilities.
Make a more formal method for registering options within a block and do it all with a single function (wtap_optionblock_add_block). Add ability for block to be able to write itself, refactored out of pcapng.c. This was implemented for SHB, ISB, and IDB blocks. Name resolution (NRB), while possible, seemed a little messy for the moment. Change-Id: Ie855c8550c7c7d96cfc188c0cd90bfbc4d5f0ee8 Reviewed-on: https://code.wireshark.org/review/14357 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
-rw-r--r--wiretap/pcapng.c815
-rw-r--r--wiretap/pcapng.h44
-rw-r--r--wiretap/wtap_opttypes.c781
-rw-r--r--wiretap/wtap_opttypes.h149
4 files changed, 725 insertions, 1064 deletions
diff --git a/wiretap/pcapng.c b/wiretap/pcapng.c
index 0d070c6b12..8729177b0b 100644
--- a/wiretap/pcapng.c
+++ b/wiretap/pcapng.c
@@ -56,15 +56,6 @@ pcapng_seek_read(wtap *wth, gint64 seek_off,
static void
pcapng_close(wtap *wth);
-
-/* pcapng: common block header file encoding for every block type */
-typedef struct pcapng_block_header_s {
- guint32 block_type;
- guint32 block_total_length;
- /* x bytes block_body */
- /* guint32 block_total_length */
-} pcapng_block_header_t;
-
/*
* Minimum block size = size of block header + size of block trailer.
*/
@@ -82,34 +73,11 @@ typedef struct pcapng_block_header_s {
*/
#define MAX_BLOCK_SIZE (16*1024*1024)
-/* pcapng: section header block file encoding */
-typedef struct pcapng_section_header_block_s {
- /* pcapng_block_header_t */
- guint32 magic;
- guint16 version_major;
- guint16 version_minor;
- guint64 section_length; /* might be -1 for unknown */
- /* ... Options ... */
-} pcapng_section_header_block_t;
-
/*
* Minimum SHB size = minimum block size + size of fixed length portion of SHB.
*/
#define MIN_SHB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_section_header_block_t)))
-/* pcapng: interface description block file encoding */
-typedef struct pcapng_interface_description_block_s {
- guint16 linktype;
- guint16 reserved;
- guint32 snaplen;
- /* ... Options ... */
-} pcapng_interface_description_block_t;
-
-/*
- * Minimum IDB size = minimum block size + size of fixed length portion of IDB.
- */
-#define MIN_IDB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_interface_description_block_t)))
-
/* pcapng: packet block file encoding (obsolete) */
typedef struct pcapng_packet_block_s {
guint16 interface_id;
@@ -170,14 +138,6 @@ typedef struct pcapng_name_resolution_block_s {
*/
#define MIN_NRB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_name_resolution_block_t)))
-/* pcapng: interface statistics block file encoding */
-typedef struct pcapng_interface_statistics_block_s {
- guint32 interface_id;
- guint32 timestamp_high;
- guint32 timestamp_low;
- /* ... Options ... */
-} pcapng_interface_statistics_block_t;
-
/*
* Minimum ISB size = minimum block size + size of fixed length portion of ISB.
*/
@@ -2739,85 +2699,25 @@ pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
{
pcapng_block_header_t bh;
pcapng_section_header_block_t shb;
- const guint32 zero_pad = 0;
- gboolean have_options = FALSE;
- struct option option_hdr; /* guint16 type, guint16 value_length; */
- guint32 options_total_length = 0;
- guint32 comment_len = 0, shb_hardware_len = 0, shb_os_len = 0, shb_user_appl_len = 0;
- guint32 comment_pad_len = 0, shb_hardware_pad_len = 0, shb_os_pad_len = 0, shb_user_appl_pad_len = 0;
- char *opt_comment, *shb_hardware, *shb_os, *shb_user_appl;
if (wdh->shb_hdr) {
pcapng_debug("pcapng_write_section_header_block: Have shb_hdr");
- /* Check if we should write comment option */
- wtap_optionblock_get_option_string(wdh->shb_hdr, OPT_COMMENT, &opt_comment);
- if (opt_comment) {
- have_options = TRUE;
- comment_len = (guint32)strlen(opt_comment) & 0xffff;
- if ((comment_len % 4)) {
- comment_pad_len = 4 - (comment_len % 4);
- } else {
- comment_pad_len = 0;
- }
- options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
- }
-
- /* Check if we should write shb_hardware option */
- wtap_optionblock_get_option_string(wdh->shb_hdr, OPT_SHB_HARDWARE, &shb_hardware);
- if (shb_hardware) {
- have_options = TRUE;
- shb_hardware_len = (guint32)strlen(shb_hardware) & 0xffff;
- if ((shb_hardware_len % 4)) {
- shb_hardware_pad_len = 4 - (shb_hardware_len % 4);
- } else {
- shb_hardware_pad_len = 0;
- }
- options_total_length = options_total_length + shb_hardware_len + shb_hardware_pad_len + 4 /* options tag */ ;
- }
- /* Check if we should write shb_os option */
- wtap_optionblock_get_option_string(wdh->shb_hdr, OPT_SHB_OS, &shb_os);
- if (shb_os) {
- have_options = TRUE;
- shb_os_len = (guint32)strlen(shb_os) & 0xffff;
- if ((shb_os_len % 4)) {
- shb_os_pad_len = 4 - (shb_os_len % 4);
- } else {
- shb_os_pad_len = 0;
- }
- options_total_length = options_total_length + shb_os_len + shb_os_pad_len + 4 /* options tag */ ;
- }
-
- /* Check if we should write shb_user_appl option */
- wtap_optionblock_get_option_string(wdh->shb_hdr, OPT_SHB_USERAPPL, &shb_user_appl);
- if (shb_user_appl) {
- have_options = TRUE;
- shb_user_appl_len = (guint32)strlen(shb_user_appl) & 0xffff;
- if ((shb_user_appl_len % 4)) {
- shb_user_appl_pad_len = 4 - (shb_user_appl_len % 4);
- } else {
- shb_user_appl_pad_len = 0;
- }
- options_total_length = options_total_length + shb_user_appl_len + shb_user_appl_pad_len + 4 /* options tag */ ;
- }
-
- if (have_options) {
- /* End-of-options tag */
- options_total_length += 4;
- }
+ return wtap_optionblock_write(wdh, wdh->shb_hdr, err);
}
+ /* we don't have a section block header already, so create a default one with no options */
+
/* write block header */
bh.block_type = BLOCK_TYPE_SHB;
- bh.block_total_length = (guint32)(sizeof(bh) + sizeof(shb) + options_total_length + 4);
- pcapng_debug("pcapng_write_section_header_block: Total len %u, Options total len %u",bh.block_total_length, options_total_length);
+ bh.block_total_length = (guint32)(sizeof(bh) + sizeof(shb) + 4);
+ pcapng_debug("pcapng_write_section_header_block: Total len %u", bh.block_total_length);
if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
return FALSE;
wdh->bytes_dumped += sizeof bh;
/* write block fixed content */
- /* XXX - get these values from wblock? */
shb.magic = 0x1A2B3C4D;
shb.version_major = 1;
shb.version_minor = 0;
@@ -2827,106 +2727,6 @@ pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
return FALSE;
wdh->bytes_dumped += sizeof shb;
- /* XXX - write (optional) block options
- * opt_comment 1
- * shb_hardware 2
- * shb_os 3
- * shb_user_appl 4
- */
-
- if (comment_len) {
- option_hdr.type = OPT_COMMENT;
- option_hdr.value_length = comment_len;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write the comments string */
- pcapng_debug("pcapng_write_section_header_block, comment:'%s' comment_len %u comment_pad_len %u" , opt_comment, comment_len, comment_pad_len);
- if (!wtap_dump_file_write(wdh, opt_comment, comment_len, err))
- return FALSE;
- wdh->bytes_dumped += comment_len;
-
- /* write padding (if any) */
- if (comment_pad_len != 0) {
- if (!wtap_dump_file_write(wdh, &zero_pad, comment_pad_len, err))
- return FALSE;
- wdh->bytes_dumped += comment_pad_len;
- }
- }
-
- if (shb_hardware_len) {
- option_hdr.type = OPT_SHB_HARDWARE;
- option_hdr.value_length = shb_hardware_len;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write the string */
- pcapng_debug("pcapng_write_section_header_block, shb_hardware:'%s' shb_hardware_len %u shb_hardware_pad_len %u" , shb_hardware, shb_hardware_len, shb_hardware_pad_len);
- if (!wtap_dump_file_write(wdh, shb_hardware, shb_hardware_len, err))
- return FALSE;
- wdh->bytes_dumped += shb_hardware_len;
-
- /* write padding (if any) */
- if (shb_hardware_pad_len != 0) {
- if (!wtap_dump_file_write(wdh, &zero_pad, shb_hardware_pad_len, err))
- return FALSE;
- wdh->bytes_dumped += shb_hardware_pad_len;
- }
- }
-
- if (shb_os_len) {
- option_hdr.type = OPT_SHB_OS;
- option_hdr.value_length = shb_os_len;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write the string */
- pcapng_debug("pcapng_write_section_header_block, shb_os:'%s' shb_os_len %u shb_os_pad_len %u" , shb_os, shb_os_len, shb_os_pad_len);
- if (!wtap_dump_file_write(wdh, shb_os, shb_os_len, err))
- return FALSE;
- wdh->bytes_dumped += shb_os_len;
-
- /* write padding (if any) */
- if (shb_os_pad_len != 0) {
- if (!wtap_dump_file_write(wdh, &zero_pad, shb_os_pad_len, err))
- return FALSE;
- wdh->bytes_dumped += shb_os_pad_len;
- }
- }
-
- if (shb_user_appl_len) {
- option_hdr.type = OPT_SHB_USERAPPL;
- option_hdr.value_length = shb_user_appl_len;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write the comments string */
- pcapng_debug("pcapng_write_section_header_block, shb_user_appl:'%s' shb_user_appl_len %u shb_user_appl_pad_len %u" , shb_user_appl, shb_user_appl_len, shb_user_appl_pad_len);
- if (!wtap_dump_file_write(wdh, shb_user_appl, shb_user_appl_len, err))
- return FALSE;
- wdh->bytes_dumped += shb_user_appl_len;
-
- /* write padding (if any) */
- if (shb_user_appl_pad_len != 0) {
- if (!wtap_dump_file_write(wdh, &zero_pad, shb_user_appl_pad_len, err))
- return FALSE;
- wdh->bytes_dumped += shb_user_appl_pad_len;
- }
- }
-
- /* Write end of options if we have otions */
- if (have_options) {
- option_hdr.type = OPT_EOFOPT;
- option_hdr.value_length = 0;
- if (!wtap_dump_file_write(wdh, &zero_pad, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
- }
-
/* write block footer */
if (!wtap_dump_file_write(wdh, &bh.block_total_length,
sizeof bh.block_total_length, err))
@@ -2936,603 +2736,6 @@ pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
return TRUE;
}
-
-static gboolean
-pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_optionblock_t int_data, int *err)
-{
- pcapng_block_header_t bh;
- pcapng_interface_description_block_t idb;
- const guint32 zero_pad = 0;
- gboolean have_options = FALSE;
- struct option option_hdr; /* guint16 type, guint16 value_length; */
- guint32 options_total_length = 0;
- guint32 comment_len = 0, if_name_len = 0, if_description_len = 0 , if_os_len = 0, if_filter_str_len = 0;
- guint32 comment_pad_len = 0, if_name_pad_len = 0, if_description_pad_len = 0, if_os_pad_len = 0, if_filter_str_pad_len = 0;
- wtapng_if_descr_mandatory_t* int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data);
- char *opt_comment, *if_name, *if_description, *if_os;
- guint64 if_speed;
- guint8 if_tsresol, if_fcslen;
- wtapng_if_descr_filter_t* if_filter;
-
- pcapng_debug("pcapng_write_if_descr_block: encap = %d (%s), snaplen = %d",
- int_data_mand->link_type,
- wtap_encap_string(wtap_pcap_encap_to_wtap_encap(int_data_mand->link_type)),
- int_data_mand->snap_len);
-
- if (int_data_mand->link_type == (guint16)-1) {
- *err = WTAP_ERR_UNWRITABLE_ENCAP;
- return FALSE;
- }
-
- /* Calculate options length */
- wtap_optionblock_get_option_string(int_data, OPT_COMMENT, &opt_comment);
- if (opt_comment) {
- have_options = TRUE;
- comment_len = (guint32)strlen(opt_comment) & 0xffff;
- if ((comment_len % 4)) {
- comment_pad_len = 4 - (comment_len % 4);
- } else {
- comment_pad_len = 0;
- }
- options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
- }
-
- /*
- * if_name 2 A UTF-8 string containing the name of the device used to capture data.
- */
- wtap_optionblock_get_option_string(int_data, OPT_IDB_NAME, &if_name);
- if (if_name) {
- have_options = TRUE;
- if_name_len = (guint32)strlen(if_name) & 0xffff;
- if ((if_name_len % 4)) {
- if_name_pad_len = 4 - (if_name_len % 4);
- } else {
- if_name_pad_len = 0;
- }
- options_total_length = options_total_length + if_name_len + if_name_pad_len + 4 /* comment options tag */ ;
- }
-
- /*
- * if_description 3 A UTF-8 string containing the description of the device used to capture data.
- */
- wtap_optionblock_get_option_string(int_data, OPT_IDB_DESCR, &if_description);
- if (if_description) {
- have_options = TRUE;
- if_description_len = (guint32)strlen(if_description) & 0xffff;
- if ((if_description_len % 4)) {
- if_description_pad_len = 4 - (if_description_len % 4);
- } else {
- if_description_pad_len = 0;
- }
- options_total_length = options_total_length + if_description_len + if_description_pad_len + 4 /* comment options tag */ ;
- }
- /* Currently not handled
- * if_IPv4addr 4 Interface network address and netmask.
- * if_IPv6addr 5 Interface network address and prefix length (stored in the last byte).
- * if_MACaddr 6 Interface Hardware MAC address (48 bits). 00 01 02 03 04 05
- * if_EUIaddr 7 Interface Hardware EUI address (64 bits), if available. TODO: give a good example
- */
- /*
- * if_speed 8 Interface speed (in bps). 100000000 for 100Mbps
- */
- wtap_optionblock_get_option_uint64(int_data, OPT_IDB_SPEED, &if_speed);
- if (if_speed != 0) {
- have_options = TRUE;
- options_total_length = options_total_length + 8 + 4;
- }
- /*
- * if_tsresol 9 Resolution of timestamps.
- */
- wtap_optionblock_get_option_uint8(int_data, OPT_IDB_TSRESOL, &if_tsresol);
- if (if_tsresol != 0) {
- have_options = TRUE;
- options_total_length = options_total_length + 4 + 4;
- }
- /* Not used
- * if_tzone 10 Time zone for GMT support (TODO: specify better). TODO: give a good example
- */
- /*
- * if_filter 11 The filter (e.g. "capture only TCP traffic") used to capture traffic.
- * The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string, or BPF bytecode, and more).
- */
- wtap_optionblock_get_option_custom(int_data, OPT_IDB_FILTER, (void**)&if_filter);
- if (if_filter->if_filter_str) {
- have_options = TRUE;
- if_filter_str_len = (guint32)(strlen(if_filter->if_filter_str) + 1) & 0xffff;
- if ((if_filter_str_len % 4)) {
- if_filter_str_pad_len = 4 - (if_filter_str_len % 4);
- } else {
- if_filter_str_pad_len = 0;
- }
- options_total_length = options_total_length + if_filter_str_len + if_filter_str_pad_len + 4 /* comment options tag */ ;
- }
- /*
- * if_os 12 A UTF-8 string containing the name of the operating system of the machine in which this interface is installed.
- */
- wtap_optionblock_get_option_string(int_data, OPT_IDB_OS, &if_os);
- if (if_os) {
- have_options = TRUE;
- if_os_len = (guint32)strlen(if_os) & 0xffff;
- if ((if_os_len % 4)) {
- if_os_pad_len = 4 - (if_os_len % 4);
- } else {
- if_os_pad_len = 0;
- }
- options_total_length = options_total_length + if_os_len + if_os_pad_len + 4 /* comment options tag */ ;
- }
- /*
- * if_fcslen 13 An integer value that specified the length of the Frame Check Sequence (in bits) for this interface.
- * -1 if unknown or changes between packets, opt 13 An integer value that specified the length of the Frame Check Sequence (in bits) for this interface.
- */
- wtap_optionblock_get_option_uint8(int_data, OPT_IDB_FCSLEN, &if_fcslen);
- if (if_fcslen != 0) {
- }
- /* Not used
- * if_tsoffset 14 A 64 bits integer value that specifies an offset (in seconds) that must be added to the timestamp of each packet
- * to obtain the absolute timestamp of a packet. If the option is missing, the timestamps stored in the packet must be considered absolute timestamps.
- */
-
- if (have_options) {
- /* End-of-options tag */
- options_total_length += 4;
- }
-
- /* write block header */
- bh.block_type = BLOCK_TYPE_IDB;
- bh.block_total_length = (guint32)(sizeof(bh) + sizeof(idb) + options_total_length + 4);
-
- if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
- return FALSE;
- wdh->bytes_dumped += sizeof bh;
-
- /* write block fixed content */
- idb.linktype = int_data_mand->link_type;
- idb.reserved = 0;
- idb.snaplen = int_data_mand->snap_len;
-
- if (!wtap_dump_file_write(wdh, &idb, sizeof idb, err))
- return FALSE;
- wdh->bytes_dumped += sizeof idb;
-
- /* XXX - write (optional) block options */
- if (comment_len != 0) {
- option_hdr.type = OPT_COMMENT;
- option_hdr.value_length = comment_len;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write the comments string */
- pcapng_debug("pcapng_write_if_descr_block, comment:'%s' comment_len %u comment_pad_len %u" , opt_comment, comment_len, comment_pad_len);
- if (!wtap_dump_file_write(wdh, opt_comment, comment_len, err))
- return FALSE;
- wdh->bytes_dumped += comment_len;
-
- /* write padding (if any) */
- if (comment_pad_len != 0) {
- if (!wtap_dump_file_write(wdh, &zero_pad, comment_pad_len, err))
- return FALSE;
- wdh->bytes_dumped += comment_pad_len;
- }
- }
- /*
- * if_name 2 A UTF-8 string containing the name of the device used to capture data.
- */
- if (if_name_len !=0) {
- option_hdr.type = OPT_IDB_NAME;
- option_hdr.value_length = if_name_len;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write the comments string */
- pcapng_debug("pcapng_write_if_descr_block, if_name:'%s' if_name_len %u if_name_pad_len %u" , if_name, if_name_len, if_name_pad_len);
- if (!wtap_dump_file_write(wdh, if_name, if_name_len, err))
- return FALSE;
- wdh->bytes_dumped += if_name_len;
-
- /* write padding (if any) */
- if (if_name_pad_len != 0) {
- if (!wtap_dump_file_write(wdh, &zero_pad, if_name_pad_len, err))
- return FALSE;
- wdh->bytes_dumped += if_name_pad_len;
- }
- }
- /*
- * if_description 3 A UTF-8 string containing the description of the device used to capture data.
- */
- if (if_description_len != 0) {
- option_hdr.type = OPT_IDB_NAME;
- option_hdr.value_length = if_description_len;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write the comments string */
- pcapng_debug("pcapng_write_if_descr_block, if_description:'%s' if_description_len %u if_description_pad_len %u" , if_description, if_description_len, if_description_pad_len);
- if (!wtap_dump_file_write(wdh, if_description, if_description_len, err))
- return FALSE;
- wdh->bytes_dumped += if_description_len;
-
- /* write padding (if any) */
- if (if_description_pad_len != 0) {
- if (!wtap_dump_file_write(wdh, &zero_pad, if_description_pad_len, err))
- return FALSE;
- wdh->bytes_dumped += if_description_pad_len;
- }
- }
- /* Currently not handled
- * if_IPv4addr 4 Interface network address and netmask.
- * if_IPv6addr 5 Interface network address and prefix length (stored in the last byte).
- * if_MACaddr 6 Interface Hardware MAC address (48 bits). 00 01 02 03 04 05
- * if_EUIaddr 7 Interface Hardware EUI address (64 bits), if available. TODO: give a good example
- */
- /*
- * if_speed 8 Interface speed (in bps). 100000000 for 100Mbps
- */
- if (if_speed != 0) {
- option_hdr.type = OPT_IDB_SPEED;
- option_hdr.value_length = 8;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write the comments string */
- pcapng_debug("pcapng_write_if_descr_block: if_speed %" G_GINT64_MODIFIER "u (bps)", if_speed);
- if (!wtap_dump_file_write(wdh, &if_speed, sizeof(guint64), err))
- return FALSE;
- wdh->bytes_dumped += 8;
- }
- /*
- * if_tsresol 9 Resolution of timestamps.
- * default is 6 for microsecond resolution, opt 9 Resolution of timestamps.
- * If the Most Significant Bit is equal to zero, the remaining bits indicates
- * the resolution of the timestamp as as a negative power of 10
- */
- if (if_tsresol != 0) {
- option_hdr.type = OPT_IDB_TSRESOL;
- option_hdr.value_length = 1;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write the time stamp resolution */
- pcapng_debug("pcapng_write_if_descr_block: if_tsresol %u", if_tsresol);
- if (!wtap_dump_file_write(wdh, &if_tsresol, 1, err))
- return FALSE;
- wdh->bytes_dumped += 1;
- if (!wtap_dump_file_write(wdh, &zero_pad, 3, err))
- return FALSE;
- wdh->bytes_dumped += 3;
- }
- /* not used
- * if_tzone 10 Time zone for GMT support (TODO: specify better). TODO: give a good example
- */
- /*
- * if_filter 11 The filter (e.g. "capture only TCP traffic") used to capture traffic.
- */
- /* Libpcap string variant */
- if (if_filter_str_len !=0) {
- option_hdr.type = OPT_IDB_FILTER;
- option_hdr.value_length = if_filter_str_len;
- /* if_filter_str_len includes the leading byte indicating filter type (libpcap str or BPF code) */
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write the zero indicating libpcap filter variant */
- if (!wtap_dump_file_write(wdh, &zero_pad, 1, err))
- return FALSE;
- wdh->bytes_dumped += 1;
-
- /* Write the comments string */
- pcapng_debug("pcapng_write_if_descr_block, if_filter_str:'%s' if_filter_str_len %u if_filter_str_pad_len %u" , if_filter->if_filter_str, if_filter_str_len, if_filter_str_pad_len);
- /* if_filter_str_len includes the leading byte indicating filter type (libpcap str or BPF code) */
- if (!wtap_dump_file_write(wdh, if_filter->if_filter_str, if_filter_str_len-1, err))
- return FALSE;
- wdh->bytes_dumped += if_filter_str_len - 1;
-
- /* write padding (if any) */
- if (if_filter_str_pad_len != 0) {
- if (!wtap_dump_file_write(wdh, &zero_pad, if_filter_str_pad_len, err))
- return FALSE;
- wdh->bytes_dumped += if_filter_str_pad_len;
- }
- }
- /*
- * if_os 12 A UTF-8 string containing the name of the operating system of the machine in which this interface is installed.
- */
- if (if_os_len != 0) {
- option_hdr.type = OPT_IDB_OS;
- option_hdr.value_length = if_os_len;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write the comments string */
- pcapng_debug("pcapng_write_if_descr_block, if_os:'%s' if_os_len %u if_os_pad_len %u" , if_os, if_os_len, if_os_pad_len);
- if (!wtap_dump_file_write(wdh, if_os, if_os_len, err))
- return FALSE;
- wdh->bytes_dumped += if_os_len;
-
- /* write padding (if any) */
- if (if_os_pad_len != 0) {
- if (!wtap_dump_file_write(wdh, &zero_pad, if_os_pad_len, err))
- return FALSE;
- wdh->bytes_dumped += if_os_pad_len;
- }
- }
-
- if (have_options) {
- option_hdr.type = OPT_EOFOPT;
- option_hdr.value_length = 0;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
- }
-
- /*
- * if_fcslen 13 An integer value that specified the length of the Frame Check Sequence (in bits) for this interface.
- */
- /*
- * if_tsoffset 14 A 64 bits integer value that specifies an offset (in seconds) that must be added to the timestamp of each packet
- * to obtain the absolute timestamp of a packet. If the option is missing, the timestamps stored in the packet must be considered absolute timestamps.
- */
-
- /* write block footer */
- if (!wtap_dump_file_write(wdh, &bh.block_total_length,
- sizeof bh.block_total_length, err))
- return FALSE;
- wdh->bytes_dumped += sizeof bh.block_total_length;
-
- return TRUE;
-}
-
-static gboolean
-pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtap_optionblock_t if_stats, int *err)
-{
-
- pcapng_block_header_t bh;
- pcapng_interface_statistics_block_t isb;
- const guint32 zero_pad = 0;
- gboolean have_options = FALSE;
- struct option option_hdr; /* guint16 type, guint16 value_length; */
- guint32 options_total_length = 0;
- guint32 comment_len = 0;
- guint32 comment_pad_len = 0;
- char *opt_comment;
- guint64 isb_starttime, isb_endtime, isb_ifrecv, isb_ifdrop, isb_filteraccept, isb_osdrop, isb_usrdeliv;
- wtapng_if_stats_mandatory_t* if_stats_mand;
-
- pcapng_debug("pcapng_write_interface_statistics_block");
-
- wtap_optionblock_get_option_string(if_stats, OPT_COMMENT, &opt_comment);
- /* Calculate options length */
- if (opt_comment) {
- have_options = TRUE;
- comment_len = (guint32)strlen(opt_comment) & 0xffff;
- if ((comment_len % 4)) {
- comment_pad_len = 4 - (comment_len % 4);
- } else {
- comment_pad_len = 0;
- }
- options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
- }
-
- wtap_optionblock_get_option_uint64(if_stats, OPT_ISB_STARTTIME, &isb_starttime);
- if (isb_starttime != 0) {
- have_options = TRUE;
- options_total_length = options_total_length + 8 + 4 /* options tag */ ;
- }
- wtap_optionblock_get_option_uint64(if_stats, OPT_ISB_ENDTIME, &isb_endtime);
- if (isb_endtime != 0) {
- have_options = TRUE;
- options_total_length = options_total_length + 8 + 4 /* options tag */ ;
- }
- wtap_optionblock_get_option_uint64(if_stats, OPT_ISB_IFRECV, &isb_ifrecv);
- if (isb_ifrecv != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
- have_options = TRUE;
- options_total_length = options_total_length + 8 + 4 /* options tag */ ;
- }
- wtap_optionblock_get_option_uint64(if_stats, OPT_ISB_IFDROP, &isb_ifdrop);
- if (isb_ifdrop != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
- have_options = TRUE;
- options_total_length = options_total_length + 8 + 4 /* options tag */ ;
- }
- wtap_optionblock_get_option_uint64(if_stats, OPT_ISB_FILTERACCEPT, &isb_filteraccept);
- if (isb_filteraccept != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
- have_options = TRUE;
- options_total_length = options_total_length + 8 + 4 /* options tag */ ;
- }
- wtap_optionblock_get_option_uint64(if_stats, OPT_ISB_OSDROP, &isb_osdrop);
- if (isb_osdrop != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
- have_options = TRUE;
- options_total_length = options_total_length + 8 + 4 /* options tag */ ;
- }
- wtap_optionblock_get_option_uint64(if_stats, OPT_ISB_USRDELIV, &isb_usrdeliv);
- if (isb_usrdeliv != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
- have_options = TRUE;
- options_total_length = options_total_length + 8 + 4 /* options tag */ ;
- }
-
- /* write block header */
- if (have_options) {
- /* End-of-optios tag */
- options_total_length += 4;
- }
-
- /* write block header */
- bh.block_type = BLOCK_TYPE_ISB;
- bh.block_total_length = (guint32)(sizeof(bh) + sizeof(isb) + options_total_length + 4);
-
- if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
- return FALSE;
- wdh->bytes_dumped += sizeof bh;
-
- /* write block fixed content */
- if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(if_stats);
-
- isb.interface_id = if_stats_mand->interface_id;
- isb.timestamp_high = if_stats_mand->ts_high;
- isb.timestamp_low = if_stats_mand->ts_low;
-
- if (!wtap_dump_file_write(wdh, &isb, sizeof isb, err))
- return FALSE;
- wdh->bytes_dumped += sizeof isb;
-
- /* write (optional) block options */
- if (comment_len) {
- option_hdr.type = OPT_COMMENT;
- option_hdr.value_length = comment_len;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write the comments string */
- pcapng_debug("pcapng_write_interface_statistics_block, comment:'%s' comment_len %u comment_pad_len %u" , opt_comment, comment_len, comment_pad_len);
- if (!wtap_dump_file_write(wdh, opt_comment, comment_len, err))
- return FALSE;
- wdh->bytes_dumped += comment_len;
-
- /* write padding (if any) */
- if (comment_pad_len != 0) {
- if (!wtap_dump_file_write(wdh, &zero_pad, comment_pad_len, err))
- return FALSE;
- wdh->bytes_dumped += comment_pad_len;
- }
- }
- /*guint64 isb_starttime */
- if (isb_starttime != 0) {
- guint32 high, low;
-
- option_hdr.type = OPT_ISB_STARTTIME;
- option_hdr.value_length = 8;
- high = (guint32)((isb_starttime>>32) & 0xffffffff);
- low = (guint32)(isb_starttime & 0xffffffff);
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write isb_starttime */
- pcapng_debug("pcapng_write_interface_statistics_block, isb_starttime: %" G_GINT64_MODIFIER "u" , isb_starttime);
- if (!wtap_dump_file_write(wdh, &high, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
- if (!wtap_dump_file_write(wdh, &low, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
- }
- /*guint64 isb_endtime */
- if (isb_endtime != 0) {
- guint32 high, low;
-
- option_hdr.type = OPT_ISB_ENDTIME;
- option_hdr.value_length = 8;
- high = (guint32)((isb_endtime>>32) & 0xffffffff);
- low = (guint32)(isb_endtime & 0xffffffff);
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write isb_endtime */
- pcapng_debug("pcapng_write_interface_statistics_block, isb_starttime: %" G_GINT64_MODIFIER "u" , isb_endtime);
- if (!wtap_dump_file_write(wdh, &high, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
- if (!wtap_dump_file_write(wdh, &low, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
- }
- /*guint64 isb_ifrecv;*/
- if (isb_ifrecv != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
- option_hdr.type = OPT_ISB_IFRECV;
- option_hdr.value_length = 8;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write isb_ifrecv */
- pcapng_debug("pcapng_write_interface_statistics_block, isb_ifrecv: %" G_GINT64_MODIFIER "u" , isb_ifrecv);
- if (!wtap_dump_file_write(wdh, &isb_ifrecv, 8, err))
- return FALSE;
- wdh->bytes_dumped += 8;
- }
- /*guint64 isb_ifdrop;*/
- if (isb_ifdrop != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
- option_hdr.type = OPT_ISB_IFDROP;
- option_hdr.value_length = 8;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write isb_ifdrop */
- pcapng_debug("pcapng_write_interface_statistics_block, isb_ifdrop: %" G_GINT64_MODIFIER "u" , isb_ifdrop);
- if (!wtap_dump_file_write(wdh, &isb_ifdrop, 8, err))
- return FALSE;
- wdh->bytes_dumped += 8;
- }
- /*guint64 isb_filteraccept;*/
- if (isb_filteraccept != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
- option_hdr.type = OPT_ISB_FILTERACCEPT;
- option_hdr.value_length = 8;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write isb_filteraccept */
- pcapng_debug("pcapng_write_interface_statistics_block, isb_filteraccept: %" G_GINT64_MODIFIER "u" , isb_filteraccept);
- if (!wtap_dump_file_write(wdh, &isb_filteraccept, 8, err))
- return FALSE;
- wdh->bytes_dumped += 8;
- }
- /*guint64 isb_osdrop;*/
- if (isb_osdrop != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
- option_hdr.type = OPT_ISB_OSDROP;
- option_hdr.value_length = 8;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write isb_osdrop */
- pcapng_debug("pcapng_write_interface_statistics_block, isb_osdrop: %" G_GINT64_MODIFIER "u" , isb_osdrop);
- if (!wtap_dump_file_write(wdh, &isb_osdrop, 8, err))
- return FALSE;
- wdh->bytes_dumped += 8;
- }
- /*guint64 isb_usrdeliv;*/
- if (isb_usrdeliv != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
- option_hdr.type = OPT_ISB_USRDELIV;
- option_hdr.value_length = 8;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
-
- /* Write isb_usrdeliv */
- pcapng_debug("pcapng_write_interface_statistics_block, isb_usrdeliv: %" G_GINT64_MODIFIER "u" , isb_usrdeliv);
- if (!wtap_dump_file_write(wdh, &isb_usrdeliv, 8, err))
- return FALSE;
- wdh->bytes_dumped += 8;
- }
-
- if (have_options) {
- option_hdr.type = OPT_EOFOPT;
- option_hdr.value_length = 0;
- if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
- return FALSE;
- wdh->bytes_dumped += 4;
- }
-
- /* write block footer */
- if (!wtap_dump_file_write(wdh, &bh.block_total_length,
- sizeof bh.block_total_length, err))
- return FALSE;
- wdh->bytes_dumped += sizeof bh.block_total_length;
-
- return TRUE;
-
-}
-
-
static gboolean
pcapng_write_enhanced_packet_block(wtap_dumper *wdh,
const struct wtap_pkthdr *phdr,
@@ -4056,7 +3259,7 @@ static gboolean pcapng_dump_finish(wtap_dumper *wdh, int *err)
if_stats = g_array_index(int_data_mand->interface_statistics, wtap_optionblock_t, j);
pcapng_debug("pcapng_dump_finish: write ISB for interface %u", ((wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(if_stats))->interface_id);
- if (!pcapng_write_interface_statistics_block(wdh, if_stats, err)) {
+ if (!wtap_optionblock_write(wdh, if_stats, err)) {
return FALSE;
}
}
@@ -4098,11 +3301,11 @@ pcapng_dump_open(wtap_dumper *wdh, int *err)
for (i = 0; i < wdh->interface_data->len; i++) {
/* Get the interface description */
- wtap_optionblock_t int_data;
+ wtap_optionblock_t idb;
- int_data = g_array_index(wdh->interface_data, wtap_optionblock_t, i);
+ idb = g_array_index(wdh->interface_data, wtap_optionblock_t, i);
- if (!pcapng_write_if_descr_block(wdh, int_data, err)) {
+ if (!wtap_optionblock_write(wdh, idb, err)) {
return FALSE;
}
diff --git a/wiretap/pcapng.h b/wiretap/pcapng.h
index 7827a83482..49a896a0f4 100644
--- a/wiretap/pcapng.h
+++ b/wiretap/pcapng.h
@@ -112,6 +112,50 @@
#define OPT_ISB_OSDROP 0x0007
#define OPT_ISB_USRDELIV 0x0008
+/* pcapng: common block header file encoding for every block type */
+typedef struct pcapng_block_header_s {
+ guint32 block_type;
+ guint32 block_total_length;
+ /* x bytes block_body */
+ /* guint32 block_total_length */
+} pcapng_block_header_t;
+
+/* pcapng: section header block file encoding */
+typedef struct pcapng_section_header_block_s {
+ /* pcapng_block_header_t */
+ guint32 magic;
+ guint16 version_major;
+ guint16 version_minor;
+ guint64 section_length; /* might be -1 for unknown */
+ /* ... Options ... */
+} pcapng_section_header_block_t;
+
+/* pcapng: interface description block file encoding */
+typedef struct pcapng_interface_description_block_s {
+ guint16 linktype;
+ guint16 reserved;
+ guint32 snaplen;
+ /* ... Options ... */
+} pcapng_interface_description_block_t;
+
+/* pcapng: interface statistics block file encoding */
+typedef struct pcapng_interface_statistics_block_s {
+ guint32 interface_id;
+ guint32 timestamp_high;
+ guint32 timestamp_low;
+ /* ... Options ... */
+} pcapng_interface_statistics_block_t;
+
+struct pcapng_option_header {
+ guint16 type;
+ guint16 value_length;
+};
+
+/*
+ * Minimum IDB size = minimum block size + size of fixed length portion of IDB.
+ */
+#define MIN_IDB_SIZE ((guint32)(MIN_BLOCK_SIZE + sizeof(pcapng_interface_description_block_t)))
+
wtap_open_return_val pcapng_open(wtap *wth, int *err, gchar **err_info);
gboolean pcapng_dump_open(wtap_dumper *wdh, int *err);
int pcapng_dump_can_write_encap(int encap);
diff --git a/wiretap/wtap_opttypes.c b/wiretap/wtap_opttypes.c
index e72d77d907..3878178d9a 100644
--- a/wiretap/wtap_opttypes.c
+++ b/wiretap/wtap_opttypes.c
@@ -27,25 +27,50 @@
#include "wtap_opttypes.h"
#include "wtap-int.h"
#include "pcapng.h"
+#include "pcapng_module.h"
+
+#if 0
+#define wtap_debug(...) g_warning(__VA_ARGS__)
+#else
+#define wtap_debug(...)
+#endif
typedef void (*wtap_block_create_func)(wtap_optionblock_t block);
typedef void (*wtap_mand_free_func)(wtap_optionblock_t block);
typedef void (*wtap_mand_copy_func)(wtap_optionblock_t dest_block, wtap_optionblock_t src_block);
+typedef gboolean (*wtap_write_func)(struct wtap_dumper *wdh, wtap_optionblock_t block, int *err);
typedef struct wtap_opt_register
{
const char *name; /**< name of block */
const char *description; /**< human-readable description of block */
wtap_block_create_func create;
+ wtap_write_func write;
wtap_mand_free_func free_mand;
wtap_mand_copy_func copy_mand;
} wtap_opt_register_t;
+typedef struct wtap_optblock_internal {
+ const char *name; /**< name of option */
+ const char *description; /**< human-readable description of option */
+ guint number; /**< Option index */
+ wtap_opttype_e type; /**< type of that option */
+ wtap_opttype_option_write_size write_size; /**< Number of bytes to write to file (0 for don't write) */
+ wtap_opttype_option_write write_data; /**< write option data to dumper */
+} wtap_optblock_internal_t;
+
+typedef struct wtap_optblock_value {
+ wtap_optblock_internal_t* info;
+ wtap_option_type option; /**< pointer to variable storing the value */
+ wtap_option_type default_val; /**< the default value of the option */
+} wtap_optblock_value_t;
+
struct wtap_optionblock
{
wtap_opt_register_t* info;
void* mandatory_data;
- GArray* options;
+ GArray* option_infos; /* Only want to keep 1 copy of "static" option information */
+ GArray* option_values;
};
/* Keep track of wtap_opt_register_t's via their id number */
@@ -72,15 +97,15 @@ void* wtap_optionblock_get_mandatory_data(wtap_optionblock_t block)
return block->mandatory_data;
}
-static wtap_opttype_t* wtap_optionblock_get_option(wtap_optionblock_t block, guint option_id)
+static wtap_optblock_value_t* wtap_optionblock_get_option(wtap_optionblock_t block, guint option_id)
{
guint i;
- wtap_opttype_t* opttype = NULL;
+ wtap_optblock_value_t* opttype = NULL;
- for (i = 0; i < block->options->len; i++)
+ for (i = 0; i < block->option_values->len; i++)
{
- opttype = g_array_index(block->options, wtap_opttype_t*, i);
- if (opttype->number == option_id)
+ opttype = g_array_index(block->option_values, wtap_optblock_value_t*, i);
+ if (opttype->info->number == option_id)
return opttype;
}
@@ -96,6 +121,8 @@ wtap_optionblock_t wtap_optionblock_create(wtap_optionblock_type_t block_type)
block = g_new(struct wtap_optionblock, 1);
block->info = block_list[block_type];
+ block->option_infos = g_array_new(FALSE, FALSE, sizeof(wtap_optblock_internal_t*));
+ block->option_values = g_array_new(FALSE, FALSE, sizeof(wtap_optblock_value_t*));
block->info->create(block);
return block;
@@ -104,11 +131,11 @@ wtap_optionblock_t wtap_optionblock_create(wtap_optionblock_type_t block_type)
static void wtap_optionblock_free_options(wtap_optionblock_t block)
{
guint i;
- wtap_opttype_t* opttype = NULL;
+ wtap_optblock_value_t* opttype = NULL;
- for (i = 0; i < block->options->len; i++) {
- opttype = g_array_index(block->options, wtap_opttype_t*, i);
- switch(opttype->type)
+ for (i = 0; i < block->option_values->len; i++) {
+ opttype = g_array_index(block->option_values, wtap_optblock_value_t*, i);
+ switch(opttype->info->type)
{
case WTAP_OPTTYPE_STRING:
g_free(opttype->option.stringval);
@@ -135,8 +162,10 @@ void wtap_optionblock_free(wtap_optionblock_t block)
g_free(block->mandatory_data);
wtap_optionblock_free_options(block);
- if (block->options != NULL)
- g_array_free(block->options, FALSE);
+ if (block->option_infos != NULL)
+ g_array_free(block->option_infos, FALSE);
+ if (block->option_values != NULL)
+ g_array_free(block->option_values, FALSE);
g_free(block);
}
}
@@ -144,7 +173,8 @@ void wtap_optionblock_free(wtap_optionblock_t block)
void wtap_optionblock_copy_options(wtap_optionblock_t dest_block, wtap_optionblock_t src_block)
{
guint i;
- wtap_opttype_t *dest_opttype, *src_opttype;
+ wtap_optblock_internal_t *src_internal;
+ wtap_optblock_value_t *dest_value, *src_value;
if (dest_block->info->copy_mand != NULL)
dest_block->info->copy_mand(dest_block, src_block);
@@ -152,290 +182,474 @@ void wtap_optionblock_copy_options(wtap_optionblock_t dest_block, wtap_optionblo
/* Copy the options. For now, don't remove any options that are in destination
* but not source.
*/
- for (i = 0; i < src_block->options->len; i++)
+ for (i = 0; i < src_block->option_values->len; i++)
{
- src_opttype = g_array_index(src_block->options, wtap_opttype_t*, i);
- dest_opttype = wtap_optionblock_get_option(dest_block, src_opttype->number);
- if (dest_opttype == NULL)
+ src_internal = g_array_index(src_block->option_infos, wtap_optblock_internal_t*, i);
+ src_value = g_array_index(src_block->option_values, wtap_optblock_value_t*, i);
+ dest_value = wtap_optionblock_get_option(dest_block, src_internal->number);
+ if (dest_value == NULL)
{
- /* Option doesn't exist, add it */
- switch(src_opttype->type)
- {
- case WTAP_OPTTYPE_UINT8:
- wtap_optionblock_add_option_uint8(dest_block, src_opttype->number, src_opttype->name, src_opttype->description,
- src_opttype->option.uint8val, src_opttype->default_val.uint8val);
- break;
- case WTAP_OPTTYPE_UINT64:
- wtap_optionblock_add_option_uint64(dest_block, src_opttype->number, src_opttype->name, src_opttype->description,
- src_opttype->option.uint64val, src_opttype->default_val.uint64val);
- break;
- case WTAP_OPTTYPE_STRING:
- wtap_optionblock_add_option_string(dest_block, src_opttype->number, src_opttype->name, src_opttype->description,
- src_opttype->option.stringval, src_opttype->default_val.stringval);
- break;
- case WTAP_OPTTYPE_CUSTOM:
- wtap_optionblock_add_option_custom(dest_block, src_opttype->number, src_opttype->name, src_opttype->description,
- src_opttype->option.customval.data, src_opttype->default_val.customval.data,
- src_opttype->option.customval.size, src_opttype->option.customval.free_func);
- break;
- }
+ wtap_optblock_reg_t reg_optblock;
+
+ reg_optblock.name = src_internal->name;
+ reg_optblock.description = src_internal->description;
+ reg_optblock.type = src_internal->type;
+ reg_optblock.option = src_value->option;
+ reg_optblock.default_val = src_value->default_val;
+
+ wtap_optionblock_add_option(dest_block, src_internal->number, &reg_optblock);
}
else
{
/* Option exists, replace it */
- switch(src_opttype->type)
+ switch(src_internal->type)
{
case WTAP_OPTTYPE_UINT8:
- dest_opttype->option.uint8val = src_opttype->option.uint8val;
+ dest_value->option.uint8val = src_value->option.uint8val;
break;
case WTAP_OPTTYPE_UINT64:
- dest_opttype->option.uint64val = src_opttype->option.uint64val;
+ dest_value->option.uint64val = src_value->option.uint64val;
break;
case WTAP_OPTTYPE_STRING:
- g_free(dest_opttype->option.stringval);
- dest_opttype->option.stringval = g_strdup(src_opttype->option.stringval);
+ g_free(dest_value->option.stringval);
+ dest_value->option.stringval = g_strdup(src_value->option.stringval);
break;
case WTAP_OPTTYPE_CUSTOM:
- dest_opttype->option.customval.free_func(dest_opttype->option.customval.data);
- g_free(dest_opttype->option.customval.data);
- dest_opttype->option.customval.data = g_memdup(src_opttype->option.customval.data, src_opttype->option.customval.size);
+ dest_value->option.customval.free_func(dest_value->option.customval.data);
+ g_free(dest_value->option.customval.data);
+ dest_value->option.customval.data = g_memdup(src_value->option.customval.data, src_value->option.customval.size);
break;
}
}
}
}
-int wtap_optionblock_add_option_string(wtap_optionblock_t block, guint option_id,
- const char *name, const char *description, char* opt_value, char* default_value)
+gboolean wtap_optionblock_write(struct wtap_dumper *wdh, wtap_optionblock_t block, int *err)
+{
+ if ((block == NULL) || (block->info->write == NULL))
+ {
+ *err = WTAP_ERR_INTERNAL;
+ return FALSE;
+ }
+
+ return block->info->write(wdh, block, err);
+}
+
+static guint32 wtap_optionblock_get_option_write_size(wtap_optionblock_t block)
+{
+ guint i;
+ guint32 options_total_length = 0, length;
+ wtap_optblock_value_t *value;
+
+ for (i = 0; i < block->option_values->len; i++)
+ {
+ value = g_array_index(block->option_values, wtap_optblock_value_t*, i);
+ if ((value->info->write_size != NULL) && (value->info->write_data != NULL))
+ {
+ length = value->info->write_size(&value->option);
+ options_total_length += length;
+ /* Add bytes for option header if option should be written */
+ if (length > 0)
+ options_total_length += 4;
+ }
+ }
+
+ return options_total_length;
+}
+
+static gboolean wtap_optionblock_write_options(struct wtap_dumper *wdh, wtap_optionblock_t block, guint32 options_total_length, int *err)
{
- wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+ guint i;
+ wtap_optblock_value_t *value;
+ struct pcapng_option_header option_hdr;
+ guint32 length;
+
+ /* Check if we have at least 1 option to write */
+ if (options_total_length == 0)
+ return TRUE;
+
+ for (i = 0; i < block->option_values->len; i++)
+ {
+ value = g_array_index(block->option_values, wtap_optblock_value_t*, i);
+ if ((value->info->write_size != NULL) && (value->info->write_data != NULL) &&
+ ((length = value->info->write_size(&value->option)) > 0))
+ {
+ /* Write the option */
+ wtap_debug("wtap_optionblock_write %s, field:'%s' length: %u", block->description, value->info->description, length);
+
+ /* String options don't consider pad bytes part of the length, so readjust here */
+ if (value->info->type == WTAP_OPTTYPE_STRING)
+ length = (guint32)strlen(value->option.stringval) & 0xffff;
+
+ option_hdr.type = value->info->number;
+ option_hdr.value_length = length;
+ if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
+ return FALSE;
+ wdh->bytes_dumped += 4;
+
+ if (!value->info->write_data(wdh, &value->option, err))
+ return FALSE;
+ }
+ }
+
+ /* Write end of options */
+ option_hdr.type = OPT_EOFOPT;
+ option_hdr.value_length = 0;
+ if (!wtap_dump_file_write(wdh, &option_hdr, 4, err))
+ return FALSE;
+ wdh->bytes_dumped += 4;
+ return TRUE;
+}
+
+int wtap_optionblock_add_option(wtap_optionblock_t block, guint option_id, wtap_optblock_reg_t* option)
+{
+ wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
+ wtap_optblock_internal_t *opt_internal;
/* Option already exists */
- if (opttype != NULL)
+ if (opt_value != NULL)
return WTAP_OPTTYPE_ALREADY_EXISTS;
- opttype = g_new(wtap_opttype_t, 1);
+ opt_value = g_new0(wtap_optblock_value_t, 1);
+ opt_internal = g_new(wtap_optblock_internal_t, 1);
+
+ opt_internal->name = option->name;
+ opt_internal->description = option->description;
+ opt_internal->number = option_id;
+ opt_internal->type = option->type;
+ opt_internal->write_size = option->write_size_func;
+ opt_internal->write_data = option->write_func;
- opttype->name = name;
- opttype->description = description;
- opttype->number = option_id;
- opttype->type = WTAP_OPTTYPE_STRING;
- opttype->option.stringval = g_strdup(opt_value);
- opttype->default_val.stringval = default_value;
+ opt_value->info = opt_internal;
+
+ switch(option->type)
+ {
+ case WTAP_OPTTYPE_UINT8:
+ opt_value->option.uint8val = option->option.uint8val;
+ opt_value->default_val.uint8val = option->default_val.uint8val;
+ break;
+ case WTAP_OPTTYPE_UINT64:
+ opt_value->option.uint64val = option->option.uint64val;
+ opt_value->default_val.uint64val = option->default_val.uint64val;
+ break;
+ case WTAP_OPTTYPE_STRING:
+ opt_value->option.stringval = g_strdup(option->option.stringval);
+ opt_value->default_val.stringval = option->default_val.stringval;
+ break;
+ case WTAP_OPTTYPE_CUSTOM:
+ opt_value->option.customval.size = option->option.customval.size;
+ opt_value->option.customval.data = g_memdup(option->option.customval.data, option->option.customval.size);
+ opt_value->option.customval.free_func = option->option.customval.free_func;
+ opt_value->default_val.customval.size = option->default_val.customval.size;
+ opt_value->default_val.customval.data = g_memdup(option->default_val.customval.data, option->default_val.customval.size);
+ opt_value->default_val.customval.free_func = option->default_val.customval.free_func;
+ break;
+ }
- g_array_append_val(block->options, opttype);
+ g_array_append_val(block->option_infos, opt_internal);
+ g_array_append_val(block->option_values, opt_value);
return WTAP_OPTTYPE_SUCCESS;
}
-int wtap_optionblock_set_option_string(wtap_optionblock_t block, guint option_id, char* opt_value)
+int wtap_optionblock_set_option_string(wtap_optionblock_t block, guint option_id, char* value)
{
- wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+ wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
/* Didn't find the option */
- if (opttype == NULL)
+ if (opt_value == NULL)
return WTAP_OPTTYPE_NOT_FOUND;
- if (opttype->type != WTAP_OPTTYPE_STRING)
+ if (opt_value->info->type != WTAP_OPTTYPE_STRING)
return WTAP_OPTTYPE_TYPE_MISMATCH;
- g_free(opttype->option.stringval);
- opttype->option.stringval = g_strdup(opt_value);
+ g_free(opt_value->option.stringval);
+ opt_value->option.stringval = g_strdup(value);
return WTAP_OPTTYPE_SUCCESS;
}
-int wtap_optionblock_get_option_string(wtap_optionblock_t block, guint option_id, char** opt_value)
+int wtap_optionblock_get_option_string(wtap_optionblock_t block, guint option_id, char** value)
{
- wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+ wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
/* Didn't find the option */
- if (opttype == NULL)
+ if (opt_value == NULL)
return WTAP_OPTTYPE_NOT_FOUND;
- if (opttype->type != WTAP_OPTTYPE_STRING)
+ if (opt_value->info->type != WTAP_OPTTYPE_STRING)
return WTAP_OPTTYPE_TYPE_MISMATCH;
- *opt_value = opttype->option.stringval;
+ *value = opt_value->option.stringval;
return WTAP_OPTTYPE_SUCCESS;
}
-int wtap_optionblock_add_option_uint64(wtap_optionblock_t block, guint option_id,
- const char *name, const char *description, guint64 opt_value, guint64 default_value)
+guint32 wtap_opttype_write_size_string(wtap_option_type* data)
{
- wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+ guint32 size, pad;
+ if ((data == NULL) ||(data->stringval == NULL))
+ return 0;
+
+ size = (guint32)strlen(data->stringval) & 0xffff;
+ if ((size % 4)) {
+ pad = 4 - (size % 4);
+ } else {
+ pad = 0;
+ }
- /* Option already exists */
- if (opttype != NULL)
- return WTAP_OPTTYPE_ALREADY_EXISTS;
+ return size+pad;
+}
- opttype = g_new(wtap_opttype_t, 1);
+gboolean wtap_opttype_write_data_string(struct wtap_dumper* wdh, wtap_option_type* data, int *err)
+{
+ guint32 size = (guint32)strlen(data->stringval) & 0xffff;
+ guint32 pad;
+ const guint32 zero_pad = 0;
+
+ if (!wtap_dump_file_write(wdh, data->stringval, size, err))
+ return FALSE;
+ wdh->bytes_dumped += size;
+
+ if ((size % 4)) {
+ pad = 4 - (size % 4);
+ } else {
+ pad = 0;
+ }
- opttype->name = name;
- opttype->description = description;
- opttype->number = option_id;
- opttype->type = WTAP_OPTTYPE_UINT64;
- opttype->option.uint64val = opt_value;
- opttype->default_val.uint64val = default_value;
+ /* write padding (if any) */
+ if (pad != 0) {
+ if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
+ return FALSE;
+ wdh->bytes_dumped += pad;
+ }
- g_array_append_val(block->options, opttype);
- return WTAP_OPTTYPE_SUCCESS;
+ return TRUE;
}
-int wtap_optionblock_set_option_uint64(wtap_optionblock_t block, guint option_id, guint64 opt_value)
+int wtap_optionblock_set_option_uint64(wtap_optionblock_t block, guint option_id, guint64 value)
{
- wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+ wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
/* Didn't find the option */
- if (opttype == NULL)
+ if (opt_value == NULL)
return WTAP_OPTTYPE_NOT_FOUND;
- if (opttype->type != WTAP_OPTTYPE_UINT64)
+ if (opt_value->info->type != WTAP_OPTTYPE_UINT64)
return WTAP_OPTTYPE_TYPE_MISMATCH;
- opttype->option.uint64val = opt_value;
+ opt_value->option.uint64val = value;
return WTAP_OPTTYPE_SUCCESS;
}
-int wtap_optionblock_get_option_uint64(wtap_optionblock_t block, guint option_id, guint64* opt_value)
+int wtap_optionblock_get_option_uint64(wtap_optionblock_t block, guint option_id, guint64* value)
{
- wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+ wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
/* Didn't find the option */
- if (opttype == NULL)
+ if (opt_value == NULL)
return WTAP_OPTTYPE_NOT_FOUND;
- if (opttype->type != WTAP_OPTTYPE_UINT64)
+ if (opt_value->info->type != WTAP_OPTTYPE_UINT64)
return WTAP_OPTTYPE_TYPE_MISMATCH;
- *opt_value = opttype->option.uint64val;
+ *value = opt_value->option.uint64val;
return WTAP_OPTTYPE_SUCCESS;
}
-int wtap_optionblock_add_option_uint8(wtap_optionblock_t block, guint option_id,
- const char *name, const char *description, guint8 opt_value, guint8 default_value)
+guint32 wtap_opttype_write_uint64_not0(wtap_option_type* data)
{
- wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+ if (data == NULL)
+ return 0;
- /* Option already exists */
- if (opttype != NULL)
- return WTAP_OPTTYPE_ALREADY_EXISTS;
+ if (data->uint64val == 0)
+ return 0;
+
+ /* value */
+ return 8;
+}
- opttype = g_new(wtap_opttype_t, 1);
+guint32 wtap_opttype_write_uint64_not_minus1(wtap_option_type* data)
+{
+ if (data == NULL)
+ return 0;
- opttype->name = name;
- opttype->description = description;
- opttype->number = option_id;
- opttype->type = WTAP_OPTTYPE_UINT8;
- opttype->option.uint8val = opt_value;
- opttype->default_val.uint8val = default_value;
+ if (data->uint64val == G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF))
+ return 0;
- g_array_append_val(block->options, opttype);
- return WTAP_OPTTYPE_SUCCESS;
+ /* value */
+ return 8;
+}
+
+gboolean wtap_opttype_write_data_uint64(struct wtap_dumper* wdh, wtap_option_type* data, int *err)
+{
+ if (!wtap_dump_file_write(wdh, &data->uint64val, sizeof(guint64), err))
+ return FALSE;
+ wdh->bytes_dumped += 8;
+ return TRUE;
}
-int wtap_optionblock_set_option_uint8(wtap_optionblock_t block, guint option_id, guint8 opt_value)
+int wtap_optionblock_set_option_uint8(wtap_optionblock_t block, guint option_id, guint8 value)
{
- wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+ wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
/* Didn't find the option */
- if (opttype == NULL)
+ if (opt_value == NULL)
return WTAP_OPTTYPE_NOT_FOUND;
- if (opttype->type != WTAP_OPTTYPE_UINT8)
+ if (opt_value->info->type != WTAP_OPTTYPE_UINT8)
return WTAP_OPTTYPE_TYPE_MISMATCH;
- opttype->option.uint8val = opt_value;
+ opt_value->option.uint8val = value;
return WTAP_OPTTYPE_SUCCESS;
}
-int wtap_optionblock_get_option_uint8(wtap_optionblock_t block, guint option_id, guint8* opt_value)
+int wtap_optionblock_get_option_uint8(wtap_optionblock_t block, guint option_id, guint8* value)
{
- wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+ wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
/* Didn't find the option */
- if (opttype == NULL)
+ if (opt_value == NULL)
return WTAP_OPTTYPE_NOT_FOUND;
- if (opttype->type != WTAP_OPTTYPE_UINT8)
+ if (opt_value->info->type != WTAP_OPTTYPE_UINT8)
return WTAP_OPTTYPE_TYPE_MISMATCH;
- *opt_value = opttype->option.uint8val;
+ *value = opt_value->option.uint8val;
return WTAP_OPTTYPE_SUCCESS;
}
-int wtap_optionblock_add_option_custom(wtap_optionblock_t block, guint option_id,
- const char *name, const char *description, void* opt_value, void* default_value,
- guint size, wtap_opttype_free_custom_func free_func)
+guint32 wtap_opttype_write_uint8_not0(wtap_option_type* data)
{
- wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+ if (data == NULL)
+ return 0;
- /* Option already exists */
- if (opttype != NULL)
- return WTAP_OPTTYPE_ALREADY_EXISTS;
+ if (data->uint8val == 0)
+ return 0;
- opttype = g_new(wtap_opttype_t, 1);
+ /* padding to 32 bits */
+ return 4;
+}
- opttype->name = name;
- opttype->description = description;
- opttype->number = option_id;
- opttype->type = WTAP_OPTTYPE_CUSTOM;
- opttype->option.customval.size = size;
- opttype->option.customval.data = g_memdup(opt_value, size);
- opttype->option.customval.free_func = free_func;
- opttype->default_val.customval.size = size;
- opttype->default_val.customval.data = g_memdup(default_value, size);
- opttype->default_val.customval.free_func = free_func;
+gboolean wtap_opttype_write_data_uint8(struct wtap_dumper* wdh, wtap_option_type* data, int *err)
+{
+ const guint32 zero_pad = 0;
- g_array_append_val(block->options, opttype);
- return WTAP_OPTTYPE_SUCCESS;
+ if (!wtap_dump_file_write(wdh, &data->uint8val, 1, err))
+ return FALSE;
+ wdh->bytes_dumped += 1;
+
+ if (!wtap_dump_file_write(wdh, &zero_pad, 3, err))
+ return FALSE;
+ wdh->bytes_dumped += 3;
+
+ return TRUE;
}
-int wtap_optionblock_set_option_custom(wtap_optionblock_t block, guint option_id, void* opt_value)
+int wtap_optionblock_set_option_custom(wtap_optionblock_t block, guint option_id, void* value)
{
- wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+ wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
void* prev_value;
/* Didn't find the option */
- if (opttype == NULL)
+ if (opt_value == NULL)
return WTAP_OPTTYPE_NOT_FOUND;
- if (opttype->type != WTAP_OPTTYPE_CUSTOM)
+ if (opt_value->info->type != WTAP_OPTTYPE_CUSTOM)
return WTAP_OPTTYPE_TYPE_MISMATCH;
- prev_value = opttype->option.customval.data;
- opttype->option.customval.data = g_memdup(opt_value, opttype->option.customval.size);
+ prev_value = opt_value->option.customval.data;
+ opt_value->option.customval.data = g_memdup(value, opt_value->option.customval.size);
/* Free after memory is duplicated in case structure was manipulated with a "get then set" */
g_free(prev_value);
return WTAP_OPTTYPE_SUCCESS;
}
-int wtap_optionblock_get_option_custom(wtap_optionblock_t block, guint option_id, void** opt_value)
+int wtap_optionblock_get_option_custom(wtap_optionblock_t block, guint option_id, void** value)
{
- wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+ wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
/* Didn't find the option */
- if (opttype == NULL)
+ if (opt_value == NULL)
return WTAP_OPTTYPE_NOT_FOUND;
- if (opttype->type != WTAP_OPTTYPE_CUSTOM)
+ if (opt_value->info->type != WTAP_OPTTYPE_CUSTOM)
return WTAP_OPTTYPE_TYPE_MISMATCH;
- *opt_value = opttype->option.customval.data;
+ *value = opt_value->option.customval.data;
return WTAP_OPTTYPE_SUCCESS;
}
static void shb_create(wtap_optionblock_t block)
{
+ static wtap_optblock_reg_t comment_option = {"opt_comment", "Optional comment", WTAP_OPTTYPE_STRING, wtap_opttype_write_size_string, wtap_opttype_write_data_string, {0}, {0}};
+ static wtap_optblock_reg_t hardware_option = {"hardware", "SBH Hardware", WTAP_OPTTYPE_STRING, wtap_opttype_write_size_string, wtap_opttype_write_data_string, {0}, {0}};
+ static wtap_optblock_reg_t os_option = {"os", "SBH Operating System", WTAP_OPTTYPE_STRING, wtap_opttype_write_size_string, wtap_opttype_write_data_string, {0}, {0}};
+ static wtap_optblock_reg_t user_appl_option = {"user_appl", "SBH User Application", WTAP_OPTTYPE_STRING, wtap_opttype_write_size_string, wtap_opttype_write_data_string, {0}, {0}};
+
wtapng_mandatory_section_t* section_mand = g_new(wtapng_mandatory_section_t, 1);
+ /* Set proper values for the union */
+ comment_option.option.stringval = NULL;
+ comment_option.default_val.stringval = NULL;
+ hardware_option.option.stringval = NULL;
+ hardware_option.default_val.stringval = NULL;
+ os_option.option.stringval = NULL;
+ os_option.default_val.stringval = NULL;
+ user_appl_option.option.stringval = NULL;
+ user_appl_option.default_val.stringval = NULL;
+
section_mand->section_length = -1;
block->mandatory_data = section_mand;
- block->options = g_array_new(FALSE, FALSE, sizeof(wtap_opttype_t*));
- wtap_optionblock_add_option_string(block, OPT_COMMENT, "opt_comment", "Optional comment", NULL, NULL);
- wtap_optionblock_add_option_string(block, OPT_SHB_HARDWARE, "hardware", "SBH Hardware", NULL, NULL);
- wtap_optionblock_add_option_string(block, OPT_SHB_OS, "os", "SBH Operating System", NULL, NULL);
- wtap_optionblock_add_option_string(block, OPT_SHB_USERAPPL, "user_appl", "SBH User Application", NULL, NULL);
+ wtap_optionblock_add_option(block, OPT_COMMENT, &comment_option);
+ wtap_optionblock_add_option(block, OPT_SHB_HARDWARE, &hardware_option);
+ wtap_optionblock_add_option(block, OPT_SHB_OS, &os_option);
+ wtap_optionblock_add_option(block, OPT_SHB_USERAPPL, &user_appl_option);
+}
+
+static gboolean shb_write(struct wtap_dumper *wdh, wtap_optionblock_t block, int *err)
+{
+ pcapng_block_header_t bh;
+ pcapng_section_header_block_t shb;
+ wtapng_mandatory_section_t* mand_data = (wtapng_mandatory_section_t*)block->mandatory_data;
+ guint32 options_total_length;
+
+ wtap_debug("write_section_header_block: Have shb_hdr");
+
+ options_total_length = wtap_optionblock_get_option_write_size(block);
+ if (options_total_length > 0)
+ {
+ /* End-of-options tag */
+ options_total_length += 4;
+ }
+
+ /* write block header */
+ bh.block_type = BLOCK_TYPE_SHB;
+ bh.block_total_length = (guint32)(sizeof(bh) + sizeof(shb) + options_total_length + 4);
+
+ if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
+ return FALSE;
+ wdh->bytes_dumped += sizeof bh;
+
+ /* write block fixed content */
+ shb.magic = 0x1A2B3C4D;
+ shb.version_major = 1;
+ shb.version_minor = 0;
+ shb.section_length = mand_data->section_length;
+
+ if (!wtap_dump_file_write(wdh, &shb, sizeof shb, err))
+ return FALSE;
+ wdh->bytes_dumped += sizeof shb;
+
+ if (!wtap_optionblock_write_options(wdh, block, options_total_length, err))
+ return FALSE;
+
+ /* write block footer */
+ if (!wtap_dump_file_write(wdh, &bh.block_total_length,
+ sizeof bh.block_total_length, err))
+ return FALSE;
+ wdh->bytes_dumped += sizeof bh.block_total_length;
+
+ return TRUE;
}
static void shb_copy_mand(wtap_optionblock_t dest_block, wtap_optionblock_t src_block)
@@ -445,25 +659,101 @@ static void shb_copy_mand(wtap_optionblock_t dest_block, wtap_optionblock_t src_
static void nrb_create(wtap_optionblock_t block)
{
+ static wtap_optblock_reg_t comment_option = {"opt_comment", "Optional comment", WTAP_OPTTYPE_STRING, wtap_opttype_write_size_string, wtap_opttype_write_data_string, {0}, {0}};
+
+ /* Set proper values for the union */
+ comment_option.option.stringval = NULL;
+ comment_option.default_val.stringval = NULL;
+
block->mandatory_data = NULL;
- block->options = g_array_new(FALSE, FALSE, sizeof(wtap_opttype_t*));
- wtap_optionblock_add_option_string(block, OPT_COMMENT, "opt_comment", "Optional comment", NULL, NULL);
+ wtap_optionblock_add_option(block, OPT_COMMENT, &comment_option);
}
static void isb_create(wtap_optionblock_t block)
{
+ static wtap_optblock_reg_t comment_option = {"opt_comment", "Optional comment", WTAP_OPTTYPE_STRING, wtap_opttype_write_size_string, wtap_opttype_write_data_string, {0}, {0}};
+ static wtap_optblock_reg_t starttime_option = {"start_time", "Start Time", WTAP_OPTTYPE_UINT64, wtap_opttype_write_uint64_not0, wtap_opttype_write_data_uint64, {0}, {0}};
+ static wtap_optblock_reg_t endtime_option = {"end_time", "End Time", WTAP_OPTTYPE_UINT64, wtap_opttype_write_uint64_not0, wtap_opttype_write_data_uint64, {0}, {0}};
+ static wtap_optblock_reg_t rcv_pkt_option = {"recv", "Receive Packets", WTAP_OPTTYPE_UINT64, wtap_opttype_write_uint64_not_minus1, wtap_opttype_write_data_uint64, {0}, {0}};
+ static wtap_optblock_reg_t drop_pkt_option = {"drop", "Dropped Packets", WTAP_OPTTYPE_UINT64, wtap_opttype_write_uint64_not_minus1, wtap_opttype_write_data_uint64, {0}, {0}};
+ static wtap_optblock_reg_t filteraccept_option = {"filter_accept", "Filter Accept", WTAP_OPTTYPE_UINT64, wtap_opttype_write_uint64_not_minus1, wtap_opttype_write_data_uint64, {0}, {0}};
+ static wtap_optblock_reg_t os_drop_option = {"os_drop", "OS Dropped Packets", WTAP_OPTTYPE_UINT64, wtap_opttype_write_uint64_not_minus1, wtap_opttype_write_data_uint64, {0}, {0}};
+ static wtap_optblock_reg_t user_deliv_option = {"user_deliv", "User Delivery", WTAP_OPTTYPE_UINT64, wtap_opttype_write_uint64_not_minus1, wtap_opttype_write_data_uint64, {0}, {0}};
+
block->mandatory_data = g_new0(wtapng_if_stats_mandatory_t, 1);
- block->options = g_array_new(FALSE, FALSE, sizeof(wtap_opttype_t*));
- wtap_optionblock_add_option_string(block, OPT_COMMENT, "opt_comment", "Optional comment", NULL, NULL);
- wtap_optionblock_add_option_uint64(block, OPT_ISB_STARTTIME, "start_time", "Start Time", 0, 0);
- wtap_optionblock_add_option_uint64(block, OPT_ISB_ENDTIME, "end_time", "End Time", 0, 0);
- wtap_optionblock_add_option_uint64(block, OPT_ISB_IFRECV, "recv", "Receive Packets", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
- wtap_optionblock_add_option_uint64(block, OPT_ISB_IFDROP, "drop", "Dropped Packets", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
- wtap_optionblock_add_option_uint64(block, OPT_ISB_FILTERACCEPT, "filter_accept", "Filter Accept", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
- wtap_optionblock_add_option_uint64(block, OPT_ISB_OSDROP, "os_drop", "OS Dropped Packets", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
- wtap_optionblock_add_option_uint64(block, OPT_ISB_USRDELIV, "user_deliv", "User Delivery", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
+ /* Set proper values for the union */
+ comment_option.option.stringval = NULL;
+ comment_option.default_val.stringval = NULL;
+ starttime_option.option.uint64val = 0;
+ starttime_option.default_val.uint64val = 0;
+ endtime_option.option.uint64val = 0;
+ endtime_option.default_val.uint64val = 0;
+ rcv_pkt_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
+ rcv_pkt_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
+ drop_pkt_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
+ drop_pkt_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
+ filteraccept_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
+ filteraccept_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
+ os_drop_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
+ os_drop_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
+ user_deliv_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
+ user_deliv_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
+
+ wtap_optionblock_add_option(block, OPT_COMMENT, &comment_option);
+ wtap_optionblock_add_option(block, OPT_ISB_STARTTIME, &starttime_option);
+ wtap_optionblock_add_option(block, OPT_ISB_ENDTIME, &endtime_option);
+ wtap_optionblock_add_option(block, OPT_ISB_IFRECV, &rcv_pkt_option);
+ wtap_optionblock_add_option(block, OPT_ISB_IFDROP, &drop_pkt_option);
+ wtap_optionblock_add_option(block, OPT_ISB_FILTERACCEPT, &filteraccept_option);
+ wtap_optionblock_add_option(block, OPT_ISB_OSDROP, &os_drop_option);
+ wtap_optionblock_add_option(block, OPT_ISB_USRDELIV, &user_deliv_option);
+}
+
+static gboolean isb_write(struct wtap_dumper *wdh, wtap_optionblock_t block, int *err)
+{
+ pcapng_block_header_t bh;
+ pcapng_interface_statistics_block_t isb;
+ guint32 options_total_length;
+ wtapng_if_stats_mandatory_t* mand_data = (wtapng_if_stats_mandatory_t*)block->mandatory_data;
+
+ wtap_debug("write_interface_statistics_block");
+
+ options_total_length = wtap_optionblock_get_option_write_size(block);
+ if (options_total_length > 0)
+ {
+ /* End-of-options tag */
+ options_total_length += 4;
+ }
+
+ /* write block header */
+ bh.block_type = BLOCK_TYPE_ISB;
+ bh.block_total_length = (guint32)(sizeof(bh) + sizeof(isb) + options_total_length + 4);
+
+ if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
+ return FALSE;
+ wdh->bytes_dumped += sizeof bh;
+
+ /* write block fixed content */
+ isb.interface_id = mand_data->interface_id;
+ isb.timestamp_high = mand_data->ts_high;
+ isb.timestamp_low = mand_data->ts_low;
+
+ if (!wtap_dump_file_write(wdh, &isb, sizeof isb, err))
+ return FALSE;
+ wdh->bytes_dumped += sizeof isb;
+
+ if (!wtap_optionblock_write_options(wdh, block, options_total_length, err))
+ return FALSE;
+
+ /* write block footer */
+ if (!wtap_dump_file_write(wdh, &bh.block_total_length,
+ sizeof bh.block_total_length, err))
+ return FALSE;
+ wdh->bytes_dumped += sizeof bh.block_total_length;
+
+ return TRUE;
}
static void isb_copy_mand(wtap_optionblock_t dest_block, wtap_optionblock_t src_block)
@@ -478,22 +768,159 @@ static void idb_filter_free(void* data)
g_free(filter->if_filter_bpf_bytes);
}
+static guint32 idb_filter_write_size(wtap_option_type* data)
+{
+ wtapng_if_descr_filter_t* filter;
+ guint32 size, pad;
+
+ if (data == NULL)
+ return 0;
+
+ filter = (wtapng_if_descr_filter_t*)data->customval.data;
+ if ((filter == NULL) || (filter->if_filter_str == NULL))
+ return 0;
+
+ size = (guint32)(strlen(filter->if_filter_str) + 1) & 0xffff;
+ if ((size % 4)) {
+ pad = 4 - (size % 4);
+ } else {
+ pad = 0;
+ }
+
+ return pad + size;
+}
+
+static gboolean idb_filter_write(struct wtap_dumper* wdh, wtap_option_type* data, int *err)
+{
+ wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)data->customval.data;
+ guint32 size, pad;
+ const guint32 zero_pad = 0;
+
+ size = (guint32)(strlen(filter->if_filter_str) + 1) & 0xffff;
+ if ((size % 4)) {
+ pad = 4 - (size % 4);
+ } else {
+ pad = 0;
+ }
+
+ /* Write the zero indicating libpcap filter variant */
+ if (!wtap_dump_file_write(wdh, &zero_pad, 1, err))
+ return FALSE;
+ wdh->bytes_dumped += 1;
+
+ /* if_filter_str_len includes the leading byte indicating filter type (libpcap str or BPF code) */
+ if (!wtap_dump_file_write(wdh, filter->if_filter_str, size-1, err))
+ return FALSE;
+ wdh->bytes_dumped += size - 1;
+
+ /* write padding (if any) */
+ if (pad != 0) {
+ if (!wtap_dump_file_write(wdh, &zero_pad, pad, err))
+ return FALSE;
+ wdh->bytes_dumped += pad;
+ }
+
+ return TRUE;
+}
+
static void idb_create(wtap_optionblock_t block)
{
+ static wtap_optblock_reg_t comment_option = {"opt_comment", "Optional comment", WTAP_OPTTYPE_STRING, wtap_opttype_write_size_string, wtap_opttype_write_data_string, {0}, {0}};
+ static wtap_optblock_reg_t name_option = {"name", "Device name", WTAP_OPTTYPE_STRING, wtap_opttype_write_size_string, wtap_opttype_write_data_string, {0}, {0}};
+ static wtap_optblock_reg_t description_option = {"description", "Device description", WTAP_OPTTYPE_STRING, wtap_opttype_write_size_string, wtap_opttype_write_data_string, {0}, {0}};
+ static wtap_optblock_reg_t speed_option = {"speed", "Interface speed (in bps)", WTAP_OPTTYPE_UINT64, wtap_opttype_write_uint64_not0, wtap_opttype_write_data_uint64, {0}, {0}};
+ static wtap_optblock_reg_t tsresol_option = {"ts_resolution", "Resolution of timestamps", WTAP_OPTTYPE_UINT8, wtap_opttype_write_uint8_not0, wtap_opttype_write_data_uint8, {0}, {0}};
+ static wtap_optblock_reg_t filter_option = {"filter", "Filter string", WTAP_OPTTYPE_CUSTOM, idb_filter_write_size, idb_filter_write, {0}, {0}};
+ static wtap_optblock_reg_t os_option = {"os", "Operating System", WTAP_OPTTYPE_STRING, wtap_opttype_write_size_string, wtap_opttype_write_data_string, {0}, {0}};
+ static wtap_optblock_reg_t fcslen_option = {"fcslen", "FCS Length", WTAP_OPTTYPE_UINT8, NULL, NULL, {0}, {0}};
+
wtapng_if_descr_filter_t default_filter;
memset(&default_filter, 0, sizeof(default_filter));
block->mandatory_data = g_new0(wtapng_if_descr_mandatory_t, 1);
- block->options = g_array_new(FALSE, FALSE, sizeof(wtap_opttype_t*));
- wtap_optionblock_add_option_string(block, OPT_COMMENT, "opt_comment", "Optional comment", NULL, NULL);
- wtap_optionblock_add_option_string(block, OPT_IDB_NAME, "name", "Device name", NULL, NULL);
- wtap_optionblock_add_option_string(block, OPT_IDB_DESCR, "description", "Device description", NULL, NULL);
- wtap_optionblock_add_option_uint64(block, OPT_IDB_SPEED, "speed", "Interface speed (in bps)", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
- wtap_optionblock_add_option_uint8(block, OPT_IDB_TSRESOL, "ts_resolution", "Resolution of timestamps", 6, 6);
- wtap_optionblock_add_option_custom(block, OPT_IDB_FILTER, "filter", "Filter string", &default_filter, &default_filter, sizeof(wtapng_if_descr_filter_t), idb_filter_free);
- wtap_optionblock_add_option_string(block, OPT_IDB_OS, "os", "Operating System", NULL, NULL);
- wtap_optionblock_add_option_uint8(block, OPT_IDB_FCSLEN, "fcslen", "FCS Length", -1, -1);
+ /* Set proper values for the union */
+ comment_option.option.stringval = NULL;
+ comment_option.default_val.stringval = NULL;
+ name_option.option.stringval = NULL;
+ name_option.default_val.stringval = NULL;
+ description_option.option.stringval = NULL;
+ description_option.default_val.stringval = NULL;
+ speed_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
+ speed_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
+ tsresol_option.option.uint8val = 6;
+ tsresol_option.default_val.uint8val = 6;
+ filter_option.option.customval.size = sizeof(wtapng_if_descr_filter_t);
+ filter_option.option.customval.data = &default_filter;
+ filter_option.option.customval.free_func = idb_filter_free;
+ filter_option.default_val.customval.size = sizeof(wtapng_if_descr_filter_t);
+ filter_option.default_val.customval.data = &default_filter;
+ filter_option.default_val.customval.free_func = idb_filter_free;
+ os_option.option.stringval = NULL;
+ os_option.default_val.stringval = NULL;
+ fcslen_option.option.uint8val = -1;
+ fcslen_option.default_val.uint8val = -1;
+
+ wtap_optionblock_add_option(block, OPT_COMMENT, &comment_option);
+ wtap_optionblock_add_option(block, OPT_IDB_NAME, &name_option);
+ wtap_optionblock_add_option(block, OPT_IDB_DESCR, &description_option);
+ wtap_optionblock_add_option(block, OPT_IDB_SPEED, &speed_option);
+ wtap_optionblock_add_option(block, OPT_IDB_TSRESOL, &tsresol_option);
+ wtap_optionblock_add_option(block, OPT_IDB_FILTER, &filter_option);
+ wtap_optionblock_add_option(block, OPT_IDB_OS, &os_option);
+ wtap_optionblock_add_option(block, OPT_IDB_FCSLEN, &fcslen_option);
+}
+
+static gboolean idb_write(struct wtap_dumper *wdh, wtap_optionblock_t block, int *err)
+{
+ pcapng_block_header_t bh;
+ pcapng_interface_description_block_t idb;
+ wtapng_if_descr_mandatory_t* mand_data = (wtapng_if_descr_mandatory_t*)block->mandatory_data;
+ guint32 options_total_length;
+
+ wtap_debug("write_interface_description_block: encap = %d (%s), snaplen = %d",
+ mand_data->link_type,
+ wtap_encap_string(wtap_pcap_encap_to_wtap_encap(mand_data->link_type)),
+ mand_data->snap_len);
+
+ if (mand_data->link_type == (guint16)-1) {
+ *err = WTAP_ERR_UNWRITABLE_ENCAP;
+ return FALSE;
+ }
+
+ options_total_length = wtap_optionblock_get_option_write_size(block);
+ if (options_total_length > 0)
+ {
+ /* End-of-options tag */
+ options_total_length += 4;
+ }
+
+ /* write block header */
+ bh.block_type = BLOCK_TYPE_IDB;
+ bh.block_total_length = (guint32)(sizeof(bh) + sizeof(idb) + options_total_length + 4);
+
+ if (!wtap_dump_file_write(wdh, &bh, sizeof bh, err))
+ return FALSE;
+ wdh->bytes_dumped += sizeof bh;
+
+ /* write block fixed content */
+ idb.linktype = mand_data->link_type;
+ idb.reserved = 0;
+ idb.snaplen = mand_data->snap_len;
+
+ if (!wtap_dump_file_write(wdh, &idb, sizeof idb, err))
+ return FALSE;
+ wdh->bytes_dumped += sizeof idb;
+
+ if (!wtap_optionblock_write_options(wdh, block, options_total_length, err))
+ return FALSE;
+
+ /* write block footer */
+ if (!wtap_dump_file_write(wdh, &bh.block_total_length,
+ sizeof bh.block_total_length, err))
+ return FALSE;
+ wdh->bytes_dumped += sizeof bh.block_total_length;
+ return TRUE;
}
static void idb_free_mand(wtap_optionblock_t block)
@@ -542,6 +969,7 @@ void wtap_opttypes_initialize(void)
"SHB", /* name */
"Section Header Block", /* description */
shb_create, /* create */
+ shb_write, /* write */
NULL, /* free_mand */
shb_copy_mand, /* copy_mand */
};
@@ -550,6 +978,7 @@ void wtap_opttypes_initialize(void)
"NRB", /* name */
"Name Resolution Block", /* description */
nrb_create, /* create */
+ NULL, /* write */
NULL, /* free_mand */
NULL, /* copy_mand */
};
@@ -558,6 +987,7 @@ void wtap_opttypes_initialize(void)
"ISB", /* name */
"Interface Statistics Block", /* description */
isb_create, /* create */
+ isb_write, /* write */
NULL, /* free_mand */
isb_copy_mand, /* copy_mand */
};
@@ -566,6 +996,7 @@ void wtap_opttypes_initialize(void)
"IDB", /* name */
"Interface Description Block", /* description */
idb_create, /* create */
+ idb_write, /* write */
idb_free_mand, /* free_mand */
idb_copy_mand, /* copy_mand */
};
diff --git a/wiretap/wtap_opttypes.h b/wiretap/wtap_opttypes.h
index 7d404f221d..1b686a829c 100644
--- a/wiretap/wtap_opttypes.h
+++ b/wiretap/wtap_opttypes.h
@@ -24,6 +24,9 @@
#include "ws_symbol_export.h"
+struct wtap_optionblock;
+typedef struct wtap_optionblock *wtap_optionblock_t;
+
/* Currently supported option blocks */
typedef enum {
WTAP_OPTION_BLOCK_IF_DESCR = 0,
@@ -57,27 +60,27 @@ struct wtap_opttype_custom
wtap_opttype_free_custom_func free_func;
};
-typedef struct wtap_opttype {
+typedef union {
+ guint8 uint8val;
+ guint64 uint64val;
+ char *stringval;
+ struct wtap_opttype_custom customval;
+} wtap_option_type;
+
+struct wtap_dumper;
+
+typedef guint32 (*wtap_opttype_option_write_size)(wtap_option_type* data); /**< does the option have data worth writing (Ex string option != NULL */
+typedef gboolean (*wtap_opttype_option_write)(struct wtap_dumper* wdh, wtap_option_type* data, int *err); /**< does the option have data worth writing (Ex string option != NULL */
+
+typedef struct wtap_optblock_reg {
const char *name; /**< name of option */
const char *description; /**< human-readable description of option */
- guint number; /**< Option index */
wtap_opttype_e type; /**< type of that option */
- union {
- guint8 uint8val;
- guint64 uint64val;
- char *stringval;
- struct wtap_opttype_custom customval;
- } option; /**< pointer to variable storing the value */
- union {
- guint8 uint8val;
- guint64 uint64val;
- char *stringval;
- struct wtap_opttype_custom customval;
- } default_val; /**< the default value of the option */
-} wtap_opttype_t;
-
-struct wtap_optionblock;
-typedef struct wtap_optionblock *wtap_optionblock_t;
+ wtap_opttype_option_write_size write_size_func; /**< Size of option in file (0 to not write option) */
+ wtap_opttype_option_write write_func; /**< write option data to dumper */
+ wtap_option_type option; /**< pointer to variable storing the value */
+ wtap_option_type default_val; /**< the default value of the option */
+} wtap_optblock_reg_t;
/** Initialize option block types.
*
@@ -111,132 +114,86 @@ WS_DLL_PUBLIC void wtap_optionblock_free(wtap_optionblock_t block);
*/
WS_DLL_PUBLIC void* wtap_optionblock_get_mandatory_data(wtap_optionblock_t block);
-/** Add a string option to the option block
+/** Add an option to the option block
*
* @param[in] block Block to add option
* @param[in] option_id Identifier value for option
- * @param[in] name Name of option
- * @param[in] description Description of option
- * @param[in] opt_value Current value of option
- * @param[in] default_value Default value of option
+ * @param[in] option structure explaining it
* @return 0 if successful
*/
-int wtap_optionblock_add_option_string(wtap_optionblock_t block, guint option_id,
- const char *name, const char *description, char* opt_value, char* default_value);
+int wtap_optionblock_add_option(wtap_optionblock_t block, guint option_id, wtap_optblock_reg_t* option);
/** Set string option value to an option block
*
* @param[in] block Block to add option
* @param[in] option_id Identifier value for option
- * @param[in] opt_value New value of option
+ * @param[in] value New value of option
* @return 0 if successful
*/
-WS_DLL_PUBLIC int wtap_optionblock_set_option_string(wtap_optionblock_t block, guint option_id, char* opt_value);
+WS_DLL_PUBLIC int wtap_optionblock_set_option_string(wtap_optionblock_t block, guint option_id, char* value);
/** Get string option value from an option block
*
* @param[in] block Block to add option
* @param[in] option_id Identifier value for option
- * @param[out] opt_value Returned value of option
+ * @param[out] value Returned value of option
* @return 0 if successful
*/
-WS_DLL_PUBLIC int wtap_optionblock_get_option_string(wtap_optionblock_t block, guint option_id, char** opt_value);
-
-/** Add UINT64 option to the option block
- *
- * @param[in] block Block to add option
- * @param[in] option_id Identifier value for option
- * @param[in] name Name of option
- * @param[in] description Description of option
- * @param[in] opt_value Current value of option
- * @param[in] default_value Default value of option
- * @return 0 if successful
- */
-int wtap_optionblock_add_option_uint64(wtap_optionblock_t block, guint option_id,
- const char *name, const char *description, guint64 opt_value, guint64 default_value);
+WS_DLL_PUBLIC int wtap_optionblock_get_option_string(wtap_optionblock_t block, guint option_id, char** value);
/** Set UINT64 option value to an option block
*
* @param[in] block Block to add option
* @param[in] option_id Identifier value for option
- * @param[in] opt_value New value of option
+ * @param[in] value New value of option
* @return 0 if successful
*/
-WS_DLL_PUBLIC int wtap_optionblock_set_option_uint64(wtap_optionblock_t block, guint option_id, guint64 opt_value);
+WS_DLL_PUBLIC int wtap_optionblock_set_option_uint64(wtap_optionblock_t block, guint option_id, guint64 value);
/** Get UINT64 option value from an option block
*
* @param[in] block Block to add option
* @param[in] option_id Identifier value for option
- * @param[out] opt_value Returned value of option
+ * @param[out] value Returned value of option
* @return 0 if successful
*/
-WS_DLL_PUBLIC int wtap_optionblock_get_option_uint64(wtap_optionblock_t block, guint option_id, guint64* opt_value);
-
-/** Add UINT8 option to the option block
- *
- * @param[in] block Block to add option
- * @param[in] option_id Identifier value for option
- * @param[in] name Name of option
- * @param[in] description Description of option
- * @param[in] opt_value Current value of option
- * @param[in] default_value Default value of option
- * @return 0 if successful
- */
-int wtap_optionblock_add_option_uint8(wtap_optionblock_t block, guint option_id,
- const char *name, const char *description, guint8 opt_value, guint8 default_value);
+WS_DLL_PUBLIC int wtap_optionblock_get_option_uint64(wtap_optionblock_t block, guint option_id, guint64* value);
/** Set UINT8 option value to an option block
*
* @param[in] block Block to add option
* @param[in] option_id Identifier value for option
- * @param[in] opt_value New value of option
+ * @param[in] value New value of option
* @return 0 if successful
*/
-WS_DLL_PUBLIC int wtap_optionblock_set_option_uint8(wtap_optionblock_t block, guint option_id, guint8 opt_value);
+WS_DLL_PUBLIC int wtap_optionblock_set_option_uint8(wtap_optionblock_t block, guint option_id, guint8 value);
/** Get UINT8 option value from an option block
*
* @param[in] block Block to add option
* @param[in] option_id Identifier value for option
- * @param[out] opt_value Returned value of option
- * @return 0 if successful
- */
-WS_DLL_PUBLIC int wtap_optionblock_get_option_uint8(wtap_optionblock_t block, guint option_id, guint8* opt_value);
-
-/** Add a "custom" option to the option block
- *
- * @param[in] block Block to add option
- * @param[in] option_id Identifier value for option
- * @param[in] name Name of option
- * @param[in] description Description of option
- * @param[in] opt_value Current value of option
- * @param[in] default_value Default value of option
- * @param[in] size Size of the option structure
- * @param[in] free_func Function to free to the option structure
+ * @param[out] value Returned value of option
* @return 0 if successful
*/
-int wtap_optionblock_add_option_custom(wtap_optionblock_t block, guint option_id,
- const char *name, const char *description, void* opt_value, void* default_value,
- guint size, wtap_opttype_free_custom_func free_func);
+WS_DLL_PUBLIC int wtap_optionblock_get_option_uint8(wtap_optionblock_t block, guint option_id, guint8* value);
/** Set a "custom" option value to an option block
*
* @param[in] block Block to add option
* @param[in] option_id Identifier value for option
- * @param[in] opt_value New value of option
+ * @param[in] value New value of option
* @return 0 if successful
*/
-WS_DLL_PUBLIC int wtap_optionblock_set_option_custom(wtap_optionblock_t block, guint option_id, void* opt_value);
+WS_DLL_PUBLIC int wtap_optionblock_set_option_custom(wtap_optionblock_t block, guint option_id, void* value);
/** Get a "custom" option value from an option block
*
* @param[in] block Block to add option
* @param[in] option_id Identifier value for option
- * @param[out] opt_value Returned value of option
+ * @param[out] value Returned value of option
* @return 0 if successful
*/
-WS_DLL_PUBLIC int wtap_optionblock_get_option_custom(wtap_optionblock_t block, guint option_id, void** opt_value);
+WS_DLL_PUBLIC int wtap_optionblock_get_option_custom(wtap_optionblock_t block, guint option_id, void** value);
/** Copy an option block to another.
*
@@ -248,5 +205,31 @@ WS_DLL_PUBLIC int wtap_optionblock_get_option_custom(wtap_optionblock_t block, g
*/
void wtap_optionblock_copy_options(wtap_optionblock_t dest_block, wtap_optionblock_t src_block);
+/** Write an option block
+ *
+ * Will write all mandatory data as well as "valid" options
+ *
+ * @param[in] wdh writing assistant
+ * @param[in] block Block to be written
+ * @param[in] err Any errors that occurred
+ * @return TRUE if successful, FALSE will populate err
+ */
+gboolean wtap_optionblock_write(struct wtap_dumper *wdh, wtap_optionblock_t block, int *err);
+
+/* Some utility functions for option types */
+
+guint32 wtap_opttype_write_size_string(wtap_option_type* data);
+gboolean wtap_opttype_write_data_string(struct wtap_dumper* wdh, wtap_option_type* data, int *err);
+
+/* if option value = 0, write size = 0, otherwise 4 */
+guint32 wtap_opttype_write_uint8_not0(wtap_option_type* data);
+gboolean wtap_opttype_write_data_uint8(struct wtap_dumper* wdh, wtap_option_type* data, int *err);
+
+/* if option value = 0, write size = 0, otherwise 8 */
+guint32 wtap_opttype_write_uint64_not0(wtap_option_type* data);
+/* if option value = -1 (0xFFFFFFFFFFFFFFFF), write size = 0, otherwise 8 */
+guint32 wtap_opttype_write_uint64_not_minus1(wtap_option_type* data);
+gboolean wtap_opttype_write_data_uint64(struct wtap_dumper* wdh, wtap_option_type* data, int *err);
+
#endif /* WTAP_OPT_TYPES_H */