From 5078561b6a2ba2ba63247254a7d131ea38bcf815 Mon Sep 17 00:00:00 2001 From: Michael Mann Date: Tue, 17 May 2016 22:50:51 -0400 Subject: Add ability to add custom block types. Change-Id: I2d23148c6f8d847aacec1d25cb694793ec9bb84e Reviewed-on: https://code.wireshark.org/review/15504 Petri-Dish: Michael Mann Tested-by: Petri Dish Buildbot Reviewed-by: Michael Mann --- wiretap/wtap_opttypes.c | 50 ++++++++++++++++++++++++++++++++++++++----------- wiretap/wtap_opttypes.h | 13 +++++++++++-- 2 files changed, 50 insertions(+), 13 deletions(-) (limited to 'wiretap') diff --git a/wiretap/wtap_opttypes.c b/wiretap/wtap_opttypes.c index 2e7016b78c..fa6de1aee6 100644 --- a/wiretap/wtap_opttypes.c +++ b/wiretap/wtap_opttypes.c @@ -35,11 +35,6 @@ #define wtap_debug(...) #endif -typedef void (*wtap_block_create_func)(wtap_optionblock_t block); -typedef void (*wtap_mand_free_func)(wtap_optionblock_t block); -typedef void (*wtap_mand_copy_func)(wtap_optionblock_t dest_block, wtap_optionblock_t src_block); -typedef gboolean (*wtap_write_func)(struct wtap_dumper *wdh, wtap_optionblock_t block, int *err); - typedef struct wtap_opt_register { const char *name; /**< name of block */ @@ -73,13 +68,18 @@ struct wtap_optionblock GArray* option_values; }; +#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) + /* 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 wtap_opt_register_t* block_list[MAX_WTAP_OPTION_BLOCK_TYPE_VALUE]; +static guint num_custom_blocks; +static wtap_opt_register_t custom_block_list[MAX_WTAP_OPTION_BLOCK_CUSTOM]; 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); + g_assert(block_type < WTAP_OPTION_BLOCK_END_OF_LIST); /* Don't re-register. */ g_assert(block_list[block_type] == NULL); @@ -92,6 +92,33 @@ static void wtap_opttype_block_register(int block_type, wtap_opt_register_t *blo block_list[block_type] = block; } +int wtap_opttype_register_custom_block_type(const char* name, const char* description, wtap_block_create_func create, + wtap_write_func write_func, wtap_mand_free_func free_mand, wtap_mand_copy_func copy_mand) +{ + int block_type; + + /* Ensure valid data/functions for required fields */ + g_assert(name); + g_assert(description); + g_assert(create); + + /* This shouldn't happen, so flag it for fixing */ + g_assert(num_custom_blocks < MAX_WTAP_OPTION_BLOCK_CUSTOM); + + block_type = WTAP_OPTION_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].write = write_func; + 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]; + + num_custom_blocks++; + return block_type; +} + void* wtap_optionblock_get_mandatory_data(wtap_optionblock_t block) { return block->mandatory_data; @@ -112,11 +139,11 @@ static wtap_optblock_value_t* wtap_optionblock_get_option(wtap_optionblock_t blo return NULL; } -wtap_optionblock_t wtap_optionblock_create(wtap_optionblock_type_t block_type) +wtap_optionblock_t wtap_optionblock_create(int block_type) { wtap_optionblock_t block; - if (block_type >= WTAP_OPTION_BLOCK_MAX_TYPE) + if (block_type >= (int)(WTAP_OPTION_BLOCK_END_OF_LIST+num_custom_blocks)) return NULL; block = g_new(struct wtap_optionblock, 1); @@ -1026,9 +1053,10 @@ void wtap_opttypes_initialize(void) idb_copy_mand, /* copy_mand */ }; - /* Initialize the block array. This is mostly for future proofing + /* Initialize the custom block array. This is for future proofing "outside registered" block types (for NULL checking) */ - memset(block_list, 0, WTAP_OPTION_BLOCK_MAX_TYPE*sizeof(wtap_opt_register_t*)); + memset(block_list, 0, MAX_WTAP_OPTION_BLOCK_TYPE_VALUE*sizeof(wtap_opt_register_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 ); diff --git a/wiretap/wtap_opttypes.h b/wiretap/wtap_opttypes.h index 1b686a829c..410dcb2e32 100644 --- a/wiretap/wtap_opttypes.h +++ b/wiretap/wtap_opttypes.h @@ -33,7 +33,7 @@ typedef enum { WTAP_OPTION_BLOCK_IF_STATS, WTAP_OPTION_BLOCK_NG_SECTION, WTAP_OPTION_BLOCK_NG_NRB, - WTAP_OPTION_BLOCK_MAX_TYPE + WTAP_OPTION_BLOCK_END_OF_LIST } wtap_optionblock_type_t; /* Currently supported option types */ @@ -69,6 +69,11 @@ typedef union { struct wtap_dumper; +typedef void (*wtap_block_create_func)(wtap_optionblock_t block); +typedef void (*wtap_mand_free_func)(wtap_optionblock_t block); +typedef void (*wtap_mand_copy_func)(wtap_optionblock_t dest_block, wtap_optionblock_t src_block); +typedef gboolean (*wtap_write_func)(struct wtap_dumper *wdh, wtap_optionblock_t block, int *err); + typedef guint32 (*wtap_opttype_option_write_size)(wtap_option_type* data); /**< does the option have data worth writing (Ex string option != NULL */ typedef gboolean (*wtap_opttype_option_write)(struct wtap_dumper* wdh, wtap_option_type* data, int *err); /**< does the option have data worth writing (Ex string option != NULL */ @@ -97,7 +102,7 @@ void wtap_opttypes_initialize(void); * @param[in] block_type Option block type to be created * @return Newly allocated option block */ -WS_DLL_PUBLIC wtap_optionblock_t wtap_optionblock_create(wtap_optionblock_type_t block_type); +WS_DLL_PUBLIC wtap_optionblock_t wtap_optionblock_create(int block_type); /** Free an option block * @@ -231,5 +236,9 @@ guint32 wtap_opttype_write_uint64_not0(wtap_option_type* data); guint32 wtap_opttype_write_uint64_not_minus1(wtap_option_type* data); gboolean wtap_opttype_write_data_uint64(struct wtap_dumper* wdh, wtap_option_type* data, int *err); +WS_DLL_PUBLIC int wtap_opttype_register_custom_block_type(const char* name, const char* description, wtap_block_create_func create, + wtap_write_func write_func, wtap_mand_free_func free_mand, wtap_mand_copy_func copy_mand); + + #endif /* WTAP_OPT_TYPES_H */ -- cgit v1.2.3