ws_pipe: don't check for negative number using DWORD.
[metze/wireshark/wip.git] / epan / print.c
1 /* print.c
2  * Routines for printing packet analysis trees.
3  *
4  * Gilbert Ramirez <gram@alumni.rice.edu>
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * SPDX-License-Identifier: GPL-2.0-or-later
11  */
12
13 #include "config.h"
14
15 #include <stdio.h>
16 #include <string.h>
17
18 #include <epan/packet.h>
19 #include <epan/epan.h>
20 #include <epan/epan_dissect.h>
21 #include <epan/to_str.h>
22 #include <epan/expert.h>
23 #include <epan/column.h>
24 #include <epan/column-info.h>
25 #include <epan/color_filters.h>
26 #include <epan/prefs.h>
27 #include <epan/print.h>
28 #include <epan/charsets.h>
29 #include <wsutil/filesystem.h>
30 #include <version_info.h>
31 #include <wsutil/utf8_entities.h>
32 #include <ftypes/ftypes-int.h>
33
34 #define PDML_VERSION "0"
35 #define PSML_VERSION "0"
36
37 typedef struct {
38     int                  level;
39     print_stream_t      *stream;
40     gboolean             success;
41     GSList              *src_list;
42     print_dissections_e  print_dissections;
43     gboolean             print_hex_for_data;
44     packet_char_enc      encoding;
45     GHashTable          *output_only_tables; /* output only these protocols */
46 } print_data;
47
48 typedef struct {
49     int             level;
50     FILE           *fh;
51     GSList         *src_list;
52     gchar         **filter;
53     pf_flags        filter_flags;
54 } write_pdml_data;
55
56 typedef struct {
57     int             level;
58     FILE           *fh;
59     GSList         *src_list;
60     gchar         **filter;
61     pf_flags        filter_flags;
62     gboolean        print_hex;
63     gboolean        print_text;
64     proto_node_children_grouper_func node_children_grouper;
65 } write_json_data;
66
67 typedef struct {
68     output_fields_t *fields;
69     epan_dissect_t  *edt;
70 } write_field_data_t;
71
72 struct _output_fields {
73     gboolean      print_bom;
74     gboolean      print_header;
75     gchar         separator;
76     gchar         occurrence;
77     gchar         aggregator;
78     GPtrArray    *fields;
79     GHashTable   *field_indicies;
80     GPtrArray   **field_values;
81     gchar         quote;
82     gboolean      includes_col_fields;
83 };
84
85 static gchar *get_field_hex_value(GSList *src_list, field_info *fi);
86 static void proto_tree_print_node(proto_node *node, gpointer data);
87 static void proto_tree_write_node_pdml(proto_node *node, gpointer data);
88 static void proto_tree_write_node_ek(proto_node *node, write_json_data *data);
89 static const guint8 *get_field_data(GSList *src_list, field_info *fi);
90 static void pdml_write_field_hex_value(write_pdml_data *pdata, field_info *fi);
91 static void json_write_field_hex_value(write_json_data *pdata, field_info *fi);
92 static gboolean print_hex_data_buffer(print_stream_t *stream, const guchar *cp,
93                                       guint length, packet_char_enc encoding);
94 static void write_specified_fields(fields_format format,
95                                    output_fields_t *fields,
96                                    epan_dissect_t *edt, column_info *cinfo,
97                                    FILE *fh);
98 static void print_escaped_xml(FILE *fh, const char *unescaped_string);
99 static void print_escaped_json(FILE *fh, const char *unescaped_string);
100 static void print_escaped_ek(FILE *fh, const char *unescaped_string);
101
102 typedef void (*proto_node_value_writer)(proto_node *, write_json_data *);
103 static void write_json_proto_node_list(GSList *proto_node_list_head, write_json_data *data);
104 static void write_json_proto_node(GSList *node_values_head,
105                                   const char *suffix,
106                                   proto_node_value_writer value_writer,
107                                   write_json_data *data);
108 static void write_json_proto_node_value_list(GSList *node_values_head,
109                                              proto_node_value_writer value_writer,
110                                              write_json_data *data);
111 static void write_json_proto_node_filtered(proto_node *node, write_json_data *data);
112 static void write_json_proto_node_hex_dump(proto_node *node, write_json_data *data);
113 static void write_json_proto_node_children(proto_node *node, write_json_data *data);
114 static void write_json_proto_node_value(proto_node *node, write_json_data *data);
115 static void write_json_proto_node_no_value(proto_node *node, write_json_data *data);
116 static const char *proto_node_to_json_key(proto_node *node);
117
118 static void print_pdml_geninfo(epan_dissect_t *edt, FILE *fh);
119 static void write_ek_summary(column_info *cinfo, FILE *fh);
120
121 static void proto_tree_get_node_field_values(proto_node *node, gpointer data);
122
123 static gboolean json_is_first;
124
125 /* Cache the protocols and field handles that the print functionality needs
126    This helps break explicit dependency on the dissectors. */
127 static int proto_data = -1;
128 static int proto_frame = -1;
129
130 void print_cache_field_handles(void)
131 {
132     proto_data = proto_get_id_by_short_name("Data");
133     proto_frame = proto_get_id_by_short_name("Frame");
134 }
135
136 gboolean
137 proto_tree_print(print_dissections_e print_dissections, gboolean print_hex,
138                  epan_dissect_t *edt, GHashTable *output_only_tables,
139                  print_stream_t *stream)
140 {
141     print_data data;
142
143     /* Create the output */
144     data.level              = 0;
145     data.stream             = stream;
146     data.success            = TRUE;
147     data.src_list           = edt->pi.data_src;
148     data.encoding           = (packet_char_enc)edt->pi.fd->flags.encoding;
149     data.print_dissections  = print_dissections;
150     /* If we're printing the entire packet in hex, don't
151        print uninterpreted data fields in hex as well. */
152     data.print_hex_for_data = !print_hex;
153     data.output_only_tables = output_only_tables;
154
155     proto_tree_children_foreach(edt->tree, proto_tree_print_node, &data);
156     return data.success;
157 }
158
159 /* Print a tree's data, and any child nodes. */
160 static void
161 proto_tree_print_node(proto_node *node, gpointer data)
162 {
163     field_info   *fi    = PNODE_FINFO(node);
164     print_data   *pdata = (print_data*) data;
165     const guint8 *pd;
166     gchar         label_str[ITEM_LABEL_LENGTH];
167     gchar        *label_ptr;
168
169     /* dissection with an invisible proto tree? */
170     g_assert(fi);
171
172     /* Don't print invisible entries. */
173     if (PROTO_ITEM_IS_HIDDEN(node) && (prefs.display_hidden_proto_items == FALSE))
174         return;
175
176     /* Give up if we've already gotten an error. */
177     if (!pdata->success)
178         return;
179
180     /* was a free format label produced? */
181     if (fi->rep) {
182         label_ptr = fi->rep->representation;
183     }
184     else { /* no, make a generic label */
185         label_ptr = label_str;
186         proto_item_fill_label(fi, label_str);
187     }
188
189     if (PROTO_ITEM_IS_GENERATED(node))
190         label_ptr = g_strconcat("[", label_ptr, "]", NULL);
191
192     pdata->success = print_line(pdata->stream, pdata->level, label_ptr);
193
194     if (PROTO_ITEM_IS_GENERATED(node))
195         g_free(label_ptr);
196
197     if (!pdata->success)
198         return;
199
200     /*
201      * If -O is specified, only display the protocols which are in the
202      * lookup table.  Only check on the first level: once we start printing
203      * a tree, print the rest of the subtree.  Otherwise we won't print
204      * subitems whose abbreviation doesn't match the protocol--for example
205      * text items (whose abbreviation is simply "text").
206      */
207     if ((pdata->output_only_tables != NULL) && (pdata->level == 0)
208         && (g_hash_table_lookup(pdata->output_only_tables, fi->hfinfo->abbrev) == NULL)) {
209         return;
210     }
211
212     /* If it's uninterpreted data, dump it (unless our caller will
213        be printing the entire packet in hex). */
214     if ((fi->hfinfo->id == proto_data) && (pdata->print_hex_for_data)) {
215         /*
216          * Find the data for this field.
217          */
218         pd = get_field_data(pdata->src_list, fi);
219         if (pd) {
220             if (!print_line(pdata->stream, 0, "")) {
221                 pdata->success = FALSE;
222                 return;
223             }
224             if (!print_hex_data_buffer(pdata->stream, pd,
225                                        fi->length, pdata->encoding)) {
226                 pdata->success = FALSE;
227                 return;
228             }
229         }
230     }
231
232     /* If we're printing all levels, or if this node is one with a
233        subtree and its subtree is expanded, recurse into the subtree,
234        if it exists. */
235     g_assert((fi->tree_type >= -1) && (fi->tree_type < num_tree_types));
236     if ((pdata->print_dissections == print_dissections_expanded) ||
237         ((pdata->print_dissections == print_dissections_as_displayed) &&
238          (fi->tree_type >= 0) && tree_expanded(fi->tree_type))) {
239         if (node->first_child != NULL) {
240             pdata->level++;
241             proto_tree_children_foreach(node,
242                                         proto_tree_print_node, pdata);
243             pdata->level--;
244             if (!pdata->success)
245                 return;
246         }
247     }
248 }
249
250 #define PDML2HTML_XSL "pdml2html.xsl"
251 void
252 write_pdml_preamble(FILE *fh, const gchar *filename)
253 {
254     time_t t = time(NULL);
255     struct tm * timeinfo;
256     char *fmt_ts;
257     const char *ts;
258
259     /* Create the output */
260     timeinfo = localtime(&t);
261     if (timeinfo != NULL) {
262         fmt_ts = asctime(timeinfo);
263         fmt_ts[strlen(fmt_ts)-1] = 0; /* overwrite \n */
264         ts = fmt_ts;
265     } else
266         ts = "Not representable";
267
268     fprintf(fh, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
269     fprintf(fh, "<?xml-stylesheet type=\"text/xsl\" href=\"" PDML2HTML_XSL "\"?>\n");
270     fprintf(fh, "<!-- You can find " PDML2HTML_XSL " in %s or at https://code.wireshark.org/review/gitweb?p=wireshark.git;a=blob_plain;f=" PDML2HTML_XSL ". -->\n", get_datafile_dir());
271     fprintf(fh, "<pdml version=\"" PDML_VERSION "\" creator=\"%s/%s\" time=\"%s\" capture_file=\"", PACKAGE, VERSION, ts);
272     if (filename) {
273         /* \todo filename should be converted to UTF-8. */
274         print_escaped_xml(fh, filename);
275     }
276     fprintf(fh, "\">\n");
277 }
278
279 /* Check if the str match the protocolfilter. json_filter is space
280    delimited string and str need to exact-match to one of the value. */
281 static gboolean check_protocolfilter(gchar **protocolfilter, const char *str)
282 {
283     gboolean res = FALSE;
284     gchar **ptr;
285
286     if (str == NULL || protocolfilter == NULL) {
287         return FALSE;
288     }
289
290     for (ptr = protocolfilter; *ptr; ptr++) {
291         if (strcmp(*ptr, str) == 0) {
292             res = TRUE;
293             break;
294         }
295     }
296
297     return res;
298 }
299
300 void
301 write_pdml_proto_tree(output_fields_t* fields, gchar **protocolfilter, pf_flags protocolfilter_flags, epan_dissect_t *edt, column_info *cinfo, FILE *fh, gboolean use_color)
302 {
303     write_pdml_data data;
304     const color_filter_t *cfp;
305
306     g_assert(edt);
307     g_assert(fh);
308
309     cfp = edt->pi.fd->color_filter;
310
311     /* Create the output */
312     if (use_color && (cfp != NULL)) {
313         fprintf(fh, "<packet foreground='#%06x' background='#%06x'>\n",
314             color_t_to_rgb(&cfp->fg_color),
315             color_t_to_rgb(&cfp->bg_color));
316     }
317     else {
318         fprintf(fh, "<packet>\n");
319     }
320
321     /* Print a "geninfo" protocol as required by PDML */
322     print_pdml_geninfo(edt, fh);
323
324     if (fields == NULL || fields->fields == NULL) {
325         /* Write out all fields */
326         data.level    = 0;
327         data.fh       = fh;
328         data.src_list = edt->pi.data_src;
329         data.filter   = protocolfilter;
330         data.filter_flags   = protocolfilter_flags;
331
332         proto_tree_children_foreach(edt->tree, proto_tree_write_node_pdml,
333                                     &data);
334     } else {
335         /* Write out specified fields */
336         write_specified_fields(FORMAT_XML, fields, edt, cinfo, fh);
337     }
338
339     fprintf(fh, "</packet>\n\n");
340 }
341
342 void
343 write_ek_proto_tree(output_fields_t* fields,
344                     gboolean print_summary, gboolean print_hex,
345                     gchar **protocolfilter,
346                     pf_flags protocolfilter_flags, epan_dissect_t *edt,
347                     column_info *cinfo,
348                     FILE *fh)
349 {
350     write_json_data data;
351     char ts[30];
352     time_t t = time(NULL);
353     struct tm  *timeinfo;
354
355     g_assert(edt);
356     g_assert(fh);
357
358     /* Create the output */
359     timeinfo = localtime(&t);
360     if (timeinfo != NULL)
361         strftime(ts, sizeof ts, "%Y-%m-%d", timeinfo);
362     else
363         g_strlcpy(ts, "XXXX-XX-XX", sizeof ts); /* XXX - better way of saying "Not representable"? */
364
365     fprintf(fh, "{\"index\" : {\"_index\": \"packets-%s\", \"_type\": \"pcap_file\"}}\n", ts);
366     /* Timestamp added for time indexing in Elasticsearch */
367     fprintf(fh, "{\"timestamp\" : \"%" G_GUINT64_FORMAT "%03d\"", (guint64)edt->pi.abs_ts.secs, edt->pi.abs_ts.nsecs/1000000);
368
369     if (print_summary)
370         write_ek_summary(edt->pi.cinfo, fh);
371
372     if (edt->tree) {
373         fprintf(fh, ", \"layers\" : {");
374
375         if (fields == NULL || fields->fields == NULL) {
376             /* Write out all fields */
377             data.level    = 0;
378             data.fh       = fh;
379             data.src_list = edt->pi.data_src;
380             data.filter   = protocolfilter;
381             data.filter_flags = protocolfilter_flags;
382             data.print_hex = print_hex;
383
384             proto_tree_write_node_ek(edt->tree, &data);
385         } else {
386             /* Write out specified fields */
387             write_specified_fields(FORMAT_EK, fields, edt, cinfo, fh);
388         }
389
390         fputs("}", fh);
391     }
392
393     fputs("}\n", fh);
394 }
395
396 void
397 write_fields_proto_tree(output_fields_t* fields, epan_dissect_t *edt, column_info *cinfo, FILE *fh)
398 {
399     g_assert(edt);
400     g_assert(fh);
401
402     /* Create the output */
403     write_specified_fields(FORMAT_CSV, fields, edt, cinfo, fh);
404 }
405
406 /* Indent to the correct level */
407 static void print_indent(int level, FILE *fh)
408 {
409     int i;
410     if (fh == NULL) {
411         return;
412     }
413     for (i = 0; i < level; i++) {
414         fputs("  ", fh);
415     }
416 }
417
418 /* Write out a tree's data, and any child nodes, as PDML */
419 static void
420 proto_tree_write_node_pdml(proto_node *node, gpointer data)
421 {
422     field_info      *fi    = PNODE_FINFO(node);
423     write_pdml_data *pdata = (write_pdml_data*) data;
424     const gchar     *label_ptr;
425     gchar            label_str[ITEM_LABEL_LENGTH];
426     char            *dfilter_string;
427     gboolean         wrap_in_fake_protocol;
428
429     /* dissection with an invisible proto tree? */
430     g_assert(fi);
431
432     /* Will wrap up top-level field items inside a fake protocol wrapper to
433        preserve the PDML schema */
434     wrap_in_fake_protocol =
435         (((fi->hfinfo->type != FT_PROTOCOL) ||
436           (fi->hfinfo->id == proto_data)) &&
437          (pdata->level == 0));
438
439     print_indent(pdata->level + 1, pdata->fh);
440
441     if (wrap_in_fake_protocol) {
442         /* Open fake protocol wrapper */
443         fputs("<proto name=\"fake-field-wrapper\">\n", pdata->fh);
444         pdata->level++;
445
446         print_indent(pdata->level + 1, pdata->fh);
447     }
448
449     /* Text label. It's printed as a field with no name. */
450     if (fi->hfinfo->id == hf_text_only) {
451         /* Get the text */
452         if (fi->rep) {
453             label_ptr = fi->rep->representation;
454         }
455         else {
456             label_ptr = "";
457         }
458
459         /* Show empty name since it is a required field */
460         fputs("<field name=\"", pdata->fh);
461         fputs("\" show=\"", pdata->fh);
462         print_escaped_xml(pdata->fh, label_ptr);
463
464         fprintf(pdata->fh, "\" size=\"%d", fi->length);
465         if (node->parent && node->parent->finfo && (fi->start < node->parent->finfo->start)) {
466             fprintf(pdata->fh, "\" pos=\"%d", node->parent->finfo->start + fi->start);
467         } else {
468             fprintf(pdata->fh, "\" pos=\"%d", fi->start);
469         }
470
471         if (fi->length > 0) {
472             fputs("\" value=\"", pdata->fh);
473             pdml_write_field_hex_value(pdata, fi);
474         }
475
476         if (node->first_child != NULL) {
477             fputs("\">\n", pdata->fh);
478         }
479         else {
480             fputs("\"/>\n", pdata->fh);
481         }
482     }
483
484     /* Uninterpreted data, i.e., the "Data" protocol, is
485      * printed as a field instead of a protocol. */
486     else if (fi->hfinfo->id == proto_data) {
487         /* Write out field with data */
488         fputs("<field name=\"data\" value=\"", pdata->fh);
489         pdml_write_field_hex_value(pdata, fi);
490         fputs("\">\n", pdata->fh);
491     }
492     /* Normal protocols and fields */
493     else {
494         if ((fi->hfinfo->type == FT_PROTOCOL) && (fi->hfinfo->id != proto_expert)) {
495             fputs("<proto name=\"", pdata->fh);
496         }
497         else {
498             fputs("<field name=\"", pdata->fh);
499         }
500         print_escaped_xml(pdata->fh, fi->hfinfo->abbrev);
501
502 #if 0
503         /* PDML spec, see:
504          * https://wayback.archive.org/web/20150330045501/http://www.nbee.org/doku.php?id=netpdl:pdml_specification
505          *
506          * the show fields contains things in 'human readable' format
507          * showname: contains only the name of the field
508          * show: contains only the data of the field
509          * showdtl: contains additional details of the field data
510          * showmap: contains mappings of the field data (e.g. the hostname to an IP address)
511          *
512          * XXX - the showname shouldn't contain the field data itself
513          * (like it's contained in the fi->rep->representation).
514          * Unfortunately, we don't have the field data representation for
515          * all fields, so this isn't currently possible */
516         fputs("\" showname=\"", pdata->fh);
517         print_escaped_xml(pdata->fh, fi->hfinfo->name);
518 #endif
519
520         if (fi->rep) {
521             fputs("\" showname=\"", pdata->fh);
522             print_escaped_xml(pdata->fh, fi->rep->representation);
523         }
524         else {
525             label_ptr = label_str;
526             proto_item_fill_label(fi, label_str);
527             fputs("\" showname=\"", pdata->fh);
528             print_escaped_xml(pdata->fh, label_ptr);
529         }
530
531         if (PROTO_ITEM_IS_HIDDEN(node) && (prefs.display_hidden_proto_items == FALSE))
532             fprintf(pdata->fh, "\" hide=\"yes");
533
534         fprintf(pdata->fh, "\" size=\"%d", fi->length);
535         if (node->parent && node->parent->finfo && (fi->start < node->parent->finfo->start)) {
536             fprintf(pdata->fh, "\" pos=\"%d", node->parent->finfo->start + fi->start);
537         } else {
538             fprintf(pdata->fh, "\" pos=\"%d", fi->start);
539         }
540 /*      fprintf(pdata->fh, "\" id=\"%d", fi->hfinfo->id);*/
541
542         /* show, value, and unmaskedvalue attributes */
543         switch (fi->hfinfo->type)
544         {
545         case FT_PROTOCOL:
546             break;
547         case FT_NONE:
548             fputs("\" show=\"\" value=\"",  pdata->fh);
549             break;
550         default:
551             dfilter_string = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
552             if (dfilter_string != NULL) {
553
554                 fputs("\" show=\"", pdata->fh);
555                 print_escaped_xml(pdata->fh, dfilter_string);
556             }
557             wmem_free(NULL, dfilter_string);
558
559             /*
560              * XXX - should we omit "value" for any fields?
561              * What should we do for fields whose length is 0?
562              * They might come from a pseudo-header or from
563              * the capture header (e.g., time stamps), or
564              * they might be generated fields.
565              */
566             if (fi->length > 0) {
567                 fputs("\" value=\"", pdata->fh);
568
569                 if (fi->hfinfo->bitmask!=0) {
570                     switch (fi->value.ftype->ftype) {
571                         case FT_INT8:
572                         case FT_INT16:
573                         case FT_INT24:
574                         case FT_INT32:
575                             fprintf(pdata->fh, "%X", (guint) fvalue_get_sinteger(&fi->value));
576                             break;
577                         case FT_UINT8:
578                         case FT_UINT16:
579                         case FT_UINT24:
580                         case FT_UINT32:
581                             fprintf(pdata->fh, "%X", fvalue_get_uinteger(&fi->value));
582                             break;
583                         case FT_INT40:
584                         case FT_INT48:
585                         case FT_INT56:
586                         case FT_INT64:
587                             fprintf(pdata->fh, "%" G_GINT64_MODIFIER "X", fvalue_get_sinteger64(&fi->value));
588                             break;
589                         case FT_UINT40:
590                         case FT_UINT48:
591                         case FT_UINT56:
592                         case FT_UINT64:
593                         case FT_BOOLEAN:
594                             fprintf(pdata->fh, "%" G_GINT64_MODIFIER "X", fvalue_get_uinteger64(&fi->value));
595                             break;
596                         default:
597                             g_assert_not_reached();
598                     }
599                     fputs("\" unmaskedvalue=\"", pdata->fh);
600                     pdml_write_field_hex_value(pdata, fi);
601                 }
602                 else {
603                     pdml_write_field_hex_value(pdata, fi);
604                 }
605             }
606         }
607
608         if (node->first_child != NULL) {
609             fputs("\">\n", pdata->fh);
610         }
611         else if (fi->hfinfo->id == proto_data) {
612             fputs("\">\n", pdata->fh);
613         }
614         else {
615             fputs("\"/>\n", pdata->fh);
616         }
617     }
618
619     /* We print some levels for PDML. Recurse here. */
620     if (node->first_child != NULL) {
621         if (pdata->filter == NULL || check_protocolfilter(pdata->filter, fi->hfinfo->abbrev)) {
622             gchar **_filter = NULL;
623             /* Remove protocol filter for children, if children should be included */
624             if ((pdata->filter_flags&PF_INCLUDE_CHILDREN) == PF_INCLUDE_CHILDREN) {
625                 _filter = pdata->filter;
626                 pdata->filter = NULL;
627             }
628
629             pdata->level++;
630             proto_tree_children_foreach(node,
631                                         proto_tree_write_node_pdml, pdata);
632             pdata->level--;
633
634             /* Put protocol filter back */
635             if ((pdata->filter_flags&PF_INCLUDE_CHILDREN) == PF_INCLUDE_CHILDREN) {
636                 pdata->filter = _filter;
637             }
638         } else {
639             print_indent(pdata->level + 2, pdata->fh);
640
641             /* print dummy field */
642             fputs("<field name=\"filtered\" value=\"", pdata->fh);
643             print_escaped_xml(pdata->fh, fi->hfinfo->abbrev);
644             fputs("\" />\n", pdata->fh);
645         }
646     }
647
648     /* Take back the extra level we added for fake wrapper protocol */
649     if (wrap_in_fake_protocol) {
650         pdata->level--;
651     }
652
653     if (node->first_child != NULL) {
654         print_indent(pdata->level + 1, pdata->fh);
655
656         /* Close off current element */
657         /* Data and expert "protocols" use simple tags */
658         if ((fi->hfinfo->id != proto_data) && (fi->hfinfo->id != proto_expert)) {
659             if (fi->hfinfo->type == FT_PROTOCOL) {
660                 fputs("</proto>\n", pdata->fh);
661             }
662             else {
663                 fputs("</field>\n", pdata->fh);
664             }
665         } else {
666             fputs("</field>\n", pdata->fh);
667         }
668     }
669
670     /* Close off fake wrapper protocol */
671     if (wrap_in_fake_protocol) {
672         print_indent(pdata->level + 1, pdata->fh);
673         fputs("</proto>\n", pdata->fh);
674     }
675 }
676
677 void
678 write_json_preamble(FILE *fh)
679 {
680     fputs("[\n", fh);
681     json_is_first = TRUE;
682 }
683
684 void
685 write_json_finale(FILE *fh)
686 {
687     fputs("\n\n]\n", fh);
688 }
689
690 void
691 write_json_proto_tree(output_fields_t* fields,
692                       print_dissections_e print_dissections,
693                       gboolean print_hex, gchar **protocolfilter,
694                       pf_flags protocolfilter_flags, epan_dissect_t *edt,
695                       column_info *cinfo,
696                       proto_node_children_grouper_func node_children_grouper,
697                       FILE *fh)
698 {
699     char ts[30];
700     time_t t = time(NULL);
701     struct tm * timeinfo;
702     write_json_data data;
703
704     if (!json_is_first) {
705         fputs("\n\n  ,\n", fh);
706     } else {
707         json_is_first = FALSE;
708     }
709
710     timeinfo = localtime(&t);
711     if (timeinfo != NULL) {
712         strftime(ts, sizeof ts, "%Y-%m-%d", timeinfo);
713     } else {
714         g_strlcpy(ts, "XXXX-XX-XX", sizeof ts); /* XXX - better way of saying "Not representable"? */
715     }
716
717     fputs("  {\n", fh);
718     fprintf(fh, "    \"_index\": \"packets-%s\",\n", ts);
719     fputs("    \"_type\": \"pcap_file\",\n", fh);
720     fputs("    \"_score\": null,\n", fh);
721     fputs("    \"_source\": {\n", fh);
722     fputs("      \"layers\": ", fh);
723
724     if (fields == NULL || fields->fields == NULL) {
725         /* Write out all fields */
726         data.level    = 3;
727         data.fh       = fh;
728         data.src_list = edt->pi.data_src;
729         data.filter   = protocolfilter;
730         data.filter_flags = protocolfilter_flags;
731         data.print_hex = print_hex;
732         data.print_text = TRUE;
733         if (print_dissections == print_dissections_none) {
734             data.print_text = FALSE;
735         }
736         data.node_children_grouper = node_children_grouper;
737
738         write_json_proto_node_children(edt->tree, &data);
739     } else {
740         write_specified_fields(FORMAT_JSON, fields, edt, cinfo, fh);
741     }
742
743     fputs("\n", fh);
744     fputs("    }\n", fh);
745     fputs("  }", fh);
746 }
747
748 /**
749  * Write a json object containing a list of key:value pairs where each key:value pair corresponds to a different json
750  * key and its associated nodes in the proto_tree.
751  * @param proto_node_list_head A 2-dimensional list containing a list of values for each different node json key. The
752  * elements themselves are a linked list of values associated with the same json key.
753  * @param data json writing metadata
754  */
755 static void
756 write_json_proto_node_list(GSList *proto_node_list_head, write_json_data *data)
757 {
758     GSList *current_node = proto_node_list_head;
759
760     fputs("{\n", data->fh);
761     data->level++;
762
763     /*
764      * In most of the following if statements we cannot be sure if its the first or last if statement to be
765      * executed. Thus we need a way of knowing whether a key:value pair has already been printed in order to know
766      * if a comma should be printed before the next key:value pair. We use the delimiter_needed variable to store
767      * whether a comma needs to be written before a new key:value pair is written. Note that instead of checking
768      * before writing a new key:value pair if a comma is needed we could also check after writing a key:value pair
769      * whether a comma is needed but this would be considerably more complex since after each if statement a
770      * different condition would have to be checked. After the first value is written a delimiter is always needed so
771      * this value is never set back to FALSE after it has been set to TRUE.
772      */
773     gboolean delimiter_needed = FALSE;
774
775     // Loop over each list of nodes (differentiated by json key) and write the associated json key:value pair in the
776     // output.
777     while (current_node != NULL) {
778         // Get the list of values for the current json key.
779         GSList *node_values_list = (GSList *) current_node->data;
780
781         // Retrieve the json key from the first value.
782         proto_node *first_value = (proto_node *) node_values_list->data;
783         const char *json_key = proto_node_to_json_key(first_value);
784         // Check if the current json key is filtered from the output with the "-j" cli option.
785         gboolean is_filtered = data->filter != NULL && !check_protocolfilter(data->filter, json_key);
786
787         field_info *fi = first_value->finfo;
788         char *value_string_repr = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
789
790         // We assume all values of a json key have roughly the same layout. Thus we can use the first value to derive
791         // attributes of all the values.
792         gboolean has_value = value_string_repr != NULL;
793         gboolean has_children = first_value->first_child != NULL;
794         gboolean is_pseudo_text_field = fi->hfinfo->id == 0;
795
796         wmem_free(NULL, value_string_repr); // fvalue_to_string_repr returns allocated buffer
797
798         // "-x" command line option. A "_raw" suffix is added to the json key so the textual value can be printed
799         // with the original json key. If both hex and text writing are enabled the raw information of fields whose
800         // length is equal to 0 is not written to the output. If the field is a special text pseudo field no raw
801         // information is written either.
802         if (data->print_hex && (!data->print_text || fi->length > 0) && !is_pseudo_text_field) {
803             if (delimiter_needed) fputs(",\n", data->fh);
804             write_json_proto_node(node_values_list, "_raw", write_json_proto_node_hex_dump, data);
805             delimiter_needed = TRUE;
806         }
807
808         if (data->print_text && has_value) {
809             if (delimiter_needed) fputs(",\n", data->fh);
810             write_json_proto_node(node_values_list, "", write_json_proto_node_value, data);
811             delimiter_needed = TRUE;
812         }
813
814         if (has_children) {
815             if (delimiter_needed) fputs(",\n", data->fh);
816
817             // If a node has both a value and a set of children we print the value and the children in separate
818             // key:value pairs. These can't have the same key so whenever a value is already printed with the node
819             // json key we print the children with the same key with a "_tree" suffix added.
820             char *suffix = has_value ? "_tree": "";
821
822             if (is_filtered) {
823                 write_json_proto_node(node_values_list, suffix, write_json_proto_node_filtered, data);
824             } else {
825                 // Remove protocol filter for children, if children should be included. This functionality is enabled
826                 // with the "-J" command line option. We save the filter so it can be reenabled when we are done with
827                 // the current key:value pair.
828                 gchar **_filter = NULL;
829                 if ((data->filter_flags&PF_INCLUDE_CHILDREN) == PF_INCLUDE_CHILDREN) {
830                     _filter = data->filter;
831                     data->filter = NULL;
832                 }
833
834                 write_json_proto_node(node_values_list, suffix, write_json_proto_node_children, data);
835
836                 // Put protocol filter back
837                 if ((data->filter_flags&PF_INCLUDE_CHILDREN) == PF_INCLUDE_CHILDREN) {
838                     data->filter = _filter;
839                 }
840             }
841
842             delimiter_needed = TRUE;
843         }
844
845         if (!has_value && !has_children && (data->print_text || (data->print_hex && is_pseudo_text_field))) {
846             if (delimiter_needed) fputs(",\n", data->fh);
847             write_json_proto_node(node_values_list, "", write_json_proto_node_no_value, data);
848             delimiter_needed = TRUE;
849         }
850
851         current_node = current_node->next;
852     }
853
854     data->level--;
855     fputs("\n", data->fh);
856     print_indent(data->level, data->fh);
857     fputs("}", data->fh);
858 }
859
860 /**
861  * Writes a single node as a key:value pair. The value_writer param can be used to specify how the node's value should
862  * be written.
863  * @param node_values_head Linked list containing all nodes associated with the same json key in this object.
864  * @param suffix Suffix that should be added to the json key.
865  * @param value_writer A function which writes the actual values of the node json key.
866  * @param data json writing metadata
867  */
868 static void
869 write_json_proto_node(GSList *node_values_head,
870                       const char *suffix,
871                       proto_node_value_writer value_writer,
872                       write_json_data *data)
873 {
874     // Retrieve json key from first value.
875     proto_node *first_value = (proto_node *) node_values_head->data;
876     const char *json_key = proto_node_to_json_key(first_value);
877
878     print_indent(data->level, data->fh);
879     fputs("\"", data->fh);
880     print_escaped_json(data->fh, json_key);
881     print_escaped_json(data->fh, suffix);
882     fputs("\": ", data->fh);
883
884     write_json_proto_node_value_list(node_values_head, value_writer, data);
885 }
886
887 /**
888  * Writes a list of values of a single json key. If multiple values are passed they are wrapped in a json array.
889  * @param node_values_head Linked list containing all values that should be written.
890  * @param value_writer Function which writes the separate values.
891  * @param data json writing metadata
892  */
893 static void
894 write_json_proto_node_value_list(GSList *node_values_head, proto_node_value_writer value_writer, write_json_data *data)
895 {
896     GSList *current_value = node_values_head;
897
898     // Write directly if only a single value is passed. Wrap in json array otherwise.
899     if (current_value->next == NULL) {
900         value_writer((proto_node *) current_value->data, data);
901     } else {
902         fputs("[\n", data->fh);
903         data->level++;
904
905         while (current_value != NULL) {
906             // Do not print delimiter before first value
907             if (current_value != node_values_head) fputs(",\n", data->fh);
908
909             print_indent(data->level, data->fh);
910             value_writer((proto_node *) current_value->data, data);
911             current_value = current_value->next;
912         }
913
914         data->level--;
915         fputs("\n", data->fh);
916         print_indent(data->level, data->fh);
917         fputs("]", data->fh);
918     }
919 }
920
921 /**
922  * Writes the value for a node that's filtered from the output.
923  */
924 static void
925 write_json_proto_node_filtered(proto_node *node, write_json_data *data)
926 {
927     const char *json_key = proto_node_to_json_key(node);
928
929     fputs("{\n", data->fh);
930     data->level++;
931
932     print_indent(data->level, data->fh);
933     fputs("\"filtered\": ", data->fh);
934     fputs("\"", data->fh);
935     print_escaped_json(data->fh, json_key);
936     fputs("\"\n", data->fh);
937
938     data->level--;
939     print_indent(data->level, data->fh);
940     fputs("}", data->fh);
941 }
942
943 /**
944  * Writes the hex dump of a node. A json array is written containing the hex dump, position, length, bitmask and type of
945  * the node.
946  */
947 static void
948 write_json_proto_node_hex_dump(proto_node *node, write_json_data *data)
949 {
950     field_info *fi = node->finfo;
951
952     fputs("[\"", data->fh);
953
954     if (fi->hfinfo->bitmask!=0) {
955         switch (fi->value.ftype->ftype) {
956             case FT_INT8:
957             case FT_INT16:
958             case FT_INT24:
959             case FT_INT32:
960                 fprintf(data->fh, "%X", (guint) fvalue_get_sinteger(&fi->value));
961                 break;
962             case FT_UINT8:
963             case FT_UINT16:
964             case FT_UINT24:
965             case FT_UINT32:
966                 fprintf(data->fh, "%X", fvalue_get_uinteger(&fi->value));
967                 break;
968             case FT_INT40:
969             case FT_INT48:
970             case FT_INT56:
971             case FT_INT64:
972                 fprintf(data->fh, "%" G_GINT64_MODIFIER "X", fvalue_get_sinteger64(&fi->value));
973                 break;
974             case FT_UINT40:
975             case FT_UINT48:
976             case FT_UINT56:
977             case FT_UINT64:
978             case FT_BOOLEAN:
979                 fprintf(data->fh, "%" G_GINT64_MODIFIER "X", fvalue_get_uinteger64(&fi->value));
980                 break;
981             default:
982                 g_assert_not_reached();
983         }
984     } else {
985         json_write_field_hex_value(data, fi);
986     }
987
988     /* Dump raw hex-encoded dissected information including position, length, bitmask, type */
989     fprintf(data->fh, "\", %" G_GINT32_MODIFIER "d", fi->start);
990     fprintf(data->fh, ", %" G_GINT32_MODIFIER "d", fi->length);
991     fprintf(data->fh, ", %" G_GUINT64_FORMAT, fi->hfinfo->bitmask);
992     fprintf(data->fh, ", %" G_GINT32_MODIFIER "d", (gint32)fi->value.ftype->ftype);
993
994     fputs("]", data->fh);
995 }
996
997 /**
998  * Writes the children of a node. Calls write_json_proto_node_list internally which recursively writes children of nodes
999  * to the output.
1000  */
1001 static void
1002 write_json_proto_node_children(proto_node *node, write_json_data *data)
1003 {
1004     GSList *grouped_children_list = data->node_children_grouper(node);
1005     write_json_proto_node_list(grouped_children_list, data);
1006     g_slist_free_full(grouped_children_list, (GDestroyNotify) g_slist_free);
1007 }
1008
1009 /**
1010  * Writes the value of a node to the output.
1011  */
1012 static void
1013 write_json_proto_node_value(proto_node *node, write_json_data *data)
1014 {
1015     field_info *fi = node->finfo;
1016     // Get the actual value of the node as a string.
1017     char *value_string_repr = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
1018
1019     fputs("\"", data->fh);
1020     print_escaped_json(data->fh, value_string_repr);
1021     fputs("\"", data->fh);
1022
1023     wmem_free(NULL, value_string_repr);
1024 }
1025
1026 /**
1027  * Write the value for a node that has no value and no children. This is the empty string for all nodes except those of
1028  * type FT_PROTOCOL for which the full name is written instead.
1029  */
1030 static void
1031 write_json_proto_node_no_value(proto_node *node, write_json_data *data)
1032 {
1033     field_info *fi = node->finfo;
1034
1035     fputs("\"", data->fh);
1036
1037     if (fi->hfinfo->type == FT_PROTOCOL) {
1038         if (fi->rep) {
1039             print_escaped_json(data->fh, fi->rep->representation);
1040         } else {
1041             gchar label_str[ITEM_LABEL_LENGTH];
1042             proto_item_fill_label(fi, label_str);
1043             print_escaped_json(data->fh, label_str);
1044         }
1045     }
1046
1047     fputs("\"", data->fh);
1048 }
1049
1050 /**
1051  * Groups each child of the node separately.
1052  * @return Linked list where each element is another linked list containing a single node.
1053  */
1054 GSList *
1055 proto_node_group_children_by_unique(proto_node *node) {
1056     GSList *unique_nodes_list = NULL;
1057     proto_node *current_child = node->first_child;
1058
1059     while (current_child != NULL) {
1060         GSList *unique_node = g_slist_prepend(NULL, current_child);
1061         unique_nodes_list = g_slist_prepend(unique_nodes_list, unique_node);
1062         current_child = current_child->next;
1063     }
1064
1065     return g_slist_reverse(unique_nodes_list);
1066 }
1067
1068 /**
1069  * Groups the children of a node by their json key. Children are put in the same group if they have the same json key.
1070  * @return Linked list where each element is another linked list of nodes associated with the same json key.
1071  */
1072 GSList *
1073 proto_node_group_children_by_json_key(proto_node *node)
1074 {
1075     /**
1076      * For each different json key we store a linked list of values corresponding to that json key. These lists are kept
1077      * in both a linked list and a hashmap. The hashmap is used to quickly retrieve the values of a json key. The linked
1078      * list is used to preserve the ordering of keys as they are encountered which is not guaranteed when only using a
1079      * hashmap.
1080      */
1081     GSList *same_key_nodes_list = NULL;
1082     GHashTable *lookup_by_json_key = g_hash_table_new(g_str_hash, g_str_equal);
1083     proto_node *current_child = node->first_child;
1084
1085     /**
1086      * For each child of the node get the key and get the list of values already associated with that key from the
1087      * hashmap. If no list exist yet for that key create a new one and add it to both the linked list and hashmap. If a
1088      * list already exists add the node to that list.
1089      */
1090     while (current_child != NULL) {
1091         char *json_key = (char *) proto_node_to_json_key(current_child);
1092         GSList *json_key_nodes = (GSList *) g_hash_table_lookup(lookup_by_json_key, json_key);
1093
1094         if (json_key_nodes == NULL) {
1095             json_key_nodes = g_slist_append(json_key_nodes, current_child);
1096             // Prepending in single linked list is O(1), appending is O(n). Better to prepend here and reverse at the
1097             // end than potentially looping to the end of the linked list for each child.
1098             same_key_nodes_list = g_slist_prepend(same_key_nodes_list, json_key_nodes);
1099             g_hash_table_insert(lookup_by_json_key, json_key, json_key_nodes);
1100         } else {
1101             // Store and insert value again to circumvent unused_variable warning.
1102             // Append in this case since most value lists will only have a single value.
1103             json_key_nodes = g_slist_append(json_key_nodes, current_child);
1104             g_hash_table_insert(lookup_by_json_key, json_key, json_key_nodes);
1105         }
1106
1107         current_child = current_child->next;
1108     }
1109
1110     // Hash table is not needed anymore since the linked list with the correct ordering is returned.
1111     g_hash_table_destroy(lookup_by_json_key);
1112
1113     return g_slist_reverse(same_key_nodes_list);
1114 }
1115
1116 /**
1117  * Returns the json key of a node. Tries to use the node's abbreviated name. If the abbreviated name is not available
1118  * the representation is used instead.
1119  */
1120 static const char *
1121 proto_node_to_json_key(proto_node *node)
1122 {
1123     const char *json_key;
1124     // Check if node has abbreviated name.
1125     if (node->finfo->hfinfo->id != hf_text_only) {
1126         json_key = node->finfo->hfinfo->abbrev;
1127     } else if (node->finfo->rep != NULL) {
1128         json_key = node->finfo->rep->representation;
1129     } else {
1130         json_key = "";
1131     }
1132
1133     return json_key;
1134 }
1135
1136 static gboolean
1137 ek_check_protocolfilter(gchar **protocolfilter, const char *str)
1138 {
1139     gchar *str_escaped = NULL;
1140     int i;
1141
1142     /* to to thread the '.' and '_' equally. The '.' is replace by print_escaped_ek for '_' */
1143     if (str != NULL && strlen(str) > 0) {
1144         str_escaped = g_strdup(str);
1145
1146         i = 0;
1147         while (str_escaped[i] != '\0') {
1148             if (str_escaped[i] == '.') {
1149                 str_escaped[i] = '_';
1150             }
1151             i++;
1152         }
1153     }
1154
1155     return check_protocolfilter(protocolfilter, str)
1156            || check_protocolfilter(protocolfilter, str_escaped);
1157 }
1158
1159 /**
1160  * Finds a node's descendants to be printed as EK/JSON attributes.
1161  */
1162 static void
1163 write_ek_summary(column_info *cinfo, FILE *fh)
1164 {
1165     gint i;
1166
1167     for (i = 0; i < cinfo->num_cols; i++) {
1168         if (!get_column_visible(i)) continue;
1169         fputs(", \"", fh);
1170         print_escaped_ek(fh, g_ascii_strdown(cinfo->columns[i].col_title, -1));
1171         fputs("\": \"", fh);
1172         print_escaped_json(fh, cinfo->columns[i].col_data);
1173         fputs("\"", fh);
1174     }
1175 }
1176
1177 /* Write out a tree's data, and any child nodes, as JSON for EK */
1178 static void
1179 ek_fill_attr(proto_node *node, GSList **attr_list, GHashTable *attr_table, write_json_data *pdata)
1180 {
1181     field_info *fi         = NULL;
1182     field_info *fi_parent  = NULL;
1183     gchar *node_name       = NULL;
1184     GSList *attr_instances = NULL;
1185
1186     proto_node *current_node = node->first_child;
1187     while (current_node != NULL) {
1188         fi        = PNODE_FINFO(current_node);
1189         fi_parent = PNODE_FINFO(current_node->parent);
1190
1191         /* dissection with an invisible proto tree? */
1192         g_assert(fi);
1193
1194         if (fi_parent == NULL) {
1195             node_name = g_strdup(fi->hfinfo->abbrev);
1196         }
1197         else {
1198             node_name = g_strconcat(fi_parent->hfinfo->abbrev, "_", fi->hfinfo->abbrev, NULL);
1199         }
1200
1201         attr_instances = (GSList *) g_hash_table_lookup(attr_table, node_name);
1202         // First time we encounter this attr
1203         if (attr_instances == NULL) {
1204             attr_instances = g_slist_append(attr_instances, current_node);
1205             *attr_list = g_slist_prepend(*attr_list, attr_instances);
1206         }
1207         else {
1208             attr_instances = g_slist_append(attr_instances, current_node);
1209         }
1210
1211         // Update instance list for this attr in hash table
1212         g_hash_table_insert(attr_table, node_name, attr_instances);
1213
1214         /* Field, recurse through children*/
1215         if (fi->hfinfo->type != FT_PROTOCOL && current_node->first_child != NULL) {
1216             if (pdata->filter != NULL) {
1217                 if (ek_check_protocolfilter(pdata->filter, fi->hfinfo->abbrev)) {
1218                     gchar **_filter = NULL;
1219                     /* Remove protocol filter for children, if children should be included */
1220                     if ((pdata->filter_flags&PF_INCLUDE_CHILDREN) == PF_INCLUDE_CHILDREN) {
1221                         _filter = pdata->filter;
1222                         pdata->filter = NULL;
1223                     }
1224
1225                     ek_fill_attr(current_node, attr_list, attr_table, pdata);
1226
1227                     /* Put protocol filter back */
1228                     if ((pdata->filter_flags&PF_INCLUDE_CHILDREN) == PF_INCLUDE_CHILDREN) {
1229                         pdata->filter = _filter;
1230                     }
1231                 }
1232                 else {
1233                     // Don't traverse children if filtered out
1234                 }
1235             }
1236             else {
1237                 ek_fill_attr(current_node, attr_list, attr_table, pdata);
1238             }
1239         }
1240         else {
1241             // Will descend into object at another point
1242         }
1243
1244         current_node = current_node->next;
1245     }
1246 }
1247
1248 static void
1249 ek_write_name(proto_node *pnode, write_json_data *pdata)
1250 {
1251     field_info *fi        = PNODE_FINFO(pnode);
1252     field_info *fi_parent = PNODE_FINFO(pnode->parent);
1253
1254     if (fi_parent != NULL) {
1255         print_escaped_ek(pdata->fh, fi_parent->hfinfo->abbrev);
1256         fputs("_", pdata->fh);
1257     }
1258     print_escaped_ek(pdata->fh, fi->hfinfo->abbrev);
1259 }
1260
1261 static void
1262 ek_write_hex(field_info *fi, write_json_data *pdata)
1263 {
1264     if (fi->hfinfo->bitmask!=0) {
1265         switch (fi->value.ftype->ftype) {
1266             case FT_INT8:
1267             case FT_INT16:
1268             case FT_INT24:
1269             case FT_INT32:
1270                 fprintf(pdata->fh, "%X", (guint) fvalue_get_sinteger(&fi->value));
1271                 break;
1272             case FT_UINT8:
1273             case FT_UINT16:
1274             case FT_UINT24:
1275             case FT_UINT32:
1276                 fprintf(pdata->fh, "%X", fvalue_get_uinteger(&fi->value));
1277                 break;
1278             case FT_INT40:
1279             case FT_INT48:
1280             case FT_INT56:
1281             case FT_INT64:
1282                 fprintf(pdata->fh, "%" G_GINT64_MODIFIER "X", fvalue_get_sinteger64(&fi->value));
1283                 break;
1284             case FT_UINT40:
1285             case FT_UINT48:
1286             case FT_UINT56:
1287             case FT_UINT64:
1288             case FT_BOOLEAN:
1289                 fprintf(pdata->fh, "%" G_GINT64_MODIFIER "X", fvalue_get_uinteger64(&fi->value));
1290                 break;
1291             default:
1292                 g_assert_not_reached();
1293         }
1294     }
1295     else {
1296         json_write_field_hex_value(pdata, fi);
1297     }
1298 }
1299
1300 static void
1301 ek_write_field_value(field_info *fi, write_json_data *pdata)
1302 {
1303     gchar label_str[ITEM_LABEL_LENGTH];
1304     char *dfilter_string;
1305
1306     /* Text label */
1307     if (fi->hfinfo->id == hf_text_only && fi->rep) {
1308         print_escaped_json(pdata->fh, fi->rep->representation);
1309     }
1310     else {
1311         /* show, value, and unmaskedvalue attributes */
1312         if (fi->hfinfo->type == FT_PROTOCOL) {
1313             if (fi->rep) {
1314                 print_escaped_json(pdata->fh, fi->rep->representation);
1315             }
1316             else {
1317                 proto_item_fill_label(fi, label_str);
1318                 print_escaped_json(pdata->fh, label_str);
1319             }
1320         }
1321         else if (fi->hfinfo->type != FT_NONE) {
1322             dfilter_string = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
1323             if (dfilter_string != NULL) {
1324                 print_escaped_json(pdata->fh, dfilter_string);
1325             }
1326             wmem_free(NULL, dfilter_string);
1327         }
1328     }
1329 }
1330
1331 static void
1332 ek_write_attr_hex(GSList *attr_instances, write_json_data *pdata)
1333 {
1334     GSList *current_node = attr_instances;
1335     proto_node *pnode    = (proto_node *) current_node->data;
1336     field_info *fi       = NULL;
1337
1338     // Raw name
1339     fputs("\"", pdata->fh);
1340     ek_write_name(pnode, pdata);
1341     fputs("_raw\": ", pdata->fh);
1342
1343     if (g_slist_length(attr_instances) > 1) {
1344         fputs("[", pdata->fh);
1345     }
1346
1347     // Raw value(s)
1348     while (current_node != NULL) {
1349         pnode = (proto_node *) current_node->data;
1350         fi    = PNODE_FINFO(pnode);
1351
1352         fputs("\"", pdata->fh);
1353         ek_write_hex(fi, pdata);
1354         fputs("\"", pdata->fh);
1355
1356         current_node = current_node->next;
1357         if (current_node != NULL) {
1358             fputs(",", pdata->fh);
1359         }
1360     }
1361
1362     if (g_slist_length(attr_instances) > 1) {
1363         fputs("]", pdata->fh);
1364     }
1365 }
1366
1367 static void
1368 ek_write_attr(GSList *attr_instances, write_json_data *pdata)
1369 {
1370     GSList *current_node = attr_instances;
1371     proto_node *pnode    = (proto_node *) current_node->data;
1372     field_info *fi       = PNODE_FINFO(pnode);
1373
1374     // Hex dump -x
1375     if (pdata->print_hex && fi && fi->length > 0 && fi->hfinfo->id != hf_text_only) {
1376         ek_write_attr_hex(attr_instances, pdata);
1377
1378         fputs(",", pdata->fh);
1379     }
1380
1381     // Print attr name
1382     fputs("\"", pdata->fh);
1383     ek_write_name(pnode, pdata);
1384     fputs("\": ", pdata->fh);
1385
1386     if (g_slist_length(attr_instances) > 1) {
1387         fputs("[", pdata->fh);
1388     }
1389
1390     while (current_node != NULL) {
1391         pnode = (proto_node *) current_node->data;
1392         fi    = PNODE_FINFO(pnode);
1393
1394         /* Field */
1395         if (fi->hfinfo->type != FT_PROTOCOL) {
1396             fputs("\"", pdata->fh);
1397
1398             if (pdata->filter != NULL
1399                 && !ek_check_protocolfilter(pdata->filter, fi->hfinfo->abbrev)) {
1400
1401                 /* print dummy field */
1402                 fputs("\",\"filtered\": \"", pdata->fh);
1403                 print_escaped_ek(pdata->fh, fi->hfinfo->abbrev);
1404             }
1405             else {
1406                 ek_write_field_value(fi, pdata);
1407             }
1408
1409             fputs("\"", pdata->fh);
1410         }
1411         /* Object */
1412         else {
1413             fputs("{", pdata->fh);
1414
1415             if (pdata->filter != NULL) {
1416                 if (ek_check_protocolfilter(pdata->filter, fi->hfinfo->abbrev)) {
1417                     gchar **_filter = NULL;
1418                     /* Remove protocol filter for children, if children should be included */
1419                     if ((pdata->filter_flags&PF_INCLUDE_CHILDREN) == PF_INCLUDE_CHILDREN) {
1420                         _filter = pdata->filter;
1421                         pdata->filter = NULL;
1422                     }
1423
1424                     proto_tree_write_node_ek(pnode, pdata);
1425
1426                     /* Put protocol filter back */
1427                     if ((pdata->filter_flags&PF_INCLUDE_CHILDREN) == PF_INCLUDE_CHILDREN) {
1428                         pdata->filter = _filter;
1429                     }
1430                 } else {
1431                     /* print dummy field */
1432                     fputs("\"filtered\": \"", pdata->fh);
1433                     print_escaped_ek(pdata->fh, fi->hfinfo->abbrev);
1434                     fputs("\"", pdata->fh);
1435                 }
1436             }
1437             else {
1438                 proto_tree_write_node_ek(pnode, pdata);
1439             }
1440
1441             fputs("}", pdata->fh);
1442         }
1443
1444         current_node = current_node->next;
1445         if (current_node != NULL) {
1446             fputs(",", pdata->fh);
1447         }
1448     }
1449
1450     if (g_slist_length(attr_instances) > 1) {
1451         fputs("]", pdata->fh);
1452     }
1453 }
1454
1455 /* Write out a tree's data, and any child nodes, as JSON for EK */
1456 static void
1457 proto_tree_write_node_ek(proto_node *node, write_json_data *pdata)
1458 {
1459     GSList *attr_list  = NULL;
1460     GHashTable *attr_table  = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
1461
1462     ek_fill_attr(node, &attr_list, attr_table, pdata);
1463
1464     g_hash_table_destroy(attr_table);
1465
1466     // Print attributes
1467     GSList *current_attr = g_slist_reverse(attr_list);
1468     while (current_attr != NULL) {
1469         GSList *attr_instances = (GSList *) current_attr->data;
1470
1471         ek_write_attr(attr_instances, pdata);
1472
1473         current_attr = current_attr->next;
1474         if (current_attr != NULL) {
1475             fputs(",", pdata->fh);
1476         }
1477     }
1478
1479     g_slist_free_full(attr_list, (GDestroyNotify) g_slist_free);
1480 }
1481
1482 /* Print info for a 'geninfo' pseudo-protocol. This is required by
1483  * the PDML spec. The information is contained in Wireshark's 'frame' protocol,
1484  * but we produce a 'geninfo' protocol in the PDML to conform to spec.
1485  * The 'frame' protocol follows the 'geninfo' protocol in the PDML. */
1486 static void
1487 print_pdml_geninfo(epan_dissect_t *edt, FILE *fh)
1488 {
1489     guint32     num, len, caplen;
1490     GPtrArray  *finfo_array;
1491     field_info *frame_finfo;
1492     gchar      *tmp;
1493
1494     /* Get frame protocol's finfo. */
1495     finfo_array = proto_find_first_finfo(edt->tree, proto_frame);
1496     if (g_ptr_array_len(finfo_array) < 1) {
1497         return;
1498     }
1499     frame_finfo = (field_info *)finfo_array->pdata[0];
1500     g_ptr_array_free(finfo_array, TRUE);
1501
1502     /* frame.number, packet_info.num */
1503     num = edt->pi.num;
1504
1505     /* frame.frame_len, packet_info.frame_data->pkt_len */
1506     len = edt->pi.fd->pkt_len;
1507
1508     /* frame.cap_len --> packet_info.frame_data->cap_len */
1509     caplen = edt->pi.fd->cap_len;
1510
1511     /* Print geninfo start */
1512     fprintf(fh,
1513             "  <proto name=\"geninfo\" pos=\"0\" showname=\"General information\" size=\"%d\">\n",
1514             frame_finfo->length);
1515
1516     /* Print geninfo.num */
1517     fprintf(fh,
1518             "    <field name=\"num\" pos=\"0\" show=\"%u\" showname=\"Number\" value=\"%x\" size=\"%d\"/>\n",
1519             num, num, frame_finfo->length);
1520
1521     /* Print geninfo.len */
1522     fprintf(fh,
1523             "    <field name=\"len\" pos=\"0\" show=\"%u\" showname=\"Frame Length\" value=\"%x\" size=\"%d\"/>\n",
1524             len, len, frame_finfo->length);
1525
1526     /* Print geninfo.caplen */
1527     fprintf(fh,
1528             "    <field name=\"caplen\" pos=\"0\" show=\"%u\" showname=\"Captured Length\" value=\"%x\" size=\"%d\"/>\n",
1529             caplen, caplen, frame_finfo->length);
1530
1531     tmp = abs_time_to_str(NULL, &edt->pi.abs_ts, ABSOLUTE_TIME_LOCAL, TRUE);
1532
1533     /* Print geninfo.timestamp */
1534     fprintf(fh,
1535             "    <field name=\"timestamp\" pos=\"0\" show=\"%s\" showname=\"Captured Time\" value=\"%d.%09d\" size=\"%d\"/>\n",
1536             tmp, (int)edt->pi.abs_ts.secs, edt->pi.abs_ts.nsecs, frame_finfo->length);
1537
1538     wmem_free(NULL, tmp);
1539
1540     /* Print geninfo end */
1541     fprintf(fh,
1542             "  </proto>\n");
1543 }
1544
1545 void
1546 write_pdml_finale(FILE *fh)
1547 {
1548     fputs("</pdml>\n", fh);
1549 }
1550
1551
1552
1553 void
1554 write_psml_preamble(column_info *cinfo, FILE *fh)
1555 {
1556     gint i;
1557
1558     fprintf(fh, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
1559     fprintf(fh, "<psml version=\"" PSML_VERSION "\" creator=\"%s/%s\">\n", PACKAGE, VERSION);
1560     fprintf(fh, "<structure>\n");
1561
1562     for (i = 0; i < cinfo->num_cols; i++) {
1563         if (!get_column_visible(i)) continue;
1564         fprintf(fh, "<section>");
1565         print_escaped_xml(fh, cinfo->columns[i].col_title);
1566         fprintf(fh, "</section>\n");
1567     }
1568
1569     fprintf(fh, "</structure>\n\n");
1570 }
1571
1572 void
1573 write_psml_columns(epan_dissect_t *edt, FILE *fh, gboolean use_color)
1574 {
1575     gint i;
1576     const color_filter_t *cfp = edt->pi.fd->color_filter;
1577
1578     if (use_color && (cfp != NULL)) {
1579         fprintf(fh, "<packet foreground='#%06x' background='#%06x'>\n",
1580             color_t_to_rgb(&cfp->fg_color),
1581             color_t_to_rgb(&cfp->bg_color));
1582     }
1583     else {
1584         fprintf(fh, "<packet>\n");
1585     }
1586
1587     for (i = 0; i < edt->pi.cinfo->num_cols; i++) {
1588         if (!get_column_visible(i)) continue;
1589         fprintf(fh, "<section>");
1590         print_escaped_xml(fh, edt->pi.cinfo->columns[i].col_data);
1591         fprintf(fh, "</section>\n");
1592     }
1593
1594     fprintf(fh, "</packet>\n\n");
1595 }
1596
1597 void
1598 write_psml_finale(FILE *fh)
1599 {
1600     fputs("</psml>\n", fh);
1601 }
1602
1603 static gchar *csv_massage_str(const gchar *source, const gchar *exceptions)
1604 {
1605     gchar *csv_str;
1606     gchar *tmp_str;
1607
1608     /* In general, our output for any field can contain Unicode characters,
1609        so g_strescape (which escapes any non-ASCII) is the wrong thing to do.
1610        Unfortunately glib doesn't appear to provide g_unicode_strescape()... */
1611     csv_str = g_strescape(source, exceptions);
1612     tmp_str = csv_str;
1613     /* Locate the UTF-8 right arrow character and replace it by an ASCII equivalent */
1614     while ( (tmp_str = strstr(tmp_str, UTF8_RIGHTWARDS_ARROW)) != NULL ) {
1615         tmp_str[0] = ' ';
1616         tmp_str[1] = '>';
1617         tmp_str[2] = ' ';
1618     }
1619     tmp_str = csv_str;
1620     while ( (tmp_str = strstr(tmp_str, "\\\"")) != NULL )
1621         *tmp_str = '\"';
1622     return csv_str;
1623 }
1624
1625 static void csv_write_str(const char *str, char sep, FILE *fh)
1626 {
1627     gchar *csv_str;
1628
1629     /* Do not escape the UTF-8 right arrow character */
1630     csv_str = csv_massage_str(str, UTF8_RIGHTWARDS_ARROW);
1631     fprintf(fh, "\"%s\"%c", csv_str, sep);
1632     g_free(csv_str);
1633 }
1634
1635 void
1636 write_csv_column_titles(column_info *cinfo, FILE *fh)
1637 {
1638     gint i;
1639
1640     for (i = 0; i < cinfo->num_cols - 1; i++) {
1641         if (!get_column_visible(i)) continue;
1642         csv_write_str(cinfo->columns[i].col_title, ',', fh);
1643     }
1644     csv_write_str(cinfo->columns[i].col_title, '\n', fh);
1645 }
1646
1647 void
1648 write_csv_columns(epan_dissect_t *edt, FILE *fh)
1649 {
1650     gint i;
1651
1652     for (i = 0; i < edt->pi.cinfo->num_cols - 1; i++) {
1653         if (!get_column_visible(i)) continue;
1654         csv_write_str(edt->pi.cinfo->columns[i].col_data, ',', fh);
1655     }
1656     csv_write_str(edt->pi.cinfo->columns[i].col_data, '\n', fh);
1657 }
1658
1659 void
1660 write_carrays_hex_data(guint32 num, FILE *fh, epan_dissect_t *edt)
1661 {
1662     guint32       i = 0, src_num = 0;
1663     GSList       *src_le;
1664     tvbuff_t     *tvb;
1665     char         *name;
1666     const guchar *cp;
1667     guint         length;
1668     char          ascii[9];
1669     struct data_source *src;
1670
1671     for (src_le = edt->pi.data_src; src_le != NULL; src_le = src_le->next) {
1672         memset(ascii, 0, sizeof(ascii));
1673         src = (struct data_source *)src_le->data;
1674         tvb = get_data_source_tvb(src);
1675         length = tvb_captured_length(tvb);
1676         if (length == 0)
1677             continue;
1678
1679         cp = tvb_get_ptr(tvb, 0, length);
1680
1681         name = get_data_source_name(src);
1682         if (name) {
1683             fprintf(fh, "/* %s */\n", name);
1684             wmem_free(NULL, name);
1685         }
1686         if (src_num) {
1687             fprintf(fh, "static const unsigned char pkt%u_%u[%u] = {\n",
1688                     num, src_num, length);
1689         } else {
1690             fprintf(fh, "static const unsigned char pkt%u[%u] = {\n",
1691                     num, length);
1692         }
1693         src_num++;
1694
1695         for (i = 0; i < length; i++) {
1696             fprintf(fh, "0x%02x", *(cp + i));
1697             ascii[i % 8] = g_ascii_isprint(*(cp + i)) ? *(cp + i) : '.';
1698
1699             if (i == (length - 1)) {
1700                 guint rem;
1701                 rem = length % 8;
1702                 if (rem) {
1703                     guint j;
1704                     for ( j = 0; j < 8 - rem; j++ )
1705                         fprintf(fh, "      ");
1706                 }
1707                 fprintf(fh, "  /* %s */\n};\n\n", ascii);
1708                 break;
1709             }
1710
1711             if (!((i + 1) % 8)) {
1712                 fprintf(fh, ", /* %s */\n", ascii);
1713                 memset(ascii, 0, sizeof(ascii));
1714             }
1715             else {
1716                 fprintf(fh, ", ");
1717             }
1718         }
1719     }
1720 }
1721
1722 /*
1723  * Find the data source for a specified field, and return a pointer
1724  * to the data in it. Returns NULL if the data is out of bounds.
1725  */
1726 /* XXX: What am I missing ?
1727  *      Why bother searching for fi->ds_tvb for the matching tvb
1728  *       in the data_source list ?
1729  *      IOW: Why not just use fi->ds_tvb for the arg to tvb_get_ptr() ?
1730  */
1731
1732 static const guint8 *
1733 get_field_data(GSList *src_list, field_info *fi)
1734 {
1735     GSList   *src_le;
1736     tvbuff_t *src_tvb;
1737     gint      length, tvbuff_length;
1738     struct data_source *src;
1739
1740     for (src_le = src_list; src_le != NULL; src_le = src_le->next) {
1741         src = (struct data_source *)src_le->data;
1742         src_tvb = get_data_source_tvb(src);
1743         if (fi->ds_tvb == src_tvb) {
1744             /*
1745              * Found it.
1746              *
1747              * XXX - a field can have a length that runs past
1748              * the end of the tvbuff.  Ideally, that should
1749              * be fixed when adding an item to the protocol
1750              * tree, but checking the length when doing
1751              * that could be expensive.  Until we fix that,
1752              * we'll do the check here.
1753              */
1754             tvbuff_length = tvb_captured_length_remaining(src_tvb,
1755                                                  fi->start);
1756             if (tvbuff_length < 0) {
1757                 return NULL;
1758             }
1759             length = fi->length;
1760             if (length > tvbuff_length)
1761                 length = tvbuff_length;
1762             return tvb_get_ptr(src_tvb, fi->start, length);
1763         }
1764     }
1765     g_assert_not_reached();
1766     return NULL;  /* not found */
1767 }
1768
1769 /* Print a string, escaping out certain characters that need to
1770  * escaped out for XML. */
1771 static void
1772 print_escaped_xml(FILE *fh, const char *unescaped_string)
1773 {
1774     const char *p;
1775     char        temp_str[8];
1776
1777     if (fh == NULL || unescaped_string == NULL) {
1778         return;
1779     }
1780
1781     for (p = unescaped_string; *p != '\0'; p++) {
1782         switch (*p) {
1783         case '&':
1784             fputs("&amp;", fh);
1785             break;
1786         case '<':
1787             fputs("&lt;", fh);
1788             break;
1789         case '>':
1790             fputs("&gt;", fh);
1791             break;
1792         case '"':
1793             fputs("&quot;", fh);
1794             break;
1795         case '\'':
1796             fputs("&#x27;", fh);
1797             break;
1798         default:
1799             if (g_ascii_isprint(*p))
1800                 fputc(*p, fh);
1801             else {
1802                 g_snprintf(temp_str, sizeof(temp_str), "\\x%x", (guint8)*p);
1803                 fputs(temp_str, fh);
1804             }
1805         }
1806     }
1807 }
1808
1809 static void
1810 print_escaped_bare(FILE *fh, const char *unescaped_string, gboolean change_dot)
1811 {
1812     const char *p;
1813     char        temp_str[8];
1814
1815     if (fh == NULL || unescaped_string == NULL) {
1816         return;
1817     }
1818
1819     for (p = unescaped_string; *p != '\0'; p++) {
1820         switch (*p) {
1821         case '"':
1822             fputs("\\\"", fh);
1823             break;
1824         case '\\':
1825             fputs("\\\\", fh);
1826             break;
1827         case '/':
1828             fputs("\\/", fh);
1829             break;
1830         case '\b':
1831             fputs("\\b", fh);
1832             break;
1833         case '\f':
1834             fputs("\\f", fh);
1835             break;
1836         case '\n':
1837             fputs("\\n", fh);
1838             break;
1839         case '\r':
1840             fputs("\\r", fh);
1841             break;
1842         case '\t':
1843             fputs("\\t", fh);
1844             break;
1845         case '.':
1846             if (change_dot)
1847                 fputs("_", fh);
1848             else
1849                 fputs(".", fh);
1850             break;
1851         default:
1852             if (g_ascii_isprint(*p))
1853                 fputc(*p, fh);
1854             else {
1855                 g_snprintf(temp_str, sizeof(temp_str), "\\u00%02x", (guint8)*p);
1856                 fputs(temp_str, fh);
1857             }
1858         }
1859     }
1860 }
1861
1862 /* Print a string, escaping out certain characters that need to
1863  * escaped out for JSON. */
1864 static void
1865 print_escaped_json(FILE *fh, const char *unescaped_string)
1866 {
1867     print_escaped_bare(fh, unescaped_string, FALSE);
1868 }
1869
1870 /* Print a string, escaping out certain characters that need to
1871  * escaped out for Elasticsearch title. */
1872 static void
1873 print_escaped_ek(FILE *fh, const char *unescaped_string)
1874 {
1875     print_escaped_bare(fh, unescaped_string, TRUE);
1876 }
1877
1878 static void
1879 pdml_write_field_hex_value(write_pdml_data *pdata, field_info *fi)
1880 {
1881     int           i;
1882     const guint8 *pd;
1883
1884     if (!fi->ds_tvb)
1885         return;
1886
1887     if (fi->length > tvb_captured_length_remaining(fi->ds_tvb, fi->start)) {
1888         fprintf(pdata->fh, "field length invalid!");
1889         return;
1890     }
1891
1892     /* Find the data for this field. */
1893     pd = get_field_data(pdata->src_list, fi);
1894
1895     if (pd) {
1896         /* Print a simple hex dump */
1897         for (i = 0 ; i < fi->length; i++) {
1898             fprintf(pdata->fh, "%02x", pd[i]);
1899         }
1900     }
1901 }
1902
1903 static void
1904 json_write_field_hex_value(write_json_data *pdata, field_info *fi)
1905 {
1906     int           i;
1907     const guint8 *pd;
1908
1909     if (!fi->ds_tvb)
1910         return;
1911
1912     if (fi->length > tvb_captured_length_remaining(fi->ds_tvb, fi->start)) {
1913         fprintf(pdata->fh, "field length invalid!");
1914         return;
1915     }
1916
1917     /* Find the data for this field. */
1918     pd = get_field_data(pdata->src_list, fi);
1919
1920     if (pd) {
1921         /* Print a simple hex dump */
1922         for (i = 0 ; i < fi->length; i++) {
1923             fprintf(pdata->fh, "%02x", pd[i]);
1924         }
1925     }
1926 }
1927
1928 gboolean
1929 print_hex_data(print_stream_t *stream, epan_dissect_t *edt)
1930 {
1931     gboolean      multiple_sources;
1932     GSList       *src_le;
1933     tvbuff_t     *tvb;
1934     char         *line, *name;
1935     const guchar *cp;
1936     guint         length;
1937     struct data_source *src;
1938
1939     /*
1940      * Set "multiple_sources" iff this frame has more than one
1941      * data source; if it does, we need to print the name of
1942      * the data source before printing the data from the
1943      * data source.
1944      */
1945     multiple_sources = (edt->pi.data_src->next != NULL);
1946
1947     for (src_le = edt->pi.data_src; src_le != NULL;
1948          src_le = src_le->next) {
1949         src = (struct data_source *)src_le->data;
1950         tvb = get_data_source_tvb(src);
1951         if (multiple_sources) {
1952             name = get_data_source_name(src);
1953             line = g_strdup_printf("%s:", name);
1954             wmem_free(NULL, name);
1955             print_line(stream, 0, line);
1956             g_free(line);
1957         }
1958         length = tvb_captured_length(tvb);
1959         if (length == 0)
1960             return TRUE;
1961         cp = tvb_get_ptr(tvb, 0, length);
1962         if (!print_hex_data_buffer(stream, cp, length,
1963                                    (packet_char_enc)edt->pi.fd->flags.encoding))
1964             return FALSE;
1965     }
1966     return TRUE;
1967 }
1968
1969 /*
1970  * This routine is based on a routine created by Dan Lasley
1971  * <DLASLEY@PROMUS.com>.
1972  *
1973  * It was modified for Wireshark by Gilbert Ramirez and others.
1974  */
1975
1976 #define MAX_OFFSET_LEN   8       /* max length of hex offset of bytes */
1977 #define BYTES_PER_LINE  16      /* max byte values printed on a line */
1978 #define HEX_DUMP_LEN    (BYTES_PER_LINE*3)
1979                                 /* max number of characters hex dump takes -
1980                                    2 digits plus trailing blank */
1981 #define DATA_DUMP_LEN   (HEX_DUMP_LEN + 2 + BYTES_PER_LINE)
1982                                 /* number of characters those bytes take;
1983                                    3 characters per byte of hex dump,
1984                                    2 blanks separating hex from ASCII,
1985                                    1 character per byte of ASCII dump */
1986 #define MAX_LINE_LEN    (MAX_OFFSET_LEN + 2 + DATA_DUMP_LEN)
1987                                 /* number of characters per line;
1988                                    offset, 2 blanks separating offset
1989                                    from data dump, data dump */
1990
1991 static gboolean
1992 print_hex_data_buffer(print_stream_t *stream, const guchar *cp,
1993                       guint length, packet_char_enc encoding)
1994 {
1995     register unsigned int ad, i, j, k, l;
1996     guchar                c;
1997     gchar                 line[MAX_LINE_LEN + 1];
1998     unsigned int          use_digits;
1999
2000     static gchar binhex[16] = {
2001         '0', '1', '2', '3', '4', '5', '6', '7',
2002         '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
2003
2004     /*
2005      * How many of the leading digits of the offset will we supply?
2006      * We always supply at least 4 digits, but if the maximum offset
2007      * won't fit in 4 digits, we use as many digits as will be needed.
2008      */
2009     if (((length - 1) & 0xF0000000) != 0)
2010         use_digits = 8; /* need all 8 digits */
2011     else if (((length - 1) & 0x0F000000) != 0)
2012         use_digits = 7; /* need 7 digits */
2013     else if (((length - 1) & 0x00F00000) != 0)
2014         use_digits = 6; /* need 6 digits */
2015     else if (((length - 1) & 0x000F0000) != 0)
2016         use_digits = 5; /* need 5 digits */
2017     else
2018         use_digits = 4; /* we'll supply 4 digits */
2019
2020     ad = 0;
2021     i = 0;
2022     j = 0;
2023     k = 0;
2024     while (i < length) {
2025         if ((i & 15) == 0) {
2026             /*
2027              * Start of a new line.
2028              */
2029             j = 0;
2030             l = use_digits;
2031             do {
2032                 l--;
2033                 c = (ad >> (l*4)) & 0xF;
2034                 line[j++] = binhex[c];
2035             } while (l != 0);
2036             line[j++] = ' ';
2037             line[j++] = ' ';
2038             memset(line+j, ' ', DATA_DUMP_LEN);
2039
2040             /*
2041              * Offset in line of ASCII dump.
2042              */
2043             k = j + HEX_DUMP_LEN + 2;
2044         }
2045         c = *cp++;
2046         line[j++] = binhex[c>>4];
2047         line[j++] = binhex[c&0xf];
2048         j++;
2049         if (encoding == PACKET_CHAR_ENC_CHAR_EBCDIC) {
2050             c = EBCDIC_to_ASCII1(c);
2051         }
2052         line[k++] = ((c >= ' ') && (c < 0x7f)) ? c : '.';
2053         i++;
2054         if (((i & 15) == 0) || (i == length)) {
2055             /*
2056              * We'll be starting a new line, or
2057              * we're finished printing this buffer;
2058              * dump out the line we've constructed,
2059              * and advance the offset.
2060              */
2061             line[k] = '\0';
2062             if (!print_line(stream, 0, line))
2063                 return FALSE;
2064             ad += 16;
2065         }
2066     }
2067     return TRUE;
2068 }
2069
2070 gsize output_fields_num_fields(output_fields_t* fields)
2071 {
2072     g_assert(fields);
2073
2074     if (NULL == fields->fields) {
2075         return 0;
2076     } else {
2077         return fields->fields->len;
2078     }
2079 }
2080
2081 void output_fields_free(output_fields_t* fields)
2082 {
2083     g_assert(fields);
2084
2085     if (NULL != fields->fields) {
2086         gsize i;
2087
2088         if (NULL != fields->field_indicies) {
2089             /* Keys are stored in fields->fields, values are
2090              * integers.
2091              */
2092             g_hash_table_destroy(fields->field_indicies);
2093         }
2094
2095         if (NULL != fields->field_values) {
2096             g_free(fields->field_values);
2097         }
2098
2099         for(i = 0; i < fields->fields->len; ++i) {
2100             gchar* field = (gchar *)g_ptr_array_index(fields->fields,i);
2101             g_free(field);
2102         }
2103         g_ptr_array_free(fields->fields, TRUE);
2104     }
2105
2106     g_free(fields);
2107 }
2108
2109 #define COLUMN_FIELD_FILTER  "_ws.col."
2110
2111 void output_fields_add(output_fields_t *fields, const gchar *field)
2112 {
2113     gchar *field_copy;
2114
2115     g_assert(fields);
2116     g_assert(field);
2117
2118
2119     if (NULL == fields->fields) {
2120         fields->fields = g_ptr_array_new();
2121     }
2122
2123     field_copy = g_strdup(field);
2124
2125     g_ptr_array_add(fields->fields, field_copy);
2126
2127     /* See if we have a column as a field entry */
2128     if (!strncmp(field, COLUMN_FIELD_FILTER, strlen(COLUMN_FIELD_FILTER)))
2129         fields->includes_col_fields = TRUE;
2130
2131 }
2132
2133 static void
2134 output_field_check(void *data, void *user_data)
2135 {
2136     gchar *field = (gchar *)data;
2137     GSList **invalid_fields = (GSList **)user_data;
2138
2139     if (!strncmp(field, COLUMN_FIELD_FILTER, strlen(COLUMN_FIELD_FILTER)))
2140         return;
2141
2142     if (!proto_registrar_get_byname(field)) {
2143         *invalid_fields = g_slist_prepend(*invalid_fields, field);
2144     }
2145
2146 }
2147
2148 GSList *
2149 output_fields_valid(output_fields_t *fields)
2150 {
2151     GSList *invalid_fields = NULL;
2152     if (fields->fields == NULL) {
2153         return NULL;
2154     }
2155
2156     g_ptr_array_foreach(fields->fields, output_field_check, &invalid_fields);
2157
2158     return invalid_fields;
2159 }
2160
2161 gboolean output_fields_set_option(output_fields_t *info, gchar *option)
2162 {
2163     const gchar *option_name;
2164     const gchar *option_value;
2165
2166     g_assert(info);
2167     g_assert(option);
2168
2169     if ('\0' == *option) {
2170         return FALSE; /* this happens if we're called from tshark -E '' */
2171     }
2172     option_name = strtok(option, "=");
2173     if (!option_name) {
2174         return FALSE;
2175     }
2176     option_value = option + strlen(option_name) + 1;
2177     if (*option_value == '\0') {
2178         return FALSE;
2179     }
2180
2181     if (0 == strcmp(option_name, "header")) {
2182         switch (*option_value) {
2183         case 'n':
2184             info->print_header = FALSE;
2185             break;
2186         case 'y':
2187             info->print_header = TRUE;
2188             break;
2189         default:
2190             return FALSE;
2191         }
2192         return TRUE;
2193     }
2194     else if (0 == strcmp(option_name, "separator")) {
2195         switch (*option_value) {
2196         case '/':
2197             switch (*++option_value) {
2198             case 't':
2199                 info->separator = '\t';
2200                 break;
2201             case 's':
2202                 info->separator = ' ';
2203                 break;
2204             default:
2205                 info->separator = '\\';
2206             }
2207             break;
2208         default:
2209             info->separator = *option_value;
2210             break;
2211         }
2212         return TRUE;
2213     }
2214     else if (0 == strcmp(option_name, "occurrence")) {
2215         switch (*option_value) {
2216         case 'f':
2217         case 'l':
2218         case 'a':
2219             info->occurrence = *option_value;
2220             break;
2221         default:
2222             return FALSE;
2223         }
2224         return TRUE;
2225     }
2226     else if (0 == strcmp(option_name, "aggregator")) {
2227         switch (*option_value) {
2228         case '/':
2229             switch (*++option_value) {
2230             case 's':
2231                 info->aggregator = ' ';
2232                 break;
2233             default:
2234                 info->aggregator = '\\';
2235             }
2236             break;
2237         default:
2238             info->aggregator = *option_value;
2239             break;
2240         }
2241         return TRUE;
2242     }
2243     else if (0 == strcmp(option_name, "quote")) {
2244         switch (*option_value) {
2245         case 'd':
2246             info->quote = '"';
2247             break;
2248         case 's':
2249             info->quote = '\'';
2250             break;
2251         case 'n':
2252             info->quote = '\0';
2253             break;
2254         default:
2255             info->quote = '\0';
2256             return FALSE;
2257         }
2258         return TRUE;
2259     }
2260     else if (0 == strcmp(option_name, "bom")) {
2261         switch (*option_value) {
2262         case 'n':
2263             info->print_bom = FALSE;
2264             break;
2265         case 'y':
2266             info->print_bom = TRUE;
2267             break;
2268         default:
2269             return FALSE;
2270         }
2271         return TRUE;
2272     }
2273
2274     return FALSE;
2275 }
2276
2277 void output_fields_list_options(FILE *fh)
2278 {
2279     fprintf(fh, "TShark: The available options for field output \"E\" are:\n");
2280     fputs("bom=y|n    Prepend output with the UTF-8 BOM (def: N: no)\n", fh);
2281     fputs("header=y|n    Print field abbreviations as first line of output (def: N: no)\n", fh);
2282     fputs("separator=/t|/s|<character>   Set the separator to use;\n     \"/t\" = tab, \"/s\" = space (def: /t: tab)\n", fh);
2283     fputs("occurrence=f|l|a  Select the occurrence of a field to use;\n     \"f\" = first, \"l\" = last, \"a\" = all (def: a: all)\n", fh);
2284     fputs("aggregator=,|/s|<character>   Set the aggregator to use;\n     \",\" = comma, \"/s\" = space (def: ,: comma)\n", fh);
2285     fputs("quote=d|s|n   Print either d: double-quotes, s: single quotes or \n     n: no quotes around field values (def: n: none)\n", fh);
2286 }
2287
2288 gboolean output_fields_has_cols(output_fields_t* fields)
2289 {
2290     g_assert(fields);
2291     return fields->includes_col_fields;
2292 }
2293
2294 void write_fields_preamble(output_fields_t* fields, FILE *fh)
2295 {
2296     gsize i;
2297
2298     g_assert(fields);
2299     g_assert(fh);
2300     g_assert(fields->fields);
2301
2302     if (fields->print_bom) {
2303         fputs(UTF8_BOM, fh);
2304     }
2305
2306
2307     if (!fields->print_header) {
2308         return;
2309     }
2310
2311     for(i = 0; i < fields->fields->len; ++i) {
2312         const gchar* field = (const gchar *)g_ptr_array_index(fields->fields,i);
2313         if (i != 0 ) {
2314             fputc(fields->separator, fh);
2315         }
2316         fputs(field, fh);
2317     }
2318     fputc('\n', fh);
2319 }
2320
2321 static void format_field_values(output_fields_t* fields, gpointer field_index, gchar* value)
2322 {
2323     guint      indx;
2324     GPtrArray* fv_p;
2325
2326     if (NULL == value)
2327         return;
2328
2329     /* Unwrap change made to disambiguiate zero / null */
2330     indx = GPOINTER_TO_UINT(field_index) - 1;
2331
2332     if (fields->field_values[indx] == NULL) {
2333         fields->field_values[indx] = g_ptr_array_new();
2334     }
2335
2336     /* Essentially: fieldvalues[indx] is a 'GPtrArray *' with each array entry */
2337     /*  pointing to a string which is (part of) the final output string.       */
2338
2339     fv_p = fields->field_values[indx];
2340
2341     switch (fields->occurrence) {
2342     case 'f':
2343         /* print the value of only the first occurrence of the field */
2344         if (g_ptr_array_len(fv_p) != 0) {
2345             /*
2346              * This isn't the first occurrence, so the value won't be used;
2347              * free it.
2348              */
2349             g_free(value);
2350             return;
2351         }
2352         break;
2353     case 'l':
2354         /* print the value of only the last occurrence of the field */
2355         if (g_ptr_array_len(fv_p) != 0) {
2356             /*
2357              * This isn't the first occurrence, so there's already a
2358              * value in the array, which won't be used; free the
2359              * first (only) element in the array, and then remove
2360              * it - this value will replace it.
2361              */
2362             g_free(g_ptr_array_index(fv_p, 0));
2363             g_ptr_array_set_size(fv_p, 0);
2364         }
2365         break;
2366     case 'a':
2367         /* print the value of all accurrences of the field */
2368         if (g_ptr_array_len(fv_p) != 0) {
2369             /*
2370              * This isn't the first occurrence. so add the "aggregator"
2371              * character as a separator between the previous element
2372              * and this element.
2373              */
2374             g_ptr_array_add(fv_p, (gpointer)g_strdup_printf("%c", fields->aggregator));
2375         }
2376         break;
2377     default:
2378         g_assert_not_reached();
2379         break;
2380     }
2381
2382     g_ptr_array_add(fv_p, (gpointer)value);
2383 }
2384
2385 static void proto_tree_get_node_field_values(proto_node *node, gpointer data)
2386 {
2387     write_field_data_t *call_data;
2388     field_info *fi;
2389     gpointer    field_index;
2390
2391     call_data = (write_field_data_t *)data;
2392     fi = PNODE_FINFO(node);
2393
2394     /* dissection with an invisible proto tree? */
2395     g_assert(fi);
2396
2397     field_index = g_hash_table_lookup(call_data->fields->field_indicies, fi->hfinfo->abbrev);
2398     if (NULL != field_index) {
2399         format_field_values(call_data->fields, field_index,
2400                             get_node_field_value(fi, call_data->edt) /* g_ alloc'd string */
2401             );
2402     }
2403
2404     /* Recurse here. */
2405     if (node->first_child != NULL) {
2406         proto_tree_children_foreach(node, proto_tree_get_node_field_values,
2407                                     call_data);
2408     }
2409 }
2410
2411 static void write_specified_fields(fields_format format, output_fields_t *fields, epan_dissect_t *edt, column_info *cinfo, FILE *fh)
2412 {
2413     gsize     i;
2414     gboolean first = TRUE;
2415     gint      col;
2416     gchar    *col_name;
2417     gpointer  field_index;
2418
2419     write_field_data_t data;
2420
2421     g_assert(fields);
2422     g_assert(fields->fields);
2423     g_assert(edt);
2424     g_assert(fh);
2425
2426     data.fields = fields;
2427     data.edt = edt;
2428
2429     if (NULL == fields->field_indicies) {
2430         /* Prepare a lookup table from string abbreviation for field to its index. */
2431         fields->field_indicies = g_hash_table_new(g_str_hash, g_str_equal);
2432
2433         i = 0;
2434         while (i < fields->fields->len) {
2435             gchar *field = (gchar *)g_ptr_array_index(fields->fields, i);
2436             /* Store field indicies +1 so that zero is not a valid value,
2437              * and can be distinguished from NULL as a pointer.
2438              */
2439             ++i;
2440             g_hash_table_insert(fields->field_indicies, field, GUINT_TO_POINTER(i));
2441         }
2442     }
2443
2444     /* Array buffer to store values for this packet              */
2445     /*  Allocate an array for the 'GPtrarray *' the first time   */
2446     /*   ths function is invoked for a file;                     */
2447     /*  Any and all 'GPtrArray *' are freed (after use) each     */
2448     /*   time (each packet) this function is invoked for a flle. */
2449     /* XXX: ToDo: use packet-scope'd memory & (if/when implemented) wmem ptr_array */
2450     if (NULL == fields->field_values)
2451         fields->field_values = g_new0(GPtrArray*, fields->fields->len);  /* free'd in output_fields_free() */
2452
2453     proto_tree_children_foreach(edt->tree, proto_tree_get_node_field_values,
2454                                 &data);
2455
2456     /* Add columns to fields */
2457     if (fields->includes_col_fields) {
2458         for (col = 0; col < cinfo->num_cols; col++) {
2459             if (!get_column_visible(col)) continue;
2460             /* Prepend COLUMN_FIELD_FILTER as the field name */
2461             col_name = g_strdup_printf("%s%s", COLUMN_FIELD_FILTER, cinfo->columns[col].col_title);
2462             field_index = g_hash_table_lookup(fields->field_indicies, col_name);
2463             g_free(col_name);
2464
2465             if (NULL != field_index) {
2466                 format_field_values(fields, field_index, g_strdup(cinfo->columns[col].col_data));
2467             }
2468         }
2469     }
2470
2471     switch (format) {
2472     case FORMAT_CSV:
2473         for(i = 0; i < fields->fields->len; ++i) {
2474             if (0 != i) {
2475                 fputc(fields->separator, fh);
2476             }
2477             if (NULL != fields->field_values[i]) {
2478                 GPtrArray *fv_p;
2479                 gchar * str;
2480                 gsize j;
2481                 fv_p = fields->field_values[i];
2482                 if (fields->quote != '\0') {
2483                     fputc(fields->quote, fh);
2484                 }
2485
2486                 /* Output the array of (partial) field values */
2487                 for (j = 0; j < g_ptr_array_len(fv_p); j++ ) {
2488                     str = (gchar *)g_ptr_array_index(fv_p, j);
2489                     fputs(str, fh);
2490                     g_free(str);
2491                 }
2492                 if (fields->quote != '\0') {
2493                     fputc(fields->quote, fh);
2494                 }
2495                 g_ptr_array_free(fv_p, TRUE);  /* get ready for the next packet */
2496                 fields->field_values[i] = NULL;
2497             }
2498         }
2499         break;
2500     case FORMAT_XML:
2501         for(i = 0; i < fields->fields->len; ++i) {
2502             gchar *field = (gchar *)g_ptr_array_index(fields->fields, i);
2503
2504             if (NULL != fields->field_values[i]) {
2505                 GPtrArray *fv_p;
2506                 gchar * str;
2507                 gsize j;
2508                 fv_p = fields->field_values[i];
2509
2510                 /* Output the array of (partial) field values */
2511                 for (j = 0; j < (g_ptr_array_len(fv_p)); j+=2 ) {
2512                     str = (gchar *)g_ptr_array_index(fv_p, j);
2513
2514                     fprintf(fh, "  <field name=\"%s\" value=", field);
2515                     fputs("\"", fh);
2516                     print_escaped_xml(fh, str);
2517                     fputs("\"/>\n", fh);
2518                     g_free(str);
2519                 }
2520                 g_ptr_array_free(fv_p, TRUE);  /* get ready for the next packet */
2521                 fields->field_values[i] = NULL;
2522             }
2523         }
2524         break;
2525     case FORMAT_JSON:
2526         fputs("{\n", fh);
2527         for(i = 0; i < fields->fields->len; ++i) {
2528             gchar *field = (gchar *)g_ptr_array_index(fields->fields, i);
2529
2530             if (NULL != fields->field_values[i]) {
2531                 GPtrArray *fv_p;
2532                 gchar * str;
2533                 gsize j;
2534                 fv_p = fields->field_values[i];
2535
2536                 /* Output the array of (partial) field values */
2537                 for (j = 0; j < (g_ptr_array_len(fv_p)); j += 2) {
2538                     str = (gchar *) g_ptr_array_index(fv_p, j);
2539
2540                     if (j == 0) {
2541                         if (!first) {
2542                             fputs(",\n", fh);
2543                         }
2544                         fprintf(fh, "        \"%s\": [", field);
2545                     }
2546                     fputs("\"", fh);
2547                     print_escaped_json(fh, str);
2548                     fputs("\"", fh);
2549                     g_free(str);
2550
2551                     if (j + 2 < (g_ptr_array_len(fv_p))) {
2552                         fputs(",", fh);
2553                     } else {
2554                         fputs("]", fh);
2555                     }
2556                 }
2557
2558                 first = FALSE;
2559                 g_ptr_array_free(fv_p, TRUE);  /* get ready for the next packet */
2560                 fields->field_values[i] = NULL;
2561             }
2562         }
2563         fputc('\n',fh);
2564
2565         fputs("      }", fh);
2566         break;
2567     case FORMAT_EK:
2568         for(i = 0; i < fields->fields->len; ++i) {
2569             gchar *field = (gchar *)g_ptr_array_index(fields->fields, i);
2570
2571             if (NULL != fields->field_values[i]) {
2572                 GPtrArray *fv_p;
2573                 gchar * str;
2574                 gsize j;
2575                 fv_p = fields->field_values[i];
2576
2577                 /* Output the array of (partial) field values */
2578                 for (j = 0; j < (g_ptr_array_len(fv_p)); j += 2) {
2579                     str = (gchar *)g_ptr_array_index(fv_p, j);
2580
2581                     if (j == 0) {
2582                         if (!first) {
2583                             fputs(",", fh);
2584                         }
2585                         fputs("\"", fh);
2586                         print_escaped_ek(fh, field);
2587                         fputs("\": [", fh);
2588                     }
2589                     fputs("\"", fh);
2590                     print_escaped_json(fh, str);
2591                     fputs("\"", fh);
2592                     g_free(str);
2593
2594                     if (j + 2 < (g_ptr_array_len(fv_p))) {
2595                         fputs(",", fh);
2596                     }
2597                     else {
2598                         fputs("]", fh);
2599
2600                         }
2601                     }
2602
2603                 first = FALSE;
2604                 g_ptr_array_free(fv_p, TRUE);  /* get ready for the next packet */
2605                 fields->field_values[i] = NULL;
2606             }
2607         }
2608         break;
2609
2610     default:
2611         fprintf(stderr, "Unknown fields format %d\n", format);
2612         g_assert_not_reached();
2613         break;
2614     }
2615 }
2616
2617 void write_fields_finale(output_fields_t* fields _U_ , FILE *fh _U_)
2618 {
2619     /* Nothing to do */
2620 }
2621
2622 /* Returns an g_malloced string */
2623 gchar* get_node_field_value(field_info* fi, epan_dissect_t* edt)
2624 {
2625     if (fi->hfinfo->id == hf_text_only) {
2626         /* Text label.
2627          * Get the text */
2628         if (fi->rep) {
2629             return g_strdup(fi->rep->representation);
2630         }
2631         else {
2632             return get_field_hex_value(edt->pi.data_src, fi);
2633         }
2634     }
2635     else if (fi->hfinfo->id == proto_data) {
2636         /* Uninterpreted data, i.e., the "Data" protocol, is
2637          * printed as a field instead of a protocol. */
2638         return get_field_hex_value(edt->pi.data_src, fi);
2639     }
2640     else {
2641         /* Normal protocols and fields */
2642         gchar      *dfilter_string;
2643
2644         switch (fi->hfinfo->type)
2645         {
2646         case FT_PROTOCOL:
2647             /* Print out the full details for the protocol. */
2648             if (fi->rep) {
2649                 return g_strdup(fi->rep->representation);
2650             } else {
2651                 /* Just print out the protocol abbreviation */
2652                 return g_strdup(fi->hfinfo->abbrev);
2653             }
2654         case FT_NONE:
2655             /* Return "1" so that the presence of a field of type
2656              * FT_NONE can be checked when using -T fields */
2657             return g_strdup("1");
2658         default:
2659             dfilter_string = fvalue_to_string_repr(NULL, &fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
2660             if (dfilter_string != NULL) {
2661                 gchar* ret = g_strdup(dfilter_string);
2662                 wmem_free(NULL, dfilter_string);
2663                 return ret;
2664             } else {
2665                 return get_field_hex_value(edt->pi.data_src, fi);
2666             }
2667         }
2668     }
2669 }
2670
2671 static gchar*
2672 get_field_hex_value(GSList *src_list, field_info *fi)
2673 {
2674     const guint8 *pd;
2675
2676     if (!fi->ds_tvb)
2677         return NULL;
2678
2679     if (fi->length > tvb_captured_length_remaining(fi->ds_tvb, fi->start)) {
2680         return g_strdup("field length invalid!");
2681     }
2682
2683     /* Find the data for this field. */
2684     pd = get_field_data(src_list, fi);
2685
2686     if (pd) {
2687         int        i;
2688         gchar     *buffer;
2689         gchar     *p;
2690         int        len;
2691         const int  chars_per_byte = 2;
2692
2693         len    = chars_per_byte * fi->length;
2694         buffer = (gchar *)g_malloc(sizeof(gchar)*(len + 1));
2695         buffer[len] = '\0'; /* Ensure NULL termination in bad cases */
2696         p = buffer;
2697         /* Print a simple hex dump */
2698         for (i = 0 ; i < fi->length; i++) {
2699             g_snprintf(p, chars_per_byte+1, "%02x", pd[i]);
2700             p += chars_per_byte;
2701         }
2702         return buffer;
2703     } else {
2704         return NULL;
2705     }
2706 }
2707
2708 output_fields_t* output_fields_new(void)
2709 {
2710     output_fields_t* fields     = g_new(output_fields_t, 1);
2711     fields->print_bom           = FALSE;
2712     fields->print_header        = FALSE;
2713     fields->separator           = '\t';
2714     fields->occurrence          = 'a';
2715     fields->aggregator          = ',';
2716     fields->fields              = NULL; /*Do lazy initialisation */
2717     fields->field_indicies      = NULL;
2718     fields->field_values        = NULL;
2719     fields->quote               ='\0';
2720     fields->includes_col_fields = FALSE;
2721     return fields;
2722 }
2723
2724 /*
2725  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
2726  *
2727  * Local variables:
2728  * c-basic-offset: 4
2729  * tab-width: 8
2730  * indent-tabs-mode: nil
2731  * End:
2732  *
2733  * vi: set shiftwidth=4 tabstop=8 expandtab:
2734  * :indentSize=4:tabSize=8:noTabs=true:
2735  */