diff options
-rw-r--r-- | capinfos.c | 19 | ||||
-rw-r--r-- | cfile.c | 16 | ||||
-rw-r--r-- | debian/libwiretap0.symbols | 13 | ||||
-rw-r--r-- | editcap.c | 26 | ||||
-rw-r--r-- | epan/wslua/wslua.h | 21 | ||||
-rw-r--r-- | epan/wslua/wslua_capture_info.c | 25 | ||||
-rw-r--r-- | file.c | 8 | ||||
-rw-r--r-- | reordercap.c | 17 | ||||
-rw-r--r-- | summary.c | 47 | ||||
-rw-r--r-- | tshark.c | 28 | ||||
-rw-r--r-- | ui/gtk/file_import_dlg.c | 56 | ||||
-rw-r--r-- | ui/tap_export_pdu.c | 57 | ||||
-rw-r--r-- | wiretap/CMakeLists.txt | 1 | ||||
-rw-r--r-- | wiretap/Makefile.common | 4 | ||||
-rw-r--r-- | wiretap/erf.c | 64 | ||||
-rw-r--r-- | wiretap/file_access.c | 109 | ||||
-rw-r--r-- | wiretap/lanalyzer.c | 3 | ||||
-rw-r--r-- | wiretap/merge.c | 201 | ||||
-rw-r--r-- | wiretap/nettrace_3gpp_32_423.c | 65 | ||||
-rw-r--r-- | wiretap/pcapng.c | 665 | ||||
-rw-r--r-- | wiretap/pcapng.h | 89 | ||||
-rw-r--r-- | wiretap/wtap-int.h | 10 | ||||
-rw-r--r-- | wiretap/wtap.c | 217 | ||||
-rw-r--r-- | wiretap/wtap.h | 216 | ||||
-rw-r--r-- | wiretap/wtap_opttypes.c | 505 | ||||
-rw-r--r-- | wiretap/wtap_opttypes.h | 250 |
26 files changed, 1713 insertions, 1019 deletions
diff --git a/capinfos.c b/capinfos.c index 5a3e2b3f56..b3b88c8d79 100644 --- a/capinfos.c +++ b/capinfos.c @@ -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); @@ -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"; } diff --git a/debian/libwiretap0.symbols b/debian/libwiretap0.symbols index 070dac92ef..2c7ff4a8d0 100644 --- a/debian/libwiretap0.symbols +++ b/debian/libwiretap0.symbols @@ -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 @@ -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); } diff --git a/epan/wslua/wslua.h b/epan/wslua/wslua.h index 75b67967ed..5239f21fe7 100644 --- a/epan/wslua/wslua.h +++ b/epan/wslua/wslua.h @@ -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); } diff --git a/epan/wslua/wslua_capture_info.c b/epan/wslua/wslua_capture_info.c index 7a4ca96341..ddba06d792 100644 --- a/epan/wslua/wslua_capture_info.c +++ b/epan/wslua/wslua_capture_info.c @@ -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 @@ -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); diff --git a/reordercap.c b/reordercap.c index b96b214b1a..0c29ea59c8 100644 --- a/reordercap.c +++ b/reordercap.c @@ -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); @@ -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); } @@ -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; } diff --git a/ui/gtk/file_import_dlg.c b/ui/gtk/file_import_dlg.c index 86248d73fa..3378d1beaf 100644 --- a/ui/gtk/file_import_dlg.c +++ b/ui/gtk/file_import_dlg.c @@ -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); } diff --git a/ui/tap_export_pdu.c b/ui/tap_export_pdu.c index a7b92788de..e0b2a9fc3c 100644 --- a/ui/tap_export_pdu.c +++ b/ui/tap_export_pdu.c @@ -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); } diff --git a/wiretap/CMakeLists.txt b/wiretap/CMakeLists.txt index e3eb20aa6f..080b7edc13 100644 --- a/wiretap/CMakeLists.txt +++ b/wiretap/CMakeLists.txt @@ -79,6 +79,7 @@ set(WIRETAP_FILES vms.c vwr.c wtap.c + wtap_opttypes.c ) if (WERROR_COMMON_FLAGS) diff --git a/wiretap/Makefile.common b/wiretap/Makefile.common index 02c12145b2..43bcfc39f0 100644 --- a/wiretap/Makefile.common +++ b/wiretap/Makefile.common @@ -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 diff --git a/wiretap/erf.c b/wiretap/erf.c index f2e5f9d409..bfe8b74361 100644 --- a/wiretap/erf.c +++ b/wiretap/erf.c @@ -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); } diff --git a/wiretap/file_access.c b/wiretap/file_access.c index 0daed2b419..4e755fff68 100644 --- a/wiretap/file_access.c +++ b/wiretap/file_access.c @@ -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; diff --git a/wiretap/lanalyzer.c b/wiretap/lanalyzer.c index 50ce3339e0..8f9fd0f63b 100644 --- a/wiretap/lanalyzer.c +++ b/wiretap/lanalyzer.c @@ -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. diff --git a/wiretap/merge.c b/wiretap/merge.c index b4e1438b0e..f2e92e384a 100644 --- a/wiretap/merge.c +++ b/wiretap/merge.c @@ -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; diff --git a/wiretap/nettrace_3gpp_32_423.c b/wiretap/nettrace_3gpp_32_423.c index 5e80584479..655e8893dd 100644 --- a/wiretap/nettrace_3gpp_32_423.c +++ b/wiretap/nettrace_3gpp_32_423.c @@ -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; diff --git a/wiretap/pcapng.c b/wiretap/pcapng.c index b55cedc34f..879f349de4 100644 --- a/wiretap/pcapng.c +++ b/wiretap/pcapng.c @@ -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; } diff --git a/wiretap/pcapng.h b/wiretap/pcapng.h index a568ab1a94..7827a83482 100644 --- a/wiretap/pcapng.h +++ b/wiretap/pcapng.h @@ -22,9 +22,96 @@ #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); diff --git a/wiretap/wtap-int.h b/wiretap/wtap-int.h index 332d836c57..89726ece9e 100644 --- a/wiretap/wtap-int.h +++ b/wiretap/wtap-int.h @@ -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.*/ }; diff --git a/wiretap/wtap.c b/wiretap/wtap.c index 3dfb426297..cdb031ef7c 100644 --- a/wiretap/wtap.c +++ b/wiretap/wtap.c @@ -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); diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 73b9f73c55..169f26c779 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -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 index 0000000000..3486ef69a9 --- /dev/null +++ b/wiretap/wtap_opttypes.c @@ -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 index 0000000000..a1b0963ea8 --- /dev/null +++ b/wiretap/wtap_opttypes.h @@ -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 |