Get the Windows build going again.
[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             g_assert(hfinfo);
252             cinfo->col_custom_field_id[i] = hfinfo->id;
253         }
254     }
255   }
256 }
257
258 /*  Appends a vararg list to a packet info string.
259  *  This function's code is duplicated in col_append_sep_fstr() below because
260  *  the for() loop below requires us to call va_start/va_end so intermediate
261  *  functions are a problem.
262  */
263 void
264 col_append_fstr(column_info *cinfo, const gint el, const gchar *format, ...)
265 {
266   int  i;
267   int  len, max_len;
268   va_list ap;
269
270   if (!CHECK_COL(cinfo, el))
271     return;
272
273   if (el == COL_INFO)
274     max_len = COL_MAX_INFO_LEN;
275   else
276     max_len = COL_MAX_LEN;
277
278   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
279     if (cinfo->fmt_matx[i][el]) {
280       /*
281        * First arrange that we can append, if necessary.
282        */
283       COL_CHECK_APPEND(cinfo, i, max_len);
284
285       len = (int) strlen(cinfo->col_buf[i]);
286
287       va_start(ap, format);
288       g_vsnprintf(&cinfo->col_buf[i][len], max_len - len, format, ap);
289       va_end(ap);
290     }
291   }
292
293 }
294
295 /*  Appends a vararg list to a packet info string.
296  *  Prefixes it with the given separator if the column is not empty.
297  *  Code is duplicated from col_append_fstr above().
298  */
299 void
300 col_append_sep_fstr(column_info *cinfo, const gint el, const gchar *separator,
301                     const gchar *format, ...)
302 {
303   int  i;
304   int  len, max_len, sep_len;
305   va_list ap;
306
307   if (!CHECK_COL(cinfo, el))
308     return;
309
310   if (separator == NULL)
311     separator = ", ";    /* default */
312
313   sep_len = (int) strlen(separator);
314
315   if (el == COL_INFO)
316     max_len = COL_MAX_INFO_LEN;
317   else
318     max_len = COL_MAX_LEN;
319
320   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
321     if (cinfo->fmt_matx[i][el]) {
322       /*
323        * First arrange that we can append, if necessary.
324        */
325       COL_CHECK_APPEND(cinfo, i, max_len);
326
327       len = (int) strlen(cinfo->col_buf[i]);
328
329       /*
330        * If we have a separator, append it if the column isn't empty.
331        */
332       if (separator != NULL) {
333         if (len != 0) {
334           g_strlcat(cinfo->col_buf[i], separator, max_len);
335           len += sep_len;
336         }
337       }
338       va_start(ap, format);
339       g_vsnprintf(&cinfo->col_buf[i][len], max_len - len, format, ap);
340       va_end(ap);
341     }
342   }
343 }
344
345 /* Prepends a vararg list to a packet info string. */
346 #define COL_BUF_MAX_LEN (((COL_MAX_INFO_LEN) > (COL_MAX_LEN)) ? \
347     (COL_MAX_INFO_LEN) : (COL_MAX_LEN))
348 void
349 col_prepend_fstr(column_info *cinfo, const gint el, const gchar *format, ...)
350 {
351   va_list     ap;
352   int         i;
353   char        orig_buf[COL_BUF_MAX_LEN];
354   const char *orig;
355   int         max_len;
356
357   if (!CHECK_COL(cinfo, el))
358     return;
359
360   if (el == COL_INFO)
361     max_len = COL_MAX_INFO_LEN;
362   else
363     max_len = COL_MAX_LEN;
364
365   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
366     if (cinfo->fmt_matx[i][el]) {
367       if (cinfo->col_data[i] != cinfo->col_buf[i]) {
368         /* This was set with "col_set_str()"; which is effectively const */
369         orig = cinfo->col_data[i];
370       } else {
371         g_strlcpy(orig_buf, cinfo->col_buf[i], max_len);
372         orig = orig_buf;
373       }
374       va_start(ap, format);
375       g_vsnprintf(cinfo->col_buf[i], max_len, format, ap);
376       va_end(ap);
377
378       /*
379        * Move the fence, unless it's at the beginning of the string.
380        */
381       if (cinfo->col_fence[i] > 0)
382         cinfo->col_fence[i] += (int) strlen(cinfo->col_buf[i]);
383
384       g_strlcat(cinfo->col_buf[i], orig, max_len);
385       cinfo->col_data[i] = cinfo->col_buf[i];
386     }
387   }
388 }
389 void
390 col_prepend_fence_fstr(column_info *cinfo, const gint el, const gchar *format, ...)
391 {
392   va_list     ap;
393   int         i;
394   char        orig_buf[COL_BUF_MAX_LEN];
395   const char *orig;
396   int         max_len;
397
398   if (!CHECK_COL(cinfo, el))
399     return;
400
401   if (el == COL_INFO)
402     max_len = COL_MAX_INFO_LEN;
403   else
404     max_len = COL_MAX_LEN;
405
406   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
407     if (cinfo->fmt_matx[i][el]) {
408       if (cinfo->col_data[i] != cinfo->col_buf[i]) {
409         /* This was set with "col_set_str()"; which is effectively const */
410         orig = cinfo->col_data[i];
411       } else {
412         g_strlcpy(orig_buf, cinfo->col_buf[i], max_len);
413         orig = orig_buf;
414       }
415       va_start(ap, format);
416       g_vsnprintf(cinfo->col_buf[i], max_len, format, ap);
417       va_end(ap);
418
419       /*
420        * Move the fence if it exists, else create a new fence at the
421        * end of the prepended data.
422        */
423       if (cinfo->col_fence[i] > 0) {
424         cinfo->col_fence[i] += (int) strlen(cinfo->col_buf[i]);
425       } else {
426         cinfo->col_fence[i]  = (int) strlen(cinfo->col_buf[i]);
427       }
428       g_strlcat(cinfo->col_buf[i], orig, max_len);
429       cinfo->col_data[i] = cinfo->col_buf[i];
430     }
431   }
432 }
433
434 /* Use this if "str" points to something that won't stay around (and
435    must thus be copied). */
436 void
437 col_add_str(column_info *cinfo, const gint el, const gchar* str)
438 {
439   int    i;
440   int    fence;
441   size_t max_len;
442
443   if (!CHECK_COL(cinfo, el))
444     return;
445
446   if (el == COL_INFO)
447     max_len = COL_MAX_INFO_LEN;
448   else
449     max_len = COL_MAX_LEN;
450
451   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
452     if (cinfo->fmt_matx[i][el]) {
453       fence = cinfo->col_fence[i];
454       if (fence != 0) {
455         /*
456          * We will append the string after the fence.
457          * First arrange that we can append, if necessary.
458          */
459         COL_CHECK_APPEND(cinfo, i, max_len);
460       } else {
461         /*
462          * There's no fence, so we can just write to the string.
463          */
464         cinfo->col_data[i] = cinfo->col_buf[i];
465       }
466       g_strlcpy(&cinfo->col_buf[i][fence], str, max_len - fence);
467     }
468   }
469 }
470
471 /* Use this if "str" points to something that will stay around (and thus
472    needn't be copied). */
473 void
474 col_set_str(column_info *cinfo, const gint el, const gchar* str)
475 {
476   int i;
477   int fence;
478   size_t max_len;
479
480   DISSECTOR_ASSERT(str);
481
482   /* The caller is expected to pass in something that 'will stay around' and
483    * something from the ephemeral pool certainly doesn't fit the bill. */
484   DISSECTOR_ASSERT(!ep_verify_pointer(str));
485
486   if (!CHECK_COL(cinfo, el))
487     return;
488
489   if (el == COL_INFO)
490     max_len = COL_MAX_INFO_LEN;
491   else
492     max_len = COL_MAX_LEN;
493
494   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
495     if (cinfo->fmt_matx[i][el]) {
496       fence = cinfo->col_fence[i];
497       if (fence != 0) {
498         /*
499          * We will append the string after the fence.
500          * First arrange that we can append, if necessary.
501          */
502         COL_CHECK_APPEND(cinfo, i, max_len);
503
504         g_strlcpy(&cinfo->col_buf[i][fence], str, max_len - fence);
505       } else {
506         /*
507          * There's no fence, so we can just set the column to point
508          * to the string.
509          */
510         cinfo->col_data[i] = str;
511       }
512     }
513   }
514 }
515
516 /* Adds a vararg list to a packet info string. */
517 void
518 col_add_fstr(column_info *cinfo, const gint el, const gchar *format, ...) {
519   va_list ap;
520   int     i;
521   int     fence;
522   int     max_len;
523
524   if (!CHECK_COL(cinfo, el))
525     return;
526
527   if (el == COL_INFO)
528     max_len = COL_MAX_INFO_LEN;
529   else
530     max_len = COL_MAX_LEN;
531
532   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
533     if (cinfo->fmt_matx[i][el]) {
534       fence = cinfo->col_fence[i];
535       if (fence != 0) {
536         /*
537          * We will append the string after the fence.
538          * First arrange that we can append, if necessary.
539          */
540         COL_CHECK_APPEND(cinfo, i, max_len);
541       } else {
542         /*
543          * There's no fence, so we can just write to the string.
544          */
545         cinfo->col_data[i] = cinfo->col_buf[i];
546       }
547       va_start(ap, format);
548       g_vsnprintf(&cinfo->col_buf[i][fence], max_len - fence, format, ap);
549       va_end(ap);
550     }
551   }
552 }
553
554 static void
555 col_do_append_str(column_info *cinfo, const gint el, const gchar* separator,
556     const gchar* str)
557 {
558   int    i;
559   size_t len, max_len;
560
561   if (el == COL_INFO)
562     max_len = COL_MAX_INFO_LEN;
563   else
564     max_len = COL_MAX_LEN;
565
566   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
567     if (cinfo->fmt_matx[i][el]) {
568       /*
569        * First arrange that we can append, if necessary.
570        */
571       COL_CHECK_APPEND(cinfo, i, max_len);
572
573       len = cinfo->col_buf[i][0];
574
575       /*
576        * If we have a separator, append it if the column isn't empty.
577        */
578       if (separator != NULL) {
579         if (len != 0) {
580           g_strlcat(cinfo->col_buf[i], separator, max_len);
581         }
582       }
583       g_strlcat(cinfo->col_buf[i], str, max_len);
584     }
585   }
586 }
587
588 void
589 col_append_str(column_info *cinfo, const gint el, const gchar* str)
590 {
591   if (!CHECK_COL(cinfo, el))
592     return;
593
594   col_do_append_str(cinfo, el, NULL, str);
595 }
596
597 void
598 col_append_sep_str(column_info *cinfo, const gint el, const gchar* separator,
599     const gchar* str)
600 {
601   if (!CHECK_COL(cinfo, el))
602     return;
603
604   if (separator == NULL)
605     separator = ", ";    /* default */
606
607   col_do_append_str(cinfo, el, separator, str);
608 }
609
610 /* --------------------------------- */
611 gboolean
612 col_has_time_fmt(column_info *cinfo, const gint col)
613 {
614   return ((cinfo->fmt_matx[col][COL_CLS_TIME]) ||
615           (cinfo->fmt_matx[col][COL_ABS_TIME]) ||
616           (cinfo->fmt_matx[col][COL_ABS_DATE_TIME]) ||
617           (cinfo->fmt_matx[col][COL_REL_TIME]) ||
618           (cinfo->fmt_matx[col][COL_DELTA_TIME]) ||
619           (cinfo->fmt_matx[col][COL_DELTA_TIME_DIS]));
620 }
621
622 static gint
623 set_abs_date_time(const frame_data *fd, gchar *buf)
624 {
625   struct tm *tmp;
626   time_t then;
627
628   then = fd->abs_ts.secs;
629   tmp = localtime(&then);
630   if (tmp != NULL) {
631       switch(timestamp_get_precision()) {
632       case TS_PREC_FIXED_SEC:
633       case TS_PREC_AUTO_SEC:
634           g_snprintf(buf, COL_MAX_LEN,"%04d-%02d-%02d %02d:%02d:%02d",
635              tmp->tm_year + 1900,
636              tmp->tm_mon + 1,
637              tmp->tm_mday,
638              tmp->tm_hour,
639              tmp->tm_min,
640              tmp->tm_sec);
641           break;
642       case TS_PREC_FIXED_DSEC:
643       case TS_PREC_AUTO_DSEC:
644           g_snprintf(buf, COL_MAX_LEN,"%04d-%02d-%02d %02d:%02d:%02d.%01ld",
645              tmp->tm_year + 1900,
646              tmp->tm_mon + 1,
647              tmp->tm_mday,
648              tmp->tm_hour,
649              tmp->tm_min,
650              tmp->tm_sec,
651              (long)fd->abs_ts.nsecs / 100000000);
652           break;
653       case TS_PREC_FIXED_CSEC:
654       case TS_PREC_AUTO_CSEC:
655           g_snprintf(buf, COL_MAX_LEN,"%04d-%02d-%02d %02d:%02d:%02d.%02ld",
656              tmp->tm_year + 1900,
657              tmp->tm_mon + 1,
658              tmp->tm_mday,
659              tmp->tm_hour,
660              tmp->tm_min,
661              tmp->tm_sec,
662              (long)fd->abs_ts.nsecs / 10000000);
663           break;
664       case TS_PREC_FIXED_MSEC:
665       case TS_PREC_AUTO_MSEC:
666           g_snprintf(buf, COL_MAX_LEN, "%04d-%02d-%02d %02d:%02d:%02d.%03ld",
667              tmp->tm_year + 1900,
668              tmp->tm_mon + 1,
669              tmp->tm_mday,
670              tmp->tm_hour,
671              tmp->tm_min,
672              tmp->tm_sec,
673              (long)fd->abs_ts.nsecs / 1000000);
674           break;
675       case TS_PREC_FIXED_USEC:
676       case TS_PREC_AUTO_USEC:
677           g_snprintf(buf, COL_MAX_LEN, "%04d-%02d-%02d %02d:%02d:%02d.%06ld",
678              tmp->tm_year + 1900,
679              tmp->tm_mon + 1,
680              tmp->tm_mday,
681              tmp->tm_hour,
682              tmp->tm_min,
683              tmp->tm_sec,
684              (long)fd->abs_ts.nsecs / 1000);
685           break;
686       case TS_PREC_FIXED_NSEC:
687       case TS_PREC_AUTO_NSEC:
688           g_snprintf(buf, COL_MAX_LEN, "%04d-%02d-%02d %02d:%02d:%02d.%09ld",
689              tmp->tm_year + 1900,
690              tmp->tm_mon + 1,
691              tmp->tm_mday,
692              tmp->tm_hour,
693              tmp->tm_min,
694              tmp->tm_sec,
695              (long)fd->abs_ts.nsecs);
696           break;
697       default:
698           g_assert_not_reached();
699       }
700   } else {
701     buf[0] = '\0';
702   }
703   return 1;
704 }
705
706 static void
707 col_set_abs_date_time(const frame_data *fd, column_info *cinfo, const int col)
708 {
709   if (set_abs_date_time(fd, cinfo->col_buf[col])) {
710       cinfo->col_expr.col_expr[col] = "frame.time";
711       g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->col_buf[col],COL_MAX_LEN);
712   }
713   cinfo->col_data[col] = cinfo->col_buf[col];
714 }
715
716 static gint
717 set_time_seconds(const nstime_t *ts, gchar *buf)
718 {
719   switch(timestamp_get_precision()) {
720       case TS_PREC_FIXED_SEC:
721       case TS_PREC_AUTO_SEC:
722           display_signed_time(buf, COL_MAX_LEN,
723             (gint32) ts->secs, ts->nsecs / 1000000000, TO_STR_TIME_RES_T_SECS);
724           break;
725       case TS_PREC_FIXED_DSEC:
726       case TS_PREC_AUTO_DSEC:
727           display_signed_time(buf, COL_MAX_LEN,
728             (gint32) ts->secs, ts->nsecs / 100000000, TO_STR_TIME_RES_T_DSECS);
729           break;
730       case TS_PREC_FIXED_CSEC:
731       case TS_PREC_AUTO_CSEC:
732           display_signed_time(buf, COL_MAX_LEN,
733             (gint32) ts->secs, ts->nsecs / 10000000, TO_STR_TIME_RES_T_CSECS);
734           break;
735       case TS_PREC_FIXED_MSEC:
736       case TS_PREC_AUTO_MSEC:
737           display_signed_time(buf, COL_MAX_LEN,
738             (gint32) ts->secs, ts->nsecs / 1000000, TO_STR_TIME_RES_T_MSECS);
739           break;
740       case TS_PREC_FIXED_USEC:
741       case TS_PREC_AUTO_USEC:
742           display_signed_time(buf, COL_MAX_LEN,
743             (gint32) ts->secs, ts->nsecs / 1000, TO_STR_TIME_RES_T_USECS);
744           break;
745       case TS_PREC_FIXED_NSEC:
746       case TS_PREC_AUTO_NSEC:
747           display_signed_time(buf, COL_MAX_LEN,
748             (gint32) ts->secs, ts->nsecs, TO_STR_TIME_RES_T_NSECS);
749           break;
750       default:
751           g_assert_not_reached();
752   }
753   return 1;
754 }
755
756 static gint
757 set_time_hour_min_sec(const nstime_t *ts, gchar *buf)
758 {
759   time_t secs = ts->secs;
760   gboolean negative = FALSE;
761
762   if (secs < 0) {
763     secs = -secs;
764     negative = TRUE;
765   }
766
767   switch(timestamp_get_precision()) {
768   case TS_PREC_FIXED_SEC:
769   case TS_PREC_AUTO_SEC:
770     if (secs >= (60*60)) {
771       g_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2ds",
772                  negative ? "- " : "",
773                  (gint32) secs / (60 * 60),
774                  (gint32) (secs / 60) % 60,
775                  (gint32) secs % 60);
776     } else if (secs >= 60) {
777       g_snprintf(buf, COL_MAX_LEN, "%s%dm %2ds",
778                  negative ? "- " : "",
779                  (gint32) secs / 60,
780                  (gint32) secs % 60);
781     } else {
782       g_snprintf(buf, COL_MAX_LEN, "%s%ds",
783                  negative ? "- " : "",
784                  (gint32) secs);
785     }
786     break;
787   case TS_PREC_FIXED_DSEC:
788   case TS_PREC_AUTO_DSEC:
789     if (secs >= (60*60)) {
790       g_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d.%01lds",
791                  negative ? "- " : "",
792                  (gint32) secs / (60 * 60),
793                  (gint32) (secs / 60) % 60,
794                  (gint32) secs % 60,
795                  (long)ts->nsecs / 100000000);
796     } else if (secs >= 60) {
797       g_snprintf(buf, COL_MAX_LEN, "%s%dm %2d.%01lds",
798                  negative ? "- " : "",
799                  (gint32) secs / 60,
800                  (gint32) secs % 60,
801                  (long)ts->nsecs / 100000000);
802     } else {
803       g_snprintf(buf, COL_MAX_LEN, "%s%d.%01lds",
804                  negative ? "- " : "",
805                  (gint32) secs,
806                  (long)ts->nsecs / 100000000);
807     }
808     break;
809   case TS_PREC_FIXED_CSEC:
810   case TS_PREC_AUTO_CSEC:
811     if (secs >= (60*60)) {
812       g_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d.%02lds",
813                  negative ? "- " : "",
814                  (gint32) secs / (60 * 60),
815                  (gint32) (secs / 60) % 60,
816                  (gint32) secs % 60,
817                  (long)ts->nsecs / 10000000);
818     } else if (secs >= 60) {
819       g_snprintf(buf, COL_MAX_LEN, "%s%dm %2d.%02lds",
820                  negative ? "- " : "",
821                  (gint32) secs / 60,
822                  (gint32) secs % 60,
823                  (long)ts->nsecs / 10000000);
824     } else {
825       g_snprintf(buf, COL_MAX_LEN, "%s%d.%02lds",
826                  negative ? "- " : "",
827                  (gint32) secs,
828                  (long)ts->nsecs / 10000000);
829     }
830     break;
831   case TS_PREC_FIXED_MSEC:
832   case TS_PREC_AUTO_MSEC:
833     if (secs >= (60*60)) {
834       g_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d.%03lds",
835                  negative ? "- " : "",
836                  (gint32) secs / (60 * 60),
837                  (gint32) (secs / 60) % 60,
838                  (gint32) secs % 60,
839                  (long)ts->nsecs / 1000000);
840     } else if (secs >= 60) {
841       g_snprintf(buf, COL_MAX_LEN, "%s%dm %2d.%03lds",
842                  negative ? "- " : "",
843                  (gint32) secs / 60,
844                  (gint32) secs % 60,
845                  (long)ts->nsecs / 1000000);
846     } else {
847       g_snprintf(buf, COL_MAX_LEN, "%s%d.%03lds",
848                  negative ? "- " : "",
849                  (gint32) secs,
850                  (long)ts->nsecs / 1000000);
851     }
852     break;
853   case TS_PREC_FIXED_USEC:
854   case TS_PREC_AUTO_USEC:
855     if (secs >= (60*60)) {
856       g_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d.%06lds",
857                  negative ? "- " : "",
858                  (gint32) secs / (60 * 60),
859                  (gint32) (secs / 60) % 60,
860                  (gint32) secs % 60,
861                  (long)ts->nsecs / 1000);
862     } else if (secs >= 60) {
863       g_snprintf(buf, COL_MAX_LEN, "%s%dm %2d.%06lds",
864                  negative ? "- " : "",
865                  (gint32) secs / 60,
866                  (gint32) secs % 60,
867                  (long)ts->nsecs / 1000);
868     } else {
869       g_snprintf(buf, COL_MAX_LEN, "%s%d.%06lds",
870                  negative ? "- " : "",
871                  (gint32) secs,
872                  (long)ts->nsecs / 1000);
873     }
874     break;
875   case TS_PREC_FIXED_NSEC:
876   case TS_PREC_AUTO_NSEC:
877     if (secs >= (60*60)) {
878       g_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d.%09lds",
879                  negative ? "- " : "",
880                  (gint32) secs / (60 * 60),
881                  (gint32) (secs / 60) % 60,
882                  (gint32) secs % 60,
883                  (long)ts->nsecs);
884     } else if (secs >= 60) {
885       g_snprintf(buf, COL_MAX_LEN, "%s%dm %2d.%09lds",
886                  negative ? "- " : "",
887                  (gint32) secs / 60,
888                  (gint32) secs % 60,
889                  (long)ts->nsecs);
890     } else {
891       g_snprintf(buf, COL_MAX_LEN, "%s%d.%09lds",
892                  negative ? "- " : "",
893                  (gint32) secs,
894                  (long)ts->nsecs);
895     }
896     break;
897   default:
898     g_assert_not_reached();
899   }
900
901   return 1;
902 }
903
904 static void
905 col_set_rel_time(const frame_data *fd, column_info *cinfo, const int col)
906 {
907   switch (timestamp_get_seconds_type()) {
908   case TS_SECONDS_DEFAULT:
909     if (set_time_seconds(&fd->rel_ts, cinfo->col_buf[col])) {
910       cinfo->col_expr.col_expr[col] = "frame.time_relative";
911       g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->col_buf[col],COL_MAX_LEN);
912     }
913     break;
914   case TS_SECONDS_HOUR_MIN_SEC:
915     if (set_time_hour_min_sec(&fd->rel_ts, cinfo->col_buf[col])) {
916       cinfo->col_expr.col_expr[col] = "frame.time_relative";
917       set_time_seconds(&fd->rel_ts, cinfo->col_expr.col_expr_val[col]);
918     }
919     break;
920   default:
921     g_assert_not_reached();
922   }
923   cinfo->col_data[col] = cinfo->col_buf[col];
924 }
925
926 static void
927 col_set_delta_time(const frame_data *fd, column_info *cinfo, const int col)
928 {
929   switch (timestamp_get_seconds_type()) {
930   case TS_SECONDS_DEFAULT:
931     if (set_time_seconds(&fd->del_cap_ts, cinfo->col_buf[col])) {
932       cinfo->col_expr.col_expr[col] = "frame.time_delta";
933       g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->col_buf[col],COL_MAX_LEN);
934     }
935     break;
936   case TS_SECONDS_HOUR_MIN_SEC:
937     if (set_time_hour_min_sec(&fd->del_cap_ts, cinfo->col_buf[col])) {
938       cinfo->col_expr.col_expr[col] = "frame.time_delta";
939       set_time_seconds(&fd->del_cap_ts, cinfo->col_expr.col_expr_val[col]);
940     }
941     break;
942   default:
943     g_assert_not_reached();
944   }
945
946   cinfo->col_data[col] = cinfo->col_buf[col];
947 }
948
949 static void
950 col_set_delta_time_dis(const frame_data *fd, column_info *cinfo, const int col)
951 {
952   switch (timestamp_get_seconds_type()) {
953   case TS_SECONDS_DEFAULT:
954     if (set_time_seconds(&fd->del_dis_ts, cinfo->col_buf[col])) {
955       cinfo->col_expr.col_expr[col] = "frame.time_delta_displayed";
956       g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->col_buf[col],COL_MAX_LEN);
957     }
958     break;
959   case TS_SECONDS_HOUR_MIN_SEC:
960     if (set_time_hour_min_sec(&fd->del_dis_ts, cinfo->col_buf[col])) {
961       cinfo->col_expr.col_expr[col] = "frame.time_delta_displayed";
962       set_time_seconds(&fd->del_dis_ts, cinfo->col_expr.col_expr_val[col]);
963     }
964     break;
965   default:
966     g_assert_not_reached();
967   }
968
969   cinfo->col_data[col] = cinfo->col_buf[col];
970 }
971
972 static gint
973 set_abs_time(const frame_data *fd, gchar *buf)
974 {
975   struct tm *tmp;
976   time_t then;
977
978   then = fd->abs_ts.secs;
979   tmp = localtime(&then);
980   if (tmp != NULL) {
981       switch(timestamp_get_precision()) {
982       case TS_PREC_FIXED_SEC:
983       case TS_PREC_AUTO_SEC:
984           g_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d",
985              tmp->tm_hour,
986              tmp->tm_min,
987              tmp->tm_sec);
988           break;
989       case TS_PREC_FIXED_DSEC:
990       case TS_PREC_AUTO_DSEC:
991           g_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d.%01ld",
992              tmp->tm_hour,
993              tmp->tm_min,
994              tmp->tm_sec,
995              (long)fd->abs_ts.nsecs / 100000000);
996           break;
997       case TS_PREC_FIXED_CSEC:
998       case TS_PREC_AUTO_CSEC:
999           g_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d.%02ld",
1000              tmp->tm_hour,
1001              tmp->tm_min,
1002              tmp->tm_sec,
1003              (long)fd->abs_ts.nsecs / 10000000);
1004           break;
1005       case TS_PREC_FIXED_MSEC:
1006       case TS_PREC_AUTO_MSEC:
1007           g_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d.%03ld",
1008              tmp->tm_hour,
1009              tmp->tm_min,
1010              tmp->tm_sec,
1011              (long)fd->abs_ts.nsecs / 1000000);
1012           break;
1013       case TS_PREC_FIXED_USEC:
1014       case TS_PREC_AUTO_USEC:
1015           g_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d.%06ld",
1016              tmp->tm_hour,
1017              tmp->tm_min,
1018              tmp->tm_sec,
1019              (long)fd->abs_ts.nsecs / 1000);
1020           break;
1021       case TS_PREC_FIXED_NSEC:
1022       case TS_PREC_AUTO_NSEC:
1023           g_snprintf(buf, COL_MAX_LEN, "%02d:%02d:%02d.%09ld",
1024              tmp->tm_hour,
1025              tmp->tm_min,
1026              tmp->tm_sec,
1027              (long)fd->abs_ts.nsecs);
1028           break;
1029       default:
1030           g_assert_not_reached();
1031       }
1032
1033   } else {
1034     *buf = '\0';
1035   }
1036   return 1;
1037 }
1038
1039 static void
1040 col_set_abs_time(const frame_data *fd, column_info *cinfo, const int col)
1041 {
1042   if (set_abs_time(fd, cinfo->col_buf[col])) {
1043       cinfo->col_expr.col_expr[col] = "frame.time";
1044       g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->col_buf[col],COL_MAX_LEN);
1045   }
1046   cinfo->col_data[col] = cinfo->col_buf[col];
1047 }
1048
1049 static gint
1050 set_epoch_time(const frame_data *fd, gchar *buf)
1051 {
1052   switch(timestamp_get_precision()) {
1053       case TS_PREC_FIXED_SEC:
1054       case TS_PREC_AUTO_SEC:
1055           display_epoch_time(buf, COL_MAX_LEN,
1056             fd->abs_ts.secs, fd->abs_ts.nsecs / 1000000000, TO_STR_TIME_RES_T_SECS);
1057           break;
1058       case TS_PREC_FIXED_DSEC:
1059       case TS_PREC_AUTO_DSEC:
1060           display_epoch_time(buf, COL_MAX_LEN,
1061             fd->abs_ts.secs, fd->abs_ts.nsecs / 100000000, TO_STR_TIME_RES_T_DSECS);
1062           break;
1063       case TS_PREC_FIXED_CSEC:
1064       case TS_PREC_AUTO_CSEC:
1065           display_epoch_time(buf, COL_MAX_LEN,
1066             fd->abs_ts.secs, fd->abs_ts.nsecs / 10000000, TO_STR_TIME_RES_T_CSECS);
1067           break;
1068       case TS_PREC_FIXED_MSEC:
1069       case TS_PREC_AUTO_MSEC:
1070           display_epoch_time(buf, COL_MAX_LEN,
1071             fd->abs_ts.secs, fd->abs_ts.nsecs / 1000000, TO_STR_TIME_RES_T_MSECS);
1072           break;
1073       case TS_PREC_FIXED_USEC:
1074       case TS_PREC_AUTO_USEC:
1075           display_epoch_time(buf, COL_MAX_LEN,
1076             fd->abs_ts.secs, fd->abs_ts.nsecs / 1000, TO_STR_TIME_RES_T_USECS);
1077           break;
1078       case TS_PREC_FIXED_NSEC:
1079       case TS_PREC_AUTO_NSEC:
1080           display_epoch_time(buf, COL_MAX_LEN,
1081             fd->abs_ts.secs, fd->abs_ts.nsecs, TO_STR_TIME_RES_T_NSECS);
1082           break;
1083       default:
1084           g_assert_not_reached();
1085   }
1086   return 1;
1087 }
1088
1089 static void
1090 col_set_epoch_time(const frame_data *fd, column_info *cinfo, const int col)
1091 {
1092   if (set_epoch_time(fd, cinfo->col_buf[col])) {
1093     cinfo->col_expr.col_expr[col] = "frame.time_delta";
1094     g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->col_buf[col],COL_MAX_LEN);
1095   }
1096   cinfo->col_data[col] = cinfo->col_buf[col];
1097 }
1098
1099 #if 0
1100 /* Set the format of the variable time format.
1101    XXX - this is called from "file.c" when the user changes the time
1102    format they want for "command-line-specified" time; it's a bit ugly
1103    that we have to export it, but if we go to a CList-like widget that
1104    invokes callbacks to get the text for the columns rather than
1105    requiring us to stuff the text into the widget from outside, we
1106    might be able to clean this up. */
1107 void
1108 set_cls_time(frame_data *fd, gchar *buf)
1109 {
1110   COL_CHECK_REF_TIME(fd, cinfo->col_buf[col]);
1111
1112   switch (timestamp_get_type()) {
1113     case TS_ABSOLUTE:
1114       set_abs_time(fd, buf);
1115       break;
1116
1117     case TS_ABSOLUTE_WITH_DATE:
1118       set_abs_date_time(fd, buf);
1119       break;
1120
1121     case TS_RELATIVE:
1122       set_rel_time(fd, buf);
1123       break;
1124
1125     case TS_DELTA:
1126       set_delta_time(fd, buf);
1127       break;
1128
1129     case TS_DELTA_DIS:
1130       set_delta_time_dis(fd, buf);
1131       break;
1132
1133     case TS_EPOCH:
1134       set_epoch_time(fd, buf);
1135       break;
1136
1137     case TS_NOT_SET:
1138     /* code is missing for this case, but I don't know which [jmayer20051219] */
1139     g_assert(FALSE);
1140         break;
1141   }
1142 }
1143 #endif
1144
1145 static void
1146 col_set_cls_time(const frame_data *fd, column_info *cinfo, const gint col)
1147 {
1148   switch (timestamp_get_type()) {
1149     case TS_ABSOLUTE:
1150       col_set_abs_time(fd, cinfo, col);
1151       break;
1152
1153     case TS_ABSOLUTE_WITH_DATE:
1154       col_set_abs_date_time(fd, cinfo, col);
1155       break;
1156
1157     case TS_RELATIVE:
1158       col_set_rel_time(fd, cinfo, col);
1159       break;
1160
1161     case TS_DELTA:
1162       col_set_delta_time(fd, cinfo, col);
1163       break;
1164
1165     case TS_DELTA_DIS:
1166       col_set_delta_time_dis(fd, cinfo, col);
1167       break;
1168
1169     case TS_EPOCH:
1170       col_set_epoch_time(fd, cinfo, col);
1171       break;
1172
1173     case TS_NOT_SET:
1174       /* code is missing for this case, but I don't know which [jmayer20051219] */
1175       g_assert_not_reached();
1176       break;
1177   }
1178 }
1179
1180 /* Set the format of the variable time format.
1181    XXX - this is called from "file.c" when the user changes the time
1182    format they want for "command-line-specified" time; it's a bit ugly
1183    that we have to export it, but if we go to a CList-like widget that
1184    invokes callbacks to get the text for the columns rather than
1185    requiring us to stuff the text into the widget from outside, we
1186    might be able to clean this up. */
1187 void
1188 col_set_fmt_time(const frame_data *fd, column_info *cinfo, const gint fmt, const gint col)
1189 {
1190   COL_CHECK_REF_TIME(fd, cinfo->col_buf[col]);
1191
1192   switch (fmt) {
1193     case COL_CLS_TIME:
1194       col_set_cls_time(fd, cinfo, col);
1195       break;
1196
1197     case COL_ABS_TIME:
1198       col_set_abs_time(fd, cinfo, col);
1199       break;
1200
1201     case COL_ABS_DATE_TIME:
1202       col_set_abs_date_time(fd, cinfo, col);
1203       break;
1204
1205     case COL_REL_TIME:
1206       col_set_rel_time(fd, cinfo, col);
1207       break;
1208
1209     case COL_DELTA_TIME:
1210       col_set_delta_time(fd, cinfo, col);
1211       break;
1212
1213     case COL_DELTA_TIME_DIS:
1214       col_set_delta_time_dis(fd, cinfo, col);
1215       break;
1216
1217     default:
1218       g_assert_not_reached();
1219       break;
1220   }
1221 }
1222
1223 /* --------------------------- */
1224 /* Set the given (relative) time to a column element.
1225  *
1226  * Used by multiple dissectors to set the time in the column
1227  * COL_DELTA_CONV_TIME
1228  *
1229  * @param cinfo         the current packet row
1230  * @param col           the column to use, e.g. COL_INFO
1231  * @param ts            the time to set in the column
1232  * @param fieldname     the fieldname to use for creating a filter (when
1233  *                        applying/preparing/copying as filter)
1234  */
1235 void
1236 col_set_time(column_info *cinfo, const gint el, const nstime_t *ts, char *fieldname)
1237 {
1238   int col;
1239
1240   if (!CHECK_COL(cinfo, el))
1241     return;
1242
1243   /** @todo TODO: We don't respect fd->flags.ref_time (no way to access 'fd')
1244   COL_CHECK_REF_TIME(fd, buf);
1245   */
1246
1247   for (col = cinfo->col_first[el]; col <= cinfo->col_last[el]; col++) {
1248     if (cinfo->fmt_matx[col][el]) {
1249       switch(timestamp_get_precision()) {
1250     case TS_PREC_FIXED_SEC:
1251     case TS_PREC_AUTO_SEC:
1252       display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
1253         (gint32) ts->secs, ts->nsecs / 1000000000, TO_STR_TIME_RES_T_SECS);
1254       break;
1255     case TS_PREC_FIXED_DSEC:
1256     case TS_PREC_AUTO_DSEC:
1257       display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
1258         (gint32) ts->secs, ts->nsecs / 100000000, TO_STR_TIME_RES_T_DSECS);
1259       break;
1260     case TS_PREC_FIXED_CSEC:
1261     case TS_PREC_AUTO_CSEC:
1262       display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
1263         (gint32) ts->secs, ts->nsecs / 10000000, TO_STR_TIME_RES_T_CSECS);
1264       break;
1265     case TS_PREC_FIXED_MSEC:
1266     case TS_PREC_AUTO_MSEC:
1267       display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
1268         (gint32) ts->secs, ts->nsecs / 1000000, TO_STR_TIME_RES_T_MSECS);
1269       break;
1270     case TS_PREC_FIXED_USEC:
1271     case TS_PREC_AUTO_USEC:
1272       display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
1273         (gint32) ts->secs, ts->nsecs / 1000, TO_STR_TIME_RES_T_USECS);
1274       break;
1275     case TS_PREC_FIXED_NSEC:
1276     case TS_PREC_AUTO_NSEC:
1277       display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
1278         (gint32) ts->secs, ts->nsecs, TO_STR_TIME_RES_T_NSECS);
1279       break;
1280     default:
1281       g_assert_not_reached();
1282       }
1283       cinfo->col_data[col] = cinfo->col_buf[col];
1284       cinfo->col_expr.col_expr[col] = fieldname;
1285       g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->col_buf[col],COL_MAX_LEN);
1286     }
1287   }
1288 }
1289
1290 static void
1291 col_set_addr(packet_info *pinfo, const int col, const address *addr, const gboolean is_src, const gboolean fill_col_exprs)
1292 {
1293   if (addr->type == AT_NONE) {
1294     /* No address, nothing to do */
1295     return;
1296   }
1297
1298 #ifdef NEW_PACKET_LIST
1299   pinfo->cinfo->col_data[col] = se_get_addr_name(addr);
1300 #else
1301   get_addr_name_buf(addr, pinfo->cinfo->col_buf[col], COL_MAX_LEN);
1302   pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
1303 #endif
1304
1305   if (!fill_col_exprs)
1306     return;
1307
1308   switch (addr->type) {
1309
1310   case AT_ETHER:
1311     if (is_src)
1312       pinfo->cinfo->col_expr.col_expr[col] = "eth.src";
1313     else
1314       pinfo->cinfo->col_expr.col_expr[col] = "eth.dst";
1315     address_to_str_buf(addr, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
1316     break;
1317
1318   case AT_IPv4:
1319     if (is_src)
1320       pinfo->cinfo->col_expr.col_expr[col] = "ip.src";
1321     else
1322       pinfo->cinfo->col_expr.col_expr[col] = "ip.dst";
1323     ip_to_str_buf(addr->data, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
1324     break;
1325
1326   case AT_IPv6:
1327     if (is_src)
1328       pinfo->cinfo->col_expr.col_expr[col] = "ipv6.src";
1329     else
1330       pinfo->cinfo->col_expr.col_expr[col] = "ipv6.dst";
1331     address_to_str_buf(addr, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
1332     break;
1333
1334   case AT_ATALK:
1335     if (is_src)
1336       pinfo->cinfo->col_expr.col_expr[col] = "ddp.src";
1337     else
1338       pinfo->cinfo->col_expr.col_expr[col] = "ddp.dst";
1339     g_strlcpy(pinfo->cinfo->col_expr.col_expr_val[col], pinfo->cinfo->col_buf[col], COL_MAX_LEN);
1340     break;
1341
1342   case AT_ARCNET:
1343     if (is_src)
1344       pinfo->cinfo->col_expr.col_expr[col] = "arcnet.src";
1345     else
1346       pinfo->cinfo->col_expr.col_expr[col] = "arcnet.dst";
1347     g_strlcpy(pinfo->cinfo->col_expr.col_expr_val[col], pinfo->cinfo->col_buf[col], COL_MAX_LEN);
1348     break;
1349
1350   case AT_URI:
1351     if (is_src)
1352       pinfo->cinfo->col_expr.col_expr[col] = "uri.src";
1353     else
1354       pinfo->cinfo->col_expr.col_expr[col] = "uri.dst";
1355     address_to_str_buf(addr, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
1356     break;
1357
1358   default:
1359     break;
1360   }
1361 }
1362
1363 /* ------------------------ */
1364 static void
1365 col_set_port(packet_info *pinfo, const int col, const gboolean is_res, const gboolean is_src, const gboolean fill_col_exprs _U_)
1366 {
1367   guint32 port;
1368
1369   if (is_src)
1370     port = pinfo->srcport;
1371   else
1372     port = pinfo->destport;
1373
1374   /* TODO: Use fill_col_exprs */
1375
1376   switch (pinfo->ptype) {
1377   case PT_SCTP:
1378     if (is_res)
1379       g_strlcpy(pinfo->cinfo->col_buf[col], get_sctp_port(port), COL_MAX_LEN);
1380     else
1381       guint32_to_str_buf(port, pinfo->cinfo->col_buf[col], COL_MAX_LEN);
1382     break;
1383
1384   case PT_TCP:
1385     guint32_to_str_buf(port, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
1386     if (is_res)
1387       g_strlcpy(pinfo->cinfo->col_buf[col], get_tcp_port(port), COL_MAX_LEN);
1388     else
1389       g_strlcpy(pinfo->cinfo->col_buf[col], pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
1390     if (is_src)
1391       pinfo->cinfo->col_expr.col_expr[col] = "tcp.srcport";
1392     else
1393       pinfo->cinfo->col_expr.col_expr[col] = "tcp.dstport";
1394     break;
1395
1396   case PT_UDP:
1397     guint32_to_str_buf(port, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
1398     if (is_res)
1399       g_strlcpy(pinfo->cinfo->col_buf[col], get_udp_port(port), COL_MAX_LEN);
1400     else
1401       g_strlcpy(pinfo->cinfo->col_buf[col], pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
1402     if (is_src)
1403       pinfo->cinfo->col_expr.col_expr[col] = "udp.srcport";
1404     else
1405       pinfo->cinfo->col_expr.col_expr[col] = "udp.dstport";
1406     break;
1407
1408   case PT_DDP:
1409     if (is_src)
1410       pinfo->cinfo->col_expr.col_expr[col] = "ddp.src_socket";
1411     else
1412       pinfo->cinfo->col_expr.col_expr[col] = "ddp.dst_socket";
1413     guint32_to_str_buf(port, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
1414     g_strlcpy(pinfo->cinfo->col_buf[col], pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
1415     break;
1416
1417   case PT_IPX:
1418     /* XXX - resolve IPX socket numbers */
1419     g_snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "0x%04x", port);
1420     g_strlcpy(pinfo->cinfo->col_expr.col_expr_val[col], pinfo->cinfo->col_buf[col],COL_MAX_LEN);
1421     if (is_src)
1422       pinfo->cinfo->col_expr.col_expr[col] = "ipx.src.socket";
1423     else
1424       pinfo->cinfo->col_expr.col_expr[col] = "ipx.dst.socket";
1425     break;
1426
1427   case PT_IDP:
1428     /* XXX - resolve IDP socket numbers */
1429     g_snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "0x%04x", port);
1430     g_strlcpy(pinfo->cinfo->col_expr.col_expr_val[col], pinfo->cinfo->col_buf[col],COL_MAX_LEN);
1431     if (is_src)
1432       pinfo->cinfo->col_expr.col_expr[col] = "idp.src.socket";
1433     else
1434       pinfo->cinfo->col_expr.col_expr[col] = "idp.dst.socket";
1435     break;
1436
1437   case PT_USB:
1438     /* XXX - resolve USB endpoint numbers */
1439     g_snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "0x%08x", port);
1440     g_strlcpy(pinfo->cinfo->col_expr.col_expr_val[col], pinfo->cinfo->col_buf[col],COL_MAX_LEN);
1441     if (is_src)
1442       pinfo->cinfo->col_expr.col_expr[col] = "usb.src.endpoint";
1443     else
1444       pinfo->cinfo->col_expr.col_expr[col] = "usb.dst.endpoint";
1445     break;
1446
1447   default:
1448     break;
1449   }
1450   pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
1451 }
1452
1453 gboolean
1454 col_based_on_frame_data(column_info *cinfo, const gint col)
1455 {
1456     g_assert(cinfo);
1457     g_assert(col < cinfo->num_cols);
1458
1459     switch (cinfo->col_fmt[col]) {
1460
1461     case COL_NUMBER:
1462     case COL_CLS_TIME:
1463     case COL_ABS_TIME:
1464     case COL_ABS_DATE_TIME:
1465     case COL_REL_TIME:
1466     case COL_DELTA_TIME:
1467     case COL_DELTA_TIME_DIS:
1468     case COL_PACKET_LENGTH:
1469     case COL_CUMULATIVE_BYTES:
1470       return TRUE;
1471
1472     default:
1473         return FALSE;
1474     }
1475 }
1476
1477 void
1478 col_fill_in_frame_data(const frame_data *fd, column_info *cinfo, const gint col, const gboolean fill_col_exprs)
1479 {
1480     switch (cinfo->col_fmt[col]) {
1481
1482     case COL_NUMBER:
1483       guint32_to_str_buf(fd->num, cinfo->col_buf[col], COL_MAX_LEN);
1484       cinfo->col_data[col] = cinfo->col_buf[col];
1485       break;
1486
1487     case COL_CLS_TIME:
1488     case COL_ABS_TIME:
1489     case COL_ABS_DATE_TIME:
1490     case COL_REL_TIME:
1491     case COL_DELTA_TIME:
1492     case COL_DELTA_TIME_DIS:
1493        /* TODO: Pass on fill_col_exprs */
1494       col_set_fmt_time(fd, cinfo, cinfo->col_fmt[col], col);
1495       break;
1496
1497     case COL_PACKET_LENGTH:
1498       guint32_to_str_buf(fd->pkt_len, cinfo->col_buf[col], COL_MAX_LEN);
1499       cinfo->col_data[col] = cinfo->col_buf[col];
1500       break;
1501
1502     case COL_CUMULATIVE_BYTES:
1503       guint32_to_str_buf(fd->cum_bytes, cinfo->col_buf[col], COL_MAX_LEN);
1504       cinfo->col_data[col] = cinfo->col_buf[col];
1505       break;
1506
1507     default:
1508       break;
1509     }
1510
1511     if (!fill_col_exprs)
1512         return;
1513
1514     switch (cinfo->col_fmt[col]) {
1515
1516     case COL_NUMBER:
1517       cinfo->col_expr.col_expr[col] = "frame.number";
1518       g_strlcpy(cinfo->col_expr.col_expr_val[col], cinfo->col_buf[col], COL_MAX_LEN);
1519       break;
1520
1521     case COL_CLS_TIME:
1522     case COL_ABS_TIME:
1523     case COL_ABS_DATE_TIME:
1524     case COL_REL_TIME:
1525     case COL_DELTA_TIME:
1526     case COL_DELTA_TIME_DIS:
1527       /* Already handled above */
1528       break;
1529
1530     case COL_PACKET_LENGTH:
1531       cinfo->col_expr.col_expr[col] = "frame.len";
1532       g_strlcpy(cinfo->col_expr.col_expr_val[col], cinfo->col_buf[col], COL_MAX_LEN);
1533       break;
1534
1535     case COL_CUMULATIVE_BYTES:
1536       break;
1537
1538     default:
1539       break;
1540     }
1541 }
1542
1543 void
1544 col_fill_in(packet_info *pinfo, const gboolean fill_col_exprs, const gboolean fill_fd_colums)
1545 {
1546   int i;
1547
1548   if (!pinfo->cinfo)
1549     return;
1550
1551   for (i = 0; i < pinfo->cinfo->num_cols; i++) {
1552     switch (pinfo->cinfo->col_fmt[i]) {
1553
1554     case COL_NUMBER:
1555     case COL_CLS_TIME:
1556     case COL_ABS_TIME:
1557     case COL_ABS_DATE_TIME:
1558     case COL_REL_TIME:
1559     case COL_DELTA_TIME:
1560     case COL_DELTA_TIME_DIS:
1561     case COL_PACKET_LENGTH:
1562     case COL_CUMULATIVE_BYTES:
1563       if (fill_fd_colums)
1564         col_fill_in_frame_data(pinfo->fd, pinfo->cinfo, i, fill_col_exprs);
1565       break;
1566
1567     case COL_DEF_SRC:
1568     case COL_RES_SRC:   /* COL_DEF_SRC is currently just like COL_RES_SRC */
1569       col_set_addr(pinfo, i, &pinfo->src, TRUE, fill_col_exprs);
1570       break;
1571
1572     case COL_UNRES_SRC:
1573       col_set_addr(pinfo, i, &pinfo->src, TRUE, fill_col_exprs);
1574       break;
1575
1576     case COL_DEF_DL_SRC:
1577     case COL_RES_DL_SRC:
1578       col_set_addr(pinfo, i, &pinfo->dl_src, TRUE, fill_col_exprs);
1579       break;
1580
1581     case COL_UNRES_DL_SRC:
1582       col_set_addr(pinfo, i, &pinfo->dl_src, TRUE, fill_col_exprs);
1583       break;
1584
1585     case COL_DEF_NET_SRC:
1586     case COL_RES_NET_SRC:
1587       col_set_addr(pinfo, i, &pinfo->net_src, TRUE, fill_col_exprs);
1588       break;
1589
1590     case COL_UNRES_NET_SRC:
1591       col_set_addr(pinfo, i, &pinfo->net_src, TRUE, fill_col_exprs);
1592       break;
1593
1594     case COL_DEF_DST:
1595     case COL_RES_DST:   /* COL_DEF_DST is currently just like COL_RES_DST */
1596       col_set_addr(pinfo, i, &pinfo->dst, FALSE, fill_col_exprs);
1597       break;
1598
1599     case COL_UNRES_DST:
1600       col_set_addr(pinfo, i, &pinfo->dst, FALSE, fill_col_exprs);
1601       break;
1602
1603     case COL_DEF_DL_DST:
1604     case COL_RES_DL_DST:
1605       col_set_addr(pinfo, i, &pinfo->dl_dst, FALSE, fill_col_exprs);
1606       break;
1607
1608     case COL_UNRES_DL_DST:
1609       col_set_addr(pinfo, i, &pinfo->dl_dst, FALSE, fill_col_exprs);
1610       break;
1611
1612     case COL_DEF_NET_DST:
1613     case COL_RES_NET_DST:
1614       col_set_addr(pinfo, i, &pinfo->net_dst, FALSE, fill_col_exprs);
1615       break;
1616
1617     case COL_UNRES_NET_DST:
1618       col_set_addr(pinfo, i, &pinfo->net_dst, FALSE, fill_col_exprs);
1619       break;
1620
1621     case COL_DEF_SRC_PORT:
1622     case COL_RES_SRC_PORT:  /* COL_DEF_SRC_PORT is currently just like COL_RES_SRC_PORT */
1623       col_set_port(pinfo, i, TRUE, TRUE, fill_col_exprs);
1624       break;
1625
1626     case COL_UNRES_SRC_PORT:
1627       col_set_port(pinfo, i, FALSE, TRUE, fill_col_exprs);
1628       break;
1629
1630     case COL_DEF_DST_PORT:
1631     case COL_RES_DST_PORT:  /* COL_DEF_DST_PORT is currently just like COL_RES_DST_PORT */
1632       col_set_port(pinfo, i, TRUE, FALSE, fill_col_exprs);
1633       break;
1634
1635     case COL_UNRES_DST_PORT:
1636       col_set_port(pinfo, i, FALSE, FALSE, fill_col_exprs);
1637       break;
1638
1639     case COL_VSAN:
1640       guint32_to_str_buf(pinfo->vsan, pinfo->cinfo->col_buf[i], COL_MAX_LEN);
1641       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
1642       break;
1643
1644     case NUM_COL_FMTS:  /* keep compiler happy - shouldn't get here */
1645       g_assert_not_reached();
1646       break;
1647     default:
1648       if (pinfo->cinfo->col_fmt[i] >= NUM_COL_FMTS) {
1649         g_assert_not_reached();
1650       }
1651       /*
1652        * Formatting handled by col_custom_set_edt() (COL_CUSTOM), expert.c
1653        * (COL_EXPERT), or individual dissectors.
1654        */
1655       break;
1656     }
1657   }
1658 }
1659
1660 #if 0
1661 XXX this needs more rework?
1662 /* --------------------------- */
1663
1664 static  gchar *
1665 set_addr(address *addr, gboolean is_res)
1666 {
1667   if (addr->type == AT_NONE)
1668     return "";  /* no address, nothing to do */
1669
1670   if (is_res) {
1671     return se_get_addr_name(addr /*, COL_MAX_LEN*/);
1672   }
1673   return se_address_to_str(addr);
1674 }
1675
1676 /* Fills col_text in the frame data structure */
1677 void
1678 col_fill_fdata(packet_info *pinfo)
1679 {
1680   int i;
1681   frame_data *fdata;
1682   gboolean res;
1683
1684   if (!pinfo->cinfo)
1685     return;
1686
1687   fdata = pinfo->fd;
1688
1689   res =FALSE;
1690
1691   for (i = 0; i < pinfo->cinfo->num_cols; i++) {
1692
1693     switch (pinfo->cinfo->col_fmt[i]) {
1694     case COL_NUMBER:           /* frame number */
1695     case COL_PACKET_LENGTH:    /* fd->pkt_len */
1696     case COL_CUMULATIVE_BYTES: /* fd->cum_bytes */
1697     case COL_CLS_TIME:
1698     case COL_ABS_TIME:
1699     case COL_ABS_DATE_TIME:    /* from fd structures */
1700     case COL_REL_TIME:
1701     case COL_DELTA_TIME:
1702     case COL_DELTA_TIME_DIS:
1703       break;
1704
1705     case COL_DEF_SRC:
1706     case COL_RES_SRC:   /* COL_DEF_SRC is currently just like COL_RES_SRC */
1707       res = TRUE;
1708     case COL_UNRES_SRC:
1709       fdata->col_text[i] = set_addr(&pinfo->src, res);
1710       break;
1711
1712     case COL_DEF_DL_SRC:
1713     case COL_RES_DL_SRC:
1714       res = TRUE;
1715     case COL_UNRES_DL_SRC:
1716       fdata->col_text[i] = set_addr (&pinfo->dl_src, res);
1717       break;
1718
1719     case COL_DEF_NET_SRC:
1720     case COL_RES_NET_SRC:
1721       res = TRUE;
1722     case COL_UNRES_NET_SRC:
1723       fdata->col_text[i] = set_addr (&pinfo->net_src, res);
1724       break;
1725
1726     case COL_DEF_DST:
1727     case COL_RES_DST:   /* COL_DEF_DST is currently just like COL_RES_DST */
1728       res = TRUE;
1729     case COL_UNRES_DST:
1730       fdata->col_text[i] = set_addr (&pinfo->dst, res);
1731       break;
1732
1733     case COL_DEF_DL_DST:
1734     case COL_RES_DL_DST:
1735       res = TRUE;
1736     case COL_UNRES_DL_DST:
1737       fdata->col_text[i] = set_addr (&pinfo->dl_dst, res);
1738       break;
1739
1740     case COL_DEF_NET_DST:
1741     case COL_RES_NET_DST:
1742       res = TRUE;
1743     case COL_UNRES_NET_DST:
1744       fdata->col_text[i] = set_addr (&pinfo->net_dst, res);
1745       break;
1746
1747     case COL_DEF_SRC_PORT:
1748     case COL_RES_SRC_PORT:  /* COL_DEF_SRC_PORT is currently just like COL_RES_SRC_PORT */
1749       fdata->col_text[i] = set_port(pinfo, TRUE, pinfo->srcport);
1750       break;
1751     case COL_UNRES_SRC_PORT:
1752       fdata->col_text[i] = set_port(pinfo, FALSE, pinfo->srcport);
1753       break;
1754
1755     case COL_DEF_DST_PORT:
1756     case COL_RES_DST_PORT:  /* COL_DEF_DST_PORT is currently just like COL_RES_DST_PORT */
1757       fdata->col_text[i] = set_port(pinfo, TRUE, pinfo->destport);
1758       break;
1759
1760     case COL_UNRES_DST_PORT:
1761       fdata->col_text[i] = set_port(pinfo, FALSE, pinfo->destport);
1762       break;
1763
1764     case COL_IF_DIR:    /* currently done by dissectors */
1765     case COL_PROTOCOL:
1766     case COL_INFO:
1767     case COL_HPUX_SUBSYS:
1768     case COL_HPUX_DEVID:
1769     case COL_DCE_CALL:
1770     case COL_8021Q_VLAN_ID:
1771     case COL_DSCP_VALUE:
1772     case COL_COS_VALUE:
1773     case COL_FR_DLCI:
1774     case COL_BSSGP_TLLI:
1775     case COL_EXPERT:
1776     case COL_CUSTOM:
1777     case COL_FREQ_CHAN:
1778       if (pinfo->cinfo->col_data[i] != pinfo->cinfo->col_buf[i]) {
1779          /* XXX assume it's a constant */
1780          fdata->col_text[i] = (gchar *)pinfo->cinfo->col_data[i];
1781       }
1782       else {
1783          /* copy */
1784          fdata->col_text[i] = se_strdup(pinfo->cinfo->col_data[i]);
1785       }
1786       break;
1787     case COL_OXID:
1788       fdata->col_text[i] = (gchar *)(GUINT_TO_POINTER((guint)pinfo->oxid));
1789       break;
1790     case COL_RXID:
1791       fdata->col_text[i] = (gchar *)(GUINT_TO_POINTER((guint)pinfo->rxid));
1792       break;
1793     case COL_CIRCUIT_ID:
1794       set_circuit_id(pinfo);
1795       break;
1796     case COL_SRCIDX:
1797       fdata->col_text[i] = (gchar *)(GUINT_TO_POINTER((guint)pinfo->src_idx));
1798       break;
1799     case COL_DSTIDX:
1800       fdata->col_text[i] = (gchar *)(GUINT_TO_POINTER((guint)pinfo->dst_idx));
1801       break;
1802     case COL_VSAN:
1803       fdata->col_text[i] = (gchar *)(GUINT_TO_POINTER((guint)pinfo->vsan));
1804       break;
1805
1806     case NUM_COL_FMTS:  /* keep compiler happy - shouldn't get here */
1807       g_assert_not_reached();
1808       break;
1809     }
1810   }
1811 }
1812
1813 /* XXX Gets/creates the text from col_text in frame data */
1814 /* --------------------- */
1815 gchar *
1816 col_get_text(frame_data *fd, column_info *cinfo, gint col)
1817 {
1818 static gchar fmtbuf[3][COL_MAX_LEN];
1819 static int idx;
1820 gchar  *buf;
1821 gchar  *ptr;
1822
1823     idx = (idx + 1) % 3;
1824     buf = fmtbuf[idx];
1825     *buf = 0;
1826     ptr = buf;
1827
1828     switch (cinfo->col_fmt[col]) {
1829     case COL_NUMBER: /* frame number */
1830       guint32_to_str_buf(fd->num, buf, COL_MAX_LEN);
1831       break;
1832
1833     case COL_CLS_TIME:
1834       set_cls_time(fd, buf);
1835       break;
1836     case COL_ABS_TIME:
1837       set_abs_time(fd, buf);
1838       break;
1839     case COL_ABS_DATE_TIME:
1840       set_abs_date_time(fd, buf);
1841       break;
1842     case COL_REL_TIME:
1843       set_rel_time(fd, buf);
1844       break;
1845     case COL_DELTA_TIME:
1846       set_delta_time(fd, buf);
1847       break;
1848     case COL_DELTA_TIME_DIS:
1849       set_delta_time_dis(fd, buf);
1850       break;
1851
1852     case COL_PACKET_LENGTH: /* fd->pkt_len */
1853       guint32_to_str_buf(fd->pkt_len, buf, COL_MAX_LEN);
1854       break;
1855
1856     case COL_CUMULATIVE_BYTES: /* fd->cum_bytes */
1857       guint32_to_str_buf(fd->cum_bytes, buf, COL_MAX_LEN);
1858       break;
1859
1860     case COL_DEF_SRC:
1861     case COL_RES_SRC:   /* network address */
1862     case COL_UNRES_SRC:
1863     case COL_DEF_DL_SRC:
1864     case COL_RES_DL_SRC:
1865     case COL_UNRES_DL_SRC:
1866     case COL_DEF_NET_SRC:
1867     case COL_RES_NET_SRC:
1868     case COL_UNRES_NET_SRC:
1869     case COL_DEF_DST:
1870     case COL_RES_DST:
1871     case COL_UNRES_DST:
1872     case COL_DEF_DL_DST:
1873     case COL_RES_DL_DST:
1874     case COL_UNRES_DL_DST:
1875     case COL_DEF_NET_DST:
1876     case COL_RES_NET_DST:
1877     case COL_UNRES_NET_DST:
1878
1879     case COL_IF_DIR:
1880     case COL_CIRCUIT_ID:
1881     case COL_PROTOCOL:
1882     case COL_INFO:
1883     case COL_HPUX_SUBSYS:
1884     case COL_HPUX_DEVID:
1885     case COL_DCE_CALL:
1886     case COL_8021Q_VLAN_ID:
1887     case COL_DSCP_VALUE:
1888     case COL_COS_VALUE:
1889     case COL_FR_DLCI:
1890     case COL_BSSGP_TLLI:
1891     case COL_EXPERT:
1892     case COL_CUSTOM:
1893     case COL_FREQ_CHAN:
1894       ptr = fd->col_text[col];
1895       break;
1896
1897     case COL_DEF_SRC_PORT:
1898     case COL_RES_SRC_PORT:
1899     case COL_UNRES_SRC_PORT:
1900     case COL_DEF_DST_PORT:
1901     case COL_RES_DST_PORT:
1902     case COL_UNRES_DST_PORT:
1903       /* hack */
1904       if (GPOINTER_TO_UINT(fd->col_text[col]) <= 65536)
1905           guint32_to_str_buf(GPOINTER_TO_UINT(fd->col_text[col], buf, COL_MAX_LEN));
1906       else
1907           ptr = fd->col_text[col];
1908       break;
1909
1910     case COL_OXID:
1911     case COL_RXID:
1912     case COL_SRCIDX:
1913     case COL_DSTIDX:
1914       g_snprintf(buf, COL_MAX_LEN, "0x%x", GPOINTER_TO_UINT(fd->col_text[col]));
1915       break;
1916
1917     case COL_VSAN:
1918       guint32_to_str_buf(GPOINTER_TO_UINT(fd->col_text[col]), buf, COL_MAX_LEN);
1919       break;
1920
1921     case NUM_COL_FMTS:  /* keep compiler happy - shouldn't get here */
1922       g_assert_not_reached();
1923       break;
1924     }
1925     return ptr;
1926 }
1927 #endif