3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 2001 Gerald Combs
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "wtap_opttypes.h"
30 #include "pcapng_module.h"
33 #define wtap_debug(...) g_warning(__VA_ARGS__)
35 #define wtap_debug(...)
39 * Structure describing a type of block.
42 wtap_block_type_t block_type; /**< internal type code for block */
43 const char *name; /**< name of block */
44 const char *description; /**< human-readable description of block */
45 wtap_block_create_func create;
46 wtap_mand_free_func free_mand;
47 wtap_mand_copy_func copy_mand;
48 GArray *options; /**< array of known options */
51 typedef void *(*wtap_opttype_dup_custom_func)(void* src);
52 typedef void (*wtap_opttype_free_custom_func)(void* data);
55 * Structure describing a type of option.
58 const char *name; /**< name of option */
59 const char *description; /**< human-readable description of option */
60 wtap_opttype_e data_type; /**< data type of that option */
61 guint flags; /**< flags for the option */
62 wtap_opttype_dup_custom_func dup_func; /**< function to duplicate custom option data */
63 wtap_opttype_free_custom_func free_func; /**< function to free custom option data */
67 #define WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED 0x00000001 /* multiple instances allowed */
71 wtap_blocktype_t* info;
76 #define MAX_WTAP_BLOCK_CUSTOM 10
77 #define MAX_WTAP_BLOCK_TYPE_VALUE (WTAP_BLOCK_END_OF_LIST+MAX_WTAP_BLOCK_CUSTOM)
79 /* Keep track of wtap_blocktype_t's via their id number */
80 static wtap_blocktype_t* blocktype_list[MAX_WTAP_BLOCK_TYPE_VALUE];
81 static guint num_custom_blocks;
82 static wtap_blocktype_t custom_blocktype_list[MAX_WTAP_BLOCK_CUSTOM];
84 static void wtap_opttype_block_register(wtap_block_type_t block_type, wtap_blocktype_t *blocktype)
86 static const wtap_opttype_t opt_comment = {
90 WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED,
96 g_assert(block_type < WTAP_BLOCK_END_OF_LIST);
98 /* Don't re-register. */
99 g_assert(blocktype_list[block_type] == NULL);
102 g_assert(blocktype->name);
103 g_assert(blocktype->description);
104 g_assert(blocktype->create);
106 blocktype->block_type = block_type;
109 * Initialize the set of supported options.
110 * All blocks that support options at all support OPT_COMMENT.
112 blocktype->options = g_array_sized_new(FALSE, TRUE, sizeof (wtap_opttype_t), OPT_COMMENT + 1);
113 if (OPT_COMMENT + 1 > blocktype->options->len)
114 g_array_set_size(blocktype->options, OPT_COMMENT + 1);
115 g_array_insert_val(blocktype->options, OPT_COMMENT, opt_comment);
117 blocktype_list[block_type] = blocktype;
120 int wtap_opttype_register_custom_block_type(const char* name, const char* description, wtap_block_create_func create,
121 wtap_mand_free_func free_mand, wtap_mand_copy_func copy_mand)
125 /* Ensure valid data/functions for required fields */
127 g_assert(description);
130 /* This shouldn't happen, so flag it for fixing */
131 g_assert(num_custom_blocks < MAX_WTAP_BLOCK_CUSTOM);
133 block_type = (wtap_block_type_t)(WTAP_BLOCK_END_OF_LIST+num_custom_blocks);
135 custom_blocktype_list[num_custom_blocks].name = name;
136 custom_blocktype_list[num_custom_blocks].description = description;
137 custom_blocktype_list[num_custom_blocks].create = create;
138 custom_blocktype_list[num_custom_blocks].free_mand = free_mand;
139 custom_blocktype_list[num_custom_blocks].copy_mand = copy_mand;
140 blocktype_list[block_type] = &custom_blocktype_list[num_custom_blocks];
146 static void wtap_opttype_option_register(wtap_blocktype_t *blocktype, int opttype, wtap_opttype_t *option)
148 if ((guint)opttype + 1 > blocktype->options->len)
149 g_array_set_size(blocktype->options, opttype + 1);
150 g_array_insert_val(blocktype->options, opttype, *option);
153 void* wtap_block_get_mandatory_data(wtap_block_t block)
155 return block->mandatory_data;
158 static wtap_optval_t *
159 wtap_block_get_option(wtap_block_t block, guint option_id)
164 for (i = 0; i < block->options->len; i++) {
165 opt = &g_array_index(block->options, wtap_option_t, i);
166 if (opt->option_id == option_id)
173 static wtap_optval_t *
174 wtap_block_get_nth_option(wtap_block_t block, guint option_id, guint idx)
181 for (i = 0; i < block->options->len; i++) {
182 opt = &g_array_index(block->options, wtap_option_t, i);
183 if (opt->option_id == option_id) {
193 wtap_block_t wtap_block_create(wtap_block_type_t block_type)
197 if (block_type >= (wtap_block_type_t)(WTAP_BLOCK_END_OF_LIST+num_custom_blocks))
200 block = g_new(struct wtap_block, 1);
201 block->info = blocktype_list[block_type];
202 block->options = g_array_new(FALSE, FALSE, sizeof(wtap_option_t));
203 block->info->create(block);
208 static void wtap_block_free_option(wtap_block_t block, wtap_option_t *opt)
210 wtap_opttype_t *opttype;
212 opttype = &g_array_index(block->info->options, wtap_opttype_t, opt->option_id);
213 switch (opttype->data_type) {
215 case WTAP_OPTTYPE_STRING:
216 g_free(opt->value.stringval);
219 case WTAP_OPTTYPE_CUSTOM:
220 opttype->free_func(opt->value.customval.data);
221 g_free(opt->value.customval.data);
229 static void wtap_block_free_options(wtap_block_t block)
234 for (i = 0; i < block->options->len; i++) {
235 opt = &g_array_index(block->options, wtap_option_t, i);
236 wtap_block_free_option(block, opt);
240 void wtap_block_free(wtap_block_t block)
244 if (block->info->free_mand != NULL)
245 block->info->free_mand(block);
247 g_free(block->mandatory_data);
248 wtap_block_free_options(block);
249 g_array_free(block->options, TRUE);
254 void wtap_block_array_free(GArray* block_array)
258 if (block_array == NULL)
261 for (block = 0; block < block_array->len; block++) {
262 wtap_block_free(g_array_index(block_array, wtap_block_t, block));
264 g_array_free(block_array, TRUE);
268 * Make a copy of a block.
271 wtap_block_copy(wtap_block_t dest_block, wtap_block_t src_block)
274 wtap_option_t *src_opt;
275 wtap_opttype_t *opttype;
278 * Copy the mandatory data.
280 if (dest_block->info->copy_mand != NULL)
281 dest_block->info->copy_mand(dest_block, src_block);
283 /* Copy the options. For now, don't remove any options that are in destination
286 for (i = 0; i < src_block->options->len; i++)
288 src_opt = &g_array_index(src_block->options, wtap_option_t, i);
289 opttype = &g_array_index(src_block->info->options, wtap_opttype_t, src_opt->option_id);
291 switch(opttype->data_type) {
293 case WTAP_OPTTYPE_UINT8:
294 wtap_block_add_uint8_option(dest_block, src_opt->option_id, src_opt->value.uint8val);
297 case WTAP_OPTTYPE_UINT64:
298 wtap_block_add_uint64_option(dest_block, src_opt->option_id, src_opt->value.uint64val);
301 case WTAP_OPTTYPE_IPv4:
302 wtap_block_add_ipv4_option(dest_block, src_opt->option_id, src_opt->value.ipv4val);
305 case WTAP_OPTTYPE_IPv6:
306 wtap_block_add_ipv6_option(dest_block, src_opt->option_id, &src_opt->value.ipv6val);
309 case WTAP_OPTTYPE_STRING:
310 wtap_block_add_string_option(dest_block, src_opt->option_id, src_opt->value.stringval, strlen(src_opt->value.stringval));
313 case WTAP_OPTTYPE_CUSTOM:
314 wtap_block_add_custom_option(dest_block, src_opt->option_id, src_opt->value.customval.data, src_opt->value.customval.size);
320 void wtap_block_foreach_option(wtap_block_t block, wtap_block_foreach_func func, void* user_data)
324 wtap_opttype_t *opttype;
326 for (i = 0; i < block->options->len; i++) {
327 opt = &g_array_index(block->options, wtap_option_t, i);
328 opttype = &g_array_index(block->info->options, wtap_opttype_t, opt->option_id);
329 func(block, opt->option_id, opttype->data_type, &opt->value, user_data);
333 static wtap_opttype_return_val
334 wtap_block_add_option_common(wtap_block_t block, guint option_id, wtap_opttype_e type, wtap_option_t **optp)
337 wtap_opttype_t *opttype;
340 if (option_id >= block->info->options->len) {
341 /* There's no option for this block with that option ID */
342 return WTAP_OPTTYPE_NO_SUCH_OPTION;
344 opttype = &g_array_index(block->info->options, wtap_opttype_t, option_id);
347 * Is this an option of the specified data type?
349 if (opttype->data_type != type) {
353 return WTAP_OPTTYPE_TYPE_MISMATCH;
357 * Can there be more than one instance of this option?
359 if (!(opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED)) {
361 * No. Is there already an instance of this option?
363 if (wtap_block_get_option(block, option_id) != NULL) {
367 return WTAP_OPTTYPE_ALREADY_EXISTS;
374 i = block->options->len;
375 g_array_set_size(block->options, i + 1);
376 opt = &g_array_index(block->options, wtap_option_t, i);
377 opt->option_id = option_id;
379 return WTAP_OPTTYPE_SUCCESS;
382 static wtap_opttype_return_val
383 wtap_block_get_option_common(wtap_block_t block, guint option_id, wtap_opttype_e type, wtap_optval_t **optvalp)
385 wtap_opttype_t *opttype;
386 wtap_optval_t *optval;
388 if (option_id >= block->info->options->len) {
389 /* There's no option for this block with that option ID */
390 return WTAP_OPTTYPE_NO_SUCH_OPTION;
393 opttype = &g_array_index(block->info->options, wtap_opttype_t, option_id);
396 * Is this an option of the specified data type?
398 if (opttype->data_type != type) {
402 return WTAP_OPTTYPE_TYPE_MISMATCH;
406 * Can there be more than one instance of this option?
408 if (opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED) {
410 * Yes. You can't ask for "the" value.
412 return WTAP_OPTTYPE_NUMBER_MISMATCH;
415 optval = wtap_block_get_option(block, option_id);
416 if (optval == NULL) {
417 /* Didn't find the option */
418 return WTAP_OPTTYPE_NOT_FOUND;
422 return WTAP_OPTTYPE_SUCCESS;
425 static wtap_opttype_return_val
426 wtap_block_get_nth_option_common(wtap_block_t block, guint option_id, wtap_opttype_e type, guint idx, wtap_optval_t **optvalp)
428 wtap_opttype_t *opttype;
429 wtap_optval_t *optval;
431 if (option_id >= block->info->options->len) {
432 /* There's no option for this block with that option ID */
433 return WTAP_OPTTYPE_NO_SUCH_OPTION;
436 opttype = &g_array_index(block->info->options, wtap_opttype_t, option_id);
439 * Is this an option of the specified data type?
441 if (opttype->data_type != type) {
445 return WTAP_OPTTYPE_TYPE_MISMATCH;
449 * Can there be more than one instance of this option?
451 if (!(opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED)) {
455 return WTAP_OPTTYPE_NUMBER_MISMATCH;
458 optval = wtap_block_get_nth_option(block, option_id, idx);
459 if (optval == NULL) {
460 /* Didn't find the option */
461 return WTAP_OPTTYPE_NOT_FOUND;
465 return WTAP_OPTTYPE_SUCCESS;
468 wtap_opttype_return_val
469 wtap_block_add_uint8_option(wtap_block_t block, guint option_id, guint8 value)
471 wtap_opttype_return_val ret;
474 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_UINT8, &opt);
475 if (ret != WTAP_OPTTYPE_SUCCESS)
477 opt->value.uint8val = value;
478 return WTAP_OPTTYPE_SUCCESS;
481 wtap_opttype_return_val
482 wtap_block_set_uint8_option_value(wtap_block_t block, guint option_id, guint8 value)
484 wtap_opttype_return_val ret;
485 wtap_optval_t *optval;
487 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT8, &optval);
488 if (ret != WTAP_OPTTYPE_SUCCESS)
490 optval->uint8val = value;
491 return WTAP_OPTTYPE_SUCCESS;
494 wtap_opttype_return_val
495 wtap_block_get_uint8_option_value(wtap_block_t block, guint option_id, guint8* value)
497 wtap_opttype_return_val ret;
498 wtap_optval_t *optval;
500 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT8, &optval);
501 if (ret != WTAP_OPTTYPE_SUCCESS)
503 *value = optval->uint8val;
504 return WTAP_OPTTYPE_SUCCESS;
507 wtap_opttype_return_val
508 wtap_block_add_uint64_option(wtap_block_t block, guint option_id, guint64 value)
510 wtap_opttype_return_val ret;
513 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_UINT64, &opt);
514 if (ret != WTAP_OPTTYPE_SUCCESS)
516 opt->value.uint64val = value;
517 return WTAP_OPTTYPE_SUCCESS;
520 wtap_opttype_return_val
521 wtap_block_set_uint64_option_value(wtap_block_t block, guint option_id, guint64 value)
523 wtap_opttype_return_val ret;
524 wtap_optval_t *optval;
526 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT64, &optval);
527 if (ret != WTAP_OPTTYPE_SUCCESS)
529 optval->uint64val = value;
530 return WTAP_OPTTYPE_SUCCESS;
533 wtap_opttype_return_val
534 wtap_block_get_uint64_option_value(wtap_block_t block, guint option_id, guint64 *value)
536 wtap_opttype_return_val ret;
537 wtap_optval_t *optval;
539 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT64, &optval);
540 if (ret != WTAP_OPTTYPE_SUCCESS)
542 *value = optval->uint64val;
543 return WTAP_OPTTYPE_SUCCESS;
546 wtap_opttype_return_val
547 wtap_block_add_ipv4_option(wtap_block_t block, guint option_id, guint32 value)
549 wtap_opttype_return_val ret;
552 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_IPv4, &opt);
553 if (ret != WTAP_OPTTYPE_SUCCESS)
555 opt->value.ipv4val = value;
556 return WTAP_OPTTYPE_SUCCESS;
559 wtap_opttype_return_val
560 wtap_block_set_ipv4_option_value(wtap_block_t block, guint option_id, guint32 value)
562 wtap_opttype_return_val ret;
563 wtap_optval_t *optval;
565 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IPv4, &optval);
566 if (ret != WTAP_OPTTYPE_SUCCESS)
568 optval->ipv4val = value;
569 return WTAP_OPTTYPE_SUCCESS;
572 wtap_opttype_return_val
573 wtap_block_get_ipv4_option_value(wtap_block_t block, guint option_id, guint32* value)
575 wtap_opttype_return_val ret;
576 wtap_optval_t *optval;
578 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IPv4, &optval);
579 if (ret != WTAP_OPTTYPE_SUCCESS)
581 *value = optval->ipv4val;
582 return WTAP_OPTTYPE_SUCCESS;
585 wtap_opttype_return_val
586 wtap_block_add_ipv6_option(wtap_block_t block, guint option_id, struct e_in6_addr *value)
588 wtap_opttype_return_val ret;
591 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_IPv6, &opt);
592 if (ret != WTAP_OPTTYPE_SUCCESS)
594 opt->value.ipv6val = *value;
595 return WTAP_OPTTYPE_SUCCESS;
598 wtap_opttype_return_val
599 wtap_block_set_ipv6_option_value(wtap_block_t block, guint option_id, struct e_in6_addr *value)
601 wtap_opttype_return_val ret;
602 wtap_optval_t *optval;
604 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IPv6, &optval);
605 if (ret != WTAP_OPTTYPE_SUCCESS)
607 optval->ipv6val = *value;
608 return WTAP_OPTTYPE_SUCCESS;
611 wtap_opttype_return_val
612 wtap_block_get_ipv6_option_value(wtap_block_t block, guint option_id, struct e_in6_addr* value)
614 wtap_opttype_return_val ret;
615 wtap_optval_t *optval;
617 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IPv4, &optval);
618 if (ret != WTAP_OPTTYPE_SUCCESS)
620 *value = optval->ipv6val;
621 return WTAP_OPTTYPE_SUCCESS;
624 wtap_opttype_return_val
625 wtap_block_add_string_option(wtap_block_t block, guint option_id, const char *value, gsize value_length)
627 wtap_opttype_return_val ret;
630 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_STRING, &opt);
631 if (ret != WTAP_OPTTYPE_SUCCESS)
633 opt->value.stringval = g_strndup(value, value_length);
634 return WTAP_OPTTYPE_SUCCESS;
637 static wtap_opttype_return_val
638 wtap_block_add_string_option_vformat(wtap_block_t block, guint option_id, const char *format, va_list va)
640 wtap_opttype_return_val ret;
643 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_STRING, &opt);
644 if (ret != WTAP_OPTTYPE_SUCCESS)
646 opt->value.stringval = g_strdup_vprintf(format, va);
647 return WTAP_OPTTYPE_SUCCESS;
650 wtap_opttype_return_val
651 wtap_block_add_string_option_format(wtap_block_t block, guint option_id, const char *format, ...)
653 wtap_opttype_return_val ret;
657 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_STRING, &opt);
658 if (ret != WTAP_OPTTYPE_SUCCESS)
660 va_start(va, format);
661 opt->value.stringval = g_strdup_vprintf(format, va);
663 return WTAP_OPTTYPE_SUCCESS;
666 wtap_opttype_return_val
667 wtap_block_set_string_option_value(wtap_block_t block, guint option_id, const char *value, size_t value_length)
669 wtap_opttype_return_val ret;
670 wtap_optval_t *optval;
672 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_STRING, &optval);
673 if (ret != WTAP_OPTTYPE_SUCCESS) {
674 if (ret == WTAP_OPTTYPE_NOT_FOUND) {
676 * There's no instance to set, so just try to create a new one
679 return wtap_block_add_string_option(block, option_id, value, value_length);
681 /* Otherwise fail. */
684 g_free(optval->stringval);
685 optval->stringval = g_strndup(value, value_length);
686 return WTAP_OPTTYPE_SUCCESS;
689 wtap_opttype_return_val
690 wtap_block_set_nth_string_option_value(wtap_block_t block, guint option_id, guint idx, const char *value, size_t value_length)
692 wtap_opttype_return_val ret;
693 wtap_optval_t *optval;
695 ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_STRING, idx, &optval);
696 if (ret != WTAP_OPTTYPE_SUCCESS)
698 g_free(optval->stringval);
699 optval->stringval = g_strndup(value, value_length);
700 return WTAP_OPTTYPE_SUCCESS;
703 wtap_opttype_return_val
704 wtap_block_set_string_option_value_format(wtap_block_t block, guint option_id, const char *format, ...)
706 wtap_opttype_return_val ret;
707 wtap_optval_t *optval;
710 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_STRING, &optval);
711 if (ret != WTAP_OPTTYPE_SUCCESS) {
712 if (ret == WTAP_OPTTYPE_NOT_FOUND) {
714 * There's no instance to set, so just try to create a new one
715 * with the formatted string.
717 va_start(va, format);
718 ret = wtap_block_add_string_option_vformat(block, option_id, format, va);
722 /* Otherwise fail. */
725 g_free(optval->stringval);
726 va_start(va, format);
727 optval->stringval = g_strdup_vprintf(format, va);
729 return WTAP_OPTTYPE_SUCCESS;
732 wtap_opttype_return_val
733 wtap_block_get_string_option_value(wtap_block_t block, guint option_id, char** value)
735 wtap_opttype_return_val ret;
736 wtap_optval_t *optval;
738 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_STRING, &optval);
739 if (ret != WTAP_OPTTYPE_SUCCESS)
741 *value = optval->stringval;
742 return WTAP_OPTTYPE_SUCCESS;
745 wtap_opttype_return_val
746 wtap_block_get_nth_string_option_value(wtap_block_t block, guint option_id, guint idx, char** value)
748 wtap_opttype_return_val ret;
749 wtap_optval_t *optval;
751 ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_STRING, idx, &optval);
752 if (ret != WTAP_OPTTYPE_SUCCESS)
754 *value = optval->stringval;
755 return WTAP_OPTTYPE_SUCCESS;
758 wtap_opttype_return_val
759 wtap_block_add_custom_option(wtap_block_t block, guint option_id, void *value, size_t value_size)
761 wtap_opttype_return_val ret;
763 wtap_opttype_t *opttype;
765 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_CUSTOM, &opt);
766 if (ret != WTAP_OPTTYPE_SUCCESS)
768 opttype = &g_array_index(block->info->options, wtap_opttype_t, opt->option_id);
769 opt->value.customval.size = (guint)value_size;
770 opt->value.customval.data = opttype->dup_func(value);
771 return WTAP_OPTTYPE_SUCCESS;
774 wtap_opttype_return_val
775 wtap_block_get_custom_option_value(wtap_block_t block, guint option_id, void** value)
777 wtap_opttype_return_val ret;
778 wtap_optval_t *optval;
780 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_CUSTOM, &optval);
781 if (ret != WTAP_OPTTYPE_SUCCESS)
783 *value = optval->customval.data;
784 return WTAP_OPTTYPE_SUCCESS;
787 wtap_opttype_return_val
788 wtap_block_set_custom_option_value(wtap_block_t block, guint option_id, void *value)
790 wtap_opttype_return_val ret;
791 wtap_optval_t *optval;
794 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_CUSTOM, &optval);
795 if (ret != WTAP_OPTTYPE_SUCCESS)
797 prev_value = optval->customval.data;
799 * XXX - a custom value can be a structure that points to other data,
800 * but we're doing a shallow copy here.
802 optval->customval.data = g_memdup(value, optval->customval.size);
803 /* Free after memory is duplicated in case structure was manipulated with a "get then set" */
806 return WTAP_OPTTYPE_SUCCESS;
809 wtap_opttype_return_val
810 wtap_block_remove_option(wtap_block_t block, guint option_id)
812 wtap_opttype_t *opttype;
816 if (option_id >= block->info->options->len) {
817 /* There's no option for this block with that option ID */
818 return WTAP_OPTTYPE_NO_SUCH_OPTION;
821 opttype = &g_array_index(block->info->options, wtap_opttype_t, option_id);
824 * Can there be more than one instance of this option?
826 if (opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED) {
828 * Yes. You can't remove "the" value.
830 return WTAP_OPTTYPE_NUMBER_MISMATCH;
833 for (i = 0; i < block->options->len; i++) {
834 opt = &g_array_index(block->options, wtap_option_t, i);
835 if (opt->option_id == option_id) {
836 /* Found it - free up the value */
837 wtap_block_free_option(block, opt);
838 /* Remove the option from the array of options */
839 g_array_remove_index(block->options, i);
840 return WTAP_OPTTYPE_SUCCESS;
844 /* Didn't find the option */
845 return WTAP_OPTTYPE_NOT_FOUND;
848 wtap_opttype_return_val
849 wtap_block_remove_nth_option_instance(wtap_block_t block, guint option_id,
852 wtap_opttype_t *opttype;
857 if (option_id >= block->info->options->len) {
858 /* There's no option for this block with that option ID */
859 return WTAP_OPTTYPE_NO_SUCH_OPTION;
862 opttype = &g_array_index(block->info->options, wtap_opttype_t, option_id);
865 * Can there be more than one instance of this option?
867 if (!(opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED)) {
871 return WTAP_OPTTYPE_NUMBER_MISMATCH;
875 for (i = 0; i < block->options->len; i++) {
876 opt = &g_array_index(block->options, wtap_option_t, i);
877 if (opt->option_id == option_id) {
878 if (opt_idx == idx) {
879 /* Found it - free up the value */
880 wtap_block_free_option(block, opt);
881 /* Remove the option from the array of options */
882 g_array_remove_index(block->options, i);
883 return WTAP_OPTTYPE_SUCCESS;
889 /* Didn't find the option */
890 return WTAP_OPTTYPE_NOT_FOUND;
893 static void shb_create(wtap_block_t block)
895 wtapng_mandatory_section_t* section_mand = g_new(wtapng_mandatory_section_t, 1);
897 section_mand->section_length = -1;
899 block->mandatory_data = section_mand;
902 static void shb_copy_mand(wtap_block_t dest_block, wtap_block_t src_block)
904 memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_mandatory_section_t));
907 static void nrb_create(wtap_block_t block)
909 block->mandatory_data = NULL;
912 static void isb_create(wtap_block_t block)
914 block->mandatory_data = g_new0(wtapng_if_stats_mandatory_t, 1);
917 static void isb_copy_mand(wtap_block_t dest_block, wtap_block_t src_block)
919 memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_if_stats_mandatory_t));
922 static void *idb_filter_dup(void* src)
924 wtapng_if_descr_filter_t* filter_src = (wtapng_if_descr_filter_t*)src;
925 wtapng_if_descr_filter_t* filter_dest;
928 filter_dest = g_new(wtapng_if_descr_filter_t, 1);
929 filter_dest->if_filter_str = g_strdup(filter_src->if_filter_str);
930 filter_dest->bpf_filter_len = filter_src->bpf_filter_len;
931 filter_dest->if_filter_bpf_bytes = (guint8 *)g_memdup(filter_src->if_filter_bpf_bytes, filter_src->bpf_filter_len);
932 return (void *)filter_dest;
935 static void idb_filter_free(void* data)
937 wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)data;
938 g_free(filter->if_filter_str);
939 g_free(filter->if_filter_bpf_bytes);
942 static void idb_create(wtap_block_t block)
944 block->mandatory_data = g_new0(wtapng_if_descr_mandatory_t, 1);
947 static void idb_free_mand(wtap_block_t block)
950 wtap_block_t if_stats;
951 wtapng_if_descr_mandatory_t* mand = (wtapng_if_descr_mandatory_t*)block->mandatory_data;
953 for(j = 0; j < mand->num_stat_entries; j++) {
954 if_stats = g_array_index(mand->interface_statistics, wtap_block_t, j);
955 wtap_block_free(if_stats);
958 if (mand->interface_statistics)
959 g_array_free(mand->interface_statistics, TRUE);
962 static void idb_copy_mand(wtap_block_t dest_block, wtap_block_t src_block)
965 wtap_block_t src_if_stats, dest_if_stats;
966 wtapng_if_descr_mandatory_t *src_mand = (wtapng_if_descr_mandatory_t*)src_block->mandatory_data,
967 *dest_mand = (wtapng_if_descr_mandatory_t*)dest_block->mandatory_data;
969 /* Need special consideration for copying of the interface_statistics member */
970 if (dest_mand->num_stat_entries != 0)
971 g_array_free(dest_mand->interface_statistics, TRUE);
973 memcpy(dest_mand, src_mand, sizeof(wtapng_if_descr_mandatory_t));
974 if (src_mand->num_stat_entries != 0)
976 dest_mand->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
977 for (j = 0; j < src_mand->num_stat_entries; j++)
979 src_if_stats = g_array_index(src_mand->interface_statistics, wtap_block_t, j);
980 dest_if_stats = wtap_block_create(WTAP_BLOCK_IF_STATS);
981 wtap_block_copy(dest_if_stats, src_if_stats);
982 dest_mand->interface_statistics = g_array_append_val(dest_mand->interface_statistics, dest_if_stats);
987 void wtap_opttypes_initialize(void)
989 static wtap_blocktype_t shb_block = {
990 WTAP_BLOCK_NG_SECTION, /* block_type */
992 "Section Header Block", /* description */
993 shb_create, /* create */
994 NULL, /* free_mand */
995 shb_copy_mand, /* copy_mand */
998 static wtap_opttype_t shb_hardware = {
1001 WTAP_OPTTYPE_STRING,
1006 static wtap_opttype_t shb_os = {
1008 "SHB Operating System",
1009 WTAP_OPTTYPE_STRING,
1014 static wtap_opttype_t shb_userappl = {
1016 "SHB User Application",
1017 WTAP_OPTTYPE_STRING,
1023 static wtap_blocktype_t idb_block = {
1024 WTAP_BLOCK_IF_DESCR, /* block_type */
1026 "Interface Description Block", /* description */
1027 idb_create, /* create */
1028 idb_free_mand, /* free_mand */
1029 idb_copy_mand, /* copy_mand */
1032 static wtap_opttype_t if_name = {
1035 WTAP_OPTTYPE_STRING,
1040 static wtap_opttype_t if_description = {
1043 WTAP_OPTTYPE_STRING,
1048 static wtap_opttype_t if_speed = {
1051 WTAP_OPTTYPE_UINT64,
1056 static wtap_opttype_t if_tsresol = {
1058 "IDB Time Stamp Resolution",
1059 WTAP_OPTTYPE_UINT8, /* XXX - signed? */
1064 static wtap_opttype_t if_filter = {
1067 WTAP_OPTTYPE_CUSTOM,
1072 static wtap_opttype_t if_os = {
1074 "IDB Operating System",
1075 WTAP_OPTTYPE_STRING,
1080 static wtap_opttype_t if_fcslen = {
1089 static wtap_blocktype_t nrb_block = {
1090 WTAP_BLOCK_NG_NRB, /* block_type */
1092 "Name Resolution Block", /* description */
1093 nrb_create, /* create */
1094 NULL, /* free_mand */
1095 NULL, /* copy_mand */
1098 static wtap_opttype_t ns_dnsname = {
1100 "NRB DNS server name",
1101 WTAP_OPTTYPE_STRING,
1106 static wtap_opttype_t ns_dnsIP4addr = {
1108 "NRB DNS server IPv4 address",
1114 static wtap_opttype_t ns_dnsIP6addr = {
1116 "NRB DNS server IPv6 address",
1123 static wtap_blocktype_t isb_block = {
1124 WTAP_BLOCK_IF_STATS, /* block_type */
1126 "Interface Statistics Block", /* description */
1127 isb_create, /* create */
1128 NULL, /* free_mand */
1129 isb_copy_mand, /* copy_mand */
1132 static wtap_opttype_t isb_starttime = {
1135 WTAP_OPTTYPE_UINT64,
1140 static wtap_opttype_t isb_endtime = {
1143 WTAP_OPTTYPE_UINT64,
1148 static wtap_opttype_t isb_ifrecv = {
1150 "ISB Received Packets",
1151 WTAP_OPTTYPE_UINT64,
1156 static wtap_opttype_t isb_ifdrop = {
1158 "ISB Dropped Packets",
1159 WTAP_OPTTYPE_UINT64,
1164 static wtap_opttype_t isb_filteraccept = {
1166 "ISB Packets Accepted By Filter",
1167 WTAP_OPTTYPE_UINT64,
1172 static wtap_opttype_t isb_osdrop = {
1174 "ISB Packets Dropped By The OS",
1175 WTAP_OPTTYPE_UINT64,
1180 static wtap_opttype_t isb_usrdeliv = {
1182 "ISB Packets Delivered To The User",
1183 WTAP_OPTTYPE_UINT64,
1189 /* Initialize the custom block array. This is for future proofing
1190 "outside registered" block types (for NULL checking) */
1191 memset(blocktype_list, 0, MAX_WTAP_BLOCK_TYPE_VALUE*sizeof(wtap_blocktype_t*));
1192 num_custom_blocks = 0;
1195 * Registser the SHB and the options that can appear in it.
1197 wtap_opttype_block_register(WTAP_BLOCK_NG_SECTION, &shb_block);
1198 wtap_opttype_option_register(&shb_block, OPT_SHB_HARDWARE, &shb_hardware);
1199 wtap_opttype_option_register(&shb_block, OPT_SHB_OS, &shb_os);
1200 wtap_opttype_option_register(&shb_block, OPT_SHB_USERAPPL, &shb_userappl);
1203 * Register the IDB and the options that can appear in it.
1205 wtap_opttype_block_register(WTAP_BLOCK_IF_DESCR, &idb_block);
1206 wtap_opttype_option_register(&idb_block, OPT_IDB_NAME, &if_name);
1207 wtap_opttype_option_register(&idb_block, OPT_IDB_DESCR, &if_description);
1208 wtap_opttype_option_register(&idb_block, OPT_IDB_SPEED, &if_speed);
1209 wtap_opttype_option_register(&idb_block, OPT_IDB_TSRESOL, &if_tsresol);
1210 wtap_opttype_option_register(&idb_block, OPT_IDB_FILTER, &if_filter);
1211 wtap_opttype_option_register(&idb_block, OPT_IDB_OS, &if_os);
1212 wtap_opttype_option_register(&idb_block, OPT_IDB_FCSLEN, &if_fcslen);
1215 * Register the NRB and the options that can appear in it.
1217 wtap_opttype_block_register(WTAP_BLOCK_NG_NRB, &nrb_block);
1218 wtap_opttype_option_register(&nrb_block, OPT_NS_DNSNAME, &ns_dnsname);
1219 wtap_opttype_option_register(&nrb_block, OPT_NS_DNSIP4ADDR, &ns_dnsIP4addr);
1220 wtap_opttype_option_register(&nrb_block, OPT_NS_DNSIP6ADDR, &ns_dnsIP6addr);
1223 * Register the ISB and the options that can appear in it.
1225 wtap_opttype_block_register(WTAP_BLOCK_IF_STATS, &isb_block);
1226 wtap_opttype_option_register(&isb_block, OPT_ISB_STARTTIME, &isb_starttime);
1227 wtap_opttype_option_register(&isb_block, OPT_ISB_ENDTIME, &isb_endtime);
1228 wtap_opttype_option_register(&isb_block, OPT_ISB_IFRECV, &isb_ifrecv);
1229 wtap_opttype_option_register(&isb_block, OPT_ISB_IFDROP, &isb_ifdrop);
1230 wtap_opttype_option_register(&isb_block, OPT_ISB_FILTERACCEPT, &isb_filteraccept);
1231 wtap_opttype_option_register(&isb_block, OPT_ISB_OSDROP, &isb_osdrop);
1232 wtap_opttype_option_register(&isb_block, OPT_ISB_USRDELIV, &isb_usrdeliv);