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