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