"ssn_range" needs to be a copy of "global_ssn_range", so that it's not
[obnox/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, 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   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         orig = orig_buf;
361         strncpy(orig, cinfo->col_buf[i], max_len);
362         orig[max_len - 1] = '\0';
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   guint32 ipv4_addr;
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     switch (addr->type) {
586
587     case AT_ETHER:
588       strncpy(pinfo->cinfo->col_buf[col], get_ether_name(addr->data), COL_MAX_LEN);
589       pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
590       break;
591
592     case AT_IPv4:
593       memcpy(&ipv4_addr, addr->data, sizeof ipv4_addr);
594       strncpy(pinfo->cinfo->col_buf[col], get_hostname(ipv4_addr), COL_MAX_LEN);
595       pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
596       break;
597
598     case AT_IPv6:
599       memcpy(&ipv6_addr.s6_addr, addr->data, sizeof ipv6_addr.s6_addr);
600       strncpy(pinfo->cinfo->col_buf[col], get_hostname6(&ipv6_addr), COL_MAX_LEN);
601       pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
602       break;
603
604     case AT_STRINGZ:
605       /* XXX - should be done in "address_to_str_buf()", but that routine
606          doesn't know COL_MAX_LEN; it should be changed to take the
607          maximum length as an argument. */
608       strncpy(pinfo->cinfo->col_buf[col], addr->data, COL_MAX_LEN);
609       pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
610       break;
611
612     default:
613       address_to_str_buf(addr, pinfo->cinfo->col_buf[col]);
614       break;
615     }
616   } else {
617     switch (addr->type) {
618
619     case AT_STRINGZ:
620       /* XXX - should be done in "address_to_str_buf()", but that routine
621          doesn't know COL_MAX_LEN; it should be changed to take the
622          maximum length as an argument. */
623       strncpy(pinfo->cinfo->col_buf[col], addr->data, COL_MAX_LEN);
624       pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
625       break;
626
627     default:
628       address_to_str_buf(addr, pinfo->cinfo->col_buf[col]);
629       break;
630     }
631   }
632   pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
633
634   switch (addr->type) {
635
636   case AT_ETHER:
637     if (is_src)
638       strcpy(pinfo->cinfo->col_expr[col], "eth.src");
639     else
640       strcpy(pinfo->cinfo->col_expr[col], "eth.dst");
641     strncpy(pinfo->cinfo->col_expr_val[col], ether_to_str(addr->data), COL_MAX_LEN);
642     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
643     break;
644
645   case AT_IPv4:
646     if (is_src)
647       strcpy(pinfo->cinfo->col_expr[col], "ip.src");
648     else
649       strcpy(pinfo->cinfo->col_expr[col], "ip.dst");
650     strncpy(pinfo->cinfo->col_expr_val[col], ip_to_str(addr->data), COL_MAX_LEN);
651     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
652     break;
653
654   case AT_IPv6:
655     if (is_src)
656       strcpy(pinfo->cinfo->col_expr[col], "ipv6.src");
657     else
658       strcpy(pinfo->cinfo->col_expr[col], "ipv6.dst");
659     strncpy(pinfo->cinfo->col_expr_val[col], ip6_to_str(&ipv6_addr), COL_MAX_LEN);
660     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
661     break;
662
663   case AT_ATALK:
664     if (is_src)
665       strcpy(pinfo->cinfo->col_expr[col], "ddp.src");
666     else
667       strcpy(pinfo->cinfo->col_expr[col], "ddp.dst");
668     strcpy(pinfo->cinfo->col_expr_val[col], pinfo->cinfo->col_buf[col]);
669     break;
670
671   case AT_ARCNET:
672     if (is_src)
673       strcpy(pinfo->cinfo->col_expr[col], "arcnet.src");
674     else
675       strcpy(pinfo->cinfo->col_expr[col], "arcnet.dst");
676     strcpy(pinfo->cinfo->col_expr_val[col], pinfo->cinfo->col_buf[col]);
677     break;
678
679   default:
680     break;
681   }
682 }
683
684 static void
685 col_set_port(packet_info *pinfo, int col, gboolean is_res, gboolean is_src)
686 {
687   guint32 port;
688
689   if (is_src)
690     port = pinfo->srcport;
691   else
692     port = pinfo->destport;
693   pinfo->cinfo->col_expr[col][0] = '\0';
694   pinfo->cinfo->col_expr_val[col][0] = '\0';
695   switch (pinfo->ptype) {
696
697   case PT_SCTP:
698     if (is_res)
699       strncpy(pinfo->cinfo->col_buf[col], get_sctp_port(port), COL_MAX_LEN);
700     else
701       snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", port);
702     break;
703
704   case PT_TCP:
705     if (is_res)
706       strncpy(pinfo->cinfo->col_buf[col], get_tcp_port(port), COL_MAX_LEN);
707     else
708       snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", port);
709     if (is_src)
710       strcpy(pinfo->cinfo->col_expr[col], "tcp.srcport");
711     else
712       strcpy(pinfo->cinfo->col_expr[col], "tcp.dstport");
713     snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "%u", port);
714     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
715     break;
716
717   case PT_UDP:
718     if (is_res)
719       strncpy(pinfo->cinfo->col_buf[col], get_udp_port(port), COL_MAX_LEN);
720     else
721       snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", port);
722     if (is_src)
723       strcpy(pinfo->cinfo->col_expr[col], "udp.srcport");
724     else
725       strcpy(pinfo->cinfo->col_expr[col], "udp.dstport");
726     snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "%u", port);
727     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
728     break;
729
730   case PT_DDP:
731     if (is_src)
732       strcpy(pinfo->cinfo->col_expr[col], "ddp.src_socket");
733     else
734       strcpy(pinfo->cinfo->col_expr[col], "ddp.dst_socket");
735     snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", port);
736     snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "%u", port);
737     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
738     break;
739
740   case PT_IPX:
741     /* XXX - resolve IPX socket numbers */
742     snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "0x%04x", port);
743     if (is_src)
744       strcpy(pinfo->cinfo->col_expr[col], "ipx.src.socket");
745     else
746       strcpy(pinfo->cinfo->col_expr[col], "ipx.dst.socket");
747     snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "0x%04x", port);
748     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
749     break;
750
751   default:
752     break;
753   }
754   pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
755   pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
756 }
757
758 /*
759  * XXX - this should be in some common code in the epan directory, shared
760  * by this code and packet-isdn.c.
761  */
762 static const value_string channel_vals[] = {
763         { 0,    "D" },
764         { 1,    "B1" },
765         { 2,    "B2" },
766         { 3,    "B3" },
767         { 4,    "B4" },
768         { 5,    "B5" },
769         { 6,    "B6" },
770         { 7,    "B7" },
771         { 8,    "B8" },
772         { 9,    "B9" },
773         { 10,   "B10" },
774         { 11,   "B11" },
775         { 12,   "B12" },
776         { 13,   "B13" },
777         { 14,   "B14" },
778         { 15,   "B15" },
779         { 16,   "B16" },
780         { 17,   "B17" },
781         { 18,   "B19" },
782         { 19,   "B19" },
783         { 20,   "B20" },
784         { 21,   "B21" },
785         { 22,   "B22" },
786         { 23,   "B23" },
787         { 24,   "B24" },
788         { 25,   "B25" },
789         { 26,   "B26" },
790         { 27,   "B27" },
791         { 28,   "B29" },
792         { 29,   "B29" },
793         { 30,   "B30" },
794         { 0,    NULL }
795 };
796
797 static void
798 col_set_circuit_id(packet_info *pinfo, int col)
799 {
800   pinfo->cinfo->col_expr[col][0] = '\0';
801   pinfo->cinfo->col_expr_val[col][0] = '\0';
802   switch (pinfo->ctype) {
803
804   case CT_DLCI:
805     snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", pinfo->circuit_id);
806     strcpy(pinfo->cinfo->col_expr[col], "fr.dlci");
807     snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "%u", pinfo->circuit_id);
808     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
809     break;
810
811   case CT_ISDN:
812     snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%s",
813              val_to_str(pinfo->circuit_id, channel_vals, "Unknown (%u)"));
814     strcpy(pinfo->cinfo->col_expr[col], "isdn.channel");
815     snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "%u", pinfo->circuit_id);
816     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
817     break;
818
819   case CT_X25:
820     snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", pinfo->circuit_id);
821     break;
822
823   case CT_ISUP:
824     snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", pinfo->circuit_id);
825     strcpy(pinfo->cinfo->col_expr[col], "isup.cic");
826     snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "%u", pinfo->circuit_id);
827     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
828     break;
829
830   default:
831     break;
832   }
833   pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
834   pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
835 }
836
837 void
838 fill_in_columns(packet_info *pinfo)
839 {
840   int i;
841
842   for (i = 0; i < pinfo->cinfo->num_cols; i++) {
843     switch (pinfo->cinfo->col_fmt[i]) {
844
845     case COL_NUMBER:
846       snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "%u", pinfo->fd->num);
847       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
848       strcpy(pinfo->cinfo->col_expr[i], "frame.number");
849       strcpy(pinfo->cinfo->col_expr_val[i], pinfo->cinfo->col_buf[i]);
850       break;
851
852     case COL_CLS_TIME:
853       if(pinfo->fd->flags.ref_time){
854          snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "*REF*");
855          pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
856       } else {
857          col_set_cls_time(pinfo->fd, pinfo->cinfo, i);
858       }
859       break;
860
861     case COL_ABS_TIME:
862       if(pinfo->fd->flags.ref_time){
863          snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "*REF*");
864          pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
865       } else {
866          col_set_abs_time(pinfo->fd, pinfo->cinfo, i);
867       }
868       break;
869
870     case COL_ABS_DATE_TIME:
871       if(pinfo->fd->flags.ref_time){
872          snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "*REF*");
873          pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
874       } else {
875          col_set_abs_date_time(pinfo->fd, pinfo->cinfo, i);
876       }
877       break;
878
879     case COL_REL_TIME:
880       if(pinfo->fd->flags.ref_time){
881          snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "*REF*");
882          pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
883       } else {
884          col_set_rel_time(pinfo->fd, pinfo->cinfo, i);
885       }
886       break;
887
888     case COL_DELTA_TIME:
889       if(pinfo->fd->flags.ref_time){
890          snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "*REF*");
891          pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
892       } else {
893          col_set_delta_time(pinfo->fd, pinfo->cinfo, i);
894       }
895       break;
896
897     case COL_DEF_SRC:
898     case COL_RES_SRC:   /* COL_DEF_SRC is currently just like COL_RES_SRC */
899       col_set_addr(pinfo, i, &pinfo->src, TRUE, TRUE);
900       break;
901
902     case COL_UNRES_SRC:
903       col_set_addr(pinfo, i, &pinfo->src, FALSE, TRUE);
904       break;
905
906     case COL_DEF_DL_SRC:
907     case COL_RES_DL_SRC:
908       col_set_addr(pinfo, i, &pinfo->dl_src, TRUE, TRUE);
909       break;
910
911     case COL_UNRES_DL_SRC:
912       col_set_addr(pinfo, i, &pinfo->dl_src, FALSE, TRUE);
913       break;
914
915     case COL_DEF_NET_SRC:
916     case COL_RES_NET_SRC:
917       col_set_addr(pinfo, i, &pinfo->net_src, TRUE, TRUE);
918       break;
919
920     case COL_UNRES_NET_SRC:
921       col_set_addr(pinfo, i, &pinfo->net_src, FALSE, TRUE);
922       break;
923
924     case COL_DEF_DST:
925     case COL_RES_DST:   /* COL_DEF_DST is currently just like COL_RES_DST */
926       col_set_addr(pinfo, i, &pinfo->dst, TRUE, FALSE);
927       break;
928
929     case COL_UNRES_DST:
930       col_set_addr(pinfo, i, &pinfo->dst, FALSE, FALSE);
931       break;
932
933     case COL_DEF_DL_DST:
934     case COL_RES_DL_DST:
935       col_set_addr(pinfo, i, &pinfo->dl_dst, TRUE, FALSE);
936       break;
937
938     case COL_UNRES_DL_DST:
939       col_set_addr(pinfo, i, &pinfo->dl_dst, FALSE, FALSE);
940       break;
941
942     case COL_DEF_NET_DST:
943     case COL_RES_NET_DST:
944       col_set_addr(pinfo, i, &pinfo->net_dst, TRUE, FALSE);
945       break;
946
947     case COL_UNRES_NET_DST:
948       col_set_addr(pinfo, i, &pinfo->net_dst, FALSE, FALSE);
949       break;
950
951     case COL_DEF_SRC_PORT:
952     case COL_RES_SRC_PORT:      /* COL_DEF_SRC_PORT is currently just like COL_RES_SRC_PORT */
953       col_set_port(pinfo, i, TRUE, TRUE);
954       break;
955
956     case COL_UNRES_SRC_PORT:
957       col_set_port(pinfo, i, FALSE, TRUE);
958       break;
959
960     case COL_DEF_DST_PORT:
961     case COL_RES_DST_PORT:      /* COL_DEF_DST_PORT is currently just like COL_RES_DST_PORT */
962       col_set_port(pinfo, i, TRUE, FALSE);
963       break;
964
965     case COL_UNRES_DST_PORT:
966       col_set_port(pinfo, i, FALSE, FALSE);
967       break;
968
969     case COL_PROTOCOL:  /* currently done by dissectors */
970     case COL_INFO:      /* currently done by dissectors */
971       break;
972
973     case COL_PACKET_LENGTH:
974       snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "%u", pinfo->fd->pkt_len);
975       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
976       strcpy(pinfo->cinfo->col_expr[i], "frame.pkt_len");
977       strcpy(pinfo->cinfo->col_expr_val[i], pinfo->cinfo->col_buf[i]);
978       break;
979
980     case COL_CUMULATIVE_BYTES:
981       snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "%u", pinfo->fd->cum_bytes);
982       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
983       break;
984
985     case COL_OXID:
986       snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "0x%x", pinfo->oxid);
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_RXID:
992       snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "0x%x", pinfo->rxid);
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 COL_IF_DIR:    /* currently done by dissectors */
998       break;
999
1000     case COL_CIRCUIT_ID:
1001       col_set_circuit_id(pinfo, i);
1002       break;
1003
1004     case COL_SRCIDX:
1005       snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "0x%x", pinfo->src_idx);
1006       pinfo->cinfo->col_buf[i][COL_MAX_LEN - 1] = '\0';
1007       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
1008       break;
1009
1010     case COL_DSTIDX:
1011       snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "0x%x", pinfo->dst_idx);
1012       pinfo->cinfo->col_buf[i][COL_MAX_LEN - 1] = '\0';
1013       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
1014       break;
1015
1016     case COL_VSAN:
1017       snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "%u", pinfo->vsan);
1018       pinfo->cinfo->col_buf[i][COL_MAX_LEN - 1] = '\0';
1019       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
1020       break;
1021         
1022     case NUM_COL_FMTS:  /* keep compiler happy - shouldn't get here */
1023       g_assert_not_reached();
1024       break;
1025     }
1026   }
1027 }