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