Making wiretap option blocks more generic.
authorMichael Mann <mmann78@netscape.net>
Tue, 26 Jan 2016 01:17:21 +0000 (20:17 -0500)
committerMichael Mann <mmann78@netscape.net>
Tue, 23 Feb 2016 00:39:38 +0000 (00:39 +0000)
This was inspired by https://code.wireshark.org/review/9729/, but takes it in a different direction where all options are put into an array, regardless of whether they are "standard" or "custom".  It should be easier to add "custom" options in this design. Some, but not all blocks have been converted.
Descriptions of some of the block options have been moved from wtap.h to pcapng.h as it seems to be the one that implements the description of the blocks.

Also what could be added/refactored is registering block behavior.

Change-Id: I3dffa38f0bb088f98749a4f97a3b7655baa4aa6a
Reviewed-on: https://code.wireshark.org/review/13667
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
26 files changed:
capinfos.c
cfile.c
debian/libwiretap0.symbols
editcap.c
epan/wslua/wslua.h
epan/wslua/wslua_capture_info.c
file.c
reordercap.c
summary.c
tshark.c
ui/gtk/file_import_dlg.c
ui/tap_export_pdu.c
wiretap/CMakeLists.txt
wiretap/Makefile.common
wiretap/erf.c
wiretap/file_access.c
wiretap/lanalyzer.c
wiretap/merge.c
wiretap/nettrace_3gpp_32_423.c
wiretap/pcapng.c
wiretap/pcapng.h
wiretap/wtap-int.h
wiretap/wtap.c
wiretap/wtap.h
wiretap/wtap_opttypes.c [new file with mode: 0644]
wiretap/wtap_opttypes.h [new file with mode: 0644]

index 5a3e2b3f5626ab82d70db148369578eb03db4284..b3b88c8d795be414ea9c5d2bcd827e4df62cd9c7 100644 (file)
@@ -80,6 +80,8 @@
 #include <wsutil/privileges.h>
 #include <wsutil/ws_diag_control.h>
 #include <wsutil/ws_version_info.h>
+#include <wiretap/wtap_opttypes.h>
+#include <wiretap/pcapng.h>
 
 #ifdef HAVE_PLUGINS
 #include <wsutil/plugins.h>
@@ -1039,9 +1041,10 @@ process_cap_file(wtap *wth, const char *filename)
   nstime_t              prev_time;
   gboolean              know_order = FALSE;
   order_t               order = IN_ORDER;
-  const wtapng_section_t *shb_inf;
+  wtap_optionblock_t    shb_inf;
   guint                 i;
   wtapng_iface_descriptions_t *idb_info;
+  char                  *shb_str;
 
   g_assert(wth != NULL);
   g_assert(filename != NULL);
@@ -1072,7 +1075,7 @@ process_cap_file(wtap *wth, const char *filename)
 
   /* get IDB info strings */
   for (i = 0; i < cf_info.num_interfaces; i++) {
-    const wtapng_if_descr_t *if_descr = &g_array_index(idb_info->interface_data, wtapng_if_descr_t, i);
+    const wtap_optionblock_t if_descr = g_array_index(idb_info->interface_data, wtap_optionblock_t, i);
     gchar *s = wtap_get_debug_if_descr(if_descr, 21, "\n");
     g_array_append_val(cf_info.idb_info_strings, s);
   }
@@ -1246,10 +1249,14 @@ process_cap_file(wtap *wth, const char *filename)
   shb_inf = wtap_file_get_shb(wth);
   if (shb_inf) {
     /* opt_comment is always 0-terminated by pcapng_read_section_header_block */
-    cf_info.comment  = g_strdup(shb_inf->opt_comment);
-    cf_info.hardware = g_strdup(shb_inf->shb_hardware);
-    cf_info.os       = g_strdup(shb_inf->shb_os);
-    cf_info.usr_appl = g_strdup(shb_inf->shb_user_appl);
+    wtap_optionblock_get_option_string(shb_inf, OPT_COMMENT, &shb_str);
+    cf_info.comment  = g_strdup(shb_str);
+    wtap_optionblock_get_option_string(shb_inf, OPT_SHB_HARDWARE, &shb_str);
+    cf_info.hardware = g_strdup(shb_str);
+    wtap_optionblock_get_option_string(shb_inf, OPT_SHB_OS, &shb_str);
+    cf_info.os       = g_strdup(shb_str);
+    wtap_optionblock_get_option_string(shb_inf, OPT_SHB_USERAPPL, &shb_str);
+    cf_info.usr_appl = g_strdup(shb_str);
   }
 
   string_replace_newlines(cf_info.comment);
diff --git a/cfile.c b/cfile.c
index 139e4e8221898772d7de2a4a82e3ea0321256f02..e2dafe569cd4fc09f6865d0b06005ef1f0821b05 100644 (file)
--- a/cfile.c
+++ b/cfile.c
@@ -26,6 +26,7 @@
 #include <glib.h>
 
 #include <epan/packet.h>
+#include <wiretap/pcapng.h>
 
 #include "cfile.h"
 
@@ -34,20 +35,23 @@ cap_file_get_interface_name(void *data, guint32 interface_id)
 {
   capture_file *cf = (capture_file *) data;
   wtapng_iface_descriptions_t *idb_info;
-  const wtapng_if_descr_t *wtapng_if_descr = NULL;
+  wtap_optionblock_t wtapng_if_descr = NULL;
+  char* interface_name;
 
   idb_info = wtap_file_get_idb_info(cf->wth);
 
   if (interface_id < idb_info->interface_data->len)
-    wtapng_if_descr = &g_array_index(idb_info->interface_data, wtapng_if_descr_t, interface_id);
+    wtapng_if_descr = g_array_index(idb_info->interface_data, wtap_optionblock_t, interface_id);
 
   g_free(idb_info);
 
   if (wtapng_if_descr) {
-    if (wtapng_if_descr->if_name)
-      return wtapng_if_descr->if_name;
-    else if (wtapng_if_descr->if_description)
-      return wtapng_if_descr->if_description;
+    wtap_optionblock_get_option_string(wtapng_if_descr, OPT_IDB_NAME, &interface_name);
+    if (interface_name)
+      return interface_name;
+    wtap_optionblock_get_option_string(wtapng_if_descr, OPT_IDB_DESCR, &interface_name);
+    if (interface_name)
+      return interface_name;
   }
   return "unknown";
 }
index 070dac92ef8d3092a6be743e8bc224e1ef853fa7..2c7ff4a8d0376fa1dbd93cfbd7ade82f69cfb058 100644 (file)
@@ -62,8 +62,6 @@ libwiretap.so.0 libwiretap0 #MINVER#
  wtap_file_type_subtype_string@Base 1.12.0~rc1
  wtap_free_extensions_list@Base 1.9.1
  wtap_free_idb_info@Base 1.99.9
- wtap_free_nrb@Base 1.99.9
- wtap_free_shb@Base 1.99.9
  wtap_fstat@Base 1.9.1
  wtap_get_all_file_extensions_list@Base 1.12.0~rc1
  wtap_get_bytes_dumped@Base 1.9.1
@@ -79,6 +77,17 @@ libwiretap.so.0 libwiretap0 #MINVER#
  wtap_has_open_info@Base 1.12.0~rc1
  wtap_iscompressed@Base 1.9.1
  wtap_open_offline@Base 1.9.1
+ wtap_optionblock_create@Base 2.1.0
+ wtap_optionblock_free@Base 2.1.0
+ wtap_optionblock_get_mandatory_data@Base 2.1.0
+ wtap_optionblock_get_option_custom@Base 2.1.0
+ wtap_optionblock_get_option_string@Base 2.1.0
+ wtap_optionblock_get_option_uint8@Base 2.1.0
+ wtap_optionblock_get_option_uint64@Base 2.1.0
+ wtap_optionblock_set_option_custom@Base 2.1.0
+ wtap_optionblock_set_option_string@Base 2.1.0
+ wtap_optionblock_set_option_uint8@Base 2.1.0
+ wtap_optionblock_set_option_uint64@Base 2.1.0
  wtap_pcap_encap_to_wtap_encap@Base 1.9.1
  wtap_phdr@Base 1.9.1
  wtap_phdr_cleanup@Base 1.99.2
index fdb80c8d09a3d3a398e76e79ae156cf67b91d57e..d6c2392c561604202a19adfb594a771f2485c9db 100644 (file)
--- a/editcap.c
+++ b/editcap.c
@@ -89,6 +89,8 @@
 #include <wsutil/str_util.h>
 #include <wsutil/ws_diag_control.h>
 #include <wsutil/ws_version_info.h>
+#include <wiretap/wtap_opttypes.h>
+#include <wiretap/pcapng.h>
 
 #include "ringbuffer.h" /* For RINGBUFFER_MAX_NUM_FILES */
 
@@ -936,9 +938,9 @@ get_editcap_runtime_info(GString *str)
 
 static wtap_dumper *
 editcap_dump_open(const char *filename, guint32 snaplen,
-                  wtapng_section_t *shb_hdr,
+                  wtap_optionblock_t shb_hdr,
                   wtapng_iface_descriptions_t *idb_inf,
-                  wtapng_name_res_t *nrb_hdr, int *write_err)
+                  wtap_optionblock_t nrb_hdr, int *write_err)
 {
   wtap_dumper *pdh;
 
@@ -998,8 +1000,9 @@ main(int argc, char *argv[])
     const struct wtap_pkthdr    *phdr;
     struct wtap_pkthdr           temp_phdr;
     wtapng_iface_descriptions_t *idb_inf = NULL;
-    wtapng_section_t            *shb_hdr = NULL;
-    wtapng_name_res_t           *nrb_hdr = NULL;
+    wtap_optionblock_t           shb_hdr = NULL;
+    wtap_optionblock_t           nrb_hdr = NULL;
+    char                        *shb_user_appl;
 
 #ifdef HAVE_PLUGINS
     char* init_progfile_dir_error;
@@ -1410,8 +1413,11 @@ main(int argc, char *argv[])
                 g_assert(filename);
 
                 /* If we don't have an application name add Editcap */
-                if (shb_hdr->shb_user_appl == NULL) {
-                    shb_hdr->shb_user_appl = g_strdup("Editcap " VERSION);
+                wtap_optionblock_get_option_string(shb_hdr, OPT_SHB_USERAPPL, &shb_user_appl);
+                if (shb_user_appl == NULL) {
+                    shb_user_appl = g_strdup("Editcap " VERSION);
+                    wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_USERAPPL, shb_user_appl);
+                    g_free(shb_user_appl);
                 }
 
                 pdh = editcap_dump_open(filename,
@@ -1873,9 +1879,9 @@ main(int argc, char *argv[])
                     wtap_strerror(write_err));
             goto error_on_exit;
         }
-        wtap_free_shb(shb_hdr);
+        wtap_optionblock_free(shb_hdr);
         shb_hdr = NULL;
-        wtap_free_nrb(nrb_hdr);
+        wtap_optionblock_free(nrb_hdr);
         nrb_hdr = NULL;
         g_free(filename);
 
@@ -1899,8 +1905,8 @@ main(int argc, char *argv[])
     return 0;
 
 error_on_exit:
-    wtap_free_shb(shb_hdr);
-    wtap_free_nrb(nrb_hdr);
+    wtap_optionblock_free(shb_hdr);
+    wtap_optionblock_free(nrb_hdr);
     g_free(idb_inf);
     exit(2);
 }
index 75b67967ed8a3fc6466bde1d09f5fca4095fc7f8..5239f21fe75accb246422feb1fd9df2692e5d64e 100644 (file)
@@ -554,6 +554,12 @@ extern int wslua_set__index(lua_State *L);
 #define WSLUA_ATTRIBUTE_STRING_GETTER(C,member) \
     WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(C,member,member)
 
+#define WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_GETTER(C,name,member,option) \
+    WSLUA_ATTRIBUTE_GET(C,name, { \
+        char* str;  \
+        wtap_optionblock_get_option_string(obj->member, option, &str); \
+        lua_pushstring(L,str); /* this pushes nil if obj->member is null */ \
+    })
 
 #define WSLUA_ATTRIBUTE_SET(C,name,block) \
     static int C##_set_##name (lua_State* L) { \
@@ -603,6 +609,21 @@ extern int wslua_set__index(lua_State *L);
 #define WSLUA_ATTRIBUTE_STRING_SETTER(C,field,need_free) \
     WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(C,field,field,need_free)
 
+#define WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_SETTER(C,field,member,option) \
+    static int C##_set_##field (lua_State* L) { \
+        C obj = check##C (L,1); \
+        gchar* s = NULL; \
+        if (lua_isstring(L,-1) || lua_isnil(L,-1)) { \
+            s = g_strdup(lua_tostring(L,-1)); \
+        } else { \
+            return luaL_error(L, "%s's attribute `%s' must be a string or nil", #C , #field ); \
+        } \
+        wtap_optionblock_set_option_string(obj->member, option, s); \
+        return 0; \
+    } \
+    /* silly little trick so we can add a semicolon after this macro */ \
+    typedef void __dummy##C##_set_##field
+
 #define WSLUA_ERROR(name,error) { luaL_error(L, "%s%s", #name ": " ,error); }
 #define WSLUA_ARG_ERROR(name,attr,error) { luaL_argerror(L,WSLUA_ARG_ ## name ## _ ## attr, #name  ": " error); }
 #define WSLUA_OPTARG_ERROR(name,attr,error) { luaL_argerror(L,WSLUA_OPTARG_##name##_ ##attr, #name  ": " error); }
index 7a4ca96341c2bf8d40b0afa48bac15378210ebce..ddba06d792996a8f89e3f5cb1cf973dd6877ba9b 100644 (file)
@@ -28,6 +28,7 @@
 #include "wslua_file_common.h"
 
 #include <epan/addr_resolv.h>
+#include <wiretap/pcapng.h>
 
 
 /* WSLUA_CONTINUE_MODULE File */
@@ -111,23 +112,23 @@ WSLUA_ATTRIBUTE_NAMED_NUMBER_SETTER(CaptureInfo,snapshot_length,wth->snapshot_le
 
 /* WSLUA_ATTRIBUTE CaptureInfo_comment RW A string comment for the whole capture file,
     or nil if there is no `comment`. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfo,comment,wth->shb_hdr.opt_comment);
-WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(CaptureInfo,comment,wth->shb_hdr.opt_comment,TRUE);
+WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_GETTER(CaptureInfo,comment,wth->shb_hdr,OPT_COMMENT);
+WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_SETTER(CaptureInfo,comment,wth->shb_hdr,OPT_COMMENT);
 
 /* WSLUA_ATTRIBUTE CaptureInfo_hardware RW A string containing the description of
     the hardware used to create the capture, or nil if there is no `hardware` string. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfo,hardware,wth->shb_hdr.shb_hardware);
-WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(CaptureInfo,hardware,wth->shb_hdr.shb_hardware,TRUE);
+WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_GETTER(CaptureInfo,hardware,wth->shb_hdr,OPT_SHB_HARDWARE);
+WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_SETTER(CaptureInfo,hardware,wth->shb_hdr,OPT_SHB_HARDWARE);
 
 /* WSLUA_ATTRIBUTE CaptureInfo_os RW A string containing the name of
     the operating system used to create the capture, or nil if there is no `os` string. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfo,os,wth->shb_hdr.shb_os);
-WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(CaptureInfo,os,wth->shb_hdr.shb_os,TRUE);
+WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_GETTER(CaptureInfo,os,wth->shb_hdr,OPT_SHB_OS);
+WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_SETTER(CaptureInfo,os,wth->shb_hdr,OPT_SHB_OS);
 
 /* WSLUA_ATTRIBUTE CaptureInfo_user_app RW A string containing the name of
     the application used to create the capture, or nil if there is no `user_app` string. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfo,user_app,wth->shb_hdr.shb_user_appl);
-WSLUA_ATTRIBUTE_NAMED_STRING_SETTER(CaptureInfo,user_app,wth->shb_hdr.shb_user_appl,TRUE);
+WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_GETTER(CaptureInfo,user_app,wth->shb_hdr,OPT_SHB_USERAPPL);
+WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_SETTER(CaptureInfo,user_app,wth->shb_hdr,OPT_SHB_USERAPPL);
 
 /* WSLUA_ATTRIBUTE CaptureInfo_hosts WO Sets resolved ip-to-hostname information.
 
@@ -354,19 +355,19 @@ WSLUA_ATTRIBUTE_NAMED_NUMBER_GETTER(CaptureInfoConst,encap,wdh->encap);
 
 /* WSLUA_ATTRIBUTE CaptureInfoConst_comment RW A comment for the whole capture file, if the
     `wtap_presence_flags.COMMENTS` was set in the presence flags; nil if there is no comment. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfoConst,comment,wth->shb_hdr.opt_comment);
+WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_GETTER(CaptureInfoConst,comment,wth->shb_hdr,OPT_COMMENT);
 
 /* WSLUA_ATTRIBUTE CaptureInfoConst_hardware RO A string containing the description of
     the hardware used to create the capture, or nil if there is no hardware string. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfoConst,hardware,wth->shb_hdr.shb_hardware);
+WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_GETTER(CaptureInfoConst,hardware,wth->shb_hdr,OPT_SHB_HARDWARE);
 
 /* WSLUA_ATTRIBUTE CaptureInfoConst_os RO A string containing the name of
     the operating system used to create the capture, or nil if there is no os string. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfoConst,os,wth->shb_hdr.shb_os);
+WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_GETTER(CaptureInfoConst,os,wth->shb_hdr,OPT_SHB_OS);
 
 /* WSLUA_ATTRIBUTE CaptureInfoConst_user_app RO A string containing the name of
     the application used to create the capture, or nil if there is no user_app string. */
-WSLUA_ATTRIBUTE_NAMED_STRING_GETTER(CaptureInfoConst,user_app,wth->shb_hdr.shb_user_appl);
+WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_GETTER(CaptureInfoConst,user_app,wth->shb_hdr,OPT_SHB_USERAPPL);
 
 /* WSLUA_ATTRIBUTE CaptureInfoConst_hosts RO A ip-to-hostname Lua table of two key-ed names: `ipv4_addresses` and `ipv6_addresses`.
     The value of each of these names are themselves array tables, of key-ed tables, such that the inner table has a key
diff --git a/file.c b/file.c
index 10290dd2c8e2ad211f84a9c40857bb6679e4c3f3..1a2e3932f8849c9b90d722731b3e4efc5f3b0bb6 100644 (file)
--- a/file.c
+++ b/file.c
@@ -4475,9 +4475,9 @@ cf_save_records(capture_file *cf, const char *fname, guint save_format,
        or moving the capture file, we have to do it by writing the packets
        out in Wiretap. */
 
-    wtapng_section_t            *shb_hdr = NULL;
+    wtap_optionblock_t           shb_hdr = NULL;
     wtapng_iface_descriptions_t *idb_inf = NULL;
-    wtapng_name_res_t           *nrb_hdr = NULL;
+    wtap_optionblock_t           nrb_hdr = NULL;
     int encap;
 
     /* XXX: what free's this shb_hdr? */
@@ -4698,9 +4698,9 @@ cf_export_specified_packets(capture_file *cf, const char *fname,
   int                          err;
   wtap_dumper                 *pdh;
   save_callback_args_t         callback_args;
-  wtapng_section_t            *shb_hdr = NULL;
+  wtap_optionblock_t           shb_hdr = NULL;
   wtapng_iface_descriptions_t *idb_inf = NULL;
-  wtapng_name_res_t           *nrb_hdr = NULL;
+  wtap_optionblock_t           nrb_hdr = NULL;
   int                          encap;
 
   cf_callback_invoke(cf_cb_file_export_specified_packets_started, (gpointer)fname);
index b96b214b1a87e377e6eff5f87002de06de91b5c4..0c29ea59c804c16d970d6fa4054dd9855311e20c 100644 (file)
@@ -46,6 +46,7 @@
 #include <wsutil/file_util.h>
 #include <wsutil/ws_diag_control.h>
 #include <wsutil/ws_version_info.h>
+#include <wiretap/wtap_opttypes.h>
 
 /* Show command-line usage */
 static void
@@ -187,9 +188,9 @@ main(int argc, char *argv[])
     guint wrong_order_count = 0;
     gboolean write_output_regardless = TRUE;
     guint i;
-    wtapng_section_t            *shb_hdr = NULL;
+    wtap_optionblock_t           shb_hdr = NULL;
     wtapng_iface_descriptions_t *idb_inf = NULL;
-    wtapng_name_res_t           *nrb_hdr = NULL;
+    wtap_optionblock_t           nrb_hdr = NULL;
 
     GPtrArray *frames;
     FrameRecord_t *prevFrame = NULL;
@@ -287,8 +288,8 @@ main(int argc, char *argv[])
     if (pdh == NULL) {
         fprintf(stderr, "reordercap: Failed to open output file: (%s) - error %s\n",
                 outfile, wtap_strerror(err));
-        wtap_free_shb(shb_hdr);
-        wtap_free_nrb(nrb_hdr);
+        wtap_optionblock_free(shb_hdr);
+        wtap_optionblock_free(nrb_hdr);
         exit(1);
     }
 
@@ -361,12 +362,12 @@ main(int argc, char *argv[])
     if (!wtap_dump_close(pdh, &err)) {
         fprintf(stderr, "reordercap: Error closing %s: %s\n", outfile,
                 wtap_strerror(err));
-        wtap_free_shb(shb_hdr);
-        wtap_free_nrb(nrb_hdr);
+        wtap_optionblock_free(shb_hdr);
+        wtap_optionblock_free(nrb_hdr);
         exit(1);
     }
-    wtap_free_shb(shb_hdr);
-    wtap_free_nrb(nrb_hdr);
+    wtap_optionblock_free(shb_hdr);
+    wtap_optionblock_free(nrb_hdr);
 
     /* Finally, close infile */
     wtap_fdclose(wth);
index 4bcfe16d147d81af17b0e1d159acff9b55212f77..cf9026e7679b97cfbe74149d91ad6e8653b77709 100644 (file)
--- a/summary.c
+++ b/summary.c
@@ -23,6 +23,8 @@
 #include <config.h>
 
 #include <wiretap/pcap-encap.h>
+#include <wiretap/wtap_opttypes.h>
+#include <wiretap/pcapng.h>
 
 #include <epan/packet.h>
 #include "cfile.h"
@@ -105,12 +107,16 @@ summary_fill_in(capture_file *cf, summary_tally *st)
 {
   frame_data    *first_frame, *cur_frame;
   guint32        framenum;
-  const wtapng_section_t* shb_inf;
+  wtap_optionblock_t shb_inf;
   iface_options iface;
   guint i;
   wtapng_iface_descriptions_t* idb_info;
-  wtapng_if_descr_t wtapng_if_descr;
-  wtapng_if_stats_t *if_stats;
+  wtap_optionblock_t wtapng_if_descr;
+  wtapng_if_descr_mandatory_t *wtapng_if_descr_mand;
+  wtap_optionblock_t if_stats;
+  guint64 isb_ifdrop;
+  char* if_string;
+  wtapng_if_descr_filter_t* if_filter;
 
   st->packet_count_ts = 0;
   st->start_time = 0;
@@ -163,34 +169,39 @@ summary_fill_in(capture_file *cf, summary_tally *st)
     st->shb_os         = NULL;
     st->shb_user_appl  = NULL;
   }else{
-    st->opt_comment    = shb_inf->opt_comment;
-    st->shb_hardware   = shb_inf->shb_hardware;
-    st->shb_os         = shb_inf->shb_os;
-    st->shb_user_appl  = shb_inf->shb_user_appl;
+    wtap_optionblock_get_option_string(shb_inf, OPT_COMMENT, &st->opt_comment);
+    wtap_optionblock_get_option_string(shb_inf, OPT_SHB_HARDWARE, &st->shb_hardware);
+    wtap_optionblock_get_option_string(shb_inf, OPT_SHB_OS, &st->shb_os);
+    wtap_optionblock_get_option_string(shb_inf, OPT_SHB_USERAPPL, (char**)&st->shb_user_appl);
   }
 
   st->ifaces  = g_array_new(FALSE, FALSE, sizeof(iface_options));
   idb_info = wtap_file_get_idb_info(cf->wth);
   for (i = 0; i < idb_info->interface_data->len; i++) {
-    wtapng_if_descr = g_array_index(idb_info->interface_data, wtapng_if_descr_t, i);
-    iface.cfilter = g_strdup(wtapng_if_descr.if_filter_str);
-    iface.name = g_strdup(wtapng_if_descr.if_name);
-    iface.descr = g_strdup(wtapng_if_descr.if_description);
+    wtapng_if_descr = g_array_index(idb_info->interface_data, wtap_optionblock_t, i);
+    wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(wtapng_if_descr);
+    wtap_optionblock_get_option_custom(wtapng_if_descr, OPT_IDB_FILTER, (void**)&if_filter);
+    iface.cfilter = g_strdup(if_filter->if_filter_str);
+    wtap_optionblock_get_option_string(wtapng_if_descr, OPT_IDB_NAME, &if_string);
+    iface.name = g_strdup(if_string);
+    wtap_optionblock_get_option_string(wtapng_if_descr, OPT_IDB_DESCR, &if_string);
+    iface.descr = g_strdup(if_string);
     iface.drops_known = FALSE;
     iface.drops = 0;
-    iface.snap = wtapng_if_descr.snap_len;
+    iface.snap = wtapng_if_descr_mand->snap_len;
     iface.has_snap = (iface.snap != 65535);
-    iface.encap_type = wtapng_if_descr.wtap_encap;
+    iface.encap_type = wtapng_if_descr_mand->wtap_encap;
     iface.isb_comment = NULL;
-    if(wtapng_if_descr.num_stat_entries == 1){
+    if(wtapng_if_descr_mand->num_stat_entries == 1){
       /* dumpcap only writes one ISB, only handle that for now */
-      if_stats = &g_array_index(wtapng_if_descr.interface_statistics, wtapng_if_stats_t, 0);
-      if (if_stats->isb_ifdrop != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
+      if_stats = g_array_index(wtapng_if_descr_mand->interface_statistics, wtap_optionblock_t, 0);
+      wtap_optionblock_get_option_uint64(if_stats, OPT_ISB_IFDROP, &isb_ifdrop);
+      if (isb_ifdrop != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
         iface.drops_known = TRUE;
-        iface.drops = if_stats->isb_ifdrop;
+        iface.drops = isb_ifdrop;
       }
       /* XXX: this doesn't get used, and might need to be g_strdup'ed when it does */
-      iface.isb_comment = if_stats->opt_comment;
+      wtap_optionblock_get_option_string(if_stats, OPT_COMMENT, &iface.isb_comment);
     }
     g_array_append_val(st->ifaces, iface);
   }
index 786afe8371dfe2a0ae8a955606b7c1a570f070f2..75489e605d036d019979c547e1b91475196e71d3 100644 (file)
--- a/tshark.c
+++ b/tshark.c
@@ -67,6 +67,8 @@
 #include <wsutil/report_err.h>
 #include <wsutil/ws_diag_control.h>
 #include <wsutil/ws_version_info.h>
+#include <wiretap/wtap_opttypes.h>
+#include <wiretap/pcapng.h>
 
 #include "globals.h"
 #include <epan/timestamp.h>
@@ -3170,12 +3172,13 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
   char        *save_file_string = NULL;
   gboolean     filtering_tap_listeners;
   guint        tap_flags;
-  wtapng_section_t            *shb_hdr = NULL;
+  wtap_optionblock_t           shb_hdr = NULL;
   wtapng_iface_descriptions_t *idb_inf = NULL;
-  wtapng_name_res_t           *nrb_hdr = NULL;
+  wtap_optionblock_t           nrb_hdr = NULL;
   struct wtap_pkthdr phdr;
   Buffer       buf;
   epan_dissect_t *edt = NULL;
+  char                        *shb_user_appl;
 
   wtap_phdr_init(&phdr);
 
@@ -3205,9 +3208,12 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
     nrb_hdr = wtap_file_get_nrb_for_new_file(cf->wth);
 
     /* If we don't have an application name add Tshark */
-    if (shb_hdr->shb_user_appl == NULL) {
-        /* this is free'd by wtap_free_shb() later */
-        shb_hdr->shb_user_appl = g_strdup_printf("TShark (Wireshark) %s", get_ws_vcs_version_info());
+    wtap_optionblock_get_option_string(shb_hdr, OPT_SHB_USERAPPL, &shb_user_appl);
+    if (shb_user_appl == NULL) {
+        /* this is free'd by wtap_optionblock_free() later */
+        shb_user_appl = g_strdup_printf("TShark (Wireshark) %s", get_ws_vcs_version_info());
+        wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_USERAPPL, shb_user_appl);
+        g_free(shb_user_appl);
     }
 
     if (linktype != WTAP_ENCAP_PER_PACKET &&
@@ -3448,8 +3454,8 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
                 break;
               }
               wtap_dump_close(pdh, &err);
-              wtap_free_shb(shb_hdr);
-              wtap_free_nrb(nrb_hdr);
+              wtap_optionblock_free(shb_hdr);
+              wtap_optionblock_free(nrb_hdr);
               exit(2);
             }
           }
@@ -3563,8 +3569,8 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type,
               break;
             }
             wtap_dump_close(pdh, &err);
-            wtap_free_shb(shb_hdr);
-            wtap_free_nrb(nrb_hdr);
+            wtap_optionblock_free(shb_hdr);
+            wtap_optionblock_free(nrb_hdr);
             exit(2);
           }
         }
