summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Kacer <kacer.martin@gmail.com>2016-06-28 13:01:25 +0200
committerGuy Harris <guy@alum.mit.edu>2016-06-29 08:29:16 +0000
commitceae9e4d1fff4500b285dba021c3f239ff87779e (patch)
treea9f61fe0b0a498030098f6f5aa62e15b08222e76
parent348e364551782237800896920f32b10cc18e9f36 (diff)
downloadwireshark-ceae9e4d1fff4500b285dba021c3f239ff87779e.tar.gz
tshark fields filter added for other outputs
-e fields filter addded to ek|json|pdml output. Bug: 12529 Change-Id: I1f0f8772eefceb5b71927925ce0c34af483571b9 Reviewed-on: https://code.wireshark.org/review/16193 Petri-Dish: Guy Harris <guy@alum.mit.edu> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Guy Harris <guy@alum.mit.edu>
-rw-r--r--doc/tshark.pod4
-rw-r--r--epan/print.c231
-rw-r--r--epan/print.h13
-rw-r--r--file.c4
-rw-r--r--tfshark.c2
-rw-r--r--tshark.c10
6 files changed, 202 insertions, 62 deletions
diff --git a/doc/tshark.pod b/doc/tshark.pod
index 7e6d0247d5..5b115cd175 100644
--- a/doc/tshark.pod
+++ b/doc/tshark.pod
@@ -291,8 +291,8 @@ from such an account, it will not list any interfaces.
=item -e E<lt>fieldE<gt>
-Add a field to the list of fields to display if B<-T fields> is
-selected. This option can be used multiple times on the command line.
+Add a field to the list of fields to display if B<-T ek|fields|json|pdml>
+is selected. This option can be used multiple times on the command line.
At least one field must be provided if the B<-T fields> option is
selected. Column names may be used prefixed with "_ws.col."
diff --git a/epan/print.c b/epan/print.c
index cf7fa148ed..db3acb3641 100644
--- a/epan/print.c
+++ b/epan/print.c
@@ -78,16 +78,17 @@ typedef struct {
} write_field_data_t;
struct _output_fields {
- gboolean print_bom;
- gboolean print_header;
- gchar separator;
- gchar occurrence;
- gchar aggregator;
- GPtrArray *fields;
- GHashTable *field_indicies;
- GPtrArray **field_values;
- gchar quote;
- gboolean includes_col_fields;
+ gboolean print_bom;
+ gboolean print_header;
+ gchar separator;
+ gchar occurrence;
+ gchar aggregator;
+ GPtrArray *fields;
+ GHashTable *field_indicies;
+ GPtrArray **field_values;
+ gchar quote;
+ gboolean includes_col_fields;
+ fields_format format;
};
static gchar *get_field_hex_value(GSList *src_list, field_info *fi);
@@ -285,10 +286,13 @@ static gboolean check_protocolfilter(gchar **protocolfilter, const char *str)
}
void
-write_pdml_proto_tree(gchar **protocolfilter, epan_dissect_t *edt, FILE *fh)
+write_pdml_proto_tree(output_fields_t* fields, gchar **protocolfilter, epan_dissect_t *edt, FILE *fh)
{
write_pdml_data data;
+ g_assert(edt);
+ g_assert(fh);
+
/* Create the output */
data.level = 0;
data.fh = fh;
@@ -301,14 +305,19 @@ write_pdml_proto_tree(gchar **protocolfilter, epan_dissect_t *edt, FILE *fh)
/* Print a "geninfo" protocol as required by PDML */
print_pdml_geninfo(edt->tree, fh);
- proto_tree_children_foreach(edt->tree, proto_tree_write_node_pdml,
- &data);
+ if (fields == NULL || fields->fields == NULL) {
+ proto_tree_children_foreach(edt->tree, proto_tree_write_node_pdml,
+ &data);
+ } else {
+ fields->format = FORMAT_XML;
+ write_fields_proto_tree(fields, edt, NULL, fh);
+ }
fprintf(fh, "</packet>\n\n");
}
void
-write_json_proto_tree(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, epan_dissect_t *edt, FILE *fh)
{
write_json_data data;
char ts[30];
@@ -316,6 +325,9 @@ write_json_proto_tree(print_args_t *print_args, gchar **protocolfilter, epan_dis
struct tm * timeinfo;
static gboolean is_first = TRUE;
+ g_assert(edt);
+ g_assert(fh);
+
/* Create the output */
data.level = 1;
data.fh = fh;
@@ -339,8 +351,13 @@ write_json_proto_tree(print_args_t *print_args, gchar **protocolfilter, epan_dis
fputs(" \"_source\": {\n", fh);
fputs(" \"layers\": {\n", fh);
- proto_tree_children_foreach(edt->tree, proto_tree_write_node_json,
- &data);
+ if (fields == NULL || fields->fields == NULL) {
+ proto_tree_children_foreach(edt->tree, proto_tree_write_node_json,
+ &data);
+ } else {
+ fields->format = FORMAT_JSON;
+ write_fields_proto_tree(fields, edt, NULL, fh);
+ }
fputs(" }\n", fh);
fputs(" }\n", fh);
@@ -349,7 +366,7 @@ write_json_proto_tree(print_args_t *print_args, gchar **protocolfilter, epan_dis
}
void
-write_ek_proto_tree(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, epan_dissect_t *edt, FILE *fh)
{
write_json_data data;
char ts[30];
@@ -358,6 +375,9 @@ write_ek_proto_tree(print_args_t *print_args, gchar **protocolfilter, epan_disse
nstime_t *timestamp;
GPtrArray *finfo_array;
+ g_assert(edt);
+ g_assert(fh);
+
/* Create the output */
data.level = 0;
data.fh = fh;
@@ -366,7 +386,6 @@ write_ek_proto_tree(print_args_t *print_args, gchar **protocolfilter, epan_disse
data.filter = protocolfilter;
data.print_hex = print_args->print_hex;
-
timeinfo = localtime(&t);
strftime(ts, 30, "%Y-%m-%d", timeinfo);
@@ -390,8 +409,14 @@ write_ek_proto_tree(print_args_t *print_args, gchar **protocolfilter, epan_disse
fprintf(fh, "{\"timestamp\" : \"%" G_GUINT64_FORMAT "%03d\", \"layers\" : {", (guint64)timestamp->secs, timestamp->nsecs/1000000);
- proto_tree_children_foreach(edt->tree, proto_tree_write_node_ek,
- &data);
+ if (fields == NULL || fields->fields == NULL) {
+ proto_tree_children_foreach(edt->tree, proto_tree_write_node_ek,
+ &data);
+ } else {
+ fields->format = FORMAT_EK;
+ write_fields_proto_tree(fields, edt, NULL, fh);
+ }
+
fputs("}}\n", fh);
}
@@ -2048,44 +2073,152 @@ void write_fields_proto_tree(output_fields_t *fields, epan_dissect_t *edt, colum
proto_tree_children_foreach(edt->tree, proto_tree_get_node_field_values,
&data);
- if (fields->includes_col_fields) {
- for (col = 0; col < cinfo->num_cols; col++) {
- /* Prepend COLUMN_FIELD_FILTER as the field name */
- col_name = g_strdup_printf("%s%s", COLUMN_FIELD_FILTER, cinfo->columns[col].col_title);
- field_index = g_hash_table_lookup(fields->field_indicies, col_name);
- g_free(col_name);
-
- if (NULL != field_index) {
- format_field_values(fields, field_index, g_strdup(cinfo->columns[col].col_data));
+ switch (fields->format) {
+ case FORMAT_CSV:
+ if (fields->includes_col_fields) {
+ for (col = 0; col < cinfo->num_cols; col++) {
+ /* Prepend COLUMN_FIELD_FILTER as the field name */
+ col_name = g_strdup_printf("%s%s", COLUMN_FIELD_FILTER, cinfo->columns[col].col_title);
+ field_index = g_hash_table_lookup(fields->field_indicies, col_name);
+ g_free(col_name);
+
+ if (NULL != field_index) {
+ format_field_values(fields, field_index, g_strdup(cinfo->columns[col].col_data));
+ }
}
}
- }
- for(i = 0; i < fields->fields->len; ++i) {
- if (0 != i) {
- fputc(fields->separator, fh);
+ for(i = 0; i < fields->fields->len; ++i) {
+ if (0 != i) {
+ fputc(fields->separator, fh);
+ }
+ if (NULL != fields->field_values[i]) {
+ GPtrArray *fv_p;
+ gchar * str;
+ gsize j;
+ fv_p = fields->field_values[i];
+ if (fields->quote != '\0') {
+ fputc(fields->quote, fh);
+ }
+
+ /* Output the array of (partial) field values */
+ for (j = 0; j < g_ptr_array_len(fv_p); j++ ) {
+ str = (gchar *)g_ptr_array_index(fv_p, j);
+ fputs(str, fh);
+ g_free(str);
+ }
+ if (fields->quote != '\0') {
+ fputc(fields->quote, fh);
+ }
+ g_ptr_array_free(fv_p, TRUE); /* get ready for the next packet */
+ fields->field_values[i] = NULL;
+ }
}
- if (NULL != fields->field_values[i]) {
- GPtrArray *fv_p;
- gchar * str;
- gsize j;
- fv_p = fields->field_values[i];
- if (fields->quote != '\0') {
- fputc(fields->quote, fh);
+ break;
+ case FORMAT_XML:
+ for(i = 0; i < fields->fields->len; ++i) {
+ gchar *field = (gchar *)g_ptr_array_index(fields->fields, i);
+
+ if (NULL != fields->field_values[i]) {
+ GPtrArray *fv_p;
+ gchar * str;
+ gsize j;
+ fv_p = fields->field_values[i];
+
+ /* Output the array of (partial) field values */
+ for (j = 0; j < (g_ptr_array_len(fv_p)) - 1; j+=2 ) {
+ str = (gchar *)g_ptr_array_index(fv_p, j);
+
+ fprintf(fh, " <field name=\"%s\" value=", field);
+ fputs("\"", fh);
+ print_escaped_xml(fh, str);
+ fputs("\"/>\n", fh);
+ g_free(str);
+ }
+ g_ptr_array_free(fv_p, TRUE); /* get ready for the next packet */
+ fields->field_values[i] = NULL;
}
+ }
+ break;
+ case FORMAT_JSON:
+ for(i = 0; i < fields->fields->len; ++i) {
+ gchar *field = (gchar *)g_ptr_array_index(fields->fields, i);
+
+ if (NULL != fields->field_values[i]) {
+ GPtrArray *fv_p;
+ gchar * str;
+ gsize j;
+ fv_p = fields->field_values[i];
- /* Output the array of (partial) field values */
- for (j = 0; j < g_ptr_array_len(fv_p); j++ ) {
- str = (gchar *)g_ptr_array_index(fv_p, j);
- fputs(str, fh);
- g_free(str);
+ /* Output the array of (partial) field values */
+ for (j = 0; j < (g_ptr_array_len(fv_p)) - 1; j+=2 ) {
+ str = (gchar *)g_ptr_array_index(fv_p, j);
+
+ if (j == 0) {
+ fprintf(fh, " \"%s\": [", field);
+ }
+ fputs("\"", fh);
+ print_escaped_json(fh, str);
+ fputs("\"", fh);
+ g_free(str);
+
+ if (j + 2 < (g_ptr_array_len(fv_p)) - 1) {
+ fputs(",", fh);
+ } else {
+ fputs("]", fh);
+
+ if ( (i + 1 < fields->fields->len) && (g_ptr_array_len(fields->field_values[i + 1]) > 1) ) {
+ fputs(",\n", fh);
+ } else {
+ fputs("\n", fh);
+ }
+ }
+ }
+ g_ptr_array_free(fv_p, TRUE); /* get ready for the next packet */
+ fields->field_values[i] = NULL;
}
- if (fields->quote != '\0') {
- fputc(fields->quote, fh);
+ }
+ break;
+ case FORMAT_EK:
+ for(i = 0; i < fields->fields->len; ++i) {
+ gchar *field = (gchar *)g_ptr_array_index(fields->fields, i);
+
+ if (NULL != fields->field_values[i]) {
+ GPtrArray *fv_p;
+ gchar * str;
+ gsize j;
+ fv_p = fields->field_values[i];
+
+ /* Output the array of (partial) field values */
+ for (j = 0; j < (g_ptr_array_len(fv_p)) - 1; j+=2 ) {
+ str = (gchar *)g_ptr_array_index(fv_p, j);
+
+ if (j == 0) {
+ fputs("\"", fh);
+ print_escaped_ek(fh, field);
+ fputs("\": [", fh);
+ }
+ fputs("\"", fh);
+ print_escaped_json(fh, str);
+ fputs("\"", fh);
+ g_free(str);
+
+ if (j + 2 < (g_ptr_array_len(fv_p)) - 1) {
+ fputs(",", fh);
+ } else {
+ fputs("]", fh);
+
+ if ( (i + 1 < fields->fields->len) && (g_ptr_array_len(fields->field_values[i + 1]) > 1) ) {
+ fputs(",", fh);
+ } else {
+ }
+ }
+ }
+ g_ptr_array_free(fv_p, TRUE); /* get ready for the next packet */
+ fields->field_values[i] = NULL;
}
- g_ptr_array_free(fv_p, TRUE); /* get ready for the next packet */
- fields->field_values[i] = NULL;
}
+ break;
}
}
diff --git a/epan/print.h b/epan/print.h
index c9cdda3c86..dc2c7ad081 100644
--- a/epan/print.h
+++ b/epan/print.h
@@ -79,6 +79,13 @@ typedef struct {
* each new packet */
} print_args_t;
+typedef enum {
+ FORMAT_CSV, /* CSV */
+ FORMAT_JSON, /* JSON */
+ FORMAT_EK, /* JSON bulk insert to Elasticsearch */
+ FORMAT_XML, /* PDML output */
+} fields_format;
+
/*
* Print user selected list of fields
*/
@@ -105,14 +112,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(gchar **protocolfilter, epan_dissect_t *edt, FILE *fh);
+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_finale(FILE *fh);
WS_DLL_PUBLIC void write_json_preamble(FILE *fh);
-WS_DLL_PUBLIC void write_json_proto_tree(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, epan_dissect_t *edt, FILE *fh);
WS_DLL_PUBLIC void write_json_finale(FILE *fh);
-WS_DLL_PUBLIC void write_ek_proto_tree(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, 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);
diff --git a/file.c b/file.c
index 49ecf2fc21..ba84efbd13 100644
--- a/file.c
+++ b/file.c
@@ -2544,7 +2544,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, &args->edt, args->fh);
+ write_pdml_proto_tree(NULL, NULL, &args->edt, args->fh);
epan_dissect_reset(&args->edt);
@@ -2838,7 +2838,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(args->print_args, NULL, &args->edt, args->fh);
+ write_json_proto_tree(NULL, args->print_args, NULL, &args->edt, args->fh);
epan_dissect_reset(&args->edt);
diff --git a/tfshark.c b/tfshark.c
index b9d3ed5cf6..fe97057713 100644
--- a/tfshark.c
+++ b/tfshark.c
@@ -2072,7 +2072,7 @@ print_packet(capture_file *cf, epan_dissect_t *edt)
break;
case WRITE_XML:
- write_pdml_proto_tree(NULL, edt, stdout);
+ write_pdml_proto_tree(NULL, NULL, edt, stdout);
printf("\n");
return !ferror(stdout);
case WRITE_FIELDS:
diff --git a/tshark.c b/tshark.c
index 5636988496..58f1765028 100644
--- a/tshark.c
+++ b/tshark.c
@@ -1365,9 +1365,9 @@ main(int argc, char *argv[])
}
/* If we specified output fields, but not the output field type... */
- if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
+ if ((WRITE_FIELDS != output_action && WRITE_XML != output_action && WRITE_JSON != output_action && WRITE_EK != output_action) && 0 != output_fields_num_fields(output_fields)) {
cmdarg_err("Output fields were specified with \"-e\", "
- "but \"-Tfields\" was not specified.");
+ "but \"-Tek, -Tfields, -Tjson or -Tpdml\" was not specified.");
return 1;
} else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
cmdarg_err("\"-Tfields\" was specified, but no fields were "
@@ -3834,7 +3834,7 @@ print_packet(capture_file *cf, epan_dissect_t *edt)
break;
case WRITE_XML:
- write_pdml_proto_tree(protocolfilter, edt, stdout);
+ write_pdml_proto_tree(output_fields, protocolfilter, edt, stdout);
printf("\n");
return !ferror(stdout);
case WRITE_FIELDS:
@@ -3843,12 +3843,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(&print_args, protocolfilter, edt, stdout);
+ write_json_proto_tree(output_fields, &print_args, protocolfilter, edt, stdout);
printf("\n");
return !ferror(stdout);
case WRITE_EK:
print_args.print_hex = print_hex;
- write_ek_proto_tree(&print_args, protocolfilter, edt, stdout);
+ write_ek_proto_tree(output_fields, &print_args, protocolfilter, edt, stdout);
printf("\n");
return !ferror(stdout);
}