3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 2001 Gerald Combs
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "wtap_opttypes.h"
30 #include "pcapng_module.h"
33 #define wtap_debug(...) g_warning(__VA_ARGS__)
35 #define wtap_debug(...)
38 typedef struct wtap_opt_register
40 const char *name; /**< name of block */
41 const char *description; /**< human-readable description of block */
42 wtap_block_create_func create;
43 wtap_mand_free_func free_mand;
44 wtap_mand_copy_func copy_mand;
45 } wtap_opt_register_t;
47 typedef struct wtap_optblock_internal {
48 const char *name; /**< name of option */
49 const char *description; /**< human-readable description of option */
50 guint number; /**< Option index */
51 wtap_opttype_e type; /**< type of that option */
52 } wtap_optblock_internal_t;
54 typedef struct wtap_optblock_value {
55 wtap_optblock_internal_t* info;
56 wtap_option_type option; /**< pointer to variable storing the value */
57 wtap_option_type default_val; /**< the default value of the option */
58 } wtap_optblock_value_t;
60 struct wtap_optionblock
62 wtap_opt_register_t* info;
64 GArray* option_infos; /* Only want to keep 1 copy of "static" option information */
65 GArray* option_values;
68 #define MAX_WTAP_OPTION_BLOCK_CUSTOM 10
69 #define MAX_WTAP_OPTION_BLOCK_TYPE_VALUE (WTAP_OPTION_BLOCK_END_OF_LIST+MAX_WTAP_OPTION_BLOCK_CUSTOM)
71 /* Keep track of wtap_opt_register_t's via their id number */
72 static wtap_opt_register_t* block_list[MAX_WTAP_OPTION_BLOCK_TYPE_VALUE];
73 static guint num_custom_blocks;
74 static wtap_opt_register_t custom_block_list[MAX_WTAP_OPTION_BLOCK_CUSTOM];
76 static void wtap_opttype_block_register(int block_type, wtap_opt_register_t *block)
79 g_assert(block_type < WTAP_OPTION_BLOCK_END_OF_LIST);
81 /* Don't re-register. */
82 g_assert(block_list[block_type] == NULL);
85 g_assert(block->name);
86 g_assert(block->description);
87 g_assert(block->create);
89 block_list[block_type] = block;
92 int wtap_opttype_register_custom_block_type(const char* name, const char* description, wtap_block_create_func create,
93 wtap_mand_free_func free_mand, wtap_mand_copy_func copy_mand)
97 /* Ensure valid data/functions for required fields */
99 g_assert(description);
102 /* This shouldn't happen, so flag it for fixing */
103 g_assert(num_custom_blocks < MAX_WTAP_OPTION_BLOCK_CUSTOM);
105 block_type = WTAP_OPTION_BLOCK_END_OF_LIST+num_custom_blocks;
107 custom_block_list[num_custom_blocks].name = name;
108 custom_block_list[num_custom_blocks].description = description;
109 custom_block_list[num_custom_blocks].create = create;
110 custom_block_list[num_custom_blocks].free_mand = free_mand;
111 custom_block_list[num_custom_blocks].copy_mand = copy_mand;
112 block_list[block_type] = &custom_block_list[num_custom_blocks];
118 void* wtap_optionblock_get_mandatory_data(wtap_optionblock_t block)
120 return block->mandatory_data;
123 static wtap_optblock_value_t* wtap_optionblock_get_option(wtap_optionblock_t block, guint option_id)
126 wtap_optblock_value_t* opttype = NULL;
128 for (i = 0; i < block->option_values->len; i++)
130 opttype = g_array_index(block->option_values, wtap_optblock_value_t*, i);
131 if (opttype->info->number == option_id)
138 wtap_optionblock_t wtap_optionblock_create(int block_type)
140 wtap_optionblock_t block;
142 if (block_type >= (int)(WTAP_OPTION_BLOCK_END_OF_LIST+num_custom_blocks))
145 block = g_new(struct wtap_optionblock, 1);
146 block->info = block_list[block_type];
147 block->option_infos = g_array_new(FALSE, FALSE, sizeof(wtap_optblock_internal_t*));
148 block->option_values = g_array_new(FALSE, FALSE, sizeof(wtap_optblock_value_t*));
149 block->info->create(block);
154 static void wtap_optionblock_free_options(wtap_optionblock_t block)
157 wtap_optblock_value_t* opttype = NULL;
159 for (i = 0; i < block->option_values->len; i++) {
160 opttype = g_array_index(block->option_values, wtap_optblock_value_t*, i);
161 switch(opttype->info->type)
163 case WTAP_OPTTYPE_STRING:
164 g_free(opttype->option.stringval);
166 case WTAP_OPTTYPE_CUSTOM:
167 opttype->option.customval.free_func(opttype->option.customval.data);
168 g_free(opttype->option.customval.data);
169 opttype->default_val.customval.free_func(opttype->default_val.customval.data);
170 g_free(opttype->default_val.customval.data);
179 void wtap_optionblock_free(wtap_optionblock_t block)
184 if (block->info->free_mand != NULL)
185 block->info->free_mand(block);
187 g_free(block->mandatory_data);
188 wtap_optionblock_free_options(block);
189 for (i = 0; i < block->option_infos->len; i++)
190 g_free(g_array_index(block->option_infos, wtap_optblock_internal_t*, i));
191 if (block->option_infos != NULL)
192 g_array_free(block->option_infos, TRUE);
193 if (block->option_values != NULL)
194 g_array_free(block->option_values, TRUE);
199 void wtap_optionblock_array_free(GArray* block_array)
202 if (block_array == NULL)
205 for (block = 0; block < block_array->len; block++) {
206 wtap_optionblock_free(g_array_index(block_array, wtap_optionblock_t, block));
208 g_array_free(block_array, TRUE);
211 void wtap_optionblock_copy_options(wtap_optionblock_t dest_block, wtap_optionblock_t src_block)
214 wtap_optblock_internal_t *src_internal;
215 wtap_optblock_value_t *dest_value, *src_value;
217 if (dest_block->info->copy_mand != NULL)
218 dest_block->info->copy_mand(dest_block, src_block);
220 /* Copy the options. For now, don't remove any options that are in destination
223 for (i = 0; i < src_block->option_values->len; i++)
225 src_internal = g_array_index(src_block->option_infos, wtap_optblock_internal_t*, i);
226 src_value = g_array_index(src_block->option_values, wtap_optblock_value_t*, i);
227 dest_value = wtap_optionblock_get_option(dest_block, src_internal->number);
228 if (dest_value == NULL)
230 wtap_optblock_reg_t reg_optblock;
232 reg_optblock.name = src_internal->name;
233 reg_optblock.description = src_internal->description;
234 reg_optblock.type = src_internal->type;
235 reg_optblock.option = src_value->option;
236 reg_optblock.default_val = src_value->default_val;
238 wtap_optionblock_add_option(dest_block, src_internal->number, ®_optblock);
242 /* Option exists, replace it */
243 switch(src_internal->type)
245 case WTAP_OPTTYPE_UINT8:
246 dest_value->option.uint8val = src_value->option.uint8val;
248 case WTAP_OPTTYPE_UINT64:
249 dest_value->option.uint64val = src_value->option.uint64val;
251 case WTAP_OPTTYPE_STRING:
252 g_free(dest_value->option.stringval);
253 dest_value->option.stringval = g_strdup(src_value->option.stringval);
255 case WTAP_OPTTYPE_CUSTOM:
256 dest_value->option.customval.free_func(dest_value->option.customval.data);
257 g_free(dest_value->option.customval.data);
258 dest_value->option.customval.data = g_memdup(src_value->option.customval.data, src_value->option.customval.size);
265 void wtap_optionblock_foreach_option(wtap_optionblock_t block, wtap_optionblock_foreach_func func, void* user_data)
268 wtap_optblock_internal_t *internal_data;
269 wtap_optblock_value_t *value;
271 for (i = 0; i < block->option_values->len; i++)
273 internal_data = g_array_index(block->option_infos, wtap_optblock_internal_t*, i);
274 value = g_array_index(block->option_values, wtap_optblock_value_t*, i);
275 func(block, internal_data->number, value->info->type, &value->option, user_data);
279 wtap_opttype_return_val wtap_optionblock_add_option(wtap_optionblock_t block, guint option_id, wtap_optblock_reg_t* option)
281 wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
282 wtap_optblock_internal_t *opt_internal;
284 /* Option already exists */
285 if (opt_value != NULL)
286 return WTAP_OPTTYPE_ALREADY_EXISTS;
288 opt_value = g_new0(wtap_optblock_value_t, 1);
289 opt_internal = g_new(wtap_optblock_internal_t, 1);
291 opt_internal->name = option->name;
292 opt_internal->description = option->description;
293 opt_internal->number = option_id;
294 opt_internal->type = option->type;
296 opt_value->info = opt_internal;
300 case WTAP_OPTTYPE_UINT8:
301 opt_value->option.uint8val = option->option.uint8val;
302 opt_value->default_val.uint8val = option->default_val.uint8val;
304 case WTAP_OPTTYPE_UINT64:
305 opt_value->option.uint64val = option->option.uint64val;
306 opt_value->default_val.uint64val = option->default_val.uint64val;
308 case WTAP_OPTTYPE_STRING:
309 opt_value->option.stringval = g_strdup(option->option.stringval);
310 opt_value->default_val.stringval = option->default_val.stringval;
312 case WTAP_OPTTYPE_CUSTOM:
313 opt_value->option.customval.size = option->option.customval.size;
314 opt_value->option.customval.data = g_memdup(option->option.customval.data, option->option.customval.size);
315 opt_value->option.customval.free_func = option->option.customval.free_func;
316 opt_value->default_val.customval.size = option->default_val.customval.size;
317 opt_value->default_val.customval.data = g_memdup(option->default_val.customval.data, option->default_val.customval.size);
318 opt_value->default_val.customval.free_func = option->default_val.customval.free_func;
322 g_array_append_val(block->option_infos, opt_internal);
323 g_array_append_val(block->option_values, opt_value);
324 return WTAP_OPTTYPE_SUCCESS;
327 wtap_opttype_return_val wtap_optionblock_set_option_string(wtap_optionblock_t block, guint option_id, char* value, gsize value_length)
329 wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
331 /* Didn't find the option */
332 if (opt_value == NULL)
333 return WTAP_OPTTYPE_NOT_FOUND;
335 if (opt_value->info->type != WTAP_OPTTYPE_STRING)
336 return WTAP_OPTTYPE_TYPE_MISMATCH;
338 g_free(opt_value->option.stringval);
339 opt_value->option.stringval = g_strndup(value, value_length);
340 return WTAP_OPTTYPE_SUCCESS;
343 wtap_opttype_return_val wtap_optionblock_set_option_string_format(wtap_optionblock_t block, guint option_id, const char *format, ...)
346 wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
348 /* Didn't find the option */
349 if (opt_value == NULL)
350 return WTAP_OPTTYPE_NOT_FOUND;
352 if (opt_value->info->type != WTAP_OPTTYPE_STRING)
353 return WTAP_OPTTYPE_TYPE_MISMATCH;
355 g_free(opt_value->option.stringval);
356 va_start(va, format);
357 opt_value->option.stringval = g_strdup_vprintf(format, va);
359 return WTAP_OPTTYPE_SUCCESS;
362 wtap_opttype_return_val wtap_optionblock_get_option_string(wtap_optionblock_t block, guint option_id, char** value)
364 wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
366 /* Didn't find the option */
367 if (opt_value == NULL)
368 return WTAP_OPTTYPE_NOT_FOUND;
370 if (opt_value->info->type != WTAP_OPTTYPE_STRING)
371 return WTAP_OPTTYPE_TYPE_MISMATCH;
373 *value = opt_value->option.stringval;
374 return WTAP_OPTTYPE_SUCCESS;
377 wtap_opttype_return_val wtap_optionblock_get_string_options(wtap_optionblock_t block, guint option_id, GArray **value)
381 wtap_optblock_value_t* opt_value;
385 for (i = 0; i < block->option_values->len; i++)
387 opt_value = g_array_index(block->option_values, wtap_optblock_value_t*, i);
388 if (opt_value->info->number == option_id) {
389 if (opt_value->info->type != WTAP_OPTTYPE_STRING)
390 return WTAP_OPTTYPE_TYPE_MISMATCH;
395 opt_values = g_array_sized_new(FALSE, FALSE, sizeof (char *), n_options);
396 for (i = 0; i < block->option_values->len; i++)
398 opt_value = g_array_index(block->option_values, wtap_optblock_value_t*, i);
399 if (opt_value->info->number == option_id)
400 g_array_append_val(opt_values, opt_value->option.stringval);
404 return WTAP_OPTTYPE_SUCCESS;
407 wtap_opttype_return_val wtap_optionblock_set_option_uint64(wtap_optionblock_t block, guint option_id, guint64 value)
409 wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
411 /* Didn't find the option */
412 if (opt_value == NULL)
413 return WTAP_OPTTYPE_NOT_FOUND;
415 if (opt_value->info->type != WTAP_OPTTYPE_UINT64)
416 return WTAP_OPTTYPE_TYPE_MISMATCH;
418 opt_value->option.uint64val = value;
419 return WTAP_OPTTYPE_SUCCESS;
422 wtap_opttype_return_val wtap_optionblock_get_option_uint64(wtap_optionblock_t block, guint option_id, guint64* value)
424 wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
426 /* Didn't find the option */
427 if (opt_value == NULL)
428 return WTAP_OPTTYPE_NOT_FOUND;
430 if (opt_value->info->type != WTAP_OPTTYPE_UINT64)
431 return WTAP_OPTTYPE_TYPE_MISMATCH;
433 *value = opt_value->option.uint64val;
434 return WTAP_OPTTYPE_SUCCESS;
438 wtap_opttype_return_val wtap_optionblock_set_option_uint8(wtap_optionblock_t block, guint option_id, guint8 value)
440 wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
442 /* Didn't find the option */
443 if (opt_value == NULL)
444 return WTAP_OPTTYPE_NOT_FOUND;
446 if (opt_value->info->type != WTAP_OPTTYPE_UINT8)
447 return WTAP_OPTTYPE_TYPE_MISMATCH;
449 opt_value->option.uint8val = value;
450 return WTAP_OPTTYPE_SUCCESS;
453 wtap_opttype_return_val wtap_optionblock_get_option_uint8(wtap_optionblock_t block, guint option_id, guint8* value)
455 wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
457 /* Didn't find the option */
458 if (opt_value == NULL)
459 return WTAP_OPTTYPE_NOT_FOUND;
461 if (opt_value->info->type != WTAP_OPTTYPE_UINT8)
462 return WTAP_OPTTYPE_TYPE_MISMATCH;
464 *value = opt_value->option.uint8val;
465 return WTAP_OPTTYPE_SUCCESS;
468 wtap_opttype_return_val wtap_optionblock_set_option_custom(wtap_optionblock_t block, guint option_id, void* value)
470 wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
473 /* Didn't find the option */
474 if (opt_value == NULL)
475 return WTAP_OPTTYPE_NOT_FOUND;
477 if (opt_value->info->type != WTAP_OPTTYPE_CUSTOM)
478 return WTAP_OPTTYPE_TYPE_MISMATCH;
480 prev_value = opt_value->option.customval.data;
481 opt_value->option.customval.data = g_memdup(value, opt_value->option.customval.size);
482 /* Free after memory is duplicated in case structure was manipulated with a "get then set" */
484 return WTAP_OPTTYPE_SUCCESS;
487 wtap_opttype_return_val wtap_optionblock_get_option_custom(wtap_optionblock_t block, guint option_id, void** value)
489 wtap_optblock_value_t* opt_value = wtap_optionblock_get_option(block, option_id);
491 /* Didn't find the option */
492 if (opt_value == NULL)
493 return WTAP_OPTTYPE_NOT_FOUND;
495 if (opt_value->info->type != WTAP_OPTTYPE_CUSTOM)
496 return WTAP_OPTTYPE_TYPE_MISMATCH;
498 *value = opt_value->option.customval.data;
499 return WTAP_OPTTYPE_SUCCESS;
502 static void shb_create(wtap_optionblock_t block)
504 static wtap_optblock_reg_t comment_option = {"opt_comment", "Optional comment", WTAP_OPTTYPE_STRING, {0}, {0}};
505 static wtap_optblock_reg_t hardware_option = {"hardware", "SBH Hardware", WTAP_OPTTYPE_STRING, {0}, {0}};
506 static wtap_optblock_reg_t os_option = {"os", "SBH Operating System", WTAP_OPTTYPE_STRING, {0}, {0}};
507 static wtap_optblock_reg_t user_appl_option = {"user_appl", "SBH User Application", WTAP_OPTTYPE_STRING, {0}, {0}};
509 wtapng_mandatory_section_t* section_mand = g_new(wtapng_mandatory_section_t, 1);
511 /* Set proper values for the union */
512 comment_option.option.stringval = NULL;
513 comment_option.default_val.stringval = NULL;
514 hardware_option.option.stringval = NULL;
515 hardware_option.default_val.stringval = NULL;
516 os_option.option.stringval = NULL;
517 os_option.default_val.stringval = NULL;
518 user_appl_option.option.stringval = NULL;
519 user_appl_option.default_val.stringval = NULL;
521 section_mand->section_length = -1;
523 block->mandatory_data = section_mand;
525 wtap_optionblock_add_option(block, OPT_COMMENT, &comment_option);
526 wtap_optionblock_add_option(block, OPT_SHB_HARDWARE, &hardware_option);
527 wtap_optionblock_add_option(block, OPT_SHB_OS, &os_option);
528 wtap_optionblock_add_option(block, OPT_SHB_USERAPPL, &user_appl_option);
531 static void shb_copy_mand(wtap_optionblock_t dest_block, wtap_optionblock_t src_block)
533 memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_mandatory_section_t));
536 static void nrb_create(wtap_optionblock_t block)
538 static wtap_optblock_reg_t comment_option = {"opt_comment", "Optional comment", WTAP_OPTTYPE_STRING, {0}, {0}};
540 /* Set proper values for the union */
541 comment_option.option.stringval = NULL;
542 comment_option.default_val.stringval = NULL;
544 block->mandatory_data = NULL;
546 wtap_optionblock_add_option(block, OPT_COMMENT, &comment_option);
549 static void isb_create(wtap_optionblock_t block)
551 static wtap_optblock_reg_t comment_option = {"opt_comment", "Optional comment", WTAP_OPTTYPE_STRING, {0}, {0}};
552 static wtap_optblock_reg_t starttime_option = {"start_time", "Start Time", WTAP_OPTTYPE_UINT64, {0}, {0}};
553 static wtap_optblock_reg_t endtime_option = {"end_time", "End Time", WTAP_OPTTYPE_UINT64, {0}, {0}};
554 static wtap_optblock_reg_t rcv_pkt_option = {"recv", "Receive Packets", WTAP_OPTTYPE_UINT64, {0}, {0}};
555 static wtap_optblock_reg_t drop_pkt_option = {"drop", "Dropped Packets", WTAP_OPTTYPE_UINT64, {0}, {0}};
556 static wtap_optblock_reg_t filteraccept_option = {"filter_accept", "Filter Accept", WTAP_OPTTYPE_UINT64, {0}, {0}};
557 static wtap_optblock_reg_t os_drop_option = {"os_drop", "OS Dropped Packets", WTAP_OPTTYPE_UINT64, {0}, {0}};
558 static wtap_optblock_reg_t user_deliv_option = {"user_deliv", "User Delivery", WTAP_OPTTYPE_UINT64, {0}, {0}};
560 block->mandatory_data = g_new0(wtapng_if_stats_mandatory_t, 1);
562 /* Set proper values for the union */
563 comment_option.option.stringval = NULL;
564 comment_option.default_val.stringval = NULL;
565 starttime_option.option.uint64val = 0;
566 starttime_option.default_val.uint64val = 0;
567 endtime_option.option.uint64val = 0;
568 endtime_option.default_val.uint64val = 0;
569 rcv_pkt_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
570 rcv_pkt_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
571 drop_pkt_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
572 drop_pkt_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
573 filteraccept_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
574 filteraccept_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
575 os_drop_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
576 os_drop_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
577 user_deliv_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
578 user_deliv_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
580 wtap_optionblock_add_option(block, OPT_COMMENT, &comment_option);
581 wtap_optionblock_add_option(block, OPT_ISB_STARTTIME, &starttime_option);
582 wtap_optionblock_add_option(block, OPT_ISB_ENDTIME, &endtime_option);
583 wtap_optionblock_add_option(block, OPT_ISB_IFRECV, &rcv_pkt_option);
584 wtap_optionblock_add_option(block, OPT_ISB_IFDROP, &drop_pkt_option);
585 wtap_optionblock_add_option(block, OPT_ISB_FILTERACCEPT, &filteraccept_option);
586 wtap_optionblock_add_option(block, OPT_ISB_OSDROP, &os_drop_option);
587 wtap_optionblock_add_option(block, OPT_ISB_USRDELIV, &user_deliv_option);
590 static void isb_copy_mand(wtap_optionblock_t dest_block, wtap_optionblock_t src_block)
592 memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_if_stats_mandatory_t));
595 static void idb_filter_free(void* data)
597 wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)data;
598 g_free(filter->if_filter_str);
599 g_free(filter->if_filter_bpf_bytes);
602 static void idb_create(wtap_optionblock_t block)
604 static wtap_optblock_reg_t comment_option = {"opt_comment", "Optional comment", WTAP_OPTTYPE_STRING, {0}, {0}};
605 static wtap_optblock_reg_t name_option = {"name", "Device name", WTAP_OPTTYPE_STRING, {0}, {0}};
606 static wtap_optblock_reg_t description_option = {"description", "Device description", WTAP_OPTTYPE_STRING, {0}, {0}};
607 static wtap_optblock_reg_t speed_option = {"speed", "Interface speed (in bps)", WTAP_OPTTYPE_UINT64, {0}, {0}};
608 static wtap_optblock_reg_t tsresol_option = {"ts_resolution", "Resolution of timestamps", WTAP_OPTTYPE_UINT8, {0}, {0}};
609 static wtap_optblock_reg_t filter_option = {"filter", "Filter string", WTAP_OPTTYPE_CUSTOM, {0}, {0}};
610 static wtap_optblock_reg_t os_option = {"os", "Operating System", WTAP_OPTTYPE_STRING, {0}, {0}};
611 static wtap_optblock_reg_t fcslen_option = {"fcslen", "FCS Length", WTAP_OPTTYPE_UINT8, {0}, {0}};
613 static wtapng_if_descr_filter_t default_filter;
615 block->mandatory_data = g_new0(wtapng_if_descr_mandatory_t, 1);
617 /* Set proper values for the union */
618 comment_option.option.stringval = NULL;
619 comment_option.default_val.stringval = NULL;
620 name_option.option.stringval = NULL;
621 name_option.default_val.stringval = NULL;
622 description_option.option.stringval = NULL;
623 description_option.default_val.stringval = NULL;
624 speed_option.option.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
625 speed_option.default_val.uint64val = G_GUINT64_CONSTANT(0xFFFFFFFFFFFFFFFF);
626 tsresol_option.option.uint8val = 6;
627 tsresol_option.default_val.uint8val = 6;
628 filter_option.option.customval.size = sizeof(wtapng_if_descr_filter_t);
629 filter_option.option.customval.data = &default_filter;
630 filter_option.option.customval.free_func = idb_filter_free;
631 filter_option.default_val.customval.size = sizeof(wtapng_if_descr_filter_t);
632 filter_option.default_val.customval.data = &default_filter;
633 filter_option.default_val.customval.free_func = idb_filter_free;
634 os_option.option.stringval = NULL;
635 os_option.default_val.stringval = NULL;
636 fcslen_option.option.uint8val = -1;
637 fcslen_option.default_val.uint8val = -1;
639 wtap_optionblock_add_option(block, OPT_COMMENT, &comment_option);
640 wtap_optionblock_add_option(block, OPT_IDB_NAME, &name_option);
641 wtap_optionblock_add_option(block, OPT_IDB_DESCR, &description_option);
642 wtap_optionblock_add_option(block, OPT_IDB_SPEED, &speed_option);
643 wtap_optionblock_add_option(block, OPT_IDB_TSRESOL, &tsresol_option);
644 wtap_optionblock_add_option(block, OPT_IDB_FILTER, &filter_option);
645 wtap_optionblock_add_option(block, OPT_IDB_OS, &os_option);
646 wtap_optionblock_add_option(block, OPT_IDB_FCSLEN, &fcslen_option);
649 static void idb_free_mand(wtap_optionblock_t block)
652 wtap_optionblock_t if_stats;
653 wtapng_if_descr_mandatory_t* mand = (wtapng_if_descr_mandatory_t*)block->mandatory_data;
655 for(j = 0; j < mand->num_stat_entries; j++) {
656 if_stats = g_array_index(mand->interface_statistics, wtap_optionblock_t, j);
657 wtap_optionblock_free(if_stats);
660 if (mand->interface_statistics)
661 g_array_free(mand->interface_statistics, TRUE);
664 static void idb_copy_mand(wtap_optionblock_t dest_block, wtap_optionblock_t src_block)
667 wtap_optionblock_t src_if_stats, dest_if_stats;
668 wtapng_if_descr_mandatory_t *src_mand = (wtapng_if_descr_mandatory_t*)src_block->mandatory_data,
669 *dest_mand = (wtapng_if_descr_mandatory_t*)dest_block->mandatory_data;
671 /* Need special consideration for copying of the interface_statistics member */
672 if (dest_mand->num_stat_entries != 0)
673 g_array_free(dest_mand->interface_statistics, TRUE);
675 memcpy(dest_mand, src_mand, sizeof(wtapng_if_descr_mandatory_t));
676 if (src_mand->num_stat_entries != 0)
678 dest_mand->interface_statistics = g_array_new(FALSE, FALSE, sizeof(wtap_optionblock_t));
679 for (j = 0; j < src_mand->num_stat_entries; j++)
681 src_if_stats = g_array_index(src_mand->interface_statistics, wtap_optionblock_t, j);
682 dest_if_stats = wtap_optionblock_create(WTAP_OPTION_BLOCK_IF_STATS);
683 wtap_optionblock_copy_options(dest_if_stats, src_if_stats);
684 dest_mand->interface_statistics = g_array_append_val(dest_mand->interface_statistics, dest_if_stats);
689 void wtap_opttypes_initialize(void)
691 static wtap_opt_register_t shb_block = {
693 "Section Header Block", /* description */
694 shb_create, /* create */
695 NULL, /* free_mand */
696 shb_copy_mand, /* copy_mand */
699 static wtap_opt_register_t nrb_block = {
701 "Name Resolution Block", /* description */
702 nrb_create, /* create */
703 NULL, /* free_mand */
704 NULL, /* copy_mand */
707 static wtap_opt_register_t isb_block = {
709 "Interface Statistics Block", /* description */
710 isb_create, /* create */
711 NULL, /* free_mand */
712 isb_copy_mand, /* copy_mand */
715 static wtap_opt_register_t idb_block = {
717 "Interface Description Block", /* description */
718 idb_create, /* create */
719 idb_free_mand, /* free_mand */
720 idb_copy_mand, /* copy_mand */
723 /* Initialize the custom block array. This is for future proofing
724 "outside registered" block types (for NULL checking) */
725 memset(block_list, 0, MAX_WTAP_OPTION_BLOCK_TYPE_VALUE*sizeof(wtap_opt_register_t*));
726 num_custom_blocks = 0;
728 wtap_opttype_block_register(WTAP_OPTION_BLOCK_NG_SECTION, &shb_block );
729 wtap_opttype_block_register(WTAP_OPTION_BLOCK_NG_NRB, &nrb_block );
730 wtap_opttype_block_register(WTAP_OPTION_BLOCK_IF_STATS, &isb_block );
731 wtap_opttype_block_register(WTAP_OPTION_BLOCK_IF_DESCR, &idb_block );