@@ -3680,8 +3686,8 @@ out:
   cf->wth = NULL;
 
   g_free(save_file_string);
-  wtap_free_shb(shb_hdr);
-  wtap_free_nrb(nrb_hdr);
+  wtap_optionblock_free(shb_hdr);
+  wtap_optionblock_free(nrb_hdr);
 
   return err;
 }
index 86248d73fa054c275c8303bd99f4c25311598dd3..3378d1beaf0a33ac9e410e0be88c73a579cb7a41 100644 (file)
@@ -48,6 +48,8 @@
 #include "wsutil/tempfile.h"
 #include "wsutil/os_version_info.h"
 #include "wsutil/ws_version_info.h"
+#include "wiretap/wtap_opttypes.h"
+#include "wiretap/pcapng.h"
 
 #define INPUT_FRM_KEY                   "input_frame"
 
@@ -456,57 +458,49 @@ file_import_open(text_import_info_t *info)
     int   err;
 
     /* pcapng defs */
-    wtapng_section_t            *shb_hdr;
+    wtap_optionblock_t           shb_hdr;
     wtapng_iface_descriptions_t *idb_inf;
-    wtapng_if_descr_t            int_data;
+    wtap_optionblock_t           int_data;
+    wtapng_if_descr_mandatory_t *int_data_mand;
     GString                     *os_info_str;
+    gchar                       *opt_comment, *wireshark_ver;
 
     /* Create data for SHB  */
     os_info_str = g_string_new("");
     get_os_version_info(os_info_str);
 
-    shb_hdr = g_new(wtapng_section_t,1);
-    shb_hdr->section_length = -1;
+    shb_hdr = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION);
+
     /* options */
-    shb_hdr->opt_comment    = g_strdup_printf("File created by File->Import of file %s", info->import_text_filename);
-    /*
-     * UTF-8 string containing the description of the hardware used to create
-     * this section.
-     */
-    shb_hdr->shb_hardware   = NULL;
+    opt_comment = g_strdup_printf("File created by File->Import of file %s", info->import_text_filename);
+    wtap_optionblock_set_option_string(shb_hdr, OPT_COMMENT, opt_comment);
+    g_free(opt_comment);
+
     /*
      * UTF-8 string containing the name of the operating system used to create
      * this section.
      */
-    shb_hdr->shb_os         = g_string_free(os_info_str, FALSE);
+    wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_OS, g_string_free(os_info_str, TRUE));
     /*
      * UTF-8 string containing the name of the application used to create
      * this section.
      */
-    shb_hdr->shb_user_appl  = g_strdup_printf("Wireshark %s", get_ws_vcs_version_info());
-
+    wireshark_ver = g_strdup_printf("Wireshark %s", get_ws_vcs_version_info());
+    wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_USERAPPL, wireshark_ver);
+    g_free(wireshark_ver);
 
     /* Create fake IDB info */
     idb_inf = g_new(wtapng_iface_descriptions_t,1);
-    idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
+    idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
 
     /* create the fake interface data */
-    int_data.wtap_encap            = info->encapsulation;
-    int_data.time_units_per_second = 1000000; /* default microsecond resolution */
-    int_data.link_type             = wtap_wtap_encap_to_pcap_encap(info->encapsulation);
-    int_data.snap_len              = WTAP_MAX_PACKET_SIZE;
-    int_data.if_name               = g_strdup("Fake IF File->Import");
-    int_data.opt_comment           = NULL;
-    int_data.if_description        = NULL;
-    int_data.if_speed              = 0;
-    int_data.if_tsresol            = 6;
-    int_data.if_filter_str         = NULL;
-    int_data.bpf_filter_len        = 0;
-    int_data.if_filter_bpf_bytes   = NULL;
-    int_data.if_os                 = NULL;
-    int_data.if_fcslen             = -1;
-    int_data.num_stat_entries      = 0;          /* Number of ISB:s */
-    int_data.interface_statistics  = NULL;
+    int_data = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
+    int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data);
+    int_data_mand->wtap_encap            = info->encapsulation;
+    int_data_mand->time_units_per_second = 1000000; /* default microsecond resolution */
+    int_data_mand->link_type             = wtap_wtap_encap_to_pcap_encap(info->encapsulation);
+    int_data_mand->snap_len              = WTAP_MAX_PACKET_SIZE;
+    wtap_optionblock_set_option_string(int_data, OPT_IDB_NAME, "Fake IF File->Import");
 
     g_array_append_val(idb_inf->interface_data, int_data);
 
@@ -565,7 +559,7 @@ end:
     g_free(info->date_timestamp_format);
     g_free(info);
     g_free(capfile_name);
-    wtap_free_shb(shb_hdr);
+    wtap_optionblock_free(shb_hdr);
     wtap_free_idb_info(idb_inf);
     window_destroy(file_import_dlg_w);
 }
index a7b92788defd00c79c431701b449561295f41bac..e0b2a9fc3c36050e91425133c5f45a30ccc4f3bf 100644 (file)
@@ -32,6 +32,8 @@
 #include <epan/tap.h>
 #include <epan/exported_pdu.h>
 #include <epan/epan_dissect.h>
+#include <wiretap/wtap_opttypes.h>
+#include <wiretap/pcapng.h>
 
 #include "ui/alert_box.h"
 #include "ui/simple_dialog.h"
@@ -102,56 +104,51 @@ exp_pdu_file_open(exp_pdu_t *exp_pdu_tap_data)
     int   err;
 
     /* pcapng defs */
-    wtapng_section_t            *shb_hdr;
+    wtap_optionblock_t           shb_hdr;
     wtapng_iface_descriptions_t *idb_inf;
-    wtapng_if_descr_t            int_data;
+    wtap_optionblock_t           int_data;
+    wtapng_if_descr_mandatory_t *int_data_mand;
     GString                     *os_info_str;
+    gchar                       *opt_comment, *wireshark_ver;
 
     /* Create data for SHB  */
     os_info_str = g_string_new("");
     get_os_version_info(os_info_str);
 
-    shb_hdr = g_new0(wtapng_section_t,1);
-    shb_hdr->section_length = -1;
+    shb_hdr = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION);
+
     /* options */
-    shb_hdr->opt_comment    = g_strdup_printf("Dump of PDUs from %s", cfile.filename);
-    /*
-     * UTF-8 string containing the description of the hardware used to create
-     * this section.
-     */
-    shb_hdr->shb_hardware   = NULL;
+    opt_comment = g_strdup_printf("Dump of PDUs from %s", cfile.filename);
+    wtap_optionblock_set_option_string(shb_hdr, OPT_COMMENT, opt_comment);
+    g_free(opt_comment);
+
     /*
      * UTF-8 string containing the name of the operating system used to create
      * this section.
      */
-    shb_hdr->shb_os         = g_string_free(os_info_str, FALSE);
+    wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_OS, g_string_free(os_info_str, TRUE));
     /*
      * UTF-8 string containing the name of the application used to create
      * this section.
      */
-    shb_hdr->shb_user_appl  = g_strdup_printf("Wireshark %s", get_ws_vcs_version_info());
+    wireshark_ver = g_strdup_printf("Wireshark %s", get_ws_vcs_version_info());
+    wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_USERAPPL, wireshark_ver);
+    g_free(wireshark_ver);
 
     /* Create fake IDB info */
     idb_inf = g_new(wtapng_iface_descriptions_t,1);
-    idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
+    idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
 
     /* create the fake interface data */
-    int_data.wtap_encap            = WTAP_ENCAP_WIRESHARK_UPPER_PDU;
-    int_data.time_units_per_second = 1000000000; /* default nanosecond resolution */
-    int_data.link_type             = wtap_wtap_encap_to_pcap_encap(WTAP_ENCAP_WIRESHARK_UPPER_PDU);
-    int_data.snap_len              = WTAP_MAX_PACKET_SIZE;
-    int_data.if_name               = g_strdup("Fake IF, PDU->Export");
-    int_data.opt_comment           = NULL;
-    int_data.if_description        = NULL;
-    int_data.if_speed              = 0;
-    int_data.if_tsresol            = 9;
-    int_data.if_filter_str         = NULL;
-    int_data.bpf_filter_len        = 0;
-    int_data.if_filter_bpf_bytes   = NULL;
-    int_data.if_os                 = NULL;
-    int_data.if_fcslen             = -1;
-    int_data.num_stat_entries      = 0;          /* Number of ISB:s */
-    int_data.interface_statistics  = NULL;
+    int_data = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
+    int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data);
+    int_data_mand->wtap_encap      = WTAP_ENCAP_WIRESHARK_UPPER_PDU;
+    int_data_mand->time_units_per_second = 1000000000; /* default nanosecond resolution */
+    int_data_mand->link_type       = wtap_wtap_encap_to_pcap_encap(WTAP_ENCAP_WIRESHARK_UPPER_PDU);
+    int_data_mand->snap_len        = WTAP_MAX_PACKET_SIZE;
+
+    wtap_optionblock_set_option_string(int_data, OPT_IDB_NAME, "Fake IF, PDU->Export");
+    wtap_optionblock_set_option_uint8(int_data, OPT_IDB_TSRESOL, 9);
 
     g_array_append_val(idb_inf->interface_data, int_data);
 
@@ -200,7 +197,7 @@ exp_pdu_file_open(exp_pdu_t *exp_pdu_tap_data)
 
 end:
     g_free(capfile_name);
-    wtap_free_shb(shb_hdr);
+    wtap_optionblock_free(shb_hdr);
     wtap_free_idb_info(idb_inf);
 }
 
index e3eb20aa6fdcb6ea9751bf4395dc95775099f9a9..080b7edc131d0e397f4405cae6c7ea0e8a70ebf9 100644 (file)
@@ -79,6 +79,7 @@ set(WIRETAP_FILES
        vms.c
        vwr.c
        wtap.c
+       wtap_opttypes.c
 )
 
 if (WERROR_COMMON_FLAGS)
index 02c12145b29b36ca117ced8e25d91d1e7668b1d9..43bcfc39f003aca87a7bb65a26e78933ecee2f69 100644 (file)
@@ -83,7 +83,8 @@ NONGENERATED_C_FILES = \
        visual.c                \
        vms.c                   \
        vwr.c           \
-       wtap.c
+       wtap.c                  \
+       wtap_opttypes.c
 
 # Header files that are not generated from other files
 NONGENERATED_HEADER_FILES = \
@@ -147,6 +148,7 @@ NONGENERATED_HEADER_FILES = \
        vms.h                   \
        vwr.h           \
        wtap.h                  \
+       wtap_opttypes.h \
        wtap-int.h
 
 # Files that generate compileable files
index f2e5f9d409fb6535360f3a4413ec37e52baeeceb..bfe8b74361c1bff58746ca5cad04817f41f8dfdd 100644 (file)
@@ -53,6 +53,7 @@
 #include "wtap-int.h"
 #include "file_wrappers.h"
 #include "pcap-encap.h"
