epan/dissectors/packet-xml.c try to decrypt data, but the data doesn't look correct yet
[metze/wireshark/wip.git] / epan / column-utils.c
1 /* column-utils.c
2  * Routines for column utilities.
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10
11 #include "config.h"
12
13 #include <string.h>
14 #include <time.h>
15 #include <locale.h>
16
17 #include "column-utils.h"
18 #include "timestamp.h"
19 #include "to_str.h"
20 #include "packet_info.h"
21 #include "wsutil/pint.h"
22 #include "addr_resolv.h"
23 #include "address_types.h"
24 #include "ipv6.h"
25 #include "osi-utils.h"
26 #include "value_string.h"
27 #include "column-info.h"
28 #include "proto.h"
29
30 #include <epan/strutil.h>
31 #include <epan/epan.h>
32 #include <epan/dfilter/dfilter.h>
33
34 #include <wsutil/utf8_entities.h>
35 #include <wsutil/ws_printf.h>
36
37 #ifdef HAVE_LUA
38 #include <epan/wslua/wslua.h>
39 #endif
40
41 /* Used for locale decimal point */
42 static char *col_decimal_point;
43
44 /* Used to indicate updated column information, e.g. a new request/response. */
45 static gboolean col_data_changed_;
46
47 /* Allocate all the data structures for constructing column data, given
48    the number of columns. */
49 void
50 col_setup(column_info *cinfo, const gint num_cols)
51 {
52   int i;
53
54   col_decimal_point            = localeconv()->decimal_point;
55   cinfo->num_cols              = num_cols;
56   cinfo->columns               = g_new(col_item_t, num_cols);
57   cinfo->col_first             = g_new(int, NUM_COL_FMTS);
58   cinfo->col_last              = g_new(int, NUM_COL_FMTS);
59   for (i = 0; i < num_cols; i++) {
60     cinfo->columns[i].col_custom_fields_ids = NULL;
61   }
62   cinfo->col_expr.col_expr     = g_new(const gchar*, num_cols + 1);
63   cinfo->col_expr.col_expr_val = g_new(gchar*, num_cols + 1);
64
65   for (i = 0; i < NUM_COL_FMTS; i++) {
66     cinfo->col_first[i] = -1;
67     cinfo->col_last[i] = -1;
68   }
69   cinfo->prime_regex = g_regex_new(COL_CUSTOM_PRIME_REGEX,
70     G_REGEX_ANCHORED, G_REGEX_MATCH_ANCHORED, NULL);
71 }
72
73 static void
74 col_custom_fields_ids_free(GSList** custom_fields_id)
75 {
76   if (*custom_fields_id != NULL) {
77     g_slist_free_full(*custom_fields_id, g_free);
78   }
79   *custom_fields_id = NULL;
80 }
81
82 /* Cleanup all the data structures for constructing column data; undoes
83    the allocations that col_setup() does. */
84 void
85 col_cleanup(column_info *cinfo)
86 {
87   int i;
88   col_item_t* col_item;
89
90   if (!cinfo)
91     return;
92
93   for (i = 0; i < cinfo->num_cols; i++) {
94     col_item = &cinfo->columns[i];
95     g_free(col_item->fmt_matx);
96     g_free(col_item->col_title);
97     g_free(col_item->col_custom_fields);
98     dfilter_free(col_item->col_custom_dfilter);
99     /* col_item->col_data points to col_buf or static memory */
100     g_free(col_item->col_buf);
101     g_free(cinfo->col_expr.col_expr_val[i]);
102     col_custom_fields_ids_free(&col_item->col_custom_fields_ids);
103   }
104
105   g_free(cinfo->columns);
106   g_free(cinfo->col_first);
107   g_free(cinfo->col_last);
108   /*
109    * XXX - MSVC doesn't correctly handle the "const" qualifier; it thinks
110    * "const XXX **" means "pointer to const pointer to XXX", i.e. that
111    * it's a pointer to something that's "const"ant, not "pointer to
112    * pointer to const XXX", i.e. that it's a pointer to a pointer to
113    * something that's "const"ant.  Cast its bogus complaints away.
114    */
115   g_free((gchar **)cinfo->col_expr.col_expr);
116   g_free(cinfo->col_expr.col_expr_val);
117   if (cinfo->prime_regex)
118     g_regex_unref(cinfo->prime_regex);
119 }
120
121 /* Initialize the data structures for constructing column data. */
122 void
123 col_init(column_info *cinfo, const struct epan_session *epan)
124 {
125   int i;
126   col_item_t* col_item;
127
128   if (!cinfo)
129     return;
130
131   for (i = 0; i < cinfo->num_cols; i++) {
132     col_item = &cinfo->columns[i];
133     col_item->col_buf[0] = '\0';
134     col_item->col_data = col_item->col_buf;
135     col_item->col_fence = 0;
136     col_item->writable = TRUE;
137     cinfo->col_expr.col_expr[i] = "";
138     cinfo->col_expr.col_expr_val[i][0] = '\0';
139   }
140   cinfo->writable = TRUE;
141   cinfo->epan = epan;
142 }
143
144 gboolean
145 col_get_writable(column_info *cinfo, const gint col)
146 {
147   int i;
148   col_item_t* col_item;
149
150   if (cinfo == NULL)
151     return FALSE;
152
153   /* "global" (not) writeability will always override
154      an individual column */
155   if ((col == -1) || (cinfo->writable == FALSE))
156     return cinfo->writable;
157
158   if (cinfo->col_first[col] >= 0) {
159     for (i = cinfo->col_first[col]; i <= cinfo->col_last[col]; i++) {
160       col_item = &cinfo->columns[i];
161       if (col_item->fmt_matx[col]) {
162         return col_item->writable;
163       }
164     }
165   }
166   return FALSE;
167 }
168
169 void
170 col_set_writable(column_info *cinfo, const gint col, const gboolean writable)
171 {
172   int i;
173   col_item_t* col_item;
174
175   if (cinfo) {
176     if (col == -1) {
177       cinfo->writable = writable;
178     } else if (cinfo->col_first[col] >= 0) {
179       for (i = cinfo->col_first[col]; i <= cinfo->col_last[col]; i++) {
180         col_item = &cinfo->columns[i];
181         if (col_item->fmt_matx[col]) {
182           col_item->writable = writable;
183         }
184       }
185     }
186   }
187 }
188
189 /* Checks to see if a particular packet information element is needed for the packet list */
190 #define CHECK_COL(cinfo, el) \
191     /* We are constructing columns, and they're writable */ \
192     (col_get_writable(cinfo, el) && \
193       /* There is at least one column in that format */ \
194     ((cinfo)->col_first[el] >= 0))
195
196 /* Sets the fence for a column to be at the end of the column. */
197 void
198 col_set_fence(column_info *cinfo, const gint el)
199 {
200   int i;
201   col_item_t* col_item;
202
203   if (!CHECK_COL(cinfo, el))
204     return;
205
206   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
207     col_item = &cinfo->columns[i];
208     if (col_item->fmt_matx[el]) {
209       col_item->col_fence = (int)strlen(col_item->col_data);
210     }
211   }
212 }
213
214 /* Clear the fence for a column. */
215 void
216 col_clear_fence(column_info *cinfo, const gint el)
217 {
218   int i;
219   col_item_t* col_item;
220
221   if (!CHECK_COL(cinfo, el))
222     return;
223
224   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
225     col_item = &cinfo->columns[i];
226      if (col_item->fmt_matx[el]) {
227         col_item->col_fence = 0;
228      }
229   }
230 }
231
232 /* Gets the text of a column */
233 const gchar *
234 col_get_text(column_info *cinfo, const gint el)
235 {
236   int i;
237   const gchar* text = NULL;
238   col_item_t* col_item;
239
240   if (!(cinfo && (cinfo)->col_first[el] >= 0)) {
241     return NULL;
242   }
243
244   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
245     col_item = &cinfo->columns[i];
246     if (col_item->fmt_matx[el]) {
247       text = (col_item->col_data);
248     }
249   }
250   return text;
251 }
252
253
254 /* Use this to clear out a column, especially if you're going to be
255    appending to it later; at least on some platforms, it's more
256    efficient than using "col_add_str()" with a null string, and
257    more efficient than "col_set_str()" with a null string if you
258    later append to it, as the later append will cause a string
259    copy to be done. */
260 void
261 col_clear(column_info *cinfo, const gint el)
262 {
263   int    i;
264   col_item_t* col_item;
265
266   if (!CHECK_COL(cinfo, el))
267     return;
268
269   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
270     col_item = &cinfo->columns[i];
271     if (col_item->fmt_matx[el]) {
272       /*
273        * At this point, either
274        *
275        *   1) col_data[i] is equal to col_buf[i], in which case we
276        *      don't have to worry about copying col_data[i] to
277        *      col_buf[i];
278        *
279        *   2) col_data[i] isn't equal to col_buf[i], in which case
280        *      the only thing that's been done to the column is
281        *      "col_set_str()" calls and possibly "col_set_fence()"
282        *      calls, in which case the fence is either unset and
283        *      at the beginning of the string or set and at the end
284        *      of the string - if it's at the beginning, we're just
285        *      going to clear the column, and if it's at the end,
286        *      we don't do anything.
287        */
288       if (col_item->col_buf == col_item->col_data || col_item->col_fence == 0) {
289         /*
290          * The fence isn't at the end of the column, or the column wasn't
291          * last set with "col_set_str()", so clear the column out.
292          */
293         col_item->col_buf[col_item->col_fence] = '\0';
294         col_item->col_data = col_item->col_buf;
295       }
296       cinfo->col_expr.col_expr[i] = "";
297       cinfo->col_expr.col_expr_val[i][0] = '\0';
298     }
299   }
300 }
301
302 #define COL_CHECK_APPEND(col_item, max_len) \
303   if (col_item->col_data != col_item->col_buf) {        \
304     /* This was set with "col_set_str()"; copy the string they  \
305        set it to into the buffer, so we can append to it. */    \
306     g_strlcpy(col_item->col_buf, col_item->col_data, max_len);  \
307     col_item->col_data = col_item->col_buf;         \
308   }
309
310 #define COL_CHECK_REF_TIME(fd, buf)         \
311   if (fd->ref_time) {                 \
312     g_strlcpy(buf, "*REF*", COL_MAX_LEN );  \
313     return;                                 \
314   }
315
316 /* The same as CHECK_COL(), but without the check to see if the column is writable. */
317 #define HAVE_CUSTOM_COLS(cinfo) ((cinfo) && (cinfo)->col_first[COL_CUSTOM] >= 0)
318
319 gboolean
320 have_custom_cols(column_info *cinfo)
321 {
322   return HAVE_CUSTOM_COLS(cinfo);
323 }
324
325 gboolean
326 have_field_extractors(void)
327 {
328 #ifdef HAVE_LUA
329     return wslua_has_field_extractors();
330 #else
331     return FALSE;
332 #endif
333 }
334
335 /* search in edt tree custom fields */
336 void col_custom_set_edt(epan_dissect_t *edt, column_info *cinfo)
337 {
338   int i;
339   col_item_t* col_item;
340
341   if (!HAVE_CUSTOM_COLS(cinfo))
342       return;
343
344   for (i = cinfo->col_first[COL_CUSTOM];
345        i <= cinfo->col_last[COL_CUSTOM]; i++) {
346     col_item = &cinfo->columns[i];
347     if (col_item->fmt_matx[COL_CUSTOM] &&
348         col_item->col_custom_fields &&
349         col_item->col_custom_fields_ids) {
350         col_item->col_data = col_item->col_buf;
351         cinfo->col_expr.col_expr[i] = epan_custom_set(edt, col_item->col_custom_fields_ids,
352                                      col_item->col_custom_occurrence,
353                                      col_item->col_buf,
354                                      cinfo->col_expr.col_expr_val[i],
355                                      COL_MAX_LEN);
356     }
357   }
358 }
359
360 void
361 col_custom_prime_edt(epan_dissect_t *edt, column_info *cinfo)
362 {
363   int i;
364   col_item_t* col_item;
365
366   if (!HAVE_CUSTOM_COLS(cinfo))
367     return;
368
369   for (i = cinfo->col_first[COL_CUSTOM];
370        i <= cinfo->col_last[COL_CUSTOM]; i++) {
371     col_item = &cinfo->columns[i];
372
373     if (col_item->fmt_matx[COL_CUSTOM] &&
374         col_item->col_custom_dfilter) {
375       epan_dissect_prime_with_dfilter(edt, col_item->col_custom_dfilter);
376     }
377   }
378 }
379
380 void
381 col_append_lstr(column_info *cinfo, const gint el, const gchar *str1, ...)
382 {
383   va_list ap;
384   size_t pos, max_len;
385   int    i;
386   const gchar *str;
387   col_item_t* col_item;
388
389   if (!CHECK_COL(cinfo, el))
390     return;
391
392   if (el == COL_INFO)
393     max_len = COL_MAX_INFO_LEN;
394   else
395     max_len = COL_MAX_LEN;
396
397   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
398     col_item = &cinfo->columns[i];
399     if (col_item->fmt_matx[el]) {
400       /*
401        * First arrange that we can append, if necessary.
402        */
403       COL_CHECK_APPEND(col_item, max_len);
404
405       pos = strlen(col_item->col_buf);
406       if (pos >= max_len)
407          return;
408
409       va_start(ap, str1);
410       str = str1;
411       do {
412          if (G_UNLIKELY(str == NULL))
413              str = "(null)";
414
415          pos += g_strlcpy(&col_item->col_buf[pos], str, max_len - pos);
416
417       } while (pos < max_len && (str = va_arg(ap, const char *)) != COL_ADD_LSTR_TERMINATOR);
418       va_end(ap);
419     }
420   }
421 }
422
423 void
424 col_append_str_uint(column_info *cinfo, const gint col, const gchar *abbrev, guint32 val, const gchar *sep)
425 {
426   char buf[16];
427
428   guint32_to_str_buf(val, buf, sizeof(buf));
429   col_append_lstr(cinfo, col, sep ? sep : "", abbrev, "=", buf, COL_ADD_LSTR_TERMINATOR);
430 }
431
432 static inline void
433 col_snprint_port(gchar *buf, gulong buf_siz, port_type typ, guint16 val)
434 {
435   const char *str;
436
437   if (gbl_resolv_flags.transport_name &&
438         (str = try_serv_name_lookup(typ, val)) != NULL) {
439     ws_snprintf(buf, buf_siz, "%s(%"G_GUINT16_FORMAT")", str, val);
440   } else {
441     ws_snprintf(buf, buf_siz, "%"G_GUINT16_FORMAT, val);
442   }
443 }
444
445 void
446 col_append_ports(column_info *cinfo, const gint col, port_type typ, guint16 src, guint16 dst)
447 {
448   char buf_src[32], buf_dst[32];
449
450   col_snprint_port(buf_src, 32, typ, src);
451   col_snprint_port(buf_dst, 32, typ, dst);
452   col_append_lstr(cinfo, col, buf_src, " " UTF8_RIGHTWARDS_ARROW " ", buf_dst, COL_ADD_LSTR_TERMINATOR);
453 }
454
455 void
456 col_append_frame_number(packet_info *pinfo, const gint col, const gchar *fmt_str, guint frame_num)
457 {
458   col_append_fstr(pinfo->cinfo, col, fmt_str, frame_num);
459   if (!pinfo->fd->visited) {
460     col_data_changed_ = TRUE;
461   }
462 }
463
464 static void
465 col_do_append_fstr(column_info *cinfo, const int el, const char *separator, const char *format, va_list ap)
466 {
467   size_t len, max_len, sep_len;
468   int    i;
469   col_item_t* col_item;
470
471   sep_len = (separator) ? strlen(separator) : 0;
472
473   if (el == COL_INFO)
474     max_len = COL_MAX_INFO_LEN;
475   else
476     max_len = COL_MAX_LEN;
477
478   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
479     col_item = &cinfo->columns[i];
480     if (col_item->fmt_matx[el]) {
481       /*
482        * First arrange that we can append, if necessary.
483        */
484       COL_CHECK_APPEND(col_item, max_len);
485
486       len = strlen(col_item->col_buf);
487
488       /*
489        * If we have a separator, append it if the column isn't empty.
490        */
491       if (sep_len != 0 && len != 0) {
492         g_strlcat(col_item->col_buf, separator, max_len);
493         len += sep_len;
494       }
495
496       if (len < max_len) {
497         va_list ap2;
498
499         G_VA_COPY(ap2, ap);
500         ws_vsnprintf(&col_item->col_buf[len], (guint32)(max_len - len), format, ap2);
501         va_end(ap2);
502       }
503     }
504   }
505 }
506
507 /*  Appends a vararg list to a packet info string. */
508 void
509 col_append_fstr(column_info *cinfo, const gint el, const gchar *format, ...)
510 {
511   va_list ap;
512
513   if (!CHECK_COL(cinfo, el))
514     return;
515
516   va_start(ap, format);
517   col_do_append_fstr(cinfo, el, NULL, format, ap);
518   va_end(ap);
519 }
520
521 /*  Appends a vararg list to a packet info string.
522  *  Prefixes it with the given separator if the column is not empty.
523  */
524 void
525 col_append_sep_fstr(column_info *cinfo, const gint el, const gchar *separator,
526                     const gchar *format, ...)
527 {
528   va_list ap;
529
530   if (!CHECK_COL(cinfo, el))
531     return;
532
533   if (separator == NULL)
534     separator = ", ";    /* default */
535
536   va_start(ap, format);
537   col_do_append_fstr(cinfo, el, separator, format, ap);
538   va_end(ap);
539 }
540
541 /* Prepends a vararg list to a packet info string. */
542 #define COL_BUF_MAX_LEN (((COL_MAX_INFO_LEN) > (COL_MAX_LEN)) ? \
543     (COL_MAX_INFO_LEN) : (COL_MAX_LEN))
544 void
545 col_prepend_fstr(column_info *cinfo, const gint el, const gchar *format, ...)
546 {
547   va_list     ap;
548   int         i;
549   char        orig_buf[COL_BUF_MAX_LEN];
550   const char *orig;
551   int         max_len;
552   col_item_t* col_item;
553
554   if (!CHECK_COL(cinfo, el))
555     return;
556
557   if (el == COL_INFO)
558     max_len = COL_MAX_INFO_LEN;
559   else
560     max_len = COL_MAX_LEN;
561
562   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
563     col_item = &cinfo->columns[i];
564     if (col_item->fmt_matx[el]) {
565       if (col_item->col_data != col_item->col_buf) {
566         /* This was set with "col_set_str()"; which is effectively const */
567         orig = col_item->col_data;
568       } else {
569         g_strlcpy(orig_buf, col_item->col_buf, max_len);
570         orig = orig_buf;
571       }
572       va_start(ap, format);
573       ws_vsnprintf(col_item->col_buf, max_len, format, ap);
574       va_end(ap);
575
576       /*
577        * Move the fence, unless it's at the beginning of the string.
578        */
579       if (col_item->col_fence > 0)
580         col_item->col_fence += (int) strlen(col_item->col_buf);
581
582       g_strlcat(col_item->col_buf, orig, max_len);
583       col_item->col_data = col_item->col_buf;
584     }
585   }
586 }
587 void
588 col_prepend_fence_fstr(column_info *cinfo, const gint el, const gchar *format, ...)
589 {
590   va_list     ap;
591   int         i;
592   char        orig_buf[COL_BUF_MAX_LEN];
593   const char *orig;
594   int         max_len;
595   col_item_t* col_item;
596
597   if (!CHECK_COL(cinfo, el))
598     return;
599
600   if (el == COL_INFO)
601     max_len = COL_MAX_INFO_LEN;
602   else
603     max_len = COL_MAX_LEN;
604
605   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
606     col_item = &cinfo->columns[i];
607     if (col_item->fmt_matx[el]) {
608       if (col_item->col_data != col_item->col_buf) {
609         /* This was set with "col_set_str()"; which is effectively const */
610         orig = col_item->col_data;
611       } else {
612         g_strlcpy(orig_buf, col_item->col_buf, max_len);
613         orig = orig_buf;
614       }
615       va_start(ap, format);
616       ws_vsnprintf(col_item->col_buf, max_len, format, ap);
617       va_end(ap);
618
619       /*
620        * Move the fence if it exists, else create a new fence at the
621        * end of the prepended data.
622        */
623       if (col_item->col_fence > 0) {
624         col_item->col_fence += (int) strlen(col_item->col_buf);
625       } else {
626         col_item->col_fence = (int) strlen(col_item->col_buf);
627       }
628       g_strlcat(col_item->col_buf, orig, max_len);
629       col_item->col_data = col_item->col_buf;
630     }
631   }
632 }
633
634 /* Use this if "str" points to something that won't stay around (and
635    must thus be copied). */
636 void
637 col_add_str(column_info *cinfo, const gint el, const gchar* str)
638 {
639   int    i;
640   size_t max_len;
641   col_item_t* col_item;
642
643   if (!CHECK_COL(cinfo, el))
644     return;
645
646   if (el == COL_INFO)
647     max_len = COL_MAX_INFO_LEN;
648   else
649     max_len = COL_MAX_LEN;
650
651   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
652     col_item = &cinfo->columns[i];
653     if (col_item->fmt_matx[el]) {
654       if (col_item->col_fence != 0) {
655         /*
656          * We will append the string after the fence.
657          * First arrange that we can append, if necessary.
658          */
659         COL_CHECK_APPEND(col_item, max_len);
660       } else {
661         /*
662          * There's no fence, so we can just write to the string.
663          */
664         col_item->col_data = col_item->col_buf;
665       }
666       g_strlcpy(&col_item->col_buf[col_item->col_fence], str, max_len - col_item->col_fence);
667     }
668   }
669 }
670
671 /* Use this if "str" points to something that will stay around (and thus
672    needn't be copied). */
673 void
674 col_set_str(column_info *cinfo, const gint el, const gchar* str)
675 {
676   int i;
677   size_t max_len;
678   col_item_t* col_item;
679
680   DISSECTOR_ASSERT(str);
681
682   if (!CHECK_COL(cinfo, el))
683     return;
684
685   if (el == COL_INFO)
686     max_len = COL_MAX_INFO_LEN;
687   else
688     max_len = COL_MAX_LEN;
689
690   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
691     col_item = &cinfo->columns[i];
692     if (col_item->fmt_matx[el]) {
693       if (col_item->col_fence != 0) {
694         /*
695          * We will append the string after the fence.
696          * First arrange that we can append, if necessary.
697          */
698         COL_CHECK_APPEND(col_item, max_len);
699
700         g_strlcpy(&col_item->col_buf[col_item->col_fence], str, max_len - col_item->col_fence);
701       } else {
702         /*
703          * There's no fence, so we can just set the column to point
704          * to the string.
705          */
706         col_item->col_data = str;
707       }
708     }
709   }
710 }
711
712 void
713 col_add_lstr(column_info *cinfo, const gint el, const gchar *str1, ...)
714 {
715   va_list ap;
716   int     i;
717   gsize   pos;
718   gsize   max_len;
719   const gchar *str;
720   col_item_t* col_item;
721
722   if (!CHECK_COL(cinfo, el))
723     return;
724
725   if (el == COL_INFO)
726     max_len = COL_MAX_INFO_LEN;
727   else
728     max_len = COL_MAX_LEN;
729
730   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
731     col_item = &cinfo->columns[i];
732     if (col_item->fmt_matx[el]) {
733       pos = col_item->col_fence;
734       if (pos != 0) {
735         /*
736          * We will append the string after the fence.
737          * First arrange that we can append, if necessary.
738          */
739         COL_CHECK_APPEND(col_item, max_len);
740       } else {
741         /*
742          * There's no fence, so we can just write to the string.
743          */
744         col_item->col_data = col_item->col_buf;
745       }
746
747       va_start(ap, str1);
748       str = str1;
749       do {
750          if (G_UNLIKELY(str == NULL))
751              str = "(null)";
752
753          pos += g_strlcpy(&col_item->col_buf[pos], str, max_len - pos);
754
755       } while (pos < max_len && (str = va_arg(ap, const char *)) != COL_ADD_LSTR_TERMINATOR);
756       va_end(ap);
757     }
758   }
759 }
760
761 /* Adds a vararg list to a packet info string. */
762 void
763 col_add_fstr(column_info *cinfo, const gint el, const gchar *format, ...)
764 {
765   va_list ap;
766   int     i;
767   int     max_len;
768   col_item_t* col_item;
769
770   if (!CHECK_COL(cinfo, el))
771     return;
772
773   if (el == COL_INFO)
774     max_len = COL_MAX_INFO_LEN;
775   else
776     max_len = COL_MAX_LEN;
777
778   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
779     col_item = &cinfo->columns[i];
780     if (col_item->fmt_matx[el]) {
781       if (col_item->col_fence != 0) {
782         /*
783          * We will append the string after the fence.
784          * First arrange that we can append, if necessary.
785          */
786         COL_CHECK_APPEND(col_item, max_len);
787       } else {
788         /*
789          * There's no fence, so we can just write to the string.
790          */
791         col_item->col_data = col_item->col_buf;
792       }
793       va_start(ap, format);
794       ws_vsnprintf(&col_item->col_buf[col_item->col_fence], max_len - col_item->col_fence, format, ap);
795       va_end(ap);
796     }
797   }
798 }
799
800 static void
801 col_do_append_str(column_info *cinfo, const gint el, const gchar* separator,
802     const gchar* str)
803 {
804   int    i;
805   size_t len, max_len;
806   col_item_t* col_item;
807
808   if (el == COL_INFO)
809     max_len = COL_MAX_INFO_LEN;
810   else
811     max_len = COL_MAX_LEN;
812
813   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
814     col_item = &cinfo->columns[i];
815     if (col_item->fmt_matx[el]) {
816       /*
817        * First arrange that we can append, if necessary.
818        */
819       COL_CHECK_APPEND(col_item, max_len);
820
821       len = col_item->col_buf[0];
822
823       /*
824        * If we have a separator, append it if the column isn't empty.
825        */
826       if (separator != NULL) {
827         if (len != 0) {
828           g_strlcat(col_item->col_buf, separator, max_len);
829         }
830       }
831       g_strlcat(col_item->col_buf, str, max_len);
832     }
833   }
834 }
835
836 void
837 col_append_str(column_info *cinfo, const gint el, const gchar* str)
838 {
839   if (!CHECK_COL(cinfo, el))
840     return;
841
842   col_do_append_str(cinfo, el, NULL, str);
843 }
844
845 void
846 col_append_sep_str(column_info *cinfo, const gint el, const gchar* separator,
847     const gchar* str)
848 {
849   if (!CHECK_COL(cinfo, el))
850     return;
851
852   if (separator == NULL)
853     separator = ", ";    /* default */
854
855   col_do_append_str(cinfo, el, separator, str);
856 }
857
858 /* --------------------------------- */
859 gboolean
860 col_has_time_fmt(column_info *cinfo, const gint col)
861 {
862   col_item_t* col_item = &cinfo->columns[col];
863   return ((col_item->fmt_matx[COL_CLS_TIME]) ||
864           (col_item->fmt_matx[COL_ABS_TIME]) ||
865           (col_item->fmt_matx[COL_ABS_YMD_TIME]) ||
866           (col_item->fmt_matx[COL_ABS_YDOY_TIME]) ||
867           (col_item->fmt_matx[COL_UTC_TIME]) ||
868           (col_item->fmt_matx[COL_UTC_YMD_TIME]) ||
869           (col_item->fmt_matx[COL_UTC_YDOY_TIME]) ||
870           (col_item->fmt_matx[COL_REL_TIME]) ||
871           (col_item->fmt_matx[COL_DELTA_TIME]) ||
872           (col_item->fmt_matx[COL_DELTA_TIME_DIS]));
873 }
874
875 static void
876 set_abs_ymd_time(const frame_data *fd, gchar *buf, char *decimal_point, gboolean local)
877 {
878   struct tm *tmp;
879   time_t then;
880   int tsprecision;
881
882   if (fd->has_ts) {
883     then = fd->abs_ts.secs;
884     if (local)
885       tmp = localtime(&then);
886     else
887       tmp = gmtime(&then);
888   } else
889     tmp = NULL;
890   if (tmp != NULL) {
891     switch (timestamp_get_precision()) {
892     case TS_PREC_FIXED_SEC:
893       tsprecision = WTAP_TSPREC_SEC;
894       break;
895     case TS_PREC_FIXED_DSEC:
896       tsprecision = WTAP_TSPREC_DSEC;
897       break;
898     case TS_PREC_FIXED_CSEC:
899       tsprecision = WTAP_TSPREC_CSEC;
900       break;
901     case TS_PREC_FIXED_MSEC:
902       tsprecision = WTAP_TSPREC_MSEC;
903       break;
904     case TS_PREC_FIXED_USEC:
905       tsprecision = WTAP_TSPREC_USEC;
906       break;
907     case TS_PREC_FIXED_NSEC:
908       tsprecision = WTAP_TSPREC_NSEC;
909       break;
910     case TS_PREC_AUTO:
911       tsprecision = fd->tsprec;
912       break;
913     default:
914       g_assert_not_reached();
915     }
916     switch (tsprecision) {
917     case WTAP_TSPREC_SEC:
918       ws_snprintf(buf, COL_MAX_LEN,"%04d-%02d-%02d %02d:%02d:%02d",
919         tmp->tm_year + 1900,
920         tmp->tm_mon + 1,
921         tmp->tm_mday,
922         tmp->tm_hour,
923         tmp->tm_min,
924         tmp->tm_sec);
925       break;
926     case WTAP_TSPREC_DSEC:
927       ws_snprintf(buf, COL_MAX_LEN,"%04d-%02d-%02d %02d:%02d:%02d%s%01d",
928         tmp->tm_year + 1900,
929         tmp->tm_mon + 1,
930         tmp->tm_mday,
931         tmp->tm_hour,
932         tmp->tm_min,
933         tmp->tm_sec,
934         decimal_point,
935         fd->abs_ts.nsecs / 100000000);
936       break;
937     case WTAP_TSPREC_CSEC:
938       ws_snprintf(buf, COL_MAX_LEN,"%04d-%02d-%02d %02d:%02d:%02d%s%02d",
939         tmp->tm_year + 1900,
940         tmp->tm_mon + 1,
941         tmp->tm_mday,
942         tmp->tm_hour,
943         tmp->tm_min,
944         tmp->tm_sec,
945         decimal_point,
946         fd->abs_ts.nsecs / 10000000);
947       break;
948     case WTAP_TSPREC_MSEC:
949       ws_snprintf(buf, COL_MAX_LEN, "%04d-%02d-%02d %02d:%02d:%02d%s%03d",
950         tmp->tm_year + 1900,
951         tmp->tm_mon + 1,
952         tmp->tm_mday,
953         tmp->tm_hour,
954         tmp->tm_min,
955         tmp->tm_sec,
956         decimal_point,
957         fd->abs_ts.nsecs / 1000000);
958       break;
959     case WTAP_TSPREC_USEC:
960       ws_snprintf(buf, COL_MAX_LEN, "%04d-%02d-%02d %02d:%02d:%02d%s%06d",
961         tmp->tm_year + 1900,
962         tmp->tm_mon + 1,
963         tmp->tm_mday,
964         tmp->tm_hour,
965         tmp->tm_min,
966         tmp->tm_sec,
967         decimal_point,
968         fd->abs_ts.nsecs / 1000);
969       break;
970     case WTAP_TSPREC_NSEC:
971       ws_snprintf(buf, COL_MAX_LEN, "%04d-%02d-%02d %02d:%02d:%02d%s%09d",
972         tmp->tm_year + 1900,
973         tmp->tm_mon + 1,
974         tmp->tm_mday,
975         tmp->tm_hour,
976         tmp->tm_min,
977         tmp->tm_sec,
978         decimal_point,
979         fd->abs_ts.nsecs);
980       break;
981     default:
982       g_assert_not_reached();
983     }
984   } else {
985     buf[0] = '\0';
986   }
987 }
988
989 static void
990 col_set_abs_ymd_time(const frame_data *fd, column_info *cinfo, const int col)
991 {
992   set_abs_ymd_time(fd, cinfo->columns[col].col_buf, col_decimal_point, TRUE);
993   cinfo->col_expr.col_expr[col] = "frame.time";
994   g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
995
996   cinfo->columns[col].col_data = cinfo->columns[col].col_buf;
997 }
998
999 static void
1000 col_set_utc_ymd_time(const frame_data *fd, column_info *cinfo, const int col)
1001 {
1002   set_abs_ymd_time(fd, cinfo->columns[col].col_buf, col_decimal_point, FALSE);
1003   cinfo->col_expr.col_expr[col] = "frame.time";
1004   g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
1005
1006   cinfo->columns[col].col_data = cinfo->columns[col].col_buf;
1007 }
1008
1009 static void
1010 set_abs_ydoy_time(const frame_data *fd, gchar *buf, char *decimal_point, gboolean local)
1011 {
1012   struct tm *tmp;
1013   time_t then;
1014   int tsprecision;
1015
1016   if (fd->has_ts) {
1017     then = fd->abs_ts.secs;
1018     if (local)
1019       tmp = localtime(&then);
1020     else
1021       tmp = gmtime(&then);
1022   } else
1023     tmp = NULL;
1024   if (tmp != NULL) {
1025     switch (timestamp_get_precision()) {
1026     case TS_PREC_FIXED_SEC:
1027       tsprecision = WTAP_TSPREC_SEC;
1028       break;
1029     case TS_PREC_FIXED_DSEC:
1030       tsprecision = WTAP_TSPREC_DSEC;
1031       break;
1032     case TS_PREC_FIXED_CSEC:
1033       tsprecision = WTAP_TSPREC_CSEC;
1034       break;
1035     case TS_PREC_FIXED_MSEC:
1036       tsprecision = WTAP_TSPREC_MSEC;
1037       break;
1038     case TS_PREC_FIXED_USEC:
1039       tsprecision = WTAP_TSPREC_USEC;
1040       break;
1041     case TS_PREC_FIXED_NSEC:
1042       tsprecision = WTAP_TSPREC_NSEC;
1043       break;
1044     case TS_PREC_AUTO:
1045       tsprecision = fd->tsprec;
1046       break;
1047     default:
1048       g_assert_not_reached();
1049     }
1050     switch (tsprecision) {
1051     case WTAP_TSPREC_SEC:
1052       ws_snprintf(buf, COL_MAX_LEN,"%04d/%03d %02d:%02d:%02d",
1053         tmp->tm_year + 1900,
1054         tmp->tm_yday + 1,
1055         tmp->tm_hour,
1056         tmp->tm_min,
1057         tmp->tm_sec);
1058       break;
1059     case WTAP_TSPREC_DSEC:
1060       ws_snprintf(buf, COL_MAX_LEN,"%04d/%03d %02d:%02d:%02d%s%01d",
1061         tmp->tm_year + 1900,
1062         tmp->tm_yday + 1,
1063         tmp->tm_hour,
1064         tmp->tm_min,
1065         tmp->tm_sec,
1066         decimal_point,
1067         fd->abs_ts.nsecs / 100000000);
1068       break;
1069     case WTAP_TSPREC_CSEC:
1070       ws_snprintf(buf, COL_MAX_LEN,"%04d/%03d %02d:%02d:%02d%s%02d",
1071         tmp->tm_year + 1900,
1072         tmp->tm_yday + 1,
1073         tmp->tm_hour,
1074         tmp->tm_min,
1075         tmp->tm_sec,
1076         decimal_point,
1077         fd->abs_ts.nsecs / 10000000);
1078       break;
1079     case WTAP_TSPREC_MSEC:
1080       ws_snprintf(buf, COL_MAX_LEN, "%04d/%03d %02d:%02d:%02d%s%03d",
1081         tmp->tm_year + 1900,
1082         tmp->tm_yday + 1,
1083         tmp->tm_hour,
1084         tmp->tm_min,
1085         tmp->tm_sec,
1086         decimal_point,
1087         fd->abs_ts.nsecs / 1000000);
1088       break;
1089     case WTAP_TSPREC_USEC:
1090       ws_snprintf(buf, COL_MAX_LEN, "%04d/%03d %02d:%02d:%02d%s%06d",
1091         tmp->tm_year + 1900,
1092         tmp->tm_yday + 1,
1093         tmp->tm_hour,
1094         tmp->tm_min,
1095         tmp->tm_sec,
1096         decimal_point,
1097         fd->abs_ts.nsecs / 1000);
1098       break;
1099     case WTAP_TSPREC_NSEC:
1100       ws_snprintf(buf, COL_MAX_LEN, "%04d/%03d %02d:%02d:%02d%s%09d",
1101         tmp->tm_year + 1900,
1102         tmp->tm_yday + 1,
1103         tmp->tm_hour,
1104         tmp->tm_min,
1105         tmp->tm_sec,
1106         decimal_point,
1107         fd->abs_ts.nsecs);
1108       break;
1109     default:
1110       g_assert_not_reached();
1111     }
1112   } else {
1113     buf[0] = '\0';
1114   }
1115 }
1116
1117 static void
1118 col_set_abs_ydoy_time(const frame_data *fd, column_info *cinfo, const int col)
1119 {
1120   set_abs_ydoy_time(fd, cinfo->columns[col].col_buf, col_decimal_point, TRUE);
1121   cinfo->col_expr.col_expr[col] = "frame.time";
1122   g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
1123
1124   cinfo->columns[col].col_data = cinfo->columns[col].col_buf;
1125 }
1126
1127 static void
1128 col_set_utc_ydoy_time(const frame_data *fd, column_info *cinfo, const int col)
1129 {
1130   set_abs_ydoy_time(fd, cinfo->columns[col].col_buf, col_decimal_point, FALSE);
1131   cinfo->col_expr.col_expr[col] = "frame.time";
1132   g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
1133
1134   cinfo->columns[col].col_data = cinfo->columns[col].col_buf;
1135 }
1136
1137 static void
1138 set_time_seconds(const frame_data *fd, const nstime_t *ts, gchar *buf)
1139 {
1140   int tsprecision;
1141
1142   switch (timestamp_get_precision()) {
1143   case TS_PREC_FIXED_SEC:
1144     tsprecision = WTAP_TSPREC_SEC;
1145     break;
1146   case TS_PREC_FIXED_DSEC:
1147     tsprecision = WTAP_TSPREC_DSEC;
1148     break;
1149   case TS_PREC_FIXED_CSEC:
1150     tsprecision = WTAP_TSPREC_CSEC;
1151     break;
1152   case TS_PREC_FIXED_MSEC:
1153     tsprecision = WTAP_TSPREC_MSEC;
1154     break;
1155   case TS_PREC_FIXED_USEC:
1156     tsprecision = WTAP_TSPREC_USEC;
1157     break;
1158   case TS_PREC_FIXED_NSEC:
1159     tsprecision = WTAP_TSPREC_NSEC;
1160     break;
1161   case TS_PREC_AUTO:
1162     tsprecision = fd->tsprec;
1163     break;
1164   default:
1165     g_assert_not_reached();
1166   }
1167   switch (tsprecision) {
1168   case WTAP_TSPREC_SEC:
1169     display_signed_time(buf, COL_MAX_LEN,
1170       (gint32) ts->secs, ts->nsecs / 1000000000, TO_STR_TIME_RES_T_SECS);
1171     break;
1172   case WTAP_TSPREC_DSEC:
1173     display_signed_time(buf, COL_MAX_LEN,
1174       (gint32) ts->secs, ts->nsecs / 100000000, TO_STR_TIME_RES_T_DSECS);
1175     break;
1176   case WTAP_TSPREC_CSEC:
1177     display_signed_time(buf, COL_MAX_LEN,
1178       (gint32) ts->secs, ts->nsecs / 10000000, TO_STR_TIME_RES_T_CSECS);
1179     break;
1180   case WTAP_TSPREC_MSEC:
1181     display_signed_time(buf, COL_MAX_LEN,
1182       (gint32) ts->secs, ts->nsecs / 1000000, TO_STR_TIME_RES_T_MSECS);
1183     break;
1184   case WTAP_TSPREC_USEC:
1185     display_signed_time(buf, COL_MAX_LEN,
1186       (gint32) ts->secs, ts->nsecs / 1000, TO_STR_TIME_RES_T_USECS);
1187     break;
1188   case WTAP_TSPREC_NSEC:
1189     display_signed_time(buf, COL_MAX_LEN,
1190       (gint32) ts->secs, ts->nsecs, TO_STR_TIME_RES_T_NSECS);
1191     break;
1192   default:
1193     g_assert_not_reached();
1194   }
1195 }
1196
1197 static void
1198 set_time_hour_min_sec(const frame_data *fd, const nstime_t *ts, gchar *buf, char *decimal_point)
1199 {
1200   time_t secs = ts->secs;
1201   long nsecs = (long) ts->nsecs;
1202   gboolean negative = FALSE;
1203   int tsprecision;
1204
1205   if (secs < 0) {
1206     secs = -secs;
1207     negative = TRUE;
1208   }
1209   if (nsecs < 0) {
1210     nsecs = -nsecs;
1211     negative = TRUE;
1212   }
1213
1214   switch (timestamp_get_precision()) {
1215   case TS_PREC_FIXED_SEC:
1216     tsprecision = WTAP_TSPREC_SEC;
1217     break;
1218   case TS_PREC_FIXED_DSEC:
1219     tsprecision = WTAP_TSPREC_DSEC;
1220     break;
1221   case TS_PREC_FIXED_CSEC:
1222     tsprecision = WTAP_TSPREC_CSEC;
1223     break;
1224   case TS_PREC_FIXED_MSEC:
1225     tsprecision = WTAP_TSPREC_MSEC;
1226     break;
1227   case TS_PREC_FIXED_USEC:
1228     tsprecision = WTAP_TSPREC_USEC;
1229     break;
1230   case TS_PREC_FIXED_NSEC:
1231     tsprecision = WTAP_TSPREC_NSEC;
1232     break;
1233   case TS_PREC_AUTO:
1234     tsprecision = fd->tsprec;
1235     break;
1236   default:
1237     g_assert_not_reached();
1238   }
1239   switch (tsprecision) {
1240   case WTAP_TSPREC_SEC:
1241     if (secs >= (60*60)) {
1242       ws_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2ds",
1243                  negative ? "- " : "",
1244                  (gint32) secs / (60 * 60),
1245                  (gint32) (secs / 60) % 60,
1246                  (gint32) secs % 60);
1247     } else if (secs >= 60) {
1248       ws_snprintf(buf, COL_MAX_LEN, "%s%dm %2ds",
1249                  negative ? "- " : "",
1250                  (gint32) secs / 60,
1251                  (gint32) secs % 60);
1252     } else {
1253       ws_snprintf(buf, COL_MAX_LEN, "%s%ds",
1254                  negative ? "- " : "",
1255                  (gint32) secs);
1256     }
1257     break;
1258   case WTAP_TSPREC_DSEC:
1259     if (secs >= (60*60)) {
1260       ws_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d%s%01lds",
1261                  negative ? "- " : "",
1262                  (gint32) secs / (60 * 60),
1263                  (gint32) (secs / 60) % 60,
1264                  (gint32) secs % 60,
1265                  decimal_point,
1266                  nsecs / 100000000);
1267     } else if (secs >= 60) {
1268       ws_snprintf(buf, COL_MAX_LEN, "%s%dm %2d%s%01lds",
1269                  negative ? "- " : "",
1270                  (gint32) secs / 60,
1271                  (gint32) secs % 60,
1272                  decimal_point,
1273                  nsecs / 100000000);
1274     } else {
1275       ws_snprintf(buf, COL_MAX_LEN, "%s%d%s%01lds",
1276                  negative ? "- " : "",
1277                  (gint32) secs,
1278                  decimal_point,
1279                  nsecs / 100000000);
1280     }
1281     break;
1282   case WTAP_TSPREC_CSEC:
1283     if (secs >= (60*60)) {
1284       ws_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d%s%02lds",
1285                  negative ? "- " : "",
1286                  (gint32) secs / (60 * 60),
1287                  (gint32) (secs / 60) % 60,
1288                  (gint32) secs % 60,
1289                  decimal_point,
1290                  nsecs / 10000000);
1291     } else if (secs >= 60) {
1292       ws_snprintf(buf, COL_MAX_LEN, "%s%dm %2d%s%02lds",
1293                  negative ? "- " : "",
1294                  (gint32) secs / 60,
1295                  (gint32) secs % 60,
1296                  decimal_point,
1297                  nsecs / 10000000);
1298     } else {
1299       ws_snprintf(buf, COL_MAX_LEN, "%s%d%s%02lds",
1300                  negative ? "- " : "",
1301                  (gint32) secs,
1302                  decimal_point,
1303                  nsecs / 10000000);
1304     }
1305     break;
1306   case WTAP_TSPREC_MSEC:
1307     if (secs >= (60*60)) {
1308       ws_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d%s%03lds",
1309                  negative ? "- " : "",
1310                  (gint32) secs / (60 * 60),
1311                  (gint32) (secs / 60) % 60,
1312                  (gint32) secs % 60,
1313                  decimal_point,
1314                  nsecs / 1000000);
1315     } else if (secs >= 60) {
1316       ws_snprintf(buf, COL_MAX_LEN, "%s%dm %2d%s%03lds",
1317                  negative ? "- " : "",
1318                  (gint32) secs / 60,
1319                  (gint32) secs % 60,
1320                  decimal_point,
1321                  nsecs / 1000000);
1322     } else {
1323       ws_snprintf(buf, COL_MAX_LEN, "%s%d%s%03lds",
1324                  negative ? "- " : "",
1325                  (gint32) secs,
1326                  decimal_point,
1327                  nsecs / 1000000);
1328     }
1329     break;
1330   case WTAP_TSPREC_USEC:
1331     if (secs >= (60*60)) {
1332       ws_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d%s%06lds",
1333                  negative ? "- " : "",
1334                  (gint32) secs / (60 * 60),
1335                  (gint32) (secs / 60) % 60,
1336                  (gint32) secs % 60,
1337                  decimal_point,
1338                  nsecs / 1000);
1339     } else if (secs >= 60) {
1340       ws_snprintf(buf, COL_MAX_LEN, "%s%dm %2d%s%06lds",
1341                  negative ? "- " : "",
1342                  (gint32) secs / 60,
1343                  (gint32) secs % 60,
1344                  decimal_point,
1345                  nsecs / 1000);
1346     } else {
1347       ws_snprintf(buf, COL_MAX_LEN, "%s%d%s%06lds",
1348                  negative ? "- " : "",
1349                  (gint32) secs,
1350                  decimal_point,
1351                  nsecs / 1000);
1352     }
1353     break;
1354   case WTAP_TSPREC_NSEC:
1355     if (secs >= (60*60)) {
1356       ws_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d%s%09lds",
1357                  negative ? "- " : "",
1358                  (gint32) secs / (60 * 60),
1359                  (gint32) (secs / 60) % 60,
1360                  (gint32) secs % 60,
1361                  decimal_point,
1362                  nsecs);
1363     } else if (secs >= 60) {
1364       ws_snprintf(buf, COL_MAX_LEN, "%s%dm %2d%s%09lds",
1365                  negative ? "- " : "",
1366                  (gint32) secs / 60,
1367                  (gint32) secs % 60,
1368                  decimal_point,
1369                  nsecs);
1370     } else {
1371       ws_snprintf(buf, COL_MAX_LEN, "%s%d%s%09lds",
1372                  negative ? "- " : "",
1373                  (gint32) secs,
1374                  decimal_point,
1375                  nsecs);
1376     }
1377     break;
1378   default:
1379     g_assert_not_reached();
1380   }
1381 }
1382
1383 static void
1384 col_set_rel_time(const frame_data *fd, column_info *cinfo, const int col)
1385 {
1386   nstime_t del_rel_ts;
1387
1388   if (!fd->has_ts) {
1389     cinfo->columns[col].col_buf[0] = '\0';
1390     return;
1391   }
1392
1393   frame_delta_abs_time(cinfo->epan, fd, fd->frame_ref_num, &del_rel_ts);
1394
1395   switch (timestamp_get_seconds_type()) {
1396   case TS_SECONDS_DEFAULT:
1397     set_time_seconds(fd, &del_rel_ts, cinfo->columns[col].col_buf);
1398     cinfo->col_expr.col_expr[col] = "frame.time_relative";
1399     g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
1400     break;
1401   case TS_SECONDS_HOUR_MIN_SEC:
1402     set_time_hour_min_sec(fd, &del_rel_ts, cinfo->columns[col].col_buf, col_decimal_point);
1403     cinfo->col_expr.col_expr[col] = "frame.time_relative";
1404     set_time_seconds(fd, &del_rel_ts, cinfo->col_expr.col_expr_val[col]);
1405     break;
1406   default:
1407     g_assert_not_reached();
1408   }
1409   cinfo->columns[col].col_data = cinfo->columns[col].col_buf;
1410 }
1411
1412 static void
1413 col_set_delta_time(const frame_data *fd, column_info *cinfo, const int col)
1414 {
1415   nstime_t del_cap_ts;
1416
1417   frame_delta_abs_time(cinfo->epan, fd, fd->num - 1, &del_cap_ts);
1418
1419   switch (timestamp_get_seconds_type()) {
1420   case TS_SECONDS_DEFAULT:
1421     set_time_seconds(fd, &del_cap_ts, cinfo->columns[col].col_buf);
1422     cinfo->col_expr.col_expr[col] = "frame.time_delta";
1423     g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
1424     break;
1425   case TS_SECONDS_HOUR_MIN_SEC:
1426     set_time_hour_min_sec(fd, &del_cap_ts, cinfo->columns[col].col_buf, col_decimal_point);
1427     cinfo->col_expr.col_expr[col] = "frame.time_delta";
1428     set_time_seconds(fd, &del_cap_ts, cinfo->col_expr.col_expr_val[col]);
1429     break;
1430   default:
1431     g_assert_not_reached();
1432   }
1433
1434   cinfo->columns[col].col_data = cinfo->columns[col].col_buf;
1435 }
1436
1437 static void
1438 col_set_delta_time_dis(const frame_data *fd, column_info *cinfo, const int col)
1439 {
1440   nstime_t del_dis_ts;
1441
1442   if (!fd->has_ts) {
1443     cinfo->columns[col].col_buf[0] = '\0';
1444     return;
1445   }
1446
1447   frame_delta_abs_time(cinfo->epan, fd, fd->prev_dis_num, &del_dis_ts);
1448
1449   switch (timestamp_get_seconds_type()) {
1450   case TS_SECONDS_DEFAULT:
1451     set_time_seconds(fd, &del_dis_ts, cinfo->columns[col].col_buf);
1452     cinfo->col_expr.col_expr[col] = "frame.time_delta_displayed";
1453     g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
1454     break;
1455   case TS_SECONDS_HOUR_MIN_SEC:
1456     set_time_hour_min_sec(fd, &del_dis_ts, cinfo->columns[col].col_buf, col_decimal_point);
1457     cinfo->col_expr.col_expr[col] = "frame.time_delta_displayed";
1458     set_time_seconds(fd, &del_dis_ts, cinfo->col_expr.col_expr_val[col]);
1459     break;
1460   default:
1461     g_assert_not_reached();
1462   }
1463
1464   cinfo->columns[col].col_data = cinfo->columns[col].col_buf;
1465 }
1466
1467 static void
1468 set_abs_time(const frame_data *fd, gchar *buf, char *decimal_point, gboolean local)
1469 {
1470   struct tm *tmp;
1471   time_t then;
1472   int tsprecision;
1473
1474   if (fd->has_ts) {
1475     then = fd->abs_ts.secs;
1476     if (local)
1477       tmp = localtime(&then);
1478     else
1479       tmp = gmtime(&then);
1480   } else
1481     tmp = NULL;
1482   if (tmp != NULL) {
1483     switch (timestamp_get_precision()) {
1484     case TS_PREC_FIXED_SEC:
1485       tsprecision = WTAP_TSPREC_SEC;
1486       break;
1487     case TS_PREC_FIXED_DSEC:
1488       tsprecision = WTAP_TSPREC_DSEC;
1489       break;
1490     case TS_PREC_FIXED_CSEC:
1491       tsprecision = WTAP_TSPREC_CSEC;
1492       break;
1493     case TS_PREC_FIXED_MSEC:
1494       tsprecision = WTAP_TSPREC_MSEC;
1495       break;
1496     case TS_PREC_FIXED_USEC:
1497       tsprecision = WTAP_TSPREC_USEC;
1498       break;
1499     case TS_PREC_FIXED_NSEC:
1500       tsprecision = WTAP_TSPREC_NSEC;
1501       break;
1502     case TS_PREC_AUTO:
1503       tsprecision = fd->tsprec;
1504       break;
1505     default:
1506       g_assert_not_reached();
1507     }
1508     switch (tsprecision) {
1509     case WTAP_TSPREC_SEC:
1510       ws_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d",
1511         tmp->tm_hour,
1512         tmp->tm_min,
1513         tmp->tm_sec);
1514       break;
1515     case WTAP_TSPREC_DSEC:
1516       ws_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d%s%01d",
1517         tmp->tm_hour,
1518         tmp->tm_min,
1519         tmp->tm_sec,
1520         decimal_point,
1521         fd->abs_ts.nsecs / 100000000);
1522       break;
1523     case WTAP_TSPREC_CSEC:
1524       ws_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d%s%02d",
1525         tmp->tm_hour,
1526         tmp->tm_min,
1527         tmp->tm_sec,
1528         decimal_point,
1529         fd->abs_ts.nsecs / 10000000);
1530       break;
1531     case WTAP_TSPREC_MSEC:
1532       ws_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d%s%03d",
1533         tmp->tm_hour,
1534         tmp->tm_min,
1535         tmp->tm_sec,
1536         decimal_point,
1537         fd->abs_ts.nsecs / 1000000);
1538       break;
1539     case WTAP_TSPREC_USEC:
1540       ws_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d%s%06d",
1541         tmp->tm_hour,
1542         tmp->tm_min,
1543         tmp->tm_sec,
1544         decimal_point,
1545         fd->abs_ts.nsecs / 1000);
1546       break;
1547     case WTAP_TSPREC_NSEC:
1548       ws_snprintf(buf, COL_MAX_LEN, "%02d:%02d:%02d%s%09d",
1549         tmp->tm_hour,
1550         tmp->tm_min,
1551         tmp->tm_sec,
1552         decimal_point,
1553         fd->abs_ts.nsecs);
1554       break;
1555     default:
1556       g_assert_not_reached();
1557     }
1558
1559   } else {
1560     *buf = '\0';
1561   }
1562 }
1563
1564 static void
1565 col_set_abs_time(const frame_data *fd, column_info *cinfo, const int col)
1566 {
1567   set_abs_time(fd, cinfo->columns[col].col_buf, col_decimal_point, TRUE);
1568   cinfo->col_expr.col_expr[col] = "frame.time";
1569   g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
1570
1571   cinfo->columns[col].col_data = cinfo->columns[col].col_buf;
1572 }
1573
1574 static void
1575 col_set_utc_time(const frame_data *fd, column_info *cinfo, const int col)
1576 {
1577   set_abs_time(fd, cinfo->columns[col].col_buf, col_decimal_point, FALSE);
1578   cinfo->col_expr.col_expr[col] = "frame.time";
1579   g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
1580
1581   cinfo->columns[col].col_data = cinfo->columns[col].col_buf;
1582 }
1583
1584 static gboolean
1585 set_epoch_time(const frame_data *fd, gchar *buf)
1586 {
1587   int tsprecision;
1588
1589   if (!fd->has_ts) {
1590     buf[0] = '\0';
1591     return FALSE;
1592   }
1593   switch (timestamp_get_precision()) {
1594   case TS_PREC_FIXED_SEC:
1595     tsprecision = WTAP_TSPREC_SEC;
1596     break;
1597   case TS_PREC_FIXED_DSEC:
1598     tsprecision = WTAP_TSPREC_DSEC;
1599     break;
1600   case TS_PREC_FIXED_CSEC:
1601     tsprecision = WTAP_TSPREC_CSEC;
1602     break;
1603   case TS_PREC_FIXED_MSEC:
1604     tsprecision = WTAP_TSPREC_MSEC;
1605     break;
1606   case TS_PREC_FIXED_USEC:
1607     tsprecision = WTAP_TSPREC_USEC;
1608     break;
1609   case TS_PREC_FIXED_NSEC:
1610     tsprecision = WTAP_TSPREC_NSEC;
1611     break;
1612   case TS_PREC_AUTO:
1613     tsprecision = fd->tsprec;
1614     break;
1615   default:
1616     g_assert_not_reached();
1617   }
1618   switch (tsprecision) {
1619   case WTAP_TSPREC_SEC:
1620     display_epoch_time(buf, COL_MAX_LEN,
1621       fd->abs_ts.secs, fd->abs_ts.nsecs / 1000000000, TO_STR_TIME_RES_T_SECS);
1622     break;
1623   case WTAP_TSPREC_DSEC:
1624     display_epoch_time(buf, COL_MAX_LEN,
1625        fd->abs_ts.secs, fd->abs_ts.nsecs / 100000000, TO_STR_TIME_RES_T_DSECS);
1626     break;
1627   case WTAP_TSPREC_CSEC:
1628     display_epoch_time(buf, COL_MAX_LEN,
1629        fd->abs_ts.secs, fd->abs_ts.nsecs / 10000000, TO_STR_TIME_RES_T_CSECS);
1630     break;
1631   case WTAP_TSPREC_MSEC:
1632     display_epoch_time(buf, COL_MAX_LEN,
1633        fd->abs_ts.secs, fd->abs_ts.nsecs / 1000000, TO_STR_TIME_RES_T_MSECS);
1634     break;
1635   case WTAP_TSPREC_USEC:
1636     display_epoch_time(buf, COL_MAX_LEN,
1637        fd->abs_ts.secs, fd->abs_ts.nsecs / 1000, TO_STR_TIME_RES_T_USECS);
1638     break;
1639   case WTAP_TSPREC_NSEC:
1640     display_epoch_time(buf, COL_MAX_LEN,
1641        fd->abs_ts.secs, fd->abs_ts.nsecs, TO_STR_TIME_RES_T_NSECS);
1642     break;
1643   default:
1644     g_assert_not_reached();
1645   }
1646   return TRUE;
1647 }
1648
1649 static void
1650 col_set_epoch_time(const frame_data *fd, column_info *cinfo, const int col)
1651 {
1652   if (set_epoch_time(fd, cinfo->columns[col].col_buf)) {
1653     cinfo->col_expr.col_expr[col] = "frame.time_delta";
1654     g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->columns[col].col_buf,COL_MAX_LEN);
1655   }
1656   cinfo->columns[col].col_data = cinfo->columns[col].col_buf;
1657 }
1658
1659 void
1660 set_fd_time(const epan_t *epan, frame_data *fd, gchar *buf)
1661 {
1662
1663   switch (timestamp_get_type()) {
1664   case TS_ABSOLUTE:
1665     set_abs_time(fd, buf, col_decimal_point, TRUE);
1666     break;
1667
1668   case TS_ABSOLUTE_WITH_YMD:
1669     set_abs_ymd_time(fd, buf, col_decimal_point, TRUE);
1670     break;
1671
1672   case TS_ABSOLUTE_WITH_YDOY:
1673     set_abs_ydoy_time(fd, buf, col_decimal_point, TRUE);
1674     break;
1675
1676   case TS_RELATIVE:
1677     if (fd->has_ts) {
1678       nstime_t del_rel_ts;
1679
1680       frame_delta_abs_time(epan, fd, fd->frame_ref_num, &del_rel_ts);
1681
1682       switch (timestamp_get_seconds_type()) {
1683       case TS_SECONDS_DEFAULT:
1684         set_time_seconds(fd, &del_rel_ts, buf);
1685         break;
1686       case TS_SECONDS_HOUR_MIN_SEC:
1687         set_time_seconds(fd, &del_rel_ts, buf);
1688         break;
1689       default:
1690         g_assert_not_reached();
1691       }
1692     } else {
1693       buf[0] = '\0';
1694     }
1695     break;
1696
1697   case TS_DELTA:
1698     if (fd->has_ts) {
1699       nstime_t del_cap_ts;
1700
1701       frame_delta_abs_time(epan, fd, fd->num - 1, &del_cap_ts);
1702
1703       switch (timestamp_get_seconds_type()) {
1704       case TS_SECONDS_DEFAULT:
1705         set_time_seconds(fd, &del_cap_ts, buf);
1706         break;
1707       case TS_SECONDS_HOUR_MIN_SEC:
1708         set_time_hour_min_sec(fd, &del_cap_ts, buf, col_decimal_point);
1709         break;
1710       default:
1711         g_assert_not_reached();
1712       }
1713     } else {
1714       buf[0] = '\0';
1715     }
1716     break;
1717
1718   case TS_DELTA_DIS:
1719     if (fd->has_ts) {
1720       nstime_t del_dis_ts;
1721
1722       frame_delta_abs_time(epan, fd, fd->prev_dis_num, &del_dis_ts);
1723
1724       switch (timestamp_get_seconds_type()) {
1725       case TS_SECONDS_DEFAULT:
1726         set_time_seconds(fd, &del_dis_ts, buf);
1727         break;
1728       case TS_SECONDS_HOUR_MIN_SEC:
1729         set_time_hour_min_sec(fd, &del_dis_ts, buf, col_decimal_point);
1730         break;
1731       default:
1732         g_assert_not_reached();
1733       }
1734     } else {
1735       buf[0] = '\0';
1736     }
1737     break;
1738
1739   case TS_EPOCH:
1740     set_epoch_time(fd, buf);
1741     break;
1742
1743   case TS_UTC:
1744     set_abs_time(fd, buf, col_decimal_point, FALSE);
1745     break;
1746
1747   case TS_UTC_WITH_YMD:
1748     set_abs_ymd_time(fd, buf, col_decimal_point, FALSE);
1749     break;
1750
1751   case TS_UTC_WITH_YDOY:
1752     set_abs_ydoy_time(fd, buf, col_decimal_point, FALSE);
1753     break;
1754
1755   case TS_NOT_SET:
1756     /* code is missing for this case, but I don't know which [jmayer20051219] */
1757     g_assert(FALSE);
1758     break;
1759   }
1760 }
1761
1762 static void
1763 col_set_cls_time(const frame_data *fd, column_info *cinfo, const gint col)
1764 {
1765   switch (timestamp_get_type()) {
1766   case TS_ABSOLUTE:
1767     col_set_abs_time(fd, cinfo, col);
1768     break;
1769
1770   case TS_ABSOLUTE_WITH_YMD:
1771     col_set_abs_ymd_time(fd, cinfo, col);
1772     break;
1773
1774   case TS_ABSOLUTE_WITH_YDOY:
1775     col_set_abs_ydoy_time(fd, cinfo, col);
1776     break;
1777
1778   case TS_RELATIVE:
1779     col_set_rel_time(fd, cinfo, col);
1780     break;
1781
1782   case TS_DELTA:
1783     col_set_delta_time(fd, cinfo, col);
1784     break;
1785
1786   case TS_DELTA_DIS:
1787     col_set_delta_time_dis(fd, cinfo, col);
1788     break;
1789
1790   case TS_EPOCH:
1791     col_set_epoch_time(fd, cinfo, col);
1792     break;
1793
1794   case TS_UTC:
1795     col_set_utc_time(fd, cinfo, col);
1796     break;
1797
1798   case TS_UTC_WITH_YMD:
1799     col_set_utc_ymd_time(fd, cinfo, col);
1800     break;
1801
1802   case TS_UTC_WITH_YDOY:
1803     col_set_utc_ydoy_time(fd, cinfo, col);
1804     break;
1805
1806   case TS_NOT_SET:
1807     /* code is missing for this case, but I don't know which [jmayer20051219] */
1808     g_assert_not_reached();
1809     break;
1810   }
1811 }
1812
1813 /* Set the format of the variable time format. */
1814 static void
1815 col_set_fmt_time(const frame_data *fd, column_info *cinfo, const gint fmt, const gint col)
1816 {
1817   COL_CHECK_REF_TIME(fd, cinfo->columns[col].col_buf);
1818
1819   switch (fmt) {
1820   case COL_CLS_TIME:
1821     col_set_cls_time(fd, cinfo, col);
1822     break;
1823
1824   case COL_ABS_TIME:
1825     col_set_abs_time(fd, cinfo, col);
1826     break;
1827
1828   case COL_ABS_YMD_TIME:
1829     col_set_abs_ymd_time(fd, cinfo, col);
1830     break;
1831
1832   case COL_ABS_YDOY_TIME:
1833     col_set_abs_ydoy_time(fd, cinfo, col);
1834     break;
1835
1836   case COL_REL_TIME:
1837     col_set_rel_time(fd, cinfo, col);
1838     break;
1839
1840   case COL_DELTA_TIME:
1841     col_set_delta_time(fd, cinfo, col);
1842     break;
1843
1844   case COL_DELTA_TIME_DIS:
1845     col_set_delta_time_dis(fd, cinfo, col);
1846     break;
1847
1848   case COL_UTC_TIME:
1849     col_set_utc_time(fd, cinfo, col);
1850     break;
1851
1852   case COL_UTC_YMD_TIME:
1853     col_set_utc_ymd_time(fd, cinfo, col);
1854     break;
1855
1856   case COL_UTC_YDOY_TIME:
1857     col_set_utc_ydoy_time(fd, cinfo, col);
1858     break;
1859
1860   default:
1861     g_assert_not_reached();
1862     break;
1863   }
1864 }
1865
1866 /* --------------------------- */
1867 /* Set the given (relative) time to a column element.
1868  *
1869  * Used by dissectors to set the time in a column
1870  *
1871  * @param cinfo         the current packet row
1872  * @param el            the column to use, e.g. COL_INFO
1873  * @param ts            the time to set in the column
1874  * @param fieldname     the fieldname to use for creating a filter (when
1875  *                        applying/preparing/copying as filter)
1876  */
1877 void
1878 col_set_time(column_info *cinfo, const gint el, const nstime_t *ts, const char *fieldname)
1879 {
1880   int col;
1881   col_item_t* col_item;
1882
1883   if (!CHECK_COL(cinfo, el))
1884     return;
1885
1886   /** @todo TODO: We don't respect fd->ref_time (no way to access 'fd')
1887   COL_CHECK_REF_TIME(fd, buf);
1888   */
1889
1890   for (col = cinfo->col_first[el]; col <= cinfo->col_last[el]; col++) {
1891     col_item = &cinfo->columns[col];
1892     if (col_item->fmt_matx[el]) {
1893       switch (timestamp_get_precision()) {
1894       case TS_PREC_FIXED_SEC:
1895         display_signed_time(col_item->col_buf, COL_MAX_LEN,
1896           (gint32) ts->secs, ts->nsecs / 1000000000, TO_STR_TIME_RES_T_SECS);
1897         break;
1898       case TS_PREC_FIXED_DSEC:
1899         display_signed_time(col_item->col_buf, COL_MAX_LEN,
1900           (gint32) ts->secs, ts->nsecs / 100000000, TO_STR_TIME_RES_T_DSECS);
1901         break;
1902       case TS_PREC_FIXED_CSEC:
1903         display_signed_time(col_item->col_buf, COL_MAX_LEN,
1904           (gint32) ts->secs, ts->nsecs / 10000000, TO_STR_TIME_RES_T_CSECS);
1905         break;
1906       case TS_PREC_FIXED_MSEC:
1907         display_signed_time(col_item->col_buf, COL_MAX_LEN,
1908           (gint32) ts->secs, ts->nsecs / 1000000, TO_STR_TIME_RES_T_MSECS);
1909         break;
1910       case TS_PREC_FIXED_USEC:
1911         display_signed_time(col_item->col_buf, COL_MAX_LEN,
1912           (gint32) ts->secs, ts->nsecs / 1000, TO_STR_TIME_RES_T_USECS);
1913         break;
1914       case TS_PREC_FIXED_NSEC:
1915       case TS_PREC_AUTO:    /* default to maximum */
1916         display_signed_time(col_item->col_buf, COL_MAX_LEN,
1917           (gint32) ts->secs, ts->nsecs, TO_STR_TIME_RES_T_NSECS);
1918         break;
1919       default:
1920         g_assert_not_reached();
1921       }
1922       col_item->col_data = col_item->col_buf;
1923       cinfo->col_expr.col_expr[col] = fieldname;
1924       g_strlcpy(cinfo->col_expr.col_expr_val[col],col_item->col_buf,COL_MAX_LEN);
1925     }
1926   }
1927 }
1928
1929 static void
1930 col_set_addr(packet_info *pinfo, const int col, const address *addr, const gboolean is_src,
1931              const gboolean fill_col_exprs, const gboolean res)
1932 {
1933   const char *name;
1934   col_item_t* col_item = &pinfo->cinfo->columns[col];
1935
1936   if (addr->type == AT_NONE) {
1937     /* No address, nothing to do */
1938     return;
1939   }
1940
1941   if (res && (name = address_to_name(addr)) != NULL)
1942     col_item->col_data = name;
1943   else {
1944     col_item->col_data = col_item->col_buf;
1945     address_to_str_buf(addr, col_item->col_buf, COL_MAX_LEN);
1946   }
1947
1948   if (!fill_col_exprs)
1949     return;
1950
1951   pinfo->cinfo->col_expr.col_expr[col] = address_type_column_filter_string(addr, is_src);
1952   /* For address types that have a filter, create a string */
1953   if (strlen(pinfo->cinfo->col_expr.col_expr[col]) > 0)
1954     address_to_str_buf(addr, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
1955 }
1956
1957 /* ------------------------ */
1958 static void
1959 col_set_port(packet_info *pinfo, const int col, const gboolean is_res, const gboolean is_src, const gboolean fill_col_exprs _U_)
1960 {
1961   guint32 port;
1962   col_item_t* col_item = &pinfo->cinfo->columns[col];
1963
1964   if (is_src)
1965     port = pinfo->srcport;
1966   else
1967     port = pinfo->destport;
1968
1969   /* TODO: Use fill_col_exprs */
1970
1971   switch (pinfo->ptype) {
1972   case PT_SCTP:
1973     if (is_res)
1974       g_strlcpy(col_item->col_buf, sctp_port_to_display(pinfo->pool, port), COL_MAX_LEN);
1975     else
1976       guint32_to_str_buf(port, col_item->col_buf, COL_MAX_LEN);
1977     break;
1978
1979   case PT_TCP:
1980     guint32_to_str_buf(port, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
1981     if (is_res)
1982       g_strlcpy(col_item->col_buf, tcp_port_to_display(pinfo->pool, port), COL_MAX_LEN);
1983     else
1984       g_strlcpy(col_item->col_buf, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
1985     if (is_src)
1986       pinfo->cinfo->col_expr.col_expr[col] = "tcp.srcport";
1987     else
1988       pinfo->cinfo->col_expr.col_expr[col] = "tcp.dstport";
1989     break;
1990
1991   case PT_UDP:
1992     guint32_to_str_buf(port, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
1993     if (is_res)
1994       g_strlcpy(col_item->col_buf, udp_port_to_display(pinfo->pool, port), COL_MAX_LEN);
1995     else
1996       g_strlcpy(col_item->col_buf, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
1997     if (is_src)
1998       pinfo->cinfo->col_expr.col_expr[col] = "udp.srcport";
1999     else
2000       pinfo->cinfo->col_expr.col_expr[col] = "udp.dstport";
2001     break;
2002
2003   case PT_DDP:
2004     if (is_src)
2005       pinfo->cinfo->col_expr.col_expr[col] = "ddp.src_socket";
2006     else
2007       pinfo->cinfo->col_expr.col_expr[col] = "ddp.dst_socket";
2008     guint32_to_str_buf(port, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
2009     g_strlcpy(col_item->col_buf, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
2010     break;
2011
2012   case PT_IPX:
2013     /* XXX - resolve IPX socket numbers */
2014     ws_snprintf(col_item->col_buf, COL_MAX_LEN, "0x%04x", port);
2015     g_strlcpy(pinfo->cinfo->col_expr.col_expr_val[col], col_item->col_buf,COL_MAX_LEN);
2016     if (is_src)
2017       pinfo->cinfo->col_expr.col_expr[col] = "ipx.src.socket";
2018     else
2019       pinfo->cinfo->col_expr.col_expr[col] = "ipx.dst.socket";
2020     break;
2021
2022   case PT_IDP:
2023     /* XXX - resolve IDP socket numbers */
2024     ws_snprintf(col_item->col_buf, COL_MAX_LEN, "0x%04x", port);
2025     g_strlcpy(pinfo->cinfo->col_expr.col_expr_val[col], col_item->col_buf,COL_MAX_LEN);
2026     if (is_src)
2027       pinfo->cinfo->col_expr.col_expr[col] = "idp.src.socket";
2028     else
2029       pinfo->cinfo->col_expr.col_expr[col] = "idp.dst.socket";
2030     break;
2031
2032   case PT_USB:
2033     /* XXX - resolve USB endpoint numbers */
2034     ws_snprintf(col_item->col_buf, COL_MAX_LEN, "0x%08x", port);
2035     g_strlcpy(pinfo->cinfo->col_expr.col_expr_val[col], col_item->col_buf,COL_MAX_LEN);
2036     if (is_src)
2037       pinfo->cinfo->col_expr.col_expr[col] = "usb.src.endpoint";
2038     else
2039       pinfo->cinfo->col_expr.col_expr[col] = "usb.dst.endpoint";
2040     break;
2041
2042   default:
2043     break;
2044   }
2045   col_item->col_data = col_item->col_buf;
2046 }
2047
2048 gboolean
2049 col_based_on_frame_data(column_info *cinfo, const gint col)
2050 {
2051   g_assert(cinfo);
2052   g_assert(col < cinfo->num_cols);
2053
2054   switch (cinfo->columns[col].col_fmt) {
2055   case COL_NUMBER:
2056   case COL_CLS_TIME:
2057   case COL_ABS_TIME:
2058   case COL_ABS_YMD_TIME:
2059   case COL_ABS_YDOY_TIME:
2060   case COL_UTC_TIME:
2061   case COL_UTC_YMD_TIME:
2062   case COL_UTC_YDOY_TIME:
2063   case COL_REL_TIME:
2064   case COL_DELTA_TIME:
2065   case COL_DELTA_TIME_DIS:
2066   case COL_PACKET_LENGTH:
2067   case COL_CUMULATIVE_BYTES:
2068     return TRUE;
2069
2070   default:
2071     return FALSE;
2072   }
2073 }
2074
2075 void
2076 col_fill_in_frame_data(const frame_data *fd, column_info *cinfo, const gint col, const gboolean fill_col_exprs)
2077 {
2078   col_item_t* col_item = &cinfo->columns[col];
2079
2080   switch (col_item->col_fmt) {
2081   case COL_NUMBER:
2082     guint32_to_str_buf(fd->num, col_item->col_buf, COL_MAX_LEN);
2083     col_item->col_data = col_item->col_buf;
2084     break;
2085
2086   case COL_CLS_TIME:
2087   case COL_ABS_TIME:
2088   case COL_ABS_YMD_TIME:
2089   case COL_ABS_YDOY_TIME:
2090   case COL_UTC_TIME:
2091   case COL_UTC_YMD_TIME:
2092   case COL_UTC_YDOY_TIME:
2093   case COL_REL_TIME:
2094   case COL_DELTA_TIME:
2095   case COL_DELTA_TIME_DIS:
2096     /* TODO: Pass on fill_col_exprs */
2097     col_set_fmt_time(fd, cinfo, col_item->col_fmt, col);
2098     break;
2099
2100   case COL_PACKET_LENGTH:
2101     guint32_to_str_buf(fd->pkt_len, col_item->col_buf, COL_MAX_LEN);
2102     col_item->col_data = col_item->col_buf;
2103     break;
2104
2105   case COL_CUMULATIVE_BYTES:
2106     guint32_to_str_buf(fd->cum_bytes, col_item->col_buf, COL_MAX_LEN);
2107     col_item->col_data = col_item->col_buf;
2108     break;
2109
2110   default:
2111     break;
2112   }
2113
2114   if (!fill_col_exprs)
2115     return;
2116
2117   switch (col_item->col_fmt) {
2118   case COL_NUMBER:
2119     cinfo->col_expr.col_expr[col] = "frame.number";
2120     g_strlcpy(cinfo->col_expr.col_expr_val[col], col_item->col_buf, COL_MAX_LEN);
2121     break;
2122
2123   case COL_CLS_TIME:
2124   case COL_ABS_TIME:
2125   case COL_ABS_YMD_TIME:
2126   case COL_ABS_YDOY_TIME:
2127   case COL_UTC_TIME:
2128   case COL_UTC_YMD_TIME:
2129   case COL_UTC_YDOY_TIME:
2130   case COL_REL_TIME:
2131   case COL_DELTA_TIME:
2132   case COL_DELTA_TIME_DIS:
2133     /* Already handled above */
2134     break;
2135
2136   case COL_PACKET_LENGTH:
2137     cinfo->col_expr.col_expr[col] = "frame.len";
2138     g_strlcpy(cinfo->col_expr.col_expr_val[col], col_item->col_buf, COL_MAX_LEN);
2139     break;
2140
2141   case COL_CUMULATIVE_BYTES:
2142     break;
2143
2144   default:
2145     break;
2146   }
2147 }
2148
2149 void
2150 col_fill_in(packet_info *pinfo, const gboolean fill_col_exprs, const gboolean fill_fd_colums)
2151 {
2152   int i;
2153   col_item_t* col_item;
2154
2155   if (!pinfo->cinfo)
2156     return;
2157
2158   for (i = 0; i < pinfo->cinfo->num_cols; i++) {
2159     col_item = &pinfo->cinfo->columns[i];
2160     if (col_based_on_frame_data(pinfo->cinfo, i)) {
2161       if (fill_fd_colums)
2162         col_fill_in_frame_data(pinfo->fd, pinfo->cinfo, i, fill_col_exprs);
2163     } else {
2164       switch (col_item->col_fmt) {
2165       case COL_DEF_SRC:
2166       case COL_RES_SRC:   /* COL_DEF_SRC is currently just like COL_RES_SRC */
2167         col_set_addr(pinfo, i, &pinfo->src, TRUE, fill_col_exprs, TRUE);
2168         break;
2169
2170       case COL_UNRES_SRC:
2171         col_set_addr(pinfo, i, &pinfo->src, TRUE, fill_col_exprs, FALSE);
2172         break;
2173
2174       case COL_DEF_DL_SRC:
2175       case COL_RES_DL_SRC:
2176         col_set_addr(pinfo, i, &pinfo->dl_src, TRUE, fill_col_exprs, TRUE);
2177         break;
2178
2179       case COL_UNRES_DL_SRC:
2180         col_set_addr(pinfo, i, &pinfo->dl_src, TRUE, fill_col_exprs, FALSE);
2181         break;
2182
2183       case COL_DEF_NET_SRC:
2184       case COL_RES_NET_SRC:
2185         col_set_addr(pinfo, i, &pinfo->net_src, TRUE, fill_col_exprs, TRUE);
2186         break;
2187
2188       case COL_UNRES_NET_SRC:
2189         col_set_addr(pinfo, i, &pinfo->net_src, TRUE, fill_col_exprs, FALSE);
2190         break;
2191
2192       case COL_DEF_DST:
2193       case COL_RES_DST:   /* COL_DEF_DST is currently just like COL_RES_DST */
2194         col_set_addr(pinfo, i, &pinfo->dst, FALSE, fill_col_exprs, TRUE);
2195         break;
2196
2197       case COL_UNRES_DST:
2198         col_set_addr(pinfo, i, &pinfo->dst, FALSE, fill_col_exprs, FALSE);
2199         break;
2200
2201       case COL_DEF_DL_DST:
2202       case COL_RES_DL_DST:
2203         col_set_addr(pinfo, i, &pinfo->dl_dst, FALSE, fill_col_exprs, TRUE);
2204         break;
2205
2206       case COL_UNRES_DL_DST:
2207         col_set_addr(pinfo, i, &pinfo->dl_dst, FALSE, fill_col_exprs, FALSE);
2208         break;
2209
2210       case COL_DEF_NET_DST:
2211       case COL_RES_NET_DST:
2212         col_set_addr(pinfo, i, &pinfo->net_dst, FALSE, fill_col_exprs, TRUE);
2213         break;
2214
2215       case COL_UNRES_NET_DST:
2216         col_set_addr(pinfo, i, &pinfo->net_dst, FALSE, fill_col_exprs, FALSE);
2217         break;
2218
2219       case COL_DEF_SRC_PORT:
2220       case COL_RES_SRC_PORT:  /* COL_DEF_SRC_PORT is currently just like COL_RES_SRC_PORT */
2221         col_set_port(pinfo, i, TRUE, TRUE, fill_col_exprs);
2222         break;
2223
2224       case COL_UNRES_SRC_PORT:
2225         col_set_port(pinfo, i, FALSE, TRUE, fill_col_exprs);
2226         break;
2227
2228       case COL_DEF_DST_PORT:
2229       case COL_RES_DST_PORT:  /* COL_DEF_DST_PORT is currently just like COL_RES_DST_PORT */
2230         col_set_port(pinfo, i, TRUE, FALSE, fill_col_exprs);
2231         break;
2232
2233       case COL_UNRES_DST_PORT:
2234         col_set_port(pinfo, i, FALSE, FALSE, fill_col_exprs);
2235         break;
2236
2237       case NUM_COL_FMTS:  /* keep compiler happy - shouldn't get here */
2238         g_assert_not_reached();
2239         break;
2240       default:
2241         if (col_item->col_fmt >= NUM_COL_FMTS) {
2242           g_assert_not_reached();
2243         }
2244         /*
2245          * Formatting handled by col_custom_set_edt() (COL_CUSTOM), expert.c
2246          * (COL_EXPERT), or individual dissectors.
2247          */
2248         break;
2249       }
2250     }
2251   }
2252 }
2253
2254 /*
2255  * Fill in columns if we got an error reading the packet.
2256  * We set most columns to "???", fill in columns that don't need data read
2257  * from the file, and set the Info column to an error message.
2258  */
2259 void
2260 col_fill_in_error(column_info *cinfo, frame_data *fdata, const gboolean fill_col_exprs, const gboolean fill_fd_colums)
2261 {
2262   int i;
2263   col_item_t* col_item;
2264
2265   if (!cinfo)
2266     return;
2267
2268   for (i = 0; i < cinfo->num_cols; i++) {
2269     col_item = &cinfo->columns[i];
2270     if (col_based_on_frame_data(cinfo, i)) {
2271       if (fill_fd_colums)
2272         col_fill_in_frame_data(fdata, cinfo, i, fill_col_exprs);
2273     } else if (col_item->col_fmt == COL_INFO) {
2274       /* XXX - say more than this */
2275       col_item->col_data = "Read error";
2276     } else {
2277       if (col_item->col_fmt >= NUM_COL_FMTS) {
2278         g_assert_not_reached();
2279       }
2280       /*
2281        * No dissection was done, and these columns are set as the
2282        * result of the dissection, so....
2283        */
2284       col_item->col_data = "???";
2285       break;
2286     }
2287   }
2288 }
2289
2290 gboolean col_data_changed(void) {
2291   gboolean cur_cdc = col_data_changed_;
2292   col_data_changed_ = FALSE;
2293   return cur_cdc;
2294 }
2295 /*
2296  * Editor modelines
2297  *
2298  * Local Variables:
2299  * c-basic-offset: 2
2300  * tab-width: 8
2301  * indent-tabs-mode: nil
2302  * End:
2303  *
2304  * ex: set shiftwidth=2 tabstop=8 expandtab:
2305  * :indentSize=2:tabSize=8:noTabs=true:
2306  */