diff options
author | Martin Kacer <kacer.martin@gmail.com> | 2016-06-20 11:03:40 +0200 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2016-06-21 16:57:59 +0000 |
commit | c3f3bd7fa89af1ccd15440cf401697fc32814ed6 (patch) | |
tree | 2b8ada654c02b0a59ae9eb7fde8eba7f16564eab /epan/print.c | |
parent | df231d9c52d8e94d2ef48f83beeef1455a0e7ce9 (diff) |
tshark JSON and Elasticsearch output fix
Fixed json and ek escape function
Fixed -j protocol filter to do exact match
Fixed -T json to correctly close json
Added -j protocol filter also to pdml output
Bug: 11754
Change-Id: I02f274e4a5a02346922b37bbe946c10340c242ea
Reviewed-on: https://code.wireshark.org/review/16034
Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'epan/print.c')
-rw-r--r-- | epan/print.c | 160 |
1 files changed, 125 insertions, 35 deletions
diff --git a/epan/print.c b/epan/print.c index 92e9bfe73d..66bc08acf3 100644 --- a/epan/print.c +++ b/epan/print.c @@ -60,6 +60,7 @@ typedef struct { FILE *fh; GSList *src_list; epan_dissect_t *edt; + gchar **filter; } write_pdml_data; typedef struct { @@ -67,7 +68,7 @@ typedef struct { FILE *fh; GSList *src_list; epan_dissect_t *edt; - gchar *filter; + gchar **filter; gboolean print_hex; } write_json_data; @@ -259,11 +260,32 @@ write_pdml_preamble(FILE *fh, const gchar *filename) void write_json_preamble(FILE *fh) { - fputs("{\n", fh); + fputs("[\n", fh); +} + +/* Check if the str match the protocolfilter. json_filter is space + delimited string and str need to exact-match to one of the value. */ +gboolean check_protocolfilter(gchar **protocolfilter, const char *str) +{ + gboolean res = FALSE; + gchar **ptr; + + if (str == NULL || protocolfilter == NULL) { + return FALSE; + } + + for (ptr = protocolfilter; *ptr; ptr++) { + if (strcmp(*ptr, str) == 0) { + res = TRUE; + break; + } + } + + return res; } void -write_pdml_proto_tree(epan_dissect_t *edt, FILE *fh) +write_pdml_proto_tree(gchar **protocolfilter, epan_dissect_t *edt, FILE *fh) { write_pdml_data data; @@ -272,6 +294,7 @@ write_pdml_proto_tree(epan_dissect_t *edt, FILE *fh) data.fh = fh; data.src_list = edt->pi.data_src; data.edt = edt; + data.filter = protocolfilter; fprintf(fh, "<packet>\n"); @@ -285,41 +308,48 @@ write_pdml_proto_tree(epan_dissect_t *edt, FILE *fh) } void -write_json_proto_tree(print_args_t *print_args, gchar *jsonfilter, epan_dissect_t *edt, FILE *fh) +write_json_proto_tree(print_args_t *print_args, gchar **protocolfilter, epan_dissect_t *edt, FILE *fh) { write_json_data data; char ts[30]; time_t t = time(NULL); struct tm * timeinfo; + static gboolean is_first = TRUE; /* Create the output */ - data.level = 0; + data.level = 1; data.fh = fh; data.src_list = edt->pi.data_src; data.edt = edt; - data.filter = jsonfilter; + data.filter = protocolfilter; data.print_hex = print_args->print_hex; timeinfo = localtime(&t); strftime(ts, 30, "%Y-%m-%d", timeinfo); - fprintf(fh, " \"_index\": \"packets-%s\",\n", ts); - fputs(" \"_type\": \"pcap_file\",\n", fh); - fputs(" \"_score\": null,\n", fh); - fputs(" \"_source\": {\n", fh); - fputs(" \"layers\": {\n", fh); + if (!is_first) + fputs(" ,\n", fh); + else + is_first = FALSE; + + fputs(" {\n", fh); + fprintf(fh, " \"_index\": \"packets-%s\",\n", ts); + fputs(" \"_type\": \"pcap_file\",\n", fh); + fputs(" \"_score\": null,\n", fh); + fputs(" \"_source\": {\n", fh); + fputs(" \"layers\": {\n", fh); proto_tree_children_foreach(edt->tree, proto_tree_write_node_json, &data); + fputs(" }\n", fh); fputs(" }\n", fh); - - fputs(" },\n", fh); + fputs(" }", fh); } void -write_ek_proto_tree(print_args_t *print_args, gchar *jsonfilter, epan_dissect_t *edt, FILE *fh) +write_ek_proto_tree(print_args_t *print_args, gchar **protocolfilter, epan_dissect_t *edt, FILE *fh) { write_json_data data; char ts[30]; @@ -333,7 +363,7 @@ write_ek_proto_tree(print_args_t *print_args, gchar *jsonfilter, epan_dissect_t data.fh = fh; data.src_list = edt->pi.data_src; data.edt = edt; - data.filter = jsonfilter; + data.filter = protocolfilter; data.print_hex = print_args->print_hex; @@ -357,7 +387,7 @@ write_ek_proto_tree(print_args_t *print_args, gchar *jsonfilter, epan_dissect_t fprintf(fh, "{\"index\" : {\"_index\": \"packets-%s\", \"_type\": \"pcap_file\", \"_score\": null}}\n", ts); /* Timestamp added for time indexing in Elasticsearch */ - fprintf(fh, "{\"timestamp\" : \"%ld%03d\", \"layers\" : {", timestamp->secs, timestamp->nsecs/1000000); + 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, @@ -573,12 +603,23 @@ proto_tree_write_node_pdml(proto_node *node, gpointer data) } } - /* We always print all levels for PDML. Recurse here. */ + /* We print some levels for PDML. Recurse here. */ if (node->first_child != NULL) { - pdata->level++; - proto_tree_children_foreach(node, - proto_tree_write_node_pdml, pdata); - pdata->level--; + if(check_protocolfilter(pdata->filter, fi->hfinfo->abbrev)) { + pdata->level++; + proto_tree_children_foreach(node, + proto_tree_write_node_pdml, pdata); + pdata->level--; + } else { + /* Indent to the correct level */ + for (i = -2; i < pdata->level; i++) { + fputs(" ", pdata->fh); + } + /* print dummy field */ + fputs("<field name=\"filtered\" value=\"", pdata->fh); + print_escaped_xml(pdata->fh, fi->hfinfo->abbrev); + fputs("\" />\n", pdata->fh); + } } /* Take back the extra level we added for fake wrapper protocol */ @@ -760,11 +801,20 @@ 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) { - if(strstr(pdata->filter, fi->hfinfo->abbrev) != NULL) { + if(check_protocolfilter(pdata->filter, fi->hfinfo->abbrev)) { pdata->level++; proto_tree_children_foreach(node, proto_tree_write_node_json, pdata); pdata->level--; + } else { + /* Indent to the correct level */ + for (i = -4; i < pdata->level; i++) { + fputs(" ", pdata->fh); + } + /* print dummy field */ + fputs("\"filtered\": \"", pdata->fh); + print_escaped_ek(pdata->fh, fi->hfinfo->abbrev); + fputs("\"\n", pdata->fh); } } else { pdata->level++; @@ -799,7 +849,6 @@ proto_tree_write_node_ek(proto_node *node, gpointer data) char *dfilter_string; int i; gchar *abbrev_escaped = NULL; - size_t abbrev_escaped_len = 0; /* dissection with an invisible proto tree? */ g_assert(fi); @@ -953,8 +1002,7 @@ proto_tree_write_node_ek(proto_node *node, gpointer data) /* to to thread the '.' and '_' equally. The '.' is replace by print_escaped_ek for '_' */ if (fi->hfinfo->abbrev != NULL) { - abbrev_escaped_len = strlen(fi->hfinfo->abbrev) + 1; - if (abbrev_escaped_len > 0) { + if (strlen(fi->hfinfo->abbrev) > 0) { abbrev_escaped = g_strdup(fi->hfinfo->abbrev); i = 0; @@ -968,19 +1016,20 @@ proto_tree_write_node_ek(proto_node *node, gpointer data) } } - if((strstr(pdata->filter, fi->hfinfo->abbrev) != NULL) || (strstr(pdata->filter, abbrev_escaped) != NULL)) { + if(check_protocolfilter(pdata->filter, fi->hfinfo->abbrev) || check_protocolfilter(pdata->filter, abbrev_escaped)) { pdata->level++; proto_tree_children_foreach(node, proto_tree_write_node_ek, pdata); pdata->level--; } else { /* print dummy field */ - fputs("\"filtered\": \"\"", pdata->fh); + fputs("\"filtered\": \"", pdata->fh); + print_escaped_ek(pdata->fh, fi->hfinfo->abbrev); + fputs("\"", pdata->fh); } /* release abbrev_escaped string */ if (abbrev_escaped != NULL) { - abbrev_escaped_len = 0; g_free(abbrev_escaped); } @@ -1104,8 +1153,7 @@ write_pdml_finale(FILE *fh) void write_json_finale(FILE *fh) { - fputs("}\n", fh); - + fputs("]\n", fh); } void @@ -1358,13 +1406,34 @@ print_escaped_json(FILE *fh, const char *unescaped_string) for (p = unescaped_string; *p != '\0'; p++) { switch (*p) { case '"': - fputs(""", fh); + fputs("\\\"", fh); + break; + case '\\': + fputs("\\\\", fh); + break; + case '/': + fputs("\\/", fh); + break; + case '\b': + fputs("\\b", fh); + break; + case '\f': + fputs("\\f", fh); + break; + case '\n': + fputs("\\n", fh); + break; + case '\r': + fputs("\\r", fh); + break; + case '\t': + fputs("\\t", fh); break; default: if (g_ascii_isprint(*p)) fputc(*p, fh); else { - g_snprintf(temp_str, sizeof(temp_str), "%x", (guint8)*p); + g_snprintf(temp_str, sizeof(temp_str), "\\u00%u", (guint8)*p); fputs(temp_str, fh); } } @@ -1382,8 +1451,29 @@ print_escaped_ek(FILE *fh, const char *unescaped_string) for (p = unescaped_string; *p != '\0'; p++) { switch (*p) { case '"': - fputs(""", fh); - break; + fputs("\\\"", fh); + break; + case '\\': + fputs("\\\\", fh); + break; + case '/': + fputs("\\/", fh); + break; + case '\b': + fputs("\\b", fh); + break; + case '\f': + fputs("\\f", fh); + break; + case '\n': + fputs("\\n", fh); + break; + case '\r': + fputs("\\r", fh); + break; + case '\t': + fputs("\\t", fh); + break; case '.': fputs("_", fh); break; @@ -1391,7 +1481,7 @@ print_escaped_ek(FILE *fh, const char *unescaped_string) if (g_ascii_isprint(*p)) fputc(*p, fh); else { - g_snprintf(temp_str, sizeof(temp_str), "\\x%x", (guint8)*p); + g_snprintf(temp_str, sizeof(temp_str), "\\u00%u", (guint8)*p); fputs(temp_str, fh); } } |