From 1f8999bb96018446e48529e75e56bf17dd3c77cf Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Thu, 14 Jul 2016 16:01:57 -0700 Subject: Redo the block options APIs. A block can have zero or more instances of a given option. We distinguish between "one instance only" options, where a block can have zero or one instance, and "multiple instances allowed" options, where a block can have zero or more instances. For "one instance only" options: "add" routines add an instance if there isn't one already and fail if there is; "set" routines add an instance if there isn't one already and change the value of the existing instance if there is one; "set nth" routines fail; "get" routines return the value of the instance if there is one and fail if there isn't; "get nth" routines fail. For "multiple instances allowed" options: "add" routines add an instance; "set" routines fail; "set nth" routines set the value of the nth instance if there is one and fail otherwise; "get" routines fail; "get nth" routines get the value if the nth instance if there is one and fail otherwise. Rename "optionblock" to just "block"; it describes the contents of a block, including both mandatory items and options. Add some support for NRB options, including IPv4 and IPv6 option types. Change-Id: Iad184f668626c3d1498b2ed00c7f1672e4abf52e Reviewed-on: https://code.wireshark.org/review/16444 Reviewed-by: Guy Harris --- capinfos.c | 44 +- cfile.c | 12 +- editcap.c | 14 +- epan/wslua/wslua.h | 39 +- epan/wslua/wslua_capture_info.c | 4 +- file.c | 49 +- reordercap.c | 12 +- summary.c | 39 +- tshark.c | 20 +- ui/gtk/file_import_dlg.c | 24 +- ui/gtk/summary_dlg.c | 45 +- ui/qt/capture_file_properties_dialog.cpp | 23 +- ui/qt/resolved_addresses_dialog.cpp | 17 +- ui/tap_export_pdu.c | 24 +- wiretap/erf.c | 99 ++- wiretap/file_access.c | 39 +- wiretap/lanalyzer.c | 2 +- wiretap/merge.c | 241 ++++-- wiretap/nettrace_3gpp_32_423.c | 26 +- wiretap/pcapng.c | 730 ++++++++++-------- wiretap/wtap.c | 191 +++-- wiretap/wtap.h | 59 +- wiretap/wtap_opttypes.c | 1238 ++++++++++++++++++++---------- wiretap/wtap_opttypes.h | 294 +++++-- 24 files changed, 2043 insertions(+), 1242 deletions(-) diff --git a/capinfos.c b/capinfos.c index de38662c8b..f4ea0bb63a 100644 --- a/capinfos.c +++ b/capinfos.c @@ -194,7 +194,7 @@ typedef struct _capture_info { int file_encap; int file_tsprec; gint64 filesize; - wtap_optionblock_t shb; + wtap_block_t shb; guint64 packet_bytes; gboolean times_known; nstime_t start_time; @@ -712,24 +712,22 @@ print_stats(const gchar *filename, capture_info *cf_info) if (cf_info->shb != NULL) { if (cap_comment) { - GArray *opts; unsigned int i; + char *str; - wtap_optionblock_get_string_options(cf_info->shb, OPT_COMMENT, &opts); - for (i = 0; i < opts->len; i++) { - show_option_string("Capture comment: ", g_array_index(opts, char *, i)); + for (i = 0; wtap_block_get_nth_string_option_value(cf_info->shb, OPT_COMMENT, i, &str) == WTAP_OPTTYPE_SUCCESS; i++) { + show_option_string("Capture comment: ", str); } - g_array_free(opts, TRUE); } if (cap_file_more_info) { char *str; - wtap_optionblock_get_option_string(cf_info->shb, OPT_SHB_HARDWARE, &str); - show_option_string("Capture hardware: ", str); - wtap_optionblock_get_option_string(cf_info->shb, OPT_SHB_OS, &str); - show_option_string("Capture oper-sys: ", str); - wtap_optionblock_get_option_string(cf_info->shb, OPT_SHB_USERAPPL, &str); - show_option_string("Capture application: ", str); + if (wtap_block_get_string_option_value(cf_info->shb, OPT_SHB_HARDWARE, &str) == WTAP_OPTTYPE_SUCCESS) + show_option_string("Capture hardware: ", str); + if (wtap_block_get_string_option_value(cf_info->shb, OPT_SHB_OS, &str) == WTAP_OPTTYPE_SUCCESS) + show_option_string("Capture oper-sys: ", str); + if (wtap_block_get_string_option_value(cf_info->shb, OPT_SHB_USERAPPL, &str) == WTAP_OPTTYPE_SUCCESS) + show_option_string("Capture application: ", str); } if (cap_file_idb && cf_info->num_interfaces != 0) { @@ -991,13 +989,10 @@ print_stats_table(const gchar *filename, capture_info *cf_info) * of options */ if (cap_comment) { - GArray *opts; unsigned int i; + char *opt_comment; - wtap_optionblock_get_string_options(cf_info->shb, OPT_COMMENT, &opts); - for (i = 0; i < opts->len; i++) { - const char *opt_comment = g_array_index(opts, char *, i); - + for (i = 0; wtap_block_get_nth_string_option_value(cf_info->shb, OPT_COMMENT, i, &opt_comment) == WTAP_OPTTYPE_SUCCESS; i++) { if (opt_comment != NULL) { putsep(); putquote(); @@ -1005,28 +1000,27 @@ print_stats_table(const gchar *filename, capture_info *cf_info) putquote(); } } - g_array_free(opts, TRUE); } if (cap_file_more_info) { char *str; - wtap_optionblock_get_option_string(cf_info->shb, OPT_SHB_HARDWARE, &str); - if (str != NULL) { + if (wtap_block_get_string_option_value(cf_info->shb, OPT_SHB_HARDWARE, &str) == WTAP_OPTTYPE_SUCCESS && + str != NULL) { putsep(); putquote(); printf("%s", str); putquote(); } - wtap_optionblock_get_option_string(cf_info->shb, OPT_SHB_OS, &str); - if (str != NULL) { + if (wtap_block_get_string_option_value(cf_info->shb, OPT_SHB_OS, &str) == WTAP_OPTTYPE_SUCCESS && + str != NULL) { putsep(); putquote(); printf("%s", str); putquote(); } - wtap_optionblock_get_option_string(cf_info->shb, OPT_SHB_USERAPPL, &str); - if (str != NULL) { + if (wtap_block_get_string_option_value(cf_info->shb, OPT_SHB_USERAPPL, &str) == WTAP_OPTTYPE_SUCCESS && + str != NULL) { putsep(); putquote(); printf("%s", str); @@ -1213,7 +1207,7 @@ process_cap_file(wtap *wth, const char *filename) cf_info.idb_info_strings = g_array_sized_new(FALSE, FALSE, sizeof(gchar*), cf_info.num_interfaces); cf_info.num_interfaces = idb_info->interface_data->len; for (i = 0; i < cf_info.num_interfaces; i++) { - const wtap_optionblock_t if_descr = g_array_index(idb_info->interface_data, wtap_optionblock_t, i); + const wtap_block_t if_descr = g_array_index(idb_info->interface_data, wtap_block_t, i); gchar *s = wtap_get_debug_if_descr(if_descr, 21, "\n"); g_array_append_val(cf_info.idb_info_strings, s); } diff --git a/cfile.c b/cfile.c index e2dafe569c..382995e696 100644 --- a/cfile.c +++ b/cfile.c @@ -35,22 +35,22 @@ cap_file_get_interface_name(void *data, guint32 interface_id) { capture_file *cf = (capture_file *) data; wtapng_iface_descriptions_t *idb_info; - wtap_optionblock_t wtapng_if_descr = NULL; + wtap_block_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, wtap_optionblock_t, interface_id); + wtapng_if_descr = g_array_index(idb_info->interface_data, wtap_block_t, interface_id); g_free(idb_info); if (wtapng_if_descr) { - wtap_optionblock_get_option_string(wtapng_if_descr, OPT_IDB_NAME, &interface_name); - if (interface_name) + if (wtap_block_get_string_option_value(wtapng_if_descr, OPT_IDB_NAME, &interface_name) == WTAP_OPTTYPE_SUCCESS && + interface_name) return interface_name; - wtap_optionblock_get_option_string(wtapng_if_descr, OPT_IDB_DESCR, &interface_name); - if (interface_name) + if (wtap_block_get_string_option_value(wtapng_if_descr, OPT_IDB_DESCR, &interface_name) == WTAP_OPTTYPE_SUCCESS && + interface_name) return interface_name; } return "unknown"; diff --git a/editcap.c b/editcap.c index 4ece4ef944..5a106a630a 100644 --- a/editcap.c +++ b/editcap.c @@ -1378,9 +1378,9 @@ main(int argc, char *argv[]) g_assert(filename); /* If we don't have an application name add Editcap */ - wtap_optionblock_get_option_string(g_array_index(shb_hdrs, wtap_optionblock_t, 0), OPT_SHB_USERAPPL, &shb_user_appl); - if (shb_user_appl == NULL) { - wtap_optionblock_set_option_string_format(g_array_index(shb_hdrs, wtap_optionblock_t, 0), OPT_SHB_USERAPPL, "Editcap " VERSION); + if (wtap_block_get_string_option_value(g_array_index(shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, &shb_user_appl) != WTAP_OPTTYPE_SUCCESS || + shb_user_appl == NULL) { + wtap_block_add_string_option_format(g_array_index(shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, "Editcap " VERSION); } pdh = editcap_dump_open(filename, @@ -1842,9 +1842,9 @@ main(int argc, char *argv[]) wtap_strerror(write_err)); goto error_on_exit; } - wtap_optionblock_array_free(shb_hdrs); + wtap_block_array_free(shb_hdrs); shb_hdrs = NULL; - wtap_optionblock_array_free(nrb_hdrs); + wtap_block_array_free(nrb_hdrs); nrb_hdrs = NULL; g_free(filename); @@ -1868,8 +1868,8 @@ main(int argc, char *argv[]) return 0; error_on_exit: - wtap_optionblock_array_free(shb_hdrs); - wtap_optionblock_array_free(nrb_hdrs); + wtap_block_array_free(shb_hdrs); + wtap_block_array_free(nrb_hdrs); g_free(idb_inf); exit(2); } diff --git a/epan/wslua/wslua.h b/epan/wslua/wslua.h index 32f5bcb2ec..333c179687 100644 --- a/epan/wslua/wslua.h +++ b/epan/wslua/wslua.h @@ -557,8 +557,23 @@ extern int wslua_set__index(lua_State *L); WSLUA_ATTRIBUTE_GET(C,name, { \ char* str; \ if ((obj->member) && (obj->member->len > 0)) { \ - wtap_optionblock_get_option_string(g_array_index(obj->member, wtap_optionblock_t, 0), option, &str); \ - lua_pushstring(L,str); /* this pushes nil if obj->member is null */ \ + if (wtap_block_get_string_option_value(g_array_index(obj->member, wtap_block_t, 0), option, &str) == WTAP_OPTTYPE_SUCCESS) { \ + lua_pushstring(L,str); /* this pushes nil if obj->member is null */ \ + } \ + } \ + }) + +/* + * XXX - we need to support Lua programs getting instances of a "multiple + * allowed" option other than the first option. + */ +#define WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_NTH_STRING_GETTER(C,name,member,option) \ + WSLUA_ATTRIBUTE_GET(C,name, { \ + char* str; \ + if ((obj->member) && (obj->member->len > 0)) { \ + if (wtap_block_get_nth_string_option_value(g_array_index(obj->member, wtap_block_t, 0), option, 0, &str) == WTAP_OPTTYPE_SUCCESS) { \ + lua_pushstring(L,str); /* this pushes nil if obj->member is null */ \ + } \ } \ }) @@ -620,7 +635,25 @@ extern int wslua_set__index(lua_State *L); return luaL_error(L, "%s's attribute `%s' must be a string or nil", #C , #field ); \ } \ if ((obj->member) && (obj->member->len > 0)) { \ - wtap_optionblock_set_option_string(g_array_index(obj->member, wtap_optionblock_t, 0), option, s, strlen(s)); \ + wtap_block_set_string_option_value(g_array_index(obj->member, wtap_block_t, 0), option, s, strlen(s)); \ + } \ + g_free(s); \ + return 0; \ + } \ + /* silly little trick so we can add a semicolon after this macro */ \ + typedef void __dummy##C##_set_##field + +#define WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_NTH_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 ); \ + } \ + if ((obj->member) && (obj->member->len > 0)) { \ + wtap_block_set_nth_string_option_value(g_array_index(obj->member, wtap_block_t, 0), option, 0, s, strlen(s)); \ } \ g_free(s); \ return 0; \ diff --git a/epan/wslua/wslua_capture_info.c b/epan/wslua/wslua_capture_info.c index e0293dad0b..433604770e 100644 --- a/epan/wslua/wslua_capture_info.c +++ b/epan/wslua/wslua_capture_info.c @@ -119,8 +119,8 @@ 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_OPT_BLOCK_STRING_GETTER(CaptureInfo,comment,wth->shb_hdrs,OPT_COMMENT); -WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_STRING_SETTER(CaptureInfo,comment,wth->shb_hdrs,OPT_COMMENT); +WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_NTH_STRING_GETTER(CaptureInfo,comment,wth->shb_hdrs,OPT_COMMENT); +WSLUA_ATTRIBUTE_NAMED_OPT_BLOCK_NTH_STRING_SETTER(CaptureInfo,comment,wth->shb_hdrs,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. */ diff --git a/file.c b/file.c index ba84efbd13..db3a4be8de 100644 --- a/file.c +++ b/file.c @@ -3839,28 +3839,47 @@ cf_unignore_frame(capture_file *cf, frame_data *frame) const gchar * cf_read_shb_comment(capture_file *cf) { - /* Get info from SHB */ - return wtap_file_get_shb_comment(cf->wth); + wtap_block_t shb_inf; + char *shb_comment; + + /* Get the SHB. */ + /* XXX - support multiple SHBs */ + shb_inf = wtap_file_get_shb(cf->wth); + + /* Get the first comment from the SHB. */ + /* XXX - support multiple comments */ + if (wtap_block_get_nth_string_option_value(shb_inf, OPT_COMMENT, 0, &shb_comment) != WTAP_OPTTYPE_SUCCESS) + return NULL; + return shb_comment; } void cf_update_capture_comment(capture_file *cf, gchar *comment) { - const gchar *shb_comment; - - /* Get info from SHB */ - shb_comment = wtap_file_get_shb_comment(cf->wth); - - /* See if the comment has changed or not */ - if (shb_comment) { - if (strcmp(shb_comment, comment) == 0) { - g_free(comment); - return; + wtap_block_t shb_inf; + gchar *shb_comment; + + /* Get the SHB. */ + /* XXX - support multiple SHBs */ + shb_inf = wtap_file_get_shb(cf->wth); + + /* Get the first comment from the SHB. */ + /* XXX - support multiple comments */ + if (wtap_block_get_nth_string_option_value(shb_inf, OPT_COMMENT, 0, &shb_comment) != WTAP_OPTTYPE_SUCCESS) { + /* There's no comment - add one. */ + wtap_block_add_string_option(shb_inf, OPT_COMMENT, comment, strlen(comment)); + } else { + /* See if the comment has changed or not */ + if (shb_comment) { + if (strcmp(shb_comment, comment) == 0) { + g_free(comment); + return; + } } - } - /* The comment has changed, let's update it */ - wtap_write_shb_comment(cf->wth, comment); + /* The comment has changed, let's update it */ + wtap_block_set_nth_string_option_value(shb_inf, OPT_COMMENT, 0, comment, strlen(comment)); + } /* Mark the file as having unsaved changes */ cf->unsaved_changes = TRUE; } diff --git a/reordercap.c b/reordercap.c index ae1e013320..206a4888c8 100644 --- a/reordercap.c +++ b/reordercap.c @@ -308,8 +308,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_optionblock_array_free(shb_hdrs); - wtap_optionblock_array_free(nrb_hdrs); + wtap_block_array_free(shb_hdrs); + wtap_block_array_free(nrb_hdrs); exit(1); } @@ -382,12 +382,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_optionblock_array_free(shb_hdrs); - wtap_optionblock_array_free(nrb_hdrs); + wtap_block_array_free(shb_hdrs); + wtap_block_array_free(nrb_hdrs); exit(1); } - wtap_optionblock_array_free(shb_hdrs); - wtap_optionblock_array_free(nrb_hdrs); + wtap_block_array_free(shb_hdrs); + wtap_block_array_free(nrb_hdrs); /* Finally, close infile */ wtap_fdclose(wth); diff --git a/summary.c b/summary.c index 77cd3886a5..a0f7965f48 100644 --- a/summary.c +++ b/summary.c @@ -110,9 +110,9 @@ summary_fill_in(capture_file *cf, summary_tally *st) iface_options iface; guint i; wtapng_iface_descriptions_t* idb_info; - wtap_optionblock_t wtapng_if_descr; + wtap_block_t wtapng_if_descr; wtapng_if_descr_mandatory_t *wtapng_if_descr_mand; - wtap_optionblock_t if_stats; + wtap_block_t if_stats; guint64 isb_ifdrop; char* if_string; wtapng_if_descr_filter_t* if_filter; @@ -163,14 +163,23 @@ summary_fill_in(capture_file *cf, summary_tally *st) 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, 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); + wtapng_if_descr = g_array_index(idb_info->interface_data, wtap_block_t, i); + wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wtapng_if_descr); + if (wtap_block_get_custom_option_value(wtapng_if_descr, OPT_IDB_FILTER, (void**)&if_filter) == WTAP_OPTTYPE_SUCCESS) { + iface.cfilter = g_strdup(if_filter->if_filter_str); + } else { + iface.cfilter = NULL; + } + if (wtap_block_get_string_option_value(wtapng_if_descr, OPT_IDB_NAME, &if_string) == WTAP_OPTTYPE_SUCCESS) { + iface.name = g_strdup(if_string); + } else { + iface.name = NULL; + } + if (wtap_block_get_string_option_value(wtapng_if_descr, OPT_IDB_DESCR, &if_string) == WTAP_OPTTYPE_SUCCESS) { + iface.descr = g_strdup(if_string); + } else { + iface.descr = NULL; + } iface.drops_known = FALSE; iface.drops = 0; iface.snap = wtapng_if_descr_mand->snap_len; @@ -179,14 +188,16 @@ summary_fill_in(capture_file *cf, summary_tally *st) iface.isb_comment = NULL; 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_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)) { + if_stats = g_array_index(wtapng_if_descr_mand->interface_statistics, wtap_block_t, 0); + if (wtap_block_get_uint64_option_value(if_stats, OPT_ISB_IFDROP, &isb_ifdrop) == WTAP_OPTTYPE_SUCCESS) { iface.drops_known = TRUE; iface.drops = isb_ifdrop; } /* XXX: this doesn't get used, and might need to be g_strdup'ed when it does */ - wtap_optionblock_get_option_string(if_stats, OPT_COMMENT, &iface.isb_comment); + /* XXX - support multiple comments */ + if (wtap_block_get_nth_string_option_value(if_stats, OPT_COMMENT, 0, &iface.isb_comment) != WTAP_OPTTYPE_SUCCESS) { + iface.isb_comment = NULL; + } } g_array_append_val(st->ifaces, iface); } diff --git a/tshark.c b/tshark.c index 58f1765028..8fac691195 100644 --- a/tshark.c +++ b/tshark.c @@ -2877,10 +2877,10 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type, nrb_hdrs = wtap_file_get_nrb_for_new_file(cf->wth); /* If we don't have an application name add Tshark */ - wtap_optionblock_get_option_string(g_array_index(shb_hdrs, wtap_optionblock_t, 0), OPT_SHB_USERAPPL, &shb_user_appl); - if (shb_user_appl == NULL) { - /* this is free'd by wtap_optionblock_free() later */ - wtap_optionblock_set_option_string_format(g_array_index(shb_hdrs, wtap_optionblock_t, 0), OPT_SHB_USERAPPL, "TShark (Wireshark) %s", get_ws_vcs_version_info()); + if (wtap_block_get_string_option_value(g_array_index(shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, &shb_user_appl) != WTAP_OPTTYPE_SUCCESS || + shb_user_appl == NULL) { + /* this is free'd by wtap_block_free() later */ + wtap_block_add_string_option_format(g_array_index(shb_hdrs, wtap_block_t, 0), OPT_SHB_USERAPPL, "TShark (Wireshark) %s", get_ws_vcs_version_info()); } if (linktype != WTAP_ENCAP_PER_PACKET && @@ -3121,8 +3121,8 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type, break; } wtap_dump_close(pdh, &err); - wtap_optionblock_array_free(shb_hdrs); - wtap_optionblock_array_free(nrb_hdrs); + wtap_block_array_free(shb_hdrs); + wtap_block_array_free(nrb_hdrs); exit(2); } } @@ -3236,8 +3236,8 @@ load_cap_file(capture_file *cf, char *save_file, int out_file_type, break; } wtap_dump_close(pdh, &err); - wtap_optionblock_array_free(shb_hdrs); - wtap_optionblock_array_free(nrb_hdrs); + wtap_block_array_free(shb_hdrs); + wtap_block_array_free(nrb_hdrs); exit(2); } } @@ -3353,8 +3353,8 @@ out: cf->wth = NULL; g_free(save_file_string); - wtap_optionblock_array_free(shb_hdrs); - wtap_optionblock_array_free(nrb_hdrs); + wtap_block_array_free(shb_hdrs); + wtap_block_array_free(nrb_hdrs); return err; } diff --git a/ui/gtk/file_import_dlg.c b/ui/gtk/file_import_dlg.c index 338c312ad4..dc6a97a4f5 100644 --- a/ui/gtk/file_import_dlg.c +++ b/ui/gtk/file_import_dlg.c @@ -458,10 +458,10 @@ file_import_open(text_import_info_t *info) int err; /* pcapng defs */ - wtap_optionblock_t shb_hdr; - GArray *shb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t)); + wtap_block_t shb_hdr; + GArray *shb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); wtapng_iface_descriptions_t *idb_inf; - wtap_optionblock_t int_data; + wtap_block_t int_data; wtapng_if_descr_mandatory_t *int_data_mand; GString *os_info_str; gsize opt_len; @@ -470,35 +470,35 @@ file_import_open(text_import_info_t *info) os_info_str = g_string_new(""); get_os_version_info(os_info_str); - shb_hdr = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION); + shb_hdr = wtap_block_create(WTAP_BLOCK_NG_SECTION); /* options */ - wtap_optionblock_set_option_string_format(shb_hdr, OPT_COMMENT, "File created by File->Import of file %s", info->import_text_filename); + wtap_block_add_string_option_format(shb_hdr, OPT_COMMENT, "File created by File->Import of file %s", info->import_text_filename); /* * UTF-8 string containing the name of the operating system used to create * this section. */ opt_len = os_info_str->len; - wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_OS, g_string_free(os_info_str, TRUE), opt_len); + wtap_block_add_string_option(shb_hdr, OPT_SHB_OS, g_string_free(os_info_str, TRUE), opt_len); /* * UTF-8 string containing the name of the application used to create * this section. */ - wtap_optionblock_set_option_string_format(shb_hdr, OPT_SHB_USERAPPL, "Wireshark %s", get_ws_vcs_version_info()); + wtap_block_add_string_option_format(shb_hdr, OPT_SHB_USERAPPL, "Wireshark %s", get_ws_vcs_version_info()); /* Create fake IDB info */ idb_inf = g_new(wtapng_iface_descriptions_t,1); - idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t)); + idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); /* create the fake interface data */ - 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 = wtap_block_create(WTAP_BLOCK_IF_DESCR); + int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_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", strlen("Fake IF File->Import")); + wtap_block_add_string_option(int_data, OPT_IDB_NAME, "Fake IF File->Import", strlen("Fake IF File->Import")); g_array_append_val(idb_inf->interface_data, int_data); g_array_append_val(shb_hdrs, shb_hdr); @@ -557,7 +557,7 @@ end: g_free(info->date_timestamp_format); g_free(info); g_free(capfile_name); - wtap_optionblock_array_free(shb_hdrs); + wtap_block_array_free(shb_hdrs); wtap_free_idb_info(idb_inf); window_destroy(file_import_dlg_w); } diff --git a/ui/gtk/summary_dlg.c b/ui/gtk/summary_dlg.c index 8bb85774ab..78f596c49e 100644 --- a/ui/gtk/summary_dlg.c +++ b/ui/gtk/summary_dlg.c @@ -188,9 +188,8 @@ summary_open_cb(GtkWidget *w _U_, gpointer d _U_) unsigned int elapsed_time; iface_options iface; - wtap_optionblock_t shb_inf; + wtap_block_t shb_inf; unsigned int i; - GArray *opts; if (summary_dlg != NULL) { /* There's already a Summary dialog box; reactivate it. */ @@ -293,14 +292,13 @@ summary_open_cb(GtkWidget *w _U_, gpointer d _U_) buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (comment_view)); gtk_text_buffer_set_text (buffer, "", -1); if (shb_inf != NULL) { - wtap_optionblock_get_string_options(shb_inf, OPT_COMMENT, &opts); - for (i = 0; i < opts->len; i++) { - /* XXX - this only shows the last comment */ - char *opt_comment = g_array_index(opts, char *, i); + char *opt_comment; + + /* XXX - this only shows the last comment */ + for (i = 0; wtap_block_get_nth_string_option_value(shb_inf, OPT_COMMENT, i, &opt_comment) == WTAP_OPTTYPE_SUCCESS; i++) { if (opt_comment != NULL && opt_comment[0] != '\0') gtk_text_buffer_set_text (buffer, opt_comment, -1); } - g_array_free(opts, TRUE); } gtk_box_pack_start(GTK_BOX(comment_vbox), comment_view, TRUE, TRUE, 0); gtk_widget_show (comment_view); @@ -350,21 +348,21 @@ summary_open_cb(GtkWidget *w _U_, gpointer d _U_) if (shb_inf != NULL) { char *str; - wtap_optionblock_get_option_string(shb_inf, OPT_SHB_HARDWARE, &str); - if (str != NULL && str[0] != '\0') { + if (wtap_block_get_string_option_value(shb_inf, OPT_SHB_HARDWARE, &str) == WTAP_OPTTYPE_SUCCESS && + str != NULL && str[0] != '\0') { g_snprintf(string_buff, SHB_STR_SNIP_LEN, "%s", str); add_string_to_grid(grid, &row, "Capture HW:",string_buff); } - wtap_optionblock_get_option_string(shb_inf, OPT_SHB_OS, &str); - if (str != NULL && str[0] != '\0') { + if (wtap_block_get_string_option_value(shb_inf, OPT_SHB_OS, &str) == WTAP_OPTTYPE_SUCCESS && + str != NULL && str[0] != '\0') { /* truncate the strings to a reasonable length */ g_snprintf(string_buff, SHB_STR_SNIP_LEN, "%s", str); add_string_to_grid(grid, &row, "OS:", string_buff); } - wtap_optionblock_get_option_string(shb_inf, OPT_SHB_USERAPPL, &str); - if (str != NULL && str[0] != '\0') { + if (wtap_block_get_string_option_value(shb_inf, OPT_SHB_USERAPPL, &str) == WTAP_OPTTYPE_SUCCESS && + str != NULL && str[0] != '\0') { /* truncate the strings to a reasonable length */ g_snprintf(string_buff, SHB_STR_SNIP_LEN, "%s", str); add_string_to_grid(grid, &row, "Capture application:", string_buff); @@ -664,8 +662,7 @@ summary_to_texbuff(GtkTextBuffer *buffer) summary_tally summary; gchar string_buff[SUM_STR_MAX]; gchar tmp_buff[SUM_STR_MAX]; - wtap_optionblock_t shb_inf; - GArray *opts; + wtap_block_t shb_inf; unsigned int i; unsigned int elapsed_time; iface_options iface; @@ -768,20 +765,20 @@ summary_to_texbuff(GtkTextBuffer *buffer) if (shb_inf != NULL) { char *str; - wtap_optionblock_get_option_string(shb_inf, OPT_SHB_HARDWARE, &str); - if (str != NULL && str[0] != '\0') { + if (wtap_block_get_string_option_value(shb_inf, OPT_SHB_HARDWARE, &str) == WTAP_OPTTYPE_SUCCESS && + str != NULL && str[0] != '\0') { /* truncate the string to a reasonable length */ g_snprintf(string_buff, SUM_STR_MAX, INDENT "Capture HW: %s\n", str); gtk_text_buffer_insert_at_cursor (buffer, string_buff, -1); } - wtap_optionblock_get_option_string(shb_inf, OPT_SHB_OS, &str); - if (str != NULL && str[0] != '\0') { + if (wtap_block_get_string_option_value(shb_inf, OPT_SHB_OS, &str) == WTAP_OPTTYPE_SUCCESS && + str != NULL && str[0] != '\0') { /* truncate the strings to a reasonable length */ g_snprintf(string_buff, SUM_STR_MAX, INDENT "OS: %s\n", str); gtk_text_buffer_insert_at_cursor (buffer, string_buff, -1); } - wtap_optionblock_get_option_string(shb_inf, OPT_SHB_USERAPPL, &str); - if (str != NULL && str[0] != '\0') { + if (wtap_block_get_string_option_value(shb_inf, OPT_SHB_USERAPPL, &str) == WTAP_OPTTYPE_SUCCESS && + str != NULL && str[0] != '\0') { /* truncate the string to a reasonable length */ g_snprintf(string_buff, SUM_STR_MAX, INDENT "Capture application: %s\n", str); gtk_text_buffer_insert_at_cursor (buffer, string_buff, -1); @@ -901,10 +898,10 @@ summary_to_texbuff(GtkTextBuffer *buffer) /* Trace file comments from SHB */ shb_inf = wtap_file_get_shb(cfile.wth); if (shb_inf != NULL) { - wtap_optionblock_get_string_options(shb_inf, OPT_COMMENT, &opts); - for (i = 0; i < opts->len; i++) { + char *opt_comment; + + for (i = 0; wtap_block_get_nth_string_option_value(shb_inf, OPT_COMMENT, i, &opt_comment) == WTAP_OPTTYPE_SUCCESS; i++) { /* XXX - separator between comments? */ - char *opt_comment = g_array_index(opts, char *, i); if (opt_comment != NULL && opt_comment[0] != '\0') gtk_text_buffer_insert_at_cursor(buffer, opt_comment, -1); } diff --git a/ui/qt/capture_file_properties_dialog.cpp b/ui/qt/capture_file_properties_dialog.cpp index 59c5bcf6d2..60ce9ddcb1 100644 --- a/ui/qt/capture_file_properties_dialog.cpp +++ b/ui/qt/capture_file_properties_dialog.cpp @@ -242,14 +242,15 @@ QString CaptureFilePropertiesDialog::summaryToHtml() out << section_tmpl_.arg(tr("Capture")); out << table_begin; - wtap_optionblock_t shb_inf = wtap_file_get_shb(cap_file_.capFile()->wth); + wtap_block_t shb_inf = wtap_file_get_shb(cap_file_.capFile()->wth); char *str; if (shb_inf != NULL) { QString capture_hardware(unknown); - wtap_optionblock_get_option_string(shb_inf, OPT_SHB_HARDWARE, &str); - if (str != NULL && str[0] != '\0') { - capture_hardware = str; + if (wtap_block_get_string_option_value(shb_inf, OPT_SHB_HARDWARE, &str) == WTAP_OPTTYPE_SUCCESS) { + if (str != NULL && str[0] != '\0') { + capture_hardware = str; + } } // capture HW out << table_row_begin @@ -258,9 +259,10 @@ QString CaptureFilePropertiesDialog::summaryToHtml() << table_row_end; QString capture_os(unknown); - wtap_optionblock_get_option_string(shb_inf, OPT_SHB_OS, &str); - if (str != NULL && str[0] != '\0') { - capture_os = str; + if (wtap_block_get_string_option_value(shb_inf, OPT_SHB_OS, &str) == WTAP_OPTTYPE_SUCCESS) { + if (str != NULL && str[0] != '\0') { + capture_os = str; + } } out << table_row_begin << table_vheader_tmpl.arg(tr("OS")) @@ -268,9 +270,10 @@ QString CaptureFilePropertiesDialog::summaryToHtml() << table_row_end; QString capture_app(unknown); - wtap_optionblock_get_option_string(shb_inf, OPT_SHB_USERAPPL, &str); - if (str != NULL && str[0] != '\0') { - capture_app = str; + if (wtap_block_get_string_option_value(shb_inf, OPT_SHB_USERAPPL, &str) == WTAP_OPTTYPE_SUCCESS) { + if (str != NULL && str[0] != '\0') { + capture_app = str; + } } out << table_row_begin << table_vheader_tmpl.arg(tr("Application")) diff --git a/ui/qt/resolved_addresses_dialog.cpp b/ui/qt/resolved_addresses_dialog.cpp index 791f6d1ca7..2e8b45cd0b 100644 --- a/ui/qt/resolved_addresses_dialog.cpp +++ b/ui/qt/resolved_addresses_dialog.cpp @@ -197,7 +197,22 @@ ResolvedAddressesDialog::ResolvedAddressesDialog(QWidget *parent, CaptureFile *c wtap* wth = capture_file->capFile()->wth; if (wth) { // might return null - comment_ = wtap_get_nrb_comment(wth); + wtap_block_t nrb_hdr; + + /* + * XXX - support multiple NRBs. + */ + nrb_hdr = wtap_file_get_nrb(wth); + if (nrb_hdr != NULL) { + char *str; + + /* + * XXX - support multiple comments. + */ + if (wtap_block_get_nth_string_option_value(nrb_hdr, OPT_COMMENT, 0, &str) == WTAP_OPTTYPE_SUCCESS) { + comment_ = str; + } + } } } diff --git a/ui/tap_export_pdu.c b/ui/tap_export_pdu.c index a151e72567..02cd3df33f 100644 --- a/ui/tap_export_pdu.c +++ b/ui/tap_export_pdu.c @@ -102,10 +102,10 @@ exp_pdu_open(exp_pdu_t *exp_pdu_tap_data, int fd, char *comment) int err; /* pcapng defs */ - wtap_optionblock_t shb_hdr; - GArray *shb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t)); + wtap_block_t shb_hdr; + GArray *shb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); wtapng_iface_descriptions_t *idb_inf; - wtap_optionblock_t int_data; + wtap_block_t int_data; wtapng_if_descr_mandatory_t *int_data_mand; GString *os_info_str; gsize opt_len; @@ -114,10 +114,10 @@ exp_pdu_open(exp_pdu_t *exp_pdu_tap_data, int fd, char *comment) os_info_str = g_string_new(""); get_os_version_info(os_info_str); - shb_hdr = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION); + shb_hdr = wtap_block_create(WTAP_BLOCK_NG_SECTION); /* options */ - wtap_optionblock_set_option_string(shb_hdr, OPT_COMMENT, comment, strlen(comment)); + wtap_block_add_string_option(shb_hdr, OPT_COMMENT, comment, strlen(comment)); g_free(comment); /* @@ -125,27 +125,27 @@ exp_pdu_open(exp_pdu_t *exp_pdu_tap_data, int fd, char *comment) * this section. */ opt_len = os_info_str->len; - wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_OS, g_string_free(os_info_str, TRUE), opt_len); + wtap_block_add_string_option(shb_hdr, OPT_SHB_OS, g_string_free(os_info_str, TRUE), opt_len); /* * UTF-8 string containing the name of the application used to create * this section. */ - wtap_optionblock_set_option_string_format(shb_hdr, OPT_SHB_USERAPPL, "Wireshark %s", get_ws_vcs_version_info()); + wtap_block_add_string_option_format(shb_hdr, OPT_SHB_USERAPPL, "Wireshark %s", get_ws_vcs_version_info()); /* Create fake IDB info */ idb_inf = g_new(wtapng_iface_descriptions_t,1); - idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t)); + idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); /* create the fake interface data */ - 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 = wtap_block_create(WTAP_BLOCK_IF_DESCR); + int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_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", strlen("Fake IF, PDU->Export")); - wtap_optionblock_set_option_uint8(int_data, OPT_IDB_TSRESOL, 9); + wtap_block_add_string_option(int_data, OPT_IDB_NAME, "Fake IF, PDU->Export", strlen("Fake IF, PDU->Export")); + wtap_block_add_uint8_option(int_data, OPT_IDB_TSRESOL, 9); g_array_append_val(idb_inf->interface_data, int_data); diff --git a/wiretap/erf.c b/wiretap/erf.c index e8208be361..e694ade9b2 100644 --- a/wiretap/erf.c +++ b/wiretap/erf.c @@ -946,7 +946,7 @@ int erf_dump_open(wtap_dumper *wdh, int *err) */ int erf_populate_interfaces(wtap *wth) { - wtap_optionblock_t int_data; + wtap_block_t int_data; wtapng_if_descr_mandatory_t* int_data_mand; int i; @@ -956,8 +956,8 @@ int erf_populate_interfaces(wtap *wth) /* Preemptively create interface entries for 4 interfaces, since this is the max number in ERF */ for (i=0; i<4; 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 = wtap_block_create(WTAP_BLOCK_IF_DESCR); + int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_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 */ @@ -969,9 +969,9 @@ int erf_populate_interfaces(wtap *wth) /* 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? */ + /* XXX: if_speed opt 8 Interface speed (in bits per second)*/ /* 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 */ + wtap_block_add_uint8_option(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). */ @@ -980,8 +980,8 @@ int erf_populate_interfaces(wtap *wth) int_data_mand->num_stat_entries = 0; int_data_mand->interface_statistics = NULL; - wtap_optionblock_set_option_string_format(int_data, OPT_IDB_NAME, "Port %c", 'A'+i); - wtap_optionblock_set_option_string_format(int_data, OPT_IDB_DESCR, "ERF Interface Id %d (Port %c)", i, 'A'+i); + wtap_block_add_string_option_format(int_data, OPT_IDB_NAME, "Port %c", 'A'+i); + wtap_block_add_string_option_format(int_data, OPT_IDB_DESCR, "ERF Interface Id %d (Port %c)", i, 'A'+i); g_array_append_val(wth->interface_data, int_data); } @@ -1065,7 +1065,7 @@ static struct erf_if_mapping* erf_find_interface_mapping(erf_t *erf_priv, guint6 return (struct erf_if_mapping*) g_hash_table_lookup(erf_priv->if_map, &if_map_lookup); } -static void erf_set_interface_descr(wtap_optionblock_t block, guint option_id, guint64 host_id, guint8 source_id, guint8 if_num, const gchar *descr) +static void erf_set_interface_descr(wtap_block_t block, guint option_id, guint64 host_id, guint8 source_id, guint8 if_num, const gchar *descr) { /* Source XXX,*/ char sourceid_buf[16]; @@ -1084,9 +1084,9 @@ static void erf_set_interface_descr(wtap_optionblock_t block, guint option_id, g } if (descr) { - wtap_optionblock_set_option_string_format(block, option_id, "%s (ERF%s%s Interface %d)", descr, hostid_buf, sourceid_buf, if_num); + wtap_block_set_string_option_value_format(block, option_id, "%s (ERF%s%s Interface %d)", descr, hostid_buf, sourceid_buf, if_num); } else { - wtap_optionblock_set_option_string_format(block, option_id, "Port %c (ERF%s%s Interface %d)", 'A'+if_num, hostid_buf, sourceid_buf, if_num); + wtap_block_set_string_option_value_format(block, option_id, "Port %c (ERF%s%s Interface %d)", 'A'+if_num, hostid_buf, sourceid_buf, if_num); } } @@ -1096,7 +1096,7 @@ static int erf_update_implicit_host_id(erf_t *erf_priv, wtap *wth, guint64 impli gpointer iter_value; GList* implicit_list = NULL; GList* item = NULL; - wtap_optionblock_t int_data; + wtap_block_t int_data; struct erf_if_mapping* if_map = NULL; int i; @@ -1128,7 +1128,7 @@ static int erf_update_implicit_host_id(erf_t *erf_priv, wtap *wth, guint64 impli for (i = 0; i < 4; i++) { if (if_map->interfaces[i].if_index >= 0) { /* XXX: this is a pointer! */ - int_data = g_array_index(wth->interface_data, wtap_optionblock_t, if_map->interfaces[i].if_index); + int_data = g_array_index(wth->interface_data, wtap_block_t, if_map->interfaces[i].if_index); erf_set_interface_descr(int_data, OPT_IDB_NAME, implicit_host_id, if_map->source_id, (guint8) i, if_map->interfaces[i].name); erf_set_interface_descr(int_data, OPT_IDB_DESCR, implicit_host_id, if_map->source_id, (guint8) i, if_map->interfaces[i].descr); } @@ -1147,7 +1147,7 @@ static int erf_update_implicit_host_id(erf_t *erf_priv, wtap *wth, guint64 impli int erf_populate_interface(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header *pseudo_header, guint64 host_id, guint8 source_id, guint8 if_num) { - wtap_optionblock_t int_data; + wtap_block_t int_data; wtapng_if_descr_mandatory_t* int_data_mand; struct erf_if_mapping* if_map = NULL; @@ -1184,8 +1184,8 @@ int erf_populate_interface(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header return if_map->interfaces[if_num].if_index; } - 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 = wtap_block_create(WTAP_BLOCK_IF_DESCR); + int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_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 */ @@ -1197,9 +1197,9 @@ int erf_populate_interface(erf_t *erf_priv, wtap *wth, union wtap_pseudo_header /* 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? */ + /* XXX: if_speed opt 8 Interface speed (in bits per second)*/ /* 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 */ + wtap_block_add_uint8_option(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 */ @@ -1247,7 +1247,7 @@ static int populate_capture_host_info(erf_t *erf_priv, wtap *wth, union wtap_pse { struct erf_meta_tag tag = {0, 0, NULL}; - wtap_optionblock_t shb_hdr; + wtap_block_t shb_hdr; char* tmp; gchar* app_name = NULL; gchar* app_version = NULL; @@ -1262,7 +1262,7 @@ static int populate_capture_host_info(erf_t *erf_priv, wtap *wth, union wtap_pse /* XXX: wth->shb_hdr is already created by different layer, using directly for now. */ /* XXX: Only one section header is supported at this time */ - shb_hdr = g_array_index(wth->shb_hdrs, wtap_optionblock_t, 0); + shb_hdr = g_array_index(wth->shb_hdrs, wtap_block_t, 0); while ((tagtotallength = erf_meta_read_tag(&tag, state->tag_ptr, state->remaining_len)) && !ERF_META_IS_SECTION(tag.type)) { switch (state->sectiontype) { @@ -1274,7 +1274,7 @@ static int populate_capture_host_info(erf_t *erf_priv, wtap *wth, union wtap_pse switch (tag.type) { case ERF_META_TAG_comment: - wtap_optionblock_set_option_string(shb_hdr, OPT_COMMENT, tag.value, tag.length); + wtap_block_add_string_option(shb_hdr, OPT_COMMENT, tag.value, tag.length); break; } /* Fall through */ @@ -1299,7 +1299,7 @@ static int populate_capture_host_info(erf_t *erf_priv, wtap *wth, union wtap_pse descr = g_strndup((gchar*) tag.value, tag.length); break; case ERF_META_TAG_os: - wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_OS, tag.value, tag.length); + wtap_block_set_string_option_value(shb_hdr, OPT_SHB_OS, tag.value, tag.length); break; case ERF_META_TAG_app_name: g_free(app_name); @@ -1328,7 +1328,7 @@ static int populate_capture_host_info(erf_t *erf_priv, wtap *wth, union wtap_pse /* If no app_version will just use app_name */ tmp = g_strjoin(" ", app_name, app_version, NULL); - wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_USERAPPL, tmp, strlen(tmp)); + wtap_block_set_string_option_value(shb_hdr, OPT_SHB_USERAPPL, tmp, strlen(tmp)); g_free(tmp); g_free(app_name); @@ -1357,13 +1357,13 @@ static int populate_capture_host_info(erf_t *erf_priv, wtap *wth, union wtap_pse /* Combine into "Description (Model; CPU)" */ if (state->sectiontype == ERF_META_SECTION_HOST && descr) { if (modelcpu) { - wtap_optionblock_set_option_string_format(shb_hdr, OPT_SHB_HARDWARE, "%s (%s)", descr, modelcpu); + wtap_block_set_string_option_value_format(shb_hdr, OPT_SHB_HARDWARE, "%s (%s)", descr, modelcpu); } else { - wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_HARDWARE, descr, strlen(descr)); + wtap_block_set_string_option_value(shb_hdr, OPT_SHB_HARDWARE, descr, strlen(descr)); /*descr = NULL;*/ } } else if (modelcpu) { - wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_HARDWARE, modelcpu, strlen(modelcpu)); + wtap_block_set_string_option_value(shb_hdr, OPT_SHB_HARDWARE, modelcpu, strlen(modelcpu)); /*modelcpu = NULL;*/ } @@ -1428,7 +1428,7 @@ static int populate_interface_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo struct erf_meta_tag tag = {0, 0, NULL}; guint32 tagtotallength; int interface_index = -1; - wtap_optionblock_t int_data = NULL; + wtap_block_t int_data = NULL; wtapng_if_descr_mandatory_t* int_data_mand = NULL; wtapng_if_descr_filter_t if_filter; guint32 if_num = 0; @@ -1487,8 +1487,8 @@ static int populate_interface_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo /* Get the wiretap interface metadata */ if (interface_index >= 0) { - int_data = g_array_index(wth->interface_data, wtap_optionblock_t, interface_index); - int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data); + int_data = g_array_index(wth->interface_data, wtap_block_t, interface_index); + int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data); } else if (interface_index == -2) { /* timing/unknown port */ return 0; @@ -1532,7 +1532,7 @@ static int populate_interface_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo break; case ERF_META_TAG_if_speed: if (tag.length >= 8) - wtap_optionblock_set_option_uint64(int_data, OPT_IDB_SPEED, pntoh64(tag.value)); + wtap_block_add_uint64_option(int_data, OPT_IDB_SPEED, pntoh64(tag.value)); break; case ERF_META_TAG_if_num: /* @@ -1544,7 +1544,7 @@ static int populate_interface_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo break; case ERF_META_TAG_fcs_len: if (tag.length >= 4) { - wtap_optionblock_set_option_uint8(int_data, OPT_IDB_FCSLEN, (guint8) pntoh32(tag.value)); + wtap_block_add_uint8_option(int_data, OPT_IDB_FCSLEN, (guint8) pntoh32(tag.value)); if_info->set_flags.fcs_len = 1; } break; @@ -1556,11 +1556,11 @@ static int populate_interface_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo } break; case ERF_META_TAG_comment: - wtap_optionblock_set_option_string(int_data, OPT_COMMENT, tag.value, tag.length); + wtap_block_add_string_option(int_data, OPT_COMMENT, tag.value, tag.length); break; case ERF_META_TAG_filter: if_filter.if_filter_str = g_strndup((gchar*) tag.value, tag.length); - wtap_optionblock_set_option_custom(int_data, OPT_IDB_FILTER, &if_filter); + wtap_block_add_custom_option(int_data, OPT_IDB_FILTER, &if_filter, sizeof if_filter); if_info->set_flags.filter = 1; break; default: @@ -1584,7 +1584,7 @@ static int populate_interface_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo if (state->if_map->module_filter_str && !if_info->set_flags.filter) { /* Duplicate because might use with multiple interfaces */ if_filter.if_filter_str = g_strdup(state->if_map->module_filter_str); - wtap_optionblock_set_option_custom(int_data, OPT_IDB_FILTER, &if_filter); + wtap_block_add_custom_option(int_data, OPT_IDB_FILTER, &if_filter, sizeof if_filter); /* * Don't set flag because stream is more specific than module. Interface * metadata bit is set so we don't look at the filter again regardless. @@ -1592,7 +1592,7 @@ static int populate_interface_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo } if (state->if_map->module_fcs_len != -1 && !if_info->set_flags.fcs_len) { - wtap_optionblock_set_option_uint8(int_data, OPT_IDB_FCSLEN, (guint8) state->if_map->module_fcs_len); + wtap_block_add_uint8_option(int_data, OPT_IDB_FCSLEN, (guint8) state->if_map->module_fcs_len); if_info->set_flags.fcs_len = 1; } @@ -1611,7 +1611,7 @@ static int populate_stream_info(erf_t *erf_priv _U_, wtap *wth, union wtap_pseud struct erf_meta_tag tag = {0, 0, NULL}; guint32 tagtotallength; int interface_index = -1; - wtap_optionblock_t int_data = NULL; + wtap_block_t int_data = NULL; wtapng_if_descr_mandatory_t* int_data_mand = NULL; wtapng_if_descr_filter_t if_filter; guint32 if_num = 0; @@ -1673,8 +1673,8 @@ static int populate_stream_info(erf_t *erf_priv _U_, wtap *wth, union wtap_pseud interface_index = if_info->if_index; /* Get the wiretap interface metadata */ if (interface_index >= 0) { - int_data = g_array_index(wth->interface_data, wtap_optionblock_t, interface_index); - int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data); + int_data = g_array_index(wth->interface_data, wtap_block_t, interface_index); + int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data); } if (!int_data) { @@ -1689,10 +1689,25 @@ static int populate_stream_info(erf_t *erf_priv _U_, wtap *wth, union wtap_pseud gint8 fcs_len = (gint8) pntoh32(tag.value); guint8 old_fcs_len = 0; - wtap_optionblock_get_option_uint8(int_data, OPT_IDB_FCSLEN, &old_fcs_len); - if (fcs_len > old_fcs_len || !if_info->set_flags.fcs_len) { - wtap_optionblock_set_option_uint8(int_data, OPT_IDB_FCSLEN, (guint8) pntoh32(tag.value)); - if_info->set_flags.fcs_len = 1; + switch (wtap_block_get_uint8_option_value(int_data, OPT_IDB_FCSLEN, &old_fcs_len)) { + + case WTAP_OPTTYPE_SUCCESS: + /* We already have an FCS length option; update it. */ + if (fcs_len > old_fcs_len || !if_info->set_flags.fcs_len) { + wtap_block_set_uint8_option_value(int_data, OPT_IDB_FCSLEN, (guint8) pntoh32(tag.value)); + if_info->set_flags.fcs_len = 1; + } + break; + + case WTAP_OPTTYPE_NOT_FOUND: + /* We don't have an FCS length option; add it. */ + wtap_block_add_uint8_option(int_data, OPT_IDB_FCSLEN, (guint8) pntoh32(tag.value)); + if_info->set_flags.fcs_len = 1; + break; + + default: + /* "shouldn't happen" */ + break; } } break; @@ -1711,7 +1726,7 @@ static int populate_stream_info(erf_t *erf_priv _U_, wtap *wth, union wtap_pseud /* Override only if not set */ if (!if_info->set_flags.filter) { if_filter.if_filter_str = g_strndup((gchar*) tag.value, tag.length); - wtap_optionblock_set_option_custom(int_data, OPT_IDB_FILTER, &if_filter); + wtap_block_add_custom_option(int_data, OPT_IDB_FILTER, &if_filter, sizeof if_filter); if_info->set_flags.filter = 1; } break; diff --git a/wiretap/file_access.c b/wiretap/file_access.c index ff2200bd2d..1466f562ff 100644 --- a/wiretap/file_access.c +++ b/wiretap/file_access.c @@ -714,7 +714,7 @@ wtap_open_offline(const char *filename, unsigned int type, int *err, char **err_ unsigned int i; gboolean use_stdin = FALSE; gchar *extension; - wtap_optionblock_t shb; + wtap_block_t shb; *err = 0; *err_info = NULL; @@ -834,15 +834,15 @@ 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_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t)); - shb = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION); + wth->shb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); + shb = wtap_block_create(WTAP_BLOCK_NG_SECTION); if (shb) g_array_append_val(wth->shb_hdrs, shb); /* 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(wtap_optionblock_t)); + wth->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); if (wth->random_fh) { wth->fast_seek = g_ptr_array_new(); @@ -1103,17 +1103,17 @@ success: if ((wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP) || (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC)) { - 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); + wtap_block_t descr = wtap_block_create(WTAP_BLOCK_IF_DESCR); + wtapng_if_descr_mandatory_t* descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(descr); descr_mand->wtap_encap = wth->file_encap; if (wth->file_type_subtype == WTAP_FILE_TYPE_SUBTYPE_PCAP_NSEC) { descr_mand->time_units_per_second = 1000000000; /* nanosecond resolution */ - wtap_optionblock_set_option_uint8(descr, OPT_IDB_TSRESOL, 9); + wtap_block_add_uint8_option(descr, OPT_IDB_TSRESOL, 9); descr_mand->tsprecision = WTAP_TSPREC_NSEC; } else { descr_mand->time_units_per_second = 1000000; /* default microsecond resolution */ - wtap_optionblock_set_option_uint8(descr, OPT_IDB_TSRESOL, 6); + /* No need to add an option, this is the default */ descr_mand->tsprecision = WTAP_TSPREC_USEC; } descr_mand->link_type = wtap_wtap_encap_to_pcap_encap(wth->file_encap); @@ -2166,7 +2166,7 @@ wtap_dump_init_dumper(int file_type_subtype, int encap, int snaplen, gboolean co GArray* nrb_hdrs, int *err) { wtap_dumper *wdh; - wtap_optionblock_t descr, file_int_data; + wtap_block_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 @@ -2188,32 +2188,29 @@ 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(wtap_optionblock_t)); + wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); for (itf_count = 0; itf_count < idb_inf->interface_data->len; itf_count++) { - 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); + file_int_data = g_array_index(idb_inf->interface_data, wtap_block_t, itf_count); + file_int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(file_int_data); + descr = wtap_block_create(WTAP_BLOCK_IF_DESCR); + wtap_block_copy(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 = (wtapng_if_descr_mandatory_t*)wtap_block_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_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR); - descr_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(descr); + descr = wtap_block_create(WTAP_BLOCK_IF_DESCR); + descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_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)", - strlen("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)); + wdh->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); g_array_append_val(wdh->interface_data, descr); } return wdh; diff --git a/wiretap/lanalyzer.c b/wiretap/lanalyzer.c index 947e3e13df..6e6f3f49dc 100644 --- a/wiretap/lanalyzer.c +++ b/wiretap/lanalyzer.c @@ -330,7 +330,7 @@ wtap_open_return_val lanalyzer_open(wtap *wth, int *err, gchar **err_info) g_free(comment); return WTAP_OPEN_NOT_MINE; } - wtap_optionblock_set_option_string(g_array_index(wth->shb_hdrs, wtap_optionblock_t, 0), OPT_COMMENT, comment, record_length); + wtap_block_add_string_option(g_array_index(wth->shb_hdrs, wtap_block_t, 0), OPT_COMMENT, comment, record_length); g_free(comment); } diff --git a/wiretap/merge.c b/wiretap/merge.c index 6870e8cbeb..ea3f9a6dd5 100644 --- a/wiretap/merge.c +++ b/wiretap/merge.c @@ -365,7 +365,7 @@ create_shb_header(const merge_in_file_t *in_files, const guint in_file_count, const gchar *app_name) { GArray *shb_hdrs; - wtap_optionblock_t shb_hdr; + wtap_block_t shb_hdr; GString *comment_gstr; GString *os_info_str; guint i; @@ -374,16 +374,21 @@ create_shb_header(const merge_in_file_t *in_files, const guint in_file_count, gsize opt_len; shb_hdrs = wtap_file_get_shb_for_new_file(in_files[0].wth); - shb_hdr = g_array_index(shb_hdrs, wtap_optionblock_t, 0); + shb_hdr = g_array_index(shb_hdrs, wtap_block_t, 0); comment_gstr = g_string_new(""); - /* 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_comment && strlen(shb_comment) > 0) { + /* + * TODO: merge comments from all files + * + * XXX - do we want some way to record which comments, hardware/OS/app + * descriptions, IDBs, etc.? came from which files? + * + * XXX - fix this to handle multiple comments from a single file. + */ + if (wtap_block_get_nth_string_option_value(shb_hdr, OPT_COMMENT, 0, &shb_comment) == WTAP_OPTTYPE_SUCCESS && + shb_comment && strlen(shb_comment) > 0) { + /* very lame way to save comments - does not save them from the other files */ g_string_append_printf(comment_gstr, "%s \n",shb_comment); } @@ -396,27 +401,32 @@ 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_data = (wtapng_mandatory_section_t*)wtap_optionblock_get_mandatory_data(shb_hdr); + shb_data = (wtapng_mandatory_section_t*)wtap_block_get_mandatory_data(shb_hdr); shb_data->section_length = -1; /* TODO: handle comments from each file being merged */ opt_len = comment_gstr->len; - wtap_optionblock_set_option_string(shb_hdr, OPT_COMMENT, g_string_free(comment_gstr, TRUE), opt_len); /* section comment */ - wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_HARDWARE, NULL, 0 ); /* NULL if not available, UTF-8 string containing the */ + wtap_block_set_nth_string_option_value(shb_hdr, OPT_COMMENT, 0, g_string_free(comment_gstr, TRUE), opt_len); /* section comment */ + /* + * XXX - and how do we preserve all the OPT_SHB_HARDWARE, OPT_SHB_OS, + * and OPT_SHB_USERAPPL values from all the previous files? + */ + wtap_block_set_string_option_value(shb_hdr, OPT_SHB_HARDWARE, NULL, 0 ); /* NULL if not available, UTF-8 string containing the */ /* description of the hardware used to create this section. */ opt_len = os_info_str->len; - wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_OS, g_string_free(os_info_str, TRUE), opt_len); /* UTF-8 string containing the name */ + wtap_block_set_string_option_value(shb_hdr, OPT_SHB_OS, g_string_free(os_info_str, TRUE), opt_len); /* 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, app_name ? strlen(app_name): 0 ); /* NULL if not available, UTF-8 string containing the name */ + wtap_block_set_string_option_value(shb_hdr, OPT_SHB_USERAPPL, (char*)app_name, app_name ? strlen(app_name): 0 ); /* NULL if not available, UTF-8 string containing the name */ /* of the application used to create this section. */ return shb_hdrs; } static gboolean -is_duplicate_idb(const wtap_optionblock_t idb1, const wtap_optionblock_t idb2) +is_duplicate_idb(const wtap_block_t idb1, const wtap_block_t idb2) { wtapng_if_descr_mandatory_t *idb1_mand, *idb2_mand; + gboolean have_idb1_value, have_idb2_value; guint64 idb1_if_speed, idb2_if_speed; guint8 idb1_if_tsresol, idb2_if_tsresol; guint8 idb1_if_fcslen, idb2_if_fcslen; @@ -424,8 +434,8 @@ is_duplicate_idb(const wtap_optionblock_t idb1, const wtap_optionblock_t idb2) *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); + idb1_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(idb1); + idb2_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(idb2); merge_debug("merge::is_duplicate_idb() called"); merge_debug("idb1_mand->wtap_encap == idb2_mand->wtap_encap: %s", @@ -439,56 +449,122 @@ is_duplicate_idb(const wtap_optionblock_t idb1, const wtap_optionblock_t idb2) 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"); + if (idb1_mand->wtap_encap != idb2_mand->wtap_encap || + idb1_mand->link_type != idb2_mand->link_type) { + /* Clearly not the same interface. */ + merge_debug("merge::is_duplicate_idb() returning FALSE"); + return FALSE; + } + + if (idb1_mand->time_units_per_second != idb2_mand->time_units_per_second || + idb1_mand->tsprecision != idb2_mand->tsprecision) { + /* + * Probably not the same interface, and we can't combine them + * in any case. + */ + merge_debug("merge::is_duplicate_idb() returning FALSE"); + return FALSE; + } + + /* XXX: should snaplen not be compared? */ + if (idb1_mand->snap_len == idb2_mand->snap_len) { + merge_debug("merge::is_duplicate_idb() returning FALSE"); + return FALSE; + } + + /* XXX - what do to if we have only one value? */ + have_idb1_value = (wtap_block_get_uint64_option_value(idb1, OPT_IDB_SPEED, &idb1_if_speed) == WTAP_OPTTYPE_SUCCESS); + have_idb2_value = (wtap_block_get_uint64_option_value(idb2, OPT_IDB_SPEED, &idb2_if_speed) == WTAP_OPTTYPE_SUCCESS); + if (have_idb1_value && have_idb2_value) { + merge_debug("idb1_if_speed == idb2_if_speed: %s", + (idb1_if_speed == idb2_if_speed) ? "TRUE":"FALSE"); + if (idb1_if_speed != idb2_if_speed) { + merge_debug("merge::is_duplicate_idb() returning FALSE"); + return FALSE; + } + } + + /* XXX - what do to if we have only one value? */ + have_idb1_value = (wtap_block_get_uint8_option_value(idb1, OPT_IDB_TSRESOL, &idb1_if_tsresol) == WTAP_OPTTYPE_SUCCESS); + have_idb2_value = (wtap_block_get_uint8_option_value(idb2, OPT_IDB_TSRESOL, &idb2_if_tsresol) == WTAP_OPTTYPE_SUCCESS); + if (have_idb1_value && have_idb2_value) { + merge_debug("idb1_if_tsresol == idb2_if_tsresol: %s", + (idb1_if_tsresol == idb2_if_tsresol) ? "TRUE":"FALSE"); + if (idb1_if_tsresol != idb2_if_tsresol) { + merge_debug("merge::is_duplicate_idb() returning FALSE"); + return FALSE; + } + } + + /* XXX - what do to if we have only one value? */ + have_idb1_value = (wtap_block_get_uint8_option_value(idb1, OPT_IDB_FCSLEN, &idb1_if_fcslen) == WTAP_OPTTYPE_SUCCESS); + have_idb2_value = (wtap_block_get_uint8_option_value(idb2, OPT_IDB_FCSLEN, &idb2_if_fcslen) == WTAP_OPTTYPE_SUCCESS); + if (have_idb1_value && have_idb2_value) { + merge_debug("idb1_if_fcslen == idb2_if_fcslen: %s", + (idb1_if_fcslen == idb2_if_fcslen) ? "TRUE":"FALSE"); + if (idb1_if_fcslen == idb2_if_fcslen) { + merge_debug("merge::is_duplicate_idb() returning FALSE"); + return FALSE; + } + } + + /* + * XXX - handle multiple comments? + * XXX - if the comments are different, just combine them if we + * decide the two interfaces are really the same? As comments + * can be arbitrary strings added by people, the fact that they're + * different doesn't necessarily mean the interfaces are different. + */ + have_idb1_value = (wtap_block_get_nth_string_option_value(idb1, OPT_COMMENT, 0, &idb1_opt_comment) == WTAP_OPTTYPE_SUCCESS); + have_idb2_value = (wtap_block_get_nth_string_option_value(idb2, OPT_COMMENT, 0, &idb2_opt_comment) == WTAP_OPTTYPE_SUCCESS); + if (have_idb1_value && have_idb2_value) { + merge_debug("g_strcmp0(idb1_opt_comment, idb2_opt_comment) == 0: %s", + (g_strcmp0(idb1_opt_comment, idb2_opt_comment) == 0) ? "TRUE":"FALSE"); + if (g_strcmp0(idb1_opt_comment, idb2_opt_comment) != 0) { + merge_debug("merge::is_duplicate_idb() returning FALSE"); + return FALSE; + } + } + + /* XXX - what do to if we have only one value? */ + have_idb1_value = (wtap_block_get_string_option_value(idb1, OPT_IDB_NAME, &idb1_if_name) == WTAP_OPTTYPE_SUCCESS); + have_idb2_value = (wtap_block_get_string_option_value(idb2, OPT_IDB_NAME, &idb2_if_name) == WTAP_OPTTYPE_SUCCESS); + if (have_idb1_value && have_idb2_value) { + merge_debug("g_strcmp0(idb1_if_name, idb2_if_name) == 0: %s", + (g_strcmp0(idb1_if_name, idb2_if_name) == 0) ? "TRUE":"FALSE"); + if (g_strcmp0(idb1_if_name, idb2_if_name) != 0) { + merge_debug("merge::is_duplicate_idb() returning FALSE"); + return FALSE; + } + } + + /* XXX - what do to if we have only one value? */ + have_idb1_value = (wtap_block_get_string_option_value(idb1, OPT_IDB_DESCR, &idb1_if_description) == WTAP_OPTTYPE_SUCCESS); + have_idb2_value = (wtap_block_get_string_option_value(idb2, OPT_IDB_DESCR, &idb2_if_description) == WTAP_OPTTYPE_SUCCESS); + if (have_idb1_value && have_idb2_value) { + merge_debug("g_strcmp0(idb1_if_description, idb2_if_description) == 0: %s", + (g_strcmp0(idb1_if_description, idb2_if_description) == 0) ? "TRUE":"FALSE"); + if (g_strcmp0(idb1_if_description, idb2_if_description) != 0) { + merge_debug("merge::is_duplicate_idb() returning FALSE"); + return FALSE; + } + } + + /* XXX - what do to if we have only one value? */ + have_idb1_value = (wtap_block_get_string_option_value(idb1, OPT_IDB_OS, &idb1_if_os) == WTAP_OPTTYPE_SUCCESS); + have_idb2_value = (wtap_block_get_string_option_value(idb2, OPT_IDB_OS, &idb2_if_os) == WTAP_OPTTYPE_SUCCESS); + if (have_idb1_value && have_idb2_value) { + merge_debug("g_strcmp0(idb1_if_os, idb2_if_os) == 0: %s", + (g_strcmp0(idb1_if_os, idb2_if_os) == 0) ? "TRUE":"FALSE"); + if (g_strcmp0(idb1_if_os, idb2_if_os) != 0) { + merge_debug("merge::is_duplicate_idb() returning FALSE"); + return FALSE; + } + } /* does not compare filters nor interface statistics */ - 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_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); + merge_debug("merge::is_duplicate_idb() returning TRUE"); + return TRUE; } /* @@ -500,7 +576,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; - wtap_optionblock_t first_file_idb, other_file_idb; + wtap_block_t first_file_idb, other_file_idb; guint i, j; g_assert(in_files != NULL); @@ -526,8 +602,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, wtap_optionblock_t, j); - other_file_idb = g_array_index(other_idb_list->interface_data, wtap_optionblock_t, j); + first_file_idb = g_array_index(first_idb_list->interface_data, wtap_block_t, j); + other_file_idb = g_array_index(other_idb_list->interface_data, wtap_block_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); @@ -556,11 +632,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 wtap_optionblock_t input_file_idb, +find_duplicate_idb(const wtap_block_t input_file_idb, const wtapng_iface_descriptions_t *merged_idb_list, guint *found_index) { - wtap_optionblock_t merged_idb; + wtap_block_t merged_idb; guint i; g_assert(input_file_idb != NULL); @@ -569,7 +645,7 @@ find_duplicate_idb(const wtap_optionblock_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, wtap_optionblock_t, i); + merged_idb = g_array_index(merged_idb_list->interface_data, wtap_block_t, i); if (is_duplicate_idb(input_file_idb, merged_idb)) { *found_index = i; @@ -583,24 +659,19 @@ find_duplicate_idb(const wtap_optionblock_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 wtap_optionblock_t input_file_idb) + const wtap_block_t input_file_idb) { - wtap_optionblock_t idb = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR); + wtap_block_t idb = wtap_block_create(WTAP_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); - wtap_optionblock_copy_options(idb, input_file_idb); - idb_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(idb); + wtap_block_copy(idb, input_file_idb); + idb_mand = (wtapng_if_descr_mandatory_t*)wtap_block_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; @@ -617,13 +688,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; - wtap_optionblock_t input_file_idb; + wtap_block_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(wtap_optionblock_t)); + merged_idb_list->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); if (mode == IDB_MERGE_MODE_ALL_SAME && all_idbs_are_duplicates(in_files, in_file_count)) { guint num_idbs; @@ -638,7 +709,7 @@ 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, - wtap_optionblock_t, itf_count); + wtap_block_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); } @@ -658,7 +729,7 @@ generate_merged_idb(merge_in_file_t *in_files, const guint in_file_count, const 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, - wtap_optionblock_t, itf_count); + wtap_block_t, itf_count); if (mode == IDB_MERGE_MODE_ANY_SAME && find_duplicate_idb(input_file_idb, merged_idb_list, &merged_index)) @@ -950,7 +1021,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_optionblock_array_free(shb_hdrs); + wtap_block_array_free(shb_hdrs); wtap_free_idb_info(idb_inf); return MERGE_ERR_CANT_OPEN_OUTFILE; } @@ -1080,7 +1151,7 @@ merge_files(int out_fd, const gchar* out_filename, const int file_type, } g_free(in_files); - wtap_optionblock_array_free(shb_hdrs); + wtap_block_array_free(shb_hdrs); 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 cf4d99df75..6b29e30ffd 100644 --- a/wiretap/nettrace_3gpp_32_423.c +++ b/wiretap/nettrace_3gpp_32_423.c @@ -709,10 +709,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 */ - GArray *shb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t)); - wtap_optionblock_t shb_hdr; + GArray *shb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); + wtap_block_t shb_hdr; wtapng_iface_descriptions_t *idb_inf = NULL; - wtap_optionblock_t int_data; + wtap_block_t int_data; wtapng_if_descr_mandatory_t *int_data_mand; GString *os_info_str; gint64 file_size; @@ -753,22 +753,22 @@ 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 = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION); + shb_hdr = wtap_block_create(WTAP_BLOCK_NG_SECTION); /* options */ - wtap_optionblock_set_option_string(shb_hdr, OPT_COMMENT, "File converted to Exported PDU format during opening", + wtap_block_add_string_option(shb_hdr, OPT_COMMENT, "File converted to Exported PDU format during opening", strlen("File converted to Exported PDU format during opening")); /* * UTF-8 string containing the name of the operating system used to create * this section. */ opt_len = os_info_str->len; - wtap_optionblock_set_option_string(shb_hdr, OPT_SHB_OS, g_string_free(os_info_str, TRUE), opt_len); + wtap_block_add_string_option(shb_hdr, OPT_SHB_OS, g_string_free(os_info_str, TRUE), opt_len); /* * UTF-8 string containing the name of the application used to create * this section. */ - wtap_optionblock_set_option_string_format(shb_hdr, OPT_SHB_USERAPPL, "Wireshark %s", get_ws_vcs_version_info()); + wtap_block_add_string_option_format(shb_hdr, OPT_SHB_USERAPPL, "Wireshark %s", get_ws_vcs_version_info()); /* Add header to the array */ g_array_append_val(shb_hdrs, shb_hdr); @@ -776,16 +776,16 @@ create_temp_pcapng_file(wtap *wth, int *err, gchar **err_info, nettrace_3gpp_32_ /* Create fake IDB info */ idb_inf = g_new(wtapng_iface_descriptions_t, 1); - idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t)); + idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); /* create the fake interface data */ - 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 = wtap_block_create(WTAP_BLOCK_IF_DESCR); + int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_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", strlen("Fake IF")); + wtap_block_add_string_option(int_data, OPT_IDB_NAME, "Fake IF", strlen("Fake IF")); int_data_mand->num_stat_entries = 0; /* Number of ISB:s */ int_data_mand->interface_statistics = NULL; @@ -1071,7 +1071,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_optionblock_array_free(shb_hdrs); + wtap_block_array_free(shb_hdrs); wtap_free_idb_info(idb_inf); return result; @@ -1130,7 +1130,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 */ - wtap_optionblock_copy_options(g_array_index(wth->shb_hdrs, wtap_optionblock_t, 0), g_array_index(file_info->wth_tmp_file->shb_hdrs, wtap_optionblock_t, 0)); + wtap_block_copy(g_array_index(wth->shb_hdrs, wtap_block_t, 0), g_array_index(file_info->wth_tmp_file->shb_hdrs, wtap_block_t, 0)); 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 afb2d72092..a46d976197 100644 --- a/wiretap/pcapng.c +++ b/wiretap/pcapng.c @@ -200,8 +200,8 @@ 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 */ - wtap_optionblock_t block; + guint32 type; /* block_type as defined by pcapng */ + wtap_block_t block; /* * XXX - currently don't know how to handle these! @@ -212,7 +212,7 @@ typedef struct wtapng_block_s { * in fact, they sometimes point to const values. */ struct wtap_pkthdr *packet_header; - Buffer *frame_buffer; + Buffer *frame_buffer; } wtapng_block_t; /* Interface data in private struct */ @@ -572,8 +572,8 @@ pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh, pn->version_major = version_major; pn->version_minor = version_minor; - wblock->block = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION); - section_data = (wtapng_mandatory_section_t*)wtap_optionblock_get_mandatory_data(wblock->block); + wblock->block = wtap_block_create(WTAP_BLOCK_NG_SECTION); + section_data = (wtapng_mandatory_section_t*)wtap_block_get_mandatory_data(wblock->block); /* 64bit section_length (currently unused) */ if (pn->byte_swapped) { section_data->section_length = GUINT64_SWAP_LE_BE(shb.section_length); @@ -614,7 +614,7 @@ pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh, case(OPT_COMMENT): if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) { tmp_content = g_strndup((char *)option_content, oh.option_length); - wtap_optionblock_set_option_string(wblock->block, OPT_COMMENT, option_content, oh.option_length); + wtap_block_add_string_option(wblock->block, OPT_COMMENT, option_content, oh.option_length); pcapng_debug("pcapng_read_section_header_block: opt_comment %s", tmp_content); g_free(tmp_content); } else { @@ -624,7 +624,8 @@ pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh, case(OPT_SHB_HARDWARE): if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) { tmp_content = g_strndup((char *)option_content, oh.option_length); - wtap_optionblock_set_option_string(wblock->block, OPT_SHB_HARDWARE, option_content, oh.option_length); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_string_option(wblock->block, OPT_SHB_HARDWARE, option_content, oh.option_length); pcapng_debug("pcapng_read_section_header_block: shb_hardware %s", tmp_content); g_free(tmp_content); } else { @@ -634,7 +635,8 @@ pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh, case(OPT_SHB_OS): if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) { tmp_content = g_strndup((char *)option_content, oh.option_length); - wtap_optionblock_set_option_string(wblock->block, OPT_SHB_OS, option_content, oh.option_length); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_string_option(wblock->block, OPT_SHB_OS, option_content, oh.option_length); pcapng_debug("pcapng_read_section_header_block: shb_os %s", tmp_content); g_free(tmp_content); } else { @@ -644,7 +646,8 @@ pcapng_read_section_header_block(FILE_T fh, pcapng_block_header_t *bh, case(OPT_SHB_USERAPPL): if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) { tmp_content = g_strndup((char *)option_content, oh.option_length); - wtap_optionblock_set_option_string(wblock->block, OPT_SHB_USERAPPL, option_content, oh.option_length); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_string_option(wblock->block, OPT_SHB_USERAPPL, option_content, oh.option_length); pcapng_debug("pcapng_read_section_header_block: shb_user_appl %s", tmp_content); g_free(tmp_content); } else { @@ -714,8 +717,8 @@ 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); + wblock->block = wtap_block_create(WTAP_BLOCK_IF_DESCR); + if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block); if (pn->byte_swapped) { if_descr_mand->link_type = GUINT16_SWAP_LE_BE(idb.linktype); if_descr_mand->snap_len = GUINT32_SWAP_LE_BE(idb.snaplen); @@ -775,7 +778,7 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh, case(OPT_COMMENT): /* opt_comment */ if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) { tmp_content = g_strndup((char *)option_content, oh.option_length); - wtap_optionblock_set_option_string(wblock->block, OPT_COMMENT, option_content, oh.option_length); + wtap_block_add_string_option(wblock->block, OPT_COMMENT, option_content, oh.option_length); pcapng_debug("pcapng_read_if_descr_block: opt_comment %s", tmp_content); g_free(tmp_content); } else { @@ -785,7 +788,8 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh, case(OPT_IDB_NAME): /* if_name */ if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) { tmp_content = g_strndup((char *)option_content, oh.option_length); - wtap_optionblock_set_option_string(wblock->block, OPT_IDB_NAME, option_content, oh.option_length); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_string_option(wblock->block, OPT_IDB_NAME, option_content, oh.option_length); pcapng_debug("pcapng_read_if_descr_block: if_name %s", tmp_content); g_free(tmp_content); } else { @@ -795,7 +799,8 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh, case(OPT_IDB_DESCR): /* if_description */ if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) { tmp_content = g_strndup((char *)option_content, oh.option_length); - wtap_optionblock_set_option_string(wblock->block, OPT_IDB_DESCR, option_content, oh.option_length); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_string_option(wblock->block, OPT_IDB_DESCR, option_content, oh.option_length); pcapng_debug("pcapng_read_if_descr_block: if_description %s", tmp_content); g_free(tmp_content); } else { @@ -811,7 +816,8 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh, memcpy(&tmp64, option_content, sizeof(guint64)); if (pn->byte_swapped) tmp64 = GUINT64_SWAP_LE_BE(tmp64); - wtap_optionblock_set_option_uint64(wblock->block, OPT_IDB_SPEED, tmp64); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_uint64_option(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); @@ -843,7 +849,8 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh, pcapng_debug("pcapng_open: time conversion might be inaccurate"); } if_descr_mand->time_units_per_second = time_units_per_second; - wtap_optionblock_set_option_uint8(wblock->block, OPT_IDB_TSRESOL, if_tsresol); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_uint8_option(wblock->block, OPT_IDB_TSRESOL, if_tsresol); if (time_units_per_second >= 1000000000) tsprecision = WTAP_TSPREC_NSEC; else if (time_units_per_second >= 1000000) @@ -881,7 +888,8 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh, 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); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_custom_option(wblock->block, OPT_IDB_FILTER, &if_filter, sizeof if_filter); } else { pcapng_debug("pcapng_read_if_descr_block: if_filter length %u seems strange", oh.option_length); } @@ -894,7 +902,8 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh, */ if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) { tmp_content = g_strndup((char *)option_content, oh.option_length); - wtap_optionblock_set_option_string(wblock->block, OPT_IDB_OS, option_content, oh.option_length); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_string_option(wblock->block, OPT_IDB_OS, option_content, oh.option_length); pcapng_debug("pcapng_read_if_descr_block: if_os %s", tmp_content); g_free(tmp_content); } else { @@ -903,7 +912,8 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh, break; case(OPT_IDB_FCSLEN): /* if_fcslen */ if (oh.option_length == 1) { - wtap_optionblock_set_option_uint8(wblock->block, OPT_IDB_TSRESOL, option_content[0]); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_uint8_option(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 */ @@ -1615,7 +1625,7 @@ pcapng_read_name_resolution_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t /* Ensure we have a name resolution block */ if (wblock->block == NULL) { - wblock->block = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_NRB); + wblock->block = wtap_block_create(WTAP_BLOCK_NG_NRB); } /* @@ -1841,7 +1851,7 @@ read_options: case(OPT_COMMENT): if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) { tmp_content = g_strndup((char *)option_content, oh.option_length); - wtap_optionblock_set_option_string(wblock->block, OPT_COMMENT, option_content, oh.option_length); + wtap_block_add_string_option(wblock->block, OPT_COMMENT, option_content, oh.option_length); pcapng_debug("pcapng_read_name_resolution_block: length %u opt_comment '%s'", oh.option_length, tmp_content); g_free(tmp_content); } else { @@ -1923,8 +1933,8 @@ 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); + wblock->block = wtap_block_create(WTAP_BLOCK_IF_STATS); + if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(wblock->block); if (pn->byte_swapped) { if_stats_mand->interface_id = GUINT32_SWAP_LE_BE(isb.interface_id); if_stats_mand->ts_high = GUINT32_SWAP_LE_BE(isb.timestamp_high); @@ -1969,7 +1979,7 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca case(OPT_COMMENT): /* opt_comment */ if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) { tmp_content = g_strndup((char *)option_content, oh.option_length); - wtap_optionblock_set_option_string(wblock->block, OPT_COMMENT, option_content, oh.option_length); + wtap_block_add_string_option(wblock->block, OPT_COMMENT, option_content, oh.option_length); pcapng_debug("pcapng_read_interface_statistics_block: opt_comment %s", tmp_content); g_free(tmp_content); } else { @@ -1994,7 +2004,8 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca starttime = (guint64)high; starttime <<= 32; starttime += (guint64)low; - wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_STARTTIME, starttime); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_uint64_option(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); @@ -2018,7 +2029,8 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca endtime = (guint64)high; endtime <<= 32; endtime += (guint64)low; - wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_ENDTIME, endtime); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_uint64_option(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); @@ -2034,7 +2046,8 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca memcpy(&ifrecv, option_content, sizeof(guint64)); if (pn->byte_swapped) ifrecv = GUINT64_SWAP_LE_BE(ifrecv); - wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_IFRECV, ifrecv); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_uint64_option(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); @@ -2050,7 +2063,8 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca memcpy(&ifdrop, option_content, sizeof(guint64)); if (pn->byte_swapped) ifdrop = GUINT64_SWAP_LE_BE(ifdrop); - wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_IFDROP, ifdrop); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_uint64_option(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); @@ -2066,7 +2080,8 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca memcpy(&filteraccept, option_content, sizeof(guint64)); if (pn->byte_swapped) filteraccept = GUINT64_SWAP_LE_BE(filteraccept); - wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_FILTERACCEPT, filteraccept); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_uint64_option(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); @@ -2082,7 +2097,8 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca memcpy(&osdrop, option_content, sizeof(guint64)); if (pn->byte_swapped) osdrop = GUINT64_SWAP_LE_BE(osdrop); - wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_OSDROP, osdrop); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_uint64_option(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); @@ -2098,7 +2114,8 @@ pcapng_read_interface_statistics_block(FILE_T fh, pcapng_block_header_t *bh, pca memcpy(&usrdeliv, option_content, sizeof(guint64)); if (pn->byte_swapped) usrdeliv = GUINT64_SWAP_LE_BE(usrdeliv); - wtap_optionblock_set_option_uint64(wblock->block, OPT_ISB_USRDELIV, usrdeliv); + /* Fails with multiple options; we silently ignore the failure */ + wtap_block_add_uint64_option(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); @@ -2402,12 +2419,12 @@ 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) { - wtap_optionblock_t int_data = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_DESCR); + wtap_block_t int_data = wtap_block_create(WTAP_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); + wtapng_if_descr_mandatory_t *if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data), + *wblock_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wblock->block); - wtap_optionblock_copy_options(int_data, wblock->block); + wtap_block_copy(int_data, wblock->block); /* XXX if_tsoffset; opt 14 A 64 bits integer value that specifies an offset (in seconds)...*/ /* Interface statistics */ @@ -2456,7 +2473,7 @@ 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. */ - wtap_optionblock_free(wblock.block); + wtap_block_free(wblock.block); wblock.block = NULL; *err = 0; *err_info = NULL; @@ -2464,7 +2481,7 @@ pcapng_open(wtap *wth, int *err, gchar **err_info) case PCAPNG_BLOCK_ERROR: /* An I/O error, or this probably *is* a pcap-ng file but not a valid one. */ - wtap_optionblock_free(wblock.block); + wtap_block_free(wblock.block); wblock.block = NULL; return WTAP_OPEN_ERROR; } @@ -2477,7 +2494,7 @@ pcapng_open(wtap *wth, int *err, gchar **err_info) * binary data? */ pcapng_debug("pcapng_open: first block type %u not SHB", wblock.type); - wtap_optionblock_free(wblock.block); + wtap_block_free(wblock.block); wblock.block = NULL; return WTAP_OPEN_NOT_MINE; } @@ -2488,7 +2505,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. */ - wtap_optionblock_copy_options(g_array_index(wth->shb_hdrs, wtap_optionblock_t, 0), wblock.block); + wtap_block_copy(g_array_index(wth->shb_hdrs, wtap_block_t, 0), wblock.block); wth->file_encap = WTAP_ENCAP_UNKNOWN; wth->snapshot_length = 0; @@ -2533,12 +2550,12 @@ 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..."); - wtap_optionblock_free(wblock.block); + wtap_block_free(wblock.block); wblock.block = NULL; break; } else { pcapng_debug("pcapng_open: couldn't read IDB"); - wtap_optionblock_free(wblock.block); + wtap_block_free(wblock.block); wblock.block = NULL; return WTAP_OPEN_ERROR; } @@ -2557,8 +2574,8 @@ pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) { pcapng_t *pcapng = (pcapng_t *)wth->priv; wtapng_block_t wblock; - wtap_optionblock_t wtapng_if_descr; - wtap_optionblock_t if_stats; + wtap_block_t wtapng_if_descr; + wtap_block_t if_stats; wtapng_if_stats_mandatory_t *if_stats_mand_block, *if_stats_mand; wtapng_if_descr_mandatory_t *wtapng_if_descr_mand; @@ -2603,7 +2620,7 @@ pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) /* More name resolution entries */ pcapng_debug("pcapng_read: block type BLOCK_TYPE_NRB"); if (wth->nrb_hdrs == NULL) { - wth->nrb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t)); + wth->nrb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); } g_array_append_val(wth->nrb_hdrs, wblock.block); break; @@ -2611,26 +2628,26 @@ 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_stats_mand_block = (wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(wblock.block); + if_stats_mand_block = (wtapng_if_stats_mandatory_t*)wtap_block_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, 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); + wtapng_if_descr = g_array_index(wth->interface_data, wtap_block_t, if_stats_mand_block->interface_id); + wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_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_mand->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t)); + wtapng_if_descr_mand->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); } - if_stats = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_STATS); - if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(if_stats); + if_stats = wtap_block_create(WTAP_BLOCK_IF_STATS); + if_stats_mand = (wtapng_if_stats_mandatory_t*)wtap_block_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); + wtap_block_copy(if_stats, wblock.block); g_array_append_val(wtapng_if_descr_mand->interface_statistics, if_stats); wtapng_if_descr_mand->num_stat_entries++; } @@ -2674,7 +2691,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); - wtap_optionblock_free(wblock.block); + wtap_block_free(wblock.block); if (ret != PCAPNG_BLOCK_OK) { pcapng_debug("pcapng_seek_read: couldn't read packet block (err=%d).", *err); @@ -2704,10 +2721,10 @@ pcapng_close(wtap *wth) g_array_free(pcapng->interfaces, TRUE); } -typedef struct pcapng_optionblock_size_t +typedef struct pcapng_block_size_t { guint32 size; -} pcapng_optionblock_size_t; +} pcapng_block_size_t; static guint32 pcapng_compute_option_string_size(char *str) { @@ -2728,9 +2745,9 @@ static guint32 pcapng_compute_option_string_size(char *str) return size; } -static void compute_shb_option_size(wtap_optionblock_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_option_type* option, void* user_data) +static void compute_shb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval, void* user_data) { - pcapng_optionblock_size_t* block_size = (pcapng_optionblock_size_t*)user_data; + pcapng_block_size_t* block_size = (pcapng_block_size_t*)user_data; guint32 size = 0; switch(option_id) @@ -2739,8 +2756,7 @@ static void compute_shb_option_size(wtap_optionblock_t block _U_, guint option_i case OPT_SHB_HARDWARE: case OPT_SHB_OS: case OPT_SHB_USERAPPL: - if (option != NULL) - size = pcapng_compute_option_string_size(option->stringval); + size = pcapng_compute_option_string_size(optval->stringval); break; default: /* Unknown options - size by datatype? */ @@ -2805,7 +2821,7 @@ static gboolean pcapng_write_option_string(wtap_dumper *wdh, guint option_id, ch return TRUE; } -static void write_wtap_shb_block(wtap_optionblock_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_option_type* option, void* user_data) +static void write_wtap_shb_block(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data) { pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data; @@ -2819,8 +2835,8 @@ static void write_wtap_shb_block(wtap_optionblock_t block _U_, guint option_id, case OPT_SHB_HARDWARE: case OPT_SHB_OS: case OPT_SHB_USERAPPL: - if ((option != NULL) && (option->stringval != NULL)) { - if (!pcapng_write_option_string(write_block->wdh, option_id, option->stringval, write_block->err)) { + if (optval->stringval != NULL) { + if (!pcapng_write_option_string(write_block->wdh, option_id, optval->stringval, write_block->err)) { write_block->success = FALSE; return; } @@ -2841,12 +2857,12 @@ pcapng_write_section_header_block(wtap_dumper *wdh, int *err) { pcapng_block_header_t bh; pcapng_section_header_block_t shb; - pcapng_optionblock_size_t block_size; + pcapng_block_size_t block_size; struct pcapng_option_header option_hdr; - wtap_optionblock_t wdh_shb = NULL; + wtap_block_t wdh_shb = NULL; if (wdh->shb_hdrs && (wdh->shb_hdrs->len > 0)) { - wdh_shb = g_array_index(wdh->shb_hdrs, wtap_optionblock_t, 0); + wdh_shb = g_array_index(wdh->shb_hdrs, wtap_block_t, 0); } block_size.size = 0; @@ -2855,7 +2871,7 @@ pcapng_write_section_header_block(wtap_dumper *wdh, int *err) pcapng_debug("pcapng_write_section_header_block: Have shb_hdr"); /* Compute block size */ - wtap_optionblock_foreach_option(wdh_shb, compute_shb_option_size, &block_size); + wtap_block_foreach_option(wdh_shb, compute_shb_option_size, &block_size); if (block_size.size > 0) { /* End-of-options tag */ @@ -2879,7 +2895,7 @@ pcapng_write_section_header_block(wtap_dumper *wdh, int *err) shb.version_major = 1; shb.version_minor = 0; if (wdh_shb) { - wtapng_mandatory_section_t* section_data = (wtapng_mandatory_section_t*)wtap_optionblock_get_mandatory_data(wdh_shb); + wtapng_mandatory_section_t* section_data = (wtapng_mandatory_section_t*)wtap_block_get_mandatory_data(wdh_shb); shb.section_length = section_data->section_length; } else { shb.section_length = -1; @@ -2897,7 +2913,7 @@ pcapng_write_section_header_block(wtap_dumper *wdh, int *err) block_data.wdh = wdh; block_data.err = err; block_data.success = TRUE; - wtap_optionblock_foreach_option(wdh_shb, write_wtap_shb_block, &block_data); + wtap_block_foreach_option(wdh_shb, write_wtap_shb_block, &block_data); if (!block_data.success) return FALSE; @@ -2935,7 +2951,7 @@ 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; - wtap_optionblock_t int_data; + wtap_block_t int_data; wtapng_if_descr_mandatory_t *int_data_mand; /* Don't write anything we're not willing to read. */ @@ -3001,9 +3017,9 @@ pcapng_write_enhanced_packet_block(wtap_dumper *wdh, *err = WTAP_ERR_INTERNAL; return FALSE; } - int_data = g_array_index(wdh->interface_data, wtap_optionblock_t, + int_data = g_array_index(wdh->interface_data, wtap_block_t, epb.interface_id); - int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data); + int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_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); @@ -3217,15 +3233,145 @@ pcapng_write_sysdig_event_block(wtap_dumper *wdh, } -/* Arbitrary. */ -#define NRES_REC_MAX_SIZE ((WTAP_MAX_PACKET_SIZE * 4) + 16) +/* + * libpcap's maximum pcapng block size is currently 16MB. + * + * The maximum pcapng block size in OS X's private pcapng reading code + * is 1MB. (Yes, this means that a program using the standard pcap + * code to read pcapng files can handle bigger blocks than can programs + * using the private code, such as Apple's tcpdump, can handle.) + * + * The pcapng reading code here can handle NRBs of arbitrary size (less + * than 4GB, obviously), as they read each NRB record independently, + * rather than reading the entire block into memory. + * + * So, for now, we set the maximum NRB block size we write as 1 MB. + * + * (Yes, for the benefit of the fussy, "MB" is really "MiB".) + */ + +#define NRES_BLOCK_MAX_SIZE (1024*1024) + +static void +compute_nrb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval, void* user_data) +{ + pcapng_block_size_t* block_size = (pcapng_block_size_t*)user_data; + guint32 size = 0; + + switch(option_id) + { + case OPT_COMMENT: + case OPT_NS_DNSNAME: + size = pcapng_compute_option_string_size(optval->stringval); + break; + case OPT_NS_DNSIP4ADDR: + size = 4; + break; + case OPT_NS_DNSIP6ADDR: + size = 16; + break; + default: + /* Unknown options - size by datatype? */ + break; + } + + block_size->size += size; + /* Add bytes for option header if option should be written */ + if (size > 0) { + /* Add optional padding to 32 bits */ + if ((block_size->size & 0x03) != 0) + { + block_size->size += 4 - (block_size->size & 0x03); + } + block_size->size += 4; + } +} + +static void +put_nrb_option(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t* optval, void* user_data) +{ + guint8 **opt_ptrp = (guint8 **)user_data; + guint32 size = 0; + struct pcapng_option_header option_hdr; + guint32 pad; + + switch(option_id) + { + case OPT_COMMENT: + case OPT_NS_DNSNAME: + if (optval->stringval != NULL) { + /* String options don't consider pad bytes part of the length */ + size = (guint32)strlen(optval->stringval) & 0xffff; + option_hdr.type = (guint16)option_id; + option_hdr.value_length = (guint16)size; + memcpy(*opt_ptrp, &option_hdr, 4); + *opt_ptrp += 4; + + memcpy(*opt_ptrp, optval->stringval, size); + *opt_ptrp += size; + + if ((size % 4)) { + pad = 4 - (size % 4); + } else { + pad = 0; + } + + /* put padding (if any) */ + if (pad != 0) { + memset(*opt_ptrp, 0, pad); + *opt_ptrp += pad; + } + } + break; + case OPT_NS_DNSIP4ADDR: + option_hdr.type = (guint16)option_id; + option_hdr.value_length = 4; + memcpy(*opt_ptrp, &option_hdr, 4); + *opt_ptrp += 4; + + memcpy(*opt_ptrp, &optval->ipv4val, 4); + *opt_ptrp += 4; + break; + case OPT_NS_DNSIP6ADDR: + option_hdr.type = (guint16)option_id; + option_hdr.value_length = 16; + memcpy(*opt_ptrp, &option_hdr, 4); + *opt_ptrp += 4; + + memcpy(*opt_ptrp, &optval->ipv6val, 16); + *opt_ptrp += 16; + break; + default: + /* Unknown options - size by datatype? */ + break; + } +} + +static void +put_nrb_options(wtap_dumper *wdh, guint8 *opt_ptr) +{ + if (wdh->nrb_hdrs && wdh->nrb_hdrs->len > 0) { + wtap_block_t nrb_hdr = g_array_index(wdh->nrb_hdrs, wtap_block_t, 0); + struct option option_hdr; + + wtap_block_foreach_option(nrb_hdr, put_nrb_option, &opt_ptr); + + /* Put end of options */ + option_hdr.type = OPT_EOFOPT; + option_hdr.value_length = 0; + memcpy(opt_ptr, &option_hdr, 4); + } +} + static gboolean pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err) { pcapng_block_header_t bh; pcapng_name_resolution_block_t nrb; - guint8 *rec_data; - guint32 rec_off; + pcapng_block_size_t opts_size; + size_t max_rec_data_size; + guint8 *block_data; + guint32 block_off; size_t hostnamelen; guint16 namelen; guint32 tot_rec_len; @@ -3234,14 +3380,66 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err) int i; if ((!wdh->addrinfo_lists) || ((!wdh->addrinfo_lists->ipv4_addr_list)&&(!wdh->addrinfo_lists->ipv6_addr_list))) { + /* + * No name/address pairs to write. + * XXX - what if we have options? + */ + return TRUE; + } + + /* Calculate the space needed for options. */ + opts_size.size = 0; + if (wdh->nrb_hdrs && wdh->nrb_hdrs->len > 0) { + wtap_block_t nrb_hdr = g_array_index(wdh->nrb_hdrs, wtap_block_t, 0); + + wtap_block_foreach_option(nrb_hdr, compute_nrb_option_size, &opts_size); + if (opts_size.size > 0) { + /* End-of options tag */ + opts_size.size += 4; + } + } + + /* + * Make sure we can fit at least one maximum-sized record, plus + * an end-of-records record, plus the options, into a maximum-sized + * block. + * + * That requires that there be enough space for the block header + * (8 bytes), a maximum-sized record (2 bytes of record type, 2 + * bytes of record value length, 65535 bytes of record value, + * and 1 byte of padding), an end-of-records record (4 bytes), + * the options (opts_size.size bytes), and the block trailer (4 + * bytes). + */ + if (8 + 2 + 2 + 65535 + 1 + 4 + opts_size.size + 4 > NRES_BLOCK_MAX_SIZE) { + /* + * XXX - we can't even fit the options in the largest NRB size + * we're willing to write and still have room enough for a + * maximum-sized record. Just discard the information for now. + */ return TRUE; } - rec_off = 8; /* block type + block total length */ + /* + * Allocate a buffer for the largest block we'll write. + */ + block_data = (guint8 *)g_malloc(NRES_BLOCK_MAX_SIZE); + + /* + * Calculate the maximum amount of record data we'll be able to + * fit into such a block, after taking into account the block header + * (8 bytes), the end-of-records record (4 bytes), the options + * (opts_size.size bytes), and the block trailer (4 bytes). + */ + max_rec_data_size = NRES_BLOCK_MAX_SIZE - (8 + 4 + opts_size.size + 4); + + block_off = 8; /* block type + block total length */ bh.block_type = BLOCK_TYPE_NRB; - bh.block_total_length = rec_off + 8; /* end-of-record + block total length */ - rec_data = (guint8 *)g_malloc(NRES_REC_MAX_SIZE); + bh.block_total_length = 12; /* block header + block trailer */ + /* + * Write out the IPv4 resolved addresses, if any. + */ if (wdh->addrinfo_lists->ipv4_addr_list){ i = 0; ipv4_hash_list_entry = (hashipv4_t *)g_list_nth_data(wdh->addrinfo_lists->ipv4_addr_list, i); @@ -3259,50 +3457,60 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err) continue; } namelen = (guint16)(hostnamelen + 1); - nrb.record_len = 4 + namelen; + nrb.record_len = 4 + namelen; /* 4 bytes IPv4 address length */ /* 2 bytes record type, 2 bytes length field */ tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len); - if (rec_off + tot_rec_len > NRES_REC_MAX_SIZE){ + if (block_off + tot_rec_len > max_rec_data_size) { /* * This record would overflow our maximum size for Name * Resolution Blocks; write out all the records we created * before it, and start a new NRB. */ - /* First, copy the block header. */ - memcpy(rec_data, &bh, sizeof(bh)); + /* Append the end-of-records record */ + memset(block_data + block_off, 0, 4); + block_off += 4; + bh.block_total_length += 4; + + /* + * Put the options into the block. + * + * XXX - this puts the same options in all NRBs. + */ + put_nrb_options(wdh, block_data + block_off); + block_off += opts_size.size; + bh.block_total_length += opts_size.size; - /* End of record */ - memset(rec_data + rec_off, 0, 4); - rec_off += 4; + /* Copy the block header. */ + memcpy(block_data, &bh, sizeof(bh)); - memcpy(rec_data + rec_off, &bh.block_total_length, sizeof(bh.block_total_length)); + /* Copy the block trailer. */ + memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length)); - pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, rec_off %u", bh.block_total_length, rec_off); + pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, block_off %u", bh.block_total_length, block_off); - if (!wtap_dump_file_write(wdh, rec_data, bh.block_total_length, err)) { - g_free(rec_data); + if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) { + g_free(block_data); return FALSE; } wdh->bytes_dumped += bh.block_total_length; /*Start a new NRB */ - rec_off = 8; /* block type + block total length */ + block_off = 8; /* block type + block total length */ bh.block_type = BLOCK_TYPE_NRB; - bh.block_total_length = rec_off + 8; /* end-of-record + block total length */ - + bh.block_total_length = 12; /* block header + block trailer */ } bh.block_total_length += tot_rec_len; - memcpy(rec_data + rec_off, &nrb, sizeof(nrb)); - rec_off += 4; - memcpy(rec_data + rec_off, &(ipv4_hash_list_entry->addr), 4); - rec_off += 4; - memcpy(rec_data + rec_off, ipv4_hash_list_entry->name, namelen); - rec_off += namelen; - memset(rec_data + rec_off, 0, PADDING4(namelen)); - rec_off += PADDING4(namelen); + memcpy(block_data + block_off, &nrb, sizeof(nrb)); + block_off += 4; + memcpy(block_data + block_off, &(ipv4_hash_list_entry->addr), 4); + block_off += 4; + memcpy(block_data + block_off, ipv4_hash_list_entry->name, namelen); + block_off += namelen; + memset(block_data + block_off, 0, PADDING4(namelen)); + block_off += PADDING4(namelen); pcapng_debug("NRB: added IPv4 record for %s", ipv4_hash_list_entry->name); i++; @@ -3333,46 +3541,56 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err) /* 2 bytes record type, 2 bytes length field */ tot_rec_len = 4 + nrb.record_len + PADDING4(nrb.record_len); - if (rec_off + tot_rec_len > NRES_REC_MAX_SIZE){ + if (block_off + tot_rec_len > max_rec_data_size) { /* * This record would overflow our maximum size for Name * Resolution Blocks; write out all the records we created * before it, and start a new NRB. */ - /* First, copy the block header. */ - memcpy(rec_data, &bh, sizeof(bh)); + /* Append the end-of-records record */ + memset(block_data + block_off, 0, 4); + block_off += 4; + bh.block_total_length += 4; - /* End of record */ - memset(rec_data + rec_off, 0, 4); - rec_off += 4; + /* + * Put the options into the block. + * + * XXX - this puts the same options in all NRBs. + */ + put_nrb_options(wdh, block_data + block_off); + block_off += opts_size.size; + bh.block_total_length += opts_size.size; + + /* Copy the block header. */ + memcpy(block_data, &bh, sizeof(bh)); - memcpy(rec_data + rec_off, &bh.block_total_length, sizeof(bh.block_total_length)); + /* Copy the block trailer. */ + memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length)); - pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, rec_off %u", bh.block_total_length, rec_off); + pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, block_off %u", bh.block_total_length, block_off); - if (!wtap_dump_file_write(wdh, rec_data, bh.block_total_length, err)) { - g_free(rec_data); + if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) { + g_free(block_data); return FALSE; } wdh->bytes_dumped += bh.block_total_length; /*Start a new NRB */ - rec_off = 8; /* block type + block total length */ + block_off = 8; /* block type + block total length */ bh.block_type = BLOCK_TYPE_NRB; - bh.block_total_length = rec_off + 8; /* end-of-record + block total length */ - + bh.block_total_length = 12; /* block header + block trailer */ } bh.block_total_length += tot_rec_len; - memcpy(rec_data + rec_off, &nrb, sizeof(nrb)); - rec_off += 4; - memcpy(rec_data + rec_off, &(ipv6_hash_list_entry->addr), 16); - rec_off += 16; - memcpy(rec_data + rec_off, ipv6_hash_list_entry->name, namelen); - rec_off += namelen; - memset(rec_data + rec_off, 0, PADDING4(namelen)); - rec_off += PADDING4(namelen); + memcpy(block_data + block_off, &nrb, sizeof(nrb)); + block_off += 4; + memcpy(block_data + block_off, &(ipv6_hash_list_entry->addr), 16); + block_off += 16; + memcpy(block_data + block_off, ipv6_hash_list_entry->name, namelen); + block_off += namelen; + memset(block_data + block_off, 0, PADDING4(namelen)); + block_off += PADDING4(namelen); pcapng_debug("NRB: added IPv6 record for %s", ipv6_hash_list_entry->name); i++; @@ -3382,139 +3600,59 @@ pcapng_write_name_resolution_block(wtap_dumper *wdh, int *err) wdh->addrinfo_lists->ipv6_addr_list = NULL; } - /* add options, if any */ - if (wdh->nrb_hdrs && wdh->nrb_hdrs->len > 0) { - gboolean have_options = FALSE; - guint32 options_total_length = 0; - struct option option_hdr; - guint32 comment_len = 0, comment_pad_len = 0; - wtap_optionblock_t nrb_hdr = g_array_index(wdh->nrb_hdrs, wtap_optionblock_t, 0); - guint32 prev_rec_off = rec_off; - char* opt_comment; - - /* get lengths first to make sure we can fit this into the block */ - wtap_optionblock_get_option_string(nrb_hdr, OPT_COMMENT, &opt_comment); - if (opt_comment) { - have_options = TRUE; - comment_len = (guint32)strlen(opt_comment) & 0xffff; - if ((comment_len % 4)) { - comment_pad_len = 4 - (comment_len % 4); - } else { - comment_pad_len = 0; - } - options_total_length = options_total_length + comment_len + comment_pad_len + 4 /* comment options tag */ ; - } - - if (have_options) { - /* End-of options tag */ - options_total_length += 4; - - if (rec_off + options_total_length > NRES_REC_MAX_SIZE) { - /* - * This record would overflow our maximum size for Name - * Resolution Blocks; write out all the records we created - * before it, and start a new NRB. - */ - - /* First, copy the block header. */ - memcpy(rec_data, &bh, sizeof(bh)); - - /* End of record */ - memset(rec_data + rec_off, 0, 4); - rec_off += 4; - - memcpy(rec_data + rec_off, &bh.block_total_length, sizeof(bh.block_total_length)); - - pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, rec_off %u", bh.block_total_length, rec_off); - - if (!wtap_dump_file_write(wdh, rec_data, bh.block_total_length, err)) { - g_free(rec_data); - return FALSE; - } - wdh->bytes_dumped += bh.block_total_length; - - /*Start a new NRB */ - prev_rec_off = rec_off = 8; /* block type + block total length */ - bh.block_type = BLOCK_TYPE_NRB; - bh.block_total_length = rec_off + 8; /* end-of-record + block total length */ - } - - bh.block_total_length += options_total_length; - - if (comment_len > 0) { - option_hdr.type = OPT_COMMENT; - option_hdr.value_length = comment_len; - - memcpy(rec_data + rec_off, &option_hdr, sizeof(option_hdr)); - rec_off += (guint32)sizeof(option_hdr); - - /* Write the comments string */ - 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; - - pcapng_debug("pcapng_write_name_resolution_block: Wrote Options comments: comment_len %u, comment_pad_len %u", - comment_len, - comment_pad_len); - } - - /* Write end of options */ - memset(rec_data + rec_off, 0, 4); - rec_off += 4; - - /* sanity check */ - g_assert(options_total_length == rec_off - prev_rec_off); - } - } + /* Append the end-of-records record */ + memset(block_data + block_off, 0, 4); + block_off += 4; + bh.block_total_length += 4; - /* We know the total length now; copy the block header. */ - memcpy(rec_data, &bh, sizeof(bh)); + /* + * Put the options into the block. + */ + put_nrb_options(wdh, block_data + block_off); + block_off += opts_size.size; + bh.block_total_length += opts_size.size; - /* End of record */ - memset(rec_data + rec_off, 0, 4); - rec_off += 4; + /* Copy the block header. */ + memcpy(block_data, &bh, sizeof(bh)); - memcpy(rec_data + rec_off, &bh.block_total_length, sizeof(bh.block_total_length)); + /* Copy the block trailer. */ + memcpy(block_data + block_off, &bh.block_total_length, sizeof(bh.block_total_length)); - pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, rec_off %u", bh.block_total_length, rec_off); + pcapng_debug("pcapng_write_name_resolution_block: Write bh.block_total_length bytes %d, block_off %u", bh.block_total_length, block_off); - if (!wtap_dump_file_write(wdh, rec_data, bh.block_total_length, err)) { - g_free(rec_data); + if (!wtap_dump_file_write(wdh, block_data, bh.block_total_length, err)) { + g_free(block_data); return FALSE; } - - g_free(rec_data); wdh->bytes_dumped += bh.block_total_length; + + g_free(block_data); + return TRUE; } -static void compute_isb_option_size(wtap_optionblock_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_option_type* option, void* user_data) +static void compute_isb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data) { - pcapng_optionblock_size_t* block_size = (pcapng_optionblock_size_t*)user_data; + pcapng_block_size_t* block_size = (pcapng_block_size_t*)user_data; guint32 size = 0; switch(option_id) { case OPT_COMMENT: - if (option != NULL) { - size = pcapng_compute_option_string_size(option->stringval); + if (optval->stringval != NULL) { + size = pcapng_compute_option_string_size(optval->stringval); } break; case OPT_ISB_STARTTIME: case OPT_ISB_ENDTIME: - if ((option != NULL) && (option->uint64val != 0)) { - size = 8; - } + size = 8; break; case OPT_ISB_IFRECV: case OPT_ISB_IFDROP: case OPT_ISB_FILTERACCEPT: case OPT_ISB_OSDROP: case OPT_ISB_USRDELIV: - if ((option != NULL) && (option->uint64val != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF))) { - size = 8; - } + size = 8; break; default: /* Unknown options - size by datatype? */ @@ -3533,7 +3671,7 @@ static void compute_isb_option_size(wtap_optionblock_t block _U_, guint option_i } } -static void write_wtap_isb_block(wtap_optionblock_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_option_type* option, void* user_data) +static void write_wtap_isb_block(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data) { pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data; struct pcapng_option_header option_hdr; @@ -3545,8 +3683,8 @@ static void write_wtap_isb_block(wtap_optionblock_t block _U_, guint option_id, switch(option_id) { case OPT_COMMENT: - if ((option != NULL) && (option->stringval != NULL)) { - if (!pcapng_write_option_string(write_block->wdh, option_id, option->stringval, write_block->err)) { + if (optval->stringval != NULL) { + if (!pcapng_write_option_string(write_block->wdh, option_id, optval->stringval, write_block->err)) { write_block->success = FALSE; return; } @@ -3554,7 +3692,7 @@ static void write_wtap_isb_block(wtap_optionblock_t block _U_, guint option_id, break; case OPT_ISB_STARTTIME: case OPT_ISB_ENDTIME: - if ((option != NULL) && (option->uint64val != 0)) { + { guint32 high, low; option_hdr.type = option_id; @@ -3565,8 +3703,8 @@ static void write_wtap_isb_block(wtap_optionblock_t block _U_, guint option_id, } write_block->wdh->bytes_dumped += 4; - high = (guint32)(option->uint64val >> 32); - low = (guint32)(option->uint64val >> 0); + high = (guint32)(optval->uint64val >> 32); + low = (guint32)(optval->uint64val >> 0); if (!wtap_dump_file_write(write_block->wdh, &high, sizeof(guint32), write_block->err)) { write_block->success = FALSE; return; @@ -3584,7 +3722,7 @@ static void write_wtap_isb_block(wtap_optionblock_t block _U_, guint option_id, case OPT_ISB_FILTERACCEPT: case OPT_ISB_OSDROP: case OPT_ISB_USRDELIV: - if ((option != NULL) && (option->uint64val != G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF))) { + { option_hdr.type = option_id; option_hdr.value_length = 8; if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) { @@ -3593,7 +3731,7 @@ static void write_wtap_isb_block(wtap_optionblock_t block _U_, guint option_id, } write_block->wdh->bytes_dumped += 4; - if (!wtap_dump_file_write(write_block->wdh, &option->uint64val, sizeof(guint64), write_block->err)) { + if (!wtap_dump_file_write(write_block->wdh, &optval->uint64val, sizeof(guint64), write_block->err)) { write_block->success = FALSE; return; } @@ -3607,20 +3745,20 @@ static void write_wtap_isb_block(wtap_optionblock_t block _U_, guint option_id, } static gboolean -pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtap_optionblock_t if_stats, int *err) +pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtap_block_t if_stats, int *err) { pcapng_block_header_t bh; pcapng_interface_statistics_block_t isb; - pcapng_optionblock_size_t block_size; + pcapng_block_size_t block_size; pcapng_write_block_t block_data; struct pcapng_option_header option_hdr; - wtapng_if_stats_mandatory_t* mand_data = (wtapng_if_stats_mandatory_t*)wtap_optionblock_get_mandatory_data(if_stats); + wtapng_if_stats_mandatory_t* mand_data = (wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats); pcapng_debug("pcapng_write_interface_statistics_block"); /* Compute block size */ block_size.size = 0; - wtap_optionblock_foreach_option(if_stats, compute_isb_option_size, &block_size); + wtap_block_foreach_option(if_stats, compute_isb_option_size, &block_size); if (block_size.size > 0) { /* End-of-options tag */ @@ -3650,7 +3788,7 @@ pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtap_optionblock_t if_ block_data.wdh = wdh; block_data.err = err; block_data.success = TRUE; - wtap_optionblock_foreach_option(if_stats, write_wtap_isb_block, &block_data); + wtap_block_foreach_option(if_stats, write_wtap_isb_block, &block_data); if (!block_data.success) return FALSE; @@ -3671,9 +3809,9 @@ pcapng_write_interface_statistics_block(wtap_dumper *wdh, wtap_optionblock_t if_ return TRUE; } -static void compute_idb_option_size(wtap_optionblock_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_option_type* option, void* user_data) +static void compute_idb_option_size(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data) { - pcapng_optionblock_size_t* block_size = (pcapng_optionblock_size_t*)user_data; + pcapng_block_size_t* block_size = (pcapng_block_size_t*)user_data; guint32 size = 0; switch(option_id) @@ -3682,23 +3820,19 @@ static void compute_idb_option_size(wtap_optionblock_t block _U_, guint option_i case OPT_IDB_NAME: case OPT_IDB_DESCR: case OPT_IDB_OS: - if (option != NULL) { - size = pcapng_compute_option_string_size(option->stringval); + if (optval != NULL) { + size = pcapng_compute_option_string_size(optval->stringval); } break; case OPT_IDB_SPEED: - if ((option != NULL) && (option->uint64val != 0)) { - size = 8; - } + size = 8; break; case OPT_IDB_TSRESOL: - if ((option != NULL) && (option->uint8val != 0)) { - size = 1; - } + size = 1; break; case OPT_IDB_FILTER: - if (option != NULL) { - wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)option->customval.data; + { + wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)optval->customval.data; guint32 pad; if ((filter != NULL) && (filter->if_filter_str != NULL)) { size = (guint32)(strlen(filter->if_filter_str) + 1) & 0xffff; @@ -3732,7 +3866,7 @@ static void compute_idb_option_size(wtap_optionblock_t block _U_, guint option_i } } -static void write_wtap_idb_block(wtap_optionblock_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_option_type* option, void* user_data) +static void write_wtap_idb_block(wtap_block_t block _U_, guint option_id, wtap_opttype_e option_type _U_, wtap_optval_t *optval, void* user_data) { pcapng_write_block_t* write_block = (pcapng_write_block_t*)user_data; struct pcapng_option_header option_hdr; @@ -3744,56 +3878,52 @@ static void write_wtap_idb_block(wtap_optionblock_t block _U_, guint option_id, case OPT_IDB_NAME: case OPT_IDB_DESCR: case OPT_IDB_OS: - if ((option != NULL) && (option->stringval != NULL)) { - if (!pcapng_write_option_string(write_block->wdh, option_id, option->stringval, write_block->err)) { + if (optval->stringval != NULL) { + if (!pcapng_write_option_string(write_block->wdh, option_id, optval->stringval, write_block->err)) { write_block->success = FALSE; return; } } break; case OPT_IDB_SPEED: - if ((option != NULL) && (option->uint64val != 0)) { - option_hdr.type = option_id; - option_hdr.value_length = 8; - if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) { - write_block->success = FALSE; - return; - } - write_block->wdh->bytes_dumped += 4; + option_hdr.type = option_id; + option_hdr.value_length = 8; + if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) { + write_block->success = FALSE; + return; + } + write_block->wdh->bytes_dumped += 4; - if (!wtap_dump_file_write(write_block->wdh, &option->uint64val, sizeof(guint64), write_block->err)) { - write_block->success = FALSE; - return; - } - write_block->wdh->bytes_dumped += 8; + if (!wtap_dump_file_write(write_block->wdh, &optval->uint64val, sizeof(guint64), write_block->err)) { + write_block->success = FALSE; + return; } + write_block->wdh->bytes_dumped += 8; break; case OPT_IDB_TSRESOL: - if ((option != NULL) && (option->uint8val != 0)) { - option_hdr.type = option_id; - option_hdr.value_length = 1; - if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) { - write_block->success = FALSE; - return; - } - write_block->wdh->bytes_dumped += 4; + option_hdr.type = option_id; + option_hdr.value_length = 1; + if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) { + write_block->success = FALSE; + return; + } + write_block->wdh->bytes_dumped += 4; - if (!wtap_dump_file_write(write_block->wdh, &option->uint8val, 1, write_block->err)) { - write_block->success = FALSE; - return; - } - write_block->wdh->bytes_dumped += 1; + if (!wtap_dump_file_write(write_block->wdh, &optval->uint8val, 1, write_block->err)) { + write_block->success = FALSE; + return; + } + write_block->wdh->bytes_dumped += 1; - if (!wtap_dump_file_write(write_block->wdh, &zero_pad, 3, write_block->err)) { - write_block->success = FALSE; - return; - } - write_block->wdh->bytes_dumped += 3; + if (!wtap_dump_file_write(write_block->wdh, &zero_pad, 3, write_block->err)) { + write_block->success = FALSE; + return; } + write_block->wdh->bytes_dumped += 3; break; case OPT_IDB_FILTER: - if (option != NULL) { - wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)option->customval.data; + { + wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)optval->customval.data; guint32 size, pad; if ((filter != NULL) && (filter->if_filter_str != NULL)) { size = (guint32)(strlen(filter->if_filter_str) + 1) & 0xffff; @@ -3847,14 +3977,14 @@ static void write_wtap_idb_block(wtap_optionblock_t block _U_, guint option_id, } static gboolean -pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_optionblock_t int_data, int *err) +pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_block_t int_data, int *err) { pcapng_block_header_t bh; pcapng_interface_description_block_t idb; - pcapng_optionblock_size_t block_size; + pcapng_block_size_t block_size; pcapng_write_block_t block_data; struct pcapng_option_header option_hdr; - wtapng_if_descr_mandatory_t* mand_data = (wtapng_if_descr_mandatory_t*)wtap_optionblock_get_mandatory_data(int_data); + wtapng_if_descr_mandatory_t* mand_data = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data); pcapng_debug("pcapng_write_if_descr_block: encap = %d (%s), snaplen = %d", mand_data->link_type, @@ -3868,7 +3998,7 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_optionblock_t int_data, int * /* Compute block size */ block_size.size = 0; - wtap_optionblock_foreach_option(int_data, compute_idb_option_size, &block_size); + wtap_block_foreach_option(int_data, compute_idb_option_size, &block_size); if (block_size.size > 0) { /* End-of-options tag */ @@ -3898,7 +4028,7 @@ pcapng_write_if_descr_block(wtap_dumper *wdh, wtap_optionblock_t int_data, int * block_data.wdh = wdh; block_data.err = err; block_data.success = TRUE; - wtap_optionblock_foreach_option(int_data, write_wtap_idb_block, &block_data); + wtap_block_foreach_option(int_data, write_wtap_idb_block, &block_data); if (!block_data.success) return FALSE; @@ -3990,17 +4120,17 @@ static gboolean pcapng_dump_finish(wtap_dumper *wdh, int *err) for (i = 0; i < wdh->interface_data->len; i++) { /* Get the interface description */ - wtap_optionblock_t int_data; + wtap_block_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, wtap_block_t, i); + int_data_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(int_data); for (j = 0; j < int_data_mand->num_stat_entries; j++) { - wtap_optionblock_t if_stats; + wtap_block_t if_stats; - 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_stats = g_array_index(int_data_mand->interface_statistics, wtap_block_t, j); + pcapng_debug("pcapng_dump_finish: write ISB for interface %u", ((wtapng_if_stats_mandatory_t*)wtap_block_get_mandatory_data(if_stats))->interface_id); if (!pcapng_write_interface_statistics_block(wdh, if_stats, err)) { return FALSE; } @@ -4043,9 +4173,9 @@ pcapng_dump_open(wtap_dumper *wdh, int *err) for (i = 0; i < wdh->interface_data->len; i++) { /* Get the interface description */ - wtap_optionblock_t idb; + wtap_block_t idb; - idb = g_array_index(wdh->interface_data, wtap_optionblock_t, i); + idb = g_array_index(wdh->interface_data, wtap_block_t, i); if (!pcapng_write_if_descr_block(wdh, idb, err)) { return FALSE; diff --git a/wiretap/wtap.c b/wiretap/wtap.c index 0d1acc3657..01dfee42d3 100644 --- a/wiretap/wtap.c +++ b/wiretap/wtap.c @@ -161,84 +161,45 @@ wtap_file_tsprec(wtap *wth) return wth->file_tsprec; } -const gchar * -wtap_file_get_shb_comment(wtap *wth) -{ - char* opt_comment; - if ((wth == NULL) || (wth->shb_hdrs == NULL) || (wth->shb_hdrs->len == 0)) - return NULL; - - wtap_optionblock_get_option_string(g_array_index(wth->shb_hdrs, wtap_optionblock_t, 0), OPT_COMMENT, &opt_comment); - return opt_comment; -} - -wtap_optionblock_t +wtap_block_t wtap_file_get_shb(wtap *wth) { if ((wth == NULL) || (wth->shb_hdrs == NULL) || (wth->shb_hdrs->len == 0)) return NULL; - return g_array_index(wth->shb_hdrs, wtap_optionblock_t, 0); + return g_array_index(wth->shb_hdrs, wtap_block_t, 0); } GArray* wtap_file_get_shb_for_new_file(wtap *wth) { guint shb_count; - wtap_optionblock_t shb_hdr_src, shb_hdr_dest; + wtap_block_t shb_hdr_src, shb_hdr_dest; GArray* shb_hdrs; if ((wth == NULL) || (wth->shb_hdrs == NULL) || (wth->shb_hdrs->len == 0)) return NULL; - shb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t)); + shb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); for (shb_count = 0; shb_count < wth->shb_hdrs->len; shb_count++) { - shb_hdr_src = g_array_index(wth->shb_hdrs, wtap_optionblock_t, shb_count); - shb_hdr_dest = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_SECTION); - wtap_optionblock_copy_options(shb_hdr_dest, shb_hdr_src); + shb_hdr_src = g_array_index(wth->shb_hdrs, wtap_block_t, shb_count); + shb_hdr_dest = wtap_block_create(WTAP_BLOCK_NG_SECTION); + wtap_block_copy(shb_hdr_dest, shb_hdr_src); g_array_append_val(shb_hdrs, shb_hdr_dest); } return shb_hdrs; } -const gchar* -wtap_get_nrb_comment(wtap *wth) -{ - char* opt_comment; - g_assert(wth); - - if ((wth == NULL) || (wth->nrb_hdrs == NULL) || (wth->nrb_hdrs->len == 0)) - return NULL; - - wtap_optionblock_get_option_string(g_array_index(wth->nrb_hdrs, wtap_optionblock_t, 0), OPT_COMMENT, &opt_comment); - return opt_comment; -} - -void -wtap_write_nrb_comment(wtap *wth, gchar *comment) -{ - wtap_optionblock_t nrb; - g_assert(wth); - - if (wth == NULL) - return; - - if (wth->nrb_hdrs == NULL) { - wth->nrb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t)); - nrb = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_NRB); - g_array_append_val(wth->nrb_hdrs, nrb); - } - - wtap_optionblock_set_option_string(g_array_index(wth->nrb_hdrs, wtap_optionblock_t, 0), OPT_COMMENT, comment, (gsize)(comment ? strlen(comment) : 0)); -} - +/* + * XXX - replace with APIs that let us handle multiple comments. + */ void wtap_write_shb_comment(wtap *wth, gchar *comment) { if ((wth != NULL) && (wth->shb_hdrs != NULL) && (wth->shb_hdrs->len > 0)) { - wtap_optionblock_set_option_string(g_array_index(wth->shb_hdrs, wtap_optionblock_t, 0), OPT_COMMENT, comment, (gsize)(comment ? strlen(comment) : 0)); + wtap_block_set_nth_string_option_value(g_array_index(wth->shb_hdrs, wtap_block_t, 0), OPT_COMMENT, 0, comment, (gsize)(comment ? strlen(comment) : 0)); } } @@ -261,12 +222,12 @@ wtap_free_idb_info(wtapng_iface_descriptions_t *idb_info) if (idb_info == NULL) return; - wtap_optionblock_array_free(idb_info->interface_data); + wtap_block_array_free(idb_info->interface_data); g_free(idb_info); } gchar * -wtap_get_debug_if_descr(const wtap_optionblock_t if_descr, +wtap_get_debug_if_descr(const wtap_block_t if_descr, const int indent, const char* line_end) { @@ -280,18 +241,20 @@ wtap_get_debug_if_descr(const wtap_optionblock_t if_descr, 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, ' ', - tmp_content ? tmp_content : "UNKNOWN", - line_end); + if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(if_descr); + if (wtap_block_get_string_option_value(if_descr, OPT_IDB_NAME, &tmp_content) == WTAP_OPTTYPE_SUCCESS) { + g_string_printf(info, + "%*cName = %s%s", indent, ' ', + 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, ' ', - tmp_content ? tmp_content : "NONE", - line_end); + if (wtap_block_get_string_option_value(if_descr, OPT_IDB_DESCR, &tmp_content) == WTAP_OPTTYPE_SUCCESS) { + g_string_append_printf(info, + "%*cDescription = %s%s", indent, ' ', + tmp_content ? tmp_content : "NONE", + line_end); + } g_string_append_printf(info, "%*cEncapsulation = %s (%d/%u - %s)%s", indent, ' ', @@ -301,22 +264,24 @@ wtap_get_debug_if_descr(const wtap_optionblock_t if_descr, 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, ' ', - tmp64, - line_end); + if (wtap_block_get_uint64_option_value(if_descr, OPT_IDB_SPEED, &tmp64) == WTAP_OPTTYPE_SUCCESS) { + g_string_append_printf(info, + "%*cSpeed = %" G_GINT64_MODIFIER "u%s", indent, ' ', + tmp64, + line_end); + } g_string_append_printf(info, "%*cCapture length = %u%s", indent, ' ', 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, ' ', - itmp8, - line_end); + if (wtap_block_get_uint8_option_value(if_descr, OPT_IDB_FCSLEN, &itmp8) == WTAP_OPTTYPE_SUCCESS) { + g_string_append_printf(info, + "%*cFCS length = %d%s", indent, ' ', + itmp8, + line_end); + } g_string_append_printf(info, "%*cTime precision = %s (%d)%s", indent, ' ', @@ -329,34 +294,41 @@ wtap_get_debug_if_descr(const wtap_optionblock_t if_descr, 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, ' ', - tmp8, - line_end); + if (wtap_block_get_uint8_option_value(if_descr, OPT_IDB_TSRESOL, &tmp8) == WTAP_OPTTYPE_SUCCESS) { + g_string_append_printf(info, + "%*cTime resolution = 0x%.2x%s", indent, ' ', + 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_filter->if_filter_str ? if_filter->if_filter_str : "NONE", - line_end); + if (wtap_block_get_custom_option_value(if_descr, OPT_IDB_FILTER, (void**)&if_filter) == WTAP_OPTTYPE_SUCCESS) { + g_string_append_printf(info, + "%*cFilter string = %s%s", indent, ' ', + 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, ' ', - tmp_content ? tmp_content : "UNKNOWN", - line_end); + g_string_append_printf(info, + "%*cBPF filter length = %u%s", indent, ' ', + if_filter->bpf_filter_len, + line_end); + } - wtap_optionblock_get_option_string(if_descr, OPT_COMMENT, &tmp_content); - g_string_append_printf(info, - "%*cComment = %s%s", indent, ' ', - tmp_content ? tmp_content : "NONE", - line_end); + if (wtap_block_get_string_option_value(if_descr, OPT_IDB_OS, &tmp_content) == WTAP_OPTTYPE_SUCCESS) { + g_string_append_printf(info, + "%*cOperating system = %s%s", indent, ' ', + tmp_content ? tmp_content : "UNKNOWN", + line_end); + } - g_string_append_printf(info, - "%*cBPF filter length = %u%s", indent, ' ', - if_filter->bpf_filter_len, - line_end); + /* + * XXX - support multiple comments. + */ + if (wtap_block_get_nth_string_option_value(if_descr, OPT_COMMENT, 0, &tmp_content) == WTAP_OPTTYPE_SUCCESS) { + g_string_append_printf(info, + "%*cComment = %s%s", indent, ' ', + tmp_content ? tmp_content : "NONE", + line_end); + } g_string_append_printf(info, "%*cNumber of stat entries = %u%s", indent, ' ', @@ -366,22 +338,31 @@ wtap_get_debug_if_descr(const wtap_optionblock_t if_descr, return g_string_free(info, FALSE); } +wtap_block_t +wtap_file_get_nrb(wtap *wth) +{ + if ((wth == NULL) || (wth->nrb_hdrs == NULL) || (wth->nrb_hdrs->len == 0)) + return NULL; + + return g_array_index(wth->nrb_hdrs, wtap_block_t, 0); +} + GArray* wtap_file_get_nrb_for_new_file(wtap *wth) { guint nrb_count; - wtap_optionblock_t nrb_hdr_src, nrb_hdr_dest; + wtap_block_t nrb_hdr_src, nrb_hdr_dest; GArray* nrb_hdrs; if ((wth == NULL || wth->nrb_hdrs == NULL) || (wth->nrb_hdrs->len == 0)) return NULL; - nrb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t)); + nrb_hdrs = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); for (nrb_count = 0; nrb_count < wth->nrb_hdrs->len; nrb_count++) { - nrb_hdr_src = g_array_index(wth->nrb_hdrs, wtap_optionblock_t, nrb_count); - nrb_hdr_dest = wtap_optionblock_create(WTAP_OPTION_BLOCK_NG_NRB); - wtap_optionblock_copy_options(nrb_hdr_dest, nrb_hdr_src); + nrb_hdr_src = g_array_index(wth->nrb_hdrs, wtap_block_t, nrb_count); + nrb_hdr_dest = wtap_block_create(WTAP_BLOCK_NG_NRB); + wtap_block_copy(nrb_hdr_dest, nrb_hdr_src); g_array_append_val(nrb_hdrs, nrb_hdr_dest); } @@ -1212,9 +1193,9 @@ wtap_close(wtap *wth) g_ptr_array_free(wth->fast_seek, TRUE); } - wtap_optionblock_array_free(wth->shb_hdrs); - wtap_optionblock_array_free(wth->nrb_hdrs); - wtap_optionblock_array_free(wth->interface_data); + wtap_block_array_free(wth->shb_hdrs); + wtap_block_array_free(wth->nrb_hdrs); + wtap_block_array_free(wth->interface_data); g_free(wth); } diff --git a/wiretap/wtap.h b/wiretap/wtap.h index b89701f24c..566ec50a75 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -1268,7 +1268,7 @@ typedef struct wtapng_section_mandatory_s { } wtapng_mandatory_section_t; /** struct holding the information to build IDB:s - * the interface_data array holds an array of wtap_optionblock_t + * the interface_data array holds an array of wtap_block_t * represending IDB of one per interface. */ typedef struct wtapng_iface_descriptions_s { @@ -1592,13 +1592,15 @@ int wtap_file_tsprec(wtap *wth); * * @param wth The wiretap session. * @return The existing section header, which must NOT be g_free'd. + * + * XXX - need to be updated to handle multiple SHBs. */ WS_DLL_PUBLIC -wtap_optionblock_t wtap_file_get_shb(wtap *wth); +wtap_block_t wtap_file_get_shb(wtap *wth); /** * @brief Gets new section header block for new file, based on existing info. - * @details Creates a new wtap_optionblock_t section header block and only + * @details Creates a new wtap_block_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 @@ -1612,16 +1614,6 @@ wtap_optionblock_t wtap_file_get_shb(wtap *wth); WS_DLL_PUBLIC GArray* wtap_file_get_shb_for_new_file(wtap *wth); -/** - * @brief Gets the section header comment string. - * @details This gets the pointer, without duplicating the string. - * - * @param wth The wtap session. - * @return The comment string. - */ -WS_DLL_PUBLIC -const gchar* wtap_file_get_shb_comment(wtap *wth); - /** * @brief Sets or replaces the section header comment. * @details The passed-in comment string is set to be the comment @@ -1675,46 +1667,37 @@ 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 wtap_optionblock_t if_descr, +gchar *wtap_get_debug_if_descr(const wtap_block_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 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. + * @brief Gets existing name resolution block, not for new file. + * @details Returns the pointer to the existing NRB, without creating a + * new one. This should only be used for accessing info, not + * for creating a new file based on existing NRB info. Use + * wtap_file_get_nrb_for_new_file() for that. * * @param wth The wiretap session. - * @return The new name resolution info, which must be freed. - */ -WS_DLL_PUBLIC -GArray* wtap_file_get_nrb_for_new_file(wtap *wth); - -/** - * @brief Gets the name resolution comment, if any. - * @details This retrieves the name resolution comment string pointer, - * possibly NULL. + * @return The existing section header, which must NOT be g_free'd. * - * @param wth The wiretap session. - * @return The comment string. + * XXX - need to be updated to handle multiple NRBs. */ WS_DLL_PUBLIC -const gchar* wtap_get_nrb_comment(wtap *wth); +wtap_block_t wtap_file_get_nrb(wtap *wth); /** - * @brief Sets or replaces the name resolution comment. - * @details The passed-in comment string is set to be the comment - * for the name resolution block. The passed-in string's - * ownership will be owned by the block, so it should be - * duplicated before passing into this function. + * @brief Gets new name resolution info for new file, based on existing info. + * @details Creates a new wtap_block_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. - * @param comment The comment string. + * @return The new name resolution info, which must be freed. */ WS_DLL_PUBLIC -void wtap_write_nrb_comment(wtap *wth, gchar *comment); +GArray* wtap_file_get_nrb_for_new_file(wtap *wth); /*** close the file descriptors for the current file ***/ WS_DLL_PUBLIC diff --git a/wiretap/wtap_opttypes.c b/wiretap/wtap_opttypes.c index f42aa26250..445621e274 100644 --- a/wiretap/wtap_opttypes.c +++ b/wiretap/wtap_opttypes.c @@ -35,62 +35,87 @@ #define wtap_debug(...) #endif -typedef struct wtap_opt_register -{ +/* + * Structure describing a type of block. + */ +typedef struct { + wtap_block_type_t block_type; /**< internal type code for block */ const char *name; /**< name of block */ const char *description; /**< human-readable description of block */ wtap_block_create_func create; wtap_mand_free_func free_mand; wtap_mand_copy_func copy_mand; -} wtap_opt_register_t; + GArray *options; /**< array of known options */ +} wtap_blocktype_t; -typedef struct wtap_optblock_internal { - const char *name; /**< name of option */ - const char *description; /**< human-readable description of option */ - guint number; /**< Option index */ - wtap_opttype_e type; /**< type of that option */ -} wtap_optblock_internal_t; +typedef void (*wtap_opttype_free_custom_func)(void* data); -typedef struct wtap_optblock_value { - wtap_optblock_internal_t* info; - wtap_option_type option; /**< pointer to variable storing the value */ - wtap_option_type default_val; /**< the default value of the option */ -} wtap_optblock_value_t; - -struct wtap_optionblock +/* + * Structure describing a type of option. + */ +typedef struct { + const char *name; /**< name of option */ + const char *description; /**< human-readable description of option */ + wtap_opttype_e data_type; /**< data type of that option */ + guint flags; /**< flags for the option */ + wtap_opttype_free_custom_func free_func; /**< function to free custom option data */ +} wtap_opttype_t; + +/* Flags */ +#define WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED 0x00000001 /* multiple instances allowed */ + +struct wtap_block { - wtap_opt_register_t* info; + wtap_blocktype_t* info; void* mandatory_data; - GArray* option_infos; /* Only want to keep 1 copy of "static" option information */ - GArray* option_values; + GArray* options; }; -#define MAX_WTAP_OPTION_BLOCK_CUSTOM 10 -#define MAX_WTAP_OPTION_BLOCK_TYPE_VALUE (WTAP_OPTION_BLOCK_END_OF_LIST+MAX_WTAP_OPTION_BLOCK_CUSTOM) +#define MAX_WTAP_BLOCK_CUSTOM 10 +#define MAX_WTAP_BLOCK_TYPE_VALUE (WTAP_BLOCK_END_OF_LIST+MAX_WTAP_BLOCK_CUSTOM) -/* Keep track of wtap_opt_register_t's via their id number */ -static wtap_opt_register_t* block_list[MAX_WTAP_OPTION_BLOCK_TYPE_VALUE]; +/* Keep track of wtap_blocktype_t's via their id number */ +static wtap_blocktype_t* blocktype_list[MAX_WTAP_BLOCK_TYPE_VALUE]; static guint num_custom_blocks; -static wtap_opt_register_t custom_block_list[MAX_WTAP_OPTION_BLOCK_CUSTOM]; +static wtap_blocktype_t custom_blocktype_list[MAX_WTAP_BLOCK_CUSTOM]; -static void wtap_opttype_block_register(int block_type, wtap_opt_register_t *block) +static void wtap_opttype_block_register(int block_type, wtap_blocktype_t *blocktype) { + static const wtap_opttype_t opt_comment = { + "opt_comment", + "Comment", + WTAP_OPTTYPE_STRING, + WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED, + NULL + }; + /* Check input */ - g_assert(block_type < WTAP_OPTION_BLOCK_END_OF_LIST); + g_assert(block_type < WTAP_BLOCK_END_OF_LIST); /* Don't re-register. */ - g_assert(block_list[block_type] == NULL); + g_assert(blocktype_list[block_type] == NULL); /* Sanity check */ - g_assert(block->name); - g_assert(block->description); - g_assert(block->create); + g_assert(blocktype->name); + g_assert(blocktype->description); + g_assert(blocktype->create); + + blocktype->block_type = block_type; - block_list[block_type] = block; + /* + * Initialize the set of supported options. + * All blocks that support options at all support OPT_COMMENT. + */ + blocktype->options = g_array_sized_new(FALSE, TRUE, sizeof (wtap_opttype_t), OPT_COMMENT + 1); + if (OPT_COMMENT + 1 > blocktype->options->len) + g_array_set_size(blocktype->options, OPT_COMMENT + 1); + g_array_insert_val(blocktype->options, OPT_COMMENT, opt_comment); + + blocktype_list[block_type] = blocktype; } int wtap_opttype_register_custom_block_type(const char* name, const char* description, wtap_block_create_func create, - wtap_mand_free_func free_mand, wtap_mand_copy_func copy_mand) + wtap_mand_free_func free_mand, wtap_mand_copy_func copy_mand) { int block_type; @@ -100,494 +125,738 @@ int wtap_opttype_register_custom_block_type(const char* name, const char* descri g_assert(create); /* This shouldn't happen, so flag it for fixing */ - g_assert(num_custom_blocks < MAX_WTAP_OPTION_BLOCK_CUSTOM); + g_assert(num_custom_blocks < MAX_WTAP_BLOCK_CUSTOM); - block_type = WTAP_OPTION_BLOCK_END_OF_LIST+num_custom_blocks; + block_type = WTAP_BLOCK_END_OF_LIST+num_custom_blocks; - custom_block_list[num_custom_blocks].name = name; - custom_block_list[num_custom_blocks].description = description; - custom_block_list[num_custom_blocks].create = create; - custom_block_list[num_custom_blocks].free_mand = free_mand; - custom_block_list[num_custom_blocks].copy_mand = copy_mand; - block_list[block_type] = &custom_block_list[num_custom_blocks]; + custom_blocktype_list[num_custom_blocks].name = name; + custom_blocktype_list[num_custom_blocks].description = description; + custom_blocktype_list[num_custom_blocks].create = create; + custom_blocktype_list[num_custom_blocks].free_mand = free_mand; + custom_blocktype_list[num_custom_blocks].copy_mand = copy_mand; + blocktype_list[block_type] = &custom_blocktype_list[num_custom_blocks]; num_custom_blocks++; return block_type; } -void* wtap_optionblock_get_mandatory_data(wtap_optionblock_t block) +static void wtap_opttype_option_register(wtap_blocktype_t *blocktype, int opttype, wtap_opttype_t *option) +{ + if ((guint)opttype + 1 > blocktype->options->len) + g_array_set_size(blocktype->options, opttype + 1); + g_array_insert_val(blocktype->options, opttype, *option); +} + +void* wtap_block_get_mandatory_data(wtap_block_t block) { return block->mandatory_data; } -static wtap_optblock_value_t* wtap_optionblock_get_option(wtap_optionblock_t block, guint option_id) +static wtap_optval_t * +wtap_block_get_option(wtap_block_t block, guint option_id) { guint i; - wtap_optblock_value_t* opttype = NULL; + wtap_option_t *opt; - for (i = 0; i < block->option_values->len; i++) - { - opttype = g_array_index(block->option_values, wtap_optblock_value_t*, i); - if (opttype->info->number == option_id) - return opttype; + for (i = 0; i < block->options->len; i++) { + opt = &g_array_index(block->options, wtap_option_t, i); + if (opt->option_id == option_id) + return &opt->value; + } + + return NULL; +} + +static wtap_optval_t * +wtap_block_get_nth_option(wtap_block_t block, guint option_id, guint idx) +{ + guint i; + wtap_option_t *opt; + guint opt_idx; + + opt_idx = 0; + for (i = 0; i < block->options->len; i++) { + opt = &g_array_index(block->options, wtap_option_t, i); + if (opt->option_id == option_id) { + if (opt_idx == idx) + return &opt->value; + opt_idx++; + } } return NULL; } -wtap_optionblock_t wtap_optionblock_create(int block_type) +wtap_block_t wtap_block_create(wtap_block_type_t block_type) { - wtap_optionblock_t block; + wtap_block_t block; - if (block_type >= (int)(WTAP_OPTION_BLOCK_END_OF_LIST+num_custom_blocks)) + if (block_type >= (WTAP_BLOCK_END_OF_LIST+num_custom_blocks)) return NULL; - block = g_new(struct wtap_optionblock, 1); - block->info = block_list[block_type]; - block->option_infos = g_array_new(FALSE, FALSE, sizeof(wtap_optblock_internal_t*)); - block->option_values = g_array_new(FALSE, FALSE, sizeof(wtap_optblock_value_t*)); + block = g_new(struct wtap_block, 1); + block->info = blocktype_list[block_type]; + block->options = g_array_new(FALSE, FALSE, sizeof(wtap_option_t)); block->info->create(block); return block; } -static void wtap_optionblock_free_options(wtap_optionblock_t block) +static void wtap_block_free_options(wtap_block_t block) { guint i; - wtap_optblock_value_t* opttype = NULL; + wtap_option_t *opt; + wtap_opttype_t *opttype; + + for (i = 0; i < block->options->len; i++) { + opt = &g_array_index(block->options, wtap_option_t, i); + opttype = &g_array_index(block->info->options, wtap_opttype_t, opt->option_id); + switch (opttype->data_type) { - for (i = 0; i < block->option_values->len; i++) { - opttype = g_array_index(block->option_values, wtap_optblock_value_t*, i); - switch(opttype->info->type) - { case WTAP_OPTTYPE_STRING: - g_free(opttype->option.stringval); + g_free(opt->value.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); + opttype->free_func(opt->value.customval.data); + g_free(opt->value.customval.data); break; + default: break; } - g_free(opttype); } } -void wtap_optionblock_free(wtap_optionblock_t block) +void wtap_block_free(wtap_block_t block) { - unsigned i; if (block != NULL) { if (block->info->free_mand != NULL) block->info->free_mand(block); g_free(block->mandatory_data); - wtap_optionblock_free_options(block); - for (i = 0; i < block->option_infos->len; i++) - g_free(g_array_index(block->option_infos, wtap_optblock_internal_t*, i)); - if (block->option_infos != NULL) - g_array_free(block->option_infos, TRUE); - if (block->option_values != NULL) - g_array_free(block->option_values, TRUE); + wtap_block_free_options(block); + if (block->options != NULL) + g_array_free(block->options, TRUE); g_free(block); } } -void wtap_optionblock_array_free(GArray* block_array) +void wtap_block_array_free(GArray* block_array) { guint block; + if (block_array == NULL) return; for (block = 0; block < block_array->len; block++) { - wtap_optionblock_free(g_array_index(block_array, wtap_optionblock_t, block)); + wtap_block_free(g_array_index(block_array, wtap_block_t, block)); } g_array_free(block_array, TRUE); } -void wtap_optionblock_copy_options(wtap_optionblock_t dest_block, wtap_optionblock_t src_block) +/* + * Make a copy of a block. + */ +void +wtap_block_copy(wtap_block_t dest_block, wtap_block_t src_block) { guint i; - wtap_optblock_internal_t *src_internal; - wtap_optblock_value_t *dest_value, *src_value; + wtap_option_t *src_opt; + wtap_opttype_t *opttype; + /* + * Copy the mandatory data. + */ if (dest_block->info->copy_mand != NULL) dest_block->info->copy_mand(dest_block, src_block); /* Copy the options. For now, don't remove any options that are in destination * but not source. */ - for (i = 0; i < src_block->option_values->len; i++) + for (i = 0; i < src_block->options->len; i++) { - src_internal = g_array_index(src_block->option_infos, wtap_optblock_internal_t*, i); - src_value = g_array_index(src_block->option_values, wtap_optblock_value_t*, i); - dest_value = wtap_optionblock_get_option(dest_block, src_internal->number); - if (dest_value == NULL) - { - wtap_optblock_reg_t reg_optblock; + src_opt = &g_array_index(src_block->options, wtap_option_t, i); + opttype = &g_array_index(src_block->info->options, wtap_opttype_t, src_opt->option_id); - reg_optblock.name = src_internal->name; - reg_optblock.description = src_internal->description; - reg_optblock.type = src_internal->type; - reg_optblock.option = src_value->option; - reg_optblock.default_val = src_value->default_val; + switch(opttype->data_type) { - wtap_optionblock_add_option(dest_block, src_internal->number, ®_optblock); - } - else - { - /* Option exists, replace it */ - switch(src_internal->type) - { - case WTAP_OPTTYPE_UINT8: - dest_value->option.uint8val = src_value->option.uint8val; - break; - case WTAP_OPTTYPE_UINT64: - dest_value->option.uint64val = src_value->option.uint64val; - break; - case WTAP_OPTTYPE_STRING: - g_free(dest_value->option.stringval); - dest_value->option.stringval = g_strdup(src_value->option.stringval); - break; - case WTAP_OPTTYPE_CUSTOM: - dest_value->option.customval.free_func(dest_value->option.customval.data); - g_free(dest_value->option.customval.data); - dest_value->option.customval.data = g_memdup(src_value->option.customval.data, src_value->option.customval.size); - break; - } + case WTAP_OPTTYPE_UINT8: + wtap_block_add_uint8_option(dest_block, src_opt->option_id, src_opt->value.uint8val); + break; + + case WTAP_OPTTYPE_UINT64: + wtap_block_add_uint64_option(dest_block, src_opt->option_id, src_opt->value.uint64val); + break; + + case WTAP_OPTTYPE_IPv4: + wtap_block_add_ipv4_option(dest_block, src_opt->option_id, src_opt->value.ipv4val); + break; + + case WTAP_OPTTYPE_IPv6: + wtap_block_add_ipv6_option(dest_block, src_opt->option_id, &src_opt->value.ipv6val); + break; + + case WTAP_OPTTYPE_STRING: + wtap_block_add_string_option(dest_block, src_opt->option_id, src_opt->value.stringval, strlen(src_opt->value.stringval)); + break; + + case WTAP_OPTTYPE_CUSTOM: + wtap_block_add_custom_option(dest_block, src_opt->option_id, src_opt->value.customval.data, src_opt->value.customval.size); + break; } } } -void wtap_optionblock_foreach_option(wtap_optionblock_t block, wtap_optionblock_foreach_func func, void* user_data) +void wtap_block_foreach_option(wtap_block_t block, wtap_block_foreach_func func, void* user_data) { guint i; - wtap_optblock_internal_t *internal_data; - wtap_optblock_value_t *value; + wtap_option_t *opt; + wtap_opttype_t *opttype; - for (i = 0; i < block->option_values->len; i++) - { - internal_data = g_array_index(block->option_infos, wtap_optblock_internal_t*, i); - value = g_array_index(block->option_values, wtap_optblock_value_t*, i); - func(block, internal_data->number, value->info->type, &value->option, user_data); + for (i = 0; i < block->options->len; i++) { + opt = &g_array_index(block->options, wtap_option_t, i); + opttype = &g_array_index(block->info->options, wtap_opttype_t, opt->option_id); + func(block, opt->option_id, opttype->data_type, &opt->value, user_data); } } -wtap_opttype_return_val wtap_optionblock_add_option(wtap_optionblock_t block, guint option_id, wtap_optblock_reg_t* option) +wtap_opttype_return_val +wtap_block_num_options_of_type(wtap_block_t block, guint option_id, guint *countp) { - wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id); - wtap_optblock_internal_t *opt_internal; + guint n_options; + guint i; + wtap_option_t *opt; + wtap_opttype_t *opttype; + + if (option_id >= block->info->options->len) { + /* There's no option for this block with that option ID */ + return WTAP_OPTTYPE_NO_SUCH_OPTION; + } - /* Option already exists */ - if (opt_value != NULL) - return WTAP_OPTTYPE_ALREADY_EXISTS; + opttype = &g_array_index(block->info->options, wtap_opttype_t, option_id); + + /* + * Can there be more than one instance of this option? + */ + if (!(opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED)) { + /* + * No; this is only for use with options with multiple + * instances. + */ + return WTAP_OPTTYPE_NUMBER_MISMATCH; + } + + n_options = 0; + for (i = 0; i < block->options->len; i++) { + opt = g_array_index(block->options, wtap_option_t*, i); + if (opt->option_id == option_id) + n_options++; + } + *countp = n_options; + return WTAP_OPTTYPE_SUCCESS; +} - opt_value = g_new0(wtap_optblock_value_t, 1); - opt_internal = g_new(wtap_optblock_internal_t, 1); +static wtap_opttype_return_val +wtap_block_add_option_common(wtap_block_t block, guint option_id, wtap_opttype_e type, wtap_option_t **optp) +{ + wtap_option_t *opt; + wtap_opttype_t *opttype; + guint i; - opt_internal->name = option->name; - opt_internal->description = option->description; - opt_internal->number = option_id; - opt_internal->type = option->type; + if (option_id >= block->info->options->len) { + /* There's no option for this block with that option ID */ + return WTAP_OPTTYPE_NO_SUCH_OPTION; + } + opttype = &g_array_index(block->info->options, wtap_opttype_t, option_id); - opt_value->info = opt_internal; + /* + * Is this an option of the specified data type? + */ + if (opttype->data_type != type) { + /* + * No. + */ + return WTAP_OPTTYPE_TYPE_MISMATCH; + } - switch(option->type) - { - case WTAP_OPTTYPE_UINT8: - opt_value->option.uint8val = option->option.uint8val; - opt_value->default_val.uint8val = option->default_val.uint8val; - break; - case WTAP_OPTTYPE_UINT64: - opt_value->option.uint64val = option->option.uint64val; - opt_value->default_val.uint64val = option->default_val.uint64val; - break; - case WTAP_OPTTYPE_STRING: - opt_value->option.stringval = g_strdup(option->option.stringval); - opt_value->default_val.stringval = option->default_val.stringval; - break; - case WTAP_OPTTYPE_CUSTOM: - opt_value->option.customval.size = option->option.customval.size; - opt_value->option.customval.data = g_memdup(option->option.customval.data, option->option.customval.size); - opt_value->option.customval.free_func = option->option.customval.free_func; - opt_value->default_val.customval.size = option->default_val.customval.size; - opt_value->default_val.customval.data = g_memdup(option->default_val.customval.data, option->default_val.customval.size); - opt_value->default_val.customval.free_func = option->default_val.customval.free_func; - break; + /* + * Can there be more than one instance of this option? + */ + if (!(opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED)) { + /* + * No. Is there already an instance of this option? + */ + if (wtap_block_get_option(block, option_id) != NULL) { + /* + * Yes. Fail. + */ + return WTAP_OPTTYPE_ALREADY_EXISTS; + } } - g_array_append_val(block->option_infos, opt_internal); - g_array_append_val(block->option_values, opt_value); + /* + * Add an instance. + */ + i = block->options->len; + g_array_set_size(block->options, i + 1); + opt = &g_array_index(block->options, wtap_option_t, i); + opt->option_id = option_id; + *optp = opt; return WTAP_OPTTYPE_SUCCESS; } -wtap_opttype_return_val wtap_optionblock_set_option_string(wtap_optionblock_t block, guint option_id, char* value, gsize value_length) +static wtap_opttype_return_val +wtap_block_get_option_common(wtap_block_t block, guint option_id, wtap_opttype_e type, wtap_optval_t **optvalp) { - wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id); + wtap_opttype_t *opttype; + wtap_optval_t *optval; - /* Didn't find the option */ - if (opt_value == NULL) - return WTAP_OPTTYPE_NOT_FOUND; + if (option_id >= block->info->options->len) { + /* There's no option for this block with that option ID */ + return WTAP_OPTTYPE_NO_SUCH_OPTION; + } + + opttype = &g_array_index(block->info->options, wtap_opttype_t, option_id); - if (opt_value->info->type != WTAP_OPTTYPE_STRING) + /* + * Is this an option of the specified data type? + */ + if (opttype->data_type != type) { + /* + * No. + */ return WTAP_OPTTYPE_TYPE_MISMATCH; + } + + /* + * Can there be more than one instance of this option? + */ + if (opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED) { + /* + * Yes. You can't ask for "the" value. + */ + return WTAP_OPTTYPE_NUMBER_MISMATCH; + } - g_free(opt_value->option.stringval); - opt_value->option.stringval = g_strndup(value, value_length); + optval = wtap_block_get_option(block, option_id); + if (optval == NULL) { + /* Didn't find the option */ + return WTAP_OPTTYPE_NOT_FOUND; + } + + *optvalp = optval; return WTAP_OPTTYPE_SUCCESS; } -wtap_opttype_return_val wtap_optionblock_set_option_string_format(wtap_optionblock_t block, guint option_id, const char *format, ...) +static wtap_opttype_return_val +wtap_block_get_nth_option_common(wtap_block_t block, guint option_id, wtap_opttype_e type, guint idx, wtap_optval_t **optvalp) { - va_list va; - wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id); + wtap_opttype_t *opttype; + wtap_optval_t *optval; - /* Didn't find the option */ - if (opt_value == NULL) - return WTAP_OPTTYPE_NOT_FOUND; + if (option_id >= block->info->options->len) { + /* There's no option for this block with that option ID */ + return WTAP_OPTTYPE_NO_SUCH_OPTION; + } + + opttype = &g_array_index(block->info->options, wtap_opttype_t, option_id); - if (opt_value->info->type != WTAP_OPTTYPE_STRING) + /* + * Is this an option of the specified data type? + */ + if (opttype->data_type != type) { + /* + * No. + */ return WTAP_OPTTYPE_TYPE_MISMATCH; + } - g_free(opt_value->option.stringval); - va_start(va, format); - opt_value->option.stringval = g_strdup_vprintf(format, va); - va_end(va); + /* + * Can there be more than one instance of this option? + */ + if (!(opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED)) { + /* + * No. + */ + return WTAP_OPTTYPE_NUMBER_MISMATCH; + } + + optval = wtap_block_get_nth_option(block, option_id, idx); + if (optval == NULL) { + /* Didn't find the option */ + return WTAP_OPTTYPE_NOT_FOUND; + } + + *optvalp = optval; return WTAP_OPTTYPE_SUCCESS; } -wtap_opttype_return_val wtap_optionblock_get_option_string(wtap_optionblock_t block, guint option_id, char** value) +wtap_opttype_return_val +wtap_block_add_uint8_option(wtap_block_t block, guint option_id, guint8 value) { - wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id); + wtap_opttype_return_val ret; + wtap_option_t *opt; - /* Didn't find the option */ - if (opt_value == NULL) - return WTAP_OPTTYPE_NOT_FOUND; + ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_UINT8, &opt); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + opt->value.uint8val = value; + return WTAP_OPTTYPE_SUCCESS; +} - if (opt_value->info->type != WTAP_OPTTYPE_STRING) - return WTAP_OPTTYPE_TYPE_MISMATCH; +wtap_opttype_return_val +wtap_block_set_uint8_option_value(wtap_block_t block, guint option_id, guint8 value) +{ + wtap_opttype_return_val ret; + wtap_optval_t *optval; - *value = opt_value->option.stringval; + ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT8, &optval); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + optval->uint8val = value; return WTAP_OPTTYPE_SUCCESS; } -wtap_opttype_return_val wtap_optionblock_get_string_options(wtap_optionblock_t block, guint option_id, GArray **value) +wtap_opttype_return_val +wtap_block_get_uint8_option_value(wtap_block_t block, guint option_id, guint8* value) { - guint n_options; - guint i; - wtap_optblock_value_t* opt_value; - GArray *opt_values; + wtap_opttype_return_val ret; + wtap_optval_t *optval; - n_options = 0; - for (i = 0; i < block->option_values->len; i++) - { - opt_value = g_array_index(block->option_values, wtap_optblock_value_t*, i); - if (opt_value->info->number == option_id) { - if (opt_value->info->type != WTAP_OPTTYPE_STRING) - return WTAP_OPTTYPE_TYPE_MISMATCH; - n_options++; - } - } + ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT8, &optval); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + *value = optval->uint8val; + return WTAP_OPTTYPE_SUCCESS; +} - opt_values = g_array_sized_new(FALSE, FALSE, sizeof (char *), n_options); - for (i = 0; i < block->option_values->len; i++) - { - opt_value = g_array_index(block->option_values, wtap_optblock_value_t*, i); - if (opt_value->info->number == option_id) - g_array_append_val(opt_values, opt_value->option.stringval); - } +wtap_opttype_return_val +wtap_block_add_uint64_option(wtap_block_t block, guint option_id, guint64 value) +{ + wtap_opttype_return_val ret; + wtap_option_t *opt; - *value = opt_values; + ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_UINT64, &opt); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + opt->value.uint64val = value; return WTAP_OPTTYPE_SUCCESS; } -wtap_opttype_return_val wtap_optionblock_set_option_uint64(wtap_optionblock_t block, guint option_id, guint64 value) +wtap_opttype_return_val +wtap_block_set_uint64_option_value(wtap_block_t block, guint option_id, guint64 value) { - wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id); + wtap_opttype_return_val ret; + wtap_optval_t *optval; - /* Didn't find the option */ - if (opt_value == NULL) - return WTAP_OPTTYPE_NOT_FOUND; + ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT64, &optval); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + optval->uint64val = value; + return WTAP_OPTTYPE_SUCCESS; +} - if (opt_value->info->type != WTAP_OPTTYPE_UINT64) - return WTAP_OPTTYPE_TYPE_MISMATCH; +wtap_opttype_return_val +wtap_block_get_uint64_option_value(wtap_block_t block, guint option_id, guint64 *value) +{ + wtap_opttype_return_val ret; + wtap_optval_t *optval; - opt_value->option.uint64val = value; + ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT64, &optval); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + *value = optval->uint64val; return WTAP_OPTTYPE_SUCCESS; } -wtap_opttype_return_val wtap_optionblock_get_option_uint64(wtap_optionblock_t block, guint option_id, guint64* value) +wtap_opttype_return_val +wtap_block_add_ipv4_option(wtap_block_t block, guint option_id, guint32 value) { - wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id); + wtap_opttype_return_val ret; + wtap_option_t *opt; - /* Didn't find the option */ - if (opt_value == NULL) - return WTAP_OPTTYPE_NOT_FOUND; + ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_IPv4, &opt); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + opt->value.ipv4val = value; + return WTAP_OPTTYPE_SUCCESS; +} - if (opt_value->info->type != WTAP_OPTTYPE_UINT64) - return WTAP_OPTTYPE_TYPE_MISMATCH; +wtap_opttype_return_val +wtap_block_set_ipv4_option_value(wtap_block_t block, guint option_id, guint32 value) +{ + wtap_opttype_return_val ret; + wtap_optval_t *optval; - *value = opt_value->option.uint64val; + ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IPv4, &optval); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + optval->ipv4val = value; return WTAP_OPTTYPE_SUCCESS; } +wtap_opttype_return_val +wtap_block_get_ipv4_option_value(wtap_block_t block, guint option_id, guint32* value) +{ + wtap_opttype_return_val ret; + wtap_optval_t *optval; + + ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IPv4, &optval); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + *value = optval->ipv4val; + return WTAP_OPTTYPE_SUCCESS; +} -wtap_opttype_return_val wtap_optionblock_set_option_uint8(wtap_optionblock_t block, guint option_id, guint8 value) +wtap_opttype_return_val +wtap_block_add_ipv6_option(wtap_block_t block, guint option_id, struct e_in6_addr *value) { - wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id); + wtap_opttype_return_val ret; + wtap_option_t *opt; - /* Didn't find the option */ - if (opt_value == NULL) - return WTAP_OPTTYPE_NOT_FOUND; + ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_IPv6, &opt); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + opt->value.ipv6val = *value; + return WTAP_OPTTYPE_SUCCESS; +} - if (opt_value->info->type != WTAP_OPTTYPE_UINT8) - return WTAP_OPTTYPE_TYPE_MISMATCH; +wtap_opttype_return_val +wtap_block_set_ipv6_option_value(wtap_block_t block, guint option_id, struct e_in6_addr *value) +{ + wtap_opttype_return_val ret; + wtap_optval_t *optval; - opt_value->option.uint8val = value; + ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IPv6, &optval); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + optval->ipv6val = *value; return WTAP_OPTTYPE_SUCCESS; } -wtap_opttype_return_val wtap_optionblock_get_option_uint8(wtap_optionblock_t block, guint option_id, guint8* value) +wtap_opttype_return_val +wtap_block_get_ipv6_option_value(wtap_block_t block, guint option_id, struct e_in6_addr* value) { - wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id); + wtap_opttype_return_val ret; + wtap_optval_t *optval; - /* Didn't find the option */ - if (opt_value == NULL) - return WTAP_OPTTYPE_NOT_FOUND; + ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IPv4, &optval); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + *value = optval->ipv6val; + return WTAP_OPTTYPE_SUCCESS; +} - if (opt_value->info->type != WTAP_OPTTYPE_UINT8) - return WTAP_OPTTYPE_TYPE_MISMATCH; +wtap_opttype_return_val +wtap_block_add_string_option(wtap_block_t block, guint option_id, const char *value, gsize value_length) +{ + wtap_opttype_return_val ret; + wtap_option_t *opt; - *value = opt_value->option.uint8val; + ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_STRING, &opt); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + opt->value.stringval = g_strndup(value, value_length); return WTAP_OPTTYPE_SUCCESS; } -wtap_opttype_return_val wtap_optionblock_set_option_custom(wtap_optionblock_t block, guint option_id, void* value) +static wtap_opttype_return_val +wtap_block_add_string_option_vformat(wtap_block_t block, guint option_id, const char *format, va_list va) { - wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id); - void* prev_value; + wtap_opttype_return_val ret; + wtap_option_t *opt; - /* Didn't find the option */ - if (opt_value == NULL) - return WTAP_OPTTYPE_NOT_FOUND; + ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_STRING, &opt); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + opt->value.stringval = g_strdup_vprintf(format, va); + return WTAP_OPTTYPE_SUCCESS; +} - if (opt_value->info->type != WTAP_OPTTYPE_CUSTOM) - return WTAP_OPTTYPE_TYPE_MISMATCH; +wtap_opttype_return_val +wtap_block_add_string_option_format(wtap_block_t block, guint option_id, const char *format, ...) +{ + wtap_opttype_return_val ret; + wtap_option_t *opt; + va_list va; - prev_value = opt_value->option.customval.data; - opt_value->option.customval.data = g_memdup(value, opt_value->option.customval.size); - /* Free after memory is duplicated in case structure was manipulated with a "get then set" */ - g_free(prev_value); + ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_STRING, &opt); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + va_start(va, format); + opt->value.stringval = g_strdup_vprintf(format, va); + va_end(va); return WTAP_OPTTYPE_SUCCESS; } -wtap_opttype_return_val wtap_optionblock_get_option_custom(wtap_optionblock_t block, guint option_id, void** value) +wtap_opttype_return_val +wtap_block_set_string_option_value(wtap_block_t block, guint option_id, const char *value, size_t value_length) { - wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id); + wtap_opttype_return_val ret; + wtap_optval_t *optval; + + ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_STRING, &optval); + if (ret != WTAP_OPTTYPE_SUCCESS) { + if (ret == WTAP_OPTTYPE_NOT_FOUND) { + /* + * There's no instance to set, so just try to create a new one + * with the value. + */ + return wtap_block_add_string_option(block, option_id, value, value_length); + } + /* Otherwise fail. */ + return ret; + } + g_free(optval->stringval); + optval->stringval = g_strndup(value, value_length); + return WTAP_OPTTYPE_SUCCESS; +} - /* Didn't find the option */ - if (opt_value == NULL) - return WTAP_OPTTYPE_NOT_FOUND; +wtap_opttype_return_val +wtap_block_set_nth_string_option_value(wtap_block_t block, guint option_id, guint idx, const char *value, size_t value_length) +{ + wtap_opttype_return_val ret; + wtap_optval_t *optval; + + ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_STRING, idx, &optval); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + g_free(optval->stringval); + optval->stringval = g_strndup(value, value_length); + return WTAP_OPTTYPE_SUCCESS; +} - if (opt_value->info->type != WTAP_OPTTYPE_CUSTOM) - return WTAP_OPTTYPE_TYPE_MISMATCH; +wtap_opttype_return_val +wtap_block_set_string_option_value_format(wtap_block_t block, guint option_id, const char *format, ...) +{ + wtap_opttype_return_val ret; + wtap_optval_t *optval; + va_list va; - *value = opt_value->option.customval.data; + ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_STRING, &optval); + if (ret != WTAP_OPTTYPE_SUCCESS) { + if (ret == WTAP_OPTTYPE_NOT_FOUND) { + /* + * There's no instance to set, so just try to create a new one + * with the formatted string. + */ + va_start(va, format); + ret = wtap_block_add_string_option_vformat(block, option_id, format, va); + va_end(va); + return ret; + } + /* Otherwise fail. */ + return ret; + } + g_free(optval->stringval); + va_start(va, format); + optval->stringval = g_strdup_vprintf(format, va); + va_end(va); return WTAP_OPTTYPE_SUCCESS; } -static void shb_create(wtap_optionblock_t block) +wtap_opttype_return_val +wtap_block_get_string_option_value(wtap_block_t block, guint option_id, char** value) { - static wtap_optblock_reg_t comment_option = {"opt_comment", "Optional comment", WTAP_OPTTYPE_STRING, {0}, {0}}; - static wtap_optblock_reg_t hardware_option = {"hardware", "SBH Hardware", WTAP_OPTTYPE_STRING, {0}, {0}}; - static wtap_optblock_reg_t os_option = {"os", "SBH Operating System", WTAP_OPTTYPE_STRING, {0}, {0}}; - static wtap_optblock_reg_t user_appl_option = {"user_appl", "SBH User Application", WTAP_OPTTYPE_STRING, {0}, {0}}; + wtap_opttype_return_val ret; + wtap_optval_t *optval; - wtapng_mandatory_section_t* section_mand = g_new(wtapng_mandatory_section_t, 1); + ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_STRING, &optval); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + *value = optval->stringval; + return WTAP_OPTTYPE_SUCCESS; +} - /* Set proper values for the union */ - comment_option.option.stringval = NULL; - comment_option.default_val.stringval = NULL; - hardware_option.option.stringval = NULL; - hardware_option.default_val.stringval = NULL; - os_option.option.stringval = NULL; - os_option.default_val.stringval = NULL; - user_appl_option.option.stringval = NULL; - user_appl_option.default_val.stringval = NULL; +wtap_opttype_return_val +wtap_block_get_nth_string_option_value(wtap_block_t block, guint option_id, guint idx, char** value) +{ + wtap_opttype_return_val ret; + wtap_optval_t *optval; - section_mand->section_length = -1; + ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_STRING, idx, &optval); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + *value = optval->stringval; + return WTAP_OPTTYPE_SUCCESS; +} - block->mandatory_data = section_mand; +wtap_opttype_return_val +wtap_block_add_custom_option(wtap_block_t block, guint option_id, void *value, size_t value_size) +{ + wtap_opttype_return_val ret; + wtap_option_t *opt; + + ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_CUSTOM, &opt); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + opt->value.customval.size = (guint)value_size; + opt->value.customval.data = g_memdup(value, (guint)value_size); + return WTAP_OPTTYPE_SUCCESS; +} + +wtap_opttype_return_val +wtap_block_get_custom_option_value(wtap_block_t block, guint option_id, void** value) +{ + wtap_opttype_return_val ret; + wtap_optval_t *optval; - wtap_optionblock_add_option(block, OPT_COMMENT, &comment_option); - wtap_optionblock_add_option(block, OPT_SHB_HARDWARE, &hardware_option); - wtap_optionblock_add_option(block, OPT_SHB_OS, &os_option); - wtap_optionblock_add_option(block, OPT_SHB_USERAPPL, &user_appl_option); + ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_CUSTOM, &optval); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + *value = optval->customval.data; + return WTAP_OPTTYPE_SUCCESS; } -static void shb_copy_mand(wtap_optionblock_t dest_block, wtap_optionblock_t src_block) +wtap_opttype_return_val +wtap_block_set_custom_option_value(wtap_block_t block, guint option_id, void *value) { - memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_mandatory_section_t)); + wtap_opttype_return_val ret; + wtap_optval_t *optval; + void *prev_value; + + ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_CUSTOM, &optval); + if (ret != WTAP_OPTTYPE_SUCCESS) + return ret; + prev_value = optval->customval.data; + /* + * XXX - a custom value can be a structure that points to other data, + * but we're doing a shallow copy here. + */ + optval->customval.data = g_memdup(value, optval->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; } -static void nrb_create(wtap_optionblock_t block) +static void shb_create(wtap_block_t block) { - static wtap_optblock_reg_t comment_option = {"opt_comment", "Optional comment", WTAP_OPTTYPE_STRING, {0}, {0}}; + wtapng_mandatory_section_t* section_mand = g_new(wtapng_mandatory_section_t, 1); - /* Set proper values for the union */ - comment_option.option.stringval = NULL; - comment_option.default_val.stringval = NULL; + section_mand->section_length = -1; - block->mandatory_data = NULL; + block->mandatory_data = section_mand; +} - wtap_optionblock_add_option(block, OPT_COMMENT, &comment_option); +static void shb_copy_mand(wtap_block_t dest_block, wtap_block_t src_block) +{ + memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_mandatory_section_t)); } -static void isb_create(wtap_optionblock_t block) +static void nrb_create(wtap_block_t block) { - static wtap_optblock_reg_t comment_option = {"opt_comment", "Optional comment", WTAP_OPTTYPE_STRING, {0}, {0}}; - static wtap_optblock_reg_t starttime_option = {"start_time", "Start Time", WTAP_OPTTYPE_UINT64, {0}, {0}}; - static wtap_optblock_reg_t endtime_option = {"end_time", "End Time", WTAP_OPTTYPE_UINT64, {0}, {0}}; - static wtap_optblock_reg_t rcv_pkt_option = {"recv", "Receive Packets", WTAP_OPTTYPE_UINT64, {0}, {0}}; - static wtap_optblock_reg_t drop_pkt_option = {"drop", "Dropped Packets", WTAP_OPTTYPE_UINT64, {0}, {0}}; - static wtap_optblock_reg_t filteraccept_option = {"filter_accept", "Filter Accept", WTAP_OPTTYPE_UINT64, {0}, {0}}; - static wtap_optblock_reg_t os_drop_option = {"os_drop", "OS Dropped Packets", WTAP_OPTTYPE_UINT64, {0}, {0}}; - static wtap_optblock_reg_t user_deliv_option = {"user_deliv", "User Delivery", WTAP_OPTTYPE_UINT64, {0}, {0}}; + block->mandatory_data = NULL; +} +static void isb_create(wtap_block_t block) +{ block->mandatory_data = g_new0(wtapng_if_stats_mandatory_t, 1); +} - /* Set proper values for the union */ - comment_option.option.stringval = NULL; - comment_option.default_val.stringval = NULL; - starttime_option.option.uint64val = 0; - starttime_option.default_val.uint64val = 0; - endtime_option.option.uint64val = 0; - endtime_option.default_val.uint64val = 0; - rcv_pkt_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF); - rcv_pkt_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF); - drop_pkt_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF); - drop_pkt_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF); - filteraccept_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF); - filteraccept_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF); - os_drop_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF); - os_drop_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF); - user_deliv_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF); - user_deliv_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF); - - wtap_optionblock_add_option(block, OPT_COMMENT, &comment_option); - wtap_optionblock_add_option(block, OPT_ISB_STARTTIME, &starttime_option); - wtap_optionblock_add_option(block, OPT_ISB_ENDTIME, &endtime_option); - wtap_optionblock_add_option(block, OPT_ISB_IFRECV, &rcv_pkt_option); - wtap_optionblock_add_option(block, OPT_ISB_IFDROP, &drop_pkt_option); - wtap_optionblock_add_option(block, OPT_ISB_FILTERACCEPT, &filteraccept_option); - wtap_optionblock_add_option(block, OPT_ISB_OSDROP, &os_drop_option); - wtap_optionblock_add_option(block, OPT_ISB_USRDELIV, &user_deliv_option); -} - -static void isb_copy_mand(wtap_optionblock_t dest_block, wtap_optionblock_t src_block) +static void isb_copy_mand(wtap_block_t dest_block, wtap_block_t src_block) { memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_if_stats_mandatory_t)); } @@ -599,72 +868,30 @@ static void idb_filter_free(void* data) g_free(filter->if_filter_bpf_bytes); } -static void idb_create(wtap_optionblock_t block) +static void idb_create(wtap_block_t block) { - static wtap_optblock_reg_t comment_option = {"opt_comment", "Optional comment", WTAP_OPTTYPE_STRING, {0}, {0}}; - static wtap_optblock_reg_t name_option = {"name", "Device name", WTAP_OPTTYPE_STRING, {0}, {0}}; - static wtap_optblock_reg_t description_option = {"description", "Device description", WTAP_OPTTYPE_STRING, {0}, {0}}; - static wtap_optblock_reg_t speed_option = {"speed", "Interface speed (in bps)", WTAP_OPTTYPE_UINT64, {0}, {0}}; - static wtap_optblock_reg_t tsresol_option = {"ts_resolution", "Resolution of timestamps", WTAP_OPTTYPE_UINT8, {0}, {0}}; - static wtap_optblock_reg_t filter_option = {"filter", "Filter string", WTAP_OPTTYPE_CUSTOM, {0}, {0}}; - static wtap_optblock_reg_t os_option = {"os", "Operating System", WTAP_OPTTYPE_STRING, {0}, {0}}; - static wtap_optblock_reg_t fcslen_option = {"fcslen", "FCS Length", WTAP_OPTTYPE_UINT8, {0}, {0}}; - - static wtapng_if_descr_filter_t default_filter; - block->mandatory_data = g_new0(wtapng_if_descr_mandatory_t, 1); +} - /* Set proper values for the union */ - comment_option.option.stringval = NULL; - comment_option.default_val.stringval = NULL; - name_option.option.stringval = NULL; - name_option.default_val.stringval = NULL; - description_option.option.stringval = NULL; - description_option.default_val.stringval = NULL; - speed_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF); - speed_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF); - tsresol_option.option.uint8val = 6; - tsresol_option.default_val.uint8val = 6; - filter_option.option.customval.size = sizeof(wtapng_if_descr_filter_t); - filter_option.option.customval.data = &default_filter; - filter_option.option.customval.free_func = idb_filter_free; - filter_option.default_val.customval.size = sizeof(wtapng_if_descr_filter_t); - filter_option.default_val.customval.data = &default_filter; - filter_option.default_val.customval.free_func = idb_filter_free; - os_option.option.stringval = NULL; - os_option.default_val.stringval = NULL; - fcslen_option.option.uint8val = -1; - fcslen_option.default_val.uint8val = -1; - - wtap_optionblock_add_option(block, OPT_COMMENT, &comment_option); - wtap_optionblock_add_option(block, OPT_IDB_NAME, &name_option); - wtap_optionblock_add_option(block, OPT_IDB_DESCR, &description_option); - wtap_optionblock_add_option(block, OPT_IDB_SPEED, &speed_option); - wtap_optionblock_add_option(block, OPT_IDB_TSRESOL, &tsresol_option); - wtap_optionblock_add_option(block, OPT_IDB_FILTER, &filter_option); - wtap_optionblock_add_option(block, OPT_IDB_OS, &os_option); - wtap_optionblock_add_option(block, OPT_IDB_FCSLEN, &fcslen_option); -} - -static void idb_free_mand(wtap_optionblock_t block) +static void idb_free_mand(wtap_block_t block) { guint j; - wtap_optionblock_t if_stats; + wtap_block_t if_stats; wtapng_if_descr_mandatory_t* mand = (wtapng_if_descr_mandatory_t*)block->mandatory_data; for(j = 0; j < mand->num_stat_entries; j++) { - if_stats = g_array_index(mand->interface_statistics, wtap_optionblock_t, j); - wtap_optionblock_free(if_stats); + if_stats = g_array_index(mand->interface_statistics, wtap_block_t, j); + wtap_block_free(if_stats); } if (mand->interface_statistics) g_array_free(mand->interface_statistics, TRUE); } -static void idb_copy_mand(wtap_optionblock_t dest_block, wtap_optionblock_t src_block) +static void idb_copy_mand(wtap_block_t dest_block, wtap_block_t src_block) { guint j; - wtap_optionblock_t src_if_stats, dest_if_stats; + wtap_block_t src_if_stats, dest_if_stats; 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; @@ -675,12 +902,12 @@ static void idb_copy_mand(wtap_optionblock_t dest_block, wtap_optionblock_t src_ memcpy(dest_mand, src_mand, sizeof(wtapng_if_descr_mandatory_t)); if (src_mand->num_stat_entries != 0) { - dest_mand->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t)); + dest_mand->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtap_block_t)); for (j = 0; j < src_mand->num_stat_entries; j++) { - src_if_stats = g_array_index(src_mand->interface_statistics, wtap_optionblock_t, j); - dest_if_stats = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_STATS); - wtap_optionblock_copy_options(dest_if_stats, src_if_stats); + src_if_stats = g_array_index(src_mand->interface_statistics, wtap_block_t, j); + dest_if_stats = wtap_block_create(WTAP_BLOCK_IF_STATS); + wtap_block_copy(dest_if_stats, src_if_stats); dest_mand->interface_statistics = g_array_append_val(dest_mand->interface_statistics, dest_if_stats); } } @@ -688,45 +915,228 @@ static void idb_copy_mand(wtap_optionblock_t dest_block, wtap_optionblock_t src_ void wtap_opttypes_initialize(void) { - static wtap_opt_register_t shb_block = { - "SHB", /* name */ - "Section Header Block", /* description */ - shb_create, /* create */ - NULL, /* free_mand */ - shb_copy_mand, /* copy_mand */ + static wtap_blocktype_t shb_block = { + WTAP_BLOCK_NG_SECTION, /* block_type */ + "SHB", /* name */ + "Section Header Block", /* description */ + shb_create, /* create */ + NULL, /* free_mand */ + shb_copy_mand, /* copy_mand */ + NULL /* options */ + }; + static wtap_opttype_t shb_hardware = { + "hardware", + "SHB Hardware", + WTAP_OPTTYPE_STRING, + 0, + NULL + }; + static wtap_opttype_t shb_os = { + "os", + "SHB Operating System", + WTAP_OPTTYPE_STRING, + 0, + NULL + }; + static wtap_opttype_t shb_userappl = { + "user_appl", + "SHB User Application", + WTAP_OPTTYPE_STRING, + 0, + NULL }; - static wtap_opt_register_t nrb_block = { - "NRB", /* name */ - "Name Resolution Block", /* description */ - nrb_create, /* create */ - NULL, /* free_mand */ - NULL, /* copy_mand */ + static wtap_blocktype_t idb_block = { + WTAP_BLOCK_IF_DESCR, /* block_type */ + "IDB", /* name */ + "Interface Description Block", /* description */ + idb_create, /* create */ + idb_free_mand, /* free_mand */ + idb_copy_mand, /* copy_mand */ + NULL /* options */ + }; + static wtap_opttype_t if_name = { + "name", + "IDB Name", + WTAP_OPTTYPE_STRING, + 0, + NULL + }; + static wtap_opttype_t if_description = { + "description", + "IDB Description", + WTAP_OPTTYPE_STRING, + 0, + NULL + }; + static wtap_opttype_t if_speed = { + "speed", + "IDB Speed", + WTAP_OPTTYPE_UINT64, + 0, + NULL + }; + static wtap_opttype_t if_tsresol = { + "tsresol", + "IDB Time Stamp Resolution", + WTAP_OPTTYPE_UINT8, /* XXX - signed? */ + 0, + NULL + }; + static wtap_opttype_t if_filter = { + "filter", + "IDB Filter", + WTAP_OPTTYPE_CUSTOM, + 0, + idb_filter_free + }; + static wtap_opttype_t if_os = { + "os", + "IDB Operating System", + WTAP_OPTTYPE_STRING, + 0, + NULL + }; + static wtap_opttype_t if_fcslen = { + "fcslen", + "IDB FCS Length", + WTAP_OPTTYPE_UINT8, + 0, + NULL }; - static wtap_opt_register_t isb_block = { - "ISB", /* name */ - "Interface Statistics Block", /* description */ - isb_create, /* create */ - NULL, /* free_mand */ - isb_copy_mand, /* copy_mand */ + static wtap_blocktype_t nrb_block = { + WTAP_BLOCK_NG_NRB, /* block_type */ + "NRB", /* name */ + "Name Resolution Block", /* description */ + nrb_create, /* create */ + NULL, /* free_mand */ + NULL, /* copy_mand */ + NULL /* options */ + }; + static wtap_opttype_t ns_dnsname = { + "dnsname", + "NRB DNS server name", + WTAP_OPTTYPE_STRING, + 0, + NULL + }; + static wtap_opttype_t ns_dnsIP4addr = { + "dnsIP4addr", + "NRB DNS server IPv4 address", + WTAP_OPTTYPE_IPv4, + 0, + NULL + }; + static wtap_opttype_t ns_dnsIP6addr = { + "dnsIP6addr", + "NRB DNS server IPv6 address", + WTAP_OPTTYPE_IPv6, + 0, + NULL }; - static wtap_opt_register_t idb_block = { - "IDB", /* name */ - "Interface Description Block", /* description */ - idb_create, /* create */ - idb_free_mand, /* free_mand */ - idb_copy_mand, /* copy_mand */ + static wtap_blocktype_t isb_block = { + WTAP_BLOCK_IF_STATS, /* block_type */ + "ISB", /* name */ + "Interface Statistics Block", /* description */ + isb_create, /* create */ + NULL, /* free_mand */ + isb_copy_mand, /* copy_mand */ + NULL /* options */ + }; + static wtap_opttype_t isb_starttime = { + "starttime", + "ISB Start Time", + WTAP_OPTTYPE_UINT64, + 0, + NULL + }; + static wtap_opttype_t isb_endtime = { + "endtime", + "ISB End Time", + WTAP_OPTTYPE_UINT64, + 0, + NULL + }; + static wtap_opttype_t isb_ifrecv = { + "ifrecv", + "ISB Received Packets", + WTAP_OPTTYPE_UINT64, + 0, + NULL + }; + static wtap_opttype_t isb_ifdrop = { + "ifdrop", + "ISB Dropped Packets", + WTAP_OPTTYPE_UINT64, + 0, + NULL + }; + static wtap_opttype_t isb_filteraccept = { + "filteraccept", + "ISB Packets Accepted By Filter", + WTAP_OPTTYPE_UINT64, + 0, + NULL + }; + static wtap_opttype_t isb_osdrop = { + "osdrop", + "ISB Packets Dropped By The OS", + WTAP_OPTTYPE_UINT64, + 0, + NULL + }; + static wtap_opttype_t isb_usrdeliv = { + "usrdeliv", + "ISB Packets Delivered To The User", + WTAP_OPTTYPE_UINT64, + 0, + NULL }; /* Initialize the custom block array. This is for future proofing "outside registered" block types (for NULL checking) */ - memset(block_list, 0, MAX_WTAP_OPTION_BLOCK_TYPE_VALUE*sizeof(wtap_opt_register_t*)); + memset(blocktype_list, 0, MAX_WTAP_BLOCK_TYPE_VALUE*sizeof(wtap_blocktype_t*)); num_custom_blocks = 0; - wtap_opttype_block_register(WTAP_OPTION_BLOCK_NG_SECTION, &shb_block ); - wtap_opttype_block_register(WTAP_OPTION_BLOCK_NG_NRB, &nrb_block ); - wtap_opttype_block_register(WTAP_OPTION_BLOCK_IF_STATS, &isb_block ); - wtap_opttype_block_register(WTAP_OPTION_BLOCK_IF_DESCR, &idb_block ); + /* + * Registser the SHB and the options that can appear in it. + */ + wtap_opttype_block_register(WTAP_BLOCK_NG_SECTION, &shb_block); + wtap_opttype_option_register(&shb_block, OPT_SHB_HARDWARE, &shb_hardware); + wtap_opttype_option_register(&shb_block, OPT_SHB_OS, &shb_os); + wtap_opttype_option_register(&shb_block, OPT_SHB_USERAPPL, &shb_userappl); + + /* + * Register the IDB and the options that can appear in it. + */ + wtap_opttype_block_register(WTAP_BLOCK_IF_DESCR, &idb_block); + wtap_opttype_option_register(&idb_block, OPT_IDB_NAME, &if_name); + wtap_opttype_option_register(&idb_block, OPT_IDB_DESCR, &if_description); + wtap_opttype_option_register(&idb_block, OPT_IDB_SPEED, &if_speed); + wtap_opttype_option_register(&idb_block, OPT_IDB_TSRESOL, &if_tsresol); + wtap_opttype_option_register(&idb_block, OPT_IDB_FILTER, &if_filter); + wtap_opttype_option_register(&idb_block, OPT_IDB_OS, &if_os); + wtap_opttype_option_register(&idb_block, OPT_IDB_FCSLEN, &if_fcslen); + + /* + * Register the NRB and the options that can appear in it. + */ + wtap_opttype_block_register(WTAP_BLOCK_NG_NRB, &nrb_block); + wtap_opttype_option_register(&nrb_block, OPT_NS_DNSNAME, &ns_dnsname); + wtap_opttype_option_register(&nrb_block, OPT_NS_DNSIP4ADDR, &ns_dnsIP4addr); + wtap_opttype_option_register(&nrb_block, OPT_NS_DNSIP6ADDR, &ns_dnsIP6addr); + + /* + * Register the ISB and the options that can appear in it. + */ + wtap_opttype_block_register(WTAP_BLOCK_IF_STATS, &isb_block); + wtap_opttype_option_register(&isb_block, OPT_ISB_STARTTIME, &isb_starttime); + wtap_opttype_option_register(&isb_block, OPT_ISB_ENDTIME, &isb_endtime); + wtap_opttype_option_register(&isb_block, OPT_ISB_IFRECV, &isb_ifrecv); + wtap_opttype_option_register(&isb_block, OPT_ISB_IFDROP, &isb_ifdrop); + wtap_opttype_option_register(&isb_block, OPT_ISB_FILTERACCEPT, &isb_filteraccept); + wtap_opttype_option_register(&isb_block, OPT_ISB_OSDROP, &isb_osdrop); + wtap_opttype_option_register(&isb_block, OPT_ISB_USRDELIV, &isb_usrdeliv); } diff --git a/wiretap/wtap_opttypes.h b/wiretap/wtap_opttypes.h index 120e167c64..688de52aa5 100644 --- a/wiretap/wtap_opttypes.h +++ b/wiretap/wtap_opttypes.h @@ -24,6 +24,8 @@ #include "ws_symbol_export.h" +#include + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -31,7 +33,7 @@ extern "C" { /* * We use the pcapng option codes for option type values. */ -#define OPT_EOFOPT 0x0000 /**< Appears in pcapng files, but not in option blocks. */ +#define OPT_EOFOPT 0x0000 /**< Appears in pcapng files, but not in blocks. */ #define OPT_COMMENT 0x0001 /**< NULL if not available */ /* Section Header block (SHB) */ @@ -109,6 +111,10 @@ extern "C" { * second offsets be useful for highly syncronized capture systems? */ +#define OPT_NS_DNSNAME 2 +#define OPT_NS_DNSIP4ADDR 3 +#define OPT_NS_DNSIP6ADDR 4 + #define OPT_ISB_STARTTIME 0x0002 #define OPT_ISB_ENDTIME 0x0003 #define OPT_ISB_IFRECV 0x0004 @@ -117,64 +123,73 @@ extern "C" { #define OPT_ISB_OSDROP 0x0007 #define OPT_ISB_USRDELIV 0x0008 -struct wtap_optionblock; -typedef struct wtap_optionblock *wtap_optionblock_t; +struct wtap_block; +typedef struct wtap_block *wtap_block_t; -/* Currently supported option blocks */ +/* + * Currently supported blocks; these are not the pcapng block type values + * for them, they're identifiers used internally. + */ typedef enum { - WTAP_OPTION_BLOCK_IF_DESCR = 0, - WTAP_OPTION_BLOCK_IF_STATS, - WTAP_OPTION_BLOCK_NG_SECTION, - WTAP_OPTION_BLOCK_NG_NRB, - WTAP_OPTION_BLOCK_END_OF_LIST -} wtap_optionblock_type_t; + WTAP_BLOCK_NG_SECTION = 0, + WTAP_BLOCK_IF_DESCR, + WTAP_BLOCK_NG_NRB, + WTAP_BLOCK_IF_STATS, + WTAP_BLOCK_END_OF_LIST +} wtap_block_type_t; /* Currently supported option types */ typedef enum { WTAP_OPTTYPE_UINT8, WTAP_OPTTYPE_UINT64, WTAP_OPTTYPE_STRING, + WTAP_OPTTYPE_IPv4, + WTAP_OPTTYPE_IPv6, 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_NO_SUCH_OPTION = -1, + WTAP_OPTTYPE_NOT_FOUND = -2, + WTAP_OPTTYPE_TYPE_MISMATCH = -3, + WTAP_OPTTYPE_NUMBER_MISMATCH = -4, + WTAP_OPTTYPE_ALREADY_EXISTS = -5, } 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; }; +/* + * Structure describing a value of an option. + */ typedef union { guint8 uint8val; guint64 uint64val; + guint32 ipv4val; /* network byte order */ + struct e_in6_addr ipv6val; char *stringval; struct wtap_opttype_custom customval; -} wtap_option_type; +} wtap_optval_t; -struct wtap_dumper; +/* + * Structure describing an option in a block. + */ +typedef struct { + guint option_id; /**< option code for the option */ + wtap_optval_t value; /**< value */ +} wtap_option_t; -typedef void (*wtap_block_create_func)(wtap_optionblock_t block); -typedef void (*wtap_mand_free_func)(wtap_optionblock_t block); -typedef void (*wtap_mand_copy_func)(wtap_optionblock_t dest_block, wtap_optionblock_t src_block); +struct wtap_dumper; -typedef struct wtap_optblock_reg { - const char *name; /**< name of option */ - const char *description; /**< human-readable description of option */ - wtap_opttype_e type; /**< type of that option */ - wtap_option_type option; /**< pointer to variable storing the value */ - wtap_option_type default_val; /**< the default value of the option */ -} wtap_optblock_reg_t; +typedef void (*wtap_block_create_func)(wtap_block_t block); +typedef void (*wtap_mand_free_func)(wtap_block_t block); +typedef void (*wtap_mand_copy_func)(wtap_block_t dest_block, wtap_block_t src_block); -/** Initialize option block types. +/** Initialize block types. * * This is currently just a placeholder as nothing needs to be * initialized yet. Should handle "registration" when code is @@ -182,76 +197,96 @@ typedef struct wtap_optblock_reg { */ WS_DLL_PUBLIC void wtap_opttypes_initialize(void); -/** Create an option block by type +/** Create a block by type * - * Return a newly allocated option block with default options provided + * Return a newly allocated block with default options provided * - * @param[in] block_type Option block type to be created - * @return Newly allocated option block + * @param[in] block_type Block type to be created + * @return Newly allocated block */ -WS_DLL_PUBLIC wtap_optionblock_t wtap_optionblock_create(int block_type); +WS_DLL_PUBLIC wtap_block_t wtap_block_create(wtap_block_type_t block_type); -/** Free an option block +/** Free a block * - * Needs to be called to clean up any allocated option block + * Needs to be called to clean up any allocated block * * @param[in] block Block to be freed */ -WS_DLL_PUBLIC void wtap_optionblock_free(wtap_optionblock_t block); +WS_DLL_PUBLIC void wtap_block_free(wtap_block_t block); -/** Free an array of option blocks +/** Free an array of blocks * - * Needs to be called to clean up option blocks allocated + * Needs to be called to clean up blocks allocated * through GArray (for multiple blocks of same type) * Includes freeing the GArray * * @param[in] block_array Array of blocks to be freed */ -WS_DLL_PUBLIC void wtap_optionblock_array_free(GArray* block_array); +WS_DLL_PUBLIC void wtap_block_array_free(GArray* block_array); -/** Provide mandatory data of an option block +/** Provide mandatory data of a block * * @param[in] block Block from which to retrieve mandatory data - * @return Option block mandatory data. Structure varies based on option block type + * @return Block mandatory data. Structure varies based on block type */ -WS_DLL_PUBLIC void* wtap_optionblock_get_mandatory_data(wtap_optionblock_t block); +WS_DLL_PUBLIC void* wtap_block_get_mandatory_data(wtap_block_t block); -/** Add an option to the option block +/** Add UINT8 option value to a block * - * @param[in] block Block to which to add option + * @param[in] block Block to which to add the option * @param[in] option_id Identifier value for option - * @param[in] option structure explaining it + * @param[in] value Value of option * @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful, * error code otherwise */ WS_DLL_PUBLIC wtap_opttype_return_val -wtap_optionblock_add_option(wtap_optionblock_t block, guint option_id, wtap_optblock_reg_t* option); +wtap_block_add_uint8_option(wtap_block_t block, guint option_id, guint8 value); -/** Set string option value in an option block +/** Set UINT8 option value in a block * * @param[in] block Block in which to set the option value * @param[in] option_id Identifier value for option * @param[in] value New value of option - * @param[in] value_length Maximum length of string to copy. * @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful, * error code otherwise */ WS_DLL_PUBLIC wtap_opttype_return_val -wtap_optionblock_set_option_string(wtap_optionblock_t block, guint option_id, char* value, gsize value_length); +wtap_block_set_uint8_option_value(wtap_block_t block, guint option_id, guint8 value); + +/** Get UINT8 option value from a block + * + * @param[in] block Block from which to get the option value + * @param[in] option_id Identifier value for option + * @param[out] value Returned value of option + * @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful, + * error code otherwise + */ +WS_DLL_PUBLIC wtap_opttype_return_val +wtap_block_get_uint8_option_value(wtap_block_t block, guint option_id, guint8* value) G_GNUC_WARN_UNUSED_RESULT; + +/** Add UINT64 option value to a block + * + * @param[in] block Block to which to add the option + * @param[in] option_id Identifier value for option + * @param[in] value Value of option + * @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful, + * error code otherwise + */ +WS_DLL_PUBLIC wtap_opttype_return_val +wtap_block_add_uint64_option(wtap_block_t block, guint option_id, guint64 value); -/** Set string option value in an option block to a printf-formatted string +/** Set UINT64 option value in a block * * @param[in] block Block in which to set the option value * @param[in] option_id Identifier value for option - * @param[in] format printf-like format string + * @param[in] value New value of option * @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful, * error code otherwise */ WS_DLL_PUBLIC wtap_opttype_return_val -wtap_optionblock_set_option_string_format(wtap_optionblock_t block, guint option_id, const char *format, ...) - G_GNUC_PRINTF(3,4); +wtap_block_set_uint64_option_value(wtap_block_t block, guint option_id, guint64 value); -/** Get string option value from an option block +/** Get UINT64 option value from a block * * @param[in] block Block from which to get the option value * @param[in] option_id Identifier value for option @@ -260,20 +295,20 @@ wtap_optionblock_set_option_string_format(wtap_optionblock_t block, guint option * error code otherwise */ WS_DLL_PUBLIC wtap_opttype_return_val -wtap_optionblock_get_option_string(wtap_optionblock_t block, guint option_id, char** value); +wtap_block_get_uint64_option_value(wtap_block_t block, guint option_id, guint64* value) G_GNUC_WARN_UNUSED_RESULT; -/** Get array of string option values from an option block +/** Add IPv4 address option value to a block * - * @param[in] block Block from which to get option values + * @param[in] block Block to which to add the option * @param[in] option_id Identifier value for option - * @param[out] value Returned GArray of option values + * @param[in] value Value of option * @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful, * error code otherwise */ WS_DLL_PUBLIC wtap_opttype_return_val -wtap_optionblock_get_string_options(wtap_optionblock_t block, guint option_id, GArray **value); +wtap_block_add_ipv4_option(wtap_block_t block, guint option_id, guint32 value); -/** Set UINT64 option value in an option block +/** Set IPv4 option value in a block * * @param[in] block Block in which to set the option value * @param[in] option_id Identifier value for option @@ -282,9 +317,9 @@ wtap_optionblock_get_string_options(wtap_optionblock_t block, guint option_id, G * error code otherwise */ WS_DLL_PUBLIC wtap_opttype_return_val -wtap_optionblock_set_option_uint64(wtap_optionblock_t block, guint option_id, guint64 value); +wtap_block_set_ipv4_option_value(wtap_block_t block, guint option_id, guint32 value); -/** Get UINT64 option value from an option block +/** Get IPv4 option value from a block * * @param[in] block Block from which to get the option value * @param[in] option_id Identifier value for option @@ -293,9 +328,20 @@ wtap_optionblock_set_option_uint64(wtap_optionblock_t block, guint option_id, gu * error code otherwise */ WS_DLL_PUBLIC wtap_opttype_return_val -wtap_optionblock_get_option_uint64(wtap_optionblock_t block, guint option_id, guint64* value); +wtap_block_get_ipv4_option_value(wtap_block_t block, guint option_id, guint32* value) G_GNUC_WARN_UNUSED_RESULT; + +/** Add IPv6 address option value to a block + * + * @param[in] block Block to which to add the option + * @param[in] option_id Identifier value for option + * @param[in] value Value of option + * @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful, + * error code otherwise + */ +WS_DLL_PUBLIC wtap_opttype_return_val +wtap_block_add_ipv6_option(wtap_block_t block, guint option_id, struct e_in6_addr *value); -/** Set UINT8 option value in an option block +/** Set IPv6 option value in a block * * @param[in] block Block in which to set the option value * @param[in] option_id Identifier value for option @@ -304,9 +350,9 @@ wtap_optionblock_get_option_uint64(wtap_optionblock_t block, guint option_id, gu * error code otherwise */ WS_DLL_PUBLIC wtap_opttype_return_val -wtap_optionblock_set_option_uint8(wtap_optionblock_t block, guint option_id, guint8 value); +wtap_block_set_ipv6_option_value(wtap_block_t block, guint option_id, struct e_in6_addr *value); -/** Get UINT8 option value from an option block +/** Get IPv6 option value from a block * * @param[in] block Block from which to get the option value * @param[in] option_id Identifier value for option @@ -315,9 +361,105 @@ wtap_optionblock_set_option_uint8(wtap_optionblock_t block, guint option_id, gui * error code otherwise */ WS_DLL_PUBLIC wtap_opttype_return_val -wtap_optionblock_get_option_uint8(wtap_optionblock_t block, guint option_id, guint8* value); +wtap_block_get_ipv6_option_value(wtap_block_t block, guint option_id, struct e_in6_addr* value) G_GNUC_WARN_UNUSED_RESULT; + +/** Add a string option to a block + * + * @param[in] block Block to which to add the option + * @param[in] option_id Identifier value for option + * @param[in] value Value of option + * @param[in] value_length Maximum length of string to copy. + * @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful, + * error code otherwise + */ +WS_DLL_PUBLIC wtap_opttype_return_val +wtap_block_add_string_option(wtap_block_t block, guint option_id, const char *value, gsize value_length); + +/** Add a string option to a block witha printf-formatted string as its value + * + * @param[in] block Block to which to add the option + * @param[in] option_id Identifier value for option + * @param[in] format printf-like format string + * @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful, + * error code otherwise + */ +WS_DLL_PUBLIC wtap_opttype_return_val +wtap_block_add_string_option_format(wtap_block_t block, guint option_id, const char *format, ...) + G_GNUC_PRINTF(3,4); + +/** Set string option value in a block + * + * @param[in] block Block in which to set the option value + * @param[in] option_id Identifier value for option + * @param[in] value New value of option + * @param[in] value_length Maximum length of string to copy. + * @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful, + * error code otherwise + */ +WS_DLL_PUBLIC wtap_opttype_return_val +wtap_block_set_string_option_value(wtap_block_t block, guint option_id, const char* value, gsize value_length); + +/** Set string option value for nth instance of a particular option in a block + * + * @param[in] block Block in which to set the option value + * @param[in] option_id Identifier value for option + * @param[in] idx Instance number of option with that ID + * @param[in] value New value of option + * @param[in] value_length Maximum length of string to copy. + * @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful, + * error code otherwise + */ +WS_DLL_PUBLIC wtap_opttype_return_val +wtap_block_set_nth_string_option_value(wtap_block_t block, guint option_id, guint idx, const char* value, gsize value_length); + +/** Set string option value in a block to a printf-formatted string + * + * @param[in] block Block in which to set the option value + * @param[in] option_id Identifier value for option + * @param[in] format printf-like format string + * @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful, + * error code otherwise + */ +WS_DLL_PUBLIC wtap_opttype_return_val +wtap_block_set_string_option_value_format(wtap_block_t block, guint option_id, const char *format, ...) + G_GNUC_PRINTF(3,4); + +/** Get string option value from a block + * + * @param[in] block Block from which to get the option value + * @param[in] option_id Identifier value for option + * @param[out] value Returned value of option + * @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful, + * error code otherwise + */ +WS_DLL_PUBLIC wtap_opttype_return_val +wtap_block_get_string_option_value(wtap_block_t block, guint option_id, char** value) G_GNUC_WARN_UNUSED_RESULT; + +/** Get string option value for nth instance of a particular option in a block + * + * @param[in] block Block from which to get the option value + * @param[in] option_id Identifier value for option + * @param[in] idx Instance number of option with that ID + * @param[out] value Returned value of option + * @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful, + * error code otherwise + */ +WS_DLL_PUBLIC wtap_opttype_return_val +wtap_block_get_nth_string_option_value(wtap_block_t block, guint option_id, guint idx, char** value) G_GNUC_WARN_UNUSED_RESULT; + +/** Add a "custom" option value to a block + * + * @param[in] block Block to which to add the option + * @param[in] option_id Identifier value for option + * @param[in] value Value of option + * @param[in] value_size Size of value + * @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful, + * error code otherwise + */ +WS_DLL_PUBLIC wtap_opttype_return_val +wtap_block_add_custom_option(wtap_block_t block, guint option_id, void* value, size_t value_size); -/** Set a "custom" option value in an option block +/** Set a "custom" option value in a block * * @param[in] block Block in which to set the option value * @param[in] option_id Identifier value for option @@ -326,9 +468,9 @@ wtap_optionblock_get_option_uint8(wtap_optionblock_t block, guint option_id, gui * error code otherwise */ WS_DLL_PUBLIC wtap_opttype_return_val -wtap_optionblock_set_option_custom(wtap_optionblock_t block, guint option_id, void* value); +wtap_block_set_custom_option_value(wtap_block_t block, guint option_id, void* value); -/** Get a "custom" option value from an option block +/** Get a "custom" option value from a block * * @param[in] block Block from which to get the option value * @param[in] option_id Identifier value for option @@ -337,9 +479,9 @@ wtap_optionblock_set_option_custom(wtap_optionblock_t block, guint option_id, vo * error code otherwise */ WS_DLL_PUBLIC wtap_opttype_return_val -wtap_optionblock_get_option_custom(wtap_optionblock_t block, guint option_id, void** value); +wtap_block_get_custom_option_value(wtap_block_t block, guint option_id, void** value) G_GNUC_WARN_UNUSED_RESULT; -/** Copy an option block to another. +/** Copy a 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 @@ -347,11 +489,11 @@ wtap_optionblock_get_option_custom(wtap_optionblock_t block, guint option_id, vo * @param[in] dest_block Block to be copied to * @param[in] src_block Block to be copied from */ -WS_DLL_PUBLIC void wtap_optionblock_copy_options(wtap_optionblock_t dest_block, wtap_optionblock_t src_block); +WS_DLL_PUBLIC void wtap_block_copy(wtap_block_t dest_block, wtap_block_t src_block); -typedef void (*wtap_optionblock_foreach_func)(wtap_optionblock_t block, guint option_id, wtap_opttype_e option_type, wtap_option_type* option, void* user_data); -WS_DLL_PUBLIC void wtap_optionblock_foreach_option(wtap_optionblock_t block, wtap_optionblock_foreach_func func, void* user_data); +typedef void (*wtap_block_foreach_func)(wtap_block_t block, guint option_id, wtap_opttype_e option_type, wtap_optval_t *option, void *user_data); +WS_DLL_PUBLIC void wtap_block_foreach_option(wtap_block_t block, wtap_block_foreach_func func, void* user_data); WS_DLL_PUBLIC int wtap_opttype_register_custom_block_type(const char* name, const char* description, wtap_block_create_func create, wtap_mand_free_func free_mand, wtap_mand_copy_func copy_mand); -- cgit v1.2.3