1 /* wtap_opttypes.c
2 *
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 2001 Gerald Combs
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9 #include "config.h"
10
11 #include <glib.h>
12 #include <string.h>
13
14 #include "wtap.h"
15 #include "wtap_opttypes.h"
16 #include "wtap-int.h"
17 #include "pcapng_module.h"
18 #include <wsutil/ws_assert.h>
19
20 #include <wsutil/glib-compat.h>
21 #include <wsutil/inet_ipv6.h>
22
23 #if 0
24 #define wtap_debug(...) g_warning(__VA_ARGS__)
25 #define DEBUG_COUNT_REFS
26 #else
27 #define wtap_debug(...)
28 #endif
29
30 #define ROUND_TO_4BYTE(len) (((len) + 3) & ~3)
31
32 /*
33 * Structure describing a type of block.
34 */
35 typedef struct {
36 wtap_block_type_t block_type; /**< internal type code for block */
37 const char *name; /**< name of block */
38 const char *description; /**< human-readable description of block */
39 wtap_block_create_func create;
40 wtap_mand_free_func free_mand;
41 wtap_mand_copy_func copy_mand;
42 GHashTable *options; /**< hash table of known options */
43 } wtap_blocktype_t;
44
45 #define GET_OPTION_TYPE(options, option_id) \
46 (const wtap_opttype_t *)g_hash_table_lookup((options), GUINT_TO_POINTER(option_id))
47
48 /*
49 * Structure describing a type of option.
50 */
51 typedef struct {
52 const char *name; /**< name of option */
53 const char *description; /**< human-readable description of option */
54 wtap_opttype_e data_type; /**< data type of that option */
55 guint flags; /**< flags for the option */
56 } wtap_opttype_t;
57
58 /* Flags */
59 #define WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED 0x00000001 /* multiple instances allowed */
60
61 /* Debugging reference counting */
62 #ifdef DEBUG_COUNT_REFS
63 static guint block_count = 0;
64 static guint8 blocks_active[sizeof(guint)/8];
65
rc_set(guint refnum)66 static void rc_set(guint refnum)
67 {
68 guint cellno = refnum / 8;
69 guint bitno = refnum % 8;
70 blocks_active[cellno] |= (guint8)(1 << bitno);
71 }
72
rc_clear(guint refnum)73 static void rc_clear(guint refnum)
74 {
75 guint cellno = refnum / 8;
76 guint bitno = refnum % 8;
77 blocks_active[cellno] &= (guint8)~(1 << bitno);
78 }
79
80 #endif /* DEBUG_COUNT_REFS */
81
82 struct wtap_block
83 {
84 wtap_blocktype_t* info;
85 void* mandatory_data;
86 GArray* options;
87 gint ref_count;
88 #ifdef DEBUG_COUNT_REFS
89 guint id;
90 #endif
91 };
92
93 /* Keep track of wtap_blocktype_t's via their id number */
94 static wtap_blocktype_t* blocktype_list[MAX_WTAP_BLOCK_TYPE_VALUE];
95
if_filter_dup(if_filter_opt_t * filter_src)96 static if_filter_opt_t if_filter_dup(if_filter_opt_t* filter_src)
97 {
98 if_filter_opt_t filter_dest;
99
100 memset(&filter_dest, 0, sizeof(filter_dest));
101
102 /* Deep copy. */
103 filter_dest.type = filter_src->type;
104 switch (filter_src->type) {
105
106 case if_filter_pcap:
107 /* pcap filter string */
108 filter_dest.data.filter_str =
109 g_strdup(filter_src->data.filter_str);
110 break;
111
112 case if_filter_bpf:
113 /* BPF program */
114 filter_dest.data.bpf_prog.bpf_prog_len =
115 filter_src->data.bpf_prog.bpf_prog_len;
116 filter_dest.data.bpf_prog.bpf_prog =
117 (wtap_bpf_insn_t *)g_memdup2(filter_src->data.bpf_prog.bpf_prog,
118 filter_src->data.bpf_prog.bpf_prog_len * sizeof (wtap_bpf_insn_t));
119 break;
120
121 default:
122 break;
123 }
124 return filter_dest;
125 }
126
if_filter_free(if_filter_opt_t * filter_src)127 static void if_filter_free(if_filter_opt_t* filter_src)
128 {
129 switch (filter_src->type) {
130
131 case if_filter_pcap:
132 /* pcap filter string */
133 g_free(filter_src->data.filter_str);
134 break;
135
136 case if_filter_bpf:
137 /* BPF program */
138 g_free(filter_src->data.bpf_prog.bpf_prog);
139 break;
140
141 default:
142 break;
143 }
144 }
145
146 static packet_verdict_opt_t
packet_verdict_dup(packet_verdict_opt_t * verdict_src)147 packet_verdict_dup(packet_verdict_opt_t* verdict_src)
148 {
149 packet_verdict_opt_t verdict_dest;
150
151 memset(&verdict_dest, 0, sizeof(verdict_dest));
152
153 /* Deep copy. */
154 verdict_dest.type = verdict_src->type;
155 switch (verdict_src->type) {
156
157 case packet_verdict_hardware:
158 /* array of octets */
159 verdict_dest.data.verdict_bytes =
160 g_byte_array_new_take((guint8 *)g_memdup2(verdict_src->data.verdict_bytes->data,
161 verdict_src->data.verdict_bytes->len),
162 verdict_src->data.verdict_bytes->len);
163 break;
164
165 case packet_verdict_linux_ebpf_tc:
166 /* eBPF TC_ACT_ value */
167 verdict_dest.data.verdict_linux_ebpf_tc =
168 verdict_src->data.verdict_linux_ebpf_tc;
169 break;
170
171 case packet_verdict_linux_ebpf_xdp:
172 /* xdp_action value */
173 verdict_dest.data.verdict_linux_ebpf_xdp =
174 verdict_src->data.verdict_linux_ebpf_xdp;
175 break;
176
177 default:
178 break;
179 }
180 return verdict_dest;
181 }
182
wtap_packet_verdict_free(packet_verdict_opt_t * verdict)183 void wtap_packet_verdict_free(packet_verdict_opt_t* verdict)
184 {
185 switch (verdict->type) {
186
187 case packet_verdict_hardware:
188 /* array of bytes */
189 g_byte_array_free(verdict->data.verdict_bytes, TRUE);
190 break;
191
192 default:
193 break;
194 }
195 }
196
wtap_opttype_block_register(wtap_blocktype_t * blocktype)197 static void wtap_opttype_block_register(wtap_blocktype_t *blocktype)
198 {
199 wtap_block_type_t block_type;
200 static const wtap_opttype_t opt_comment = {
201 "opt_comment",
202 "Comment",
203 WTAP_OPTTYPE_STRING,
204 WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED
205 };
206 static const wtap_opttype_t opt_custom = {
207 "opt_custom",
208 "Custom Option",
209 WTAP_OPTTYPE_CUSTOM,
210 WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED
211 };
212
213 block_type = blocktype->block_type;
214
215 /* Check input */
216 ws_assert(block_type < MAX_WTAP_BLOCK_TYPE_VALUE);
217
218 /* Don't re-register. */
219 ws_assert(blocktype_list[block_type] == NULL);
220
221 /* Sanity check */
222 ws_assert(blocktype->name);
223 ws_assert(blocktype->description);
224 ws_assert(blocktype->create);
225
226 /*
227 * Initialize the set of supported options.
228 * All blocks that support options at all support
229 * OPT_COMMENT and OPT_CUSTOM.
230 *
231 * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
232 * so we use "g_direct_hash()" and "g_direct_equal()".
233 */
234 blocktype->options = g_hash_table_new(g_direct_hash, g_direct_equal);
235 g_hash_table_insert(blocktype->options, GUINT_TO_POINTER(OPT_COMMENT),
236 (gpointer)&opt_comment);
237 g_hash_table_insert(blocktype->options, GUINT_TO_POINTER(OPT_CUSTOM_STR_COPY),
238 (gpointer)&opt_custom);
239 g_hash_table_insert(blocktype->options, GUINT_TO_POINTER(OPT_CUSTOM_BIN_COPY),
240 (gpointer)&opt_custom);
241 g_hash_table_insert(blocktype->options, GUINT_TO_POINTER(OPT_CUSTOM_STR_NO_COPY),
242 (gpointer)&opt_custom);
243 g_hash_table_insert(blocktype->options, GUINT_TO_POINTER(OPT_CUSTOM_BIN_NO_COPY),
244 (gpointer)&opt_custom);
245
246 blocktype_list[block_type] = blocktype;
247 }
248
wtap_opttype_option_register(wtap_blocktype_t * blocktype,guint opttype,const wtap_opttype_t * option)249 static void wtap_opttype_option_register(wtap_blocktype_t *blocktype, guint opttype, const wtap_opttype_t *option)
250 {
251 g_hash_table_insert(blocktype->options, GUINT_TO_POINTER(opttype),
252 (gpointer) option);
253 }
254
wtap_block_get_type(wtap_block_t block)255 wtap_block_type_t wtap_block_get_type(wtap_block_t block)
256 {
257 return block->info->block_type;
258 }
259
wtap_block_get_mandatory_data(wtap_block_t block)260 void* wtap_block_get_mandatory_data(wtap_block_t block)
261 {
262 return block->mandatory_data;
263 }
264
265 static wtap_optval_t *
wtap_block_get_option(wtap_block_t block,guint option_id)266 wtap_block_get_option(wtap_block_t block, guint option_id)
267 {
268 guint i;
269 wtap_option_t *opt;
270
271 if (block == NULL) {
272 return NULL;
273 }
274
275 for (i = 0; i < block->options->len; i++) {
276 opt = &g_array_index(block->options, wtap_option_t, i);
277 if (opt->option_id == option_id)
278 return &opt->value;
279 }
280
281 return NULL;
282 }
283
284 static wtap_optval_t *
wtap_block_get_nth_option(wtap_block_t block,guint option_id,guint idx)285 wtap_block_get_nth_option(wtap_block_t block, guint option_id, guint idx)
286 {
287 guint i;
288 wtap_option_t *opt;
289 guint opt_idx;
290
291 if (block == NULL) {
292 return NULL;
293 }
294
295 opt_idx = 0;
296 for (i = 0; i < block->options->len; i++) {
297 opt = &g_array_index(block->options, wtap_option_t, i);
298 if (opt->option_id == option_id) {
299 if (opt_idx == idx)
300 return &opt->value;
301 opt_idx++;
302 }
303 }
304
305 return NULL;
306 }
307
wtap_block_create(wtap_block_type_t block_type)308 wtap_block_t wtap_block_create(wtap_block_type_t block_type)
309 {
310 wtap_block_t block;
311
312 if (block_type >= MAX_WTAP_BLOCK_TYPE_VALUE)
313 return NULL;
314
315 block = g_new(struct wtap_block, 1);
316 block->info = blocktype_list[block_type];
317 block->options = g_array_new(FALSE, FALSE, sizeof(wtap_option_t));
318 block->info->create(block);
319 block->ref_count = 1;
320 #ifdef DEBUG_COUNT_REFS
321 block->id = block_count++;
322 rc_set(block->id);
323 wtap_debug("Created #%d %s", block->id, block->info->name);
324 #endif /* DEBUG_COUNT_REFS */
325
326 return block;
327 }
328
wtap_block_free_option(wtap_block_t block,wtap_option_t * opt)329 static void wtap_block_free_option(wtap_block_t block, wtap_option_t *opt)
330 {
331 const wtap_opttype_t *opttype;
332
333 if (block == NULL) {
334 return;
335 }
336
337 opttype = GET_OPTION_TYPE(block->info->options, opt->option_id);
338 switch (opttype->data_type) {
339
340 case WTAP_OPTTYPE_STRING:
341 g_free(opt->value.stringval);
342 break;
343
344 case WTAP_OPTTYPE_BYTES:
345 g_bytes_unref(opt->value.byteval);
346 break;
347
348 case WTAP_OPTTYPE_CUSTOM:
349 switch (opt->value.custom_opt.pen) {
350 case PEN_NFLX:
351 g_free(opt->value.custom_opt.data.nflx_data.custom_data);
352 break;
353 default:
354 g_free(opt->value.custom_opt.data.generic_data.custom_data);
355 break;
356 }
357 break;
358
359 case WTAP_OPTTYPE_IF_FILTER:
360 if_filter_free(&opt->value.if_filterval);
361 break;
362
363 case WTAP_OPTTYPE_PACKET_VERDICT:
364 wtap_packet_verdict_free(&opt->value.packet_verdictval);
365 break;
366
367 default:
368 break;
369 }
370 }
371
wtap_block_free_options(wtap_block_t block)372 static void wtap_block_free_options(wtap_block_t block)
373 {
374 guint i;
375 wtap_option_t *opt;
376
377 if (block == NULL || block->options == NULL) {
378 return;
379 }
380
381 for (i = 0; i < block->options->len; i++) {
382 opt = &g_array_index(block->options, wtap_option_t, i);
383 wtap_block_free_option(block, opt);
384 }
385 g_array_remove_range(block->options, 0, block->options->len);
386 }
387
wtap_block_ref(wtap_block_t block)388 wtap_block_t wtap_block_ref(wtap_block_t block)
389 {
390 if (block == NULL) {
391 return NULL;
392 }
393
394 g_atomic_int_inc(&block->ref_count);
395 #ifdef DEBUG_COUNT_REFS
396 wtap_debug("Ref #%d %s", block->id, block->info->name);
397 #endif /* DEBUG_COUNT_REFS */
398 return block;
399 }
400
wtap_block_unref(wtap_block_t block)401 void wtap_block_unref(wtap_block_t block)
402 {
403 if (block != NULL)
404 {
405 if (g_atomic_int_dec_and_test(&block->ref_count)) {
406 #ifdef DEBUG_COUNT_REFS
407 wtap_debug("Destroy #%d %s", block->id, block->info->name);
408 rc_clear(block->id);
409 #endif /* DEBUG_COUNT_REFS */
410 if (block->info->free_mand != NULL)
411 block->info->free_mand(block);
412
413 g_free(block->mandatory_data);
414 wtap_block_free_options(block);
415 g_array_free(block->options, TRUE);
416 g_free(block);
417 }
418 #ifdef DEBUG_COUNT_REFS
419 else {
420 wtap_debug("Unref #%d %s", block->id, block->info->name);
421 }
422 #endif /* DEBUG_COUNT_REFS */
423 }
424 }
425
wtap_block_array_free(GArray * block_array)426 void wtap_block_array_free(GArray* block_array)
427 {
428 guint block;
429
430 if (block_array == NULL)
431 return;
432
433 for (block = 0; block < block_array->len; block++) {
434 wtap_block_unref(g_array_index(block_array, wtap_block_t, block));
435 }
436 g_array_free(block_array, TRUE);
437 }
438
439 /*
440 * Make a copy of a block.
441 */
442 void
wtap_block_copy(wtap_block_t dest_block,wtap_block_t src_block)443 wtap_block_copy(wtap_block_t dest_block, wtap_block_t src_block)
444 {
445 guint i;
446 wtap_option_t *src_opt;
447 const wtap_opttype_t *opttype;
448
449 /*
450 * Copy the mandatory data.
451 */
452 if (dest_block->info->copy_mand != NULL)
453 dest_block->info->copy_mand(dest_block, src_block);
454
455 /* Copy the options. For now, don't remove any options that are in destination
456 * but not source.
457 */
458 for (i = 0; i < src_block->options->len; i++)
459 {
460 src_opt = &g_array_index(src_block->options, wtap_option_t, i);
461 opttype = GET_OPTION_TYPE(src_block->info->options, src_opt->option_id);
462
463 switch(opttype->data_type) {
464
465 case WTAP_OPTTYPE_UINT8:
466 wtap_block_add_uint8_option(dest_block, src_opt->option_id, src_opt->value.uint8val);
467 break;
468
469 case WTAP_OPTTYPE_UINT32:
470 wtap_block_add_uint32_option(dest_block, src_opt->option_id, src_opt->value.uint32val);
471 break;
472
473 case WTAP_OPTTYPE_UINT64:
474 wtap_block_add_uint64_option(dest_block, src_opt->option_id, src_opt->value.uint64val);
475 break;
476
477 case WTAP_OPTTYPE_IPv4:
478 wtap_block_add_ipv4_option(dest_block, src_opt->option_id, src_opt->value.ipv4val);
479 break;
480
481 case WTAP_OPTTYPE_IPv6:
482 wtap_block_add_ipv6_option(dest_block, src_opt->option_id, &src_opt->value.ipv6val);
483 break;
484
485 case WTAP_OPTTYPE_STRING:
486 wtap_block_add_string_option(dest_block, src_opt->option_id, src_opt->value.stringval, strlen(src_opt->value.stringval));
487 break;
488
489 case WTAP_OPTTYPE_BYTES:
490 wtap_block_add_bytes_option_borrow(dest_block, src_opt->option_id, src_opt->value.byteval);
491 break;
492
493 case WTAP_OPTTYPE_CUSTOM:
494 switch (src_opt->value.custom_opt.pen) {
495 case PEN_NFLX:
496 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);
497 break;
498 default:
499 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);
500 break;
501 }
502 break;
503
504 case WTAP_OPTTYPE_IF_FILTER:
505 wtap_block_add_if_filter_option(dest_block, src_opt->option_id, &src_opt->value.if_filterval);
506 break;
507
508 case WTAP_OPTTYPE_PACKET_VERDICT:
509 wtap_block_add_packet_verdict_option(dest_block, src_opt->option_id, &src_opt->value.packet_verdictval);
510 break;
511 }
512 }
513 }
514
wtap_block_make_copy(wtap_block_t block)515 wtap_block_t wtap_block_make_copy(wtap_block_t block)
516 {
517 wtap_block_t block_copy;
518
519 block_copy = wtap_block_create(block->info->block_type);
520 wtap_block_copy(block_copy, block);
521 return block_copy;
522 }
523
524 guint
wtap_block_count_option(wtap_block_t block,guint option_id)525 wtap_block_count_option(wtap_block_t block, guint option_id)
526 {
527 guint i;
528 guint ret_val = 0;
529 wtap_option_t *opt;
530
531 if (block == NULL) {
532 return 0;
533 }
534
535 for (i = 0; i < block->options->len; i++) {
536 opt = &g_array_index(block->options, wtap_option_t, i);
537 if (opt->option_id == option_id)
538 ret_val++;
539 }
540
541 return ret_val;
542 }
543
544
wtap_block_foreach_option(wtap_block_t block,wtap_block_foreach_func func,void * user_data)545 gboolean wtap_block_foreach_option(wtap_block_t block, wtap_block_foreach_func func, void* user_data)
546 {
547 guint i;
548 wtap_option_t *opt;
549 const wtap_opttype_t *opttype;
550
551 if (block == NULL) {
552 return TRUE;
553 }
554
555 for (i = 0; i < block->options->len; i++) {
556 opt = &g_array_index(block->options, wtap_option_t, i);
557 opttype = GET_OPTION_TYPE(block->info->options, opt->option_id);
558 if (!func(block, opt->option_id, opttype->data_type, &opt->value, user_data))
559 return FALSE;
560 }
561 return TRUE;
562 }
563
564 static wtap_opttype_return_val
wtap_block_add_option_common(wtap_block_t block,guint option_id,wtap_opttype_e type,wtap_option_t ** optp)565 wtap_block_add_option_common(wtap_block_t block, guint option_id, wtap_opttype_e type, wtap_option_t **optp)
566 {
567 wtap_option_t *opt;
568 const wtap_opttype_t *opttype;
569 guint i;
570
571 if (block == NULL) {
572 return WTAP_OPTTYPE_BAD_BLOCK;
573 }
574
575 opttype = GET_OPTION_TYPE(block->info->options, option_id);
576 if (opttype == NULL) {
577 /* There's no option for this block with that option ID */
578 return WTAP_OPTTYPE_NO_SUCH_OPTION;
579 }
580
581 /*
582 * Is this an option of the specified data type?
583 */
584 if (opttype->data_type != type) {
585 /*
586 * No.
587 */
588 return WTAP_OPTTYPE_TYPE_MISMATCH;
589 }
590
591 /*
592 * Can there be more than one instance of this option?
593 */
594 if (!(opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED)) {
595 /*
596 * No. Is there already an instance of this option?
597 */
598 if (wtap_block_get_option(block, option_id) != NULL) {
599 /*
600 * Yes. Fail.
601 */
602 return WTAP_OPTTYPE_ALREADY_EXISTS;
603 }
604 }
605
606 /*
607 * Add an instance.
608 */
609 i = block->options->len;
610 g_array_set_size(block->options, i + 1);
611 opt = &g_array_index(block->options, wtap_option_t, i);
612 opt->option_id = option_id;
613 *optp = opt;
614 return WTAP_OPTTYPE_SUCCESS;
615 }
616
617 static wtap_opttype_return_val
wtap_block_get_option_common(wtap_block_t block,guint option_id,wtap_opttype_e type,wtap_optval_t ** optvalp)618 wtap_block_get_option_common(wtap_block_t block, guint option_id, wtap_opttype_e type, wtap_optval_t **optvalp)
619 {
620 const wtap_opttype_t *opttype;
621 wtap_optval_t *optval;
622
623 if (block == NULL) {
624 return WTAP_OPTTYPE_BAD_BLOCK;
625 }
626
627 opttype = GET_OPTION_TYPE(block->info->options, option_id);
628 if (opttype == NULL) {
629 /* There's no option for this block with that option ID */
630 return WTAP_OPTTYPE_NO_SUCH_OPTION;
631 }
632
633 /*
634 * Is this an option of the specified data type?
635 */
636 if (opttype->data_type != type) {
637 /*
638 * No.
639 */
640 return WTAP_OPTTYPE_TYPE_MISMATCH;
641 }
642
643 /*
644 * Can there be more than one instance of this option?
645 */
646 if (opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED) {
647 /*
648 * Yes. You can't ask for "the" value.
649 */
650 return WTAP_OPTTYPE_NUMBER_MISMATCH;
651 }
652
653 optval = wtap_block_get_option(block, option_id);
654 if (optval == NULL) {
655 /* Didn't find the option */
656 return WTAP_OPTTYPE_NOT_FOUND;
657 }
658
659 *optvalp = optval;
660 return WTAP_OPTTYPE_SUCCESS;
661 }
662
663 static wtap_opttype_return_val
wtap_block_get_nth_option_common(wtap_block_t block,guint option_id,wtap_opttype_e type,guint idx,wtap_optval_t ** optvalp)664 wtap_block_get_nth_option_common(wtap_block_t block, guint option_id, wtap_opttype_e type, guint idx, wtap_optval_t **optvalp)
665 {
666 const wtap_opttype_t *opttype;
667 wtap_optval_t *optval;
668
669 if (block == NULL) {
670 return WTAP_OPTTYPE_BAD_BLOCK;
671 }
672
673 opttype = GET_OPTION_TYPE(block->info->options, option_id);
674 if (opttype == NULL) {
675 /* There's no option for this block with that option ID */
676 return WTAP_OPTTYPE_NO_SUCH_OPTION;
677 }
678
679 /*
680 * Is this an option of the specified data type?
681 */
682 if (opttype->data_type != type) {
683 /*
684 * No.
685 */
686 return WTAP_OPTTYPE_TYPE_MISMATCH;
687 }
688
689 /*
690 * Can there be more than one instance of this option?
691 */
692 if (!(opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED)) {
693 /*
694 * No.
695 */
696 return WTAP_OPTTYPE_NUMBER_MISMATCH;
697 }
698
699 optval = wtap_block_get_nth_option(block, option_id, idx);
700 if (optval == NULL) {
701 /* Didn't find the option */
702 return WTAP_OPTTYPE_NOT_FOUND;
703 }
704
705 *optvalp = optval;
706 return WTAP_OPTTYPE_SUCCESS;
707 }
708
709 wtap_opttype_return_val
wtap_block_add_uint8_option(wtap_block_t block,guint option_id,guint8 value)710 wtap_block_add_uint8_option(wtap_block_t block, guint option_id, guint8 value)
711 {
712 wtap_opttype_return_val ret;
713 wtap_option_t *opt;
714
715 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_UINT8, &opt);
716 if (ret != WTAP_OPTTYPE_SUCCESS)
717 return ret;
718 opt->value.uint8val = value;
719 return WTAP_OPTTYPE_SUCCESS;
720 }
721
722 wtap_opttype_return_val
wtap_block_set_uint8_option_value(wtap_block_t block,guint option_id,guint8 value)723 wtap_block_set_uint8_option_value(wtap_block_t block, guint option_id, guint8 value)
724 {
725 wtap_opttype_return_val ret;
726 wtap_optval_t *optval;
727
728 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT8, &optval);
729 if (ret != WTAP_OPTTYPE_SUCCESS)
730 return ret;
731 optval->uint8val = value;
732 return WTAP_OPTTYPE_SUCCESS;
733 }
734
735 wtap_opttype_return_val
wtap_block_get_uint8_option_value(wtap_block_t block,guint option_id,guint8 * value)736 wtap_block_get_uint8_option_value(wtap_block_t block, guint option_id, guint8* value)
737 {
738 wtap_opttype_return_val ret;
739 wtap_optval_t *optval;
740
741 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT8, &optval);
742 if (ret != WTAP_OPTTYPE_SUCCESS)
743 return ret;
744 *value = optval->uint8val;
745 return WTAP_OPTTYPE_SUCCESS;
746 }
747
748 wtap_opttype_return_val
wtap_block_add_uint32_option(wtap_block_t block,guint option_id,guint32 value)749 wtap_block_add_uint32_option(wtap_block_t block, guint option_id, guint32 value)
750 {
751 wtap_opttype_return_val ret;
752 wtap_option_t *opt;
753
754 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_UINT32, &opt);
755 if (ret != WTAP_OPTTYPE_SUCCESS)
756 return ret;
757 opt->value.uint32val = value;
758 return WTAP_OPTTYPE_SUCCESS;
759 }
760
761 wtap_opttype_return_val
wtap_block_set_uint32_option_value(wtap_block_t block,guint option_id,guint32 value)762 wtap_block_set_uint32_option_value(wtap_block_t block, guint option_id, guint32 value)
763 {
764 wtap_opttype_return_val ret;
765 wtap_optval_t *optval;
766
767 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT32, &optval);
768 if (ret != WTAP_OPTTYPE_SUCCESS)
769 return ret;
770 optval->uint32val = value;
771 return WTAP_OPTTYPE_SUCCESS;
772 }
773
774 wtap_opttype_return_val
wtap_block_get_uint32_option_value(wtap_block_t block,guint option_id,guint32 * value)775 wtap_block_get_uint32_option_value(wtap_block_t block, guint option_id, guint32* value)
776 {
777 wtap_opttype_return_val ret;
778 wtap_optval_t *optval;
779
780 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT32, &optval);
781 if (ret != WTAP_OPTTYPE_SUCCESS)
782 return ret;
783 *value = optval->uint32val;
784 return WTAP_OPTTYPE_SUCCESS;
785 }
786
787 wtap_opttype_return_val
wtap_block_add_uint64_option(wtap_block_t block,guint option_id,guint64 value)788 wtap_block_add_uint64_option(wtap_block_t block, guint option_id, guint64 value)
789 {
790 wtap_opttype_return_val ret;
791 wtap_option_t *opt;
792
793 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_UINT64, &opt);
794 if (ret != WTAP_OPTTYPE_SUCCESS)
795 return ret;
796 opt->value.uint64val = value;
797 return WTAP_OPTTYPE_SUCCESS;
798 }
799
800 wtap_opttype_return_val
wtap_block_set_uint64_option_value(wtap_block_t block,guint option_id,guint64 value)801 wtap_block_set_uint64_option_value(wtap_block_t block, guint option_id, guint64 value)
802 {
803 wtap_opttype_return_val ret;
804 wtap_optval_t *optval;
805
806 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT64, &optval);
807 if (ret != WTAP_OPTTYPE_SUCCESS)
808 return ret;
809 optval->uint64val = value;
810 return WTAP_OPTTYPE_SUCCESS;
811 }
812
813 wtap_opttype_return_val
wtap_block_get_uint64_option_value(wtap_block_t block,guint option_id,guint64 * value)814 wtap_block_get_uint64_option_value(wtap_block_t block, guint option_id, guint64 *value)
815 {
816 wtap_opttype_return_val ret;
817 wtap_optval_t *optval;
818
819 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_UINT64, &optval);
820 if (ret != WTAP_OPTTYPE_SUCCESS)
821 return ret;
822 *value = optval->uint64val;
823 return WTAP_OPTTYPE_SUCCESS;
824 }
825
826 wtap_opttype_return_val
wtap_block_add_ipv4_option(wtap_block_t block,guint option_id,guint32 value)827 wtap_block_add_ipv4_option(wtap_block_t block, guint option_id, guint32 value)
828 {
829 wtap_opttype_return_val ret;
830 wtap_option_t *opt;
831
832 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_IPv4, &opt);
833 if (ret != WTAP_OPTTYPE_SUCCESS)
834 return ret;
835 opt->value.ipv4val = value;
836 return WTAP_OPTTYPE_SUCCESS;
837 }
838
839 wtap_opttype_return_val
wtap_block_set_ipv4_option_value(wtap_block_t block,guint option_id,guint32 value)840 wtap_block_set_ipv4_option_value(wtap_block_t block, guint option_id, guint32 value)
841 {
842 wtap_opttype_return_val ret;
843 wtap_optval_t *optval;
844
845 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IPv4, &optval);
846 if (ret != WTAP_OPTTYPE_SUCCESS)
847 return ret;
848 optval->ipv4val = value;
849 return WTAP_OPTTYPE_SUCCESS;
850 }
851
852 wtap_opttype_return_val
wtap_block_get_ipv4_option_value(wtap_block_t block,guint option_id,guint32 * value)853 wtap_block_get_ipv4_option_value(wtap_block_t block, guint option_id, guint32* value)
854 {
855 wtap_opttype_return_val ret;
856 wtap_optval_t *optval;
857
858 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IPv4, &optval);
859 if (ret != WTAP_OPTTYPE_SUCCESS)
860 return ret;
861 *value = optval->ipv4val;
862 return WTAP_OPTTYPE_SUCCESS;
863 }
864
865 wtap_opttype_return_val
wtap_block_add_ipv6_option(wtap_block_t block,guint option_id,ws_in6_addr * value)866 wtap_block_add_ipv6_option(wtap_block_t block, guint option_id, ws_in6_addr *value)
867 {
868 wtap_opttype_return_val ret;
869 wtap_option_t *opt;
870
871 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_IPv6, &opt);
872 if (ret != WTAP_OPTTYPE_SUCCESS)
873 return ret;
874 opt->value.ipv6val = *value;
875 return WTAP_OPTTYPE_SUCCESS;
876 }
877
878 wtap_opttype_return_val
wtap_block_set_ipv6_option_value(wtap_block_t block,guint option_id,ws_in6_addr * value)879 wtap_block_set_ipv6_option_value(wtap_block_t block, guint option_id, ws_in6_addr *value)
880 {
881 wtap_opttype_return_val ret;
882 wtap_optval_t *optval;
883
884 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IPv6, &optval);
885 if (ret != WTAP_OPTTYPE_SUCCESS)
886 return ret;
887 optval->ipv6val = *value;
888 return WTAP_OPTTYPE_SUCCESS;
889 }
890
891 wtap_opttype_return_val
wtap_block_get_ipv6_option_value(wtap_block_t block,guint option_id,ws_in6_addr * value)892 wtap_block_get_ipv6_option_value(wtap_block_t block, guint option_id, ws_in6_addr* value)
893 {
894 wtap_opttype_return_val ret;
895 wtap_optval_t *optval;
896
897 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IPv6, &optval);
898 if (ret != WTAP_OPTTYPE_SUCCESS)
899 return ret;
900 *value = optval->ipv6val;
901 return WTAP_OPTTYPE_SUCCESS;
902 }
903
904 wtap_opttype_return_val
wtap_block_add_string_option(wtap_block_t block,guint option_id,const char * value,gsize value_length)905 wtap_block_add_string_option(wtap_block_t block, guint option_id, const char *value, gsize value_length)
906 {
907 wtap_opttype_return_val ret;
908 wtap_option_t *opt;
909
910 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_STRING, &opt);
911 if (ret != WTAP_OPTTYPE_SUCCESS)
912 return ret;
913 opt->value.stringval = g_strndup(value, value_length);
914 return WTAP_OPTTYPE_SUCCESS;
915 }
916
917 static wtap_opttype_return_val
wtap_block_add_string_option_vformat(wtap_block_t block,guint option_id,const char * format,va_list va)918 wtap_block_add_string_option_vformat(wtap_block_t block, guint option_id, const char *format, va_list va)
919 {
920 wtap_opttype_return_val ret;
921 wtap_option_t *opt;
922
923 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_STRING, &opt);
924 if (ret != WTAP_OPTTYPE_SUCCESS)
925 return ret;
926 opt->value.stringval = g_strdup_vprintf(format, va);
927 return WTAP_OPTTYPE_SUCCESS;
928 }
929
930 wtap_opttype_return_val
wtap_block_add_string_option_format(wtap_block_t block,guint option_id,const char * format,...)931 wtap_block_add_string_option_format(wtap_block_t block, guint option_id, const char *format, ...)
932 {
933 wtap_opttype_return_val ret;
934 wtap_option_t *opt;
935 va_list va;
936
937 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_STRING, &opt);
938 if (ret != WTAP_OPTTYPE_SUCCESS)
939 return ret;
940 va_start(va, format);
941 opt->value.stringval = g_strdup_vprintf(format, va);
942 va_end(va);
943 return WTAP_OPTTYPE_SUCCESS;
944 }
945
946 wtap_opttype_return_val
wtap_block_set_string_option_value(wtap_block_t block,guint option_id,const char * value,size_t value_length)947 wtap_block_set_string_option_value(wtap_block_t block, guint option_id, const char *value, size_t value_length)
948 {
949 wtap_opttype_return_val ret;
950 wtap_optval_t *optval;
951
952 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_STRING, &optval);
953 if (ret != WTAP_OPTTYPE_SUCCESS) {
954 if (ret == WTAP_OPTTYPE_NOT_FOUND) {
955 /*
956 * There's no instance to set, so just try to create a new one
957 * with the value.
958 */
959 return wtap_block_add_string_option(block, option_id, value, value_length);
960 }
961 /* Otherwise fail. */
962 return ret;
963 }
964 g_free(optval->stringval);
965 optval->stringval = g_strndup(value, value_length);
966 return WTAP_OPTTYPE_SUCCESS;
967 }
968
969 wtap_opttype_return_val
wtap_block_set_nth_string_option_value(wtap_block_t block,guint option_id,guint idx,const char * value,size_t value_length)970 wtap_block_set_nth_string_option_value(wtap_block_t block, guint option_id, guint idx, const char *value, size_t value_length)
971 {
972 wtap_opttype_return_val ret;
973 wtap_optval_t *optval;
974
975 ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_STRING, idx, &optval);
976 if (ret != WTAP_OPTTYPE_SUCCESS)
977 return ret;
978 g_free(optval->stringval);
979 optval->stringval = g_strndup(value, value_length);
980 return WTAP_OPTTYPE_SUCCESS;
981 }
982
983 wtap_opttype_return_val
wtap_block_set_string_option_value_format(wtap_block_t block,guint option_id,const char * format,...)984 wtap_block_set_string_option_value_format(wtap_block_t block, guint option_id, const char *format, ...)
985 {
986 wtap_opttype_return_val ret;
987 wtap_optval_t *optval;
988 va_list va;
989
990 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_STRING, &optval);
991 if (ret != WTAP_OPTTYPE_SUCCESS) {
992 if (ret == WTAP_OPTTYPE_NOT_FOUND) {
993 /*
994 * There's no instance to set, so just try to create a new one
995 * with the formatted string.
996 */
997 va_start(va, format);
998 ret = wtap_block_add_string_option_vformat(block, option_id, format, va);
999 va_end(va);
1000 return ret;
1001 }
1002 /* Otherwise fail. */
1003 return ret;
1004 }
1005 g_free(optval->stringval);
1006 va_start(va, format);
1007 optval->stringval = g_strdup_vprintf(format, va);
1008 va_end(va);
1009 return WTAP_OPTTYPE_SUCCESS;
1010 }
1011
1012 wtap_opttype_return_val
wtap_block_set_nth_string_option_value_format(wtap_block_t block,guint option_id,guint idx,const char * format,...)1013 wtap_block_set_nth_string_option_value_format(wtap_block_t block, guint option_id, guint idx, const char *format, ...)
1014 {
1015 wtap_opttype_return_val ret;
1016 wtap_optval_t *optval;
1017 va_list va;
1018
1019 ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_STRING, idx, &optval);
1020 if (ret != WTAP_OPTTYPE_SUCCESS)
1021 return ret;
1022 g_free(optval->stringval);
1023 va_start(va, format);
1024 optval->stringval = g_strdup_vprintf(format, va);
1025 va_end(va);
1026 return WTAP_OPTTYPE_SUCCESS;
1027 }
1028
1029 wtap_opttype_return_val
wtap_block_get_string_option_value(wtap_block_t block,guint option_id,char ** value)1030 wtap_block_get_string_option_value(wtap_block_t block, guint option_id, char** value)
1031 {
1032 wtap_opttype_return_val ret;
1033 wtap_optval_t *optval;
1034
1035 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_STRING, &optval);
1036 if (ret != WTAP_OPTTYPE_SUCCESS)
1037 return ret;
1038 *value = optval->stringval;
1039 return WTAP_OPTTYPE_SUCCESS;
1040 }
1041
1042 wtap_opttype_return_val
wtap_block_get_nth_string_option_value(wtap_block_t block,guint option_id,guint idx,char ** value)1043 wtap_block_get_nth_string_option_value(wtap_block_t block, guint option_id, guint idx, char** value)
1044 {
1045 wtap_opttype_return_val ret;
1046 wtap_optval_t *optval;
1047
1048 ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_STRING, idx, &optval);
1049 if (ret != WTAP_OPTTYPE_SUCCESS)
1050 return ret;
1051 *value = optval->stringval;
1052 return WTAP_OPTTYPE_SUCCESS;
1053 }
1054
1055 wtap_opttype_return_val
wtap_block_add_bytes_option(wtap_block_t block,guint option_id,const guint8 * value,gsize value_length)1056 wtap_block_add_bytes_option(wtap_block_t block, guint option_id, const guint8 *value, gsize value_length)
1057 {
1058 wtap_opttype_return_val ret;
1059 wtap_option_t *opt;
1060
1061 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_BYTES, &opt);
1062 if (ret != WTAP_OPTTYPE_SUCCESS)
1063 return ret;
1064 opt->value.byteval = g_bytes_new(value, value_length);
1065 return WTAP_OPTTYPE_SUCCESS;
1066 }
1067
1068 wtap_opttype_return_val
wtap_block_add_bytes_option_borrow(wtap_block_t block,guint option_id,GBytes * value)1069 wtap_block_add_bytes_option_borrow(wtap_block_t block, guint option_id, GBytes *value)
1070 {
1071 wtap_opttype_return_val ret;
1072 wtap_option_t *opt;
1073
1074 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_BYTES, &opt);
1075 if (ret != WTAP_OPTTYPE_SUCCESS)
1076 return ret;
1077 opt->value.byteval = g_bytes_ref(value);
1078 return WTAP_OPTTYPE_SUCCESS;
1079 }
1080
1081 wtap_opttype_return_val
wtap_block_set_bytes_option_value(wtap_block_t block,guint option_id,const guint8 * value,size_t value_length)1082 wtap_block_set_bytes_option_value(wtap_block_t block, guint option_id, const guint8 *value, size_t value_length)
1083 {
1084 wtap_opttype_return_val ret;
1085 wtap_optval_t *optval;
1086
1087 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_BYTES, &optval);
1088 if (ret != WTAP_OPTTYPE_SUCCESS) {
1089 if (ret == WTAP_OPTTYPE_NOT_FOUND) {
1090 /*
1091 * There's no instance to set, so just try to create a new one
1092 * with the value.
1093 */
1094 return wtap_block_add_bytes_option(block, option_id, value, value_length);
1095 }
1096 /* Otherwise fail. */
1097 return ret;
1098 }
1099 g_bytes_unref(optval->byteval);
1100 optval->byteval = g_bytes_new(value, value_length);
1101 return WTAP_OPTTYPE_SUCCESS;
1102 }
1103
1104 wtap_opttype_return_val
wtap_block_set_nth_bytes_option_value(wtap_block_t block,guint option_id,guint idx,GBytes * value)1105 wtap_block_set_nth_bytes_option_value(wtap_block_t block, guint option_id, guint idx, GBytes *value)
1106 {
1107 wtap_opttype_return_val ret;
1108 wtap_optval_t *optval;
1109
1110 ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_BYTES, idx, &optval);
1111 if (ret != WTAP_OPTTYPE_SUCCESS)
1112 return ret;
1113 g_bytes_unref(optval->byteval);
1114 optval->byteval = g_bytes_ref(value);
1115 return WTAP_OPTTYPE_SUCCESS;
1116 }
1117
1118 wtap_opttype_return_val
wtap_block_get_bytes_option_value(wtap_block_t block,guint option_id,GBytes ** value)1119 wtap_block_get_bytes_option_value(wtap_block_t block, guint option_id, GBytes** value)
1120 {
1121 wtap_opttype_return_val ret;
1122 wtap_optval_t *optval;
1123
1124 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_BYTES, &optval);
1125 if (ret != WTAP_OPTTYPE_SUCCESS)
1126 return ret;
1127 *value = optval->byteval;
1128 return WTAP_OPTTYPE_SUCCESS;
1129 }
1130
1131 wtap_opttype_return_val
wtap_block_get_nth_bytes_option_value(wtap_block_t block,guint option_id,guint idx,GBytes ** value)1132 wtap_block_get_nth_bytes_option_value(wtap_block_t block, guint option_id, guint idx, GBytes** value)
1133 {
1134 wtap_opttype_return_val ret;
1135 wtap_optval_t *optval;
1136
1137 ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_BYTES, idx, &optval);
1138 if (ret != WTAP_OPTTYPE_SUCCESS)
1139 return ret;
1140 *value = optval->byteval;
1141 return WTAP_OPTTYPE_SUCCESS;
1142 }
1143
1144 wtap_opttype_return_val
wtap_block_add_nflx_custom_option(wtap_block_t block,guint32 type,const char * custom_data,gsize custom_data_len)1145 wtap_block_add_nflx_custom_option(wtap_block_t block, guint32 type, const char *custom_data, gsize custom_data_len)
1146 {
1147 wtap_opttype_return_val ret;
1148 wtap_option_t *opt;
1149
1150 ret = wtap_block_add_option_common(block, OPT_CUSTOM_BIN_COPY, WTAP_OPTTYPE_CUSTOM, &opt);
1151 if (ret != WTAP_OPTTYPE_SUCCESS)
1152 return ret;
1153 opt->value.custom_opt.pen = PEN_NFLX;
1154 opt->value.custom_opt.data.nflx_data.type = type;
1155 opt->value.custom_opt.data.nflx_data.custom_data_len = custom_data_len;
1156 opt->value.custom_opt.data.nflx_data.custom_data = g_memdup2(custom_data, custom_data_len);
1157 opt->value.custom_opt.data.nflx_data.use_little_endian = (block->info->block_type == WTAP_BLOCK_CUSTOM);
1158 return WTAP_OPTTYPE_SUCCESS;
1159 }
1160
1161 wtap_opttype_return_val
wtap_block_get_nflx_custom_option(wtap_block_t block,guint32 nflx_type,char * nflx_custom_data _U_,gsize nflx_custom_data_len)1162 wtap_block_get_nflx_custom_option(wtap_block_t block, guint32 nflx_type, char *nflx_custom_data _U_, gsize nflx_custom_data_len)
1163 {
1164 const wtap_opttype_t *opttype;
1165 wtap_option_t *opt;
1166 guint i;
1167
1168 if (block == NULL) {
1169 return WTAP_OPTTYPE_BAD_BLOCK;
1170 }
1171 opttype = GET_OPTION_TYPE(block->info->options, OPT_CUSTOM_BIN_COPY);
1172 if (opttype == NULL) {
1173 return WTAP_OPTTYPE_NO_SUCH_OPTION;
1174 }
1175 if (opttype->data_type != WTAP_OPTTYPE_CUSTOM) {
1176 return WTAP_OPTTYPE_TYPE_MISMATCH;
1177 }
1178
1179 for (i = 0; i < block->options->len; i++) {
1180 opt = &g_array_index(block->options, wtap_option_t, i);
1181 if ((opt->option_id == OPT_CUSTOM_BIN_COPY) &&
1182 (opt->value.custom_opt.pen == PEN_NFLX) &&
1183 (opt->value.custom_opt.data.nflx_data.type == nflx_type)) {
1184 break;
1185 }
1186 }
1187 if (i == block->options->len) {
1188 return WTAP_OPTTYPE_NOT_FOUND;
1189 }
1190 if (nflx_custom_data_len < opt->value.custom_opt.data.nflx_data.custom_data_len) {
1191 return WTAP_OPTTYPE_TYPE_MISMATCH;
1192 }
1193 switch (nflx_type) {
1194 case NFLX_OPT_TYPE_VERSION: {
1195 guint32 *src, *dst;
1196
1197 ws_assert(nflx_custom_data_len == sizeof(guint32));
1198 src = (guint32 *)opt->value.custom_opt.data.nflx_data.custom_data;
1199 dst = (guint32 *)nflx_custom_data;
1200 *dst = GUINT32_FROM_LE(*src);
1201 break;
1202 }
1203 case NFLX_OPT_TYPE_TCPINFO: {
1204 struct nflx_tcpinfo *src, *dst;
1205
1206 ws_assert(nflx_custom_data_len == sizeof(struct nflx_tcpinfo));
1207 src = (struct nflx_tcpinfo *)opt->value.custom_opt.data.nflx_data.custom_data;
1208 dst = (struct nflx_tcpinfo *)nflx_custom_data;
1209 dst->tlb_tv_sec = GUINT64_FROM_LE(src->tlb_tv_sec);
1210 dst->tlb_tv_usec = GUINT64_FROM_LE(src->tlb_tv_usec);
1211 dst->tlb_ticks = GUINT32_FROM_LE(src->tlb_ticks);
1212 dst->tlb_sn = GUINT32_FROM_LE(src->tlb_sn);
1213 dst->tlb_stackid = src->tlb_stackid;
1214 dst->tlb_eventid = src->tlb_eventid;
1215 dst->tlb_eventflags = GUINT16_FROM_LE(src->tlb_eventflags);
1216 dst->tlb_errno = GINT32_FROM_LE(src->tlb_errno);
1217 dst->tlb_rxbuf_tls_sb_acc = GUINT32_FROM_LE(src->tlb_rxbuf_tls_sb_acc);
1218 dst->tlb_rxbuf_tls_sb_ccc = GUINT32_FROM_LE(src->tlb_rxbuf_tls_sb_ccc);
1219 dst->tlb_rxbuf_tls_sb_spare = GUINT32_FROM_LE(src->tlb_rxbuf_tls_sb_spare);
1220 dst->tlb_txbuf_tls_sb_acc = GUINT32_FROM_LE(src->tlb_txbuf_tls_sb_acc);
1221 dst->tlb_txbuf_tls_sb_ccc = GUINT32_FROM_LE(src->tlb_txbuf_tls_sb_ccc);
1222 dst->tlb_txbuf_tls_sb_spare = GUINT32_FROM_LE(src->tlb_txbuf_tls_sb_spare);
1223 dst->tlb_state = GINT32_FROM_LE(src->tlb_state);
1224 dst->tlb_starttime = GUINT32_FROM_LE(src->tlb_starttime);
1225 dst->tlb_iss = GUINT32_FROM_LE(src->tlb_iss);
1226 dst->tlb_flags = GUINT32_FROM_LE(src->tlb_flags);
1227 dst->tlb_snd_una = GUINT32_FROM_LE(src->tlb_snd_una);
1228 dst->tlb_snd_max = GUINT32_FROM_LE(src->tlb_snd_max);
1229 dst->tlb_snd_cwnd = GUINT32_FROM_LE(src->tlb_snd_cwnd);
1230 dst->tlb_snd_nxt = GUINT32_FROM_LE(src->tlb_snd_nxt);
1231 dst->tlb_snd_recover = GUINT32_FROM_LE(src->tlb_snd_recover);
1232 dst->tlb_snd_wnd = GUINT32_FROM_LE(src->tlb_snd_wnd);
1233 dst->tlb_snd_ssthresh = GUINT32_FROM_LE(src->tlb_snd_ssthresh);
1234 dst->tlb_srtt = GUINT32_FROM_LE(src->tlb_srtt);
1235 dst->tlb_rttvar = GUINT32_FROM_LE(src->tlb_rttvar);
1236 dst->tlb_rcv_up = GUINT32_FROM_LE(src->tlb_rcv_up);
1237 dst->tlb_rcv_adv = GUINT32_FROM_LE(src->tlb_rcv_adv);
1238 dst->tlb_flags2 = GUINT32_FROM_LE(src->tlb_flags2);
1239 dst->tlb_rcv_nxt = GUINT32_FROM_LE(src->tlb_rcv_nxt);
1240 dst->tlb_rcv_wnd = GUINT32_FROM_LE(src->tlb_rcv_wnd);
1241 dst->tlb_dupacks = GUINT32_FROM_LE(src->tlb_dupacks);
1242 dst->tlb_segqlen = GINT32_FROM_LE(src->tlb_segqlen);
1243 dst->tlb_snd_numholes = GINT32_FROM_LE(src->tlb_snd_numholes);
1244 dst->tlb_flex1 = GUINT32_FROM_LE(src->tlb_flex1);
1245 dst->tlb_flex2 = GUINT32_FROM_LE(src->tlb_flex2);
1246 dst->tlb_fbyte_in = GUINT32_FROM_LE(src->tlb_fbyte_in);
1247 dst->tlb_fbyte_out = GUINT32_FROM_LE(src->tlb_fbyte_out);
1248 dst->tlb_snd_scale = src->tlb_snd_scale;
1249 dst->tlb_rcv_scale = src->tlb_rcv_scale;
1250 for (i = 0; i < 3; i++) {
1251 dst->_pad[i] = src->_pad[i];
1252 }
1253 dst->tlb_stackinfo_bbr_cur_del_rate = GUINT64_FROM_LE(src->tlb_stackinfo_bbr_cur_del_rate);
1254 dst->tlb_stackinfo_bbr_delRate = GUINT64_FROM_LE(src->tlb_stackinfo_bbr_delRate);
1255 dst->tlb_stackinfo_bbr_rttProp = GUINT64_FROM_LE(src->tlb_stackinfo_bbr_rttProp);
1256 dst->tlb_stackinfo_bbr_bw_inuse = GUINT64_FROM_LE(src->tlb_stackinfo_bbr_bw_inuse);
1257 dst->tlb_stackinfo_bbr_inflight = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_inflight);
1258 dst->tlb_stackinfo_bbr_applimited = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_applimited);
1259 dst->tlb_stackinfo_bbr_delivered = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_delivered);
1260 dst->tlb_stackinfo_bbr_timeStamp = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_timeStamp);
1261 dst->tlb_stackinfo_bbr_epoch = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_epoch);
1262 dst->tlb_stackinfo_bbr_lt_epoch = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_lt_epoch);
1263 dst->tlb_stackinfo_bbr_pkts_out = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_pkts_out);
1264 dst->tlb_stackinfo_bbr_flex1 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex1);
1265 dst->tlb_stackinfo_bbr_flex2 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex2);
1266 dst->tlb_stackinfo_bbr_flex3 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex3);
1267 dst->tlb_stackinfo_bbr_flex4 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex4);
1268 dst->tlb_stackinfo_bbr_flex5 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex5);
1269 dst->tlb_stackinfo_bbr_flex6 = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_flex6);
1270 dst->tlb_stackinfo_bbr_lost = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_lost);
1271 dst->tlb_stackinfo_bbr_pacing_gain = GUINT16_FROM_LE(src->tlb_stackinfo_bbr_lost);
1272 dst->tlb_stackinfo_bbr_cwnd_gain = GUINT16_FROM_LE(src->tlb_stackinfo_bbr_lost);
1273 dst->tlb_stackinfo_bbr_flex7 = GUINT16_FROM_LE(src->tlb_stackinfo_bbr_flex7);
1274 dst->tlb_stackinfo_bbr_bbr_state = src->tlb_stackinfo_bbr_bbr_state;
1275 dst->tlb_stackinfo_bbr_bbr_substate = src->tlb_stackinfo_bbr_bbr_substate;
1276 dst->tlb_stackinfo_bbr_inhpts = src->tlb_stackinfo_bbr_inhpts;
1277 dst->tlb_stackinfo_bbr_ininput = src->tlb_stackinfo_bbr_ininput;
1278 dst->tlb_stackinfo_bbr_use_lt_bw = src->tlb_stackinfo_bbr_use_lt_bw;
1279 dst->tlb_stackinfo_bbr_flex8 = src->tlb_stackinfo_bbr_flex8;
1280 dst->tlb_stackinfo_bbr_pkt_epoch = GUINT32_FROM_LE(src->tlb_stackinfo_bbr_pkt_epoch);
1281 dst->tlb_len = GUINT32_FROM_LE(src->tlb_len);
1282 break;
1283 }
1284 case NFLX_OPT_TYPE_DUMPINFO: {
1285 struct nflx_dumpinfo *src, *dst;
1286
1287 ws_assert(nflx_custom_data_len == sizeof(struct nflx_dumpinfo));
1288 src = (struct nflx_dumpinfo *)opt->value.custom_opt.data.nflx_data.custom_data;
1289 dst = (struct nflx_dumpinfo *)nflx_custom_data;
1290 dst->tlh_version = GUINT32_FROM_LE(src->tlh_version);
1291 dst->tlh_type = GUINT32_FROM_LE(src->tlh_type);
1292 dst->tlh_length = GUINT64_FROM_LE(src->tlh_length);
1293 dst->tlh_ie_fport = src->tlh_ie_fport;
1294 dst->tlh_ie_lport = src->tlh_ie_lport;
1295 for (i = 0; i < 4; i++) {
1296 dst->tlh_ie_faddr_addr32[i] = src->tlh_ie_faddr_addr32[i];
1297 dst->tlh_ie_laddr_addr32[i] = src->tlh_ie_laddr_addr32[i];
1298 }
1299 dst->tlh_ie_zoneid = src->tlh_ie_zoneid;
1300 dst->tlh_offset_tv_sec = GUINT64_FROM_LE(src->tlh_offset_tv_sec);
1301 dst->tlh_offset_tv_usec = GUINT64_FROM_LE(src->tlh_offset_tv_usec);
1302 memcpy(dst->tlh_id, src->tlh_id, 64);
1303 memcpy(dst->tlh_reason, src->tlh_reason, 32);
1304 memcpy(dst->tlh_tag, src->tlh_tag, 32);
1305 dst->tlh_af = src->tlh_af;
1306 memcpy(dst->_pad, src->_pad, 7);
1307 break;
1308 }
1309 case NFLX_OPT_TYPE_DUMPTIME: {
1310 guint64 *src, *dst;
1311
1312 ws_assert(nflx_custom_data_len == sizeof(guint64));
1313 src = (guint64 *)opt->value.custom_opt.data.nflx_data.custom_data;
1314 dst = (guint64 *)nflx_custom_data;
1315 *dst = GUINT64_FROM_LE(*src);
1316 break;
1317 }
1318 case NFLX_OPT_TYPE_STACKNAME:
1319 ws_assert(nflx_custom_data_len >= 2);
1320 memcpy(nflx_custom_data, opt->value.custom_opt.data.nflx_data.custom_data, nflx_custom_data_len);
1321 break;
1322 default:
1323 return WTAP_OPTTYPE_NOT_FOUND;
1324 }
1325 return WTAP_OPTTYPE_SUCCESS;
1326 }
1327
1328 wtap_opttype_return_val
wtap_block_add_custom_option(wtap_block_t block,guint option_id,guint32 pen,const char * custom_data,gsize custom_data_len)1329 wtap_block_add_custom_option(wtap_block_t block, guint option_id, guint32 pen, const char *custom_data, gsize custom_data_len)
1330 {
1331 wtap_opttype_return_val ret;
1332 wtap_option_t *opt;
1333
1334 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_CUSTOM, &opt);
1335 if (ret != WTAP_OPTTYPE_SUCCESS)
1336 return ret;
1337 opt->value.custom_opt.pen = pen;
1338 opt->value.custom_opt.data.generic_data.custom_data_len = custom_data_len;
1339 opt->value.custom_opt.data.generic_data.custom_data = g_memdup2(custom_data, custom_data_len);
1340 return WTAP_OPTTYPE_SUCCESS;
1341 }
1342
1343 wtap_opttype_return_val
wtap_block_add_if_filter_option(wtap_block_t block,guint option_id,if_filter_opt_t * value)1344 wtap_block_add_if_filter_option(wtap_block_t block, guint option_id, if_filter_opt_t* value)
1345 {
1346 wtap_opttype_return_val ret;
1347 wtap_option_t *opt;
1348
1349 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_IF_FILTER, &opt);
1350 if (ret != WTAP_OPTTYPE_SUCCESS)
1351 return ret;
1352 opt->value.if_filterval = if_filter_dup(value);
1353 return WTAP_OPTTYPE_SUCCESS;
1354 }
1355
1356 wtap_opttype_return_val
wtap_block_set_if_filter_option_value(wtap_block_t block,guint option_id,if_filter_opt_t * value)1357 wtap_block_set_if_filter_option_value(wtap_block_t block, guint option_id, if_filter_opt_t* value)
1358 {
1359 wtap_opttype_return_val ret;
1360 wtap_optval_t *optval;
1361 if_filter_opt_t prev_value;
1362
1363 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IF_FILTER, &optval);
1364 if (ret != WTAP_OPTTYPE_SUCCESS)
1365 return ret;
1366 prev_value = optval->if_filterval;
1367 optval->if_filterval = if_filter_dup(value);
1368 /* Free after memory is duplicated in case structure was manipulated with a "get then set" */
1369 if_filter_free(&prev_value);
1370
1371 return WTAP_OPTTYPE_SUCCESS;
1372 }
1373
1374 wtap_opttype_return_val
wtap_block_get_if_filter_option_value(wtap_block_t block,guint option_id,if_filter_opt_t * value)1375 wtap_block_get_if_filter_option_value(wtap_block_t block, guint option_id, if_filter_opt_t* value)
1376 {
1377 wtap_opttype_return_val ret;
1378 wtap_optval_t *optval;
1379
1380 ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IF_FILTER, &optval);
1381 if (ret != WTAP_OPTTYPE_SUCCESS)
1382 return ret;
1383 *value = optval->if_filterval;
1384 return WTAP_OPTTYPE_SUCCESS;
1385 }
1386
1387 wtap_opttype_return_val
wtap_block_add_packet_verdict_option(wtap_block_t block,guint option_id,packet_verdict_opt_t * value)1388 wtap_block_add_packet_verdict_option(wtap_block_t block, guint option_id, packet_verdict_opt_t* value)
1389 {
1390 wtap_opttype_return_val ret;
1391 wtap_option_t *opt;
1392
1393 ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_PACKET_VERDICT, &opt);
1394 if (ret != WTAP_OPTTYPE_SUCCESS)
1395 return ret;
1396 opt->value.packet_verdictval = packet_verdict_dup(value);
1397 return WTAP_OPTTYPE_SUCCESS;
1398 }
1399
1400 wtap_opttype_return_val
wtap_block_set_nth_packet_verdict_option_value(wtap_block_t block,guint option_id,guint idx,packet_verdict_opt_t * value)1401 wtap_block_set_nth_packet_verdict_option_value(wtap_block_t block, guint option_id, guint idx, packet_verdict_opt_t* value)
1402 {
1403 wtap_opttype_return_val ret;
1404 wtap_optval_t *optval;
1405 packet_verdict_opt_t prev_value;
1406
1407 ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_PACKET_VERDICT, idx, &optval);
1408 if (ret != WTAP_OPTTYPE_SUCCESS)
1409 return ret;
1410 prev_value = optval->packet_verdictval;
1411 optval->packet_verdictval = packet_verdict_dup(value);
1412 /* Free after memory is duplicated in case structure was manipulated with a "get then set" */
1413 wtap_packet_verdict_free(&prev_value);
1414
1415 return WTAP_OPTTYPE_SUCCESS;
1416 }
1417
1418 wtap_opttype_return_val
wtap_block_get_nth_packet_verdict_option_value(wtap_block_t block,guint option_id,guint idx,packet_verdict_opt_t * value)1419 wtap_block_get_nth_packet_verdict_option_value(wtap_block_t block, guint option_id, guint idx, packet_verdict_opt_t* value)
1420 {
1421 wtap_opttype_return_val ret;
1422 wtap_optval_t *optval;
1423
1424 ret = wtap_block_get_nth_option_common(block, option_id, WTAP_OPTTYPE_STRING, idx, &optval);
1425 if (ret != WTAP_OPTTYPE_SUCCESS)
1426 return ret;
1427 *value = optval->packet_verdictval;
1428 return WTAP_OPTTYPE_SUCCESS;
1429 }
1430
1431 wtap_opttype_return_val
wtap_block_remove_option(wtap_block_t block,guint option_id)1432 wtap_block_remove_option(wtap_block_t block, guint option_id)
1433 {
1434 const wtap_opttype_t *opttype;
1435 guint i;
1436 wtap_option_t *opt;
1437
1438 if (block == NULL) {
1439 return WTAP_OPTTYPE_BAD_BLOCK;
1440 }
1441
1442 opttype = GET_OPTION_TYPE(block->info->options, option_id);
1443 if (opttype == NULL) {
1444 /* There's no option for this block with that option ID */
1445 return WTAP_OPTTYPE_NO_SUCH_OPTION;
1446 }
1447
1448 /*
1449 * Can there be more than one instance of this option?
1450 */
1451 if (opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED) {
1452 /*
1453 * Yes. You can't remove "the" value.
1454 */
1455 return WTAP_OPTTYPE_NUMBER_MISMATCH;
1456 }
1457
1458 for (i = 0; i < block->options->len; i++) {
1459 opt = &g_array_index(block->options, wtap_option_t, i);
1460 if (opt->option_id == option_id) {
1461 /* Found it - free up the value */
1462 wtap_block_free_option(block, opt);
1463 /* Remove the option from the array of options */
1464 g_array_remove_index(block->options, i);
1465 return WTAP_OPTTYPE_SUCCESS;
1466 }
1467 }
1468
1469 /* Didn't find the option */
1470 return WTAP_OPTTYPE_NOT_FOUND;
1471 }
1472
1473 wtap_opttype_return_val
wtap_block_remove_nth_option_instance(wtap_block_t block,guint option_id,guint idx)1474 wtap_block_remove_nth_option_instance(wtap_block_t block, guint option_id,
1475 guint idx)
1476 {
1477 const wtap_opttype_t *opttype;
1478 guint i;
1479 wtap_option_t *opt;
1480 guint opt_idx;
1481
1482 if (block == NULL) {
1483 return WTAP_OPTTYPE_BAD_BLOCK;
1484 }
1485
1486 opttype = GET_OPTION_TYPE(block->info->options, option_id);
1487 if (opttype == NULL) {
1488 /* There's no option for this block with that option ID */
1489 return WTAP_OPTTYPE_NO_SUCH_OPTION;
1490 }
1491
1492 /*
1493 * Can there be more than one instance of this option?
1494 */
1495 if (!(opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED)) {
1496 /*
1497 * No.
1498 */
1499 return WTAP_OPTTYPE_NUMBER_MISMATCH;
1500 }
1501
1502 opt_idx = 0;
1503 for (i = 0; i < block->options->len; i++) {
1504 opt = &g_array_index(block->options, wtap_option_t, i);
1505 if (opt->option_id == option_id) {
1506 if (opt_idx == idx) {
1507 /* Found it - free up the value */
1508 wtap_block_free_option(block, opt);
1509 /* Remove the option from the array of options */
1510 g_array_remove_index(block->options, i);
1511 return WTAP_OPTTYPE_SUCCESS;
1512 }
1513 opt_idx++;
1514 }
1515 }
1516
1517 /* Didn't find the option */
1518 return WTAP_OPTTYPE_NOT_FOUND;
1519 }
1520
shb_create(wtap_block_t block)1521 static void shb_create(wtap_block_t block)
1522 {
1523 wtapng_section_mandatory_t* section_mand = g_new(wtapng_section_mandatory_t, 1);
1524
1525 section_mand->section_length = -1;
1526
1527 block->mandatory_data = section_mand;
1528 }
1529
shb_copy_mand(wtap_block_t dest_block,wtap_block_t src_block)1530 static void shb_copy_mand(wtap_block_t dest_block, wtap_block_t src_block)
1531 {
1532 memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_section_mandatory_t));
1533 }
1534
nrb_create(wtap_block_t block)1535 static void nrb_create(wtap_block_t block)
1536 {
1537 block->mandatory_data = NULL;
1538 }
1539
isb_create(wtap_block_t block)1540 static void isb_create(wtap_block_t block)
1541 {
1542 block->mandatory_data = g_new0(wtapng_if_stats_mandatory_t, 1);
1543 }
1544
isb_copy_mand(wtap_block_t dest_block,wtap_block_t src_block)1545 static void isb_copy_mand(wtap_block_t dest_block, wtap_block_t src_block)
1546 {
1547 memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_if_stats_mandatory_t));
1548 }
1549
idb_create(wtap_block_t block)1550 static void idb_create(wtap_block_t block)
1551 {
1552 block->mandatory_data = g_new0(wtapng_if_descr_mandatory_t, 1);
1553 }
1554
idb_free_mand(wtap_block_t block)1555 static void idb_free_mand(wtap_block_t block)
1556 {
1557 guint j;
1558 wtap_block_t if_stats;
1559 wtapng_if_descr_mandatory_t* mand = (wtapng_if_descr_mandatory_t*)block->mandatory_data;
1560
1561 for(j = 0; j < mand->num_stat_entries; j++) {
1562 if_stats = g_array_index(mand->interface_statistics, wtap_block_t, j);
1563 wtap_block_unref(if_stats);
1564 }
1565
1566 if (mand->interface_statistics)
1567 g_array_free(mand->interface_statistics, TRUE);
1568 }
1569
idb_copy_mand(wtap_block_t dest_block,wtap_block_t src_block)1570 static void idb_copy_mand(wtap_block_t dest_block, wtap_block_t src_block)
1571 {
1572 guint j;
1573 wtap_block_t src_if_stats, dest_if_stats;
1574 wtapng_if_descr_mandatory_t *src_mand = (wtapng_if_descr_mandatory_t*)src_block->mandatory_data,
1575 *dest_mand = (wtapng_if_descr_mandatory_t*)dest_block->mandatory_data;
1576
1577 /* Need special consideration for copying of the interface_statistics member */
1578 if (dest_mand->num_stat_entries != 0)
1579 g_array_free(dest_mand->interface_statistics, TRUE);
1580
1581 memcpy(dest_mand, src_mand, sizeof(wtapng_if_descr_mandatory_t));
1582 if (src_mand->num_stat_entries != 0)
1583 {
1584 dest_mand->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtap_block_t));
1585 for (j = 0; j < src_mand->num_stat_entries; j++)
1586 {
1587 src_if_stats = g_array_index(src_mand->interface_statistics, wtap_block_t, j);
1588 dest_if_stats = wtap_block_make_copy(src_if_stats);
1589 dest_mand->interface_statistics = g_array_append_val(dest_mand->interface_statistics, dest_if_stats);
1590 }
1591 }
1592 }
1593
dsb_create(wtap_block_t block)1594 static void dsb_create(wtap_block_t block)
1595 {
1596 block->mandatory_data = g_new0(wtapng_dsb_mandatory_t, 1);
1597 }
1598
dsb_free_mand(wtap_block_t block)1599 static void dsb_free_mand(wtap_block_t block)
1600 {
1601 wtapng_dsb_mandatory_t *mand = (wtapng_dsb_mandatory_t *)block->mandatory_data;
1602 g_free(mand->secrets_data);
1603 }
1604
dsb_copy_mand(wtap_block_t dest_block,wtap_block_t src_block)1605 static void dsb_copy_mand(wtap_block_t dest_block, wtap_block_t src_block)
1606 {
1607 wtapng_dsb_mandatory_t *src = (wtapng_dsb_mandatory_t *)src_block->mandatory_data;
1608 wtapng_dsb_mandatory_t *dst = (wtapng_dsb_mandatory_t *)dest_block->mandatory_data;
1609 dst->secrets_type = src->secrets_type;
1610 dst->secrets_len = src->secrets_len;
1611 g_free(dst->secrets_data);
1612 dst->secrets_data = (guint8 *)g_memdup2(src->secrets_data, src->secrets_len);
1613 }
1614
pkt_create(wtap_block_t block)1615 static void pkt_create(wtap_block_t block)
1616 {
1617 /* Commented out for now, there's no mandatory data that isn't handled by
1618 * Wireshark in other ways.
1619 */
1620 //block->mandatory_data = g_new0(wtapng_packet_mandatory_t, 1);
1621
1622 /* Ensure this is null, so when g_free is called on it, it simply returns */
1623 block->mandatory_data = NULL;
1624 }
1625
cb_create(wtap_block_t block)1626 static void cb_create(wtap_block_t block)
1627 {
1628 /* Ensure this is null, so when g_free is called on it, it simply returns */
1629 block->mandatory_data = NULL;
1630 }
1631
wtap_opttypes_initialize(void)1632 void wtap_opttypes_initialize(void)
1633 {
1634 static wtap_blocktype_t shb_block = {
1635 WTAP_BLOCK_SECTION, /* block_type */
1636 "SHB", /* name */
1637 "Section Header Block", /* description */
1638 shb_create, /* create */
1639 NULL, /* free_mand */
1640 shb_copy_mand, /* copy_mand */
1641 NULL /* options */
1642 };
1643 static const wtap_opttype_t shb_hardware = {
1644 "hardware",
1645 "SHB Hardware",
1646 WTAP_OPTTYPE_STRING,
1647 0
1648 };
1649 static const wtap_opttype_t shb_os = {
1650 "os",
1651 "SHB Operating System",
1652 WTAP_OPTTYPE_STRING,
1653 0
1654 };
1655 static const wtap_opttype_t shb_userappl = {
1656 "user_appl",
1657 "SHB User Application",
1658 WTAP_OPTTYPE_STRING,
1659 0
1660 };
1661
1662 static wtap_blocktype_t idb_block = {
1663 WTAP_BLOCK_IF_ID_AND_INFO, /* block_type */
1664 "IDB", /* name */
1665 "Interface Description Block", /* description */
1666 idb_create, /* create */
1667 idb_free_mand, /* free_mand */
1668 idb_copy_mand, /* copy_mand */
1669 NULL /* options */
1670 };
1671 static const wtap_opttype_t if_name = {
1672 "name",
1673 "IDB Name",
1674 WTAP_OPTTYPE_STRING,
1675 0
1676 };
1677 static const wtap_opttype_t if_description = {
1678 "description",
1679 "IDB Description",
1680 WTAP_OPTTYPE_STRING,
1681 0
1682 };
1683 static const wtap_opttype_t if_speed = {
1684 "speed",
1685 "IDB Speed",
1686 WTAP_OPTTYPE_UINT64,
1687 0
1688 };
1689 static const wtap_opttype_t if_tsresol = {
1690 "tsresol",
1691 "IDB Time Stamp Resolution",
1692 WTAP_OPTTYPE_UINT8, /* XXX - signed? */
1693 0
1694 };
1695 static const wtap_opttype_t if_filter = {
1696 "filter",
1697 "IDB Filter",
1698 WTAP_OPTTYPE_IF_FILTER,
1699 0
1700 };
1701 static const wtap_opttype_t if_os = {
1702 "os",
1703 "IDB Operating System",
1704 WTAP_OPTTYPE_STRING,
1705 0
1706 };
1707 static const wtap_opttype_t if_fcslen = {
1708 "fcslen",
1709 "IDB FCS Length",
1710 WTAP_OPTTYPE_UINT8,
1711 0
1712 };
1713 static const wtap_opttype_t if_hardware = {
1714 "hardware",
1715 "IDB Hardware",
1716 WTAP_OPTTYPE_STRING,
1717 0
1718 };
1719
1720 static wtap_blocktype_t dsb_block = {
1721 WTAP_BLOCK_DECRYPTION_SECRETS,
1722 "DSB",
1723 "Decryption Secrets Block",
1724 dsb_create,
1725 dsb_free_mand,
1726 dsb_copy_mand,
1727 NULL
1728 };
1729
1730 static wtap_blocktype_t nrb_block = {
1731 WTAP_BLOCK_NAME_RESOLUTION, /* block_type */
1732 "NRB", /* name */
1733 "Name Resolution Block", /* description */
1734 nrb_create, /* create */
1735 NULL, /* free_mand */
1736 NULL, /* copy_mand */
1737 NULL /* options */
1738 };
1739 static const wtap_opttype_t ns_dnsname = {
1740 "dnsname",
1741 "NRB DNS server name",
1742 WTAP_OPTTYPE_STRING,
1743 0
1744 };
1745 static const wtap_opttype_t ns_dnsIP4addr = {
1746 "dnsIP4addr",
1747 "NRB DNS server IPv4 address",
1748 WTAP_OPTTYPE_IPv4,
1749 0
1750 };
1751 static const wtap_opttype_t ns_dnsIP6addr = {
1752 "dnsIP6addr",
1753 "NRB DNS server IPv6 address",
1754 WTAP_OPTTYPE_IPv6,
1755 0
1756 };
1757
1758 static wtap_blocktype_t isb_block = {
1759 WTAP_BLOCK_IF_STATISTICS, /* block_type */
1760 "ISB", /* name */
1761 "Interface Statistics Block", /* description */
1762 isb_create, /* create */
1763 NULL, /* free_mand */
1764 isb_copy_mand, /* copy_mand */
1765 NULL /* options */
1766 };
1767 static const wtap_opttype_t isb_starttime = {
1768 "starttime",
1769 "ISB Start Time",
1770 WTAP_OPTTYPE_UINT64,
1771 0
1772 };
1773 static const wtap_opttype_t isb_endtime = {
1774 "endtime",
1775 "ISB End Time",
1776 WTAP_OPTTYPE_UINT64,
1777 0
1778 };
1779 static const wtap_opttype_t isb_ifrecv = {
1780 "ifrecv",
1781 "ISB Received Packets",
1782 WTAP_OPTTYPE_UINT64,
1783 0
1784 };
1785 static const wtap_opttype_t isb_ifdrop = {
1786 "ifdrop",
1787 "ISB Dropped Packets",
1788 WTAP_OPTTYPE_UINT64,
1789 0
1790 };
1791 static const wtap_opttype_t isb_filteraccept = {
1792 "filteraccept",
1793 "ISB Packets Accepted By Filter",
1794 WTAP_OPTTYPE_UINT64,
1795 0
1796 };
1797 static const wtap_opttype_t isb_osdrop = {
1798 "osdrop",
1799 "ISB Packets Dropped By The OS",
1800 WTAP_OPTTYPE_UINT64,
1801 0
1802 };
1803 static const wtap_opttype_t isb_usrdeliv = {
1804 "usrdeliv",
1805 "ISB Packets Delivered To The User",
1806 WTAP_OPTTYPE_UINT64,
1807 0
1808 };
1809
1810 static wtap_blocktype_t pkt_block = {
1811 WTAP_BLOCK_PACKET, /* block_type */
1812 "EPB/SPB/PB", /* name */
1813 "Packet Block", /* description */
1814 pkt_create, /* create */
1815 NULL, /* free_mand */
1816 NULL, /* copy_mand */
1817 NULL /* options */
1818 };
1819 static const wtap_opttype_t pkt_flags = {
1820 "flags",
1821 "Link-layer flags",
1822 WTAP_OPTTYPE_UINT32,
1823 0
1824 };
1825 static const wtap_opttype_t pkt_dropcount = {
1826 "dropcount",
1827 "Packets Dropped since last packet",
1828 WTAP_OPTTYPE_UINT64,
1829 0
1830 };
1831 static const wtap_opttype_t pkt_id = {
1832 "packetid",
1833 "Unique Packet Identifier",
1834 WTAP_OPTTYPE_UINT64,
1835 0
1836 };
1837 static const wtap_opttype_t pkt_queue = {
1838 "queue",
1839 "Queue ID in which packet was received",
1840 WTAP_OPTTYPE_UINT32,
1841 0
1842 };
1843 static const wtap_opttype_t pkt_hash = {
1844 "hash",
1845 "Hash of packet data",
1846 WTAP_OPTTYPE_BYTES, // TODO: replace with a pkt_hash_opt_t
1847 WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED
1848 };
1849 static const wtap_opttype_t pkt_verdict = {
1850 "verdict",
1851 "Packet Verdict",
1852 WTAP_OPTTYPE_PACKET_VERDICT,
1853 WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED
1854 };
1855
1856 static wtap_blocktype_t cb_block = {
1857 WTAP_BLOCK_CUSTOM, /* block_type */
1858 "CB", /* name */
1859 "Packet Block", /* description */
1860 cb_create, /* create */
1861 NULL, /* free_mand */
1862 NULL, /* copy_mand */
1863 NULL /* options */
1864 };
1865
1866 /*
1867 * Register the SHB and the options that can appear in it.
1868 */
1869 wtap_opttype_block_register(&shb_block);
1870 wtap_opttype_option_register(&shb_block, OPT_SHB_HARDWARE, &shb_hardware);
1871 wtap_opttype_option_register(&shb_block, OPT_SHB_OS, &shb_os);
1872 wtap_opttype_option_register(&shb_block, OPT_SHB_USERAPPL, &shb_userappl);
1873
1874 /*
1875 * Register the IDB and the options that can appear in it.
1876 */
1877 wtap_opttype_block_register(&idb_block);
1878 wtap_opttype_option_register(&idb_block, OPT_IDB_NAME, &if_name);
1879 wtap_opttype_option_register(&idb_block, OPT_IDB_DESCRIPTION, &if_description);
1880 wtap_opttype_option_register(&idb_block, OPT_IDB_SPEED, &if_speed);
1881 wtap_opttype_option_register(&idb_block, OPT_IDB_TSRESOL, &if_tsresol);
1882 wtap_opttype_option_register(&idb_block, OPT_IDB_FILTER, &if_filter);
1883 wtap_opttype_option_register(&idb_block, OPT_IDB_OS, &if_os);
1884 wtap_opttype_option_register(&idb_block, OPT_IDB_FCSLEN, &if_fcslen);
1885 wtap_opttype_option_register(&idb_block, OPT_IDB_HARDWARE, &if_hardware);
1886
1887 /*
1888 * Register the NRB and the options that can appear in it.
1889 */
1890 wtap_opttype_block_register(&nrb_block);
1891 wtap_opttype_option_register(&nrb_block, OPT_NS_DNSNAME, &ns_dnsname);
1892 wtap_opttype_option_register(&nrb_block, OPT_NS_DNSIP4ADDR, &ns_dnsIP4addr);
1893 wtap_opttype_option_register(&nrb_block, OPT_NS_DNSIP6ADDR, &ns_dnsIP6addr);
1894
1895 /*
1896 * Register the ISB and the options that can appear in it.
1897 */
1898 wtap_opttype_block_register(&isb_block);
1899 wtap_opttype_option_register(&isb_block, OPT_ISB_STARTTIME, &isb_starttime);
1900 wtap_opttype_option_register(&isb_block, OPT_ISB_ENDTIME, &isb_endtime);
1901 wtap_opttype_option_register(&isb_block, OPT_ISB_IFRECV, &isb_ifrecv);
1902 wtap_opttype_option_register(&isb_block, OPT_ISB_IFDROP, &isb_ifdrop);
1903 wtap_opttype_option_register(&isb_block, OPT_ISB_FILTERACCEPT, &isb_filteraccept);
1904 wtap_opttype_option_register(&isb_block, OPT_ISB_OSDROP, &isb_osdrop);
1905 wtap_opttype_option_register(&isb_block, OPT_ISB_USRDELIV, &isb_usrdeliv);
1906
1907 /*
1908 * Register the DSB, currently no options are defined.
1909 */
1910 wtap_opttype_block_register(&dsb_block);
1911
1912 /*
1913 * Register EPB/SPB/PB and the options that can appear in it/them.
1914 * NB: Simple Packet Blocks have no options.
1915 * NB: obsolete Packet Blocks have dropcount as a mandatory member instead
1916 * of an option.
1917 */
1918 wtap_opttype_block_register(&pkt_block);
1919 wtap_opttype_option_register(&pkt_block, OPT_PKT_FLAGS, &pkt_flags);
1920 wtap_opttype_option_register(&pkt_block, OPT_PKT_DROPCOUNT, &pkt_dropcount);
1921 wtap_opttype_option_register(&pkt_block, OPT_PKT_PACKETID, &pkt_id);
1922 wtap_opttype_option_register(&pkt_block, OPT_PKT_QUEUE, &pkt_queue);
1923 wtap_opttype_option_register(&pkt_block, OPT_PKT_HASH, &pkt_hash);
1924 wtap_opttype_option_register(&pkt_block, OPT_PKT_VERDICT, &pkt_verdict);
1925
1926 /*
1927 * Register the CB and the options that can appear in it.
1928 */
1929 wtap_opttype_block_register(&cb_block);
1930
1931 #ifdef DEBUG_COUNT_REFS
1932 memset(blocks_active, 0, sizeof(blocks_active));
1933 #endif
1934 }
1935
wtap_opttypes_cleanup(void)1936 void wtap_opttypes_cleanup(void)
1937 {
1938 guint block_type;
1939 #ifdef DEBUG_COUNT_REFS
1940 guint i;
1941 guint cellno;
1942 guint bitno;
1943 guint8 mask;
1944 #endif /* DEBUG_COUNT_REFS */
1945
1946 for (block_type = (guint)WTAP_BLOCK_SECTION;
1947 block_type < (guint)MAX_WTAP_BLOCK_TYPE_VALUE; block_type++) {
1948 if (blocktype_list[block_type]) {
1949 if (blocktype_list[block_type]->options)
1950 g_hash_table_destroy(blocktype_list[block_type]->options);
1951 blocktype_list[block_type] = NULL;
1952 }
1953 }
1954
1955 #ifdef DEBUG_COUNT_REFS
1956 for (i = 0 ; i < block_count; i++) {
1957 cellno = i / 8;
1958 bitno = i % 8;
1959 mask = 1 << bitno;
1960
1961 if ((blocks_active[cellno] & mask) == mask) {
1962 wtap_debug("wtap_opttypes_cleanup: orphaned block #%d", i);
1963 }
1964 }
1965 #endif /* DEBUG_COUNT_REFS */
1966 }
1967