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