PDML: protocol filter incorrectly filters desired subfields

Bug: 12847
Change-Id: I8a560dc44dceb06123d8bcecd512d132ee4ebb0d
Reviewed-on: https://code.wireshark.org/review/19671
Petri-Dish: Alexis La Goutte <alexis.lagoutte@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
This commit is contained in:
Martin Kacer 2017-01-19 15:37:54 +01:00 committed by Alexis La Goutte
parent a8ceeca444
commit c9d8c1c8c5
5 changed files with 69 additions and 15 deletions

View File

@ -60,6 +60,7 @@ typedef struct {
FILE *fh;
GSList *src_list;
gchar **filter;
pf_flags filter_flags;
} write_pdml_data;
typedef struct {
@ -67,6 +68,7 @@ typedef struct {
FILE *fh;
GSList *src_list;
gchar **filter;
pf_flags filter_flags;
gboolean print_hex;
} write_json_data;
@ -302,7 +304,7 @@ static gboolean check_protocolfilter(gchar **protocolfilter, const char *str)
}
void
write_pdml_proto_tree(output_fields_t* fields, gchar **protocolfilter, epan_dissect_t *edt, FILE *fh)
write_pdml_proto_tree(output_fields_t* fields, gchar **protocolfilter, pf_flags protocolfilter_flags, epan_dissect_t *edt, FILE *fh)
{
write_pdml_data data;
@ -321,6 +323,7 @@ write_pdml_proto_tree(output_fields_t* fields, gchar **protocolfilter, epan_diss
data.fh = fh;
data.src_list = edt->pi.data_src;
data.filter = protocolfilter;
data.filter_flags = protocolfilter_flags;
proto_tree_children_foreach(edt->tree, proto_tree_write_node_pdml,
&data);
@ -333,7 +336,7 @@ write_pdml_proto_tree(output_fields_t* fields, gchar **protocolfilter, epan_diss
}
void
write_json_proto_tree(output_fields_t* fields, print_args_t *print_args, gchar **protocolfilter, epan_dissect_t *edt, FILE *fh)
write_json_proto_tree(output_fields_t* fields, print_args_t *print_args, gchar **protocolfilter, pf_flags protocolfilter_flags, epan_dissect_t *edt, FILE *fh)
{
write_json_data data;
char ts[30];
@ -368,6 +371,7 @@ write_json_proto_tree(output_fields_t* fields, print_args_t *print_args, gchar *
data.fh = fh;
data.src_list = edt->pi.data_src;
data.filter = protocolfilter;
data.filter_flags = protocolfilter_flags;
data.print_hex = print_args->print_hex;
proto_tree_children_foreach(edt->tree, proto_tree_write_node_json,
@ -384,7 +388,7 @@ write_json_proto_tree(output_fields_t* fields, print_args_t *print_args, gchar *
}
void
write_ek_proto_tree(output_fields_t* fields, print_args_t *print_args, gchar **protocolfilter, epan_dissect_t *edt, FILE *fh)
write_ek_proto_tree(output_fields_t* fields, print_args_t *print_args, gchar **protocolfilter, pf_flags protocolfilter_flags, epan_dissect_t *edt, FILE *fh)
{
write_json_data data;
char ts[30];
@ -411,6 +415,7 @@ write_ek_proto_tree(output_fields_t* fields, print_args_t *print_args, gchar **p
data.fh = fh;
data.src_list = edt->pi.data_src;
data.filter = protocolfilter;
data.filter_flags = protocolfilter_flags;
data.print_hex = print_args->print_hex;
proto_tree_children_foreach(edt->tree, proto_tree_write_node_ek,
@ -644,10 +649,22 @@ proto_tree_write_node_pdml(proto_node *node, gpointer data)
/* We print some levels for PDML. Recurse here. */
if (node->first_child != NULL) {
if (pdata->filter == NULL || check_protocolfilter(pdata->filter, fi->hfinfo->abbrev)) {
gchar **_filter = NULL;
/* Remove protocol filter for children, if children should be included */
if ((pdata->filter_flags&PF_INCLUDE_CHILDREN) == PF_INCLUDE_CHILDREN) {
_filter = pdata->filter;
pdata->filter = NULL;
}
pdata->level++;
proto_tree_children_foreach(node,
proto_tree_write_node_pdml, pdata);
pdata->level--;
/* Put protocol filter back */
if ((pdata->filter_flags&PF_INCLUDE_CHILDREN) == PF_INCLUDE_CHILDREN) {
pdata->filter = _filter;
}
} else {
/* Indent to the correct level */
for (i = -2; i < pdata->level; i++) {
@ -861,9 +878,21 @@ proto_tree_write_node_json(proto_node *node, gpointer data)
/* We print some levels for JSON. Recurse here. */
if (node->first_child != NULL) {
if (pdata->filter == NULL || check_protocolfilter(pdata->filter, fi->hfinfo->abbrev)) {
gchar **_filter = NULL;
/* Remove protocol filter for children, if children should be included */
if ((pdata->filter_flags&PF_INCLUDE_CHILDREN) == PF_INCLUDE_CHILDREN) {
_filter = pdata->filter;
pdata->filter = NULL;
}
pdata->level++;
proto_tree_children_foreach(node, proto_tree_write_node_json, pdata);
pdata->level--;
/* Put protocol filter back */
if ((pdata->filter_flags&PF_INCLUDE_CHILDREN) == PF_INCLUDE_CHILDREN) {
pdata->filter = _filter;
}
} else {
/* Indent to the correct level */
for (i = -4; i < pdata->level; i++) {
@ -1078,9 +1107,21 @@ proto_tree_write_node_ek(proto_node *node, gpointer data)
}
if(check_protocolfilter(pdata->filter, fi->hfinfo->abbrev) || check_protocolfilter(pdata->filter, abbrev_escaped)) {
gchar **_filter = NULL;
/* Remove protocol filter for children, if children should be included */
if ((pdata->filter_flags&PF_INCLUDE_CHILDREN) == PF_INCLUDE_CHILDREN) {
_filter = pdata->filter;
pdata->filter = NULL;
}
pdata->level++;
proto_tree_children_foreach(node, proto_tree_write_node_ek, pdata);
pdata->level--;
/* Put protocol filter back */
if ((pdata->filter_flags&PF_INCLUDE_CHILDREN) == PF_INCLUDE_CHILDREN) {
pdata->filter = _filter;
}
} else {
/* print dummy field */
fputs("\"filtered\": \"", pdata->fh);

View File

@ -86,6 +86,11 @@ typedef enum {
FORMAT_XML, /* PDML output */
} fields_format;
typedef enum {
PF_NONE = 0x00,
PF_INCLUDE_CHILDREN = 0x01
} pf_flags;
/*
* Print user selected list of fields
*/
@ -112,14 +117,14 @@ WS_DLL_PUBLIC gboolean proto_tree_print(print_args_t *print_args,
WS_DLL_PUBLIC gboolean print_hex_data(print_stream_t *stream, epan_dissect_t *edt);
WS_DLL_PUBLIC void write_pdml_preamble(FILE *fh, const gchar* filename);
WS_DLL_PUBLIC void write_pdml_proto_tree(output_fields_t* fields, gchar **protocolfilter, epan_dissect_t *edt, FILE *fh);
WS_DLL_PUBLIC void write_pdml_proto_tree(output_fields_t* fields, gchar **protocolfilter, pf_flags protocolfilter_flags, epan_dissect_t *edt, FILE *fh);
WS_DLL_PUBLIC void write_pdml_finale(FILE *fh);
WS_DLL_PUBLIC void write_json_preamble(FILE *fh);
WS_DLL_PUBLIC void write_json_proto_tree(output_fields_t* fields, print_args_t *print_args, gchar **protocolfilter, epan_dissect_t *edt, FILE *fh);
WS_DLL_PUBLIC void write_json_proto_tree(output_fields_t* fields, print_args_t *print_args, gchar **protocolfilter, pf_flags protocolfilter_flags, epan_dissect_t *edt, FILE *fh);
WS_DLL_PUBLIC void write_json_finale(FILE *fh);
WS_DLL_PUBLIC void write_ek_proto_tree(output_fields_t* fields, print_args_t *print_args, gchar **protocolfilter, epan_dissect_t *edt, FILE *fh);
WS_DLL_PUBLIC void write_ek_proto_tree(output_fields_t* fields, print_args_t *print_args, gchar **protocolfilter, pf_flags protocolfilter_flags, epan_dissect_t *edt, FILE *fh);
WS_DLL_PUBLIC void write_psml_preamble(column_info *cinfo, FILE *fh);
WS_DLL_PUBLIC void write_psml_columns(epan_dissect_t *edt, FILE *fh);

4
file.c
View File

@ -2518,7 +2518,7 @@ write_pdml_packet(capture_file *cf, frame_data *fdata,
epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
/* Write out the information in that tree. */
write_pdml_proto_tree(NULL, NULL, &args->edt, args->fh);
write_pdml_proto_tree(NULL, NULL, PF_NONE, &args->edt, args->fh);
epan_dissect_reset(&args->edt);
@ -2812,7 +2812,7 @@ write_json_packet(capture_file *cf, frame_data *fdata,
epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
/* Write out the information in that tree. */
write_json_proto_tree(NULL, args->print_args, NULL, &args->edt, args->fh);
write_json_proto_tree(NULL, args->print_args, NULL, PF_NONE, &args->edt, args->fh);
epan_dissect_reset(&args->edt);

View File

@ -2045,7 +2045,7 @@ print_packet(capture_file *cf, epan_dissect_t *edt)
break;
case WRITE_XML:
write_pdml_proto_tree(NULL, NULL, edt, stdout);
write_pdml_proto_tree(NULL, NULL, PF_NONE, edt, stdout);
printf("\n");
return !ferror(stdout);
case WRITE_FIELDS:

View File

@ -188,6 +188,7 @@ static print_stream_t *print_stream;
static output_fields_t* output_fields = NULL;
static gchar **protocolfilter = NULL;
static pf_flags protocolfilter_flags = PF_NONE;
/* The line separator used between packets, changeable via the -S option */
static const char *separator = "";
@ -387,8 +388,11 @@ print_usage(FILE *output)
fprintf(output, " -x add output of hex and ASCII dump (Packet Bytes)\n");
fprintf(output, " -T pdml|ps|psml|json|ek|text|fields\n");
fprintf(output, " format of text output (def: text)\n");
fprintf(output, " -j <protocolfilter> protocols layers filter if -T ek|pdml|json selected,\n");
fprintf(output, " (e.g. \"http tcp ip\",\n");
fprintf(output, " -j <protocolfilter> protocols layers filter if -T ek|pdml|json selected\n");
fprintf(output, " (e.g. \"ip ip.flags text\", filter does not expand child\n");
fprintf(output, " nodes, unless child is specified also in the filter)\n");
fprintf(output, " -J <protocolfilter> top level protocol filter if -T ek|pdml|json selected\n");
fprintf(output, " (e.g. \"http tcp\", filter which expands all child nodes)\n");
fprintf(output, " -e <field> field to print if -Tfields selected (e.g. tcp.port,\n");
fprintf(output, " _ws.col.Info)\n");
fprintf(output, " this option can be repeated to print multiple fields\n");
@ -717,7 +721,7 @@ main(int argc, char *argv[])
* We do *not* use a leading - because the behavior of a leading - is
* platform-dependent.
*/
#define OPTSTRING "+2" OPTSTRING_CAPTURE_COMMON OPTSTRING_DISSECT_COMMON "C:e:E:F:gG:hH:j:lo:O:PqQr:R:S:T:U:vVw:W:xX:Y:z:"
#define OPTSTRING "+2" OPTSTRING_CAPTURE_COMMON OPTSTRING_DISSECT_COMMON "C:e:E:F:gG:hH:j:J:lo:O:PqQr:R:S:T:U:vVw:W:xX:Y:z:"
static const char optstring[] = OPTSTRING;
@ -1192,6 +1196,10 @@ main(int argc, char *argv[])
case 'j':
protocolfilter = wmem_strsplit(wmem_epan_scope(), optarg, " ", -1);
break;
case 'J':
protocolfilter_flags = PF_INCLUDE_CHILDREN;
protocolfilter = wmem_strsplit(wmem_epan_scope(), optarg, " ", -1);
break;
case 'W': /* Select extra information to save in our capture file */
/* This is patterned after the -N flag which may not be the best idea. */
if (strchr(optarg, 'n')) {
@ -3997,7 +4005,7 @@ print_packet(capture_file *cf, epan_dissect_t *edt)
break;
case WRITE_XML:
write_pdml_proto_tree(output_fields, protocolfilter, edt, stdout);
write_pdml_proto_tree(output_fields, protocolfilter, protocolfilter_flags, edt, stdout);
printf("\n");
return !ferror(stdout);
case WRITE_FIELDS:
@ -4006,12 +4014,12 @@ print_packet(capture_file *cf, epan_dissect_t *edt)
return !ferror(stdout);
case WRITE_JSON:
print_args.print_hex = print_hex;
write_json_proto_tree(output_fields, &print_args, protocolfilter, edt, stdout);
write_json_proto_tree(output_fields, &print_args, protocolfilter, protocolfilter_flags, edt, stdout);
printf("\n");
return !ferror(stdout);
case WRITE_EK:
print_args.print_hex = print_hex;
write_ek_proto_tree(output_fields, &print_args, protocolfilter, edt, stdout);
write_ek_proto_tree(output_fields, &print_args, protocolfilter, protocolfilter_flags, edt, stdout);
printf("\n");
return !ferror(stdout);
}