+#include "pcapng.h"
 #include "erf.h"
 
 static gboolean erf_read_header(FILE_T fh,
@@ -751,42 +752,47 @@ int erf_dump_open(wtap_dumper *wdh, int *err)
 
 int erf_populate_interfaces(wtap *wth)
 {
-  wtapng_if_descr_t int_data;
+  wtap_optionblock_t int_data;
+  wtapng_if_descr_mandatory_t* int_data_mand;
   int i;
+  char* tmp;
 
   if (!wth)
     return -1;
 
-  memset(&int_data, 0, sizeof(int_data)); /* Zero all fields */
-
-  int_data.wtap_encap = WTAP_ENCAP_ERF;
-  /* int_data.time_units_per_second = (1LL<<32);  ERF format resolution is 2^-32, capture resolution is unknown */
-  int_data.time_units_per_second = 1000000000; /* XXX Since Wireshark only supports down to nanosecond resolution we have to dilute to this */
-  int_data.link_type = wtap_wtap_encap_to_pcap_encap(WTAP_ENCAP_ERF);
-  int_data.snap_len = 65535; /* ERF max length */
-  int_data.opt_comment = NULL;
-  /* XXX: if_IPv4addr opt 4  Interface network address and netmask.*/
-  /* XXX: if_IPv6addr opt 5  Interface network address and prefix length (stored in the last byte).*/
-  /* XXX: if_MACaddr  opt 6  Interface Hardware MAC address (48 bits).*/
-  /* XXX: if_EUIaddr  opt 7  Interface Hardware EUI address (64 bits)*/
-  int_data.if_speed = 0; /* Unknown */
-  /* int_data.if_tsresol = 0xa0;  ERF format resolution is 2^-32 = 0xa0, capture resolution is unknown */
-  int_data.if_tsresol = 0x09; /* XXX Since Wireshark only supports down to nanosecond resolution we have to dilute to this */
-  /* XXX: if_tzone      10  Time zone for GMT support (TODO: specify better). */
-  int_data.if_filter_str = NULL;
-  int_data.bpf_filter_len = 0;
-  int_data.if_filter_bpf_bytes = NULL;
-  int_data.if_os = NULL;
-  int_data.if_fcslen = 0; /* unknown! */
-  /* XXX if_tsoffset; opt 14  A 64 bits integer value that specifies an offset (in seconds)...*/
-  /* Interface statistics */
-  int_data.num_stat_entries = 0;
-  int_data.interface_statistics = NULL;
-
   /* Preemptively create interface entries for 4 interfaces, since this is the max number in ERF */
   for (i=0; i<4; i++) {
-    int_data.if_name = g_strdup_printf("Port %c", 'A'+i);
-    int_data.if_description = g_strdup_printf("ERF Interface Id %d (Port %c)", i, 'A'+i);
+
+    int_data = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
+    int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data);
+
+    int_data_mand->wtap_encap = WTAP_ENCAP_ERF;
+    /* int_data.time_units_per_second = (1LL<<32);  ERF format resolution is 2^-32, capture resolution is unknown */
+    int_data_mand->time_units_per_second = 1000000000; /* XXX Since Wireshark only supports down to nanosecond resolution we have to dilute to this */
+    int_data_mand->link_type = wtap_wtap_encap_to_pcap_encap(WTAP_ENCAP_ERF);
+    int_data_mand->snap_len = 65535; /* ERF max length */
+
+    /* XXX: if_IPv4addr opt 4  Interface network address and netmask.*/
+    /* XXX: if_IPv6addr opt 5  Interface network address and prefix length (stored in the last byte).*/
+    /* XXX: if_MACaddr  opt 6  Interface Hardware MAC address (48 bits).*/
+    /* XXX: if_EUIaddr  opt 7  Interface Hardware EUI address (64 bits)*/
+    wtap_optionblock_set_option_uint64(int_data, OPT_IDB_SPEED, 0); /* Unknown  - XXX should be left at default? */
+    /* int_data.if_tsresol = 0xa0;  ERF format resolution is 2^-32 = 0xa0, capture resolution is unknown */
+    wtap_optionblock_set_option_uint8(int_data, OPT_IDB_TSRESOL, 0x09); /* XXX Since Wireshark only supports down to nanosecond resolution we have to dilute to this */
+
+    /* XXX: if_tzone      10  Time zone for GMT support (TODO: specify better). */
+
+    /* XXX if_tsoffset; opt 14  A 64 bits integer value that specifies an offset (in seconds)...*/
+    /* Interface statistics */
+    int_data_mand->num_stat_entries = 0;
+    int_data_mand->interface_statistics = NULL;
+
+    tmp = g_strdup_printf("Port %c", 'A'+i);
+    wtap_optionblock_set_option_string(int_data, OPT_IDB_NAME, tmp);
+    g_free(tmp);
+    tmp = g_strdup_printf("ERF Interface Id %d (Port %c)", i, 'A'+i);
+    wtap_optionblock_set_option_string(int_data, OPT_IDB_DESCR, tmp);
+    g_free(tmp);
 
     g_array_append_val(wth->interface_data, int_data);
   }
index 0daed2b419349b535887073ef3bad8335a2b631b..4e755fff689825efab7bfa97cac78a839a08e1ac 100644 (file)
@@ -818,11 +818,12 @@ wtap_open_offline(const char *filename, unsigned int type, int *err, char **err_
        wth->file_tsprec = WTAP_TSPREC_USEC;
        wth->priv = NULL;
        wth->wslua_data = NULL;
+       wth->shb_hdr = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION);
 
        /* Initialize the array containing a list of interfaces. pcapng_open and
         * erf_open needs this (and libpcap_open for ERF encapsulation types).
         * Always initing it here saves checking for a NULL ptr later. */
-       wth->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
+       wth->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
 
        if (wth->random_fh) {
                wth->fast_seek = g_ptr_array_new();
@@ -1083,31 +1084,24 @@ success:
        if ((wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP) ||
                (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC)) {
 
-               wtapng_if_descr_t descr;
+               wtap_optionblock_t descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
+               wtapng_if_descr_mandatory_t* descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
 
-               descr.wtap_encap = wth->file_encap;
+               descr_mand->wtap_encap = wth->file_encap;
                if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC) {
-                       descr.time_units_per_second = 1000000000; /* nanosecond resolution */
-                       descr.if_tsresol = 9;
-                       descr.tsprecision = WTAP_TSPREC_NSEC;
+                       descr_mand->time_units_per_second = 1000000000; /* nanosecond resolution */
+                       wtap_optionblock_set_option_uint8(descr, OPT_IDB_TSRESOL, 9);
+                       descr_mand->tsprecision = WTAP_TSPREC_NSEC;
                } else {
-                       descr.time_units_per_second = 1000000; /* default microsecond resolution */
-                       descr.if_tsresol = 6;
-                       descr.tsprecision = WTAP_TSPREC_USEC;
+                       descr_mand->time_units_per_second = 1000000; /* default microsecond resolution */
+                       wtap_optionblock_set_option_uint8(descr, OPT_IDB_TSRESOL, 6);
+                       descr_mand->tsprecision = WTAP_TSPREC_USEC;
                }
-               descr.link_type = wtap_wtap_encap_to_pcap_encap(wth->file_encap);
-               descr.snap_len = wth->snapshot_length;
-               descr.opt_comment = NULL;
-               descr.if_name = NULL;
-               descr.if_description = NULL;
-               descr.if_speed = 0;
-               descr.if_filter_str= NULL;
-               descr.bpf_filter_len= 0;
-               descr.if_filter_bpf_bytes= NULL;
-               descr.if_os = NULL;
-               descr.if_fcslen = -1;
-               descr.num_stat_entries = 0;          /* Number of ISB:s */
-               descr.interface_statistics = NULL;
+               descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(wth->file_encap);
+               descr_mand->snap_len = wth->snapshot_length;
+
+               descr_mand->num_stat_entries = 0;          /* Number of ISB:s */
+               descr_mand->interface_statistics = NULL;
                g_array_append_val(wth->interface_data, descr);
 
        }
@@ -2144,11 +2138,12 @@ static int wtap_dump_file_close(wtap_dumper *wdh);
 
 static wtap_dumper *
 wtap_dump_init_dumper(int file_type_subtype, int encap, int snaplen, gboolean compressed,
-                      wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf,
-                      wtapng_name_res_t *nrb_hdr, int *err)
+                      wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+                      wtap_optionblock_t nrb_hdr, int *err)
 {
        wtap_dumper *wdh;
-       wtapng_if_descr_t descr, *file_int_data;
+       wtap_optionblock_t descr, file_int_data;
+       wtapng_if_descr_mandatory_t *descr_mand, *file_int_data_mand;
 
        /* Check whether we can open a capture file with that file type
           and that encapsulation. */
@@ -2169,37 +2164,31 @@ wtap_dump_init_dumper(int file_type_subtype, int encap, int snaplen, gboolean co
                guint itf_count;
 
                /* XXX: what free's this stuff? */
-               wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
+               wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
                for (itf_count = 0; itf_count < idb_inf->interface_data->len; itf_count++) {
-                       file_int_data = &g_array_index(idb_inf->interface_data, wtapng_if_descr_t, itf_count);
-                       if ((encap != WTAP_ENCAP_PER_PACKET) && (encap != file_int_data->wtap_encap)) {
-                               /* XXX: this does a shallow copy, not a true clone; e.g., comments are not duped */
-                               memcpy(&descr, file_int_data, sizeof(wtapng_if_descr_t));
-                               descr.wtap_encap = encap;
-                               descr.link_type = wtap_wtap_encap_to_pcap_encap(encap);
-                               g_array_append_val(wdh->interface_data, descr);
-                       } else {
-                               g_array_append_val(wdh->interface_data, *file_int_data);
+                       file_int_data = g_array_index(idb_inf->interface_data, wtap_optionblock_t, itf_count);
+                       file_int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(file_int_data);
+                       descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
+                       wtap_optionblock_copy_options(descr, file_int_data);
+                       if ((encap != WTAP_ENCAP_PER_PACKET) && (encap != file_int_data_mand->wtap_encap)) {
+                               descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
+                               descr_mand->wtap_encap = encap;
+                               descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(encap);
                        }
+                       g_array_append_val(wdh->interface_data, descr);
                }
        } else {
-               descr.wtap_encap = encap;
-               descr.time_units_per_second = 1000000; /* default microsecond resolution */
-               descr.link_type = wtap_wtap_encap_to_pcap_encap(encap);
-               descr.snap_len = snaplen;
-               descr.opt_comment = NULL;
-               descr.if_name = g_strdup("Unknown/not available in original file format(libpcap)");
-               descr.if_description = NULL;
-               descr.if_speed = 0;
-               descr.if_tsresol = 6;
-               descr.if_filter_str= NULL;
-               descr.bpf_filter_len= 0;
-               descr.if_filter_bpf_bytes= NULL;
-               descr.if_os = NULL;
-               descr.if_fcslen = -1;
-               descr.num_stat_entries = 0;          /* Number of ISB:s */
-               descr.interface_statistics = NULL;
-               wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
+               descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
+               descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr);
+               descr_mand->wtap_encap = encap;
+               descr_mand->time_units_per_second = 1000000; /* default microsecond resolution */
+               descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(encap);
+               descr_mand->snap_len = snaplen;
+               wtap_optionblock_set_option_string(descr, OPT_IDB_NAME, "Unknown/not available in original file format(libpcap)");
+
+               descr_mand->num_stat_entries = 0;          /* Number of ISB:s */
+               descr_mand->interface_statistics = NULL;
+               wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
                g_array_append_val(wdh->interface_data, descr);
        }
        return wdh;
@@ -2214,8 +2203,8 @@ wtap_dump_open(const char *filename, int file_type_subtype, int encap,
 
 wtap_dumper *
 wtap_dump_open_ng(const char *filename, int file_type_subtype, int encap,
-                 int snaplen, gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf,
-                 wtapng_name_res_t *nrb_hdr, int *err)
+                 int snaplen, gboolean compressed, wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+                 wtap_optionblock_t nrb_hdr, int *err)
 {
        wtap_dumper *wdh;
        WFILE_T fh;
@@ -2260,9 +2249,9 @@ wtap_dumper *
 wtap_dump_open_tempfile_ng(char **filenamep, const char *pfx,
                           int file_type_subtype, int encap,
                           int snaplen, gboolean compressed,
-                          wtapng_section_t *shb_hdr,
+                          wtap_optionblock_t shb_hdr,
                           wtapng_iface_descriptions_t *idb_inf,
-                          wtapng_name_res_t *nrb_hdr, int *err)
+                          wtap_optionblock_t nrb_hdr, int *err)
 {
        int fd;
        char *tmpname;
@@ -2319,8 +2308,8 @@ wtap_dump_fdopen(int fd, int file_type_subtype, int encap, int snaplen,
 
 wtap_dumper *
 wtap_dump_fdopen_ng(int fd, int file_type_subtype, int encap, int snaplen,
-                   gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf,
-                   wtapng_name_res_t *nrb_hdr, int *err)
+                   gboolean compressed, wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+                   wtap_optionblock_t nrb_hdr, int *err)
 {
        wtap_dumper *wdh;
        WFILE_T fh;
@@ -2359,9 +2348,9 @@ wtap_dump_open_stdout(int file_type_subtype, int encap, int snaplen,
 
 wtap_dumper *
 wtap_dump_open_stdout_ng(int file_type_subtype, int encap, int snaplen,
-                        gboolean compressed, wtapng_section_t *shb_hdr,
+                        gboolean compressed, wtap_optionblock_t shb_hdr,
                         wtapng_iface_descriptions_t *idb_inf,
-                        wtapng_name_res_t *nrb_hdr, int *err)
+                        wtap_optionblock_t nrb_hdr, int *err)
 {
        wtap_dumper *wdh;
        WFILE_T fh;
index 50ce3339e083ddd791a25d1a7a2d87ebd4071936..8f9fd0f63bd3d8411b75966a23e563955639f250 100644 (file)
@@ -24,6 +24,7 @@
 #include "wtap-int.h"
 #include "file_wrappers.h"
 #include "lanalyzer.h"
+#include "pcapng.h"
 
 /* The LANalyzer format is documented (at least in part) in Novell document
    TID022037, which can be found at, among other places:
@@ -327,7 +328,7 @@ wtap_open_return_val lanalyzer_open(wtap *wth, int *err, gchar **err_info)
                   return WTAP_OPEN_NOT_MINE;
             }
             comment[record_length] = '\0';
-            wth->shb_hdr.opt_comment = comment;
+            wtap_optionblock_set_option_string(wth->shb_hdr, OPT_COMMENT, comment);
       }
 
       /* If we made it this far, then the file is a LANAlyzer file.
index b4e1438b0e9adc65b39162698dd7f3c3417566d3..f2e92e384a5cafadd7785ffd60a9b054d3105156 100644 (file)
@@ -35,6 +35,8 @@
 
 #include <string.h>
 #include "merge.h"
+#include "wtap_opttypes.h"
+#include "pcapng.h"
 
 #include <wsutil/filesystem.h>
 #include "wsutil/os_version_info.h"
@@ -358,14 +360,16 @@ merge_append_read_packet(int in_file_count, merge_in_file_t in_files[],
 
 
 /* creates a section header block for the new output file */
-static wtapng_section_t*
+static wtap_optionblock_t
 create_shb_header(const merge_in_file_t *in_files, const guint in_file_count,
                   const gchar *app_name)
 {
-    wtapng_section_t *shb_hdr = NULL;
+    wtap_optionblock_t shb_hdr;
     GString *comment_gstr;
     GString *os_info_str;
     guint i;
+    char* shb_comment = NULL;
+    wtapng_mandatory_section_t* shb_data;
 
     shb_hdr = wtap_file_get_shb_for_new_file(in_files[0].wth);
 
@@ -373,12 +377,12 @@ create_shb_header(const merge_in_file_t *in_files, const guint in_file_count,
 
     /* TODO: merge comments from all files */
 
+    wtap_optionblock_get_option_string(shb_hdr, OPT_COMMENT, &shb_comment);
+
     /* very lame way to save comments - does not save them from the other files */
-    if (shb_hdr->opt_comment && strlen(shb_hdr->opt_comment) > 0) {
-        g_string_append_printf(comment_gstr, "%s \n",shb_hdr->opt_comment);
+    if (shb_comment && strlen(shb_comment) > 0) {
+        g_string_append_printf(comment_gstr, "%s \n",shb_comment);
     }
-    g_free(shb_hdr->opt_comment);
-    shb_hdr->opt_comment = NULL;
 
     g_string_append_printf(comment_gstr, "File created by merging: \n");
 
@@ -389,65 +393,97 @@ create_shb_header(const merge_in_file_t *in_files, const guint in_file_count,
     os_info_str = g_string_new("");
     get_os_version_info(os_info_str);
 
-    shb_hdr->section_length = -1;
+    shb_data = (wtapng_mandatory_section_t*)wtap_optionblock_get_mandatory_data(shb_hdr);
+    shb_data->section_length = -1;
     /* TODO: handle comments from each file being merged */
-    shb_hdr->opt_comment   = g_string_free(comment_gstr, FALSE);  /* section comment */
-    shb_hdr->shb_hardware  = NULL;        /* NULL if not available, UTF-8 string containing the        */
-                                          /*  description of the hardware used to create this section. */
-    shb_hdr->shb_os        = g_string_free(os_info_str, FALSE); /* UTF-8 string containing the name   */
-                                          /*  of the operating system used to create this section.     */
-    shb_hdr->shb_user_appl = g_strdup(app_name); /* NULL if not available, UTF-8 string containing the name */
-                                          /*  of the application used to create this section.          */
+    wtap_optionblock_set_option_string(shb_hdr, OPT_COMMENT, g_string_free(comment_gstr, TRUE)); /* section comment */
+    wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_HARDWARE, NULL ); /* NULL if not available, UTF-8 string containing the        */
+                                                                                      /*  description of the hardware used to create this section. */
+
+    wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_OS, g_string_free(os_info_str, TRUE)); /* UTF-8 string containing the name   */
+                                                                                                            /*  of the operating system used to create this section.     */
+    wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_USERAPPL, (char*)app_name ); /* NULL if not available, UTF-8 string containing the name */
+                                                                                      /*  of the application used to create this section.          */
 
     return shb_hdr;
 }
 
 static gboolean
-is_duplicate_idb(const wtapng_if_descr_t *idb1, const wtapng_if_descr_t *idb2)
+is_duplicate_idb(const wtap_optionblock_t idb1, const wtap_optionblock_t idb2)
 {
+    wtapng_if_descr_mandatory_t *idb1_mand, *idb2_mand;
+    guint64 idb1_if_speed, idb2_if_speed;
+    guint8 idb1_if_tsresol, idb2_if_tsresol;
+    guint8 idb1_if_fcslen, idb2_if_fcslen;
+    char *idb1_opt_comment, *idb2_opt_comment, *idb1_if_name, *idb2_if_name,
+         *idb1_if_description, *idb2_if_description, *idb1_if_os, *idb2_if_os;
+
     g_assert(idb1 && idb2);
+    idb1_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(idb1);
+    idb2_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(idb2);
 
     merge_debug("merge::is_duplicate_idb() called");
-    merge_debug("idb1->wtap_encap == idb2->wtap_encap: %s",
-                 (idb1->wtap_encap == idb2->wtap_encap) ? "TRUE":"FALSE");
-    merge_debug("idb1->time_units_per_second == idb2->time_units_per_second: %s",
-                 (idb1->time_units_per_second == idb2->time_units_per_second) ? "TRUE":"FALSE");
-    merge_debug("idb1->tsprecision == idb2->tsprecision: %s",
-                 (idb1->tsprecision == idb2->tsprecision) ? "TRUE":"FALSE");
-    merge_debug("idb1->link_type == idb2->link_type: %s",
-                 (idb1->link_type == idb2->link_type) ? "TRUE":"FALSE");
-    merge_debug("idb1->snap_len == idb2->snap_len: %s",
-                 (idb1->snap_len == idb2->snap_len) ? "TRUE":"FALSE");
-    merge_debug("idb1->if_speed == idb2->if_speed: %s",
-                 (idb1->if_speed == idb2->if_speed) ? "TRUE":"FALSE");
-    merge_debug("idb1->if_tsresol == idb2->if_tsresol: %s",
-                 (idb1->if_tsresol == idb2->if_tsresol) ? "TRUE":"FALSE");
-    merge_debug("idb1->if_fcslen == idb2->if_fcslen: %s",
-                 (idb1->if_fcslen == idb2->if_fcslen) ? "TRUE":"FALSE");
-    merge_debug("g_strcmp0(idb1->opt_comment, idb2->opt_comment) == 0: %s",
-                 (g_strcmp0(idb1->opt_comment, idb2->opt_comment) == 0) ? "TRUE":"FALSE");
-    merge_debug("g_strcmp0(idb1->if_name, idb2->if_name) == 0: %s",
-                 (g_strcmp0(idb1->if_name, idb2->if_name) == 0) ? "TRUE":"FALSE");
-    merge_debug("g_strcmp0(idb1->if_description, idb2->if_description) == 0: %s",
-                 (g_strcmp0(idb1->if_description, idb2->if_description) == 0) ? "TRUE":"FALSE");
-    merge_debug("g_strcmp0(idb1->if_os, idb2->if_os) == 0: %s",
-                 (g_strcmp0(idb1->if_os, idb2->if_os) == 0) ? "TRUE":"FALSE");
+    merge_debug("idb1_mand->wtap_encap == idb2_mand->wtap_encap: %s",
+                 (idb1_mand->wtap_encap == idb2_mand->wtap_encap) ? "TRUE":"FALSE");
+    merge_debug("idb1_mand->time_units_per_second == idb2_mand->time_units_per_second: %s",
+                 (idb1_mand->time_units_per_second == idb2_mand->time_units_per_second) ? "TRUE":"FALSE");
+    merge_debug("idb1_mand->tsprecision == idb2_mand->tsprecision: %s",
+                 (idb1_mand->tsprecision == idb2_mand->tsprecision) ? "TRUE":"FALSE");
+    merge_debug("idb1_mand->link_type == idb2_mand->link_type: %s",
+                 (idb1_mand->link_type == idb2_mand->link_type) ? "TRUE":"FALSE");
+    merge_debug("idb1_mand->snap_len == idb2_mand->snap_len: %s",
+                 (idb1_mand->snap_len == idb2_mand->snap_len) ? "TRUE":"FALSE");
+
+    wtap_optionblock_get_option_uint64(idb1, OPT_IDB_SPEED, &idb1_if_speed);
+    wtap_optionblock_get_option_uint64(idb2, OPT_IDB_SPEED, &idb2_if_speed);
+    merge_debug("idb1_if_speed == idb2_if_speed: %s",
+                 (idb1_if_speed == idb2_if_speed) ? "TRUE":"FALSE");
+
+    wtap_optionblock_get_option_uint8(idb1, OPT_IDB_TSRESOL, &idb1_if_tsresol);
+    wtap_optionblock_get_option_uint8(idb2, OPT_IDB_TSRESOL, &idb2_if_tsresol);
+    merge_debug("idb1_if_tsresol == idb2_if_tsresol: %s",
+                 (idb1_if_tsresol == idb2_if_tsresol) ? "TRUE":"FALSE");
+
+    wtap_optionblock_get_option_uint8(idb1, OPT_IDB_FCSLEN, &idb1_if_fcslen);
+    wtap_optionblock_get_option_uint8(idb2, OPT_IDB_FCSLEN, &idb2_if_fcslen);
+    merge_debug("idb1_if_fcslen == idb2_if_fcslen: %s",
+                 (idb1_if_fcslen == idb2_if_fcslen) ? "TRUE":"FALSE");
+
+    wtap_optionblock_get_option_string(idb1, OPT_COMMENT, &idb1_opt_comment);
+    wtap_optionblock_get_option_string(idb2, OPT_COMMENT, &idb2_opt_comment);
+    merge_debug("g_strcmp0(idb1_opt_comment, idb2_opt_comment) == 0: %s",
+                 (g_strcmp0(idb1_opt_comment, idb2_opt_comment) == 0) ? "TRUE":"FALSE");
+
+    wtap_optionblock_get_option_string(idb1, OPT_IDB_NAME, &idb1_if_name);
+    wtap_optionblock_get_option_string(idb2, OPT_IDB_NAME, &idb2_if_name);
+    merge_debug("g_strcmp0(idb1_if_name, idb2_if_name) == 0: %s",
+                 (g_strcmp0(idb1_if_name, idb2_if_name) == 0) ? "TRUE":"FALSE");
+
+    wtap_optionblock_get_option_string(idb1, OPT_IDB_DESCR, &idb1_if_description);
+    wtap_optionblock_get_option_string(idb2, OPT_IDB_DESCR, &idb2_if_description);
+    merge_debug("g_strcmp0(idb1_if_description, idb2_if_description) == 0: %s",
+                 (g_strcmp0(idb1_if_description, idb2_if_description) == 0) ? "TRUE":"FALSE");
+
+    wtap_optionblock_get_option_string(idb1, OPT_IDB_OS, &idb1_if_os);
+    wtap_optionblock_get_option_string(idb2, OPT_IDB_OS, &idb2_if_os);
+    merge_debug("g_strcmp0(idb1_if_os, idb2_if_os) == 0: %s",
+                 (g_strcmp0(idb1_if_os, idb2_if_os) == 0) ? "TRUE":"FALSE");
     merge_debug("merge::is_duplicate_idb() returning");
 
     /* does not compare filters nor interface statistics */
-    return (idb1->wtap_encap == idb2->wtap_encap &&
-            idb1->time_units_per_second == idb2->time_units_per_second &&
-            idb1->tsprecision == idb2->tsprecision &&
-            idb1->link_type == idb2->link_type &&
+    return (idb1_mand->wtap_encap == idb2_mand->wtap_encap &&
+            idb1_mand->time_units_per_second == idb2_mand->time_units_per_second &&
+            idb1_mand->tsprecision == idb2_mand->tsprecision &&
+            idb1_mand->link_type == idb2_mand->link_type &&
             /* XXX: should snaplen not be compared? */
-            idb1->snap_len == idb2->snap_len &&
-            idb1->if_speed == idb2->if_speed &&
-            idb1->if_tsresol == idb2->if_tsresol &&
-            idb1->if_fcslen == idb2->if_fcslen &&
-            g_strcmp0(idb1->opt_comment, idb2->opt_comment) == 0 &&
-            g_strcmp0(idb1->if_name, idb2->if_name) == 0 &&
-            g_strcmp0(idb1->if_description, idb2->if_description) == 0 &&
-            g_strcmp0(idb1->if_os, idb2->if_os) == 0);
+            idb1_mand->snap_len == idb2_mand->snap_len &&
+            idb1_if_speed == idb2_if_speed &&
+            idb1_if_tsresol == idb2_if_tsresol &&
+            idb1_if_fcslen == idb2_if_fcslen &&
+            g_strcmp0(idb1_opt_comment, idb2_opt_comment) == 0 &&
+            g_strcmp0(idb1_if_name, idb2_if_name) == 0 &&
+            g_strcmp0(idb1_if_description, idb2_if_description) == 0 &&
+            g_strcmp0(idb1_if_os, idb2_if_os) == 0);
 }
 
 /*
@@ -459,7 +495,7 @@ all_idbs_are_duplicates(const merge_in_file_t *in_files, const guint in_file_cou
     wtapng_iface_descriptions_t *first_idb_list = NULL;
     wtapng_iface_descriptions_t *other_idb_list = NULL;
     guint first_idb_list_size, other_idb_list_size;
-    const wtapng_if_descr_t *first_file_idb, *other_file_idb;
+    wtap_optionblock_t first_file_idb, other_file_idb;
     guint i, j;
 
     g_assert(in_files != NULL);
@@ -485,8 +521,8 @@ all_idbs_are_duplicates(const merge_in_file_t *in_files, const guint in_file_cou
         }
 
         for (j = 0; j < other_idb_list_size; j++) {
-            first_file_idb = &g_array_index(first_idb_list->interface_data, wtapng_if_descr_t, j);
-            other_file_idb = &g_array_index(other_idb_list->interface_data, wtapng_if_descr_t, j);
+            first_file_idb = g_array_index(first_idb_list->interface_data, wtap_optionblock_t, j);
+            other_file_idb = g_array_index(other_idb_list->interface_data, wtap_optionblock_t, j);
 
             if (!is_duplicate_idb(first_file_idb, other_file_idb)) {
                 merge_debug("merge::all_idbs_are_duplicates: IDBs at index %d do not match, returning FALSE", j);
@@ -515,11 +551,11 @@ all_idbs_are_duplicates(const merge_in_file_t *in_files, const guint in_file_cou
  * own (same) input file.
  */
 static gboolean
-find_duplicate_idb(const wtapng_if_descr_t *input_file_idb,
+find_duplicate_idb(const wtap_optionblock_t input_file_idb,
                const wtapng_iface_descriptions_t *merged_idb_list,
                guint *found_index)
 {
-    const wtapng_if_descr_t *merged_idb;
+    wtap_optionblock_t merged_idb;
     guint i;
 
     g_assert(input_file_idb != NULL);
@@ -528,7 +564,7 @@ find_duplicate_idb(const wtapng_if_descr_t *input_file_idb,
     g_assert(found_index != NULL);
 
     for (i = 0; i < merged_idb_list->interface_data->len; i++) {
-        merged_idb = &g_array_index(merged_idb_list->interface_data, wtapng_if_descr_t, i);
+        merged_idb = g_array_index(merged_idb_list->interface_data, wtap_optionblock_t, i);
 
         if (is_duplicate_idb(input_file_idb, merged_idb)) {
             *found_index = i;
@@ -542,31 +578,26 @@ find_duplicate_idb(const wtapng_if_descr_t *input_file_idb,
 /* adds IDB to merged file info, returns its index */
 static guint
 add_idb_to_merged_file(wtapng_iface_descriptions_t *merged_idb_list,
-                       const wtapng_if_descr_t *input_file_idb)
+                       const wtap_optionblock_t input_file_idb)
 {
-    wtapng_if_descr_t idb;
+    wtap_optionblock_t idb = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
+    wtapng_if_descr_mandatory_t* idb_mand;
+    wtapng_if_descr_filter_t if_filter;
+
 
     g_assert(merged_idb_list != NULL);
     g_assert(merged_idb_list->interface_data != NULL);
     g_assert(input_file_idb != NULL);
 
-    idb.wtap_encap            = input_file_idb->wtap_encap;
-    idb.time_units_per_second = input_file_idb->time_units_per_second;
-    idb.tsprecision           = input_file_idb->tsprecision;
-    idb.link_type             = input_file_idb->link_type;
-    idb.snap_len              = input_file_idb->snap_len;
-    idb.if_name               = g_strdup(input_file_idb->if_name);
-    idb.opt_comment           = g_strdup(input_file_idb->opt_comment);;
-    idb.if_description        = g_strdup(input_file_idb->if_description);
-    idb.if_speed              = input_file_idb->if_speed;
-    idb.if_tsresol            = input_file_idb->if_tsresol;
-    idb.if_filter_str         = NULL;
-    idb.bpf_filter_len        = 0;
-    idb.if_filter_bpf_bytes   = NULL;
-    idb.if_os                 = g_strdup(input_file_idb->if_os);
-    idb.if_fcslen             = input_file_idb->if_fcslen;
-    idb.num_stat_entries      = 0;          /* Number of ISB:s */
-    idb.interface_statistics  = NULL;
+    wtap_optionblock_copy_options(idb, input_file_idb);
+    idb_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(idb);
+
+    /* Don't copy filter or stat information */
+    memset(&if_filter, 0, sizeof(if_filter));
+    wtap_optionblock_set_option_custom(idb, OPT_IDB_FILTER, &if_filter);
+
+    idb_mand->num_stat_entries      = 0;          /* Number of ISB:s */
+    idb_mand->interface_statistics  = NULL;
 
     g_array_append_val(merged_idb_list->interface_data, idb);
 
@@ -581,13 +612,13 @@ generate_merged_idb(merge_in_file_t *in_files, const guint in_file_count, const
 {
     wtapng_iface_descriptions_t *merged_idb_list = NULL;
     wtapng_iface_descriptions_t *input_file_idb_list = NULL;
-    const wtapng_if_descr_t     *input_file_idb = NULL;
+    wtap_optionblock_t           input_file_idb;
     guint                        itf_count, merged_index;
     guint                        i;
 
     /* create new IDB info */
     merged_idb_list = g_new(wtapng_iface_descriptions_t,1);
-    merged_idb_list->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
+    merged_idb_list->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
 
     if (mode == IDB_MERGE_MODE_ALL_SAME && all_idbs_are_duplicates(in_files, in_file_count)) {
         guint num_idbs;
@@ -601,8 +632,8 @@ generate_merged_idb(merge_in_file_t *in_files, const guint in_file_count, const
 
         /* put them in the merged file */
         for (itf_count = 0; itf_count < num_idbs; itf_count++) {
-            input_file_idb = &g_array_index(input_file_idb_list->interface_data,
-                                            wtapng_if_descr_t, itf_count);
+            input_file_idb = g_array_index(input_file_idb_list->interface_data,
+                                            wtap_optionblock_t, itf_count);
             merged_index = add_idb_to_merged_file(merged_idb_list, input_file_idb);
             add_idb_index_map(&in_files[0], itf_count, merged_index);
         }
@@ -621,8 +652,8 @@ generate_merged_idb(merge_in_file_t *in_files, const guint in_file_count, const
             input_file_idb_list = wtap_file_get_idb_info(in_files[i].wth);
 
             for (itf_count = 0; itf_count < input_file_idb_list->interface_data->len; itf_count++) {
-                input_file_idb = &g_array_index(input_file_idb_list->interface_data,
-                                                wtapng_if_descr_t, itf_count);
+                input_file_idb = g_array_index(input_file_idb_list->interface_data,
+                                                wtap_optionblock_t, itf_count);
 
                 if (mode == IDB_MERGE_MODE_ANY_SAME &&
                     find_duplicate_idb(input_file_idb, merged_idb_list, &merged_index))
@@ -851,7 +882,7 @@ merge_files(int out_fd, const gchar* out_filename, const int file_type,
     struct wtap_pkthdr *phdr, snap_phdr;
     int                 count = 0;
     gboolean            stop_flag = FALSE;
-    wtapng_section_t            *shb_hdr = NULL;
+    wtap_optionblock_t          shb_hdr = NULL;
     wtapng_iface_descriptions_t *idb_inf = NULL;
 
     g_assert(out_fd > 0);
@@ -913,7 +944,7 @@ merge_files(int out_fd, const gchar* out_filename, const int file_type,
     if (pdh == NULL) {
         merge_close_in_files(in_file_count, in_files);
         g_free(in_files);
-        wtap_free_shb(shb_hdr);
+        wtap_optionblock_free(shb_hdr);
         wtap_free_idb_info(idb_inf);
         return MERGE_ERR_CANT_OPEN_OUTFILE;
     }
@@ -1035,7 +1066,7 @@ merge_files(int out_fd, const gchar* out_filename, const int file_type,
     }
 
     g_free(in_files);
-    wtap_free_shb(shb_hdr);
+    wtap_optionblock_free(shb_hdr);
     wtap_free_idb_info(idb_inf);
 
     return status;
index 5e80584479eff43ac7162ca1de92b08ebcb2c681..655e8893ddbc13494c9de864ca2137e2229754be 100644 (file)
@@ -187,10 +187,10 @@ nettrace_close(wtap *wth)
        wtap_close(file_info->wth_tmp_file);
 
        /*Clear the shb info, it's been freed by wtap_close*/
-       wth->shb_hdr.opt_comment = NULL;
-       wth->shb_hdr.shb_hardware = NULL;
-       wth->shb_hdr.shb_os = NULL;
-       wth->shb_hdr.shb_user_appl = NULL;
+       wtap_optionblock_set_option_string(wth->shb_hdr, OPT_COMMENT, NULL);
+       wtap_optionblock_set_option_string(wth->shb_hdr, OPT_SHB_HARDWARE, NULL);
+       wtap_optionblock_set_option_string(wth->shb_hdr, OPT_SHB_OS, NULL);
+       wtap_optionblock_set_option_string(wth->shb_hdr, OPT_SHB_USERAPPL, NULL);
 
        /* delete the temp file */
        ws_unlink(file_info->tmpname);
@@ -609,9 +609,10 @@ create_temp_pcapng_file(wtap *wth, int *err, gchar **err_info, nettrace_3gpp_32_
        wtap_open_return_val result = WTAP_OPEN_MINE;
 
        /* pcapng defs */
-       wtapng_section_t            *shb_hdr = NULL;
+       wtap_optionblock_t           shb_hdr = NULL;
        wtapng_iface_descriptions_t *idb_inf = NULL;
-       wtapng_if_descr_t            int_data;
+       wtap_optionblock_t           int_data;
+       wtapng_if_descr_mandatory_t *int_data_mand;
        GString                     *os_info_str;
        gint64 file_size;
        int packet_size;
@@ -623,6 +624,7 @@ create_temp_pcapng_file(wtap *wth, int *err, gchar **err_info, nettrace_3gpp_32_
        int scan_found;
        unsigned second, ms;
        gboolean do_random = FALSE;
+       gchar* wireshark_ver;
        char *curr_pos, *next_msg_pos, *next_pos, *prev_pos;
        /* Info to build exported_pdu tags*/
        exported_pdu_info_t  exported_pdu_info;
@@ -647,47 +649,37 @@ create_temp_pcapng_file(wtap *wth, int *err, gchar **err_info, nettrace_3gpp_32_
        os_info_str = g_string_new("");
        get_os_version_info(os_info_str);
 
-       shb_hdr = g_new(wtapng_section_t, 1);
-       shb_hdr->section_length = -1;
+       shb_hdr = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION);
        /* options */
-       shb_hdr->opt_comment = g_strdup_printf("File converted to Exported PDU format during opening");
-       /*
-       * UTF-8 string containing the description of the hardware used to create
-       * this section.
-       */
-       shb_hdr->shb_hardware = NULL;
+       wtap_optionblock_set_option_string(wth->shb_hdr, OPT_COMMENT, "File converted to Exported PDU format during opening");
        /*
        * UTF-8 string containing the name of the operating system used to create
        * this section.
        */
-       shb_hdr->shb_os = g_string_free(os_info_str, FALSE);
+       wtap_optionblock_set_option_string(wth->shb_hdr, OPT_SHB_OS, g_string_free(os_info_str, TRUE));
+
        /*
        * UTF-8 string containing the name of the application used to create
        * this section.
        */
-       shb_hdr->shb_user_appl = g_strdup_printf("Wireshark %s", get_ws_vcs_version_info());
+       wireshark_ver = g_strdup_printf("Wireshark %s", get_ws_vcs_version_info());
+       wtap_optionblock_set_option_string(wth->shb_hdr, OPT_SHB_USERAPPL, wireshark_ver);
+       g_free(wireshark_ver);
 
        /* Create fake IDB info */
        idb_inf = g_new(wtapng_iface_descriptions_t, 1);
-       idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
+       idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
 
        /* create the fake interface data */
-       int_data.wtap_encap = WTAP_ENCAP_WIRESHARK_UPPER_PDU;
-       int_data.time_units_per_second = 1000000; /* default microsecond resolution */
-       int_data.link_type = wtap_wtap_encap_to_pcap_encap(WTAP_ENCAP_WIRESHARK_UPPER_PDU);
-       int_data.snap_len = WTAP_MAX_PACKET_SIZE;
-       int_data.if_name = g_strdup("Fake IF");
-       int_data.opt_comment = NULL;
-       int_data.if_description = NULL;
-       int_data.if_speed = 0;
-       int_data.if_tsresol = 6;
-       int_data.if_filter_str = NULL;
-       int_data.bpf_filter_len = 0;
-       int_data.if_filter_bpf_bytes = NULL;
-       int_data.if_os = NULL;
-       int_data.if_fcslen = -1;
-       int_data.num_stat_entries = 0;          /* Number of ISB:s */
-       int_data.interface_statistics = NULL;
+       int_data = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
+       int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data);
+       int_data_mand->wtap_encap = WTAP_ENCAP_WIRESHARK_UPPER_PDU;
+       int_data_mand->time_units_per_second = 1000000; /* default microsecond resolution */
+       int_data_mand->link_type = wtap_wtap_encap_to_pcap_encap(WTAP_ENCAP_WIRESHARK_UPPER_PDU);
+       int_data_mand->snap_len = WTAP_MAX_PACKET_SIZE;
+       wtap_optionblock_set_option_string(int_data, OPT_IDB_NAME, "Fake IF");
+       int_data_mand->num_stat_entries = 0;          /* Number of ISB:s */
+       int_data_mand->interface_statistics = NULL;
 
        g_array_append_val(idb_inf->interface_data, int_data);
 
@@ -953,7 +945,7 @@ create_temp_pcapng_file(wtap *wth, int *err, gchar **err_info, nettrace_3gpp_32_
 end:
        g_free(wrt_err_info);
        g_free(packet_buf);
-       wtap_free_shb(shb_hdr);
+       wtap_optionblock_free(shb_hdr);
        wtap_free_idb_info(idb_inf);
 
        return result;
@@ -1012,10 +1004,7 @@ nettrace_3gpp_32_423_file_open(wtap *wth, int *err, gchar **err_info)
                return WTAP_OPEN_ERROR;
 
        /* Copy data from the temp file wth */
-       wth->shb_hdr.opt_comment = file_info->wth_tmp_file->shb_hdr.opt_comment;
-       wth->shb_hdr.shb_hardware = file_info->wth_tmp_file->shb_hdr.shb_hardware;
-       wth->shb_hdr.shb_os = file_info->wth_tmp_file->shb_hdr.shb_os;
-       wth->shb_hdr.shb_user_appl = file_info->wth_tmp_file->shb_hdr.shb_user_appl;
+       wtap_optionblock_copy_options(wth->shb_hdr, file_info->wth_tmp_file->shb_hdr);
 
        wth->file_type_subtype = WTAP_FILE_TYPE_SUBTYPE_NETTRACE_3GPP_32_423;
        wth->file_encap = file_info->wth_tmp_file->file_encap;
index b55cedc34fe381dfff1a6e806472ddaae10d4847..879f349de460e62b01701212cc21f432f09075d4 100644 (file)
@@ -202,39 +202,10 @@ struct option {
 };
 
 /* Option codes: 16-bit field */
-#define OPT_EOFOPT           0x0000
-#define OPT_COMMENT          0x0001
-
-#define OPT_SHB_HARDWARE     0x0002
-#define OPT_SHB_OS           0x0003
-#define OPT_SHB_USERAPPL     0x0004
-
 #define OPT_EPB_FLAGS        0x0002
 #define OPT_EPB_HASH         0x0003
 #define OPT_EPB_DROPCOUNT    0x0004
 
-#define OPT_IDB_NAME         0x0002
-#define OPT_IDB_DESCR        0x0003
-#define OPT_IDB_IP4ADDR      0x0004
-#define OPT_IDB_IP6ADDR      0x0005
-#define OPT_IDB_MACADDR      0x0006
-#define OPT_IDB_EUIADDR      0x0007
-#define OPT_IDB_SPEED        0x0008
-#define OPT_IDB_TSRESOL      0x0009
-#define OPT_IDB_TZONE        0x000A
-#define OPT_IDB_FILTER       0x000B
-#define OPT_IDB_OS           0x000C
-#define OPT_IDB_FCSLEN       0x000D
-#define OPT_IDB_TSOFFSET     0x000E
-
-#define OPT_ISB_STARTTIME    0x0002
-#define OPT_ISB_ENDTIME      0x0003
-#define OPT_ISB_IFRECV       0x0004
-#define OPT_ISB_IFDROP       0x0005
-#define OPT_ISB_FILTERACCEPT 0x0006
-#define OPT_ISB_OSDROP       0x0007
-#define OPT_ISB_USRDELIV     0x0008
-
 #define OPT_NRB_DNSNAME      0x0002
 #define OPT_NRB_DNSV4ADDR    0x0003
 #define OPT_NRB_DNSV6ADDR    0x0004
@@ -269,12 +240,7 @@ typedef struct wtapng_simple_packet_s {
 /* Block data to be passed between functions during reading */
 typedef struct wtapng_block_s {
     guint32                     type;           /* block_type as defined by pcapng */
-    union {
-        wtapng_section_t        section;
-        wtapng_if_descr_t       if_descr;
-        wtapng_name_res_t       name_res;
-        wtapng_if_stats_t       if_stats;
-    } data;
+    wtap_optionblock_t          block;
 
     /*
      * XXX - currently don't know how to handle these!
@@ -528,20 +494,6 @@ pcapng_read_option(FILE_T fh, pcapng_t *pn, pcapng_option_header_t *oh,
     return block_read;
 }
 
-
-static void
-pcapng_free_wtapng_block_data(wtapng_block_t *wblock)
-{
-    switch (wblock->type) {
-        case(BLOCK_TYPE_SHB):
-            g_free(wblock->data.section.opt_comment);
-            g_free(wblock->data.section.shb_hardware);
-            g_free(wblock->data.section.shb_os);
-            g_free(wblock->data.section.shb_user_appl);
-            break;
-    }
-}
-
 typedef enum {
     PCAPNG_BLOCK_OK,
     PCAPNG_BLOCK_NOT_SHB,
@@ -557,6 +509,9 @@ pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh,
     guint to_read, opt_cont_buf_len;
     pcapng_section_header_block_t shb;
     pcapng_option_header_t oh;
+    wtapng_mandatory_section_t* section_data;
+    gchar* tmp_content;
+
     guint8 *option_content = NULL; /* Allocate as large as the options block */
 
     /* read fixed-length part of the block */
@@ -656,12 +611,13 @@ pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh,
         return PCAPNG_BLOCK_ERROR;
     }
 
-
+    wblock->block = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION);
+    section_data = (wtapng_mandatory_section_t*)wtap_optionblock_get_mandatory_data(wblock->block);
     /* 64bit section_length (currently unused) */
     if (pn->byte_swapped) {
-        wblock->data.section.section_length = GUINT64_SWAP_LE_BE(shb.section_length);
+        section_data->section_length = GUINT64_SWAP_LE_BE(shb.section_length);
     } else {
-        wblock->data.section.section_length = shb.section_length;
+        section_data->section_length = shb.section_length;
     }
 
     /* Options */
@@ -696,36 +652,40 @@ pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh,
                 break;
             case(OPT_COMMENT):
                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
-                    g_free(wblock->data.section.opt_comment);
-                    wblock->data.section.opt_comment = g_strndup((char *)option_content, oh.option_length);
-                    pcapng_debug("pcapng_read_section_header_block: opt_comment %s", wblock->data.section.opt_comment);
+                    tmp_content = g_strndup((char *)option_content, oh.option_length);
+                    wtap_optionblock_set_option_string(wblock->block, OPT_COMMENT, tmp_content);
+                    pcapng_debug("pcapng_read_section_header_block: opt_comment %s", tmp_content);
+                    g_free(tmp_content);
                 } else {
                     pcapng_debug("pcapng_read_section_header_block: opt_comment length %u seems strange", oh.option_length);
                 }
                 break;
             case(OPT_SHB_HARDWARE):
                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
-                    g_free(wblock->data.section.shb_hardware);
-                    wblock->data.section.shb_hardware = g_strndup((char *)option_content, oh.option_length);
-                    pcapng_debug("pcapng_read_section_header_block: shb_hardware %s", wblock->data.section.shb_hardware);
+                    tmp_content = g_strndup((char *)option_content, oh.option_length);
+                    wtap_optionblock_set_option_string(wblock->block, OPT_SHB_HARDWARE, tmp_content);
+                    pcapng_debug("pcapng_read_section_header_block: shb_hardware %s", tmp_content);
+                    g_free(tmp_content);
                 } else {
                     pcapng_debug("pcapng_read_section_header_block: shb_hardware length %u seems strange", oh.option_length);
                 }
                 break;
             case(OPT_SHB_OS):
                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
-                    g_free(wblock->data.section.shb_os);
-                    wblock->data.section.shb_os = g_strndup((char *)option_content, oh.option_length);
-                    pcapng_debug("pcapng_read_section_header_block: shb_os %s", wblock->data.section.shb_os);
+                    tmp_content = g_strndup((char *)option_content, oh.option_length);
+                    wtap_optionblock_set_option_string(wblock->block, OPT_SHB_OS, tmp_content);
+                    pcapng_debug("pcapng_read_section_header_block: shb_os %s", tmp_content);
+                    g_free(tmp_content);
                 } else {
                     pcapng_debug("pcapng_read_section_header_block: shb_os length %u seems strange, opt buffsize %u", oh.option_length,to_read);
                 }
                 break;
             case(OPT_SHB_USERAPPL):
                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
-                    g_free(wblock->data.section.shb_user_appl);
-                    wblock->data.section.shb_user_appl = g_strndup((char *)option_content, oh.option_length);
-                    pcapng_debug("pcapng_read_section_header_block: shb_user_appl %s", wblock->data.section.shb_user_appl);
+                    tmp_content = g_strndup((char *)option_content, oh.option_length);
+                    wtap_optionblock_set_option_string(wblock->block, OPT_SHB_USERAPPL, tmp_content);
+                    pcapng_debug("pcapng_read_section_header_block: shb_user_appl %s", tmp_content);
+                    g_free(tmp_content);
                 } else {
                     pcapng_debug("pcapng_read_section_header_block: shb_user_appl length %u seems strange", oh.option_length);
                 }
@@ -752,8 +712,11 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
     int     bytes_read;
     guint to_read, opt_cont_buf_len;
     pcapng_interface_description_block_t idb;
+    wtapng_if_descr_mandatory_t* if_descr_mand;
     pcapng_option_header_t oh;
     guint8 *option_content = NULL; /* Allocate as large as the options block */
+    gchar* tmp_content;
+    guint64 tmp64;
 
     /*
      * Is this block long enough to be an IDB?
@@ -790,51 +753,35 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
     }
 
     /* mandatory values */
+    wblock->block = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
+    if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(wblock->block);
     if (pn->byte_swapped) {
-        wblock->data.if_descr.link_type = GUINT16_SWAP_LE_BE(idb.linktype);
-        wblock->data.if_descr.snap_len  = GUINT32_SWAP_LE_BE(idb.snaplen);
+        if_descr_mand->link_type = GUINT16_SWAP_LE_BE(idb.linktype);
+        if_descr_mand->snap_len  = GUINT32_SWAP_LE_BE(idb.snaplen);
     } else {
-        wblock->data.if_descr.link_type = idb.linktype;
-        wblock->data.if_descr.snap_len  = idb.snaplen;
+        if_descr_mand->link_type = idb.linktype;
+        if_descr_mand->snap_len  = idb.snaplen;
     }
 
-    wblock->data.if_descr.wtap_encap = wtap_pcap_encap_to_wtap_encap(wblock->data.if_descr.link_type);
-    wblock->data.if_descr.time_units_per_second = time_units_per_second;
-    wblock->data.if_descr.tsprecision = tsprecision;
+    if_descr_mand->wtap_encap = wtap_pcap_encap_to_wtap_encap(if_descr_mand->link_type);
+    if_descr_mand->time_units_per_second = time_units_per_second;
+    if_descr_mand->tsprecision = tsprecision;
 
     pcapng_debug("pcapng_read_if_descr_block: IDB link_type %u (%s), snap %u",
-                  wblock->data.if_descr.link_type,
-                  wtap_encap_string(wblock->data.if_descr.wtap_encap),
-                  wblock->data.if_descr.snap_len);
+                  if_descr_mand->link_type,
+                  wtap_encap_string(if_descr_mand->wtap_encap),
+                  if_descr_mand->snap_len);
 
-    if (wblock->data.if_descr.snap_len > WTAP_MAX_PACKET_SIZE) {
+    if (if_descr_mand->snap_len > WTAP_MAX_PACKET_SIZE) {
         /* This is unrealistic, but text2pcap currently uses 102400.
          * We do not use this value, maybe we should check the
          * snap_len of the packets against it. For now, only warn.
          */
         pcapng_debug("pcapng_read_if_descr_block: snapshot length %u unrealistic.",
-                      wblock->data.if_descr.snap_len);
-        /*wblock->data.if_descr.snap_len = WTAP_MAX_PACKET_SIZE;*/
+                      if_descr_mand->snap_len);
+        /*if_descr_mand->snap_len = WTAP_MAX_PACKET_SIZE;*/
     }
 
-    /* Option defaults */
-    wblock->data.if_descr.opt_comment = NULL;
-    wblock->data.if_descr.if_name = NULL;
-    wblock->data.if_descr.if_description = NULL;
-    /* XXX: if_IPv4addr */
-    /* XXX: if_IPv6addr */
-    /* XXX: if_MACaddr */
-    /* XXX: if_EUIaddr */
-    wblock->data.if_descr.if_speed = 0;                     /* "unknown" */
-    wblock->data.if_descr.if_tsresol = 6;                   /* default is 6 for microsecond resolution */
-    wblock->data.if_descr.if_filter_str = NULL;
-    wblock->data.if_descr.bpf_filter_len = 0;
-    wblock->data.if_descr.if_filter_bpf_bytes = NULL;
-    wblock->data.if_descr.if_os = NULL;
-    wblock->data.if_descr.if_fcslen = -1;                   /* unknown or changes between packets */
-    /* XXX: guint64 if_tsoffset; */
-
-
     /* Options */
     to_read = bh->block_total_length - MIN_IDB_SIZE;
 
@@ -866,24 +813,30 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
                 break;
             case(OPT_COMMENT): /* opt_comment */
                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
-                    wblock->data.if_descr.opt_comment = g_strndup((char *)option_content, oh.option_length);
-                    pcapng_debug("pcapng_read_if_descr_block: opt_comment %s", wblock->data.if_descr.opt_comment);
+                    tmp_content = g_strndup((char *)option_content, oh.option_length);
+                    wtap_optionblock_set_option_string(wblock->block, OPT_COMMENT, tmp_content);
+                    pcapng_debug("pcapng_read_if_descr_block: opt_comment %s", tmp_content);
+                    g_free(tmp_content);
                 } else {
                     pcapng_debug("pcapng_read_if_descr_block: opt_comment length %u seems strange", oh.option_length);
                 }
                 break;
             case(OPT_IDB_NAME): /* if_name */
                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
-                    wblock->data.if_descr.if_name = g_strndup((char *)option_content, oh.option_length);
-                    pcapng_debug("pcapng_read_if_descr_block: if_name %s", wblock->data.if_descr.if_name);
+                    tmp_content = g_strndup((char *)option_content, oh.option_length);
+                    wtap_optionblock_set_option_string(wblock->block, OPT_IDB_NAME, tmp_content);
+                    pcapng_debug("pcapng_read_if_descr_block: if_name %s", tmp_content);
+                    g_free(tmp_content);
                 } else {
                     pcapng_debug("pcapng_read_if_descr_block: if_name length %u seems strange", oh.option_length);
                 }
                 break;
             case(OPT_IDB_DESCR): /* if_description */
                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
-                    wblock->data.if_descr.if_description = g_strndup((char *)option_content, oh.option_length);
-                    pcapng_debug("pcapng_read_if_descr_block: if_description %s", wblock->data.if_descr.if_description);
+                    tmp_content = g_strndup((char *)option_content, oh.option_length);
+                    wtap_optionblock_set_option_string(wblock->block, OPT_IDB_DESCR, tmp_content);
+                    pcapng_debug("pcapng_read_if_descr_block: if_description %s", tmp_content);
+                    g_free(tmp_content);
                 } else {
                     pcapng_debug("pcapng_read_if_descr_block: if_description length %u seems strange", oh.option_length);
                 }
@@ -894,10 +847,11 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
                      *  guint8 * may not point to something that's
                      *  aligned correctly.
                      */
-                    memcpy(&wblock->data.if_descr.if_speed, option_content, sizeof(guint64));
+                    memcpy(&tmp64, option_content, sizeof(guint64));
                     if (pn->byte_swapped)
-                        wblock->data.if_descr.if_speed = GUINT64_SWAP_LE_BE(wblock->data.if_descr.if_speed);
-                    pcapng_debug("pcapng_read_if_descr_block: if_speed %" G_GINT64_MODIFIER "u (bps)", wblock->data.if_descr.if_speed);
+                        tmp64 = GUINT64_SWAP_LE_BE(tmp64);
+                    wtap_optionblock_set_option_uint64(wblock->block, OPT_IDB_SPEED, tmp64);
+                    pcapng_debug("pcapng_read_if_descr_block: if_speed %" G_GINT64_MODIFIER "u (bps)", tmp64);
                 } else {
                     pcapng_debug("pcapng_read_if_descr_block: if_speed length %u not 8 as expected", oh.option_length);
                 }
@@ -927,8 +881,8 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
                     if (time_units_per_second > (((guint64)1) << 32)) {
                         pcapng_debug("pcapng_open: time conversion might be inaccurate");
                     }
-                    wblock->data.if_descr.time_units_per_second = time_units_per_second;
-                    wblock->data.if_descr.if_tsresol = if_tsresol;
+                    if_descr_mand->time_units_per_second = time_units_per_second;
+                    wtap_optionblock_set_option_uint8(wblock->block, OPT_IDB_TSRESOL, if_tsresol);
                     if (time_units_per_second >= 1000000000)
                         tsprecision = WTAP_TSPREC_NSEC;
                     else if (time_units_per_second >= 1000000)
@@ -941,8 +895,8 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
                         tsprecision = WTAP_TSPREC_DSEC;
                     else
                         tsprecision = WTAP_TSPREC_SEC;
-                    wblock->data.if_descr.tsprecision = tsprecision;
-                    pcapng_debug("pcapng_read_if_descr_block: if_tsresol %u, units/s %" G_GINT64_MODIFIER "u, tsprecision %d", wblock->data.if_descr.if_tsresol, wblock->data.if_descr.time_units_per_second, tsprecision);
+                    if_descr_mand->tsprecision = tsprecision;
+                    pcapng_debug("pcapng_read_if_descr_block: if_tsresol %u, units/s %" G_GINT64_MODIFIER "u, tsprecision %d", if_tsresol, if_descr_mand->time_units_per_second, tsprecision);
                 } else {
                     pcapng_debug("pcapng_read_if_descr_block: if_tsresol length %u not 1 as expected", oh.option_length);
                 }
@@ -952,17 +906,21 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
                  */
             case(OPT_IDB_FILTER): /* if_filter */
                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
+                    wtapng_if_descr_filter_t if_filter;
+                    memset(&if_filter, 0, sizeof(if_filter));
+
                     /* 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.
                      */
                     if (option_content[0] == 0) {
-                        wblock->data.if_descr.if_filter_str = g_strndup((char *)option_content+1, oh.option_length-1);
-                        pcapng_debug("pcapng_read_if_descr_block: if_filter_str %s oh.option_length %u", wblock->data.if_descr.if_filter_str, oh.option_length);
+                        if_filter.if_filter_str = g_strndup((char *)option_content+1, oh.option_length-1);
+                        pcapng_debug("pcapng_read_if_descr_block: if_filter_str %s oh.option_length %u", if_filter.if_filter_str, oh.option_length);
                     } else if (option_content[0] == 1) {
-                        wblock->data.if_descr.bpf_filter_len = oh.option_length-1;
-                        wblock->data.if_descr.if_filter_bpf_bytes = (gchar *)g_malloc(oh.option_length-1);
-                        memcpy(wblock->data.if_descr.if_filter_bpf_bytes, (char *)option_content+1, oh.option_length-1);
+                        if_filter.bpf_filter_len = oh.option_length-1;
+                        if_filter.if_filter_bpf_bytes = (gchar *)g_malloc(oh.option_length-1);
+                        memcpy(if_filter.if_filter_bpf_bytes, (char *)option_content+1, oh.option_length-1);
                     }
+                    wtap_optionblock_set_option_custom(wblock->block, OPT_IDB_FILTER, &if_filter);
                 } else {
                     pcapng_debug("pcapng_read_if_descr_block: if_filter length %u seems strange", oh.option_length);
                 }
@@ -974,17 +932,19 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
                  * because the capture can have been done on a remote machine. "Windows XP SP2" / "openSUSE 10.2" / ...
                  */
                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
-                    wblock->data.if_descr.if_os = g_strndup((char *)option_content, oh.option_length);
-                    pcapng_debug("pcapng_read_if_descr_block: if_os %s", wblock->data.if_descr.if_os);
+                    tmp_content = g_strndup((char *)option_content, oh.option_length);
+                    wtap_optionblock_set_option_string(wblock->block, OPT_IDB_OS, tmp_content);
+                    pcapng_debug("pcapng_read_if_descr_block: if_os %s", tmp_content);
+                    g_free(tmp_content);
                 } else {
                     pcapng_debug("pcapng_read_if_descr_block: if_os length %u seems strange", oh.option_length);
                 }
                 break;
             case(OPT_IDB_FCSLEN): /* if_fcslen */
                 if (oh.option_length == 1) {
-                    wblock->data.if_descr.if_fcslen = option_content[0];
-                    pn->if_fcslen = wblock->data.if_descr.if_fcslen;
-                    pcapng_debug("pcapng_read_if_descr_block: if_fcslen %u", wblock->data.if_descr.if_fcslen);
+                    wtap_optionblock_set_option_uint8(wblock->block, OPT_IDB_TSRESOL, option_content[0]);
+                    pn->if_fcslen = option_content[0];
+                    pcapng_debug("pcapng_read_if_descr_block: if_fcslen %u", pn->if_fcslen);
                     /* XXX - add sanity check */
                 } else {
                     pcapng_debug("pcapng_read_if_descr_block: if_fcslen length %u not 1 as expected", oh.option_length);
@@ -1054,9 +1014,9 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
      * packets in the file.
      */
     if (wth->file_encap == WTAP_ENCAP_UNKNOWN) {
-        wth->file_encap = wblock->data.if_descr.wtap_encap;
+        wth->file_encap = if_descr_mand->wtap_encap;
     } else {
-        if (wth->file_encap != wblock->data.if_descr.wtap_encap) {
+        if (wth->file_encap != if_descr_mand->wtap_encap) {
             wth->file_encap = WTAP_ENCAP_PER_PACKET;
         }
     }
@@ -1065,9 +1025,9 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
      * The same applies to the per-file time stamp resolution.
      */
     if (wth->file_tsprec == WTAP_TSPREC_UNKNOWN) {
-        wth->file_tsprec = wblock->data.if_descr.tsprecision;
+        wth->file_tsprec = if_descr_mand->tsprecision;
     } else {
-        if (wth->file_tsprec != wblock->data.if_descr.tsprecision) {
+        if (wth->file_tsprec != if_descr_mand->tsprecision) {
             wth->file_tsprec = WTAP_TSPREC_PER_PACKET;
         }
     }
@@ -1658,6 +1618,7 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t
 #ifdef HAVE_PLUGINS
     option_handler *handler;
 #endif
+    gchar* tmp_content;
 
     /*
      * Is this block long enough to be an NRB?
@@ -1913,8 +1874,10 @@ read_options:
                 break;
             case(OPT_COMMENT):
                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
-                    wblock->data.name_res.opt_comment = g_strndup((char *)option_content, oh.option_length);
-                    pcapng_debug("pcapng_read_name_resolution_block: length %u opt_comment '%s'", oh.option_length, wblock->data.name_res.opt_comment);
+                    tmp_content = g_strndup((char *)option_content, oh.option_length);
+                    wtap_optionblock_set_option_string(wblock->block, OPT_COMMENT, tmp_content);
+                    pcapng_debug("pcapng_read_name_resolution_block: length %u opt_comment '%s'", oh.option_length, tmp_content);
+                    g_free(tmp_content);
                 } else {
                     pcapng_debug("pcapng_read_name_resolution_block: opt_comment length %u seems strange", oh.option_length);
                 }
@@ -1957,6 +1920,8 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
     pcapng_interface_statistics_block_t isb;
     pcapng_option_header_t oh;
     guint8 *option_content = NULL; /* Allocate as large as the options block */
+    wtapng_if_stats_mandatory_t* if_stats_mand;
+    char* tmp_content;
 
     /*
      * Is this block long enough to be an ISB?
@@ -1992,24 +1957,18 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
         return FALSE;
     }
 
+    wblock->block = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_STATS);
+    if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(wblock->block);
     if (pn->byte_swapped) {
-        wblock->data.if_stats.interface_id = GUINT32_SWAP_LE_BE(isb.interface_id);
-        wblock->data.if_stats.ts_high      = GUINT32_SWAP_LE_BE(isb.timestamp_high);
-        wblock->data.if_stats.ts_low       = GUINT32_SWAP_LE_BE(isb.timestamp_low);
+        if_stats_mand->interface_id = GUINT32_SWAP_LE_BE(isb.interface_id);
+        if_stats_mand->ts_high      = GUINT32_SWAP_LE_BE(isb.timestamp_high);
+        if_stats_mand->ts_low       = GUINT32_SWAP_LE_BE(isb.timestamp_low);
     } else {
-        wblock->data.if_stats.interface_id = isb.interface_id;
-        wblock->data.if_stats.ts_high      = isb.timestamp_high;
-        wblock->data.if_stats.ts_low       = isb.timestamp_low;
+        if_stats_mand->interface_id = isb.interface_id;
+        if_stats_mand->ts_high      = isb.timestamp_high;
+        if_stats_mand->ts_low       = isb.timestamp_low;
     }
-    pcapng_debug("pcapng_read_interface_statistics_block: interface_id %u", wblock->data.if_stats.interface_id);
-
-    /* Option defaults */
-    wblock->data.if_stats.opt_comment          = NULL;
-    wblock->data.if_stats.isb_ifrecv           = -1;
-    wblock->data.if_stats.isb_ifdrop           = -1;
-    wblock->data.if_stats.isb_filteraccept     = -1;
-    wblock->data.if_stats.isb_osdrop           = -1;
-    wblock->data.if_stats.isb_usrdeliv         = -1;
+    pcapng_debug("pcapng_read_interface_statistics_block: interface_id %u", if_stats_mand->interface_id);
 
     /* Options */
     to_read = bh->block_total_length -
@@ -2043,8 +2002,10 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
                 break;
             case(OPT_COMMENT): /* opt_comment */
                 if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
-                    wblock->data.if_stats.opt_comment = g_strndup((char *)option_content, oh.option_length);
-                    pcapng_debug("pcapng_read_interface_statistics_block: opt_comment %s", wblock->data.if_stats.opt_comment);
+                    tmp_content = g_strndup((char *)option_content, oh.option_length);
+                    wtap_optionblock_set_option_string(wblock->block, OPT_COMMENT, tmp_content);
+                    g_free(tmp_content);
+                    pcapng_debug("pcapng_read_interface_statistics_block: opt_comment %s", tmp_content);
                 } else {
                     pcapng_debug("pcapng_read_interface_statistics_block: opt_comment length %u seems strange", oh.option_length);
                 }
@@ -2052,6 +2013,7 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
             case(OPT_ISB_STARTTIME): /* isb_starttime */
                 if (oh.option_length == 8) {
                     guint32 high, low;
+                    guint64 starttime;
 
                     /*  Don't cast a guint8 * into a guint32 *--the
                      *  guint8 * may not point to something that's
@@ -2063,10 +2025,11 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
                         high = GUINT32_SWAP_LE_BE(high);
                         low = GUINT32_SWAP_LE_BE(low);
                     }
-                    wblock->data.if_stats.isb_starttime = (guint64)high;
-                    wblock->data.if_stats.isb_starttime <<= 32;
-                    wblock->data.if_stats.isb_starttime += (guint64)low;
-                    pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime %" G_GINT64_MODIFIER "u", wblock->data.if_stats.isb_starttime);
+                    starttime = (guint64)high;
+                    starttime <<= 32;
+                    starttime += (guint64)low;
+                    wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_STARTTIME, starttime);
+                    pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime %" G_GINT64_MODIFIER "u", starttime);
                 } else {
                     pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime length %u not 8 as expected", oh.option_length);
                 }
@@ -2074,6 +2037,7 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
             case(OPT_ISB_ENDTIME): /* isb_endtime */
                 if (oh.option_length == 8) {
                     guint32 high, low;
+                    guint64 endtime;
 
                     /*  Don't cast a guint8 * into a guint32 *--the
                      *  guint8 * may not point to something that's
@@ -2085,80 +2049,91 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca
                         high = GUINT32_SWAP_LE_BE(high);
                         low = GUINT32_SWAP_LE_BE(low);
                     }
-                    wblock->data.if_stats.isb_endtime = (guint64)high;
-                    wblock->data.if_stats.isb_endtime <<= 32;
-                    wblock->data.if_stats.isb_endtime += (guint64)low;
-                    pcapng_debug("pcapng_read_interface_statistics_block: isb_endtime %" G_GINT64_MODIFIER "u", wblock->data.if_stats.isb_endtime);
+                    endtime = (guint64)high;
+                    endtime <<= 32;
+                    endtime += (guint64)low;
+                    wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_ENDTIME, endtime);
+                    pcapng_debug("pcapng_read_interface_statistics_block: isb_endtime %" G_GINT64_MODIFIER "u", endtime);
                 } else {
                     pcapng_debug("pcapng_read_interface_statistics_block: isb_starttime length %u not 8 as expected", oh.option_length);
                 }
                 break;
             case(OPT_ISB_IFRECV): /* isb_ifrecv */
                 if (oh.option_length == 8) {
+                    guint64 ifrecv;
                     /*  Don't cast a guint8 * into a guint64 *--the
                      *  guint8 * may not point to something that's
                      *  aligned correctly.
                      */
-                    memcpy(&wblock->data.if_stats.isb_ifrecv, option_content, sizeof(guint64));
+                    memcpy(&ifrecv, option_content, sizeof(guint64));
                     if (pn->byte_swapped)
-                        wblock->data.if_stats.isb_ifrecv = GUINT64_SWAP_LE_BE(wblock->data.if_stats.isb_ifrecv);
-                    pcapng_debug("pcapng_read_interface_statistics_block: isb_ifrecv %" G_GINT64_MODIFIER "u", wblock->data.if_stats.isb_ifrecv);
+                        ifrecv = GUINT64_SWAP_LE_BE(ifrecv);
+                    wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_IFRECV, ifrecv);
+                    pcapng_debug("pcapng_read_interface_statistics_block: isb_ifrecv %" G_GINT64_MODIFIER "u", ifrecv);
                 } else {
                     pcapng_debug("pcapng_read_interface_statistics_block: isb_ifrecv length %u not 8 as expected", oh.option_length);
                 }
                 break;
             case(OPT_ISB_IFDROP): /* isb_ifdrop */
                 if (oh.option_length == 8) {
+                    guint64 ifdrop;
                     /*  Don't cast a guint8 * into a guint64 *--the
                      *  guint8 * may not point to something that's
                      *  aligned correctly.
                      */
-                    memcpy(&wblock->data.if_stats.isb_ifdrop, option_content, sizeof(guint64));
+                    memcpy(&ifdrop, option_content, sizeof(guint64));
                     if (pn->byte_swapped)
-                        wblock->data.if_stats.isb_ifdrop = GUINT64_SWAP_LE_BE(wblock->data.if_stats.isb_ifdrop);
-                    pcapng_debug("pcapng_read_interface_statistics_block: isb_ifdrop %" G_GINT64_MODIFIER "u", wblock->data.if_stats.isb_ifdrop);
+                        ifdrop = GUINT64_SWAP_LE_BE(ifdrop);
+                    wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_IFDROP, ifdrop);
+                    pcapng_debug("pcapng_read_interface_statistics_block: isb_ifdrop %" G_GINT64_MODIFIER "u", ifdrop);
                 } else {
                     pcapng_debug("pcapng_read_interface_statistics_block: isb_ifdrop length %u not 8 as expected", oh.option_length);
                 }
                 break;
             case(OPT_ISB_FILTERACCEPT): /* isb_filteraccept 6 */
                 if (oh.option_length == 8) {
+                    guint64 filteraccept;
                     /*  Don't cast a guint8 * into a guint64 *--the
                      *  guint8 * may not point to something that's
                      *  aligned correctly.
                      */
-                    memcpy(&wblock->data.if_stats.isb_filteraccept, option_content, sizeof(guint64));
+                    memcpy(&filteraccept, option_content, sizeof(guint64));
                     if (pn->byte_swapped)
-                        wblock->data.if_stats.isb_filteraccept = GUINT64_SWAP_LE_BE(wblock->data.if_stats.isb_filteraccept);
-                    pcapng_debug("pcapng_read_interface_statistics_block: isb_filteraccept %" G_GINT64_MODIFIER "u", wblock->data.if_stats.isb_filteraccept);
+                        filteraccept = GUINT64_SWAP_LE_BE(filteraccept);
+                    wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_FILTERACCEPT, filteraccept);
+                    pcapng_debug("pcapng_read_interface_statistics_block: isb_filteraccept %" G_GINT64_MODIFIER "u", filteraccept);
                 } else {
                     pcapng_debug("pcapng_read_interface_statistics_block: isb_filteraccept length %u not 8 as expected", oh.option_length);
                 }
                 break;
             case(OPT_ISB_OSDROP): /* isb_osdrop 7 */
                 if (oh.option_length == 8) {
+                    guint64 osdrop;
                     /*  Don't cast a guint8 * into a guint64 *--the
                      *  guint8 * may not point to something that's
                      *  aligned correctly.
                      */
-                    memcpy(&wblock->data.if_stats.isb_osdrop, option_content, sizeof(guint64));
+                    memcpy(&osdrop, option_content, sizeof(guint64));
                     if (pn->byte_swapped)
-                        wblock->data.if_stats.isb_osdrop = GUINT64_SWAP_LE_BE(wblock->data.if_stats.isb_osdrop);
-                    pcapng_debug("pcapng_read_interface_statistics_block: isb_osdrop %" G_GINT64_MODIFIER "u", wblock->data.if_stats.isb_osdrop);
+                        osdrop = GUINT64_SWAP_LE_BE(osdrop);
+                    wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_OSDROP, osdrop);
+                    pcapng_debug("pcapng_read_interface_statistics_block: isb_osdrop %" G_GINT64_MODIFIER "u", osdrop);
                 } else {
                     pcapng_debug("pcapng_read_interface_statistics_block: isb_osdrop length %u not 8 as expected", oh.option_length);
                 }
                 break;
             case(OPT_ISB_USRDELIV): /* isb_usrdeliv 8  */
                 if (oh.option_length == 8) {
+                    guint64 usrdeliv;
                     /*  Don't cast a guint8 * into a guint64 *--the
                      *  guint8 * may not point to something that's
                      *  aligned correctly.
                      */
-                    memcpy(&wblock->data.if_stats.isb_usrdeliv, option_content, sizeof(guint64));
+                    memcpy(&usrdeliv, option_content, sizeof(guint64));
                     if (pn->byte_swapped)
-                        wblock->data.if_stats.isb_usrdeliv = GUINT64_SWAP_LE_BE(wblock->data.if_stats.isb_usrdeliv);
-                    pcapng_debug("pcapng_read_interface_statistics_block: isb_usrdeliv %" G_GINT64_MODIFIER "u", wblock->data.if_stats.isb_usrdeliv);
+                        usrdeliv = GUINT64_SWAP_LE_BE(usrdeliv);
+                    wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_USRDELIV, usrdeliv);
+                    pcapng_debug("pcapng_read_interface_statistics_block: isb_usrdeliv %" G_GINT64_MODIFIER "u", usrdeliv);
                 } else {
                     pcapng_debug("pcapng_read_interface_statistics_block: isb_usrdeliv length %u not 8 as expected", oh.option_length);
                 }
@@ -2323,7 +2298,7 @@ pcapng_read_block(wtap *wth, FILE_T fh, pcapng_t *pn, wtapng_block_t *wblock, in
     pcapng_block_header_t bh;
     guint32 block_total_length;
 
-    memset(&(wblock->data), 0, sizeof(wblock->data));
+    wblock->block = NULL;
 
     /* Try to read the (next) block header */
     if (!wtap_read_bytes_or_eof(fh, &bh, sizeof bh, err, err_info)) {
@@ -2435,41 +2410,24 @@ pcapng_read_block(wtap *wth, FILE_T fh, pcapng_t *pn, wtapng_block_t *wblock, in
 static void
 pcapng_process_idb(wtap *wth, pcapng_t *pcapng, wtapng_block_t *wblock)
 {
-    wtapng_if_descr_t int_data;
+    wtap_optionblock_t int_data = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
     interface_info_t iface_info;
+    wtapng_if_descr_mandatory_t *if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data),
+                                *wblock_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(wblock->block);
+
+    wtap_optionblock_copy_options(int_data, wblock->block);
 
-    int_data.wtap_encap = wblock->data.if_descr.wtap_encap;
-    int_data.time_units_per_second = wblock->data.if_descr.time_units_per_second;
-    int_data.tsprecision = wblock->data.if_descr.tsprecision;
-    int_data.link_type = wblock->data.if_descr.link_type;
-    int_data.snap_len = wblock->data.if_descr.snap_len;
-    /* Options */
-    int_data.opt_comment = wblock->data.if_descr.opt_comment;
-    int_data.if_name = wblock->data.if_descr.if_name;
-    int_data.if_description = wblock->data.if_descr.if_description;
-    /* XXX: if_IPv4addr opt 4  Interface network address and netmask.*/
-    /* XXX: if_IPv6addr opt 5  Interface network address and prefix length (stored in the last byte).*/
-    /* XXX: if_MACaddr  opt 6  Interface Hardware MAC address (48 bits).*/
-    /* XXX: if_EUIaddr  opt 7  Interface Hardware EUI address (64 bits)*/
-    int_data.if_speed = wblock->data.if_descr.if_speed;
-    int_data.if_tsresol = wblock->data.if_descr.if_tsresol;
-    /* XXX: if_tzone      10  Time zone for GMT support (TODO: specify better). */
-    int_data.if_filter_str = wblock->data.if_descr.if_filter_str;
-    int_data.bpf_filter_len = wblock->data.if_descr.bpf_filter_len;
-    int_data.if_filter_bpf_bytes = wblock->data.if_descr.if_filter_bpf_bytes;
-    int_data.if_os = wblock->data.if_descr.if_os;
-    int_data.if_fcslen = wblock->data.if_descr.if_fcslen;
     /* XXX if_tsoffset; opt 14  A 64 bits integer value that specifies an offset (in seconds)...*/
     /* Interface statistics */
-    int_data.num_stat_entries = 0;
-    int_data.interface_statistics = NULL;
+    if_descr_mand->num_stat_entries = 0;
+    if_descr_mand->interface_statistics = NULL;
 
     g_array_append_val(wth->interface_data, int_data);
 
-    iface_info.wtap_encap = wblock->data.if_descr.wtap_encap;
-    iface_info.snap_len = wblock->data.if_descr.snap_len;
-    iface_info.time_units_per_second = wblock->data.if_descr.time_units_per_second;
-    iface_info.tsprecision = wblock->data.if_descr.tsprecision;
+    iface_info.wtap_encap = wblock_if_descr_mand->wtap_encap;
+    iface_info.snap_len = wblock_if_descr_mand->snap_len;
+    iface_info.time_units_per_second = wblock_if_descr_mand->time_units_per_second;
+    iface_info.tsprecision = wblock_if_descr_mand->tsprecision;
 
     g_array_append_val(pcapng->interfaces, iface_info);
 }
@@ -2506,14 +2464,14 @@ pcapng_open(wtap *wth, int *err, gchar **err_info)
 
     case PCAPNG_BLOCK_NOT_SHB:
         /* An error indicating that this isn't a pcap-ng file. */
-        pcapng_free_wtapng_block_data(&wblock);
+        wtap_optionblock_free(wblock.block);
         *err = 0;
         *err_info = NULL;
         return WTAP_OPEN_NOT_MINE;
 
     case PCAPNG_BLOCK_ERROR:
         /* An I/O error, or this probably *is* a pcap-ng file but not a valid one. */
-        pcapng_free_wtapng_block_data(&wblock);
+        wtap_optionblock_free(wblock.block);
         return WTAP_OPEN_ERROR;
     }
 
@@ -2525,7 +2483,7 @@ pcapng_open(wtap *wth, int *err, gchar **err_info)
          * binary data?
          */
         pcapng_debug("pcapng_open: first block type %u not SHB", wblock.type);
-        pcapng_free_wtapng_block_data(&wblock);
+        wtap_optionblock_free(wblock.block);
         return WTAP_OPEN_NOT_MINE;
     }
     pn.shb_read = TRUE;
@@ -2535,10 +2493,7 @@ pcapng_open(wtap *wth, int *err, gchar **err_info)
      * some other type of file, so we can't return WTAP_OPEN_NOT_MINE
      * past this point.
      */
-    wth->shb_hdr.opt_comment = wblock.data.section.opt_comment;
-    wth->shb_hdr.shb_hardware = wblock.data.section.shb_hardware;
-    wth->shb_hdr.shb_os = wblock.data.section.shb_os;
-    wth->shb_hdr.shb_user_appl = wblock.data.section.shb_user_appl;
+    wtap_optionblock_copy_options(wth->shb_hdr, wblock.block);
 
     wth->file_encap = WTAP_ENCAP_UNKNOWN;
     wth->snapshot_length = 0;
@@ -2583,11 +2538,11 @@ pcapng_open(wtap *wth, int *err, gchar **err_info)
         if (pcapng_read_block(wth, wth->fh, &pn, &wblock, err, err_info) != PCAPNG_BLOCK_OK) {
             if (*err == 0) {
                 pcapng_debug("No more IDBs available...");
-                pcapng_free_wtapng_block_data(&wblock);
+                wtap_optionblock_free(wblock.block);
                 break;
             } else {
                 pcapng_debug("pcapng_open: couldn't read IDB");
-                pcapng_free_wtapng_block_data(&wblock);
+                wtap_optionblock_free(wblock.block);
                 return WTAP_OPEN_ERROR;
             }
         }
@@ -2605,8 +2560,10 @@ pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
 {
     pcapng_t *pcapng = (pcapng_t *)wth->priv;
     wtapng_block_t wblock;
-    wtapng_if_descr_t *wtapng_if_descr;
-    wtapng_if_stats_t if_stats;
+    wtap_optionblock_t wtapng_if_descr = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR);
+    wtap_optionblock_t if_stats = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_STATS);
+    wtapng_if_stats_mandatory_t *if_stats_mand_block, *if_stats_mand;
+    wtapng_if_descr_mandatory_t *wtapng_if_descr_mand;
 
     wblock.frame_buffer  = wth->frame_buffer;
     wblock.packet_header = &wth->phdr;
@@ -2656,32 +2613,27 @@ pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
             case(BLOCK_TYPE_ISB):
                 /* Another interface statistics report */
                 pcapng_debug("pcapng_read: block type BLOCK_TYPE_ISB");
-                if (wth->interface_data->len <= wblock.data.if_stats.interface_id) {
-                    pcapng_debug("pcapng_read: BLOCK_TYPE_ISB wblock.if_stats.interface_id %u >= number_of_interfaces", wblock.data.if_stats.interface_id);
+                if_stats_mand_block = (wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(wblock.block);
+                if (wth->interface_data->len <= if_stats_mand_block->interface_id) {
+                    pcapng_debug("pcapng_read: BLOCK_TYPE_ISB wblock.if_stats.interface_id %u >= number_of_interfaces", if_stats_mand_block->interface_id);
                 } else {
                     /* Get the interface description */
-                    wtapng_if_descr = &g_array_index(wth->interface_data, wtapng_if_descr_t, wblock.data.if_stats.interface_id);
-                    if (wtapng_if_descr->num_stat_entries == 0) {
+                    wtapng_if_descr = g_array_index(wth->interface_data, wtap_optionblock_t, if_stats_mand_block->interface_id);
+                    wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(wtapng_if_descr);
+                    if (wtapng_if_descr_mand->num_stat_entries == 0) {
                         /* First ISB found, no previous entry */
                         pcapng_debug("pcapng_read: block type BLOCK_TYPE_ISB. First ISB found, no previous entry");
-                        wtapng_if_descr->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtapng_if_stats_t));
+                        wtapng_if_descr_mand->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
                     }
 
-                    if_stats.interface_id       = wblock.data.if_stats.interface_id;
-                    if_stats.ts_high            = wblock.data.if_stats.ts_high;
-                    if_stats.ts_low             = wblock.data.if_stats.ts_low;
-                    /* options */
-                    if_stats.opt_comment        = wblock.data.if_stats.opt_comment;     /* NULL if not available */
-                    if_stats.isb_starttime      = wblock.data.if_stats.isb_starttime;
-                    if_stats.isb_endtime        = wblock.data.if_stats.isb_endtime;
-                    if_stats.isb_ifrecv         = wblock.data.if_stats.isb_ifrecv;
-                    if_stats.isb_ifdrop         = wblock.data.if_stats.isb_ifdrop;
-                    if_stats.isb_filteraccept   = wblock.data.if_stats.isb_filteraccept;
-                    if_stats.isb_osdrop         = wblock.data.if_stats.isb_osdrop;
-                    if_stats.isb_usrdeliv       = wblock.data.if_stats.isb_usrdeliv;
-
-                    g_array_append_val(wtapng_if_descr->interface_statistics, if_stats);
-                    wtapng_if_descr->num_stat_entries++;
+                    if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(if_stats);
+                    if_stats_mand->interface_id  = if_stats_mand_block->interface_id;
+                    if_stats_mand->ts_high       = if_stats_mand_block->ts_high;
+                    if_stats_mand->ts_low        = if_stats_mand_block->ts_low;
+
+                    wtap_optionblock_copy_options(if_stats, wblock.block);
+                    g_array_append_val(wtapng_if_descr_mand->interface_statistics, if_stats);
+                    wtapng_if_descr_mand->num_stat_entries++;
                 }
                 break;
 
@@ -2723,7 +2675,7 @@ pcapng_seek_read(wtap *wth, gint64 seek_off,
 
     /* read the block */
     ret = pcapng_read_block(wth, wth->random_fh, pcapng, &wblock, err, err_info);
-    pcapng_free_wtapng_block_data(&wblock);
+    wtap_optionblock_free(wblock.block);
     if (ret != PCAPNG_BLOCK_OK) {
         pcapng_debug("pcapng_seek_read: couldn't read packet block (err=%d).",
                       *err);
@@ -2765,13 +2717,15 @@ pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
     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 */
-        if (wdh->shb_hdr->opt_comment) {
+        wtap_optionblock_get_option_string(wdh->shb_hdr, OPT_COMMENT, &opt_comment);
+        if (opt_comment) {
             have_options = TRUE;
-            comment_len = (guint32)strlen(wdh->shb_hdr->opt_comment) & 0xffff;
+            comment_len = (guint32)strlen(opt_comment) & 0xffff;
             if ((comment_len % 4)) {
                 comment_pad_len = 4 - (comment_len % 4);
             } else {
@@ -2781,9 +2735,10 @@ pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
         }
 
         /* Check if we should write shb_hardware option */
-        if (wdh->shb_hdr->shb_hardware) {
+        wtap_optionblock_get_option_string(wdh->shb_hdr, OPT_SHB_HARDWARE, &shb_hardware);
+        if (shb_hardware) {
             have_options = TRUE;
-            shb_hardware_len = (guint32)strlen(wdh->shb_hdr->shb_hardware) & 0xffff;
+            shb_hardware_len = (guint32)strlen(shb_hardware) & 0xffff;
             if ((shb_hardware_len % 4)) {
                 shb_hardware_pad_len = 4 - (shb_hardware_len % 4);
             } else {
@@ -2793,9 +2748,10 @@ pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
         }
 
         /* Check if we should write shb_os option */
-        if (wdh->shb_hdr->shb_os) {
+        wtap_optionblock_get_option_string(wdh->shb_hdr, OPT_SHB_OS, &shb_os);
+        if (shb_os) {
             have_options = TRUE;
-            shb_os_len = (guint32)strlen(wdh->shb_hdr->shb_os) & 0xffff;
+            shb_os_len = (guint32)strlen(shb_os) & 0xffff;
             if ((shb_os_len % 4)) {
                 shb_os_pad_len = 4 - (shb_os_len % 4);
             } else {
@@ -2805,9 +2761,10 @@ pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
         }
 
         /* Check if we should write shb_user_appl option */
-        if (wdh->shb_hdr->shb_user_appl) {
+        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(wdh->shb_hdr->shb_user_appl) & 0xffff;
+            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 {
@@ -2857,8 +2814,8 @@ pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
         wdh->bytes_dumped += 4;
 
         /* Write the comments string */
-        pcapng_debug("pcapng_write_section_header_block, comment:'%s' comment_len %u comment_pad_len %u" , wdh->shb_hdr->opt_comment, comment_len, comment_pad_len);
-        if (!wtap_dump_file_write(wdh, wdh->shb_hdr->opt_comment, comment_len, err))
+        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;
 
@@ -2878,8 +2835,8 @@ pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
         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" , wdh->shb_hdr->shb_hardware, shb_hardware_len, shb_hardware_pad_len);
-        if (!wtap_dump_file_write(wdh, wdh->shb_hdr->shb_hardware, shb_hardware_len, err))
+        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;
 
@@ -2899,8 +2856,8 @@ pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
         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" , wdh->shb_hdr->shb_os, shb_os_len, shb_os_pad_len);
-        if (!wtap_dump_file_write(wdh, wdh->shb_hdr->shb_os, shb_os_len, err))
+        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;
 
@@ -2920,8 +2877,8 @@ pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
         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" , wdh->shb_hdr->shb_user_appl, shb_user_appl_len, shb_user_appl_pad_len);
-        if (!wtap_dump_file_write(wdh, wdh->shb_hdr->shb_user_appl, shb_user_appl_len, err))
+        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;
 
@@ -2953,7 +2910,7 @@ pcapng_write_section_header_block(wtap_dumper *wdh, int *err)
 
 
 static gboolean
-pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *err)
+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;
@@ -2963,22 +2920,27 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
     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->link_type,
-                  wtap_encap_string(wtap_pcap_encap_to_wtap_encap(int_data->link_type)),
-                  int_data->snap_len);
+                  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->link_type == (guint16)-1) {
+    if (int_data_mand->link_type == (guint16)-1) {
         *err = WTAP_ERR_UNWRITABLE_ENCAP;
         return FALSE;
     }
 
     /* Calculate options length */
-    if (int_data->opt_comment) {
+    wtap_optionblock_get_option_string(int_data, OPT_COMMENT, &opt_comment);
+    if (opt_comment) {
         have_options = TRUE;
-        comment_len = (guint32)strlen(int_data->opt_comment) & 0xffff;
+        comment_len = (guint32)strlen(opt_comment) & 0xffff;
         if ((comment_len % 4)) {
             comment_pad_len = 4 - (comment_len % 4);
         } else {
@@ -2990,9 +2952,10 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
     /*
      * if_name        2  A UTF-8 string containing the name of the device used to capture data.
      */
-    if (int_data->if_name) {
+    wtap_optionblock_get_option_string(int_data, OPT_IDB_NAME, &if_name);
+    if (if_name) {
         have_options = TRUE;
-        if_name_len = (guint32)strlen(int_data->if_name) & 0xffff;
+        if_name_len = (guint32)strlen(if_name) & 0xffff;
         if ((if_name_len % 4)) {
             if_name_pad_len = 4 - (if_name_len % 4);
         } else {
@@ -3004,9 +2967,10 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
     /*
      * if_description 3  A UTF-8 string containing the description of the device used to capture data.
      */
-    if (int_data->if_description) {
+    wtap_optionblock_get_option_string(int_data, OPT_IDB_DESCR, &if_description);
+    if (if_description) {
         have_options = TRUE;
-        if_description_len = (guint32)strlen(int_data->if_description) & 0xffff;
+        if_description_len = (guint32)strlen(if_description) & 0xffff;
         if ((if_description_len % 4)) {
             if_description_pad_len = 4 - (if_description_len % 4);
         } else {
@@ -3023,14 +2987,16 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
     /*
      * if_speed       8  Interface speed (in bps). 100000000 for 100Mbps
      */
-    if (int_data->if_speed != 0) {
+    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.
      */
-    if (int_data->if_tsresol != 0) {
+    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;
     }
@@ -3041,9 +3007,10 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
      * 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).
      */
-    if (int_data->if_filter_str) {
+    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(int_data->if_filter_str) + 1) & 0xffff;
+        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 {
@@ -3054,9 +3021,10 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
     /*
      * if_os         12  A UTF-8 string containing the name of the operating system of the machine in which this interface is installed.
      */
-    if (int_data->if_os) {
+    wtap_optionblock_get_option_string(int_data, OPT_IDB_OS, &if_os);
+    if (if_os) {
         have_options = TRUE;
-        if_os_len = (guint32)strlen(int_data->if_os) & 0xffff;
+        if_os_len = (guint32)strlen(if_os) & 0xffff;
         if ((if_os_len % 4)) {
             if_os_pad_len = 4 - (if_os_len % 4);
         } else {
@@ -3068,7 +3036,8 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
      * 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.
      */
-    if (int_data->if_fcslen != 0) {
+    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
@@ -3089,9 +3058,9 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
     wdh->bytes_dumped += sizeof bh;
 
     /* write block fixed content */
-    idb.linktype    = int_data->link_type;
+    idb.linktype    = int_data_mand->link_type;
     idb.reserved    = 0;
-    idb.snaplen     = int_data->snap_len;
+    idb.snaplen     = int_data_mand->snap_len;
 
     if (!wtap_dump_file_write(wdh, &idb, sizeof idb, err))
         return FALSE;
@@ -3106,8 +3075,8 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
         wdh->bytes_dumped += 4;
 
         /* Write the comments string */
-        pcapng_debug("pcapng_write_if_descr_block, comment:'%s' comment_len %u comment_pad_len %u" , int_data->opt_comment, comment_len, comment_pad_len);
-        if (!wtap_dump_file_write(wdh, int_data->opt_comment, comment_len, err))
+        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;
 
@@ -3129,8 +3098,8 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
         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" , int_data->if_name, if_name_len, if_name_pad_len);
-        if (!wtap_dump_file_write(wdh, int_data->if_name, if_name_len, err))
+        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;
 
@@ -3152,8 +3121,8 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
         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" , int_data->if_description, if_description_len, if_description_pad_len);
-        if (!wtap_dump_file_write(wdh, int_data->if_description, if_description_len, err))
+        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;
 
@@ -3173,7 +3142,7 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
     /*
      * if_speed       8  Interface speed (in bps). 100000000 for 100Mbps
      */
-    if (int_data->if_speed != 0) {
+    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))
@@ -3181,8 +3150,8 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
         wdh->bytes_dumped += 4;
 
         /* Write the comments string */
-        pcapng_debug("pcapng_write_if_descr_block: if_speed %" G_GINT64_MODIFIER "u (bps)", int_data->if_speed);
-        if (!wtap_dump_file_write(wdh, &int_data->if_speed, sizeof(guint64), err))
+        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;
     }
@@ -3192,7 +3161,7 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
      * 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 (int_data->if_tsresol != 0) {
+    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))
@@ -3200,8 +3169,8 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
         wdh->bytes_dumped += 4;
 
         /* Write the time stamp resolution */
-        pcapng_debug("pcapng_write_if_descr_block: if_tsresol %u", int_data->if_tsresol);
-        if (!wtap_dump_file_write(wdh, &int_data->if_tsresol, 1, err))
+        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))
@@ -3229,9 +3198,9 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
         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" , int_data->if_filter_str, if_filter_str_len, if_filter_str_pad_len);
+        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, int_data->if_filter_str, if_filter_str_len-1, err))
+        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;
 
@@ -3253,8 +3222,8 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
         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" , int_data->if_os, if_os_len, if_os_pad_len);
-        if (!wtap_dump_file_write(wdh, int_data->if_os, if_os_len, err))
+        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;
 
@@ -3292,7 +3261,7 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtapng_if_descr_t *int_data, int *
 }
 
 static gboolean
-pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtapng_if_stats_t *if_stats, int *err)
+pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtap_optionblock_t if_stats, int *err)
 {
 
     pcapng_block_header_t bh;
@@ -3303,14 +3272,17 @@ pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtapng_if_stats_t *if_
     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 (if_stats->opt_comment) {
+    if (opt_comment) {
         have_options = TRUE;
-        comment_len = (guint32)strlen(if_stats->opt_comment) & 0xffff;
+        comment_len = (guint32)strlen(opt_comment) & 0xffff;
         if ((comment_len % 4)) {
             comment_pad_len = 4 - (comment_len % 4);
         } else {
@@ -3318,38 +3290,39 @@ pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtapng_if_stats_t *if_
         }
         options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ;
     }
-    /*guint64                           isb_starttime */
-    if (if_stats->isb_starttime != 0) {
+
+    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 */ ;
     }
-    /*guint64                           isb_endtime */
-    if (if_stats->isb_endtime != 0) {
+    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 */ ;
     }
-    /*guint64                           isb_ifrecv */
-    if (if_stats->isb_ifrecv != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
+    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 */ ;
     }
-    /*guint64                           isb_ifdrop */
-    if (if_stats->isb_ifdrop != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
+    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 */ ;
     }
-    /*guint64                           isb_filteraccept */
-    if (if_stats->isb_filteraccept != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
+    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 */ ;
     }
-    /*guint64                           isb_osdrop */
-    if (if_stats->isb_osdrop != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
+    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 */ ;
     }
-    /*guint64                           isb_usrdeliv */
-    if (if_stats->isb_usrdeliv != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
+    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 */ ;
     }
@@ -3369,10 +3342,11 @@ pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtapng_if_stats_t *if_
     wdh->bytes_dumped += sizeof bh;
 
     /* write block fixed content */
-    isb.interface_id                = if_stats->interface_id;
-    isb.timestamp_high              = if_stats->ts_high;
-    isb.timestamp_low               = if_stats->ts_low;
+    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;
@@ -3387,8 +3361,8 @@ pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtapng_if_stats_t *if_
         wdh->bytes_dumped += 4;
 
         /* Write the comments string */
-        pcapng_debug("pcapng_write_interface_statistics_block, comment:'%s' comment_len %u comment_pad_len %u" , if_stats->opt_comment, comment_len, comment_pad_len);
-        if (!wtap_dump_file_write(wdh, if_stats->opt_comment, comment_len, err))
+        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;
 
@@ -3400,19 +3374,19 @@ pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtapng_if_stats_t *if_
         }
     }
     /*guint64               isb_starttime */
-    if (if_stats->isb_starttime != 0) {
+    if (isb_starttime != 0) {
         guint32 high, low;
 
         option_hdr.type = OPT_ISB_STARTTIME;
         option_hdr.value_length = 8;
-        high = (guint32)((if_stats->isb_starttime>>32) & 0xffffffff);
-        low = (guint32)(if_stats->isb_starttime & 0xffffffff);
+        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" , if_stats->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;
@@ -3421,19 +3395,19 @@ pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtapng_if_stats_t *if_
         wdh->bytes_dumped += 4;
     }
     /*guint64               isb_endtime */
-    if (if_stats->isb_endtime != 0) {
+    if (isb_endtime != 0) {
         guint32 high, low;
 
         option_hdr.type = OPT_ISB_ENDTIME;
         option_hdr.value_length = 8;
-        high = (guint32)((if_stats->isb_endtime>>32) & 0xffffffff);
-        low = (guint32)(if_stats->isb_endtime & 0xffffffff);
+        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" , if_stats->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;
@@ -3442,7 +3416,7 @@ pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtapng_if_stats_t *if_
         wdh->bytes_dumped += 4;
     }
     /*guint64               isb_ifrecv;*/
-    if (if_stats->isb_ifrecv != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
+    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))
@@ -3450,13 +3424,13 @@ pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtapng_if_stats_t *if_
         wdh->bytes_dumped += 4;
 
         /* Write isb_ifrecv */
-        pcapng_debug("pcapng_write_interface_statistics_block, isb_ifrecv: %" G_GINT64_MODIFIER "u" , if_stats->isb_ifrecv);
-        if (!wtap_dump_file_write(wdh, &if_stats->isb_ifrecv, 8, err))
+        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 (if_stats->isb_ifdrop != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
+    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))
@@ -3464,13 +3438,13 @@ pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtapng_if_stats_t *if_
         wdh->bytes_dumped += 4;
 
         /* Write isb_ifdrop */
-        pcapng_debug("pcapng_write_interface_statistics_block, isb_ifdrop: %" G_GINT64_MODIFIER "u" , if_stats->isb_ifdrop);
-        if (!wtap_dump_file_write(wdh, &if_stats->isb_ifdrop, 8, err))
+        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 (if_stats->isb_filteraccept != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
+    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))
@@ -3478,13 +3452,13 @@ pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtapng_if_stats_t *if_
         wdh->bytes_dumped += 4;
 
         /* Write isb_filteraccept */
-        pcapng_debug("pcapng_write_interface_statistics_block, isb_filteraccept: %" G_GINT64_MODIFIER "u" , if_stats->isb_filteraccept);
-        if (!wtap_dump_file_write(wdh, &if_stats->isb_filteraccept, 8, err))
+        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 (if_stats->isb_osdrop != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
+    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))
@@ -3492,13 +3466,13 @@ pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtapng_if_stats_t *if_
         wdh->bytes_dumped += 4;
 
         /* Write isb_osdrop */
-        pcapng_debug("pcapng_write_interface_statistics_block, isb_osdrop: %" G_GINT64_MODIFIER "u" , if_stats->isb_osdrop);
-        if (!wtap_dump_file_write(wdh, &if_stats->isb_osdrop, 8, err))
+        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 (if_stats->isb_usrdeliv != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF)) {
+    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))
@@ -3506,8 +3480,8 @@ pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtapng_if_stats_t *if_
         wdh->bytes_dumped += 4;
 
         /* Write isb_usrdeliv */
-        pcapng_debug("pcapng_write_interface_statistics_block, isb_usrdeliv: %" G_GINT64_MODIFIER "u" , if_stats->isb_usrdeliv);
-        if (!wtap_dump_file_write(wdh, &if_stats->isb_usrdeliv, 8, err))
+        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;
     }
@@ -3546,7 +3520,8 @@ pcapng_write_enhanced_packet_block(wtap_dumper *wdh,
     guint32 options_total_length = 0;
     struct option option_hdr;
     guint32 comment_len = 0, comment_pad_len = 0;
-    wtapng_if_descr_t int_data;
+    wtap_optionblock_t int_data;
+    wtapng_if_descr_mandatory_t *int_data_mand;
 
     /* Don't write anything we're not willing to read. */
     if (phdr->caplen > WTAP_MAX_PACKET_SIZE) {
@@ -3611,10 +3586,11 @@ pcapng_write_enhanced_packet_block(wtap_dumper *wdh,
         *err = WTAP_ERR_INTERNAL;
         return FALSE;
     }
-    int_data = g_array_index(wdh->interface_data, wtapng_if_descr_t,
+    int_data = g_array_index(wdh->interface_data, wtap_optionblock_t,
                              epb.interface_id);
-    ts = ((guint64)phdr->ts.secs) * int_data.time_units_per_second +
-        (((guint64)phdr->ts.nsecs) * int_data.time_units_per_second) / 1000000000;
+    int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data);
+    ts = ((guint64)phdr->ts.secs) * int_data_mand->time_units_per_second +
+        (((guint64)phdr->ts.nsecs) * int_data_mand->time_units_per_second) / 1000000000;
     epb.timestamp_high      = (guint32)(ts >> 32);
     epb.timestamp_low       = (guint32)ts;
     epb.captured_len        = phdr->caplen + phdr_len;
@@ -3876,13 +3852,15 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
         guint32 options_total_length = 0;
         struct option option_hdr;
         guint32 comment_len = 0, comment_pad_len = 0;
-        wtapng_name_res_t *nrb_hdr = wdh->nrb_hdr;
+        wtap_optionblock_t nrb_hdr = wdh->nrb_hdr;
         guint32 prev_rec_off = rec_off;
+        char* opt_comment;
 
         /* get lengths first to make sure we can fit this into the block */
-        if (nrb_hdr->opt_comment) {
+        wtap_optionblock_get_option_string(nrb_hdr, OPT_COMMENT, &opt_comment);
+        if (opt_comment) {
             have_options = TRUE;
-            comment_len = (guint32)strlen(nrb_hdr->opt_comment) & 0xffff;
+            comment_len = (guint32)strlen(opt_comment) & 0xffff;
             if ((comment_len % 4)) {
                 comment_pad_len = 4 - (comment_len % 4);
             } else {
@@ -3935,7 +3913,7 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err)
                 rec_off += (guint32)sizeof(option_hdr);
 
                 /* Write the comments string */
-                memcpy(rec_data + rec_off, nrb_hdr->opt_comment, comment_len);
+                memcpy(rec_data + rec_off, opt_comment, comment_len);
                 rec_off += comment_len;
                 memset(rec_data + rec_off, 0, comment_pad_len);
                 rec_off += comment_pad_len;
@@ -4039,15 +4017,18 @@ static gboolean pcapng_dump_finish(wtap_dumper *wdh, int *err)
     for (i = 0; i < wdh->interface_data->len; i++) {
 
         /* Get the interface description */
-        wtapng_if_descr_t int_data;
+        wtap_optionblock_t int_data;
+        wtapng_if_descr_mandatory_t *int_data_mand;
+
+        int_data = g_array_index(wdh->interface_data, wtap_optionblock_t, i);
+        int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data);
 
-        int_data = g_array_index(wdh->interface_data, wtapng_if_descr_t, i);
-        for (j = 0; j < int_data.num_stat_entries; j++) {
-            wtapng_if_stats_t if_stats;
+        for (j = 0; j < int_data_mand->num_stat_entries; j++) {
+            wtap_optionblock_t if_stats;
 
-            if_stats = g_array_index(int_data.interface_statistics, wtapng_if_stats_t, j);
-            pcapng_debug("pcapng_dump_finish: write ISB for interface %u",if_stats.interface_id);
-            if (!pcapng_write_interface_statistics_block(wdh, &if_stats, 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)) {
                 return FALSE;
             }
         }
@@ -4089,11 +4070,11 @@ pcapng_dump_open(wtap_dumper *wdh, int *err)
     for (i = 0; i < wdh->interface_data->len; i++) {
 
         /* Get the interface description */
-        wtapng_if_descr_t int_data;
+        wtap_optionblock_t int_data;
 
-        int_data = g_array_index(wdh->interface_data, wtapng_if_descr_t, i);
+        int_data = g_array_index(wdh->interface_data, wtap_optionblock_t, i);
 
-        if (!pcapng_write_if_descr_block(wdh, &int_data, err)) {
+        if (!pcapng_write_if_descr_block(wdh, int_data, err)) {
             return FALSE;
         }
 
index a568ab1a949cf4452acfdcff6ffc8d5ff8508b4e..7827a834824bbe8fb88021ef38ebf93575dc59b0 100644 (file)
 #define __W_PCAPNG_H__
 
 #include <glib.h>
-#include <wtap.h>
+#include "wtap.h"
 #include "ws_symbol_export.h"
 
+/* Option codes: 16-bit field */
+#define OPT_EOFOPT           0x0000
+#define OPT_COMMENT          0x0001 /**< NULL if not available */
+
+/* Section Header block (SHB) */
+#define OPT_SHB_HARDWARE     0x0002 /**< NULL if not available
+                                     *     UTF-8 string containing the description of the
+                                     *     hardware used to create this section.
+                                     */
+#define OPT_SHB_OS           0x0003 /**< NULL if not available, UTF-8 string containing the
+                                     *     name of the operating system used to create this section.
+                                     */
+#define OPT_SHB_USERAPPL     0x0004 /**< NULL if not available, UTF-8 string containing the
+                                     *     name of the application used to create this section.
+                                     */
+
+/* Interface Description block (IDB) */
+#define OPT_IDB_NAME         0x0002 /**< NULL if not available, A UTF-8 string containing the name
+                                     *     of the device used to capture data.
+                                     *     "eth0" / "\Device\NPF_{AD1CE675-96D0-47C5-ADD0-2504B9126B68}"
+                                     */
+#define OPT_IDB_DESCR        0x0003 /**< NULL if not available, A UTF-8 string containing the description
+                                     *     of the device used to capture data.
+                                     *     "Broadcom NetXtreme" / "First Ethernet Interface"
+                                     */
+#define OPT_IDB_IP4ADDR      0x0004 /**< XXX: if_IPv4addr Interface network address and netmask.
+                                     *     This option can be repeated multiple times within the same Interface Description Block
+                                     *     when multiple IPv4 addresses are assigned to the interface.
+                                     *     192 168 1 1 255 255 255 0
+                                     */
+#define OPT_IDB_IP6ADDR      0x0005 /* XXX: if_IPv6addr Interface network address and prefix length (stored in the last byte).
+                                     *     This option can be repeated multiple times within the same Interface
+                                     *     Description Block when multiple IPv6 addresses are assigned to the interface.
+                                     *     2001:0db8:85a3:08d3:1319:8a2e:0370:7344/64 is written (in hex) as
+                                     *     "20 01 0d b8 85 a3 08 d3 13 19 8a 2e 03 70 73 44 40"*/
+#define OPT_IDB_MACADDR      0x0006 /* XXX: if_MACaddr  Interface Hardware MAC address (48 bits).                             */
+#define OPT_IDB_EUIADDR      0x0007 /* XXX: if_EUIaddr  Interface Hardware EUI address (64 bits)                              */
+#define OPT_IDB_SPEED        0x0008 /**< 0xFFFFFFFF if unknown
+                                     *     Interface speed (in bps). 100000000 for 100Mbps
+                                     */
+#define OPT_IDB_TSRESOL      0x0009 /**< 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 (e.g. 6 means microsecond resolution, timestamps
+                                     *     are the number of microseconds since 1/1/1970). If the Most Significant Bit
+                                     *     is equal to one, the remaining bits indicates the resolution has a
+                                     *     negative power of 2 (e.g. 10 means 1/1024 of second).
+                                     *     If this option is not present, a resolution of 10^-6 is assumed
+                                     *     (i.e. timestamps have the same resolution of the standard 'libpcap' timestamps).
+                                     */
+#define OPT_IDB_TZONE        0x000A /* XXX: if_tzone    Time zone for GMT support (TODO: specify better). */
+#define OPT_IDB_FILTER       0x000B /**< 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).
+                                     *     More details about this format will be presented in Appendix XXX (TODO).
+                                     *     (TODO: better use different options for different fields?
+                                     *     e.g. if_filter_pcap, if_filter_bpf, ...) 00 "tcp port 23 and host 10.0.0.5"
+                                     */
+#define OPT_IDB_OS           0x000C /**< NULL if not available, A UTF-8 string containing the name of the operating system of the
+                                     *     machine in which this interface is installed.
+                                     *     This can be different from the same information that can be
+                                     *     contained by the Section Header Block
+                                     *     (Section 3.1 (Section Header Block (mandatory))) because
+                                     *     the capture can have been done on a remote machine.
+                                     *     "Windows XP SP2" / "openSUSE 10.2"
+                                     */
+#define OPT_IDB_FCSLEN       0x000D /**< An integer value that specified the length of the
+                                     *     Frame Check Sequence (in bits) for this interface.
+                                     *     For link layers whose FCS length can change during time,
+                                     *     the Packet Block Flags Word can be used (see Appendix A (Packet Block Flags Word))
+                                     */
+#define OPT_IDB_TSOFFSET     0x000E /**< XXX: 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. The time zone of the offset can be specified with the
+                                     *                     option if_tzone. TODO: won't a if_tsoffset_low for fractional
+                                     *                     second offsets be useful for highly syncronized capture systems?
+                                     */
+
+#define OPT_ISB_STARTTIME    0x0002
+#define OPT_ISB_ENDTIME      0x0003
+#define OPT_ISB_IFRECV       0x0004
+#define OPT_ISB_IFDROP       0x0005
+#define OPT_ISB_FILTERACCEPT 0x0006
+#define OPT_ISB_OSDROP       0x0007
+#define OPT_ISB_USRDELIV     0x0008
+
 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);
index 332d836c57813c9049785fd14864bf6c3ba7d856..89726ece9e6eaad7718ad6043c436193d5ce1155 100644 (file)
@@ -31,6 +31,7 @@
 #include <wsutil/file_util.h>
 
 #include "wtap.h"
+#include "wtap_opttypes.h"
 
 WS_DLL_PUBLIC
 int wtap_fstat(wtap *wth, ws_statb64 *statb, int *err);
@@ -39,6 +40,7 @@ typedef gboolean (*subtype_read_func)(struct wtap*, int*, char**, gint64*);
 typedef gboolean (*subtype_seek_read_func)(struct wtap*, gint64,
                                            struct wtap_pkthdr *, Buffer *buf,
                                            int *, char **);
+
 /**
  * Struct holding data of the currently read file.
  */
@@ -49,9 +51,9 @@ struct wtap {
     guint                       snapshot_length;
     struct Buffer               *frame_buffer;
     struct wtap_pkthdr          phdr;
-    struct wtapng_section_s     shb_hdr;
+    wtap_optionblock_t          shb_hdr;
     GArray                      *interface_data;        /**< An array holding the interface data from pcapng IDB:s or equivalent(?)*/
-    wtapng_name_res_t           *nrb_hdr;               /**< holds the Name Res Block's comment/custom_opts, or NULL */
+    wtap_optionblock_t          nrb_hdr;               /**< holds the Name Res Block's comment/custom_opts, or NULL */
 
     void                        *priv;          /* this one holds per-file state and is free'd automatically by wtap_close() */
     void                        *wslua_data;    /* this one holds wslua state info and is not free'd */
@@ -112,8 +114,8 @@ struct wtap_dumper {
                                              * e.g. WTAP_TSPREC_USEC
                                              */
     addrinfo_lists_t        *addrinfo_lists; /**< Struct containing lists of resolved addresses */
-    wtapng_section_t        *shb_hdr;
-    wtapng_name_res_t       *nrb_hdr;        /**< name resolution comment/custom_opt, or NULL */
+    wtap_optionblock_t       shb_hdr;
+    wtap_optionblock_t       nrb_hdr;        /**< name resolution comment/custom_opt, or NULL */
     GArray                  *interface_data; /**< An array holding the interface data from pcapng IDB:s or equivalent(?) NULL if not present.*/
 };
 
index 3dfb42629796aacbe51fa6b53896ebbf5f496e1b..cdb031ef7c1e4da4ec6bd3edbb79466e306fe2a3 100644 (file)
@@ -28,6 +28,8 @@
 #endif
 
 #include "wtap-int.h"
+#include "wtap_opttypes.h"
+#include "pcapng.h"
 
 #include "file_wrappers.h"
 #include <wsutil/file_util.h>
@@ -79,6 +81,9 @@ DIAG_ON(pedantic)
 void
 wtap_register_plugin_types(void)
 {
+       /* Piggyback the initialization here for now */
+       wtap_opttypes_initialize();
+
        add_plugin_type("libwiretap", check_for_wtap_plugin);
 }
 
@@ -160,29 +165,34 @@ wtap_file_tsprec(wtap *wth)
 const gchar *
 wtap_file_get_shb_comment(wtap *wth)
 {
-       return wth ? wth->shb_hdr.opt_comment : NULL;
+       char* opt_comment;
+       if (wth == NULL)
+               return NULL;
+
+       wtap_optionblock_get_option_string(wth->shb_hdr, OPT_COMMENT, &opt_comment);
+       return opt_comment;
 }
 
-const wtapng_section_t *
+wtap_optionblock_t
 wtap_file_get_shb(wtap *wth)
 {
-       return wth ? &(wth->shb_hdr) : NULL;
+       return wth ? wth->shb_hdr : NULL;
 }
 
-wtapng_section_t *
+wtap_optionblock_t
 wtap_file_get_shb_for_new_file(wtap *wth)
 {
-       wtapng_section_t *shb_hdr;
+       wtap_optionblock_t shb_hdr;
+       char* opt_comment;
 
        if (wth == NULL)
-           return NULL;
+               return NULL;
 
-       shb_hdr = g_new0(wtapng_section_t,1);
+       shb_hdr = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION);
 
-       shb_hdr->section_length = -1;
        /* options */
-       shb_hdr->opt_comment = g_strdup(wth->shb_hdr.opt_comment);
-       /* the rest of the options remain NULL */
+       wtap_optionblock_get_option_string(wth->shb_hdr, OPT_COMMENT, &opt_comment);
+       wtap_optionblock_set_option_string(shb_hdr, OPT_COMMENT, opt_comment);
 
        return shb_hdr;
 }
@@ -190,12 +200,14 @@ wtap_file_get_shb_for_new_file(wtap *wth)
 const gchar*
 wtap_get_nrb_comment(wtap *wth)
 {
+       char* opt_comment;
        g_assert(wth);
 
-       if (wth == NULL)
+       if ((wth == NULL) || (wth->nrb_hdr == NULL))
                return NULL;
 
-       return wth->nrb_hdr ? wth->nrb_hdr->opt_comment : NULL;
+       wtap_optionblock_get_option_string(wth->nrb_hdr, OPT_COMMENT, &opt_comment);
+       return opt_comment;
 }
 
 void
@@ -207,38 +219,16 @@ wtap_write_nrb_comment(wtap *wth, gchar *comment)
                return;
 
        if (wth->nrb_hdr == NULL) {
-               wth->nrb_hdr = g_new0(wtapng_name_res_t,1);
-       } else {
-               g_free(wth->nrb_hdr->opt_comment);
+               wth->nrb_hdr = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_NRB);
        }
 
-       /*
-        * I'd prefer this function duplicate the passed-in comment,
-        * but wtap_write_shb_comment() assumes the caller duplicated
-        * it so we'll stick with that.
-        */
-       wth->nrb_hdr->opt_comment = comment;
-}
-
-void
-wtap_free_shb(wtapng_section_t *shb_hdr)
-{
-       if (shb_hdr == NULL)
-           return;
-
-       g_free(shb_hdr->opt_comment);
-       g_free(shb_hdr->shb_hardware);
-       g_free(shb_hdr->shb_os);
-       g_free(shb_hdr->shb_user_appl);
-       g_free(shb_hdr);
+       wtap_optionblock_set_option_string(wth->nrb_hdr, OPT_COMMENT, comment);
 }
 
 void
 wtap_write_shb_comment(wtap *wth, gchar *comment)
 {
-       g_free(wth->shb_hdr.opt_comment);
-       wth->shb_hdr.opt_comment = comment;
-
+       wtap_optionblock_set_option_string(wth->shb_hdr, OPT_COMMENT, comment);
 }
 
 wtapng_iface_descriptions_t *
@@ -253,47 +243,18 @@ wtap_file_get_idb_info(wtap *wth)
        return idb_info;
 }
 
-static void
-wtap_free_isb_members(wtapng_if_stats_t *isb)
-{
-       if (isb) {
-               g_free(isb->opt_comment);
-       }
-}
-
-static void
-wtap_free_idb_members(wtapng_if_descr_t* idb)
-{
-       if (idb) {
-               g_free(idb->opt_comment);
-               g_free(idb->if_os);
-               g_free(idb->if_name);
-               g_free(idb->if_description);
-               g_free(idb->if_filter_str);
-               g_free(idb->if_filter_bpf_bytes);
-               if (idb->interface_statistics) {
-                       wtapng_if_stats_t *isb;
-                       guint i;
-                       for (i = 0; i < idb->interface_statistics->len; i++) {
-                               isb = &g_array_index(idb->interface_statistics, wtapng_if_stats_t, i);
-                               wtap_free_isb_members(isb);
-                       }
-                       g_array_free(idb->interface_statistics, TRUE);
-               }
-       }
-}
 
 void
 wtap_free_idb_info(wtapng_iface_descriptions_t *idb_info)
 {
        if (idb_info == NULL)
-           return;
+               return;
 
        if (idb_info->interface_data) {
                guint i;
                for (i = 0; i < idb_info->interface_data->len; i++) {
-                       wtapng_if_descr_t* idb = &g_array_index(idb_info->interface_data, wtapng_if_descr_t, i);
-                       wtap_free_idb_members(idb);
+                       wtap_optionblock_t idb = g_array_index(idb_info->interface_data, wtap_optionblock_t, i);
+                       wtap_optionblock_free(idb);
                }
                g_array_free(idb_info->interface_data, TRUE);
        }
@@ -302,117 +263,120 @@ wtap_free_idb_info(wtapng_iface_descriptions_t *idb_info)
 }
 
 gchar *
-wtap_get_debug_if_descr(const wtapng_if_descr_t *if_descr,
+wtap_get_debug_if_descr(const wtap_optionblock_t if_descr,
                         const int indent,
                         const char* line_end)
 {
+       char* tmp_content;
+       wtapng_if_descr_mandatory_t* if_descr_mand;
        GString *info = g_string_new("");
+       guint64 tmp64;
+       gint8 itmp8;
+       guint8 tmp8;
+       wtapng_if_descr_filter_t* if_filter;
 
        g_assert(if_descr);
 
+       if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(if_descr);
+       wtap_optionblock_get_option_string(if_descr, OPT_IDB_NAME, &tmp_content);
        g_string_printf(info,
                        "%*cName = %s%s", indent, ' ',
-                       if_descr->if_name ? if_descr->if_name : "UNKNOWN",
+                       tmp_content ? tmp_content : "UNKNOWN",
                        line_end);
 
+       wtap_optionblock_get_option_string(if_descr, OPT_IDB_DESCR, &tmp_content);
        g_string_append_printf(info,
                        "%*cDescription = %s%s", indent, ' ',
-                       if_descr->if_description ? if_descr->if_description : "NONE",
+                       tmp_content ? tmp_content : "NONE",
                        line_end);
 
        g_string_append_printf(info,
                        "%*cEncapsulation = %s (%d/%u - %s)%s", indent, ' ',
-                       wtap_encap_string(if_descr->wtap_encap),
-                       if_descr->wtap_encap,
-                       if_descr->link_type,
-                       wtap_encap_short_string(if_descr->wtap_encap),
+                       wtap_encap_string(if_descr_mand->wtap_encap),
+                       if_descr_mand->wtap_encap,
+                       if_descr_mand->link_type,
+                       wtap_encap_short_string(if_descr_mand->wtap_encap),
                        line_end);
 
+       wtap_optionblock_get_option_uint64(if_descr, OPT_IDB_SPEED, &tmp64);
        g_string_append_printf(info,
                        "%*cSpeed = %" G_GINT64_MODIFIER "u%s", indent, ' ',
-                       if_descr->if_speed,
+                       tmp64,
                        line_end);
 
        g_string_append_printf(info,
                        "%*cCapture length = %u%s", indent, ' ',
-                       if_descr->snap_len,
+                       if_descr_mand->snap_len,
                        line_end);
 
+       wtap_optionblock_get_option_uint8(if_descr, OPT_IDB_FCSLEN, &itmp8);
        g_string_append_printf(info,
                        "%*cFCS length = %d%s", indent, ' ',
-                       if_descr->if_fcslen,
+                       itmp8,
                        line_end);
 
        g_string_append_printf(info,
                        "%*cTime precision = %s (%d)%s", indent, ' ',
-                       wtap_tsprec_string(if_descr->tsprecision),
-                       if_descr->tsprecision,
+                       wtap_tsprec_string(if_descr_mand->tsprecision),
+                       if_descr_mand->tsprecision,
                        line_end);
 
        g_string_append_printf(info,
                        "%*cTime ticks per second = %" G_GINT64_MODIFIER "u%s", indent, ' ',
-                       if_descr->time_units_per_second,
+                       if_descr_mand->time_units_per_second,
                        line_end);
 
+       wtap_optionblock_get_option_uint8(if_descr, OPT_IDB_TSRESOL, &tmp8);
        g_string_append_printf(info,
                        "%*cTime resolution = 0x%.2x%s", indent, ' ',
-                       if_descr->if_tsresol,
+                       tmp8,
                        line_end);
 
+       wtap_optionblock_get_option_custom(if_descr, OPT_IDB_FILTER, (void**)&if_filter);
        g_string_append_printf(info,
                        "%*cFilter string = %s%s", indent, ' ',
-                       if_descr->if_filter_str ? if_descr->if_filter_str : "NONE",
+                       if_filter->if_filter_str ? if_filter->if_filter_str : "NONE",
                        line_end);
 
+       wtap_optionblock_get_option_string(if_descr, OPT_IDB_OS, &tmp_content);
        g_string_append_printf(info,
                        "%*cOperating system = %s%s", indent, ' ',
-                       if_descr->if_os ? if_descr->if_os : "UNKNOWN",
+                       tmp_content ? tmp_content : "UNKNOWN",
                        line_end);
 
+       wtap_optionblock_get_option_string(if_descr, OPT_COMMENT, &tmp_content);
        g_string_append_printf(info,
                        "%*cComment = %s%s", indent, ' ',
-                       if_descr->opt_comment ? if_descr->opt_comment : "NONE",
+                       tmp_content ? tmp_content : "NONE",
                        line_end);
 
        g_string_append_printf(info,
                        "%*cBPF filter length = %u%s", indent, ' ',
-                       if_descr->bpf_filter_len,
+                       if_filter->bpf_filter_len,
                        line_end);
 
        g_string_append_printf(info,
                        "%*cNumber of stat entries = %u%s", indent, ' ',
-                       if_descr->num_stat_entries,
+                       if_descr_mand->num_stat_entries,
                        line_end);
 
        return g_string_free(info, FALSE);
 }
 
-wtapng_name_res_t *
+wtap_optionblock_t
 wtap_file_get_nrb_for_new_file(wtap *wth)
 {
-       wtapng_name_res_t *nrb_hdr;
+       wtap_optionblock_t nrb_hdr;
 
        if (wth == NULL || wth->nrb_hdr == NULL)
-           return NULL;
-
-       nrb_hdr = g_new0(wtapng_name_res_t,1);
+               return NULL;
 
-       nrb_hdr->opt_comment = g_strdup(wth->nrb_hdr->opt_comment);
+       nrb_hdr = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_NRB);
 
+       wtap_optionblock_copy_options(nrb_hdr, wth->nrb_hdr);
        return nrb_hdr;
 }
 
-void
-wtap_free_nrb(wtapng_name_res_t *nrb_hdr)
-{
-       if (nrb_hdr == NULL)
-           return;
-
-       g_free(nrb_hdr->opt_comment);
-       g_free(nrb_hdr);
-}
-
-
 /* Table of the encapsulation types we know about. */
 struct encap_type_info {
        const char *name;
@@ -1217,8 +1181,9 @@ void
 wtap_close(wtap *wth)
 {
        guint i, j;
-       wtapng_if_descr_t *wtapng_if_descr;
-       wtapng_if_stats_t *if_stats;
+       wtap_optionblock_t wtapng_if_descr;
+       wtap_optionblock_t if_stats;
+       wtapng_if_descr_mandatory_t* wtapng_if_descr_mand;
 
        wtap_sequential_close(wth);
 
@@ -1236,40 +1201,16 @@ wtap_close(wtap *wth)
                g_ptr_array_free(wth->fast_seek, TRUE);
        }
 
-       g_free(wth->shb_hdr.opt_comment);
-       g_free(wth->shb_hdr.shb_hardware);
-       g_free(wth->shb_hdr.shb_os);
-       g_free(wth->shb_hdr.shb_user_appl);
+       wtap_optionblock_free(wth->shb_hdr);
 
        for(i = 0; i < wth->interface_data->len; i++) {
-               wtapng_if_descr = &g_array_index(wth->interface_data, wtapng_if_descr_t, i);
-               if(wtapng_if_descr->opt_comment != NULL){
-                       g_free(wtapng_if_descr->opt_comment);
-               }
-               if(wtapng_if_descr->if_name != NULL){
-                       g_free(wtapng_if_descr->if_name);
-               }
-               if(wtapng_if_descr->if_description != NULL){
-                       g_free(wtapng_if_descr->if_description);
-               }
-               if(wtapng_if_descr->if_filter_str != NULL){
-                       g_free(wtapng_if_descr->if_filter_str);
-               }
-               if(wtapng_if_descr->if_filter_bpf_bytes != NULL){
-                       g_free(wtapng_if_descr->if_filter_bpf_bytes);
-               }
-               if(wtapng_if_descr->if_os != NULL){
-                       g_free(wtapng_if_descr->if_os);
-               }
-               for(j = 0; j < wtapng_if_descr->num_stat_entries; j++) {
-                       if_stats = &g_array_index(wtapng_if_descr->interface_statistics, wtapng_if_stats_t, j);
-                       if(if_stats->opt_comment != NULL){
-                               g_free(if_stats->opt_comment);
-                       }
-               }
-               if(wtapng_if_descr->num_stat_entries != 0){
-                       g_array_free(wtapng_if_descr->interface_statistics, TRUE);
+               wtapng_if_descr = g_array_index(wth->interface_data, wtap_optionblock_t, i);
+               wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(wtapng_if_descr);
+               for(j = 0; j < wtapng_if_descr_mand->num_stat_entries; j++) {
+                       if_stats = g_array_index(wtapng_if_descr_mand->interface_statistics, wtap_optionblock_t, j);
+                       wtap_optionblock_free(if_stats);
                }
+               wtap_optionblock_free(wtapng_if_descr);
        }
        g_array_free(wth->interface_data, TRUE);
        g_free(wth);
index 73b9f73c557d9cffd381478a2ad9cb843834f3cd..169f26c7798b63b2bcf2af1fce60eab68a872de8 100644 (file)
@@ -25,6 +25,7 @@
 #include <time.h>
 #include <wsutil/buffer.h>
 #include <wsutil/nstime.h>
+#include "wtap_opttypes.h"
 #include "ws_symbol_export.h"
 
 #ifdef __cplusplus
@@ -1249,10 +1250,9 @@ struct wtap_pkthdr {
 #define WTAP_HAS_PACK_FLAGS    0x00000020  /**< packet flags */
 
 /**
- * Holds the option strings from pcapng:s Section Header block(SHB).
+ * Holds the required data from pcapng:s Section Header block(SHB).
  */
-typedef struct wtapng_section_s {
-    /* mandatory */
+typedef struct wtapng_section_mandatory_s {
     guint64             section_length; /**< 64-bit value specifying the length in bytes of the
                                          *     following section.
                                          *     Section Length equal -1 (0xFFFFFFFFFFFFFFFF) means
@@ -1261,185 +1261,49 @@ typedef struct wtapng_section_s {
                                          *     be invalid if anything changes, such as the other
                                          *     members of this struct, or the packets written.
                                          */
-    /* options */
-    gchar               *opt_comment;   /**< NULL if not available */
-    gchar               *shb_hardware;  /**< NULL if not available
-                                         *     UTF-8 string containing the description of the
-                                         *     hardware used to create this section.
-                                         */
-    gchar               *shb_os;        /**< NULL if not available, UTF-8 string containing the
-                                         *     name of the operating system used to create this section.
-                                         */
-    gchar               *shb_user_appl; /**< NULL if not available, UTF-8 string containing the
-                                         *     name of the application used to create this section.
-                                         */
-} wtapng_section_t;
-
+} wtapng_mandatory_section_t;
 
 /** struct holding the information to build IDB:s
- *  the interface_data array holds an array of wtapng_if_descr_t
- *  one per interface.
+ *  the interface_data array holds an array of wtap_optionblock_t
+ *  represending IDB of one per interface.
  */
 typedef struct wtapng_iface_descriptions_s {
     GArray *interface_data;
 } wtapng_iface_descriptions_t;
 
-/* Interface Description
- *
- * Options:
- *
- * if_name        2  A UTF-8 string containing the name of the device used to capture data.
- *                     "eth0" / "\Device\NPF_{AD1CE675-96D0-47C5-ADD0-2504B9126B68}" / ...
- *
- * if_description 3  A UTF-8 string containing the description of the device used
- *                     to capture data. "Broadcom NetXtreme" / "First Ethernet Interface" / ...
- *
- * if_IPv4addr    4  Interface network address and netmask. This option can be
- *                     repeated multiple times within the same Interface Description Block
- *                     when multiple IPv4 addresses are assigned to the interface. 192 168 1 1 255 255 255 0
- *
- * if_IPv6addr    5  Interface network address and prefix length (stored in the last byte).
- *                     This option can be repeated multiple times within the same Interface
- *                     Description Block when multiple IPv6 addresses are assigned to the interface.
- *                     2001:0db8:85a3:08d3:1319:8a2e:0370:7344/64 is written (in hex) as
- *                     "20 01 0d b8 85 a3 08 d3 13 19 8a 2e 03 70 73 44 40"
- *
- * 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_tsresol     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 (e.g. 6 means microsecond resolution, timestamps
- *                     are the number of microseconds since 1/1/1970). If the Most Significant Bit
- *                     is equal to one, the remaining bits indicates the resolution has a
- *                     negative power of 2 (e.g. 10 means 1/1024 of second).
- *                     If this option is not present, a resolution of 10^-6 is assumed
- *                     (i.e. timestamps have the same resolution of the standard 'libpcap' timestamps). 6
- *
- * 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).
- *                     More details about this format will be presented in Appendix XXX (TODO).
- *                     (TODO: better use different options for different fields?
- *                     e.g. if_filter_pcap, if_filter_bpf, ...) 00 "tcp port 23 and host 10.0.0.5"
- *
- * if_os         12  A UTF-8 string containing the name of the operating system of the
- *                     machine in which this interface is installed.
- *                     This can be different from the same information that can be
- *                     contained by the Section Header Block
- *                     (Section 3.1 (Section Header Block (mandatory))) because
- *                     the capture can have been done on a remote machine.
- *                     "Windows XP SP2" / "openSUSE 10.2" / ...
- *
- * if_fcslen     13  An integer value that specified the length of the
- *                     Frame Check Sequence (in bits) for this interface.
- *                     For link layers whose FCS length can change during time,
- *                     the Packet Block Flags Word can be used (see Appendix A (Packet Block Flags Word)). 4
- *
- * 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. The time zone of the offset can be specified with the
- *                     option if_tzone. TODO: won't a if_tsoffset_low for fractional
- *                     second offsets be useful for highly syncronized capture systems? 1234
- */
 /**
  * Interface description data
  */
-typedef struct wtapng_if_descr_s {
+typedef struct wtapng_if_descr_mandatory_s {
     int                    wtap_encap;            /**< link_type translated to wtap_encap */
     guint64                time_units_per_second;
     int                    tsprecision;           /**< WTAP_TSPREC_ value for this interface */
 
-    /* mandatory */
     guint16                link_type;
     guint32                snap_len;
 
-    /* options */
-    gchar                 *opt_comment;           /**< NULL if not available */
-    gchar                 *if_name;               /**< NULL if not available
-                                                   *  opt 2
-                                                   *     A UTF-8 string containing the name of the
-                                                   *     device used to capture data.
-                                                   */
-    gchar                 *if_description;        /**< NULL if not available
-                                                   *  opt 3
-                                                   *     A UTF-8 string containing the description
-                                                   *     of the device used to capture data.
-                                                   */
-
-    /* XXX: if_IPv4addr opt 4  Interface network address and netmask.                                */
-    /* XXX: if_IPv6addr opt 5  Interface network address and prefix length (stored in the last byte).*/
-    /* XXX: if_MACaddr  opt 6  Interface Hardware MAC address (48 bits).                             */
-    /* XXX: if_EUIaddr  opt 7  Interface Hardware EUI address (64 bits)                              */
-
-    guint64                if_speed;              /**< 0xFFFFFFFF if unknown
-                                                   *  opt 8
-                                                   *     Interface speed (in bps). 100000000 for 100Mbps
-                                                   */
-    guint8                 if_tsresol;            /**< 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
-                                                   */
-
-    /* XXX: if_tzone      10  Time zone for GMT support (TODO: specify better). */
-
-    gchar                 *if_filter_str;         /**< NULL if not available
-                                                   *  opt 11  libpcap string.
-                                                   */
-    guint16                bpf_filter_len;        /** Opt 11 variant II BPF filter len 0 if not used*/
-    gchar                 *if_filter_bpf_bytes;   /** Opt 11 BPF filter or NULL */
-    gchar                 *if_os;                 /**< NULL if not available
-                                                   *     12  A UTF-8 string containing the name of the
-                                                   *     operating system of the machine in which this
-                                                   *     interface is installed.
-                                                   */
-    gint8                  if_fcslen;             /**< -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. */
-    /* XXX: guint64    if_tsoffset; opt 14  A 64 bits integer value that specifies an offset (in seconds)...*/
     guint8                 num_stat_entries;
     GArray                *interface_statistics;  /**< An array holding the interface statistics from
                                                    *     pcapng ISB:s or equivalent(?)*/
-} wtapng_if_descr_t;
+} wtapng_if_descr_mandatory_t;
 
+/* Interface description data - Option 11 structure */
+typedef struct wtapng_if_descr_filter_s {
+    gchar                 *if_filter_str;         /**< NULL if not available
+                                                   *  libpcap string.
+                                                   */
+    guint16                bpf_filter_len;        /** variant II BPF filter len 0 if not used*/
+    gchar                 *if_filter_bpf_bytes;   /** BPF filter or NULL */
+} wtapng_if_descr_filter_t;
 
 /**
- * Interface Statistics. pcap-ng Interface Statistics Block (ISB).
+ * Holds the required data for pcap-ng Interface Statistics Block (ISB).
  */
-typedef struct wtapng_if_stats_s {
-    /* mandatory */
+typedef struct wtapng_if_stats_mandatory_s {
     guint32  interface_id;
     guint32  ts_high;
     guint32  ts_low;
-    /* options */
-    gchar   *opt_comment;       /**< NULL if not available */
-    guint64  isb_starttime;
-    guint64  isb_endtime;
-    guint64  isb_ifrecv;
-    guint64  isb_ifdrop;
-    guint64  isb_filteraccept;
-    guint64  isb_osdrop;
-    guint64  isb_usrdeliv;
-} wtapng_if_stats_t;
-
-
-/* Name Resolution, pcap-ng Name Resolution Block (NRB). */
-typedef struct wtapng_name_res_s {
-    /* options */
-    gchar  *opt_comment;    /**< NULL if not available */
-    /* XXX */
-} wtapng_name_res_t;
+} wtapng_if_stats_mandatory_t;
 
 #ifndef MAXNAMELEN
 #define MAXNAMELEN     64      /* max name length (hostname and port name) */
@@ -1726,11 +1590,11 @@ int wtap_file_tsprec(wtap *wth);
  * @return The existing section header, which must NOT be g_free'd.
  */
 WS_DLL_PUBLIC
-const wtapng_section_t* wtap_file_get_shb(wtap *wth);
+wtap_optionblock_t wtap_file_get_shb(wtap *wth);
 
 /**
  * @brief Gets new section header block for new file, based on existing info.
- * @details Creates a new wtapng_section_t section header block and only
+ * @details Creates a new wtap_optionblock_t section header block and only
  *          copies appropriate members of the SHB for a new file. In
  *          particular, the comment string is copied, and any custom options
  *          which should be copied are copied. The os, hardware, and
@@ -1742,13 +1606,7 @@ const wtapng_section_t* wtap_file_get_shb(wtap *wth);
  * @return The new section header, which must be wtap_free_shb'd.
  */
 WS_DLL_PUBLIC
-wtapng_section_t* wtap_file_get_shb_for_new_file(wtap *wth);
-
-/**
- * Free's a section header block and all of its members.
- */
-WS_DLL_PUBLIC
-void wtap_free_shb(wtapng_section_t *shb_hdr);
+wtap_optionblock_t wtap_file_get_shb_for_new_file(wtap *wth);
 
 /**
  * @brief Gets the section header comment string.
@@ -1813,28 +1671,22 @@ void wtap_free_idb_info(wtapng_iface_descriptions_t *idb_info);
  * @return A newly allocated gcahr array string, which must be g_free'd.
  */
 WS_DLL_PUBLIC
-gchar *wtap_get_debug_if_descr(const wtapng_if_descr_t *if_descr,
+gchar *wtap_get_debug_if_descr(const wtap_optionblock_t if_descr,
                                const int indent,
                                const char* line_end);
 
 /**
  * @brief Gets new name resolution info for new file, based on existing info.
- * @details Creates a new wtapng_name_res_t name resolution info and only
+ * @details Creates a new wtap_optionblock_t of name resolution info and only
  *          copies appropriate members for a new file.
  *
  * @note Use wtap_free_nrb() to free the returned pointer.
  *
  * @param wth The wiretap session.
- * @return The new name resolution info, which must be wtap_free_nrb'd.
- */
-WS_DLL_PUBLIC
-wtapng_name_res_t* wtap_file_get_nrb_for_new_file(wtap *wth);
-
-/**
- * Free's the name resolution info and all of its members.
+ * @return The new name resolution info, which must be wtap_optionblock_free'd.
  */
 WS_DLL_PUBLIC
-void wtap_free_nrb(wtapng_name_res_t *nrb_hdr);
+wtap_optionblock_t wtap_file_get_nrb_for_new_file(wtap *wth);
 
 /**
  * @brief Gets the name resolution comment, if any.
@@ -1930,8 +1782,8 @@ wtap_dumper* wtap_dump_open(const char *filename, int file_type_subtype, int enc
  */
 WS_DLL_PUBLIC
 wtap_dumper* wtap_dump_open_ng(const char *filename, int file_type_subtype, int encap,
-    int snaplen, gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf,
-    wtapng_name_res_t *nrb_hdr, int *err);
+    int snaplen, gboolean compressed, wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+    wtap_optionblock_t nrb_hdr, int *err);
 
 WS_DLL_PUBLIC
 wtap_dumper* wtap_dump_open_tempfile(char **filenamep, const char *pfx,
@@ -1961,8 +1813,8 @@ wtap_dumper* wtap_dump_open_tempfile(char **filenamep, const char *pfx,
 WS_DLL_PUBLIC
 wtap_dumper* wtap_dump_open_tempfile_ng(char **filenamep, const char *pfx,
     int file_type_subtype, int encap, int snaplen, gboolean compressed,
-    wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf,
-    wtapng_name_res_t *nrb_hdr, int *err);
+    wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+    wtap_optionblock_t nrb_hdr, int *err);
 
 WS_DLL_PUBLIC
 wtap_dumper* wtap_dump_fdopen(int fd, int file_type_subtype, int encap, int snaplen,
@@ -1988,8 +1840,8 @@ wtap_dumper* wtap_dump_fdopen(int fd, int file_type_subtype, int encap, int snap
  */
 WS_DLL_PUBLIC
 wtap_dumper* wtap_dump_fdopen_ng(int fd, int file_type_subtype, int encap, int snaplen,
-                gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf,
-                wtapng_name_res_t *nrb_hdr, int *err);
+                gboolean compressed, wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+                wtap_optionblock_t nrb_hdr, int *err);
 
 WS_DLL_PUBLIC
 wtap_dumper* wtap_dump_open_stdout(int file_type_subtype, int encap, int snaplen,
@@ -2014,8 +1866,8 @@ wtap_dumper* wtap_dump_open_stdout(int file_type_subtype, int encap, int snaplen
  */
 WS_DLL_PUBLIC
 wtap_dumper* wtap_dump_open_stdout_ng(int file_type_subtype, int encap, int snaplen,
-                gboolean compressed, wtapng_section_t *shb_hdr, wtapng_iface_descriptions_t *idb_inf,
-                wtapng_name_res_t *nrb_hdr, int *err);
+                gboolean compressed, wtap_optionblock_t shb_hdr, wtapng_iface_descriptions_t *idb_inf,
+                wtap_optionblock_t nrb_hdr, int *err);
 
 WS_DLL_PUBLIC
 gboolean wtap_dump(wtap_dumper *, const struct wtap_pkthdr *, const guint8 *,
diff --git a/wiretap/wtap_opttypes.c b/wiretap/wtap_opttypes.c
new file mode 100644 (file)
index 0000000..3486ef6
--- /dev/null
@@ -0,0 +1,505 @@
+/* wtap_opttypes.c
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 2001 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include "config.h"
+
+#include <glib.h>
+#include <string.h>
+
+#include "wtap.h"
+#include "wtap_opttypes.h"
+#include "wtap-int.h"
+#include "pcapng.h"
+
+struct wtap_optionblock
+{
+    const char *name;                /**< name of block */
+    const char *description;         /**< human-readable description of block */
+    wtap_optionblock_type_t type;
+    void* mandatory_data;
+    GArray* options;
+};
+
+void wtap_opttypes_initialize(void)
+{
+}
+
+static void wtap_if_descr_filter_free(void* data)
+{
+    wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)data;
+    g_free(filter->if_filter_str);
+    g_free(filter->if_filter_bpf_bytes);
+}
+
+wtap_optionblock_t wtap_optionblock_create(wtap_optionblock_type_t block_type)
+{
+    wtap_optionblock_t block = NULL;
+
+    switch(block_type)
+    {
+    case WTAP_OPTION_BLOCK_NG_SECTION:
+        {
+        wtapng_mandatory_section_t* section_mand;
+
+        block = g_new(struct wtap_optionblock, 1);
+        block->name = "SHB";
+        block->description = "Section Header block";
+        block->type = WTAP_OPTION_BLOCK_NG_SECTION;
+        block->mandatory_data = g_new(wtapng_mandatory_section_t, 1);
+        section_mand = (wtapng_mandatory_section_t*)block->mandatory_data;
+        section_mand->section_length = -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_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);
+        }
+        break;
+    case WTAP_OPTION_BLOCK_NG_NRB:
+        block = g_new(struct wtap_optionblock, 1);
+        block->name = "NRB";
+        block->description = "Name Resolution Block";
+        block->type = WTAP_OPTION_BLOCK_NG_NRB;
+        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);
+        break;
+
+    case WTAP_OPTION_BLOCK_IF_STATS:
+        block = g_new(struct wtap_optionblock, 1);
+        block->name = "ISB";
+        block->description = "Interface Statistics Block";
+        block->type = WTAP_OPTION_BLOCK_IF_STATS;
+        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));
+        break;
+    case WTAP_OPTION_BLOCK_IF_DESCR:
+        {
+        wtapng_if_descr_filter_t default_filter;
+        memset(&default_filter, 0, sizeof(default_filter));
+
+        block = g_new(struct wtap_optionblock, 1);
+        block->name = "IDB";
+        block->description = "Interface Description Block";
+        block->type = WTAP_OPTION_BLOCK_IF_DESCR;
+        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), wtap_if_descr_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);
+        }
+        break;
+    }
+
+    return block;
+}
+
+static void wtap_optionblock_free_options(wtap_optionblock_t block)
+{
+    guint i;
+    wtap_opttype_t* opttype = NULL;
+
+    for (i = 0; i < block->options->len; i++) {
+        opttype = g_array_index(block->options, wtap_opttype_t*, i);
+        switch(opttype->type)
+        {
+        case WTAP_OPTTYPE_STRING:
+            g_free(opttype->option.stringval);
+            break;
+        case WTAP_OPTTYPE_CUSTOM:
+            opttype->option.customval.free_func(opttype->option.customval.data);
+            g_free(opttype->option.customval.data);
+            opttype->default_val.customval.free_func(opttype->default_val.customval.data);
+            g_free(opttype->default_val.customval.data);
+            break;
+        default:
+            break;
+        }
+        g_free(opttype);
+    }
+}
+
+void wtap_optionblock_free(wtap_optionblock_t block)
+{
+    if (block != NULL)
+    {
+        /* Need special consideration for freeing of the interface_statistics member */
+        if (block->type == WTAP_OPTION_BLOCK_IF_DESCR)
+        {
+            wtapng_if_descr_mandatory_t* mand = (wtapng_if_descr_mandatory_t*)block->mandatory_data;
+            if (mand->num_stat_entries != 0)
+            {
+                g_array_free(mand->interface_statistics, TRUE);
+            }
+        }
+
+        g_free(block->mandatory_data);
+        wtap_optionblock_free_options(block);
+        g_array_free(block->options, FALSE);
+        g_free(block);
+    }
+}
+
+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)
+{
+    guint i;
+    wtap_opttype_t* opttype = NULL;
+
+    for (i = 0; i < block->options->len; i++)
+    {
+        opttype = g_array_index(block->options, wtap_opttype_t*, i);
+        if (opttype->number == option_id)
+            return opttype;
+    }
+
+    return NULL;
+}
+
+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)
+{
+    wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+
+    /* Option already exists */
+    if (opttype != NULL)
+        return WTAP_OPTTYPE_ALREADY_EXISTS;
+
+    opttype = g_new(wtap_opttype_t, 1);
+
+    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;
+
+    g_array_append_val(block->options, opttype);
+    return WTAP_OPTTYPE_SUCCESS;
+}
+
+int wtap_optionblock_set_option_string(wtap_optionblock_t block, guint option_id, char* opt_value)
+{
+    wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+
+    /* Didn't find the option */
+    if (opttype == NULL)
+        return WTAP_OPTTYPE_NOT_FOUND;
+
+    if (opttype->type != WTAP_OPTTYPE_STRING)
+        return WTAP_OPTTYPE_TYPE_MISMATCH;
+
+    g_free(opttype->option.stringval);
+    opttype->option.stringval = g_strdup(opt_value);
+    return WTAP_OPTTYPE_SUCCESS;
+}
+
+int wtap_optionblock_get_option_string(wtap_optionblock_t block, guint option_id, char** opt_value)
+{
+    wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+
+    /* Didn't find the option */
+    if (opttype == NULL)
+        return WTAP_OPTTYPE_NOT_FOUND;
+
+    if (opttype->type != WTAP_OPTTYPE_STRING)
+        return WTAP_OPTTYPE_TYPE_MISMATCH;
+
+    *opt_value = opttype->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)
+{
+    wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+
+    /* Option already exists */
+    if (opttype != NULL)
+        return WTAP_OPTTYPE_ALREADY_EXISTS;
+
+    opttype = g_new(wtap_opttype_t, 1);
+
+    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;
+
+    g_array_append_val(block->options, opttype);
+    return WTAP_OPTTYPE_SUCCESS;
+}
+
+int wtap_optionblock_set_option_uint64(wtap_optionblock_t block, guint option_id, guint64 opt_value)
+{
+    wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+
+    /* Didn't find the option */
+    if (opttype == NULL)
+        return WTAP_OPTTYPE_NOT_FOUND;
+
+    if (opttype->type != WTAP_OPTTYPE_UINT64)
+        return WTAP_OPTTYPE_TYPE_MISMATCH;
+
+    opttype->option.uint64val = opt_value;
+    return WTAP_OPTTYPE_SUCCESS;
+}
+
+int wtap_optionblock_get_option_uint64(wtap_optionblock_t block, guint option_id, guint64* opt_value)
+{
+    wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+
+    /* Didn't find the option */
+    if (opttype == NULL)
+        return WTAP_OPTTYPE_NOT_FOUND;
+
+    if (opttype->type != WTAP_OPTTYPE_UINT64)
+        return WTAP_OPTTYPE_TYPE_MISMATCH;
+
+    *opt_value = opttype->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)
+{
+    wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+
+    /* Option already exists */
+    if (opttype != NULL)
+        return WTAP_OPTTYPE_ALREADY_EXISTS;
+
+    opttype = g_new(wtap_opttype_t, 1);
+
+    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;
+
+    g_array_append_val(block->options, opttype);
+    return WTAP_OPTTYPE_SUCCESS;
+}
+
+int wtap_optionblock_set_option_uint8(wtap_optionblock_t block, guint option_id, guint8 opt_value)
+{
+    wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+
+    /* Didn't find the option */
+    if (opttype == NULL)
+        return WTAP_OPTTYPE_NOT_FOUND;
+
+    if (opttype->type != WTAP_OPTTYPE_UINT8)
+        return WTAP_OPTTYPE_TYPE_MISMATCH;
+
+    opttype->option.uint8val = opt_value;
+    return WTAP_OPTTYPE_SUCCESS;
+}
+
+int wtap_optionblock_get_option_uint8(wtap_optionblock_t block, guint option_id, guint8* opt_value)
+{
+    wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+
+    /* Didn't find the option */
+    if (opttype == NULL)
+        return WTAP_OPTTYPE_NOT_FOUND;
+
+    if (opttype->type != WTAP_OPTTYPE_UINT8)
+        return WTAP_OPTTYPE_TYPE_MISMATCH;
+
+    *opt_value = opttype->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)
+{
+    wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+
+    /* Option already exists */
+    if (opttype != NULL)
+        return WTAP_OPTTYPE_ALREADY_EXISTS;
+
+    opttype = g_new(wtap_opttype_t, 1);
+
+    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;
+
+    g_array_append_val(block->options, opttype);
+    return WTAP_OPTTYPE_SUCCESS;
+}
+
+int wtap_optionblock_set_option_custom(wtap_optionblock_t block, guint option_id, void* opt_value)
+{
+    wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+    void* prev_value;
+
+    /* Didn't find the option */
+    if (opttype == NULL)
+        return WTAP_OPTTYPE_NOT_FOUND;
+
+    if (opttype->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);
+    /* 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)
+{
+    wtap_opttype_t* opttype = wtap_optionblock_get_option(block, option_id);
+
+    /* Didn't find the option */
+    if (opttype == NULL)
+        return WTAP_OPTTYPE_NOT_FOUND;
+
+    if (opttype->type != WTAP_OPTTYPE_CUSTOM)
+        return WTAP_OPTTYPE_TYPE_MISMATCH;
+
+    *opt_value = opttype->option.customval.data;
+    return WTAP_OPTTYPE_SUCCESS;
+}
+
+void wtap_optionblock_copy_options(wtap_optionblock_t dest_block, wtap_optionblock_t src_block)
+{
+    guint i;
+    wtap_opttype_t *dest_opttype, *src_opttype;
+
+    switch(src_block->type)
+    {
+    case WTAP_OPTION_BLOCK_NG_SECTION:
+        memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_mandatory_section_t));
+        break;
+    case WTAP_OPTION_BLOCK_NG_NRB:
+        /* No mandatory data */
+        break;
+    case WTAP_OPTION_BLOCK_IF_STATS:
+        memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_if_stats_mandatory_t));
+        break;
+    case WTAP_OPTION_BLOCK_IF_DESCR:
+        {
+        wtapng_if_descr_mandatory_t *src_mand = (wtapng_if_descr_mandatory_t*)src_block->mandatory_data,
+                                    *dest_mand = (wtapng_if_descr_mandatory_t*)dest_block->mandatory_data;
+        /* Need special consideration for copying of the interface_statistics member */
+        if (dest_mand->num_stat_entries != 0)
+        {
+            g_array_free(dest_mand->interface_statistics, TRUE);
+        }
+
+        memcpy(dest_mand, src_mand, sizeof(wtapng_if_descr_mandatory_t));
+        if (src_mand->num_stat_entries != 0)
+        {
+            dest_mand->interface_statistics = NULL;
+            dest_mand->interface_statistics = g_array_append_vals(dest_mand->interface_statistics, src_mand->interface_statistics->data, src_mand->interface_statistics->len);
+        }
+        }
+        break;
+    }
+
+    /* 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++)
+    {
+        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)
+        {
+            /* 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;
+            }
+        }
+        else
+        {
+            /* Option exists, replace it */
+            switch(src_opttype->type)
+            {
+            case WTAP_OPTTYPE_UINT8:
+                dest_opttype->option.uint8val = src_opttype->option.uint8val;
+                break;
+            case WTAP_OPTTYPE_UINT64:
+                dest_opttype->option.uint64val = src_opttype->option.uint64val;
+                break;
+            case WTAP_OPTTYPE_STRING:
+                g_free(dest_opttype->option.stringval);
+                dest_opttype->option.stringval = g_strdup(src_opttype->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);
+                break;
+            }
+        }
+    }
+}
diff --git a/wiretap/wtap_opttypes.h b/wiretap/wtap_opttypes.h
new file mode 100644 (file)
index 0000000..a1b0963
--- /dev/null
@@ -0,0 +1,250 @@
+/* wtap_opttypes.h
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 2001 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef WTAP_OPT_TYPES_H
+#define WTAP_OPT_TYPES_H
+
+#include "ws_symbol_export.h"
+
+/* Currently supported option blocks */
+typedef enum {
+    WTAP_OPTION_BLOCK_IF_DESCR = 0,
+    WTAP_OPTION_BLOCK_IF_STATS,
+    WTAP_OPTION_BLOCK_NG_SECTION,
+    WTAP_OPTION_BLOCK_NG_NRB
+} wtap_optionblock_type_t;
+
+/* Currently supported option types */
+typedef enum {
+    WTAP_OPTTYPE_UINT8,
+    WTAP_OPTTYPE_UINT64,
+    WTAP_OPTTYPE_STRING,
+    WTAP_OPTTYPE_CUSTOM
+} wtap_opttype_e;
+
+typedef enum {
+    WTAP_OPTTYPE_SUCCESS = 0,
+    WTAP_OPTTYPE_NOT_FOUND = -1,
+    WTAP_OPTTYPE_TYPE_MISMATCH = -2,
+    WTAP_OPTTYPE_ALREADY_EXISTS = -3
+} wtap_opttype_return_val;
+
+typedef void (*wtap_opttype_free_custom_func)(void* data);
+
+struct wtap_opttype_custom
+{
+    void* data;
+    guint size;
+    wtap_opttype_free_custom_func free_func;
+};
+
+typedef struct wtap_opttype {
+    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;
+
+/** Initialize option block types.
+ *
+ * This is currently just a placeholder as nothing needs to be
+ * initialized yet.  Should handle "registration" when code is
+ * refactored to do so.
+ */
+void wtap_opttypes_initialize(void);
+
+/** Create an option block by type
+ *
+ * Return a newly allocated option block with default options provided
+ *
+ * @param[in] block_type Option block type to be created
+ * @return Newly allocated option block
+ */
+WS_DLL_PUBLIC wtap_optionblock_t wtap_optionblock_create(wtap_optionblock_type_t block_type);
+
+/** Free an option block
+ *
+ * Needs to be called to clean up any allocated option block
+ *
+ * @param[in] block Block to be freed
+ */
+WS_DLL_PUBLIC void wtap_optionblock_free(wtap_optionblock_t block);
+
+/** Provide mandatory data of an option block
+ *
+ * @param[in] block Block to retrieve mandatory data
+ * @return Option block mandatory data.  Structure varies based on option block type
+ */
+WS_DLL_PUBLIC void* wtap_optionblock_get_mandatory_data(wtap_optionblock_t block);
+
+/** Add a string 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_string(wtap_optionblock_t block, guint option_id,
+                                       const char *name, const char *description, char* opt_value, char* default_value);
+
+/** 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
+ * @return 0 if successful
+ */
+WS_DLL_PUBLIC int wtap_optionblock_set_option_string(wtap_optionblock_t block, guint option_id, char* opt_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
+ * @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);
+
+/** 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
+ * @return 0 if successful
+ */
+WS_DLL_PUBLIC int wtap_optionblock_set_option_uint64(wtap_optionblock_t block, guint option_id, guint64 opt_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
+ * @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);
+
+/** 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
+ * @return 0 if successful
+ */
+WS_DLL_PUBLIC int wtap_optionblock_set_option_uint8(wtap_optionblock_t block, guint option_id, guint8 opt_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
+ * @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);
+
+/** 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
+ * @return 0 if successful
+ */
+WS_DLL_PUBLIC int wtap_optionblock_set_option_custom(wtap_optionblock_t block, guint option_id, void* opt_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
+ * @return 0 if successful
+ */
+WS_DLL_PUBLIC int wtap_optionblock_get_option_custom(wtap_optionblock_t block, guint option_id, void** opt_value);
+
+/** Copy an option block to another.
+ *
+ * Any options that are in the destination but not the source are not removed.
+ * Options that are just in source will be added to destination
+ *
+ * @param[in] dest_block Block to be copied to
+ * @param[in] src_block Block to be copied from
+ */
+void wtap_optionblock_copy_options(wtap_optionblock_t dest_block, wtap_optionblock_t src_block);
+
+#endif /* WTAP_OPT_TYPES_H */
\ No newline at end of file