Refactor wiretap option block types into a registration system.

Also required mergecap to look for plugins to initialize wiretap option blocks.

Change-Id: I4208d1028dd0f94f185393801d72025329266cb7
Reviewed-on: https://code.wireshark.org/review/14300
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
Michael Mann 2016-03-02 09:13:08 -05:00
parent 28b76dbb9e
commit d7de3515db
3 changed files with 304 additions and 190 deletions

View File

@ -49,11 +49,18 @@
#include <wsutil/clopts_common.h>
#include <wsutil/cmdarg_err.h>
#include <wsutil/crash_info.h>
#include <wsutil/filesystem.h>
#include <wsutil/file_util.h>
#include <wsutil/strnatcmp.h>
#include <wsutil/ws_diag_control.h>
#include <wsutil/ws_version_info.h>
#ifdef HAVE_PLUGINS
#include <wsutil/plugins.h>
#endif
#include <wsutil/report_err.h>
#include <wiretap/merge.h>
#include <wiretap/pcap-encap.h>
@ -125,6 +132,19 @@ string_elem_print(gpointer data, gpointer not_used _U_)
((struct string_elem *)data)->lstr);
}
#ifdef HAVE_PLUGINS
/*
* Don't report failures to load plugins because most (non-wiretap) plugins
* *should* fail to load (because we're not linked against libwireshark and
* dissector plugins need libwireshark).
*/
static void
failure_message(const char *msg_format _U_, va_list ap _U_)
{
return;
}
#endif
static void
list_capture_types(void) {
int i;
@ -279,6 +299,10 @@ main(int argc, char *argv[])
gboolean use_stdout = FALSE;
merge_progress_callback_t cb;
#ifdef HAVE_PLUGINS
char *init_progfile_dir_error;
#endif
cmdarg_err_init(mergecap_cmdarg_err, mergecap_cmdarg_err_cont);
#ifdef _WIN32
@ -300,6 +324,25 @@ main(int argc, char *argv[])
"%s",
get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
#ifdef HAVE_PLUGINS
if ((init_progfile_dir_error = init_progfile_dir(argv[0], main))) {
g_warning("captype: init_progfile_dir(): %s", init_progfile_dir_error);
g_free(init_progfile_dir_error);
} else {
/* Register all the plugin types we have. */
wtap_register_plugin_types(); /* Types known to libwiretap */
init_report_err(failure_message,NULL,NULL,NULL);
/* Scan for plugins. This does *not* call their registration routines;
that's done later. */
scan_plugins();
/* Register all libwiretap plugin modules. */
register_all_wiretap_modules();
}
#endif
/* Process the options first */
while ((opt = getopt_long(argc, argv, "aF:hI:s:vVw:", long_options, NULL)) != -1) {

View File

@ -28,102 +28,75 @@
#include "wtap-int.h"
#include "pcapng.h"
struct wtap_optionblock
typedef void (*wtap_block_create_func)(wtap_optionblock_t block);
typedef void (*wtap_mand_free_func)(wtap_optionblock_t block);
typedef void (*wtap_mand_copy_func)(wtap_optionblock_t dest_block, wtap_optionblock_t src_block);
typedef struct wtap_opt_register
{
const char *name; /**< name of block */
const char *description; /**< human-readable description of block */
wtap_optionblock_type_t type;
wtap_block_create_func create;
wtap_mand_free_func free_mand;
wtap_mand_copy_func copy_mand;
} wtap_opt_register_t;
struct wtap_optionblock
{
wtap_opt_register_t* info;
void* mandatory_data;
GArray* options;
};
void wtap_opttypes_initialize(void)
/* Keep track of wtap_opt_register_t's via their id number */
static wtap_opt_register_t* block_list[WTAP_OPTION_BLOCK_MAX_TYPE];
static void wtap_opttype_block_register(int block_type, wtap_opt_register_t *block)
{
/* Check input */
g_assert(block_type < WTAP_OPTION_BLOCK_MAX_TYPE);
/* Don't re-register. */
g_assert(block_list[block_type] == NULL);
/* Sanity check */
g_assert(block->name);
g_assert(block->description);
g_assert(block->create);
block_list[block_type] = block;
}
static void wtap_if_descr_filter_free(void* data)
void* wtap_optionblock_get_mandatory_data(wtap_optionblock_t block)
{
wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)data;
g_free(filter->if_filter_str);
g_free(filter->if_filter_bpf_bytes);
return block->mandatory_data;
}
static wtap_opttype_t* wtap_optionblock_get_option(wtap_optionblock_t block, guint option_id)
{
guint i;
wtap_opttype_t* opttype = NULL;
for (i = 0; i < block->options->len; i++)
{
opttype = g_array_index(block->options, wtap_opttype_t*, i);
if (opttype->number == option_id)
return opttype;
}
return NULL;
}
wtap_optionblock_t wtap_optionblock_create(wtap_optionblock_type_t block_type)
{
wtap_optionblock_t block = NULL;
wtap_optionblock_t block;
switch(block_type)
{
case WTAP_OPTION_BLOCK_NG_SECTION:
{
wtapng_mandatory_section_t* section_mand;
if (block_type >= WTAP_OPTION_BLOCK_MAX_TYPE)
return NULL;
block = g_new(struct wtap_optionblock, 1);
block->name = "SHB";
block->description = "Section Header block";
block->type = WTAP_OPTION_BLOCK_NG_SECTION;
block->mandatory_data = g_new(wtapng_mandatory_section_t, 1);
section_mand = (wtapng_mandatory_section_t*)block->mandatory_data;
section_mand->section_length = -1;
block->options = g_array_new(FALSE, FALSE, sizeof(wtap_opttype_t*));
wtap_optionblock_add_option_string(block, OPT_COMMENT, "opt_comment", "Optional comment", NULL, NULL);
wtap_optionblock_add_option_string(block, OPT_SHB_HARDWARE, "hardware", "SBH Hardware", NULL, NULL);
wtap_optionblock_add_option_string(block, OPT_SHB_OS, "os", "SBH Operating System", NULL, NULL);
wtap_optionblock_add_option_string(block, OPT_SHB_USERAPPL, "user_appl", "SBH User Application", NULL, NULL);
}
break;
case WTAP_OPTION_BLOCK_NG_NRB:
block = g_new(struct wtap_optionblock, 1);
block->name = "NRB";
block->description = "Name Resolution Block";
block->type = WTAP_OPTION_BLOCK_NG_NRB;
block->mandatory_data = NULL;
block->options = g_array_new(FALSE, FALSE, sizeof(wtap_opttype_t*));
wtap_optionblock_add_option_string(block, OPT_COMMENT, "opt_comment", "Optional comment", NULL, NULL);
break;
case WTAP_OPTION_BLOCK_IF_STATS:
block = g_new(struct wtap_optionblock, 1);
block->name = "ISB";
block->description = "Interface Statistics Block";
block->type = WTAP_OPTION_BLOCK_IF_STATS;
block->mandatory_data = g_new0(wtapng_if_stats_mandatory_t, 1);
block->options = g_array_new(FALSE, FALSE, sizeof(wtap_opttype_t*));
wtap_optionblock_add_option_string(block, OPT_COMMENT, "opt_comment", "Optional comment", NULL, NULL);
wtap_optionblock_add_option_uint64(block, OPT_ISB_STARTTIME, "start_time", "Start Time", 0, 0);
wtap_optionblock_add_option_uint64(block, OPT_ISB_ENDTIME, "end_time", "End Time", 0, 0);
wtap_optionblock_add_option_uint64(block, OPT_ISB_IFRECV, "recv", "Receive Packets", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
wtap_optionblock_add_option_uint64(block, OPT_ISB_IFDROP, "drop", "Dropped Packets", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
wtap_optionblock_add_option_uint64(block, OPT_ISB_FILTERACCEPT, "filter_accept", "Filter Accept", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
wtap_optionblock_add_option_uint64(block, OPT_ISB_OSDROP, "os_drop", "OS Dropped Packets", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
wtap_optionblock_add_option_uint64(block, OPT_ISB_USRDELIV, "user_deliv", "User Delivery", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
break;
case WTAP_OPTION_BLOCK_IF_DESCR:
{
wtapng_if_descr_filter_t default_filter;
memset(&default_filter, 0, sizeof(default_filter));
block = g_new(struct wtap_optionblock, 1);
block->name = "IDB";
block->description = "Interface Description Block";
block->type = WTAP_OPTION_BLOCK_IF_DESCR;
block->mandatory_data = g_new0(wtapng_if_descr_mandatory_t, 1);
block->options = g_array_new(FALSE, FALSE, sizeof(wtap_opttype_t*));
wtap_optionblock_add_option_string(block, OPT_COMMENT, "opt_comment", "Optional comment", NULL, NULL);
wtap_optionblock_add_option_string(block, OPT_IDB_NAME, "name", "Device name", NULL, NULL);
wtap_optionblock_add_option_string(block, OPT_IDB_DESCR, "description", "Device description", NULL, NULL);
wtap_optionblock_add_option_uint64(block, OPT_IDB_SPEED, "speed", "Interface speed (in bps)", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
wtap_optionblock_add_option_uint8(block, OPT_IDB_TSRESOL, "ts_resolution", "Resolution of timestamps", 6, 6);
wtap_optionblock_add_option_custom(block, OPT_IDB_FILTER, "filter", "Filter string", &default_filter, &default_filter, sizeof(wtapng_if_descr_filter_t), wtap_if_descr_filter_free);
wtap_optionblock_add_option_string(block, OPT_IDB_OS, "os", "Operating System", NULL, NULL);
wtap_optionblock_add_option_uint8(block, OPT_IDB_FCSLEN, "fcslen", "FCS Length", -1, -1);
}
break;
}
block = g_new(struct wtap_optionblock, 1);
block->info = block_list[block_type];
block->info->create(block);
return block;
}
@ -155,49 +128,81 @@ static void wtap_optionblock_free_options(wtap_optionblock_t block)
void wtap_optionblock_free(wtap_optionblock_t block)
{
guint j;
wtap_optionblock_t if_stats;
if (block != NULL)
{
/* Need special consideration for freeing of the interface_statistics member */
if (block->type == WTAP_OPTION_BLOCK_IF_DESCR)
{
wtapng_if_descr_mandatory_t* mand = (wtapng_if_descr_mandatory_t*)block->mandatory_data;
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 (mand->interface_statistics)
g_array_free(mand->interface_statistics, TRUE);
}
if (block->info->free_mand != NULL)
block->info->free_mand(block);
g_free(block->mandatory_data);
wtap_optionblock_free_options(block);
g_array_free(block->options, FALSE);
if (block->options != NULL)
g_array_free(block->options, FALSE);
g_free(block);
}
}
void* wtap_optionblock_get_mandatory_data(wtap_optionblock_t block)
{
return block->mandatory_data;
}
static wtap_opttype_t* wtap_optionblock_get_option(wtap_optionblock_t block, guint option_id)
void wtap_optionblock_copy_options(wtap_optionblock_t dest_block, wtap_optionblock_t src_block)
{
guint i;
wtap_opttype_t* opttype = NULL;
wtap_opttype_t *dest_opttype, *src_opttype;
for (i = 0; i < block->options->len; i++)
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->options->len; i++)
{
opttype = g_array_index(block->options, wtap_opttype_t*, i);
if (opttype->number == option_id)
return opttype;
src_opttype = g_array_index(src_block->options, wtap_opttype_t*, i);
dest_opttype = wtap_optionblock_get_option(dest_block, src_opttype->number);
if (dest_opttype == NULL)
{
/* Option doesn't exist, add it */
switch(src_opttype->type)
{
case WTAP_OPTTYPE_UINT8:
wtap_optionblock_add_option_uint8(dest_block, src_opttype->number, src_opttype->name, src_opttype->description,
src_opttype->option.uint8val, src_opttype->default_val.uint8val);
break;
case WTAP_OPTTYPE_UINT64:
wtap_optionblock_add_option_uint64(dest_block, src_opttype->number, src_opttype->name, src_opttype->description,
src_opttype->option.uint64val, src_opttype->default_val.uint64val);
break;
case WTAP_OPTTYPE_STRING:
wtap_optionblock_add_option_string(dest_block, src_opttype->number, src_opttype->name, src_opttype->description,
src_opttype->option.stringval, src_opttype->default_val.stringval);
break;
case WTAP_OPTTYPE_CUSTOM:
wtap_optionblock_add_option_custom(dest_block, src_opttype->number, src_opttype->name, src_opttype->description,
src_opttype->option.customval.data, src_opttype->default_val.customval.data,
src_opttype->option.customval.size, src_opttype->option.customval.free_func);
break;
}
}
else
{
/* Option exists, replace it */
switch(src_opttype->type)
{
case WTAP_OPTTYPE_UINT8:
dest_opttype->option.uint8val = src_opttype->option.uint8val;
break;
case WTAP_OPTTYPE_UINT64:
dest_opttype->option.uint64val = src_opttype->option.uint64val;
break;
case WTAP_OPTTYPE_STRING:
g_free(dest_opttype->option.stringval);
dest_opttype->option.stringval = g_strdup(src_opttype->option.stringval);
break;
case WTAP_OPTTYPE_CUSTOM:
dest_opttype->option.customval.free_func(dest_opttype->option.customval.data);
g_free(dest_opttype->option.customval.data);
dest_opttype->option.customval.data = g_memdup(src_opttype->option.customval.data, src_opttype->option.customval.size);
break;
}
}
}
return NULL;
}
int wtap_optionblock_add_option_string(wtap_optionblock_t block, guint option_id,
@ -418,94 +423,159 @@ int wtap_optionblock_get_option_custom(wtap_optionblock_t block, guint option_id
return WTAP_OPTTYPE_SUCCESS;
}
void wtap_optionblock_copy_options(wtap_optionblock_t dest_block, wtap_optionblock_t src_block)
static void shb_create(wtap_optionblock_t block)
{
guint i;
wtap_opttype_t *dest_opttype, *src_opttype;
wtapng_mandatory_section_t* section_mand = g_new(wtapng_mandatory_section_t, 1);
switch(src_block->type)
{
case WTAP_OPTION_BLOCK_NG_SECTION:
memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_mandatory_section_t));
break;
case WTAP_OPTION_BLOCK_NG_NRB:
/* No mandatory data */
break;
case WTAP_OPTION_BLOCK_IF_STATS:
memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_if_stats_mandatory_t));
break;
case WTAP_OPTION_BLOCK_IF_DESCR:
{
wtapng_if_descr_mandatory_t *src_mand = (wtapng_if_descr_mandatory_t*)src_block->mandatory_data,
*dest_mand = (wtapng_if_descr_mandatory_t*)dest_block->mandatory_data;
/* Need special consideration for copying of the interface_statistics member */
if (dest_mand->num_stat_entries != 0)
{
g_array_free(dest_mand->interface_statistics, TRUE);
}
section_mand->section_length = -1;
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_append_vals(dest_mand->interface_statistics, src_mand->interface_statistics->data, src_mand->interface_statistics->len);
}
}
break;
block->mandatory_data = section_mand;
block->options = g_array_new(FALSE, FALSE, sizeof(wtap_opttype_t*));
wtap_optionblock_add_option_string(block, OPT_COMMENT, "opt_comment", "Optional comment", NULL, NULL);
wtap_optionblock_add_option_string(block, OPT_SHB_HARDWARE, "hardware", "SBH Hardware", NULL, NULL);
wtap_optionblock_add_option_string(block, OPT_SHB_OS, "os", "SBH Operating System", NULL, NULL);
wtap_optionblock_add_option_string(block, OPT_SHB_USERAPPL, "user_appl", "SBH User Application", NULL, NULL);
}
static void shb_copy_mand(wtap_optionblock_t dest_block, wtap_optionblock_t src_block)
{
memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_mandatory_section_t));
}
static void nrb_create(wtap_optionblock_t block)
{
block->mandatory_data = NULL;
block->options = g_array_new(FALSE, FALSE, sizeof(wtap_opttype_t*));
wtap_optionblock_add_option_string(block, OPT_COMMENT, "opt_comment", "Optional comment", NULL, NULL);
}
static void isb_create(wtap_optionblock_t block)
{
block->mandatory_data = g_new0(wtapng_if_stats_mandatory_t, 1);
block->options = g_array_new(FALSE, FALSE, sizeof(wtap_opttype_t*));
wtap_optionblock_add_option_string(block, OPT_COMMENT, "opt_comment", "Optional comment", NULL, NULL);
wtap_optionblock_add_option_uint64(block, OPT_ISB_STARTTIME, "start_time", "Start Time", 0, 0);
wtap_optionblock_add_option_uint64(block, OPT_ISB_ENDTIME, "end_time", "End Time", 0, 0);
wtap_optionblock_add_option_uint64(block, OPT_ISB_IFRECV, "recv", "Receive Packets", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
wtap_optionblock_add_option_uint64(block, OPT_ISB_IFDROP, "drop", "Dropped Packets", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
wtap_optionblock_add_option_uint64(block, OPT_ISB_FILTERACCEPT, "filter_accept", "Filter Accept", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
wtap_optionblock_add_option_uint64(block, OPT_ISB_OSDROP, "os_drop", "OS Dropped Packets", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
wtap_optionblock_add_option_uint64(block, OPT_ISB_USRDELIV, "user_deliv", "User Delivery", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
}
static void isb_copy_mand(wtap_optionblock_t dest_block, wtap_optionblock_t src_block)
{
memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_if_stats_mandatory_t));
}
static void idb_filter_free(void* data)
{
wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)data;
g_free(filter->if_filter_str);
g_free(filter->if_filter_bpf_bytes);
}
static void idb_create(wtap_optionblock_t block)
{
wtapng_if_descr_filter_t default_filter;
memset(&default_filter, 0, sizeof(default_filter));
block->mandatory_data = g_new0(wtapng_if_descr_mandatory_t, 1);
block->options = g_array_new(FALSE, FALSE, sizeof(wtap_opttype_t*));
wtap_optionblock_add_option_string(block, OPT_COMMENT, "opt_comment", "Optional comment", NULL, NULL);
wtap_optionblock_add_option_string(block, OPT_IDB_NAME, "name", "Device name", NULL, NULL);
wtap_optionblock_add_option_string(block, OPT_IDB_DESCR, "description", "Device description", NULL, NULL);
wtap_optionblock_add_option_uint64(block, OPT_IDB_SPEED, "speed", "Interface speed (in bps)", G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF), G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF));
wtap_optionblock_add_option_uint8(block, OPT_IDB_TSRESOL, "ts_resolution", "Resolution of timestamps", 6, 6);
wtap_optionblock_add_option_custom(block, OPT_IDB_FILTER, "filter", "Filter string", &default_filter, &default_filter, sizeof(wtapng_if_descr_filter_t), idb_filter_free);
wtap_optionblock_add_option_string(block, OPT_IDB_OS, "os", "Operating System", NULL, NULL);
wtap_optionblock_add_option_uint8(block, OPT_IDB_FCSLEN, "fcslen", "FCS Length", -1, -1);
}
static void idb_free_mand(wtap_optionblock_t block)
{
guint j;
wtap_optionblock_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);
}
/* Copy the options. For now, don't remove any options that are in destination
* but not source.
*/
for (i = 0; i < src_block->options->len; i++)
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)
{
guint j;
wtap_optionblock_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;
/* Need special consideration for copying of the interface_statistics member */
if (dest_mand->num_stat_entries != 0)
g_array_free(dest_mand->interface_statistics, TRUE);
memcpy(dest_mand, src_mand, sizeof(wtapng_if_descr_mandatory_t));
if (src_mand->num_stat_entries != 0)
{
src_opttype = g_array_index(src_block->options, wtap_opttype_t*, i);
dest_opttype = wtap_optionblock_get_option(dest_block, src_opttype->number);
if (dest_opttype == NULL)
dest_mand->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
for (j = 0; j < src_mand->num_stat_entries; j++)
{
/* Option doesn't exist, add it */
switch(src_opttype->type)
{
case WTAP_OPTTYPE_UINT8:
wtap_optionblock_add_option_uint8(dest_block, src_opttype->number, src_opttype->name, src_opttype->description,
src_opttype->option.uint8val, src_opttype->default_val.uint8val);
break;
case WTAP_OPTTYPE_UINT64:
wtap_optionblock_add_option_uint64(dest_block, src_opttype->number, src_opttype->name, src_opttype->description,
src_opttype->option.uint64val, src_opttype->default_val.uint64val);
break;
case WTAP_OPTTYPE_STRING:
wtap_optionblock_add_option_string(dest_block, src_opttype->number, src_opttype->name, src_opttype->description,
src_opttype->option.stringval, src_opttype->default_val.stringval);
break;
case WTAP_OPTTYPE_CUSTOM:
wtap_optionblock_add_option_custom(dest_block, src_opttype->number, src_opttype->name, src_opttype->description,
src_opttype->option.customval.data, src_opttype->default_val.customval.data,
src_opttype->option.customval.size, src_opttype->option.customval.free_func);
break;
}
}
else
{
/* Option exists, replace it */
switch(src_opttype->type)
{
case WTAP_OPTTYPE_UINT8:
dest_opttype->option.uint8val = src_opttype->option.uint8val;
break;
case WTAP_OPTTYPE_UINT64:
dest_opttype->option.uint64val = src_opttype->option.uint64val;
break;
case WTAP_OPTTYPE_STRING:
g_free(dest_opttype->option.stringval);
dest_opttype->option.stringval = g_strdup(src_opttype->option.stringval);
break;
case WTAP_OPTTYPE_CUSTOM:
dest_opttype->option.customval.free_func(dest_opttype->option.customval.data);
g_free(dest_opttype->option.customval.data);
dest_opttype->option.customval.data = g_memdup(src_opttype->option.customval.data, src_opttype->option.customval.size);
break;
}
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);
dest_mand->interface_statistics = g_array_append_val(dest_mand->interface_statistics, dest_if_stats);
}
}
}
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_opt_register_t nrb_block = {
"NRB", /* name */
"Name Resolution Block", /* description */
nrb_create, /* create */
NULL, /* free_mand */
NULL, /* copy_mand */
};
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_opt_register_t idb_block = {
"IDB", /* name */
"Interface Description Block", /* description */
idb_create, /* create */
idb_free_mand, /* free_mand */
idb_copy_mand, /* copy_mand */
};
/* Initialize the block array. This is mostly for future proofing
"outside registered" block types (for NULL checking) */
memset(block_list, 0, WTAP_OPTION_BLOCK_MAX_TYPE*sizeof(wtap_opt_register_t*));
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 );
}

View File

@ -29,7 +29,8 @@ 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_NG_NRB,
WTAP_OPTION_BLOCK_MAX_TYPE
} wtap_optionblock_type_t;
/* Currently supported option types */