Revert "UNUSED enc_key_id_{equal,hash}"
[wireshark-sm.git] / wiretap / wtap_opttypes.c
blob9f3b150b9eab9080040320d2940aa3ea1e513fb4
1 /* wtap_opttypes.c
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 2001 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 #include "config.h"
10 #include "wtap_opttypes.h"
12 #define WS_LOG_DOMAIN LOG_DOMAIN_WIRETAP
14 #include <glib.h>
15 #include <string.h>
17 #include "wtap.h"
18 #include "wtap-int.h"
19 #include "pcapng_module.h"
20 #include <wsutil/ws_assert.h>
22 #include <wsutil/glib-compat.h>
23 #include <wsutil/unicode-utils.h>
25 #if 0
26 #define wtap_debug(...) ws_warning(__VA_ARGS__)
27 #define DEBUG_COUNT_REFS
28 #else
29 #define wtap_debug(...)
30 #endif
32 #define ROUND_TO_4BYTE(len) (((len) + 3) & ~3)
35 * Structure describing a type of block.
37 typedef struct {
38 wtap_block_type_t block_type; /**< internal type code for block */
39 const char *name; /**< name of block */
40 const char *description; /**< human-readable description of block */
41 wtap_block_create_func create;
42 wtap_mand_free_func free_mand;
43 wtap_mand_copy_func copy_mand;
44 GHashTable *options; /**< hash table of known options */
45 } wtap_blocktype_t;
47 #define GET_OPTION_TYPE(options, option_id) \
48 (const wtap_opttype_t *)g_hash_table_lookup((options), GUINT_TO_POINTER(option_id))
51 * Structure describing a type of option.
53 typedef struct {
54 const char *name; /**< name of option */
55 const char *description; /**< human-readable description of option */
56 wtap_opttype_e data_type; /**< data type of that option */
57 unsigned flags; /**< flags for the option */
58 } wtap_opttype_t;
60 /* Flags */
61 #define WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED 0x00000001 /* multiple instances allowed */
63 /* Debugging reference counting */
64 #ifdef DEBUG_COUNT_REFS
65 static unsigned block_count;
66 static uint8_t blocks_active[sizeof(unsigned)/8];
68 static void rc_set(unsigned refnum)
70 unsigned cellno = refnum / 8;
71 unsigned bitno = refnum % 8;
72 blocks_active[cellno] |= (uint8_t)(1 << bitno);
75 static void rc_clear(unsigned refnum)
77 unsigned cellno = refnum / 8;
78 unsigned bitno = refnum % 8;
79 blocks_active[cellno] &= (uint8_t)~(1 << bitno);
82 #endif /* DEBUG_COUNT_REFS */
84 struct wtap_block
86 wtap_blocktype_t* info;
87 void* mandatory_data;
88 GArray* options;
89 int ref_count;
90 #ifdef DEBUG_COUNT_REFS
91 unsigned id;
92 #endif
95 /* Keep track of wtap_blocktype_t's via their id number */
96 static wtap_blocktype_t* blocktype_list[MAX_WTAP_BLOCK_TYPE_VALUE];
98 static if_filter_opt_t if_filter_dup(if_filter_opt_t* filter_src)
100 if_filter_opt_t filter_dest;
102 memset(&filter_dest, 0, sizeof(filter_dest));
104 /* Deep copy. */
105 filter_dest.type = filter_src->type;
106 switch (filter_src->type) {
108 case if_filter_pcap:
109 /* pcap filter string */
110 filter_dest.data.filter_str =
111 g_strdup(filter_src->data.filter_str);
112 break;
114 case if_filter_bpf:
115 /* BPF program */
116 filter_dest.data.bpf_prog.bpf_prog_len =
117 filter_src->data.bpf_prog.bpf_prog_len;
118 filter_dest.data.bpf_prog.bpf_prog =
119 (wtap_bpf_insn_t *)g_memdup2(filter_src->data.bpf_prog.bpf_prog,
120 filter_src->data.bpf_prog.bpf_prog_len * sizeof (wtap_bpf_insn_t));
121 break;
123 default:
124 break;
126 return filter_dest;
129 static void if_filter_free(if_filter_opt_t* filter_src)
131 switch (filter_src->type) {
133 case if_filter_pcap:
134 /* pcap filter string */
135 g_free(filter_src->data.filter_str);
136 break;
138 case if_filter_bpf:
139 /* BPF program */
140 g_free(filter_src->data.bpf_prog.bpf_prog);
141 break;
143 default:
144 break;
148 static packet_verdict_opt_t
149 packet_verdict_dup(packet_verdict_opt_t* verdict_src)
151 packet_verdict_opt_t verdict_dest;
153 memset(&verdict_dest, 0, sizeof(verdict_dest));
155 /* Deep copy. */
156 verdict_dest.type = verdict_src->type;
157 switch (verdict_src->type) {
159 case packet_verdict_hardware:
160 /* array of octets */
161 verdict_dest.data.verdict_bytes =
162 g_byte_array_new_take((uint8_t *)g_memdup2(verdict_src->data.verdict_bytes->data,
163 verdict_src->data.verdict_bytes->len),
164 verdict_src->data.verdict_bytes->len);
165 break;
167 case packet_verdict_linux_ebpf_tc:
168 /* eBPF TC_ACT_ value */
169 verdict_dest.data.verdict_linux_ebpf_tc =
170 verdict_src->data.verdict_linux_ebpf_tc;
171 break;
173 case packet_verdict_linux_ebpf_xdp:
174 /* xdp_action value */
175 verdict_dest.data.verdict_linux_ebpf_xdp =
176 verdict_src->data.verdict_linux_ebpf_xdp;
177 break;
179 default:
180 break;
182 return verdict_dest;
185 void wtap_packet_verdict_free(packet_verdict_opt_t* verdict)
187 switch (verdict->type) {
189 case packet_verdict_hardware:
190 /* array of bytes */
191 g_byte_array_free(verdict->data.verdict_bytes, true);
192 break;
194 default:
195 break;
199 static packet_hash_opt_t
200 packet_hash_dup(packet_hash_opt_t* hash_src)
202 packet_hash_opt_t hash_dest;
204 memset(&hash_dest, 0, sizeof(hash_dest));
206 /* Deep copy. */
207 hash_dest.type = hash_src->type;
208 /* array of octets */
209 hash_dest.hash_bytes =
210 g_byte_array_new_take((uint8_t *)g_memdup2(hash_src->hash_bytes->data,
211 hash_src->hash_bytes->len),
212 hash_src->hash_bytes->len);
213 return hash_dest;
216 void wtap_packet_hash_free(packet_hash_opt_t* hash)
218 /* array of bytes */
219 g_byte_array_free(hash->hash_bytes, true);
222 static void wtap_opttype_block_register(wtap_blocktype_t *blocktype)
224 wtap_block_type_t block_type;
225 static const wtap_opttype_t opt_comment = {
226 "opt_comment",
227 "Comment",
228 WTAP_OPTTYPE_STRING,
229 WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED
231 static const wtap_opttype_t opt_custom = {
232 "opt_custom",
233 "Custom Option",
234 WTAP_OPTTYPE_CUSTOM,
235 WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED
238 block_type = blocktype->block_type;
240 /* Check input */
241 ws_assert(block_type < MAX_WTAP_BLOCK_TYPE_VALUE);
243 /* Don't re-register. */
244 ws_assert(blocktype_list[block_type] == NULL);
246 /* Sanity check */
247 ws_assert(blocktype->name);
248 ws_assert(blocktype->description);
249 ws_assert(blocktype->create);
252 * Initialize the set of supported options.
253 * All blocks that support options at all support
254 * OPT_COMMENT and OPT_CUSTOM.
256 * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
257 * so we use "g_direct_hash()" and "g_direct_equal()".
259 blocktype->options = g_hash_table_new(g_direct_hash, g_direct_equal);
260 g_hash_table_insert(blocktype->options, GUINT_TO_POINTER(OPT_COMMENT),
261 (void *)&opt_comment);
262 g_hash_table_insert(blocktype->options, GUINT_TO_POINTER(OPT_CUSTOM_STR_COPY),
263 (void *)&opt_custom);
264 g_hash_table_insert(blocktype->options, GUINT_TO_POINTER(OPT_CUSTOM_BIN_COPY),
265 (void *)&opt_custom);
266 g_hash_table_insert(blocktype->options, GUINT_TO_POINTER(OPT_CUSTOM_STR_NO_COPY),
267 (void *)&opt_custom);
268 g_hash_table_insert(blocktype->options, GUINT_TO_POINTER(OPT_CUSTOM_BIN_NO_COPY),
269 (void *)&opt_custom);
271 blocktype_list[block_type] = blocktype;
274 static void wtap_opttype_option_register(wtap_blocktype_t *blocktype, unsigned opttype, const wtap_opttype_t *option)
276 g_hash_table_insert(blocktype->options, GUINT_TO_POINTER(opttype),
277 (void *) option);
280 wtap_block_type_t wtap_block_get_type(wtap_block_t block)
282 return block->info->block_type;
285 void* wtap_block_get_mandatory_data(wtap_block_t block)
287 return block->mandatory_data;
290 static wtap_optval_t *
291 wtap_block_get_option(wtap_block_t block, unsigned option_id)
293 unsigned i;
294 wtap_option_t *opt;
296 if (block == NULL) {
297 return NULL;
300 for (i = 0; i < block->options->len; i++) {
301 opt = &g_array_index(block->options, wtap_option_t, i);
302 if (opt->option_id == option_id)
303 return &opt->value;
306 return NULL;
309 static wtap_optval_t *
310 wtap_block_get_nth_option(wtap_block_t block, unsigned option_id, unsigned idx)
312 unsigned i;
313 wtap_option_t *opt;
314 unsigned opt_idx;
316 if (block == NULL) {
317 return NULL;
320 opt_idx = 0;
321 for (i = 0; i < block->options->len; i++) {
322 opt = &g_array_index(block->options, wtap_option_t, i);
323 if (opt->option_id == option_id) {
324 if (opt_idx == idx)
325 return &opt->value;
326 opt_idx++;
330 return NULL;
333 wtap_block_t wtap_block_create(wtap_block_type_t block_type)
335 wtap_block_t block;
337 if (block_type >= MAX_WTAP_BLOCK_TYPE_VALUE)
338 return NULL;
340 block = g_new(struct wtap_block, 1);
341 block->info = blocktype_list[block_type];
342 block->options = g_array_new(false, false, sizeof(wtap_option_t));
343 block->info->create(block);
344 block->ref_count = 1;
345 #ifdef DEBUG_COUNT_REFS
346 block->id = block_count++;
347 rc_set(block->id);
348 wtap_debug("Created #%d %s", block->id, block->info->name);
349 #endif /* DEBUG_COUNT_REFS */
351 return block;
354 static void wtap_block_free_option(wtap_block_t block, wtap_option_t *opt)
356 const wtap_opttype_t *opttype;
358 if (block == NULL) {
359 return;
362 opttype = GET_OPTION_TYPE(block->info->options, opt->option_id);
363 switch (opttype->data_type) {
365 case WTAP_OPTTYPE_STRING:
366 g_free(opt->value.stringval);
367 break;
369 case WTAP_OPTTYPE_BYTES:
370 g_bytes_unref(opt->value.byteval);
371 break;
373 case WTAP_OPTTYPE_CUSTOM:
374 switch (opt->value.custom_opt.pen) {
375 case PEN_NFLX:
376 g_free(opt->value.custom_opt.data.nflx_data.custom_data);
377 break;
378 default:
379 g_free(opt->value.custom_opt.data.generic_data.custom_data);
380 break;
382 break;
384 case WTAP_OPTTYPE_IF_FILTER:
385 if_filter_free(&opt->value.if_filterval);
386 break;
388 case WTAP_OPTTYPE_PACKET_VERDICT:
389 wtap_packet_verdict_free(&opt->value.packet_verdictval);
390 break;
392 case WTAP_OPTTYPE_PACKET_HASH:
393 wtap_packet_hash_free(&opt->value.packet_hash);
394 break;
396 default:
397 break;
401 static void wtap_block_free_options(wtap_block_t block)
403 unsigned i;
404 wtap_option_t *opt;
406 if (block == NULL || block->options == NULL) {
407 return;
410 for (i = 0; i < block->options->len; i++) {
411 opt = &g_array_index(block->options, wtap_option_t, i);
412 wtap_block_free_option(block, opt);
414 g_array_remove_range(block->options, 0, block->options->len);
417 wtap_block_t wtap_block_ref(wtap_block_t block)
419 if (block == NULL) {
420 return NULL;
423 g_atomic_int_inc(&block->ref_count);
424 #ifdef DEBUG_COUNT_REFS
425 wtap_debug("Ref #%d %s", block->id, block->info->name);
426 #endif /* DEBUG_COUNT_REFS */
427 return block;
430 void wtap_block_unref(wtap_block_t block)
432 if (block != NULL)
434 if (g_atomic_int_dec_and_test(&block->ref_count)) {
435 #ifdef DEBUG_COUNT_REFS
436 wtap_debug("Destroy #%d %s", block->id, block->info->name);
437 rc_clear(block->id);
438 #endif /* DEBUG_COUNT_REFS */
439 if (block->info->free_mand != NULL)
440 block->info->free_mand(block);
442 g_free(block->mandatory_data);
443 wtap_block_free_options(block);
444 g_array_free(block->options, true);
445 g_free(block);
447 #ifdef DEBUG_COUNT_REFS
448 else {
449 wtap_debug("Unref #%d %s", block->id, block->info->name);
451 #endif /* DEBUG_COUNT_REFS */
455 void wtap_block_array_free(GArray* block_array)
457 unsigned block;
459 if (block_array == NULL)
460 return;
462 for (block = 0; block < block_array->len; block++) {
463 wtap_block_unref(g_array_index(block_array, wtap_block_t, block));
465 g_array_free(block_array, true);
468 void wtap_block_array_ref(GArray* block_array)
470 unsigned block;
472 if (block_array == NULL)
473 return;
475 for (block = 0; block < block_array->len; block++) {
476 wtap_block_ref(g_array_index(block_array, wtap_block_t, block));
478 g_array_ref(block_array);
481 void wtap_block_array_unref(GArray* block_array)
483 unsigned block;
485 if (block_array == NULL)
486 return;
488 for (block = 0; block < block_array->len; block++) {
489 wtap_block_unref(g_array_index(block_array, wtap_block_t, block));
491 g_array_unref(block_array);
495 * Make a copy of a block.
497 void
498 wtap_block_copy(wtap_block_t dest_block, wtap_block_t src_block)
500 unsigned i;
501 wtap_option_t *src_opt;
502 const wtap_opttype_t *opttype;
505 * Copy the mandatory data.
507 if (dest_block->info->copy_mand != NULL)
508 dest_block->info->copy_mand(dest_block, src_block);
510 /* Copy the options. For now, don't remove any options that are in destination
511 * but not source.
513 for (i = 0; i < src_block->options->len; i++)
515 src_opt = &g_array_index(src_block->options, wtap_option_t, i);
516 opttype = GET_OPTION_TYPE(src_block->info->options, src_opt->option_id);
518 switch(opttype->data_type) {
520 case WTAP_OPTTYPE_UINT8:
521 wtap_block_add_uint8_option(dest_block, src_opt->option_id, src_opt->value.uint8val);
522 break;
524 case WTAP_OPTTYPE_UINT32:
525 wtap_block_add_uint32_option(dest_block, src_opt->option_id, src_opt->value.uint32val);
526 break;
528 case WTAP_OPTTYPE_UINT64:
529 wtap_block_add_uint64_option(dest_block, src_opt->option_id, src_opt->value.uint64val);
530 break;
532 case WTAP_OPTTYPE_INT8:
533 wtap_block_add_int8_option(dest_block, src_opt->option_id, src_opt->value.int8val);
534 break;
536 case WTAP_OPTTYPE_INT32:
537 wtap_block_add_int32_option(dest_block, src_opt->option_id, src_opt->value.int32val);
538 break;
540 case WTAP_OPTTYPE_INT64:
541 wtap_block_add_int64_option(dest_block, src_opt->option_id, src_opt->value.int64val);
542 break;
544 case WTAP_OPTTYPE_IPv4:
545 wtap_block_add_ipv4_option(dest_block, src_opt->option_id, src_opt->value.ipv4val);
546 break;
548 case WTAP_OPTTYPE_IPv6:
549 wtap_block_add_ipv6_option(dest_block, src_opt->option_id, &src_opt->value.ipv6val);
550 break;
552 case WTAP_OPTTYPE_STRING:
553 wtap_block_add_string_option(dest_block, src_opt->option_id, src_opt->value.stringval, strlen(src_opt->value.stringval));
554 break;
556 case WTAP_OPTTYPE_BYTES:
557 wtap_block_add_bytes_option_borrow(dest_block, src_opt->option_id, src_opt->value.byteval);
558 break;
560 case WTAP_OPTTYPE_CUSTOM:
561 switch (src_opt->value.custom_opt.pen) {
562 case PEN_NFLX:
563 wtap_block_add_nflx_custom_option(dest_block, src_opt->value.custom_opt.data.nflx_data.type, src_opt->value.custom_opt.data.nflx_data.custom_data, src_opt->value.custom_opt.data.nflx_data.custom_data_len);
564 break;
565 default:
566 wtap_block_add_custom_option(dest_block, src_opt->option_id, src_opt->value.custom_opt.pen, src_opt->value.custom_opt.data.generic_data.custom_data, src_opt->value.custom_opt.data.generic_data.custom_data_len);
567 break;
569 break;
571 case WTAP_OPTTYPE_IF_FILTER:
572 wtap_block_add_if_filter_option(dest_block, src_opt->option_id, &src_opt->value.if_filterval);
573 break;
575 case WTAP_OPTTYPE_PACKET_VERDICT:
576 wtap_block_add_packet_verdict_option(dest_block, src_opt->option_id, &src_opt->value.packet_verdictval);
577 break;
579 case WTAP_OPTTYPE_PACKET_HASH:
580 wtap_block_add_packet_hash_option(dest_block, src_opt->option_id, &src_opt->value.packet_hash);
581 break;
586 wtap_block_t wtap_block_make_copy(wtap_block_t block)
588 wtap_block_t block_copy;
590 block_copy = wtap_block_create(block->info->block_type);
591 wtap_block_copy(block_copy, block);
592 return block_copy;
595 unsigned
596 wtap_block_count_option(wtap_block_t block, unsigned option_id)
598 unsigned i;
599 unsigned ret_val = 0;
600 wtap_option_t *opt;
602 if (block == NULL) {
603 return 0;
606 for (i = 0; i < block->options->len; i++) {
607 opt = &g_array_index(block->options, wtap_option_t, i);
608 if (opt->option_id == option_id)
609 ret_val++;
612 return ret_val;
616 bool wtap_block_foreach_option(wtap_block_t block, wtap_block_foreach_func func, void* user_data)
618 unsigned i;
619 wtap_option_t *opt;
620 const wtap_opttype_t *opttype;
622 if (block == NULL) {
623 return true;
626 for (i = 0; i < block->options->len; i++) {
627 opt = &g_array_index(block->options, wtap_option_t, i);
628 opttype = GET_OPTION_TYPE(block->info->options, opt->option_id);
629 if (!func(block, opt->option_id, opttype->data_type, &opt->value, user_data))
630 return false;
632 return true;
635 static wtap_opttype_return_val
636 wtap_block_add_option_common(wtap_block_t block, unsigned option_id, wtap_opttype_e type, wtap_option_t **optp)
638 wtap_option_t *opt;
639 const wtap_opttype_t *opttype;
640 unsigned i;
642 if (block == NULL) {
643 return WTAP_OPTTYPE_BAD_BLOCK;
646 opttype = GET_OPTION_TYPE(block->info->options, option_id);
647 if (opttype == NULL) {
648 /* There's no option for this block with that option ID */
649 return WTAP_OPTTYPE_NO_SUCH_OPTION;
653 * Is this an option of the specified data type?
655 if (opttype->data_type != type) {
657 * No.
659 return WTAP_OPTTYPE_TYPE_MISMATCH;
663 * Can there be more than one instance of this option?
665 if (!(opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED)) {
667 * No. Is there already an instance of this option?
669 if (wtap_block_get_option(block, option_id) != NULL) {
671 * Yes. Fail.
673 return WTAP_OPTTYPE_ALREADY_EXISTS;
678 * Add an instance.
680 i = block->options->len;
681 g_array_set_size(block->options, i + 1);
682 opt = &g_array_index(block->options, wtap_option_t, i);
683 opt->option_id = option_id;
684 *optp = opt;
685 return WTAP_OPTTYPE_SUCCESS;
688 static wtap_opttype_return_val
689 wtap_block_get_option_common(wtap_block_t block, unsigned option_id, wtap_opttype_e type, wtap_optval_t **optvalp)
691 const wtap_opttype_t *opttype;
692 wtap_optval_t *optval;
694 if (block == NULL) {
695 return WTAP_OPTTYPE_BAD_BLOCK;
698 opttype = GET_OPTION_TYPE(block->info->options, option_id);
699 if (opttype == NULL) {
700 /* There's no option for this block with that option ID */
701 return WTAP_OPTTYPE_NO_SUCH_OPTION;
705 * Is this an option of the specified data type?
707 if (opttype->data_type != type) {
709 * No.
711 return WTAP_OPTTYPE_TYPE_MISMATCH;
715 * Can there be more than one instance of this option?
717 if (opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED) {
719 * Yes. You can't ask for "the" value.
721 return WTAP_OPTTYPE_NUMBER_MISMATCH;
724 optval = wtap_block_get_option(block, option_id);
725 if (optval == NULL) {
726 /* Didn't find the option */
727 return WTAP_OPTTYPE_NOT_FOUND;
730 *optvalp = optval;
731 return WTAP_OPTTYPE_SUCCESS;
734 static wtap_opttype_return_val
735 wtap_block_get_nth_option_common(wtap_block_t block, unsigned option_id, wtap_opttype_e type, unsigned idx, wtap_optval_t **optvalp)
737 const wtap_opttype_t *opttype;
738 wtap_optval_t *optval;
740 if (block == NULL) {
741 return WTAP_OPTTYPE_BAD_BLOCK;
744 opttype = GET_OPTION_TYPE(block->info->options, option_id);
745 if (opttype == NULL) {
746 /* There's no option for this block with that option ID */
747 return WTAP_OPTTYPE_NO_SUCH_OPTION;
751 * Is this an option of the specified data type?
753 if (opttype->data_type != type) {
755 * No.
757 return WTAP_OPTTYPE_TYPE_MISMATCH;
761 * Can there be more than one instance of this option?
763 if (!(opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED)) {
765 * No.
767 return WTAP_OPTTYPE_NUMBER_MISMATCH;
770 optval = wtap_block_get_nth_option(block, option_id, idx);
771 if (optval == NULL) {
772 /* Didn't find the option */
773 return WTAP_OPTTYPE_NOT_FOUND;
776 *optvalp = optval;
777 return WTAP_OPTTYPE_SUCCESS;
780 wtap_opttype_return_val
781 wtap_block_add_uint8_option(wtap_block_t block, unsigned option_id, uint8_t value)
783 wtap_opttype_return_val ret;
784 wtap_option_t *opt;
786 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_UINT8, &opt);
787 if (ret != WTAP_OPTTYPE_SUCCESS)
788 return ret;
789 opt->value.uint8val = value;
790 return WTAP_OPTTYPE_SUCCESS;
793 wtap_opttype_return_val
794 wtap_block_set_uint8_option_value(wtap_block_t block, unsigned option_id, uint8_t value)
796 wtap_opttype_return_val ret;
797 wtap_optval_t *optval;
799 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT8, &optval);
800 if (ret != WTAP_OPTTYPE_SUCCESS)
801 return ret;
802 optval->uint8val = value;
803 return WTAP_OPTTYPE_SUCCESS;
806 wtap_opttype_return_val
807 wtap_block_get_uint8_option_value(wtap_block_t block, unsigned option_id, uint8_t* value)
809 wtap_opttype_return_val ret;
810 wtap_optval_t *optval;
812 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT8, &optval);
813 if (ret != WTAP_OPTTYPE_SUCCESS)
814 return ret;
815 *value = optval->uint8val;
816 return WTAP_OPTTYPE_SUCCESS;
819 wtap_opttype_return_val
820 wtap_block_add_uint32_option(wtap_block_t block, unsigned option_id, uint32_t value)
822 wtap_opttype_return_val ret;
823 wtap_option_t *opt;
825 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_UINT32, &opt);
826 if (ret != WTAP_OPTTYPE_SUCCESS)
827 return ret;
828 opt->value.uint32val = value;
829 return WTAP_OPTTYPE_SUCCESS;
832 wtap_opttype_return_val
833 wtap_block_set_uint32_option_value(wtap_block_t block, unsigned option_id, uint32_t value)
835 wtap_opttype_return_val ret;
836 wtap_optval_t *optval;
838 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT32, &optval);
839 if (ret != WTAP_OPTTYPE_SUCCESS)
840 return ret;
841 optval->uint32val = value;
842 return WTAP_OPTTYPE_SUCCESS;
845 wtap_opttype_return_val
846 wtap_block_get_uint32_option_value(wtap_block_t block, unsigned option_id, uint32_t* value)
848 wtap_opttype_return_val ret;
849 wtap_optval_t *optval;
851 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT32, &optval);
852 if (ret != WTAP_OPTTYPE_SUCCESS)
853 return ret;
854 *value = optval->uint32val;
855 return WTAP_OPTTYPE_SUCCESS;
858 wtap_opttype_return_val
859 wtap_block_add_uint64_option(wtap_block_t block, unsigned option_id, uint64_t value)
861 wtap_opttype_return_val ret;
862 wtap_option_t *opt;
864 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_UINT64, &opt);
865 if (ret != WTAP_OPTTYPE_SUCCESS)
866 return ret;
867 opt->value.uint64val = value;
868 return WTAP_OPTTYPE_SUCCESS;
871 wtap_opttype_return_val
872 wtap_block_set_uint64_option_value(wtap_block_t block, unsigned option_id, uint64_t value)
874 wtap_opttype_return_val ret;
875 wtap_optval_t *optval;
877 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT64, &optval);
878 if (ret != WTAP_OPTTYPE_SUCCESS)
879 return ret;
880 optval->uint64val = value;
881 return WTAP_OPTTYPE_SUCCESS;
884 wtap_opttype_return_val
885 wtap_block_get_uint64_option_value(wtap_block_t block, unsigned option_id, uint64_t *value)
887 wtap_opttype_return_val ret;
888 wtap_optval_t *optval;
890 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT64, &optval);
891 if (ret != WTAP_OPTTYPE_SUCCESS)
892 return ret;
893 *value = optval->uint64val;
894 return WTAP_OPTTYPE_SUCCESS;
897 wtap_opttype_return_val
898 wtap_block_add_int8_option(wtap_block_t block, unsigned option_id, int8_t value)
900 wtap_opttype_return_val ret;
901 wtap_option_t *opt;
903 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_INT8, &opt);
904 if (ret != WTAP_OPTTYPE_SUCCESS)
905 return ret;
906 opt->value.int8val = value;
907 return WTAP_OPTTYPE_SUCCESS;
910 wtap_opttype_return_val
911 wtap_block_set_int8_option_value(wtap_block_t block, unsigned option_id, int8_t value)
913 wtap_opttype_return_val ret;
914 wtap_optval_t *optval;
916 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_INT8, &optval);
917 if (ret != WTAP_OPTTYPE_SUCCESS)
918 return ret;
919 optval->int8val = value;
920 return WTAP_OPTTYPE_SUCCESS;
923 wtap_opttype_return_val
924 wtap_block_get_int8_option_value(wtap_block_t block, unsigned option_id, int8_t* value)
926 wtap_opttype_return_val ret;
927 wtap_optval_t *optval;
929 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_INT8, &optval);
930 if (ret != WTAP_OPTTYPE_SUCCESS)
931 return ret;
932 *value = optval->int8val;
933 return WTAP_OPTTYPE_SUCCESS;
936 wtap_opttype_return_val
937 wtap_block_add_int32_option(wtap_block_t block, unsigned option_id, int32_t value)
939 wtap_opttype_return_val ret;
940 wtap_option_t *opt;
942 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_INT32, &opt);
943 if (ret != WTAP_OPTTYPE_SUCCESS)
944 return ret;
945 opt->value.int32val = value;
946 return WTAP_OPTTYPE_SUCCESS;
949 wtap_opttype_return_val
950 wtap_block_set_int32_option_value(wtap_block_t block, unsigned option_id, int32_t value)
952 wtap_opttype_return_val ret;
953 wtap_optval_t *optval;
955 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_INT32, &optval);
956 if (ret != WTAP_OPTTYPE_SUCCESS)
957 return ret;
958 optval->int32val = value;
959 return WTAP_OPTTYPE_SUCCESS;
962 wtap_opttype_return_val
963 wtap_block_get_int32_option_value(wtap_block_t block, unsigned option_id, int32_t* value)
965 wtap_opttype_return_val ret;
966 wtap_optval_t *optval;
968 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_INT32, &optval);
969 if (ret != WTAP_OPTTYPE_SUCCESS)
970 return ret;
971 *value = optval->int32val;
972 return WTAP_OPTTYPE_SUCCESS;
975 wtap_opttype_return_val
976 wtap_block_add_int64_option(wtap_block_t block, unsigned option_id, int64_t value)
978 wtap_opttype_return_val ret;
979 wtap_option_t *opt;
981 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_INT64, &opt);
982 if (ret != WTAP_OPTTYPE_SUCCESS)
983 return ret;
984 opt->value.int64val = value;
985 return WTAP_OPTTYPE_SUCCESS;
988 wtap_opttype_return_val
989 wtap_block_set_int64_option_value(wtap_block_t block, unsigned option_id, int64_t value)
991 wtap_opttype_return_val ret;
992 wtap_optval_t *optval;
994 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_INT64, &optval);
995 if (ret != WTAP_OPTTYPE_SUCCESS)
996 return ret;
997 optval->int64val = value;
998 return WTAP_OPTTYPE_SUCCESS;
1001 wtap_opttype_return_val
1002 wtap_block_get_int64_option_value(wtap_block_t block, unsigned option_id, int64_t *value)
1004 wtap_opttype_return_val ret;
1005 wtap_optval_t *optval;
1007 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_INT64, &optval);
1008 if (ret != WTAP_OPTTYPE_SUCCESS)
1009 return ret;
1010 *value = optval->int64val;
1011 return WTAP_OPTTYPE_SUCCESS;
1014 wtap_opttype_return_val
1015 wtap_block_add_ipv4_option(wtap_block_t block, unsigned option_id, uint32_t value)
1017 wtap_opttype_return_val ret;
1018 wtap_option_t *opt;
1020 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_IPv4, &opt);
1021 if (ret != WTAP_OPTTYPE_SUCCESS)
1022 return ret;
1023 opt->value.ipv4val = value;
1024 return WTAP_OPTTYPE_SUCCESS;
1027 wtap_opttype_return_val
1028 wtap_block_set_ipv4_option_value(wtap_block_t block, unsigned option_id, uint32_t value)
1030 wtap_opttype_return_val ret;
1031 wtap_optval_t *optval;
1033 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IPv4, &optval);
1034 if (ret != WTAP_OPTTYPE_SUCCESS)
1035 return ret;
1036 optval->ipv4val = value;
1037 return WTAP_OPTTYPE_SUCCESS;
1040 wtap_opttype_return_val
1041 wtap_block_get_ipv4_option_value(wtap_block_t block, unsigned option_id, uint32_t* value)
1043 wtap_opttype_return_val ret;
1044 wtap_optval_t *optval;
1046 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IPv4, &optval);
1047 if (ret != WTAP_OPTTYPE_SUCCESS)
1048 return ret;
1049 *value = optval->ipv4val;
1050 return WTAP_OPTTYPE_SUCCESS;
1053 wtap_opttype_return_val
1054 wtap_block_add_ipv6_option(wtap_block_t block, unsigned option_id, ws_in6_addr *value)
1056 wtap_opttype_return_val ret;
1057 wtap_option_t *opt;
1059 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_IPv6, &opt);
1060 if (ret != WTAP_OPTTYPE_SUCCESS)
1061 return ret;
1062 opt->value.ipv6val = *value;
1063 return WTAP_OPTTYPE_SUCCESS;
1066 wtap_opttype_return_val
1067 wtap_block_set_ipv6_option_value(wtap_block_t block, unsigned option_id, ws_in6_addr *value)
1069 wtap_opttype_return_val ret;
1070 wtap_optval_t *optval;
1072 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IPv6, &optval);
1073 if (ret != WTAP_OPTTYPE_SUCCESS)
1074 return ret;
1075 optval->ipv6val = *value;
1076 return WTAP_OPTTYPE_SUCCESS;
1079 wtap_opttype_return_val
1080 wtap_block_get_ipv6_option_value(wtap_block_t block, unsigned option_id, ws_in6_addr* value)
1082 wtap_opttype_return_val ret;
1083 wtap_optval_t *optval;
1085 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IPv6, &optval);
1086 if (ret != WTAP_OPTTYPE_SUCCESS)
1087 return ret;
1088 *value = optval->ipv6val;
1089 return WTAP_OPTTYPE_SUCCESS;
1092 wtap_opttype_return_val
1093 wtap_block_add_string_option(wtap_block_t block, unsigned option_id, const char *value, size_t value_length)
1095 wtap_opttype_return_val ret;
1096 wtap_option_t *opt;
1098 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_STRING, &opt);
1099 if (ret != WTAP_OPTTYPE_SUCCESS)
1100 return ret;
1101 opt->value.stringval = g_strndup(value, value_length);
1102 WS_UTF_8_CHECK(opt->value.stringval, -1);
1103 return WTAP_OPTTYPE_SUCCESS;
1106 wtap_opttype_return_val
1107 wtap_block_add_string_option_owned(wtap_block_t block, unsigned option_id, char *value)
1109 wtap_opttype_return_val ret;
1110 wtap_option_t *opt;
1112 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_STRING, &opt);
1113 if (ret != WTAP_OPTTYPE_SUCCESS)
1114 return ret;
1115 opt->value.stringval = value;
1116 WS_UTF_8_CHECK(opt->value.stringval, -1);
1117 return WTAP_OPTTYPE_SUCCESS;
1120 static wtap_opttype_return_val
1121 wtap_block_add_string_option_vformat(wtap_block_t block, unsigned option_id, const char *format, va_list va)
1123 wtap_opttype_return_val ret;
1124 wtap_option_t *opt;
1126 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_STRING, &opt);
1127 if (ret != WTAP_OPTTYPE_SUCCESS)
1128 return ret;
1129 opt->value.stringval = ws_strdup_vprintf(format, va);
1130 WS_UTF_8_CHECK(opt->value.stringval, -1);
1131 return WTAP_OPTTYPE_SUCCESS;
1134 wtap_opttype_return_val
1135 wtap_block_add_string_option_format(wtap_block_t block, unsigned option_id, const char *format, ...)
1137 wtap_opttype_return_val ret;
1138 wtap_option_t *opt;
1139 va_list va;
1141 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_STRING, &opt);
1142 if (ret != WTAP_OPTTYPE_SUCCESS)
1143 return ret;
1144 va_start(va, format);
1145 opt->value.stringval = ws_strdup_vprintf(format, va);
1146 va_end(va);
1147 return WTAP_OPTTYPE_SUCCESS;
1150 wtap_opttype_return_val
1151 wtap_block_set_string_option_value(wtap_block_t block, unsigned option_id, const char *value, size_t value_length)
1153 wtap_opttype_return_val ret;
1154 wtap_optval_t *optval;
1156 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_STRING, &optval);
1157 if (ret != WTAP_OPTTYPE_SUCCESS) {
1158 if (ret == WTAP_OPTTYPE_NOT_FOUND) {
1160 * There's no instance to set, so just try to create a new one
1161 * with the value.
1163 return wtap_block_add_string_option(block, option_id, value, value_length);
1165 /* Otherwise fail. */
1166 return ret;
1168 g_free(optval->stringval);
1169 optval->stringval = g_strndup(value, value_length);
1170 return WTAP_OPTTYPE_SUCCESS;
1173 wtap_opttype_return_val
1174 wtap_block_set_nth_string_option_value(wtap_block_t block, unsigned option_id, unsigned idx, const char *value, size_t value_length)
1176 wtap_opttype_return_val ret;
1177 wtap_optval_t *optval;
1179 ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_STRING, idx, &optval);
1180 if (ret != WTAP_OPTTYPE_SUCCESS)
1181 return ret;
1182 g_free(optval->stringval);
1183 optval->stringval = g_strndup(value, value_length);
1184 return WTAP_OPTTYPE_SUCCESS;
1187 wtap_opttype_return_val
1188 wtap_block_set_string_option_value_format(wtap_block_t block, unsigned option_id, const char *format, ...)
1190 wtap_opttype_return_val ret;
1191 wtap_optval_t *optval;
1192 va_list va;
1194 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_STRING, &optval);
1195 if (ret != WTAP_OPTTYPE_SUCCESS) {
1196 if (ret == WTAP_OPTTYPE_NOT_FOUND) {
1198 * There's no instance to set, so just try to create a new one
1199 * with the formatted string.
1201 va_start(va, format);
1202 ret = wtap_block_add_string_option_vformat(block, option_id, format, va);
1203 va_end(va);
1204 return ret;
1206 /* Otherwise fail. */
1207 return ret;
1209 g_free(optval->stringval);
1210 va_start(va, format);
1211 optval->stringval = ws_strdup_vprintf(format, va);
1212 va_end(va);
1213 return WTAP_OPTTYPE_SUCCESS;
1216 wtap_opttype_return_val
1217 wtap_block_set_nth_string_option_value_format(wtap_block_t block, unsigned option_id, unsigned idx, const char *format, ...)
1219 wtap_opttype_return_val ret;
1220 wtap_optval_t *optval;
1221 va_list va;
1223 ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_STRING, idx, &optval);
1224 if (ret != WTAP_OPTTYPE_SUCCESS)
1225 return ret;
1226 g_free(optval->stringval);
1227 va_start(va, format);
1228 optval->stringval = ws_strdup_vprintf(format, va);
1229 va_end(va);
1230 return WTAP_OPTTYPE_SUCCESS;
1233 wtap_opttype_return_val
1234 wtap_block_get_string_option_value(wtap_block_t block, unsigned option_id, char** value)
1236 wtap_opttype_return_val ret;
1237 wtap_optval_t *optval;
1239 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_STRING, &optval);
1240 if (ret != WTAP_OPTTYPE_SUCCESS)
1241 return ret;
1242 *value = optval->stringval;
1243 return WTAP_OPTTYPE_SUCCESS;
1246 wtap_opttype_return_val
1247 wtap_block_get_nth_string_option_value(wtap_block_t block, unsigned option_id, unsigned idx, char** value)
1249 wtap_opttype_return_val ret;
1250 wtap_optval_t *optval;
1252 ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_STRING, idx, &optval);
1253 if (ret != WTAP_OPTTYPE_SUCCESS)
1254 return ret;
1255 *value = optval->stringval;
1256 return WTAP_OPTTYPE_SUCCESS;
1259 wtap_opttype_return_val
1260 wtap_block_add_bytes_option(wtap_block_t block, unsigned option_id, const uint8_t *value, size_t value_length)
1262 wtap_opttype_return_val ret;
1263 wtap_option_t *opt;
1265 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_BYTES, &opt);
1266 if (ret != WTAP_OPTTYPE_SUCCESS)
1267 return ret;
1268 opt->value.byteval = g_bytes_new(value, value_length);
1269 return WTAP_OPTTYPE_SUCCESS;
1272 wtap_opttype_return_val
1273 wtap_block_add_bytes_option_borrow(wtap_block_t block, unsigned option_id, GBytes *value)
1275 wtap_opttype_return_val ret;
1276 wtap_option_t *opt;
1278 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_BYTES, &opt);
1279 if (ret != WTAP_OPTTYPE_SUCCESS)
1280 return ret;
1281 opt->value.byteval = g_bytes_ref(value);
1282 return WTAP_OPTTYPE_SUCCESS;
1285 wtap_opttype_return_val
1286 wtap_block_set_bytes_option_value(wtap_block_t block, unsigned option_id, const uint8_t *value, size_t value_length)
1288 wtap_opttype_return_val ret;
1289 wtap_optval_t *optval;
1291 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_BYTES, &optval);
1292 if (ret != WTAP_OPTTYPE_SUCCESS) {
1293 if (ret == WTAP_OPTTYPE_NOT_FOUND) {
1295 * There's no instance to set, so just try to create a new one
1296 * with the value.
1298 return wtap_block_add_bytes_option(block, option_id, value, value_length);
1300 /* Otherwise fail. */
1301 return ret;
1303 g_bytes_unref(optval->byteval);
1304 optval->byteval = g_bytes_new(value, value_length);
1305 return WTAP_OPTTYPE_SUCCESS;
1308 wtap_opttype_return_val
1309 wtap_block_set_nth_bytes_option_value(wtap_block_t block, unsigned option_id, unsigned idx, GBytes *value)
1311 wtap_opttype_return_val ret;
1312 wtap_optval_t *optval;
1314 ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_BYTES, idx, &optval);
1315 if (ret != WTAP_OPTTYPE_SUCCESS)
1316 return ret;
1317 g_bytes_unref(optval->byteval);
1318 optval->byteval = g_bytes_ref(value);
1319 return WTAP_OPTTYPE_SUCCESS;
1322 wtap_opttype_return_val
1323 wtap_block_get_bytes_option_value(wtap_block_t block, unsigned option_id, GBytes** value)
1325 wtap_opttype_return_val ret;
1326 wtap_optval_t *optval;
1328 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_BYTES, &optval);
1329 if (ret != WTAP_OPTTYPE_SUCCESS)
1330 return ret;
1331 *value = optval->byteval;
1332 return WTAP_OPTTYPE_SUCCESS;
1335 wtap_opttype_return_val
1336 wtap_block_get_nth_bytes_option_value(wtap_block_t block, unsigned option_id, unsigned idx, GBytes** value)
1338 wtap_opttype_return_val ret;
1339 wtap_optval_t *optval;
1341 ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_BYTES, idx, &optval);
1342 if (ret != WTAP_OPTTYPE_SUCCESS)
1343 return ret;
1344 *value = optval->byteval;
1345 return WTAP_OPTTYPE_SUCCESS;
1348 wtap_opttype_return_val
1349 wtap_block_add_nflx_custom_option(wtap_block_t block, uint32_t type, const char *custom_data, size_t custom_data_len)
1351 wtap_opttype_return_val ret;
1352 wtap_option_t *opt;
1354 ret = wtap_block_add_option_common(block, OPT_CUSTOM_BIN_COPY, WTAP_OPTTYPE_CUSTOM, &opt);
1355 if (ret != WTAP_OPTTYPE_SUCCESS)
1356 return ret;
1357 opt->value.custom_opt.pen = PEN_NFLX;
1358 opt->value.custom_opt.data.nflx_data.type = type;
1359 opt->value.custom_opt.data.nflx_data.custom_data_len = custom_data_len;
1360 opt->value.custom_opt.data.nflx_data.custom_data = g_memdup2(custom_data, custom_data_len);
1361 opt->value.custom_opt.data.nflx_data.use_little_endian = (block->info->block_type == WTAP_BLOCK_CUSTOM);
1362 return WTAP_OPTTYPE_SUCCESS;
1365 wtap_opttype_return_val
1366 wtap_block_get_nflx_custom_option(wtap_block_t block, uint32_t nflx_type, char *nflx_custom_data _U_, size_t nflx_custom_data_len)
1368 const wtap_opttype_t *opttype;
1369 wtap_option_t *opt;
1370 unsigned i;
1372 if (block == NULL) {
1373 return WTAP_OPTTYPE_BAD_BLOCK;
1375 opttype = GET_OPTION_TYPE(block->info->options, OPT_CUSTOM_BIN_COPY);
1376 if (opttype == NULL) {
1377 return WTAP_OPTTYPE_NO_SUCH_OPTION;
1379 if (opttype->data_type != WTAP_OPTTYPE_CUSTOM) {
1380 return WTAP_OPTTYPE_TYPE_MISMATCH;
1383 for (i = 0; i < block->options->len; i++) {
1384 opt = &g_array_index(block->options, wtap_option_t, i);
1385 if ((opt->option_id == OPT_CUSTOM_BIN_COPY) &&
1386 (opt->value.custom_opt.pen == PEN_NFLX) &&
1387 (opt->value.custom_opt.data.nflx_data.type == nflx_type)) {
1388 break;
1391 if (i == block->options->len) {
1392 return WTAP_OPTTYPE_NOT_FOUND;
1394 if (nflx_custom_data_len < opt->value.custom_opt.data.nflx_data.custom_data_len) {
1395 return WTAP_OPTTYPE_TYPE_MISMATCH;
1397 switch (nflx_type) {
1398 case NFLX_OPT_TYPE_VERSION: {
1399 uint32_t *src, *dst;
1401 ws_assert(nflx_custom_data_len == sizeof(uint32_t));
1402 src = (uint32_t *)opt->value.custom_opt.data.nflx_data.custom_data;
1403 dst = (uint32_t *)nflx_custom_data;
1404 *dst = GUINT32_FROM_LE(*src);
1405 break;
1407 case NFLX_OPT_TYPE_TCPINFO: {
1408 struct nflx_tcpinfo *src, *dst;
1410 ws_assert(nflx_custom_data_len == sizeof(struct nflx_tcpinfo));
1411 src = (struct nflx_tcpinfo *)opt->value.custom_opt.data.nflx_data.custom_data;
1412 dst = (struct nflx_tcpinfo *)nflx_custom_data;
1413 dst->tlb_tv_sec = GUINT64_FROM_LE(src->tlb_tv_sec);
1414 dst->tlb_tv_usec = GUINT64_FROM_LE(src->tlb_tv_usec);
1415 dst->tlb_ticks = GUINT32_FROM_LE(src->tlb_ticks);
1416 dst->tlb_sn = GUINT32_FROM_LE(src->tlb_sn);
1417 dst->tlb_stackid = src->tlb_stackid;
1418 dst->tlb_eventid = src->tlb_eventid;
1419 dst->tlb_eventflags = GUINT16_FROM_LE(src->tlb_eventflags);
1420 dst->tlb_errno = GINT32_FROM_LE(src->tlb_errno);
1421 dst->tlb_rxbuf_tls_sb_acc = GUINT32_FROM_LE(src->tlb_rxbuf_tls_sb_acc);
1422 dst->tlb_rxbuf_tls_sb_ccc = GUINT32_FROM_LE(src->tlb_rxbuf_tls_sb_ccc);
1423 dst->tlb_rxbuf_tls_sb_spare = GUINT32_FROM_LE(src->tlb_rxbuf_tls_sb_spare);
1424 dst->tlb_txbuf_tls_sb_acc = GUINT32_FROM_LE(src->tlb_txbuf_tls_sb_acc);
1425 dst->tlb_txbuf_tls_sb_ccc = GUINT32_FROM_LE(src->tlb_txbuf_tls_sb_ccc);
1426 dst->tlb_txbuf_tls_sb_spare = GUINT32_FROM_LE(src->tlb_txbuf_tls_sb_spare);
1427 dst->tlb_state = GINT32_FROM_LE(src->tlb_state);
1428 dst->tlb_starttime = GUINT32_FROM_LE(src->tlb_starttime);
1429 dst->tlb_iss = GUINT32_FROM_LE(src->tlb_iss);
1430 dst->tlb_flags = GUINT32_FROM_LE(src->tlb_flags);
1431 dst->tlb_snd_una = GUINT32_FROM_LE(src->tlb_snd_una);
1432 dst->tlb_snd_max = GUINT32_FROM_LE(src->tlb_snd_max);
1433 dst->tlb_snd_cwnd = GUINT32_FROM_LE(src->tlb_snd_cwnd);
1434 dst->tlb_snd_nxt = GUINT32_FROM_LE(src->tlb_snd_nxt);
1435 dst->tlb_snd_recover = GUINT32_FROM_LE(src->tlb_snd_recover);
1436 dst->tlb_snd_wnd = GUINT32_FROM_LE(src->tlb_snd_wnd);
1437 dst->tlb_snd_ssthresh = GUINT32_FROM_LE(src->tlb_snd_ssthresh);
1438 dst->tlb_srtt = GUINT32_FROM_LE(src->tlb_srtt);
1439 dst->tlb_rttvar = GUINT32_FROM_LE(src->tlb_rttvar);
1440 dst->tlb_rcv_up = GUINT32_FROM_LE(src->tlb_rcv_up);
1441 dst->tlb_rcv_adv = GUINT32_FROM_LE(src->tlb_rcv_adv);
1442 dst->tlb_flags2 = GUINT32_FROM_LE(src->tlb_flags2);
1443 dst->tlb_rcv_nxt = GUINT32_FROM_LE(src->tlb_rcv_nxt);
1444 dst->tlb_rcv_wnd = GUINT32_FROM_LE(src->tlb_rcv_wnd);
1445 dst->tlb_dupacks = GUINT32_FROM_LE(src->tlb_dupacks);
1446 dst->tlb_segqlen = GINT32_FROM_LE(src->tlb_segqlen);
1447 dst->tlb_snd_numholes = GINT32_FROM_LE(src->tlb_snd_numholes);
1448 dst->tlb_flex1 = GUINT32_FROM_LE(src->tlb_flex1);
1449 dst->tlb_flex2 = GUINT32_FROM_LE(src->tlb_flex2);
1450 dst->tlb_fbyte_in = GUINT32_FROM_LE(src->tlb_fbyte_in);
1451 dst->tlb_fbyte_out = GUINT32_FROM_LE(src->tlb_fbyte_out);
1452 dst->tlb_snd_scale = src->tlb_snd_scale;
1453 dst->tlb_rcv_scale = src->tlb_rcv_scale;
1454 for (i = 0; i < 3; i++) {
1455 dst->_pad[i] = src->_pad[i];
1457 dst->tlb_stackinfo_bbr_cur_del_rate = GUINT64_FROM_LE(src->tlb_stackinfo_bbr_cur_del_rate);
1458 dst->tlb_stackinfo_bbr_delRate = GUINT64_FROM_LE(src->tlb_stackinfo_bbr_delRate);
1459 dst->tlb_stackinfo_bbr_rttProp = GUINT64_FROM_LE(src->tlb_stackinfo_bbr_rttProp);
1460 dst->tlb_stackinfo_bbr_bw_inuse = GUINT64_FROM_LE(src->tlb_stackinfo_bbr_bw_inuse);
1461 dst->tlb_stackinfo_bbr_inflight = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_inflight);
1462 dst->tlb_stackinfo_bbr_applimited = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_applimited);
1463 dst->tlb_stackinfo_bbr_delivered = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_delivered);
1464 dst->tlb_stackinfo_bbr_timeStamp = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_timeStamp);
1465 dst->tlb_stackinfo_bbr_epoch = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_epoch);
1466 dst->tlb_stackinfo_bbr_lt_epoch = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_lt_epoch);
1467 dst->tlb_stackinfo_bbr_pkts_out = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_pkts_out);
1468 dst->tlb_stackinfo_bbr_flex1 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex1);
1469 dst->tlb_stackinfo_bbr_flex2 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex2);
1470 dst->tlb_stackinfo_bbr_flex3 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex3);
1471 dst->tlb_stackinfo_bbr_flex4 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex4);
1472 dst->tlb_stackinfo_bbr_flex5 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex5);
1473 dst->tlb_stackinfo_bbr_flex6 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex6);
1474 dst->tlb_stackinfo_bbr_lost = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_lost);
1475 dst->tlb_stackinfo_bbr_pacing_gain = GUINT16_FROM_LE(src->tlb_stackinfo_bbr_lost);
1476 dst->tlb_stackinfo_bbr_cwnd_gain = GUINT16_FROM_LE(src->tlb_stackinfo_bbr_lost);
1477 dst->tlb_stackinfo_bbr_flex7 = GUINT16_FROM_LE(src->tlb_stackinfo_bbr_flex7);
1478 dst->tlb_stackinfo_bbr_bbr_state = src->tlb_stackinfo_bbr_bbr_state;
1479 dst->tlb_stackinfo_bbr_bbr_substate = src->tlb_stackinfo_bbr_bbr_substate;
1480 dst->tlb_stackinfo_bbr_inhpts = src->tlb_stackinfo_bbr_inhpts;
1481 dst->tlb_stackinfo_bbr_ininput = src->tlb_stackinfo_bbr_ininput;
1482 dst->tlb_stackinfo_bbr_use_lt_bw = src->tlb_stackinfo_bbr_use_lt_bw;
1483 dst->tlb_stackinfo_bbr_flex8 = src->tlb_stackinfo_bbr_flex8;
1484 dst->tlb_stackinfo_bbr_pkt_epoch = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_pkt_epoch);
1485 dst->tlb_len = GUINT32_FROM_LE(src->tlb_len);
1486 break;
1488 case NFLX_OPT_TYPE_DUMPINFO: {
1489 struct nflx_dumpinfo *src, *dst;
1491 ws_assert(nflx_custom_data_len == sizeof(struct nflx_dumpinfo));
1492 src = (struct nflx_dumpinfo *)opt->value.custom_opt.data.nflx_data.custom_data;
1493 dst = (struct nflx_dumpinfo *)nflx_custom_data;
1494 dst->tlh_version = GUINT32_FROM_LE(src->tlh_version);
1495 dst->tlh_type = GUINT32_FROM_LE(src->tlh_type);
1496 dst->tlh_length = GUINT64_FROM_LE(src->tlh_length);
1497 dst->tlh_ie_fport = src->tlh_ie_fport;
1498 dst->tlh_ie_lport = src->tlh_ie_lport;
1499 for (i = 0; i < 4; i++) {
1500 dst->tlh_ie_faddr_addr32[i] = src->tlh_ie_faddr_addr32[i];
1501 dst->tlh_ie_laddr_addr32[i] = src->tlh_ie_laddr_addr32[i];
1503 dst->tlh_ie_zoneid = src->tlh_ie_zoneid;
1504 dst->tlh_offset_tv_sec = GUINT64_FROM_LE(src->tlh_offset_tv_sec);
1505 dst->tlh_offset_tv_usec = GUINT64_FROM_LE(src->tlh_offset_tv_usec);
1506 memcpy(dst->tlh_id, src->tlh_id, 64);
1507 memcpy(dst->tlh_reason, src->tlh_reason, 32);
1508 memcpy(dst->tlh_tag, src->tlh_tag, 32);
1509 dst->tlh_af = src->tlh_af;
1510 memcpy(dst->_pad, src->_pad, 7);
1511 break;
1513 case NFLX_OPT_TYPE_DUMPTIME: {
1514 uint64_t *src, *dst;
1516 ws_assert(nflx_custom_data_len == sizeof(uint64_t));
1517 src = (uint64_t *)opt->value.custom_opt.data.nflx_data.custom_data;
1518 dst = (uint64_t *)nflx_custom_data;
1519 *dst = GUINT64_FROM_LE(*src);
1520 break;
1522 case NFLX_OPT_TYPE_STACKNAME:
1523 ws_assert(nflx_custom_data_len >= 2);
1524 memcpy(nflx_custom_data, opt->value.custom_opt.data.nflx_data.custom_data, nflx_custom_data_len);
1525 break;
1526 default:
1527 return WTAP_OPTTYPE_NOT_FOUND;
1529 return WTAP_OPTTYPE_SUCCESS;
1532 wtap_opttype_return_val
1533 wtap_block_add_custom_option(wtap_block_t block, unsigned option_id, uint32_t pen, const char *custom_data, size_t custom_data_len)
1535 wtap_opttype_return_val ret;
1536 wtap_option_t *opt;
1538 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_CUSTOM, &opt);
1539 if (ret != WTAP_OPTTYPE_SUCCESS)
1540 return ret;
1541 opt->value.custom_opt.pen = pen;
1542 opt->value.custom_opt.data.generic_data.custom_data_len = custom_data_len;
1543 opt->value.custom_opt.data.generic_data.custom_data = g_memdup2(custom_data, custom_data_len);
1544 return WTAP_OPTTYPE_SUCCESS;
1547 wtap_opttype_return_val
1548 wtap_block_add_if_filter_option(wtap_block_t block, unsigned option_id, if_filter_opt_t* value)
1550 wtap_opttype_return_val ret;
1551 wtap_option_t *opt;
1553 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_IF_FILTER, &opt);
1554 if (ret != WTAP_OPTTYPE_SUCCESS)
1555 return ret;
1556 opt->value.if_filterval = if_filter_dup(value);
1557 return WTAP_OPTTYPE_SUCCESS;
1560 wtap_opttype_return_val
1561 wtap_block_set_if_filter_option_value(wtap_block_t block, unsigned option_id, if_filter_opt_t* value)
1563 wtap_opttype_return_val ret;
1564 wtap_optval_t *optval;
1565 if_filter_opt_t prev_value;
1567 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IF_FILTER, &optval);
1568 if (ret != WTAP_OPTTYPE_SUCCESS)
1569 return ret;
1570 prev_value = optval->if_filterval;
1571 optval->if_filterval = if_filter_dup(value);
1572 /* Free after memory is duplicated in case structure was manipulated with a "get then set" */
1573 if_filter_free(&prev_value);
1575 return WTAP_OPTTYPE_SUCCESS;
1578 wtap_opttype_return_val
1579 wtap_block_get_if_filter_option_value(wtap_block_t block, unsigned option_id, if_filter_opt_t* value)
1581 wtap_opttype_return_val ret;
1582 wtap_optval_t *optval;
1584 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IF_FILTER, &optval);
1585 if (ret != WTAP_OPTTYPE_SUCCESS)
1586 return ret;
1587 *value = optval->if_filterval;
1588 return WTAP_OPTTYPE_SUCCESS;
1591 wtap_opttype_return_val
1592 wtap_block_add_packet_verdict_option(wtap_block_t block, unsigned option_id, packet_verdict_opt_t* value)
1594 wtap_opttype_return_val ret;
1595 wtap_option_t *opt;
1597 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_PACKET_VERDICT, &opt);
1598 if (ret != WTAP_OPTTYPE_SUCCESS)
1599 return ret;
1600 opt->value.packet_verdictval = packet_verdict_dup(value);
1601 return WTAP_OPTTYPE_SUCCESS;
1604 wtap_opttype_return_val
1605 wtap_block_set_nth_packet_verdict_option_value(wtap_block_t block, unsigned option_id, unsigned idx, packet_verdict_opt_t* value)
1607 wtap_opttype_return_val ret;
1608 wtap_optval_t *optval;
1609 packet_verdict_opt_t prev_value;
1611 ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_PACKET_VERDICT, idx, &optval);
1612 if (ret != WTAP_OPTTYPE_SUCCESS)
1613 return ret;
1614 prev_value = optval->packet_verdictval;
1615 optval->packet_verdictval = packet_verdict_dup(value);
1616 /* Free after memory is duplicated in case structure was manipulated with a "get then set" */
1617 wtap_packet_verdict_free(&prev_value);
1619 return WTAP_OPTTYPE_SUCCESS;
1622 wtap_opttype_return_val
1623 wtap_block_get_nth_packet_verdict_option_value(wtap_block_t block, unsigned option_id, unsigned idx, packet_verdict_opt_t* value)
1625 wtap_opttype_return_val ret;
1626 wtap_optval_t *optval;
1628 ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_STRING, idx, &optval);
1629 if (ret != WTAP_OPTTYPE_SUCCESS)
1630 return ret;
1631 *value = optval->packet_verdictval;
1632 return WTAP_OPTTYPE_SUCCESS;
1635 wtap_opttype_return_val
1636 wtap_block_add_packet_hash_option(wtap_block_t block, unsigned option_id, packet_hash_opt_t* value)
1638 wtap_opttype_return_val ret;
1639 wtap_option_t *opt;
1641 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_PACKET_HASH, &opt);
1642 if (ret != WTAP_OPTTYPE_SUCCESS)
1643 return ret;
1644 opt->value.packet_hash = packet_hash_dup(value);
1645 return WTAP_OPTTYPE_SUCCESS;
1648 wtap_opttype_return_val
1649 wtap_block_remove_option(wtap_block_t block, unsigned option_id)
1651 const wtap_opttype_t *opttype;
1652 unsigned i;
1653 wtap_option_t *opt;
1655 if (block == NULL) {
1656 return WTAP_OPTTYPE_BAD_BLOCK;
1659 opttype = GET_OPTION_TYPE(block->info->options, option_id);
1660 if (opttype == NULL) {
1661 /* There's no option for this block with that option ID */
1662 return WTAP_OPTTYPE_NO_SUCH_OPTION;
1666 * Can there be more than one instance of this option?
1668 if (opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED) {
1670 * Yes. You can't remove "the" value.
1672 return WTAP_OPTTYPE_NUMBER_MISMATCH;
1675 for (i = 0; i < block->options->len; i++) {
1676 opt = &g_array_index(block->options, wtap_option_t, i);
1677 if (opt->option_id == option_id) {
1678 /* Found it - free up the value */
1679 wtap_block_free_option(block, opt);
1680 /* Remove the option from the array of options */
1681 g_array_remove_index(block->options, i);
1682 return WTAP_OPTTYPE_SUCCESS;
1686 /* Didn't find the option */
1687 return WTAP_OPTTYPE_NOT_FOUND;
1690 wtap_opttype_return_val
1691 wtap_block_remove_nth_option_instance(wtap_block_t block, unsigned option_id,
1692 unsigned idx)
1694 const wtap_opttype_t *opttype;
1695 unsigned i;
1696 wtap_option_t *opt;
1697 unsigned opt_idx;
1699 if (block == NULL) {
1700 return WTAP_OPTTYPE_BAD_BLOCK;
1703 opttype = GET_OPTION_TYPE(block->info->options, option_id);
1704 if (opttype == NULL) {
1705 /* There's no option for this block with that option ID */
1706 return WTAP_OPTTYPE_NO_SUCH_OPTION;
1710 * Can there be more than one instance of this option?
1712 if (!(opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED)) {
1714 * No.
1716 return WTAP_OPTTYPE_NUMBER_MISMATCH;
1719 opt_idx = 0;
1720 for (i = 0; i < block->options->len; i++) {
1721 opt = &g_array_index(block->options, wtap_option_t, i);
1722 if (opt->option_id == option_id) {
1723 if (opt_idx == idx) {
1724 /* Found it - free up the value */
1725 wtap_block_free_option(block, opt);
1726 /* Remove the option from the array of options */
1727 g_array_remove_index(block->options, i);
1728 return WTAP_OPTTYPE_SUCCESS;
1730 opt_idx++;
1734 /* Didn't find the option */
1735 return WTAP_OPTTYPE_NOT_FOUND;
1738 static void shb_create(wtap_block_t block)
1740 wtapng_section_mandatory_t* section_mand = g_new(wtapng_section_mandatory_t, 1);
1742 section_mand->section_length = -1;
1744 block->mandatory_data = section_mand;
1747 static void shb_copy_mand(wtap_block_t dest_block, wtap_block_t src_block)
1749 memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_section_mandatory_t));
1752 static void nrb_create(wtap_block_t block)
1754 block->mandatory_data = g_new0(wtapng_nrb_mandatory_t, 1);
1757 static void nrb_free_mand(wtap_block_t block)
1759 wtapng_nrb_mandatory_t *mand = (wtapng_nrb_mandatory_t *)block->mandatory_data;
1760 g_list_free_full(mand->ipv4_addr_list, g_free);
1761 g_list_free_full(mand->ipv6_addr_list, g_free);
1764 #if 0
1765 static void *copy_hashipv4(const void *src, void *user_data _U_
1767 hashipv4_t *src_ipv4 = (hashipv4_t*)src;
1768 hashipv4_t *dst = g_new0(hashipv4_t, 1);
1769 dst->addr = src_ipv4->addr;
1770 (void) g_strlcpy(dst->name, src_ipv4->name, MAXDNSNAMELEN);
1771 return dst;
1774 static void *copy_hashipv4(const void *src, void *user_data _U_
1776 hashipv6_t *src_ipv6 = (hashipv6_t*)src;
1777 hashipv6_t *dst = g_new0(hashipv6_t, 1);
1778 dst->addr = src_ipv4->addr;
1779 (void) g_strlcpy(dst->name, src_ipv4->name, MAXDNSNAMELEN);
1780 return dst;
1783 static void nrb_copy_mand(wtap_block_t dest_block, wtap_block_t src_block)
1785 wtapng_nrb_mandatory_t *src = (wtapng_nrb_mandatory_t *)src_block->mandatory_data;
1786 wtapng_nrb_mandatory_t *dst = (wtapng_nrb_mandatory_t *)dest_block->mandatory_data;
1787 g_list_free_full(dst->ipv4_addr_list, g_free);
1788 g_list_free_full(dst->ipv6_addr_list, g_free);
1789 dst->ipv4_addr_list = g_list_copy_deep(src->ipv4_addr_list, copy_hashipv4, NULL);
1790 dst->ipv6_addr_list = g_list_copy_deep(src->ipv6_addr_list, copy_hashipv6, NULL);
1792 #endif
1794 static void isb_create(wtap_block_t block)
1796 block->mandatory_data = g_new0(wtapng_if_stats_mandatory_t, 1);
1799 static void isb_copy_mand(wtap_block_t dest_block, wtap_block_t src_block)
1801 memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_if_stats_mandatory_t));
1804 static void idb_create(wtap_block_t block)
1806 block->mandatory_data = g_new0(wtapng_if_descr_mandatory_t, 1);
1809 static void idb_free_mand(wtap_block_t block)
1811 unsigned j;
1812 wtap_block_t if_stats;
1813 wtapng_if_descr_mandatory_t* mand = (wtapng_if_descr_mandatory_t*)block->mandatory_data;
1815 for(j = 0; j < mand->num_stat_entries; j++) {
1816 if_stats = g_array_index(mand->interface_statistics, wtap_block_t, j);
1817 wtap_block_unref(if_stats);
1820 if (mand->interface_statistics)
1821 g_array_free(mand->interface_statistics, true);
1824 static void idb_copy_mand(wtap_block_t dest_block, wtap_block_t src_block)
1826 unsigned j;
1827 wtap_block_t src_if_stats, dest_if_stats;
1828 wtapng_if_descr_mandatory_t *src_mand = (wtapng_if_descr_mandatory_t*)src_block->mandatory_data,
1829 *dest_mand = (wtapng_if_descr_mandatory_t*)dest_block->mandatory_data;
1831 /* Need special consideration for copying of the interface_statistics member */
1832 if (dest_mand->num_stat_entries != 0)
1833 g_array_free(dest_mand->interface_statistics, true);
1835 memcpy(dest_mand, src_mand, sizeof(wtapng_if_descr_mandatory_t));
1836 if (src_mand->num_stat_entries != 0)
1838 dest_mand->interface_statistics = g_array_new(false, false, sizeof(wtap_block_t));
1839 for (j = 0; j < src_mand->num_stat_entries; j++)
1841 src_if_stats = g_array_index(src_mand->interface_statistics, wtap_block_t, j);
1842 dest_if_stats = wtap_block_make_copy(src_if_stats);
1843 dest_mand->interface_statistics = g_array_append_val(dest_mand->interface_statistics, dest_if_stats);
1848 static void dsb_create(wtap_block_t block)
1850 block->mandatory_data = g_new0(wtapng_dsb_mandatory_t, 1);
1853 static void dsb_free_mand(wtap_block_t block)
1855 wtapng_dsb_mandatory_t *mand = (wtapng_dsb_mandatory_t *)block->mandatory_data;
1856 g_free(mand->secrets_data);
1859 static void dsb_copy_mand(wtap_block_t dest_block, wtap_block_t src_block)
1861 wtapng_dsb_mandatory_t *src = (wtapng_dsb_mandatory_t *)src_block->mandatory_data;
1862 wtapng_dsb_mandatory_t *dst = (wtapng_dsb_mandatory_t *)dest_block->mandatory_data;
1863 dst->secrets_type = src->secrets_type;
1864 dst->secrets_len = src->secrets_len;
1865 g_free(dst->secrets_data);
1866 dst->secrets_data = (uint8_t *)g_memdup2(src->secrets_data, src->secrets_len);
1869 static void mev_create(wtap_block_t block)
1871 block->mandatory_data = g_new0(wtapng_meta_event_mandatory_t, 1);
1874 static void mev_free_mand(wtap_block_t block)
1876 wtapng_meta_event_mandatory_t *mand = (wtapng_meta_event_mandatory_t *)block->mandatory_data;
1877 g_free(mand->mev_data);
1880 static void mev_copy_mand(wtap_block_t dest_block, wtap_block_t src_block)
1882 wtapng_meta_event_mandatory_t *src = (wtapng_meta_event_mandatory_t *)src_block->mandatory_data;
1883 wtapng_meta_event_mandatory_t *dst = (wtapng_meta_event_mandatory_t *)dest_block->mandatory_data;
1884 dst->mev_block_type = src->mev_block_type;
1885 dst->mev_data_len = src->mev_data_len;
1886 g_free(dst->mev_data);
1887 dst->mev_data = (uint8_t *)g_memdup2(src->mev_data, src->mev_data_len);
1890 static void pkt_create(wtap_block_t block)
1892 /* Commented out for now, there's no mandatory data that isn't handled by
1893 * Wireshark in other ways.
1895 //block->mandatory_data = g_new0(wtapng_packet_mandatory_t, 1);
1897 /* Ensure this is null, so when g_free is called on it, it simply returns */
1898 block->mandatory_data = NULL;
1901 static void sjeb_create(wtap_block_t block)
1903 /* Ensure this is null, so when g_free is called on it, it simply returns */
1904 block->mandatory_data = NULL;
1907 static void cb_create(wtap_block_t block)
1909 /* Ensure this is null, so when g_free is called on it, it simply returns */
1910 block->mandatory_data = NULL;
1913 void wtap_opttypes_initialize(void)
1915 static wtap_blocktype_t shb_block = {
1916 WTAP_BLOCK_SECTION, /* block_type */
1917 "SHB", /* name */
1918 "Section Header Block", /* description */
1919 shb_create, /* create */
1920 NULL, /* free_mand */
1921 shb_copy_mand, /* copy_mand */
1922 NULL /* options */
1924 static const wtap_opttype_t shb_hardware = {
1925 "hardware",
1926 "SHB Hardware",
1927 WTAP_OPTTYPE_STRING,
1930 static const wtap_opttype_t shb_os = {
1931 "os",
1932 "SHB Operating System",
1933 WTAP_OPTTYPE_STRING,
1936 static const wtap_opttype_t shb_userappl = {
1937 "user_appl",
1938 "SHB User Application",
1939 WTAP_OPTTYPE_STRING,
1943 static wtap_blocktype_t idb_block = {
1944 WTAP_BLOCK_IF_ID_AND_INFO, /* block_type */
1945 "IDB", /* name */
1946 "Interface Description Block", /* description */
1947 idb_create, /* create */
1948 idb_free_mand, /* free_mand */
1949 idb_copy_mand, /* copy_mand */
1950 NULL /* options */
1952 static const wtap_opttype_t if_name = {
1953 "name",
1954 "IDB Name",
1955 WTAP_OPTTYPE_STRING,
1958 static const wtap_opttype_t if_description = {
1959 "description",
1960 "IDB Description",
1961 WTAP_OPTTYPE_STRING,
1964 static const wtap_opttype_t if_speed = {
1965 "speed",
1966 "IDB Speed",
1967 WTAP_OPTTYPE_UINT64,
1970 static const wtap_opttype_t if_tsresol = {
1971 "tsresol",
1972 "IDB Time Stamp Resolution",
1973 WTAP_OPTTYPE_UINT8, /* XXX - signed? */
1976 static const wtap_opttype_t if_filter = {
1977 "filter",
1978 "IDB Filter",
1979 WTAP_OPTTYPE_IF_FILTER,
1982 static const wtap_opttype_t if_os = {
1983 "os",
1984 "IDB Operating System",
1985 WTAP_OPTTYPE_STRING,
1988 static const wtap_opttype_t if_fcslen = {
1989 "fcslen",
1990 "IDB FCS Length",
1991 WTAP_OPTTYPE_UINT8,
1994 static const wtap_opttype_t if_tsoffset = {
1995 "tsoffset",
1996 "IDB Time Stamp Offset",
1997 WTAP_OPTTYPE_INT64,
2000 static const wtap_opttype_t if_hardware = {
2001 "hardware",
2002 "IDB Hardware",
2003 WTAP_OPTTYPE_STRING,
2007 static wtap_blocktype_t dsb_block = {
2008 WTAP_BLOCK_DECRYPTION_SECRETS,
2009 "DSB",
2010 "Decryption Secrets Block",
2011 dsb_create,
2012 dsb_free_mand,
2013 dsb_copy_mand,
2014 NULL
2017 static wtap_blocktype_t nrb_block = {
2018 WTAP_BLOCK_NAME_RESOLUTION, /* block_type */
2019 "NRB", /* name */
2020 "Name Resolution Block", /* description */
2021 nrb_create, /* create */
2022 nrb_free_mand, /* free_mand */
2023 /* We eventually want to copy these, when dumper actually
2024 * writes them out. If we're actually processing packets,
2025 * as opposed to just reading and writing a file without
2026 * printing (e.g., editcap), do we still want to copy all
2027 * the pre-existing NRBs, or do we want to limit it to
2028 * the actually used addresses, as currently?
2030 #if 0
2031 nrb_copy_mand, /* copy_mand */
2032 #endif
2033 NULL,
2034 NULL /* options */
2036 static const wtap_opttype_t ns_dnsname = {
2037 "dnsname",
2038 "NRB DNS server name",
2039 WTAP_OPTTYPE_STRING,
2042 static const wtap_opttype_t ns_dnsIP4addr = {
2043 "dnsIP4addr",
2044 "NRB DNS server IPv4 address",
2045 WTAP_OPTTYPE_IPv4,
2048 static const wtap_opttype_t ns_dnsIP6addr = {
2049 "dnsIP6addr",
2050 "NRB DNS server IPv6 address",
2051 WTAP_OPTTYPE_IPv6,
2055 static wtap_blocktype_t isb_block = {
2056 WTAP_BLOCK_IF_STATISTICS, /* block_type */
2057 "ISB", /* name */
2058 "Interface Statistics Block", /* description */
2059 isb_create, /* create */
2060 NULL, /* free_mand */
2061 isb_copy_mand, /* copy_mand */
2062 NULL /* options */
2064 static const wtap_opttype_t isb_starttime = {
2065 "starttime",
2066 "ISB Start Time",
2067 WTAP_OPTTYPE_UINT64,
2070 static const wtap_opttype_t isb_endtime = {
2071 "endtime",
2072 "ISB End Time",
2073 WTAP_OPTTYPE_UINT64,
2076 static const wtap_opttype_t isb_ifrecv = {
2077 "ifrecv",
2078 "ISB Received Packets",
2079 WTAP_OPTTYPE_UINT64,
2082 static const wtap_opttype_t isb_ifdrop = {
2083 "ifdrop",
2084 "ISB Dropped Packets",
2085 WTAP_OPTTYPE_UINT64,
2088 static const wtap_opttype_t isb_filteraccept = {
2089 "filteraccept",
2090 "ISB Packets Accepted By Filter",
2091 WTAP_OPTTYPE_UINT64,
2094 static const wtap_opttype_t isb_osdrop = {
2095 "osdrop",
2096 "ISB Packets Dropped By The OS",
2097 WTAP_OPTTYPE_UINT64,
2100 static const wtap_opttype_t isb_usrdeliv = {
2101 "usrdeliv",
2102 "ISB Packets Delivered To The User",
2103 WTAP_OPTTYPE_UINT64,
2107 static wtap_blocktype_t mev_block = {
2108 WTAP_BLOCK_META_EVENT,
2109 "MEV",
2110 "Meta Event Block",
2111 mev_create,
2112 mev_free_mand,
2113 mev_copy_mand,
2114 NULL
2117 static wtap_blocktype_t pkt_block = {
2118 WTAP_BLOCK_PACKET, /* block_type */
2119 "EPB/SPB/PB", /* name */
2120 "Packet Block", /* description */
2121 pkt_create, /* create */
2122 NULL, /* free_mand */
2123 NULL, /* copy_mand */
2124 NULL /* options */
2126 static const wtap_opttype_t pkt_flags = {
2127 "flags",
2128 "Link-layer flags",
2129 WTAP_OPTTYPE_UINT32,
2132 static const wtap_opttype_t pkt_dropcount = {
2133 "dropcount",
2134 "Packets Dropped since last packet",
2135 WTAP_OPTTYPE_UINT64,
2138 static const wtap_opttype_t pkt_id = {
2139 "packetid",
2140 "Unique Packet Identifier",
2141 WTAP_OPTTYPE_UINT64,
2144 static const wtap_opttype_t pkt_queue = {
2145 "queue",
2146 "Queue ID in which packet was received",
2147 WTAP_OPTTYPE_UINT32,
2150 static const wtap_opttype_t pkt_hash = {
2151 "hash",
2152 "Hash of packet data",
2153 WTAP_OPTTYPE_PACKET_HASH,
2154 WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED
2156 static const wtap_opttype_t pkt_verdict = {
2157 "verdict",
2158 "Packet Verdict",
2159 WTAP_OPTTYPE_PACKET_VERDICT,
2160 WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED
2163 static wtap_blocktype_t journal_block = {
2164 WTAP_BLOCK_SYSTEMD_JOURNAL_EXPORT, /* block_type */
2165 "SJEB", /* name */
2166 "systemd Journal Export Block", /* description */
2167 sjeb_create, /* create */
2168 NULL, /* free_mand */
2169 NULL, /* copy_mand */
2170 NULL /* options */
2173 static wtap_blocktype_t cb_block = {
2174 WTAP_BLOCK_CUSTOM, /* block_type */
2175 "CB", /* name */
2176 "Custom Block", /* description */
2177 cb_create, /* create */
2178 NULL, /* free_mand */
2179 NULL, /* copy_mand */
2180 NULL /* options */
2184 * Register the SHB and the options that can appear in it.
2186 wtap_opttype_block_register(&shb_block);
2187 wtap_opttype_option_register(&shb_block, OPT_SHB_HARDWARE, &shb_hardware);
2188 wtap_opttype_option_register(&shb_block, OPT_SHB_OS, &shb_os);
2189 wtap_opttype_option_register(&shb_block, OPT_SHB_USERAPPL, &shb_userappl);
2192 * Register the IDB and the options that can appear in it.
2194 wtap_opttype_block_register(&idb_block);
2195 wtap_opttype_option_register(&idb_block, OPT_IDB_NAME, &if_name);
2196 wtap_opttype_option_register(&idb_block, OPT_IDB_DESCRIPTION, &if_description);
2197 wtap_opttype_option_register(&idb_block, OPT_IDB_SPEED, &if_speed);
2198 wtap_opttype_option_register(&idb_block, OPT_IDB_TSRESOL, &if_tsresol);
2199 wtap_opttype_option_register(&idb_block, OPT_IDB_FILTER, &if_filter);
2200 wtap_opttype_option_register(&idb_block, OPT_IDB_OS, &if_os);
2201 wtap_opttype_option_register(&idb_block, OPT_IDB_FCSLEN, &if_fcslen);
2202 wtap_opttype_option_register(&idb_block, OPT_IDB_TSOFFSET, &if_tsoffset);
2203 wtap_opttype_option_register(&idb_block, OPT_IDB_HARDWARE, &if_hardware);
2206 * Register the NRB and the options that can appear in it.
2208 wtap_opttype_block_register(&nrb_block);
2209 wtap_opttype_option_register(&nrb_block, OPT_NS_DNSNAME, &ns_dnsname);
2210 wtap_opttype_option_register(&nrb_block, OPT_NS_DNSIP4ADDR, &ns_dnsIP4addr);
2211 wtap_opttype_option_register(&nrb_block, OPT_NS_DNSIP6ADDR, &ns_dnsIP6addr);
2214 * Register the ISB and the options that can appear in it.
2216 wtap_opttype_block_register(&isb_block);
2217 wtap_opttype_option_register(&isb_block, OPT_ISB_STARTTIME, &isb_starttime);
2218 wtap_opttype_option_register(&isb_block, OPT_ISB_ENDTIME, &isb_endtime);
2219 wtap_opttype_option_register(&isb_block, OPT_ISB_IFRECV, &isb_ifrecv);
2220 wtap_opttype_option_register(&isb_block, OPT_ISB_IFDROP, &isb_ifdrop);
2221 wtap_opttype_option_register(&isb_block, OPT_ISB_FILTERACCEPT, &isb_filteraccept);
2222 wtap_opttype_option_register(&isb_block, OPT_ISB_OSDROP, &isb_osdrop);
2223 wtap_opttype_option_register(&isb_block, OPT_ISB_USRDELIV, &isb_usrdeliv);
2226 * Register the DSB, currently no options are defined.
2228 wtap_opttype_block_register(&dsb_block);
2231 * Register the Sysdig MEV, currently no options are defined.
2233 wtap_opttype_block_register(&mev_block);
2236 * Register EPB/SPB/PB and the options that can appear in it/them.
2237 * NB: Simple Packet Blocks have no options.
2238 * NB: obsolete Packet Blocks have dropcount as a mandatory member instead
2239 * of an option.
2241 wtap_opttype_block_register(&pkt_block);
2242 wtap_opttype_option_register(&pkt_block, OPT_PKT_FLAGS, &pkt_flags);
2243 wtap_opttype_option_register(&pkt_block, OPT_PKT_DROPCOUNT, &pkt_dropcount);
2244 wtap_opttype_option_register(&pkt_block, OPT_PKT_PACKETID, &pkt_id);
2245 wtap_opttype_option_register(&pkt_block, OPT_PKT_QUEUE, &pkt_queue);
2246 wtap_opttype_option_register(&pkt_block, OPT_PKT_HASH, &pkt_hash);
2247 wtap_opttype_option_register(&pkt_block, OPT_PKT_VERDICT, &pkt_verdict);
2250 * Register the SJEB and the (no) options that can appear in it.
2252 wtap_opttype_block_register(&journal_block);
2255 * Register the CB and the options that can appear in it.
2257 wtap_opttype_block_register(&cb_block);
2259 #ifdef DEBUG_COUNT_REFS
2260 memset(blocks_active, 0, sizeof(blocks_active));
2261 #endif
2264 void wtap_opttypes_cleanup(void)
2266 unsigned block_type;
2267 #ifdef DEBUG_COUNT_REFS
2268 unsigned i;
2269 unsigned cellno;
2270 unsigned bitno;
2271 uint8_t mask;
2272 #endif /* DEBUG_COUNT_REFS */
2274 for (block_type = (unsigned)WTAP_BLOCK_SECTION;
2275 block_type < (unsigned)MAX_WTAP_BLOCK_TYPE_VALUE; block_type++) {
2276 if (blocktype_list[block_type]) {
2277 if (blocktype_list[block_type]->options)
2278 g_hash_table_destroy(blocktype_list[block_type]->options);
2279 blocktype_list[block_type] = NULL;
2283 #ifdef DEBUG_COUNT_REFS
2284 for (i = 0 ; i < block_count; i++) {
2285 cellno = i / 8;
2286 bitno = i % 8;
2287 mask = 1 << bitno;
2289 if ((blocks_active[cellno] & mask) == mask) {
2290 wtap_debug("wtap_opttypes_cleanup: orphaned block #%d", i);
2293 #endif /* DEBUG_COUNT_REFS */