aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--debian/libwiretap0.symbols6
-rw-r--r--ui/summary.c11
-rw-r--r--wiretap/erf.c36
-rw-r--r--wiretap/pcapng.c186
-rw-r--r--wiretap/wtap.c34
-rw-r--r--wiretap/wtap.h9
-rw-r--r--wiretap/wtap_opttypes.c220
-rw-r--r--wiretap/wtap_opttypes.h52
8 files changed, 336 insertions, 218 deletions
diff --git a/debian/libwiretap0.symbols b/debian/libwiretap0.symbols
index 72909048b6..4063fae2c9 100644
--- a/debian/libwiretap0.symbols
+++ b/debian/libwiretap0.symbols
@@ -21,7 +21,7 @@ libwiretap.so.0 libwiretap0 #MINVER#
register_pcapng_option_handler@Base 1.99.2
wtap_add_generated_idb@Base 3.3.0
wtap_addrinfo_list_empty@Base 2.5.0
- wtap_block_add_structured_option@Base 3.5.0
+ wtap_block_add_if_filter_option@Base 3.5.0
wtap_block_add_ipv4_option@Base 2.1.2
wtap_block_add_ipv6_option@Base 2.1.2
wtap_block_add_string_option@Base 2.1.2
@@ -33,7 +33,7 @@ libwiretap.so.0 libwiretap0 #MINVER#
wtap_block_create@Base 2.1.2
wtap_block_foreach_option@Base 2.1.2
wtap_block_free@Base 2.1.2
- wtap_block_get_structured_option_value@Base 3.5.0
+ wtap_block_get_if_filter_option_value@Base 3.5.0
wtap_block_get_ipv4_option_value@Base 2.1.2
wtap_block_get_ipv6_option_value@Base 2.1.2
wtap_block_get_mandatory_data@Base 2.1.2
@@ -44,7 +44,7 @@ libwiretap.so.0 libwiretap0 #MINVER#
wtap_block_make_copy@Base 3.3.2
wtap_block_remove_nth_option_instance@Base 2.2.0
wtap_block_remove_option@Base 2.2.0
- wtap_block_set_structured_option_value@Base 3.5.0
+ wtap_block_set_if_filter_option_value@Base 3.5.0
wtap_block_set_ipv4_option_value@Base 2.1.2
wtap_block_set_ipv6_option_value@Base 2.1.2
wtap_block_set_nth_string_option_value@Base 2.1.2
diff --git a/ui/summary.c b/ui/summary.c
index 565bb86307..268f993694 100644
--- a/ui/summary.c
+++ b/ui/summary.c
@@ -117,7 +117,7 @@ summary_fill_in(capture_file *cf, summary_tally *st)
wtap_block_t if_stats;
guint64 isb_ifdrop;
char* if_string;
- wtapng_if_descr_filter_t* if_filter;
+ if_filter_opt_t if_filter;
FILE *fh;
char *hash_buf;
@@ -171,8 +171,13 @@ summary_fill_in(capture_file *cf, summary_tally *st)
for (i = 0; i < idb_info->interface_data->len; i++) {
wtapng_if_descr = g_array_index(idb_info->interface_data, wtap_block_t, i);
wtapng_if_descr_mand = (wtapng_if_descr_mandatory_t*)wtap_block_get_mandatory_data(wtapng_if_descr);
- if (wtap_block_get_structured_option_value(wtapng_if_descr, OPT_IDB_FILTER, (void**)&if_filter) == WTAP_OPTTYPE_SUCCESS) {
- iface.cfilter = g_strdup(if_filter->if_filter_str);
+ if (wtap_block_get_if_filter_option_value(wtapng_if_descr, OPT_IDB_FILTER, &if_filter) == WTAP_OPTTYPE_SUCCESS) {
+ if (if_filter.type == if_filter_pcap) {
+ iface.cfilter = g_strdup(if_filter.data.filter_str);
+ } else {
+ /* Not a pcap filter string; punt for now */
+ iface.cfilter = NULL;
+ }
} else {
iface.cfilter = NULL;
}
diff --git a/wiretap/erf.c b/wiretap/erf.c
index 8804f450f8..512a114455 100644
--- a/wiretap/erf.c
+++ b/wiretap/erf.c
@@ -1107,12 +1107,12 @@ static void erf_write_wtap_option_to_interface_tag(wtap_block_t block _U_,
break;
case OPT_IDB_FILTER:
{
- wtapng_if_descr_filter_t *filter;
+ if_filter_opt_t *filter;
+ filter = &optval->if_filterval;
tag_ptr->type = 0xF800;
- filter = (wtapng_if_descr_filter_t*)&optval->structuredval;
- if(filter->if_filter_str) {
+ if(filter->type == if_filter_pcap) {
tag_ptr->type = ERF_META_TAG_filter;
- tag_ptr->value = (guint8*)g_strdup(filter->if_filter_str);
+ tag_ptr->value = (guint8*)g_strdup(filter->data.filter_str);
tag_ptr->length = (guint16)strlen((char*)tag_ptr->value);
}
}
@@ -2710,7 +2710,7 @@ static int populate_interface_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo
int interface_index = -1;
wtap_block_t int_data = NULL;
wtapng_if_descr_mandatory_t* int_data_mand = NULL;
- wtapng_if_descr_filter_t if_filter = {0};
+ if_filter_opt_t if_filter;
guint32 if_num = 0;
struct erf_if_info* if_info = NULL;
@@ -2840,9 +2840,10 @@ static int populate_interface_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo
wtap_block_add_string_option(int_data, OPT_COMMENT, tag.value, tag.length);
break;
case ERF_META_TAG_filter:
- if_filter.if_filter_str = g_strndup((gchar*) tag.value, tag.length);
- wtap_block_add_structured_option(int_data, OPT_IDB_FILTER, &if_filter, sizeof if_filter);
- g_free(if_filter.if_filter_str);
+ if_filter.type = if_filter_pcap;
+ if_filter.data.filter_str = g_strndup((gchar*) tag.value, tag.length);
+ wtap_block_add_if_filter_option(int_data, OPT_IDB_FILTER, &if_filter);
+ g_free(if_filter.data.filter_str);
if_info->set_flags.filter = 1;
break;
default:
@@ -2866,16 +2867,18 @@ static int populate_interface_info(erf_t *erf_priv, wtap *wth, union wtap_pseudo
if (!if_info->set_flags.filter) {
if (state->if_map->module_filter_str) {
/* Duplicate because might use with multiple interfaces */
- if_filter.if_filter_str = state->if_map->module_filter_str;
- wtap_block_add_structured_option(int_data, OPT_IDB_FILTER, &if_filter, sizeof if_filter);
+ if_filter.type = if_filter_pcap;
+ if_filter.data.filter_str = state->if_map->module_filter_str;
+ wtap_block_add_if_filter_option(int_data, OPT_IDB_FILTER, &if_filter);
/*
* Don't set flag because stream is more specific than module.
*/
} else if (state->if_map->capture_filter_str) {
/* TODO: display separately? Note that we could have multiple captures
* from multiple hosts in the file */
- if_filter.if_filter_str = state->if_map->capture_filter_str;
- wtap_block_add_structured_option(int_data, OPT_IDB_FILTER, &if_filter, sizeof if_filter);
+ if_filter.type = if_filter_pcap;
+ if_filter.data.filter_str = state->if_map->capture_filter_str;
+ wtap_block_add_if_filter_option(int_data, OPT_IDB_FILTER, &if_filter);
}
}
@@ -2901,7 +2904,7 @@ static int populate_stream_info(erf_t *erf_priv _U_, wtap *wth, union wtap_pseud
int interface_index = -1;
wtap_block_t int_data = NULL;
wtapng_if_descr_mandatory_t* int_data_mand = NULL;
- wtapng_if_descr_filter_t if_filter = {0};
+ if_filter_opt_t if_filter;
guint32 if_num = 0;
gint32 stream_num = -1;
guint8 *tag_ptr_tmp;
@@ -3011,9 +3014,10 @@ static int populate_stream_info(erf_t *erf_priv _U_, wtap *wth, union wtap_pseud
case ERF_META_TAG_filter:
/* Override only if not set */
if (!if_info->set_flags.filter) {
- if_filter.if_filter_str = g_strndup((gchar*) tag.value, tag.length);
- wtap_block_add_structured_option(int_data, OPT_IDB_FILTER, &if_filter, sizeof if_filter);
- g_free(if_filter.if_filter_str);
+ if_filter.type = if_filter_pcap;
+ if_filter.data.filter_str = g_strndup((gchar*) tag.value, tag.length);
+ wtap_block_add_if_filter_option(int_data, OPT_IDB_FILTER, &if_filter);
+ g_free(if_filter.data.filter_str);
if_info->set_flags.filter = 1;
}
break;
diff --git a/wiretap/pcapng.c b/wiretap/pcapng.c
index 019bf17084..4c78e073aa 100644
--- a/wiretap/pcapng.c
+++ b/wiretap/pcapng.c
@@ -937,21 +937,55 @@ pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh,
*/
case(OPT_IDB_FILTER): /* if_filter */
if (oh.option_length > 0 && oh.option_length < opt_cont_buf_len) {
- wtapng_if_descr_filter_t if_filter = {0};
+ if_filter_opt_t if_filter;
/* The first byte of the Option Data keeps a code of the filter used (e.g. if this is a libpcap string,
* or BPF bytecode.
*/
if (option_content[0] == 0) {
- if_filter.if_filter_str = g_strndup((char *)option_content+1, oh.option_length-1);
- pcapng_debug("pcapng_read_if_descr_block: if_filter_str %s oh.option_length %u", if_filter.if_filter_str, oh.option_length);
+ if_filter.type = if_filter_pcap;
+ if_filter.data.filter_str = g_strndup((char *)option_content+1, oh.option_length-1);
+ pcapng_debug("pcapng_read_if_descr_block: filter_str %s oh.option_length %u", if_filter.filter_str, oh.option_length);
} else if (option_content[0] == 1) {
- if_filter.bpf_filter_len = oh.option_length-1;
- if_filter.if_filter_bpf_bytes = option_content+1;
+ /*
+ * XXX - byte-swap the code and k fields
+ * of each instruction as needed!
+ *
+ * XXX - what if oh.option_length-1 is not a
+ * multiple of the size of a BPF instruction?
+ */
+ guint num_insns;
+ const guint8 *insn_in;
+
+ if_filter.type = if_filter_bpf;
+ num_insns = (oh.option_length-1)/8;
+ insn_in = option_content+1;
+ if_filter.data.bpf_prog.bpf_prog_len = num_insns;
+ if_filter.data.bpf_prog.bpf_prog = g_new(wtap_bpf_insn_t, num_insns);
+ for (guint i = 0; i < num_insns; i++) {
+ wtap_bpf_insn_t *insn = &if_filter.data.bpf_prog.bpf_prog[i];
+
+ memcpy(&insn->code, insn_in, 2);
+ if (section_info->byte_swapped)
+ insn->code = GUINT16_SWAP_LE_BE(insn->code);
+ insn_in += 2;
+ memcpy(&insn->jt, insn_in, 1);
+ insn_in += 1;
+ memcpy(&insn->jf, insn_in, 1);
+ insn_in += 1;
+ memcpy(&insn->k, insn_in, 4);
+ if (section_info->byte_swapped)
+ insn->code = GUINT32_SWAP_LE_BE(insn->code);
+ insn_in += 4;
+ }
}
/* Fails with multiple options; we silently ignore the failure */
- wtap_block_add_structured_option(wblock->block, oh.option_code, &if_filter, sizeof if_filter);
- g_free(if_filter.if_filter_str);
+ wtap_block_add_if_filter_option(wblock->block, oh.option_code, &if_filter);
+ if (if_filter.type == if_filter_pcap) {
+ g_free(if_filter.data.filter_str);
+ } else if (if_filter.type == if_filter_bpf) {
+ g_free(if_filter.data.bpf_prog.bpf_prog);
+ }
} else {
pcapng_debug("pcapng_read_if_descr_block: if_filter length %u seems strange", oh.option_length);
}
@@ -3294,12 +3328,21 @@ pcapng_write_block_t;
static gboolean pcapng_write_option_string(wtap_dumper *wdh, guint option_id, char *str, int *err)
{
struct pcapng_option_header option_hdr;
- guint32 size = (guint32)strlen(str) & 0xffff;
+ size_t size = strlen(str);
const guint32 zero_pad = 0;
guint32 pad;
if (size == 0)
return TRUE;
+ if (size > 65535) {
+ /*
+ * Too big to fit in the option.
+ * Don't write anything.
+ *
+ * XXX - truncate it? Report an error?
+ */
+ return TRUE;
+ }
/* String options don't consider pad bytes part of the length */
option_hdr.type = (guint16)option_id;
@@ -4541,18 +4584,22 @@ static void compute_idb_option_size(wtap_block_t block _U_, guint option_id, wta
break;
case OPT_IDB_FILTER:
{
- wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)optval->structuredval.data;
+ if_filter_opt_t* filter = &optval->if_filterval;
guint32 pad;
- if (filter->if_filter_str != NULL) {
- size = (guint32)(strlen(filter->if_filter_str) + 1) & 0xffff;
- if ((size % 4)) {
- pad = 4 - (size % 4);
- } else {
- pad = 0;
- }
-
- size += pad;
+ if (filter->type == if_filter_pcap) {
+ size = (guint32)(strlen(filter->data.filter_str) + 1) & 0xffff;
+ } else if (filter->type == if_filter_bpf) {
+ size = (guint32)((filter->data.bpf_prog.bpf_prog_len * 8) + 1) & 0xffff;
+ } else {
+ /* Unknown type; don't write it */
+ size = 0;
}
+ if ((size % 4)) {
+ pad = 4 - (size % 4);
+ } else {
+ pad = 0;
+ }
+ size += pad;
}
break;
case OPT_IDB_FCSLEN:
@@ -4631,47 +4678,98 @@ static void write_wtap_idb_option(wtap_block_t block _U_, guint option_id, wtap_
break;
case OPT_IDB_FILTER:
{
- wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)optval->structuredval.data;
+ if_filter_opt_t* filter = &optval->if_filterval;
guint32 size, pad;
- if (filter->if_filter_str != NULL) {
- size = (guint32)(strlen(filter->if_filter_str) + 1) & 0xffff;
- if ((size % 4)) {
- pad = 4 - (size % 4);
- } else {
- pad = 0;
+ guint8 filter_type;
+ size_t filter_data_len;
+ switch (filter->type) {
+
+ case if_filter_pcap:
+ filter_type = 0; /* pcap filter string */
+ filter_data_len = strlen(filter->data.filter_str);
+ if (filter_data_len > 65534) {
+ /*
+ * Too big to fit in the option.
+ * Don't write anything.
+ *
+ * XXX - truncate it? Report an error?
+ */
+ return;
}
+ break;
- option_hdr.type = option_id;
- option_hdr.value_length = size;
- if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
- write_block->success = FALSE;
+ case if_filter_bpf:
+ filter_type = 1; /* BPF filter program */
+ filter_data_len = filter->data.bpf_prog.bpf_prog_len*8;
+ if (filter_data_len > 65528) {
+ /*
+ * Too big to fit in the option. (The filter length
+ * must be a multiple of 8, as that's the length
+ * of a BPF instruction.) Don't write anything.
+ *
+ * XXX - truncate it? Report an error?
+ */
return;
}
- write_block->wdh->bytes_dumped += 4;
+ break;
+
+ default:
+ /* Unknown filter type; don't write anything. */
+ return;
+ }
+ size = (guint32)(filter_data_len + 1);
+ if ((size % 4)) {
+ pad = 4 - (size % 4);
+ } else {
+ pad = 0;
+ }
+
+ option_hdr.type = option_id;
+ option_hdr.value_length = size;
+ if (!wtap_dump_file_write(write_block->wdh, &option_hdr, 4, write_block->err)) {
+ write_block->success = FALSE;
+ return;
+ }
+ write_block->wdh->bytes_dumped += 4;
+
+ /* Write the filter type */
+ if (!wtap_dump_file_write(write_block->wdh, &filter_type, 1, write_block->err)) {
+ write_block->success = FALSE;
+ return;
+ }
+ write_block->wdh->bytes_dumped += 1;
- /* Write the zero indicating libpcap filter variant */
- if (!wtap_dump_file_write(write_block->wdh, &zero_pad, 1, write_block->err)) {
+ switch (filter->type) {
+
+ case if_filter_pcap:
+ /* Write the filter string */
+ if (!wtap_dump_file_write(write_block->wdh, filter->data.filter_str, filter_data_len, write_block->err)) {
write_block->success = FALSE;
return;
}
- write_block->wdh->bytes_dumped += 1;
+ write_block->wdh->bytes_dumped += filter_data_len;
+ break;
- /* if_filter_str_len includes the leading byte indicating filter type (libpcap str or BPF code) */
- if (!wtap_dump_file_write(write_block->wdh, filter->if_filter_str, size-1, write_block->err)) {
+ case if_filter_bpf:
+ if (!wtap_dump_file_write(write_block->wdh, filter->data.bpf_prog.bpf_prog, filter_data_len, write_block->err)) {
write_block->success = FALSE;
return;
}
- write_block->wdh->bytes_dumped += size - 1;
+ write_block->wdh->bytes_dumped += filter_data_len;
+ break;
- /* write padding (if any) */
- if (pad != 0) {
- if (!wtap_dump_file_write(write_block->wdh, &zero_pad, pad, write_block->err)) {
- write_block->success = FALSE;
- return;
- }
- write_block->wdh->bytes_dumped += pad;
- }
+ default:
+ g_assert_not_reached();
+ return;
+ }
+ /* write padding (if any) */
+ if (pad != 0) {
+ if (!wtap_dump_file_write(write_block->wdh, &zero_pad, pad, write_block->err)) {
+ write_block->success = FALSE;
+ return;
+ }
+ write_block->wdh->bytes_dumped += pad;
}
}
break;
diff --git a/wiretap/wtap.c b/wiretap/wtap.c
index ff4479f68a..26615e3d3a 100644
--- a/wiretap/wtap.c
+++ b/wiretap/wtap.c
@@ -295,7 +295,7 @@ wtap_get_debug_if_descr(const wtap_block_t if_descr,
guint64 tmp64;
gint8 itmp8;
guint8 tmp8;
- wtapng_if_descr_filter_t* if_filter;
+ if_filter_opt_t if_filter;
g_assert(if_descr);
@@ -365,16 +365,30 @@ wtap_get_debug_if_descr(const wtap_block_t if_descr,
line_end);
}
- if (wtap_block_get_structured_option_value(if_descr, OPT_IDB_FILTER, (void**)&if_filter) == WTAP_OPTTYPE_SUCCESS) {
- g_string_append_printf(info,
- "%*cFilter string = %s%s", indent, ' ',
- if_filter->if_filter_str ? if_filter->if_filter_str : "NONE",
- line_end);
+ if (wtap_block_get_if_filter_option_value(if_descr, OPT_IDB_FILTER, &if_filter) == WTAP_OPTTYPE_SUCCESS) {
+ switch (if_filter.type) {
- g_string_append_printf(info,
- "%*cBPF filter length = %u%s", indent, ' ',
- if_filter->bpf_filter_len,
- line_end);
+ case if_filter_pcap:
+ g_string_append_printf(info,
+ "%*cFilter string = %s%s", indent, ' ',
+ if_filter.data.filter_str,
+ line_end);
+ break;
+
+ case if_filter_bpf:
+ g_string_append_printf(info,
+ "%*cBPF filter length = %u%s", indent, ' ',
+ if_filter.data.bpf_prog.bpf_prog_len,
+ line_end);
+ break;
+
+ default:
+ g_string_append_printf(info,
+ "%*cUnknown filter type %u%s", indent, ' ',
+ if_filter.type,
+ line_end);
+ break;
+ }
}
if (wtap_block_get_string_option_value(if_descr, OPT_IDB_OS, &tmp_content) == WTAP_OPTTYPE_SUCCESS) {
diff --git a/wiretap/wtap.h b/wiretap/wtap.h
index 9005cf3290..9e4b835bd5 100644
--- a/wiretap/wtap.h
+++ b/wiretap/wtap.h
@@ -1515,15 +1515,6 @@ typedef struct wtapng_dsb_mandatory_s {
guint8 *secrets_data; /** Buffer of secrets (not NUL-terminated) */
} wtapng_dsb_mandatory_t;
-/* Interface description data - Option 11 structure */
-typedef struct wtapng_if_descr_filter_s {
- gchar *if_filter_str; /**< NULL if not available
- * libpcap string.
- */
- guint16 bpf_filter_len; /** variant II BPF filter len 0 if not used*/
- guint8 *if_filter_bpf_bytes; /** BPF filter or NULL */
-} wtapng_if_descr_filter_t;
-
/**
* Holds the required data for pcapng Interface Statistics Block (ISB).
*/
diff --git a/wiretap/wtap_opttypes.c b/wiretap/wtap_opttypes.c
index 29c5f82b46..42439e8fc6 100644
--- a/wiretap/wtap_opttypes.c
+++ b/wiretap/wtap_opttypes.c
@@ -36,9 +36,6 @@ typedef struct {
GArray *options; /**< array of known options */
} wtap_blocktype_t;
-typedef void *(*wtap_opttype_dup_structured_func)(void* src);
-typedef void (*wtap_opttype_free_structured_func)(void* data);
-
/*
* Structure describing a type of option.
*/
@@ -47,8 +44,6 @@ typedef struct {
const char *description; /**< human-readable description of option */
wtap_opttype_e data_type; /**< data type of that option */
guint flags; /**< flags for the option */
- wtap_opttype_dup_structured_func dup_func; /**< function to duplicate structured option data */
- wtap_opttype_free_structured_func free_func; /**< function to free structured option data */
} wtap_opttype_t;
/* Flags */
@@ -75,9 +70,7 @@ static void wtap_opttype_block_register(wtap_block_type_t block_type, wtap_block
"opt_comment",
"Comment",
WTAP_OPTTYPE_STRING,
- WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED,
- NULL,
- NULL
+ WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED
};
/* Check input */
@@ -204,9 +197,21 @@ static void wtap_block_free_option(wtap_block_t block, wtap_option_t *opt)
g_free(opt->value.stringval);
break;
- case WTAP_OPTTYPE_STRUCTURED:
- opttype->free_func(opt->value.structuredval.data);
- g_free(opt->value.structuredval.data);
+ case WTAP_OPTTYPE_IF_FILTER:
+ switch (opt->value.if_filterval.type) {
+
+ case if_filter_pcap:
+ /* pcap filter string */
+ g_free(opt->value.if_filterval.data.filter_str);
+ break;
+
+ case if_filter_bpf:
+ g_free(opt->value.if_filterval.data.bpf_prog.bpf_prog);
+ break;
+
+ default:
+ break;
+ }
break;
default:
@@ -298,8 +303,8 @@ wtap_block_copy(wtap_block_t dest_block, wtap_block_t src_block)
wtap_block_add_string_option(dest_block, src_opt->option_id, src_opt->value.stringval, strlen(src_opt->value.stringval));
break;
- case WTAP_OPTTYPE_STRUCTURED:
- wtap_block_add_structured_option(dest_block, src_opt->option_id, src_opt->value.structuredval.data, src_opt->value.structuredval.size);
+ case WTAP_OPTTYPE_IF_FILTER:
+ wtap_block_add_if_filter_option(dest_block, src_opt->option_id, &src_opt->value.if_filterval);
break;
}
}
@@ -769,54 +774,95 @@ wtap_block_get_nth_string_option_value(wtap_block_t block, guint option_id, guin
return WTAP_OPTTYPE_SUCCESS;
}
+static if_filter_opt_t if_filter_dup(if_filter_opt_t* filter_src)
+{
+ if_filter_opt_t filter_dest;
+
+ /* Deep copy. */
+ filter_dest.type = filter_src->type;
+ switch (filter_src->type) {
+
+ case if_filter_pcap:
+ /* pcap filter string */
+ filter_dest.data.filter_str =
+ g_strdup(filter_src->data.filter_str);
+ break;
+
+ case if_filter_bpf:
+ /* BPF program */
+ filter_dest.data.bpf_prog.bpf_prog_len =
+ filter_src->data.bpf_prog.bpf_prog_len;
+ filter_dest.data.bpf_prog.bpf_prog =
+ (wtap_bpf_insn_t *)g_memdup(filter_src->data.bpf_prog.bpf_prog,
+ filter_src->data.bpf_prog.bpf_prog_len * sizeof (wtap_bpf_insn_t));
+ break;
+
+ default:
+ break;
+ }
+ return filter_dest;
+}
+
+static void if_filter_free(if_filter_opt_t* filter_src)
+{
+ switch (filter_src->type) {
+
+ case if_filter_pcap:
+ /* pcap filter string */
+ g_free(filter_src->data.filter_str);
+ break;
+
+ case if_filter_bpf:
+ /* BPF program */
+ g_free(filter_src->data.bpf_prog.bpf_prog);
+ break;
+
+ default:
+ break;
+ }
+}
+
wtap_opttype_return_val
-wtap_block_add_structured_option(wtap_block_t block, guint option_id, void *value, size_t value_size)
+wtap_block_add_if_filter_option(wtap_block_t block, guint option_id, if_filter_opt_t* value)
{
wtap_opttype_return_val ret;
wtap_option_t *opt;
- wtap_opttype_t *opttype;
- ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_STRUCTURED, &opt);
+ ret = wtap_block_add_option_common(block, option_id, WTAP_OPTTYPE_IF_FILTER, &opt);
if (ret != WTAP_OPTTYPE_SUCCESS)
return ret;
- opttype = &g_array_index(block->info->options, wtap_opttype_t, opt->option_id);
- opt->value.structuredval.size = (guint)value_size;
- opt->value.structuredval.data = opttype->dup_func(value);
+ opt->value.if_filterval = if_filter_dup(value);
return WTAP_OPTTYPE_SUCCESS;
}
wtap_opttype_return_val
-wtap_block_get_structured_option_value(wtap_block_t block, guint option_id, void** value)
+wtap_block_set_if_filter_option_value(wtap_block_t block, guint option_id, if_filter_opt_t* value)
{
wtap_opttype_return_val ret;
wtap_optval_t *optval;
+ if_filter_opt_t prev_value;
- ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_STRUCTURED, &optval);
+ ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IF_FILTER, &optval);
if (ret != WTAP_OPTTYPE_SUCCESS)
return ret;
- *value = optval->structuredval.data;
+ prev_value = optval->if_filterval;
+ optval->if_filterval = if_filter_dup(value);
+ /* Free after memory is duplicated in case structure was manipulated with a "get then set" */
+ if_filter_free(&prev_value);
+
return WTAP_OPTTYPE_SUCCESS;
}
wtap_opttype_return_val
-wtap_block_set_structured_option_value(wtap_block_t block, guint option_id, void *value)
+wtap_block_get_if_filter_option_value(wtap_block_t block, guint option_id, if_filter_opt_t* value)
{
wtap_opttype_return_val ret;
wtap_optval_t *optval;
- void *prev_value;
- ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_STRUCTURED, &optval);
+ ret = wtap_block_get_option_common(block, option_id, WTAP_OPTTYPE_IF_FILTER, &optval);
if (ret != WTAP_OPTTYPE_SUCCESS)
return ret;
- prev_value = optval->structuredval.data;
- /*
- * XXX - a custom value can be a structure that points to other data,
- * but we're doing a shallow copy here.
- */
- optval->structuredval.data = g_memdup(value, optval->structuredval.size);
- /* Free after memory is duplicated in case structure was manipulated with a "get then set" */
- g_free(prev_value);
-
+ *value = optval->if_filterval;
return WTAP_OPTTYPE_SUCCESS;
}
@@ -933,26 +979,6 @@ static void isb_copy_mand(wtap_block_t dest_block, wtap_block_t src_block)
memcpy(dest_block->mandatory_data, src_block->mandatory_data, sizeof(wtapng_if_stats_mandatory_t));
}
-static void *idb_filter_dup(void* src)
-{
- wtapng_if_descr_filter_t* filter_src = (wtapng_if_descr_filter_t*)src;
- wtapng_if_descr_filter_t* filter_dest;
-
- /* Deep copy. */
- filter_dest = g_new(wtapng_if_descr_filter_t, 1);
- filter_dest->if_filter_str = g_strdup(filter_src->if_filter_str);
- filter_dest->bpf_filter_len = filter_src->bpf_filter_len;
- filter_dest->if_filter_bpf_bytes = (guint8 *)g_memdup(filter_src->if_filter_bpf_bytes, filter_src->bpf_filter_len);
- return (void *)filter_dest;
-}
-
-static void idb_filter_free(void* data)
-{
- wtapng_if_descr_filter_t* filter = (wtapng_if_descr_filter_t*)data;
- g_free(filter->if_filter_str);
- g_free(filter->if_filter_bpf_bytes);
-}
-
static void idb_create(wtap_block_t block)
{
block->mandatory_data = g_new0(wtapng_if_descr_mandatory_t, 1);
@@ -1033,25 +1059,19 @@ void wtap_opttypes_initialize(void)
"hardware",
"SHB Hardware",
WTAP_OPTTYPE_STRING,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_opttype_t shb_os = {
"os",
"SHB Operating System",
WTAP_OPTTYPE_STRING,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_opttype_t shb_userappl = {
"user_appl",
"SHB User Application",
WTAP_OPTTYPE_STRING,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_blocktype_t idb_block = {
@@ -1067,65 +1087,49 @@ void wtap_opttypes_initialize(void)
"name",
"IDB Name",
WTAP_OPTTYPE_STRING,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_opttype_t if_description = {
"description",
"IDB Description",
WTAP_OPTTYPE_STRING,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_opttype_t if_speed = {
"speed",
"IDB Speed",
WTAP_OPTTYPE_UINT64,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_opttype_t if_tsresol = {
"tsresol",
"IDB Time Stamp Resolution",
WTAP_OPTTYPE_UINT8, /* XXX - signed? */
- 0,
- NULL,
- NULL
+ 0
};
static wtap_opttype_t if_filter = {
"filter",
"IDB Filter",
- WTAP_OPTTYPE_STRUCTURED,
- 0,
- idb_filter_dup,
- idb_filter_free
+ WTAP_OPTTYPE_IF_FILTER,
+ 0
};
static wtap_opttype_t if_os = {
"os",
"IDB Operating System",
WTAP_OPTTYPE_STRING,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_opttype_t if_fcslen = {
"fcslen",
"IDB FCS Length",
WTAP_OPTTYPE_UINT8,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_opttype_t if_hardware = {
"hardware",
"IDB Hardware",
WTAP_OPTTYPE_STRING,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_blocktype_t dsb_block = {
@@ -1151,25 +1155,19 @@ void wtap_opttypes_initialize(void)
"dnsname",
"NRB DNS server name",
WTAP_OPTTYPE_STRING,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_opttype_t ns_dnsIP4addr = {
"dnsIP4addr",
"NRB DNS server IPv4 address",
WTAP_OPTTYPE_IPv4,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_opttype_t ns_dnsIP6addr = {
"dnsIP6addr",
"NRB DNS server IPv6 address",
WTAP_OPTTYPE_IPv6,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_blocktype_t isb_block = {
@@ -1185,57 +1183,43 @@ void wtap_opttypes_initialize(void)
"starttime",
"ISB Start Time",
WTAP_OPTTYPE_UINT64,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_opttype_t isb_endtime = {
"endtime",
"ISB End Time",
WTAP_OPTTYPE_UINT64,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_opttype_t isb_ifrecv = {
"ifrecv",
"ISB Received Packets",
WTAP_OPTTYPE_UINT64,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_opttype_t isb_ifdrop = {
"ifdrop",
"ISB Dropped Packets",
WTAP_OPTTYPE_UINT64,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_opttype_t isb_filteraccept = {
"filteraccept",
"ISB Packets Accepted By Filter",
WTAP_OPTTYPE_UINT64,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_opttype_t isb_osdrop = {
"osdrop",
"ISB Packets Dropped By The OS",
WTAP_OPTTYPE_UINT64,
- 0,
- NULL,
- NULL
+ 0
};
static wtap_opttype_t isb_usrdeliv = {
"usrdeliv",
"ISB Packets Delivered To The User",
WTAP_OPTTYPE_UINT64,
- 0,
- NULL,
- NULL
+ 0
};
/* Initialize the custom block array. This is for future proofing
diff --git a/wiretap/wtap_opttypes.h b/wiretap/wtap_opttypes.h
index f9477b56cd..d2e4a39f10 100644
--- a/wiretap/wtap_opttypes.h
+++ b/wiretap/wtap_opttypes.h
@@ -144,7 +144,7 @@ typedef enum {
WTAP_OPTTYPE_STRING,
WTAP_OPTTYPE_IPv4,
WTAP_OPTTYPE_IPv6,
- WTAP_OPTTYPE_STRUCTURED /* option-dependent non-simple format */
+ WTAP_OPTTYPE_IF_FILTER
} wtap_opttype_e;
typedef enum {
@@ -156,11 +156,34 @@ typedef enum {
WTAP_OPTTYPE_ALREADY_EXISTS = -5
} wtap_opttype_return_val;
-struct wtap_opttype_structured
-{
- void* data;
- guint size;
-};
+/* Interface description data - if_filter option structure */
+
+/* BPF instruction */
+typedef struct wtap_bpf_insn_s {
+ guint16 code;
+ guint8 jt;
+ guint8 jf;
+ guint32 k;
+} wtap_bpf_insn_t;
+
+/*
+ * Type of filter.
+ */
+typedef enum {
+ if_filter_pcap = 0, /* pcap filter string */
+ if_filter_bpf = 1 /* BPF program */
+} if_filter_type_e;
+
+typedef struct if_filter_opt_s {
+ if_filter_type_e type;
+ union {
+ gchar *filter_str; /**< pcap filter string */
+ struct wtap_bpf_insns {
+ guint bpf_prog_len; /**< number of BPF instructions */
+ wtap_bpf_insn_t *bpf_prog; /**< BPF instructions */
+ } bpf_prog; /**< BPF program */
+ } data;
+} if_filter_opt_t;
/*
* Structure describing a value of an option.
@@ -171,7 +194,7 @@ typedef union {
guint32 ipv4val; /* network byte order */
ws_in6_addr ipv6val;
char *stringval;
- struct wtap_opttype_structured structuredval;
+ if_filter_opt_t if_filterval;
} wtap_optval_t;
/*
@@ -460,19 +483,18 @@ wtap_block_get_string_option_value(wtap_block_t block, guint option_id, char** v
WS_DLL_PUBLIC wtap_opttype_return_val
wtap_block_get_nth_string_option_value(wtap_block_t block, guint option_id, guint idx, char** value) G_GNUC_WARN_UNUSED_RESULT;
-/** Add a structured option value to a block
+/** Add an if_filter option value to a block
*
* @param[in] block Block to which to add the option
* @param[in] option_id Identifier value for option
* @param[in] value Value of option
- * @param[in] value_size Size of value
* @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful,
* error code otherwise
*/
WS_DLL_PUBLIC wtap_opttype_return_val
-wtap_block_add_structured_option(wtap_block_t block, guint option_id, void* value, size_t value_size);
+wtap_block_add_if_filter_option(wtap_block_t block, guint option_id, if_filter_opt_t* value);
-/** Set a structured option value in a block
+/** Set an if_filter option value in a block
*
* @param[in] block Block in which to set the option value
* @param[in] option_id Identifier value for option
@@ -481,18 +503,18 @@ wtap_block_add_structured_option(wtap_block_t block, guint option_id, void* valu
* error code otherwise
*/
WS_DLL_PUBLIC wtap_opttype_return_val
-wtap_block_set_structured_option_value(wtap_block_t block, guint option_id, void* value);
+wtap_block_set_if_filter_option_value(wtap_block_t block, guint option_id, if_filter_opt_t* value);
-/** Get a structured option value from a block
+/** Get an if_filter option value from a block
*
* @param[in] block Block from which to get the option value
* @param[in] option_id Identifier value for option
- * @param[out] value Returned value of option
+ * @param[out] value Returned value of option value
* @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful,
* error code otherwise
*/
WS_DLL_PUBLIC wtap_opttype_return_val
-wtap_block_get_structured_option_value(wtap_block_t block, guint option_id, void** value) G_GNUC_WARN_UNUSED_RESULT;
+wtap_block_get_if_filter_option_value(wtap_block_t block, guint option_id, if_filter_opt_t* value) G_GNUC_WARN_UNUSED_RESULT;
/** Remove an option from a block
*