diff options
author | Guy Harris <guy@alum.mit.edu> | 2016-07-14 16:01:57 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2016-07-14 23:02:39 +0000 |
commit | 1f8999bb96018446e48529e75e56bf17dd3c77cf (patch) | |
tree | 0103d875702fa1a7c64816e21e079d7ceee190c2 /wiretap/wtap_opttypes.c | |
parent | 42e72d529cdbab62d52a26332985ecf28b997a87 (diff) | |
download | wireshark-1f8999bb96018446e48529e75e56bf17dd3c77cf.tar.gz |
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 <guy@alum.mit.edu>
Diffstat (limited to 'wiretap/wtap_opttypes.c')
-rw-r--r-- | wiretap/wtap_opttypes.c | 1238 |
1 files changed, 824 insertions, 414 deletions
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); } |