name change
[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
44 /* Allocate all the data structures for constructing column data, given
45    the number of columns. */
46 void
47 col_setup(column_info *cinfo, gint num_cols)
48 {
49   int i;
50
51   cinfo->num_cols       = num_cols;
52   cinfo->col_fmt        = (gint *) g_malloc(sizeof(gint) * num_cols);
53   cinfo->fmt_matx       = (gboolean **) g_malloc(sizeof(gboolean *) * num_cols);
54   cinfo->col_first      = (int *) g_malloc(sizeof(int) * (NUM_COL_FMTS));
55   cinfo->col_last       = (int *) g_malloc(sizeof(int) * (NUM_COL_FMTS));
56   cinfo->col_title      = (gchar **) g_malloc(sizeof(gchar *) * num_cols);
57   cinfo->col_data       = (const gchar **) g_malloc(sizeof(gchar *) * num_cols);
58   cinfo->col_buf        = (gchar **) g_malloc(sizeof(gchar *) * num_cols);
59   cinfo->col_fence      = (int *) g_malloc(sizeof(int) * num_cols);
60   cinfo->col_expr       = (gchar **) g_malloc(sizeof(gchar *) * num_cols);
61   cinfo->col_expr_val = (gchar **) g_malloc(sizeof(gchar *) * num_cols);
62
63   for (i = 0; i < NUM_COL_FMTS; i++) {
64     cinfo->col_first[i] = -1;
65     cinfo->col_last[i] = -1;
66   }
67 }
68
69 /* Initialize the data structures for constructing column data. */
70 void
71 col_init(column_info *cinfo)
72 {
73   int i;
74
75   for (i = 0; i < cinfo->num_cols; i++) {
76     cinfo->col_buf[i][0] = '\0';
77     cinfo->col_data[i] = cinfo->col_buf[i];
78     cinfo->col_fence[i] = 0;
79     cinfo->col_expr[i][0] = '\0';
80     cinfo->col_expr_val[i][0] = '\0';
81   }
82   cinfo->writable = TRUE;
83 }
84
85 gboolean
86 col_get_writable(column_info *cinfo)
87 {
88         return (cinfo ? cinfo->writable : FALSE);
89 }
90
91 void
92 col_set_writable(column_info *cinfo, gboolean writable)
93 {
94         if (cinfo)
95                 cinfo->writable = writable;
96 }
97
98 /* Checks to see if a particular packet information element is needed for
99    the packet list */
100 gint
101 check_col(column_info *cinfo, gint el) {
102
103   if (cinfo && cinfo->writable) {
104     /* We are constructing columns, and they're writable */
105     if (cinfo->col_first[el] >= 0) {
106       /* There is at least one column in that format */
107       return TRUE;
108     }
109   }
110   return FALSE;
111 }
112
113 /* Sets the fence for a column to be at the end of the column. */
114 void
115 col_set_fence(column_info *cinfo, gint el)
116 {
117   int i;
118
119   if (cinfo && cinfo->writable) {
120     /* We are constructing columns, and they're writable */
121     if (cinfo->col_first[el] >= 0) {
122       /* There is at least one column in that format */
123       for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
124         if (cinfo->fmt_matx[i][el]) {
125           cinfo->col_fence[i] = strlen(cinfo->col_data[i]);
126         }
127       }
128     }
129   }
130 }
131
132 /* Use this to clear out a column, especially if you're going to be
133    appending to it later; at least on some platforms, it's more
134    efficient than using "col_add_str()" with a null string, and
135    more efficient than "col_set_str()" with a null string if you
136    later append to it, as the later append will cause a string
137    copy to be done. */
138 void
139 col_clear(column_info *cinfo, gint el)
140 {
141   int    i;
142   int    fence;
143
144   g_assert(cinfo->col_first[el] >= 0);
145   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
146     if (cinfo->fmt_matx[i][el]) {
147       /*
148        * At this point, either
149        *
150        *   1) col_data[i] is equal to col_buf[i], in which case we
151        *      don't have to worry about copying col_data[i] to
152        *      col_buf[i];
153        *
154        *   2) col_data[i] isn't equal to col_buf[i], in which case
155        *      the only thing that's been done to the column is
156        *      "col_set_str()" calls and possibly "col_set_fence()"
157        *      calls, in which case the fence is either unset and
158        *      at the beginning of the string or set and at the end
159        *      of the string - if it's at the beginning, we're just
160        *      going to clear the column, and if it's at the end,
161        *      we don't do anything.
162        */
163       fence = cinfo->col_fence[i];
164       if (fence == 0 || cinfo->col_buf[i] == cinfo->col_data[i]) {
165         /*
166          * The fence isn't at the end of the column, or the column wasn't
167          * last set with "col_set_str()", so clear the column out.
168          */
169         cinfo->col_buf[i][fence] = '\0';
170         cinfo->col_data[i] = cinfo->col_buf[i];
171       }
172       cinfo->col_expr[i][0] = '\0';
173       cinfo->col_expr_val[i][0] = '\0';
174     }
175   }
176 }
177
178 #define COL_CHECK_APPEND(cinfo, i, max_len) \
179   if (cinfo->col_data[i] != cinfo->col_buf[i]) {                \
180     /* This was set with "col_set_str()"; copy the string they  \
181        set it to into the buffer, so we can append to it. */    \
182     strncpy(cinfo->col_buf[i], cinfo->col_data[i], max_len);    \
183     cinfo->col_buf[i][max_len - 1] = '\0';                      \
184     cinfo->col_data[i] = cinfo->col_buf[i];                     \
185   }
186
187 #define COL_CHECK_REF_TIME(fd, cinfo, col)      \
188   if(fd->flags.ref_time){                                       \
189     g_snprintf(cinfo->col_buf[col], COL_MAX_LEN, "*REF*");      \
190     cinfo->col_data[col] = cinfo->col_buf[col];                 \
191     return;                                                     \
192   }
193
194 /* Use this if "str" points to something that will stay around (and thus
195    needn't be copied). */
196 void
197 col_set_str(column_info *cinfo, gint el, const gchar* str)
198 {
199   int i;
200   int fence;
201   size_t max_len;
202
203   if (el == COL_INFO)
204         max_len = COL_MAX_INFO_LEN;
205   else
206         max_len = COL_MAX_LEN;
207
208   g_assert(cinfo->col_first[el] >= 0);
209   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
210     if (cinfo->fmt_matx[i][el]) {
211       fence = cinfo->col_fence[i];
212       if (fence != 0) {
213         /*
214          * We will append the string after the fence.
215          * First arrange that we can append, if necessary.
216          */
217         COL_CHECK_APPEND(cinfo, i, max_len);
218
219         strncpy(&cinfo->col_buf[i][fence], str, max_len - fence);
220         cinfo->col_buf[i][max_len - 1] = 0;
221       } else {
222         /*
223          * There's no fence, so we can just set the column to point
224          * to the string.
225          */
226         cinfo->col_data[i] = str;
227       }
228     }
229   }
230 }
231
232 /* Adds a vararg list to a packet info string. */
233 void
234 col_add_fstr(column_info *cinfo, gint el, const gchar *format, ...) {
235   va_list ap;
236   int     i;
237   int     fence;
238   size_t  max_len;
239
240   g_assert(cinfo->col_first[el] >= 0);
241   if (el == COL_INFO)
242         max_len = COL_MAX_INFO_LEN;
243   else
244         max_len = COL_MAX_LEN;
245
246   va_start(ap, format);
247   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
248     if (cinfo->fmt_matx[i][el]) {
249       fence = cinfo->col_fence[i];
250       if (fence != 0) {
251         /*
252          * We will append the string after the fence.
253          * First arrange that we can append, if necessary.
254          */
255         COL_CHECK_APPEND(cinfo, i, max_len);
256       } else {
257         /*
258          * There's no fence, so we can just write to the string.
259          */
260         cinfo->col_data[i] = cinfo->col_buf[i];
261       }
262       g_vsnprintf(&cinfo->col_buf[i][fence], max_len - fence, format, ap);
263       cinfo->col_buf[i][max_len - 1] = '\0';
264     }
265   }
266   va_end(ap);
267 }
268
269 static void
270 col_do_append_sep_va_fstr(column_info *cinfo, gint el, const gchar *separator,
271                           const gchar *format, va_list ap)
272 {
273   int     i;
274   size_t  len, max_len, sep_len;
275
276   g_assert(cinfo->col_first[el] >= 0);
277   if (el == COL_INFO)
278         max_len = COL_MAX_INFO_LEN;
279   else
280         max_len = COL_MAX_LEN;
281
282   if (separator == NULL)
283     sep_len = 0;
284   else
285     sep_len = strlen(separator);
286   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
287     if (cinfo->fmt_matx[i][el]) {
288       /*
289        * First arrange that we can append, if necessary.
290        */
291       COL_CHECK_APPEND(cinfo, i, max_len);
292
293       len = strlen(cinfo->col_buf[i]);
294
295       /*
296        * If we have a separator, append it if the column isn't empty.
297        */
298       if (separator != NULL) {
299         if (len != 0) {
300           strncat(cinfo->col_buf[i], separator, max_len - len);
301           len += sep_len;
302         }
303       }
304       g_vsnprintf(&cinfo->col_buf[i][len], max_len - len, format, ap);
305       cinfo->col_buf[i][max_len-1] = 0;
306     }
307   }
308 }
309
310 /* Appends a vararg list to a packet info string. */
311 void
312 col_append_fstr(column_info *cinfo, gint el, const gchar *format, ...)
313 {
314   va_list ap;
315
316   va_start(ap, format);
317   col_do_append_sep_va_fstr(cinfo, el, NULL, format, ap);
318   va_end(ap);
319 }
320
321 /* Appends a vararg list to a packet info string.
322  * Prefixes it with the given separator if the column is not empty. */
323 void
324 col_append_sep_fstr(column_info *cinfo, gint el, const gchar *separator,
325                 const gchar *format, ...)
326 {
327   va_list ap;
328
329   if (separator == NULL)
330     separator = ", ";    /* default */
331   va_start(ap, format);
332   col_do_append_sep_va_fstr(cinfo, el, separator, format, ap);
333   va_end(ap);
334 }
335
336
337
338 /* Prepends a vararg list to a packet info string. */
339 #define COL_BUF_MAX_LEN (((COL_MAX_INFO_LEN) > (COL_MAX_LEN)) ? \
340         (COL_MAX_INFO_LEN) : (COL_MAX_LEN))
341 void
342 col_prepend_fstr(column_info *cinfo, gint el, const gchar *format, ...)
343 {
344   va_list     ap;
345   int         i;
346   char        orig_buf[COL_BUF_MAX_LEN];
347   const char *orig;
348   size_t      max_len;
349
350   g_assert(cinfo->col_first[el] >= 0);
351   if (el == COL_INFO)
352         max_len = COL_MAX_INFO_LEN;
353   else
354         max_len = COL_MAX_LEN;
355
356   va_start(ap, format);
357   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
358     if (cinfo->fmt_matx[i][el]) {
359       if (cinfo->col_data[i] != cinfo->col_buf[i]) {
360         /* This was set with "col_set_str()"; which is effectively const */
361         orig = cinfo->col_data[i];
362       } else {
363         strncpy(orig_buf, cinfo->col_buf[i], max_len);
364         orig_buf[max_len - 1] = '\0';
365         orig = orig_buf;
366       }
367       g_vsnprintf(cinfo->col_buf[i], max_len, format, ap);
368       cinfo->col_buf[i][max_len - 1] = '\0';
369
370       /*
371        * Move the fence, unless it's at the beginning of the string.
372        */
373       if (cinfo->col_fence[i] > 0)
374         cinfo->col_fence[i] += strlen(cinfo->col_buf[i]);
375
376       strncat(cinfo->col_buf[i], orig, max_len);
377       cinfo->col_buf[i][max_len - 1] = '\0';
378       cinfo->col_data[i] = cinfo->col_buf[i];
379     }
380   }
381   va_end(ap);
382 }
383 void
384 col_prepend_fence_fstr(column_info *cinfo, gint el, const gchar *format, ...)
385 {
386   va_list     ap;
387   int         i;
388   char        orig_buf[COL_BUF_MAX_LEN];
389   const char *orig;
390   size_t      max_len;
391
392   g_assert(cinfo->col_first[el] >= 0);
393   if (el == COL_INFO)
394         max_len = COL_MAX_INFO_LEN;
395   else
396         max_len = COL_MAX_LEN;
397
398   va_start(ap, format);
399   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
400     if (cinfo->fmt_matx[i][el]) {
401       if (cinfo->col_data[i] != cinfo->col_buf[i]) {
402         /* This was set with "col_set_str()"; which is effectively const */
403         orig = cinfo->col_data[i];
404       } else {
405         strncpy(orig_buf, cinfo->col_buf[i], max_len);
406         orig_buf[max_len - 1] = '\0';
407         orig = orig_buf;
408       }
409       g_vsnprintf(cinfo->col_buf[i], max_len, format, ap);
410       cinfo->col_buf[i][max_len - 1] = '\0';
411
412       /*
413        * Move the fence if it exists, else create a new fence at the
414        * end of the prepended data.
415        */
416       if (cinfo->col_fence[i] > 0) {
417         cinfo->col_fence[i] += strlen(cinfo->col_buf[i]);
418       } else {
419         cinfo->col_fence[i]  = strlen(cinfo->col_buf[i]);
420       }
421       strncat(cinfo->col_buf[i], orig, max_len);
422       cinfo->col_buf[i][max_len - 1] = '\0';
423       cinfo->col_data[i] = cinfo->col_buf[i];
424     }
425   }
426   va_end(ap);
427 }
428
429 /* Use this if "str" points to something that won't stay around (and
430    must thus be copied). */
431 void
432 col_add_str(column_info *cinfo, gint el, const gchar* str)
433 {
434   int    i;
435   int    fence;
436   size_t max_len;
437
438   g_assert(cinfo->col_first[el] >= 0);
439   if (el == COL_INFO)
440         max_len = COL_MAX_INFO_LEN;
441   else
442         max_len = COL_MAX_LEN;
443
444   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
445     if (cinfo->fmt_matx[i][el]) {
446       fence = cinfo->col_fence[i];
447       if (fence != 0) {
448         /*
449          * We will append the string after the fence.
450          * First arrange that we can append, if necessary.
451          */
452         COL_CHECK_APPEND(cinfo, i, max_len);
453       } else {
454         /*
455          * There's no fence, so we can just write to the string.
456          */
457         cinfo->col_data[i] = cinfo->col_buf[i];
458       }
459       strncpy(&cinfo->col_buf[i][fence], str, max_len - fence);
460       cinfo->col_buf[i][max_len - 1] = 0;
461     }
462   }
463 }
464
465 static void
466 col_do_append_str(column_info *cinfo, gint el, const gchar* separator,
467     const gchar* str)
468 {
469   int    i;
470   size_t len, max_len, sep_len;
471
472   g_assert(cinfo->col_first[el] >= 0);
473   if (el == COL_INFO)
474         max_len = COL_MAX_INFO_LEN;
475   else
476         max_len = COL_MAX_LEN;
477
478   if (separator == NULL)
479     sep_len = 0;
480   else
481     sep_len = strlen(separator);
482
483   for (i = cinfo->col_first[el]; i <= cinfo->col_last[el]; i++) {
484     if (cinfo->fmt_matx[i][el]) {
485       /*
486        * First arrange that we can append, if necessary.
487        */
488       COL_CHECK_APPEND(cinfo, i, max_len);
489
490       len = strlen(cinfo->col_buf[i]);
491
492       /*
493        * If we have a separator, append it if the column isn't empty.
494        */
495       if (separator != NULL) {
496         if (len != 0) {
497           strncat(cinfo->col_buf[i], separator, max_len - len);
498           len += sep_len;
499         }
500       }
501       strncat(cinfo->col_buf[i], str, max_len - len);
502       cinfo->col_buf[i][max_len - 1] = 0;
503     }
504   }
505 }
506
507 void
508 col_append_str(column_info *cinfo, gint el, const gchar* str)
509 {
510   col_do_append_str(cinfo, el, NULL, str);
511 }
512
513 void
514 col_append_sep_str(column_info *cinfo, gint el, const gchar* separator,
515     const gchar* str)
516 {
517   if (separator == NULL)
518     separator = ", ";    /* default */
519   col_do_append_str(cinfo, el, separator, str);
520 }
521
522 static void
523 col_set_abs_date_time(frame_data *fd, column_info *cinfo, int col)
524 {
525   struct tm *tmp;
526   time_t then;
527
528   COL_CHECK_REF_TIME(fd, cinfo, col);
529
530   then = fd->abs_ts.secs;
531   tmp = localtime(&then);
532   if (tmp != NULL) {
533           switch(timestamp_get_precision()) {
534           case(TS_PREC_FIXED_SEC):
535           case(TS_PREC_AUTO_SEC):
536                   g_snprintf(cinfo->col_buf[col], COL_MAX_LEN,
537              "%04d-%02d-%02d %02d:%02d:%02d",
538              tmp->tm_year + 1900,
539              tmp->tm_mon + 1,
540              tmp->tm_mday,
541              tmp->tm_hour,
542              tmp->tm_min,
543              tmp->tm_sec);
544                   break;
545           case(TS_PREC_FIXED_DSEC):
546           case(TS_PREC_AUTO_DSEC):
547                   g_snprintf(cinfo->col_buf[col], COL_MAX_LEN,
548              "%04d-%02d-%02d %02d:%02d:%02d.%01ld",
549              tmp->tm_year + 1900,
550              tmp->tm_mon + 1,
551              tmp->tm_mday,
552              tmp->tm_hour,
553              tmp->tm_min,
554              tmp->tm_sec,
555              (long)fd->abs_ts.nsecs / 100000000);
556                   break;
557           case(TS_PREC_FIXED_CSEC):
558           case(TS_PREC_AUTO_CSEC):
559                   g_snprintf(cinfo->col_buf[col], COL_MAX_LEN,
560              "%04d-%02d-%02d %02d:%02d:%02d.%02ld",
561              tmp->tm_year + 1900,
562              tmp->tm_mon + 1,
563              tmp->tm_mday,
564              tmp->tm_hour,
565              tmp->tm_min,
566              tmp->tm_sec,
567              (long)fd->abs_ts.nsecs / 10000000);
568                   break;
569           case(TS_PREC_FIXED_MSEC):
570           case(TS_PREC_AUTO_MSEC):
571                   g_snprintf(cinfo->col_buf[col], COL_MAX_LEN,
572              "%04d-%02d-%02d %02d:%02d:%02d.%03ld",
573              tmp->tm_year + 1900,
574              tmp->tm_mon + 1,
575              tmp->tm_mday,
576              tmp->tm_hour,
577              tmp->tm_min,
578              tmp->tm_sec,
579              (long)fd->abs_ts.nsecs / 1000000);
580                   break;
581           case(TS_PREC_FIXED_USEC):
582           case(TS_PREC_AUTO_USEC):
583                   g_snprintf(cinfo->col_buf[col], COL_MAX_LEN,
584              "%04d-%02d-%02d %02d:%02d:%02d.%06ld",
585              tmp->tm_year + 1900,
586              tmp->tm_mon + 1,
587              tmp->tm_mday,
588              tmp->tm_hour,
589              tmp->tm_min,
590              tmp->tm_sec,
591              (long)fd->abs_ts.nsecs / 1000);
592                   break;
593           case(TS_PREC_FIXED_NSEC):
594           case(TS_PREC_AUTO_NSEC):
595                   g_snprintf(cinfo->col_buf[col], COL_MAX_LEN,
596              "%04d-%02d-%02d %02d:%02d:%02d.%09ld",
597              tmp->tm_year + 1900,
598              tmp->tm_mon + 1,
599              tmp->tm_mday,
600              tmp->tm_hour,
601              tmp->tm_min,
602              tmp->tm_sec,
603              (long)fd->abs_ts.nsecs);
604                   break;
605           default:
606                   g_assert_not_reached();
607           }
608   } else {
609     cinfo->col_buf[col][0] = '\0';
610   }
611   cinfo->col_data[col] = cinfo->col_buf[col];
612   strcpy(cinfo->col_expr[col],"frame.time");
613   strcpy(cinfo->col_expr_val[col],cinfo->col_buf[col]);
614 }
615
616 static void
617 col_set_rel_time(frame_data *fd, column_info *cinfo, int col)
618 {
619   COL_CHECK_REF_TIME(fd, cinfo, col);
620
621   switch(timestamp_get_precision()) {
622           case(TS_PREC_FIXED_SEC):
623           case(TS_PREC_AUTO_SEC):
624                   display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
625                         fd->rel_ts.secs, fd->rel_ts.nsecs / 1000000000, SECS);
626                   break;
627           case(TS_PREC_FIXED_DSEC):
628           case(TS_PREC_AUTO_DSEC):
629                   display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
630                         fd->rel_ts.secs, fd->rel_ts.nsecs / 100000000, DSECS);
631                   break;
632           case(TS_PREC_FIXED_CSEC):
633           case(TS_PREC_AUTO_CSEC):
634                   display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
635                         fd->rel_ts.secs, fd->rel_ts.nsecs / 10000000, CSECS);
636                   break;
637           case(TS_PREC_FIXED_MSEC):
638           case(TS_PREC_AUTO_MSEC):
639                   display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
640                         fd->rel_ts.secs, fd->rel_ts.nsecs / 1000000, MSECS);
641                   break;
642           case(TS_PREC_FIXED_USEC):
643           case(TS_PREC_AUTO_USEC):
644                   display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
645                         fd->rel_ts.secs, fd->rel_ts.nsecs / 1000, USECS);
646                   break;
647           case(TS_PREC_FIXED_NSEC):
648           case(TS_PREC_AUTO_NSEC):
649                   display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
650                         fd->rel_ts.secs, fd->rel_ts.nsecs, NSECS);
651                   break;
652           default:
653                   g_assert_not_reached();
654   }
655   cinfo->col_data[col] = cinfo->col_buf[col];
656   strcpy(cinfo->col_expr[col],"frame.time_relative");
657   strcpy(cinfo->col_expr_val[col],cinfo->col_buf[col]);
658 }
659
660 static void
661 col_set_delta_time(frame_data *fd, column_info *cinfo, int col)
662 {
663   COL_CHECK_REF_TIME(fd, cinfo, col);
664
665   switch(timestamp_get_precision()) {
666           case(TS_PREC_FIXED_SEC):
667           case(TS_PREC_AUTO_SEC):
668                   display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
669                         fd->del_ts.secs, fd->del_ts.nsecs / 1000000000, SECS);
670                   break;
671           case(TS_PREC_FIXED_DSEC):
672           case(TS_PREC_AUTO_DSEC):
673                   display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
674                         fd->del_ts.secs, fd->del_ts.nsecs / 100000000, DSECS);
675                   break;
676           case(TS_PREC_FIXED_CSEC):
677           case(TS_PREC_AUTO_CSEC):
678                   display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
679                         fd->del_ts.secs, fd->del_ts.nsecs / 10000000, CSECS);
680                   break;
681           case(TS_PREC_FIXED_MSEC):
682           case(TS_PREC_AUTO_MSEC):
683                   display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
684                         fd->del_ts.secs, fd->del_ts.nsecs / 1000000, MSECS);
685                   break;
686           case(TS_PREC_FIXED_USEC):
687           case(TS_PREC_AUTO_USEC):
688                   display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
689                         fd->del_ts.secs, fd->del_ts.nsecs / 1000, USECS);
690                   break;
691           case(TS_PREC_FIXED_NSEC):
692           case(TS_PREC_AUTO_NSEC):
693                   display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
694                         fd->del_ts.secs, fd->del_ts.nsecs, NSECS);
695                   break;
696           default:
697                   g_assert_not_reached();
698   }
699   cinfo->col_data[col] = cinfo->col_buf[col];
700   strcpy(cinfo->col_expr[col],"frame.time_delta");
701   strcpy(cinfo->col_expr_val[col],cinfo->col_buf[col]);
702 }
703
704 /* To do: Add check_col checks to the col_add* routines */
705
706 static void
707 col_set_abs_time(frame_data *fd, column_info *cinfo, int col)
708 {
709   struct tm *tmp;
710   time_t then;
711
712   COL_CHECK_REF_TIME(fd, cinfo, col);
713
714   then = fd->abs_ts.secs;
715   tmp = localtime(&then);
716   if (tmp != NULL) {
717           switch(timestamp_get_precision()) {
718           case(TS_PREC_FIXED_SEC):
719           case(TS_PREC_AUTO_SEC):
720                   g_snprintf(cinfo->col_buf[col], COL_MAX_LEN,
721              "%02d:%02d:%02d",
722              tmp->tm_hour,
723              tmp->tm_min,
724              tmp->tm_sec);
725                   break;
726           case(TS_PREC_FIXED_DSEC):
727           case(TS_PREC_AUTO_DSEC):
728                   g_snprintf(cinfo->col_buf[col], COL_MAX_LEN,
729              "%02d:%02d:%02d.%01ld",
730              tmp->tm_hour,
731              tmp->tm_min,
732              tmp->tm_sec,
733              (long)fd->abs_ts.nsecs / 100000000);
734                   break;
735           case(TS_PREC_FIXED_CSEC):
736           case(TS_PREC_AUTO_CSEC):
737                   g_snprintf(cinfo->col_buf[col], COL_MAX_LEN,
738              "%02d:%02d:%02d.%02ld",
739              tmp->tm_hour,
740              tmp->tm_min,
741              tmp->tm_sec,
742              (long)fd->abs_ts.nsecs / 10000000);
743                   break;
744           case(TS_PREC_FIXED_MSEC):
745           case(TS_PREC_AUTO_MSEC):
746                   g_snprintf(cinfo->col_buf[col], COL_MAX_LEN,
747              "%02d:%02d:%02d.%03ld",
748              tmp->tm_hour,
749              tmp->tm_min,
750              tmp->tm_sec,
751              (long)fd->abs_ts.nsecs / 1000000);
752                   break;
753           case(TS_PREC_FIXED_USEC):
754           case(TS_PREC_AUTO_USEC):
755                   g_snprintf(cinfo->col_buf[col], COL_MAX_LEN,
756              "%02d:%02d:%02d.%06ld",
757              tmp->tm_hour,
758              tmp->tm_min,
759              tmp->tm_sec,
760              (long)fd->abs_ts.nsecs / 1000);
761                   break;
762           case(TS_PREC_FIXED_NSEC):
763           case(TS_PREC_AUTO_NSEC):
764                   g_snprintf(cinfo->col_buf[col], COL_MAX_LEN,
765              "%02d:%02d:%02d.%09ld",
766              tmp->tm_hour,
767              tmp->tm_min,
768              tmp->tm_sec,
769              (long)fd->abs_ts.nsecs);
770                   break;
771           default:
772                   g_assert_not_reached();
773           }
774   } else {
775     cinfo->col_buf[col][0] = '\0';
776   }
777   cinfo->col_data[col] = cinfo->col_buf[col];
778   strcpy(cinfo->col_expr[col],"frame.time");
779   strcpy(cinfo->col_expr_val[col],cinfo->col_buf[col]);
780 }
781
782 /* Set the format of the variable time format.
783    XXX - this is called from "file.c" when the user changes the time
784    format they want for "command-line-specified" time; it's a bit ugly
785    that we have to export it, but if we go to a CList-like widget that
786    invokes callbacks to get the text for the columns rather than
787    requiring us to stuff the text into the widget from outside, we
788    might be able to clean this up. */
789 void
790 col_set_cls_time(frame_data *fd, column_info *cinfo, gint col)
791 {
792   switch (timestamp_get_type()) {
793     case TS_ABSOLUTE:
794       col_set_abs_time(fd, cinfo, col);
795       break;
796
797     case TS_ABSOLUTE_WITH_DATE:
798       col_set_abs_date_time(fd, cinfo, col);
799       break;
800
801     case TS_RELATIVE:
802       col_set_rel_time(fd, cinfo, col);
803       break;
804
805     case TS_DELTA:
806       col_set_delta_time(fd, cinfo, col);
807       break;
808    case TS_NOT_SET:
809         /* code is missing for this case, but I don't know which [jmayer20051219] */
810         g_assert(FALSE);
811         break;
812   }
813 }
814
815 static void
816 col_set_addr(packet_info *pinfo, int col, address *addr, gboolean is_res,
817              gboolean is_src)
818 {
819   struct e_in6_addr ipv6_addr;
820
821   pinfo->cinfo->col_expr[col][0] = '\0';
822   pinfo->cinfo->col_expr_val[col][0] = '\0';
823   
824   if (addr->type == AT_NONE)
825     return;     /* no address, nothing to do */
826   
827   if (is_res) {
828     get_addr_name_buf(addr, pinfo->cinfo->col_buf[col],COL_MAX_LEN-1);
829   } else {
830     switch (addr->type) {
831
832     case AT_STRINGZ:
833       /* XXX - should be done in "address_to_str_buf()", but that routine
834          doesn't know COL_MAX_LEN; it should be changed to take the
835          maximum length as an argument. */
836       strncpy(pinfo->cinfo->col_buf[col], addr->data, COL_MAX_LEN);
837       pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
838       break;
839
840     default:
841       address_to_str_buf(addr, pinfo->cinfo->col_buf[col], COL_MAX_LEN);
842       break;
843     }
844   }
845   pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
846
847   switch (addr->type) {
848
849   case AT_ETHER:
850     if (is_src)
851       strcpy(pinfo->cinfo->col_expr[col], "eth.src");
852     else
853       strcpy(pinfo->cinfo->col_expr[col], "eth.dst");
854     strncpy(pinfo->cinfo->col_expr_val[col], ether_to_str(addr->data), COL_MAX_LEN);
855     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
856     break;
857
858   case AT_IPv4:
859     if (is_src)
860       strcpy(pinfo->cinfo->col_expr[col], "ip.src");
861     else
862       strcpy(pinfo->cinfo->col_expr[col], "ip.dst");
863     strncpy(pinfo->cinfo->col_expr_val[col], ip_to_str(addr->data), COL_MAX_LEN);
864     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
865     break;
866
867   case AT_IPv6:
868     if (is_src)
869       strcpy(pinfo->cinfo->col_expr[col], "ipv6.src");
870     else
871       strcpy(pinfo->cinfo->col_expr[col], "ipv6.dst");
872     strncpy(pinfo->cinfo->col_expr_val[col], ip6_to_str(&ipv6_addr), COL_MAX_LEN);
873     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
874     break;
875
876   case AT_ATALK:
877     if (is_src)
878       strcpy(pinfo->cinfo->col_expr[col], "ddp.src");
879     else
880       strcpy(pinfo->cinfo->col_expr[col], "ddp.dst");
881     strcpy(pinfo->cinfo->col_expr_val[col], pinfo->cinfo->col_buf[col]);
882     break;
883
884   case AT_ARCNET:
885     if (is_src)
886       strcpy(pinfo->cinfo->col_expr[col], "arcnet.src");
887     else
888       strcpy(pinfo->cinfo->col_expr[col], "arcnet.dst");
889     strcpy(pinfo->cinfo->col_expr_val[col], pinfo->cinfo->col_buf[col]);
890     break;
891
892   default:
893     break;
894   }
895 }
896
897 static void
898 col_set_port(packet_info *pinfo, int col, gboolean is_res, gboolean is_src)
899 {
900   guint32 port;
901
902   if (is_src)
903     port = pinfo->srcport;
904   else
905     port = pinfo->destport;
906   pinfo->cinfo->col_expr[col][0] = '\0';
907   pinfo->cinfo->col_expr_val[col][0] = '\0';
908   switch (pinfo->ptype) {
909
910   case PT_SCTP:
911     if (is_res)
912       strncpy(pinfo->cinfo->col_buf[col], get_sctp_port(port), COL_MAX_LEN);
913     else
914       g_snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", port);
915     break;
916
917   case PT_TCP:
918     if (is_res)
919       strncpy(pinfo->cinfo->col_buf[col], get_tcp_port(port), COL_MAX_LEN);
920     else
921       g_snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", port);
922     if (is_src)
923       strcpy(pinfo->cinfo->col_expr[col], "tcp.srcport");
924     else
925       strcpy(pinfo->cinfo->col_expr[col], "tcp.dstport");
926     g_snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "%u", port);
927     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
928     break;
929
930   case PT_UDP:
931     if (is_res)
932       strncpy(pinfo->cinfo->col_buf[col], get_udp_port(port), COL_MAX_LEN);
933     else
934       g_snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", port);
935     if (is_src)
936       strcpy(pinfo->cinfo->col_expr[col], "udp.srcport");
937     else
938       strcpy(pinfo->cinfo->col_expr[col], "udp.dstport");
939     g_snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "%u", port);
940     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
941     break;
942
943   case PT_DDP:
944     if (is_src)
945       strcpy(pinfo->cinfo->col_expr[col], "ddp.src_socket");
946     else
947       strcpy(pinfo->cinfo->col_expr[col], "ddp.dst_socket");
948     g_snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", port);
949     g_snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "%u", port);
950     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
951     break;
952
953   case PT_IPX:
954     /* XXX - resolve IPX socket numbers */
955     g_snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "0x%04x", port);
956     if (is_src)
957       strcpy(pinfo->cinfo->col_expr[col], "ipx.src.socket");
958     else
959       strcpy(pinfo->cinfo->col_expr[col], "ipx.dst.socket");
960     g_snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "0x%04x", port);
961     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
962     break;
963
964   case PT_IDP:
965     /* XXX - resolve IDP socket numbers */
966     g_snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "0x%04x", port);
967     if (is_src)
968       strcpy(pinfo->cinfo->col_expr[col], "idp.src.socket");
969     else
970       strcpy(pinfo->cinfo->col_expr[col], "idp.dst.socket");
971     g_snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "0x%04x", port);
972     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
973     break;
974
975   default:
976     break;
977   }
978   pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
979   pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
980 }
981
982 /*
983  * XXX - this should be in some common code in the epan directory, shared
984  * by this code and packet-isdn.c.
985  */
986 static const value_string channel_vals[] = {
987         { 0,    "D" },
988         { 1,    "B1" },
989         { 2,    "B2" },
990         { 3,    "B3" },
991         { 4,    "B4" },
992         { 5,    "B5" },
993         { 6,    "B6" },
994         { 7,    "B7" },
995         { 8,    "B8" },
996         { 9,    "B9" },
997         { 10,   "B10" },
998         { 11,   "B11" },
999         { 12,   "B12" },
1000         { 13,   "B13" },
1001         { 14,   "B14" },
1002         { 15,   "B15" },
1003         { 16,   "B16" },
1004         { 17,   "B17" },
1005         { 18,   "B19" },
1006         { 19,   "B19" },
1007         { 20,   "B20" },
1008         { 21,   "B21" },
1009         { 22,   "B22" },
1010         { 23,   "B23" },
1011         { 24,   "B24" },
1012         { 25,   "B25" },
1013         { 26,   "B26" },
1014         { 27,   "B27" },
1015         { 28,   "B29" },
1016         { 29,   "B29" },
1017         { 30,   "B30" },
1018         { 0,    NULL }
1019 };
1020
1021 static void
1022 col_set_circuit_id(packet_info *pinfo, int col)
1023 {
1024   pinfo->cinfo->col_expr[col][0] = '\0';
1025   pinfo->cinfo->col_expr_val[col][0] = '\0';
1026   switch (pinfo->ctype) {
1027
1028   case CT_DLCI:
1029     g_snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", pinfo->circuit_id);
1030     strcpy(pinfo->cinfo->col_expr[col], "fr.dlci");
1031     g_snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "%u", pinfo->circuit_id);
1032     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
1033     break;
1034
1035   case CT_ISDN:
1036     g_snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%s",
1037              val_to_str(pinfo->circuit_id, channel_vals, "Unknown (%u)"));
1038     strcpy(pinfo->cinfo->col_expr[col], "isdn.channel");
1039     g_snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "%u", pinfo->circuit_id);
1040     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
1041     break;
1042
1043   case CT_X25:
1044     g_snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", pinfo->circuit_id);
1045     break;
1046
1047   case CT_ISUP:
1048     g_snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", pinfo->circuit_id);
1049     strcpy(pinfo->cinfo->col_expr[col], "isup.cic");
1050     g_snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "%u", pinfo->circuit_id);
1051     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
1052     break;
1053
1054   default:
1055     break;
1056   }
1057   pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
1058   pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
1059 }
1060
1061 void
1062 col_fill_in(packet_info *pinfo)
1063 {
1064   int i;
1065
1066   for (i = 0; i < pinfo->cinfo->num_cols; i++) {
1067     switch (pinfo->cinfo->col_fmt[i]) {
1068
1069     case COL_NUMBER:
1070       g_snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "%u", pinfo->fd->num);
1071       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
1072       strcpy(pinfo->cinfo->col_expr[i], "frame.number");
1073       strcpy(pinfo->cinfo->col_expr_val[i], pinfo->cinfo->col_buf[i]);
1074       break;
1075
1076     case COL_CLS_TIME:
1077        col_set_cls_time(pinfo->fd, pinfo->cinfo, i);
1078       break;
1079
1080     case COL_ABS_TIME:
1081       col_set_abs_time(pinfo->fd, pinfo->cinfo, i);
1082       break;
1083
1084     case COL_ABS_DATE_TIME:
1085       col_set_abs_date_time(pinfo->fd, pinfo->cinfo, i);
1086       break;
1087
1088     case COL_REL_TIME:
1089       col_set_rel_time(pinfo->fd, pinfo->cinfo, i);
1090       break;
1091
1092     case COL_DELTA_TIME:
1093       col_set_delta_time(pinfo->fd, pinfo->cinfo, i);
1094       break;
1095
1096     case COL_DEF_SRC:
1097     case COL_RES_SRC:   /* COL_DEF_SRC is currently just like COL_RES_SRC */
1098       col_set_addr(pinfo, i, &pinfo->src, TRUE, TRUE);
1099       break;
1100
1101     case COL_UNRES_SRC:
1102       col_set_addr(pinfo, i, &pinfo->src, FALSE, TRUE);
1103       break;
1104
1105     case COL_DEF_DL_SRC:
1106     case COL_RES_DL_SRC:
1107       col_set_addr(pinfo, i, &pinfo->dl_src, TRUE, TRUE);
1108       break;
1109
1110     case COL_UNRES_DL_SRC:
1111       col_set_addr(pinfo, i, &pinfo->dl_src, FALSE, TRUE);
1112       break;
1113
1114     case COL_DEF_NET_SRC:
1115     case COL_RES_NET_SRC:
1116       col_set_addr(pinfo, i, &pinfo->net_src, TRUE, TRUE);
1117       break;
1118
1119     case COL_UNRES_NET_SRC:
1120       col_set_addr(pinfo, i, &pinfo->net_src, FALSE, TRUE);
1121       break;
1122
1123     case COL_DEF_DST:
1124     case COL_RES_DST:   /* COL_DEF_DST is currently just like COL_RES_DST */
1125       col_set_addr(pinfo, i, &pinfo->dst, TRUE, FALSE);
1126       break;
1127
1128     case COL_UNRES_DST:
1129       col_set_addr(pinfo, i, &pinfo->dst, FALSE, FALSE);
1130       break;
1131
1132     case COL_DEF_DL_DST:
1133     case COL_RES_DL_DST:
1134       col_set_addr(pinfo, i, &pinfo->dl_dst, TRUE, FALSE);
1135       break;
1136
1137     case COL_UNRES_DL_DST:
1138       col_set_addr(pinfo, i, &pinfo->dl_dst, FALSE, FALSE);
1139       break;
1140
1141     case COL_DEF_NET_DST:
1142     case COL_RES_NET_DST:
1143       col_set_addr(pinfo, i, &pinfo->net_dst, TRUE, FALSE);
1144       break;
1145
1146     case COL_UNRES_NET_DST:
1147       col_set_addr(pinfo, i, &pinfo->net_dst, FALSE, FALSE);
1148       break;
1149
1150     case COL_DEF_SRC_PORT:
1151     case COL_RES_SRC_PORT:      /* COL_DEF_SRC_PORT is currently just like COL_RES_SRC_PORT */
1152       col_set_port(pinfo, i, TRUE, TRUE);
1153       break;
1154
1155     case COL_UNRES_SRC_PORT:
1156       col_set_port(pinfo, i, FALSE, TRUE);
1157       break;
1158
1159     case COL_DEF_DST_PORT:
1160     case COL_RES_DST_PORT:      /* COL_DEF_DST_PORT is currently just like COL_RES_DST_PORT */
1161       col_set_port(pinfo, i, TRUE, FALSE);
1162       break;
1163
1164     case COL_UNRES_DST_PORT:
1165       col_set_port(pinfo, i, FALSE, FALSE);
1166       break;
1167
1168     case COL_PROTOCOL:  /* currently done by dissectors */
1169     case COL_INFO:      /* currently done by dissectors */
1170       break;
1171
1172     case COL_PACKET_LENGTH:
1173       g_snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "%u", pinfo->fd->pkt_len);
1174       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
1175       strcpy(pinfo->cinfo->col_expr[i], "frame.pkt_len");
1176       strcpy(pinfo->cinfo->col_expr_val[i], pinfo->cinfo->col_buf[i]);
1177       break;
1178
1179     case COL_CUMULATIVE_BYTES:
1180       g_snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "%u", pinfo->fd->cum_bytes);
1181       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
1182       break;
1183
1184     case COL_OXID:
1185       g_snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "0x%x", pinfo->oxid);
1186       pinfo->cinfo->col_buf[i][COL_MAX_LEN - 1] = '\0';
1187       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
1188       break;
1189
1190     case COL_RXID:
1191       g_snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "0x%x", pinfo->rxid);
1192       pinfo->cinfo->col_buf[i][COL_MAX_LEN - 1] = '\0';
1193       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
1194       break;
1195
1196     case COL_IF_DIR:    /* currently done by dissectors */
1197       break;
1198
1199     case COL_CIRCUIT_ID:
1200       col_set_circuit_id(pinfo, i);
1201       break;
1202
1203     case COL_SRCIDX:
1204       g_snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "0x%x", pinfo->src_idx);
1205       pinfo->cinfo->col_buf[i][COL_MAX_LEN - 1] = '\0';
1206       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
1207       break;
1208
1209     case COL_DSTIDX:
1210       g_snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "0x%x", pinfo->dst_idx);
1211       pinfo->cinfo->col_buf[i][COL_MAX_LEN - 1] = '\0';
1212       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
1213       break;
1214
1215     case COL_VSAN:
1216       g_snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "%u", pinfo->vsan);
1217       pinfo->cinfo->col_buf[i][COL_MAX_LEN - 1] = '\0';
1218       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
1219       break;
1220         
1221     case COL_HPUX_SUBSYS: /* done by nettl disector */
1222     case COL_HPUX_DEVID:  /* done by nettl disector */
1223       break;
1224         
1225     case COL_DCE_CALL:  /* done by dcerpc */
1226       break;
1227
1228     case COL_8021Q_VLAN_ID:
1229         break;
1230
1231     case NUM_COL_FMTS:  /* keep compiler happy - shouldn't get here */
1232       g_assert_not_reached();
1233       break;
1234     }
1235   }
1236 }