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