From Jirka Novak:
[obnox/wireshark/wip.git] / epan / column-utils.c
1 /* column-utils.c
2  * Routines for column utilities.
3  *
4  * $Id: column-utils.c,v 1.10 2002/01/11 08:21:00 guy Exp $
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 HAVE_SYS_TYPES_H
33 # include <sys/types.h>
34 #endif
35
36 #ifdef NEED_SNPRINTF_H
37 # include "snprintf.h"
38 #endif
39
40 #ifdef NEED_INET_V6DEFS_H
41 # include "inet_v6defs.h"
42 #endif
43
44 #include "column-utils.h"
45 #include "timestamp.h"
46 #include "sna-utils.h"
47 #include "atalk-utils.h"
48 #include "to_str.h"
49 #include "packet_info.h"
50 #include "pint.h"
51 #include "resolv.h"
52 #include "ipv6-utils.h" 
53 #include "osi-utils.h"
54
55 /* Allocate all the data structures for constructing column data, given
56    the number of columns. */
57 void
58 col_init(column_info *col_info, gint num_cols)
59 {
60   col_info->num_cols    = num_cols;
61   col_info->col_fmt     = (gint *) g_malloc(sizeof(gint) * num_cols);
62   col_info->fmt_matx    = (gboolean **) g_malloc(sizeof(gboolean *) * num_cols);
63   col_info->col_width   = (gint *) g_malloc(sizeof(gint) * num_cols);
64   col_info->col_title   = (gchar **) g_malloc(sizeof(gchar *) * num_cols);
65   col_info->col_data    = (gchar **) g_malloc(sizeof(gchar *) * num_cols);
66   col_info->col_buf     = (gchar **) g_malloc(sizeof(gchar *) * num_cols);
67   col_info->col_expr    = (gchar **) g_malloc(sizeof(gchar *) * num_cols);
68   col_info->col_expr_val = (gchar **) g_malloc(sizeof(gchar *) * num_cols);
69 }
70
71 #if 0
72 /*
73  * This function does not appear to be used anywhere...  
74  */
75 gboolean
76 col_get_writable(column_info *cinfo)
77 {
78         return (cinfo ? cinfo->writable : FALSE);
79 }
80 #endif
81
82 void
83 col_set_writable(column_info *cinfo, gboolean writable)
84 {
85         if (cinfo)
86                 cinfo->writable = writable;
87 }
88
89 /* Checks to see if a particular packet information element is needed for
90    the packet list */
91 gint
92 check_col(column_info *cinfo, gint el) {
93   int i;
94
95   if (cinfo && cinfo->writable) {
96     for (i = 0; i < cinfo->num_cols; i++) {
97       if (cinfo->fmt_matx[i][el])
98         return TRUE;
99     }
100   }
101   return FALSE;
102 }
103
104
105
106 /* Use this to clear out a column, especially if you're going to be
107    appending to it later; at least on some platforms, it's more
108    efficient than using "col_add_str()" with a null string, and
109    more efficient than "col_set_str()" with a null string if you
110    later append to it, as the later append will cause a string
111    copy to be done. */
112 void
113 col_clear(column_info *cinfo, gint el) {
114   int    i;
115
116   for (i = 0; i < cinfo->num_cols; i++) {
117     if (cinfo->fmt_matx[i][el]) {
118       cinfo->col_buf[i][0] = 0;
119       cinfo->col_data[i] = cinfo->col_buf[i];
120       cinfo->col_expr[i][0] = '\0';
121       cinfo->col_expr_val[i][0] = '\0';
122     }
123   }
124 }
125
126 /* Use this if "str" points to something that will stay around (and thus
127    needn't be copied). */
128 void
129 col_set_str(column_info *cinfo, gint el, gchar* str) {
130   int i;
131   
132   for (i = 0; i < cinfo->num_cols; i++) {
133     if (cinfo->fmt_matx[i][el])
134       cinfo->col_data[i] = str;
135   }
136 }
137
138 /* Adds a vararg list to a packet info string. */
139 void
140 col_add_fstr(column_info *cinfo, gint el, gchar *format, ...) {
141   va_list ap;
142   int     i;
143   size_t  max_len;
144
145   if (el == COL_INFO)
146         max_len = COL_MAX_INFO_LEN;
147   else
148         max_len = COL_MAX_LEN;
149   
150   va_start(ap, format);
151   for (i = 0; i < cinfo->num_cols; i++) {
152     if (cinfo->fmt_matx[i][el]) {
153       vsnprintf(cinfo->col_buf[i], max_len, format, ap);
154       cinfo->col_data[i] = cinfo->col_buf[i];
155     }
156   }
157 }
158
159 /* Appends a vararg list to a packet info string. */
160 void
161 col_append_fstr(column_info *cinfo, gint el, gchar *format, ...) {
162   va_list ap;
163   int     i;
164   size_t  len, max_len;
165   
166   if (el == COL_INFO)
167         max_len = COL_MAX_INFO_LEN;
168   else
169         max_len = COL_MAX_LEN;
170   
171   va_start(ap, format);
172   for (i = 0; i < cinfo->num_cols; i++) {
173     if (cinfo->fmt_matx[i][el]) {
174       if (cinfo->col_data[i] != cinfo->col_buf[i]) {
175         /* This was set with "col_set_str()"; copy the string they
176            set it to into the buffer, so we can append to it. */
177         strncpy(cinfo->col_buf[i], cinfo->col_data[i], max_len);
178         cinfo->col_buf[i][max_len - 1] = '\0';
179       }
180       len = strlen(cinfo->col_buf[i]);
181       vsnprintf(&cinfo->col_buf[i][len], max_len - len, format, ap);
182       cinfo->col_data[i] = cinfo->col_buf[i];
183     }
184   }
185 }
186
187 /* Use this if "str" points to something that won't stay around (and
188    must thus be copied). */
189 void
190 col_add_str(column_info *cinfo, gint el, const gchar* str) {
191   int    i;
192   size_t max_len;
193
194   if (el == COL_INFO)
195         max_len = COL_MAX_INFO_LEN;
196   else
197         max_len = COL_MAX_LEN;
198   
199   for (i = 0; i < cinfo->num_cols; i++) {
200     if (cinfo->fmt_matx[i][el]) {
201       strncpy(cinfo->col_buf[i], str, max_len);
202       cinfo->col_buf[i][max_len - 1] = 0;
203       cinfo->col_data[i] = cinfo->col_buf[i];
204     }
205   }
206 }
207
208 void
209 col_append_str(column_info *cinfo, gint el, gchar* str) {
210   int    i;
211   size_t len, max_len;
212
213   if (el == COL_INFO)
214         max_len = COL_MAX_INFO_LEN;
215   else
216         max_len = COL_MAX_LEN;
217   
218   for (i = 0; i < cinfo->num_cols; i++) {
219     if (cinfo->fmt_matx[i][el]) {
220       if (cinfo->col_data[i] != cinfo->col_buf[i]) {
221         /* This was set with "col_set_str()"; copy the string they
222            set it to into the buffer, so we can append to it. */
223         strncpy(cinfo->col_buf[i], cinfo->col_data[i], max_len);
224         cinfo->col_buf[i][max_len - 1] = '\0';
225       }
226       len = strlen(cinfo->col_buf[i]);
227       strncat(cinfo->col_buf[i], str, max_len - len);
228       cinfo->col_buf[i][max_len - 1] = 0;
229       cinfo->col_data[i] = cinfo->col_buf[i];
230     }
231   }
232 }
233
234 static void
235 col_set_abs_date_time(frame_data *fd, column_info *cinfo, int col)
236 {
237   struct tm *tmp;
238   time_t then;
239
240   then = fd->abs_secs;
241   tmp = localtime(&then);
242   if (tmp != NULL) {
243     snprintf(cinfo->col_buf[col], COL_MAX_LEN,
244              "%04d-%02d-%02d %02d:%02d:%02d.%04ld",
245              tmp->tm_year + 1900,
246              tmp->tm_mon + 1,
247              tmp->tm_mday,
248              tmp->tm_hour,
249              tmp->tm_min,
250              tmp->tm_sec,
251              (long)fd->abs_usecs/100);
252   } else {
253     cinfo->col_buf[col][0] = '\0';
254   }
255   cinfo->col_data[col] = cinfo->col_buf[col];
256   strcpy(cinfo->col_expr[col],"frame.time");
257   strcpy(cinfo->col_expr_val[col],cinfo->col_buf[col]);
258 }
259
260 static void
261 col_set_rel_time(frame_data *fd, column_info *cinfo, int col)
262 {
263   display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
264         fd->rel_secs, fd->rel_usecs, USECS);
265   cinfo->col_data[col] = cinfo->col_buf[col];
266   strcpy(cinfo->col_expr[col],"frame.time_relative");
267   strcpy(cinfo->col_expr_val[col],cinfo->col_buf[col]);
268 }
269
270 static void
271 col_set_delta_time(frame_data *fd, column_info *cinfo, int col)
272 {
273   display_signed_time(cinfo->col_buf[col], COL_MAX_LEN,
274         fd->del_secs, fd->del_usecs, USECS);
275   cinfo->col_data[col] = cinfo->col_buf[col];
276   strcpy(cinfo->col_expr[col],"frame.time_delta");
277   strcpy(cinfo->col_expr_val[col],cinfo->col_buf[col]);
278 }
279
280 /* To do: Add check_col checks to the col_add* routines */
281
282 static void
283 col_set_abs_time(frame_data *fd, column_info *cinfo, int col)
284 {
285   struct tm *tmp;
286   time_t then;
287
288   then = fd->abs_secs;
289   tmp = localtime(&then);
290   if (tmp != NULL) {
291     snprintf(cinfo->col_buf[col], COL_MAX_LEN, "%02d:%02d:%02d.%04ld",
292              tmp->tm_hour,
293              tmp->tm_min,
294              tmp->tm_sec,
295              (long)fd->abs_usecs/100);
296   } else {
297     cinfo->col_buf[col][0] = '\0';
298   }
299   cinfo->col_data[col] = cinfo->col_buf[col];
300   strcpy(cinfo->col_expr[col],"frame.time");
301   strcpy(cinfo->col_expr_val[col],cinfo->col_buf[col]);
302 }
303
304 /* Add "command-line-specified" time.
305    XXX - this is called from "file.c" when the user changes the time
306    format they want for "command-line-specified" time; it's a bit ugly
307    that we have to export it, but if we go to a CList-like widget that
308    invokes callbacks to get the text for the columns rather than
309    requiring us to stuff the text into the widget from outside, we
310    might be able to clean this up. */
311 void
312 col_set_cls_time(frame_data *fd, column_info *cinfo, int col)
313 {
314   switch (timestamp_type) {
315     case ABSOLUTE:
316       col_set_abs_time(fd, cinfo, col);
317       break;
318
319     case ABSOLUTE_WITH_DATE:
320       col_set_abs_date_time(fd, cinfo, col);
321       break;
322
323     case RELATIVE:
324       col_set_rel_time(fd, cinfo, col);
325       break;
326
327     case DELTA:
328       col_set_delta_time(fd, cinfo, col);
329       break;
330   }
331 }
332
333 static void
334 col_set_addr(packet_info *pinfo, int col, address *addr, gboolean is_res,
335              gboolean is_src)
336 {
337   guint32 ipv4_addr;
338   struct e_in6_addr ipv6_addr;
339   struct atalk_ddp_addr ddp_addr;
340   struct sna_fid_type_4_addr sna_fid_type_4_addr;
341
342   pinfo->cinfo->col_expr[col][0] = '\0';
343   pinfo->cinfo->col_expr_val[col][0] = '\0';
344   switch (addr->type) {
345
346   case AT_ETHER:
347     if (is_res)
348       strncpy(pinfo->cinfo->col_buf[col], get_ether_name(addr->data), COL_MAX_LEN);
349     else
350       strncpy(pinfo->cinfo->col_buf[col], ether_to_str(addr->data), COL_MAX_LEN);
351     pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
352     pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
353     if (is_src)
354       strcpy(pinfo->cinfo->col_expr[col], "eth.src");
355     else
356       strcpy(pinfo->cinfo->col_expr[col], "eth.dst");
357     strncpy(pinfo->cinfo->col_expr_val[col], ether_to_str(addr->data), COL_MAX_LEN);
358     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
359     break;
360
361   case AT_IPv4:
362     memcpy(&ipv4_addr, addr->data, sizeof ipv4_addr);
363     if (is_res)
364       strncpy(pinfo->cinfo->col_buf[col], get_hostname(ipv4_addr), COL_MAX_LEN);
365     else
366       strncpy(pinfo->cinfo->col_buf[col], ip_to_str(addr->data), COL_MAX_LEN);
367     pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
368     pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
369     if (is_src)
370       strcpy(pinfo->cinfo->col_expr[col], "ip.src");
371     else
372       strcpy(pinfo->cinfo->col_expr[col], "ip.dst");
373     strncpy(pinfo->cinfo->col_expr_val[col], ip_to_str(addr->data), COL_MAX_LEN);
374     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
375     break;
376
377   case AT_IPv6:
378     memcpy(&ipv6_addr.s6_addr, addr->data, sizeof ipv6_addr.s6_addr);
379     if (is_res)
380       strncpy(pinfo->cinfo->col_buf[col], get_hostname6(&ipv6_addr), COL_MAX_LEN);
381     else
382       strncpy(pinfo->cinfo->col_buf[col], ip6_to_str(&ipv6_addr), COL_MAX_LEN);
383     pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
384     pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
385     if (is_src)
386       strcpy(pinfo->cinfo->col_expr[col], "ipv6.src");
387     else
388       strcpy(pinfo->cinfo->col_expr[col], "ipv6.dst");
389     strncpy(pinfo->cinfo->col_expr_val[col], ip6_to_str(&ipv6_addr), COL_MAX_LEN);
390     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
391     break;
392
393   case AT_IPX:
394     strncpy(pinfo->cinfo->col_buf[col],
395       ipx_addr_to_str(pntohl(&addr->data[0]), &addr->data[4]), COL_MAX_LEN);
396     pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
397     pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
398     if (is_src)
399       strcpy(pinfo->cinfo->col_expr[col], "ipx.src");
400     else
401       strcpy(pinfo->cinfo->col_expr[col], "ipx.dst");
402     strcpy(pinfo->cinfo->col_expr_val[col],pinfo->cinfo->col_buf[col]);
403     break;
404
405   case AT_SNA:
406     switch (addr->len) {
407
408     case 1:
409       snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%04X", addr->data[0]);
410       break;
411
412     case 2:
413       snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%04X",
414         pntohs(&addr->data[0]));
415       break;
416
417     case SNA_FID_TYPE_4_ADDR_LEN:
418       memcpy(&sna_fid_type_4_addr, addr->data, SNA_FID_TYPE_4_ADDR_LEN);
419       strncpy(pinfo->cinfo->col_buf[col],
420         sna_fid_type_4_addr_to_str(&sna_fid_type_4_addr), COL_MAX_LEN);
421       break;
422     }
423     pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
424     pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
425     break;
426
427   case AT_ATALK:
428     memcpy(&ddp_addr, addr->data, sizeof ddp_addr);
429     strncpy(pinfo->cinfo->col_buf[col], atalk_addr_to_str(&ddp_addr),
430       COL_MAX_LEN);
431     pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
432     pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
433     break;
434
435   case AT_VINES:
436     strncpy(pinfo->cinfo->col_buf[col], vines_addr_to_str(&addr->data[0]),
437       COL_MAX_LEN);
438     pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
439     pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
440     break;
441
442   case AT_OSI:
443     strncpy(pinfo->cinfo->col_buf[col], print_nsap_net(addr->data, addr->len),
444       COL_MAX_LEN);
445     pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
446     pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
447     break;
448
449   default:
450     break;
451   }
452 }
453
454 static void
455 col_set_port(packet_info *pinfo, int col, port_type ptype, guint32 port,
456                 gboolean is_res, gboolean is_src)
457 {
458   pinfo->cinfo->col_expr[col][0] = '\0';
459   pinfo->cinfo->col_expr_val[col][0] = '\0';
460   switch (ptype) {
461
462   case PT_SCTP:
463     if (is_res)
464       strncpy(pinfo->cinfo->col_buf[col], get_sctp_port(port), COL_MAX_LEN);
465     else
466       snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", port);
467     break;
468     
469   case PT_TCP:
470     if (is_res)
471       strncpy(pinfo->cinfo->col_buf[col], get_tcp_port(port), COL_MAX_LEN);
472     else
473       snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", port);
474     if (is_src)
475       strcpy(pinfo->cinfo->col_expr[col], "tcp.srcport");
476     else
477       strcpy(pinfo->cinfo->col_expr[col], "tcp.dstport");
478     snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "%u", port);
479     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
480     break;
481
482   case PT_UDP:
483     if (is_res)
484       strncpy(pinfo->cinfo->col_buf[col], get_udp_port(port), COL_MAX_LEN);
485     else
486       snprintf(pinfo->cinfo->col_buf[col], COL_MAX_LEN, "%u", port);
487     if (is_src)
488       strcpy(pinfo->cinfo->col_expr[col], "udp.srcport");
489     else
490       strcpy(pinfo->cinfo->col_expr[col], "udp.dstport");
491     snprintf(pinfo->cinfo->col_expr_val[col], COL_MAX_LEN, "%u", port);
492     pinfo->cinfo->col_expr_val[col][COL_MAX_LEN - 1] = '\0';
493     break;
494
495   default:
496     break;
497   }
498   pinfo->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
499   pinfo->cinfo->col_data[col] = pinfo->cinfo->col_buf[col];
500 }
501
502 void
503 fill_in_columns(packet_info *pinfo)
504 {
505   int i;
506
507   for (i = 0; i < pinfo->cinfo->num_cols; i++) {
508     switch (pinfo->cinfo->col_fmt[i]) {
509
510     case COL_NUMBER:
511       snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "%u", pinfo->fd->num);
512       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
513       strcpy(pinfo->cinfo->col_expr[i], "frame.number");
514       strcpy(pinfo->cinfo->col_expr_val[i], pinfo->cinfo->col_buf[i]);
515       break;
516
517     case COL_CLS_TIME:
518       col_set_cls_time(pinfo->fd, pinfo->cinfo, i);
519       break;
520
521     case COL_ABS_TIME:
522       col_set_abs_time(pinfo->fd, pinfo->cinfo, i);
523       break;
524
525     case COL_ABS_DATE_TIME:
526       col_set_abs_date_time(pinfo->fd, pinfo->cinfo, i);
527       break;
528
529     case COL_REL_TIME:
530       col_set_rel_time(pinfo->fd, pinfo->cinfo, i);
531       break;
532
533     case COL_DELTA_TIME:
534       col_set_delta_time(pinfo->fd, pinfo->cinfo, i);
535       break;
536
537     case COL_DEF_SRC:
538     case COL_RES_SRC:   /* COL_DEF_SRC is currently just like COL_RES_SRC */
539       col_set_addr(pinfo, i, &pinfo->src, TRUE, TRUE);
540       break;
541
542     case COL_UNRES_SRC:
543       col_set_addr(pinfo, i, &pinfo->src, FALSE, TRUE);
544       break;
545
546     case COL_DEF_DL_SRC:
547     case COL_RES_DL_SRC:
548       col_set_addr(pinfo, i, &pinfo->dl_src, TRUE, TRUE);
549       break;
550
551     case COL_UNRES_DL_SRC:
552       col_set_addr(pinfo, i, &pinfo->dl_src, FALSE, TRUE);
553       break;
554
555     case COL_DEF_NET_SRC:
556     case COL_RES_NET_SRC:
557       col_set_addr(pinfo, i, &pinfo->net_src, TRUE, TRUE);
558       break;
559
560     case COL_UNRES_NET_SRC:
561       col_set_addr(pinfo, i, &pinfo->net_src, FALSE, TRUE);
562       break;
563
564     case COL_DEF_DST:
565     case COL_RES_DST:   /* COL_DEF_DST is currently just like COL_RES_DST */
566       col_set_addr(pinfo, i, &pinfo->dst, TRUE, FALSE);
567       break;
568
569     case COL_UNRES_DST:
570       col_set_addr(pinfo, i, &pinfo->dst, FALSE, FALSE);
571       break;
572
573     case COL_DEF_DL_DST:
574     case COL_RES_DL_DST:
575       col_set_addr(pinfo, i, &pinfo->dl_dst, TRUE, FALSE);
576       break;
577
578     case COL_UNRES_DL_DST:
579       col_set_addr(pinfo, i, &pinfo->dl_dst, FALSE, FALSE);
580       break;
581
582     case COL_DEF_NET_DST:
583     case COL_RES_NET_DST:
584       col_set_addr(pinfo, i, &pinfo->net_dst, TRUE, FALSE);
585       break;
586
587     case COL_UNRES_NET_DST:
588       col_set_addr(pinfo, i, &pinfo->net_dst, FALSE, FALSE);
589       break;
590
591     case COL_DEF_SRC_PORT:
592     case COL_RES_SRC_PORT:      /* COL_DEF_SRC_PORT is currently just like COL_RES_SRC_PORT */
593       col_set_port(pinfo, i, pinfo->ptype, pinfo->srcport, TRUE, TRUE);
594       break;
595
596     case COL_UNRES_SRC_PORT:
597       col_set_port(pinfo, i, pinfo->ptype, pinfo->srcport, FALSE, TRUE);
598       break;
599
600     case COL_DEF_DST_PORT:
601     case COL_RES_DST_PORT:      /* COL_DEF_DST_PORT is currently just like COL_RES_DST_PORT */
602       col_set_port(pinfo, i, pinfo->ptype, pinfo->destport, TRUE, FALSE);
603       break;
604
605     case COL_UNRES_DST_PORT:
606       col_set_port(pinfo, i, pinfo->ptype, pinfo->destport, FALSE, FALSE);
607       break;
608
609     case COL_PROTOCOL:  /* currently done by dissectors */
610     case COL_INFO:      /* currently done by dissectors */
611       break;
612
613     case COL_PACKET_LENGTH:
614       snprintf(pinfo->cinfo->col_buf[i], COL_MAX_LEN, "%u", pinfo->fd->pkt_len);
615       pinfo->cinfo->col_data[i] = pinfo->cinfo->col_buf[i];
616       strcpy(pinfo->cinfo->col_expr[i], "frame.pkt_len");
617       strcpy(pinfo->cinfo->col_expr_val[i], pinfo->cinfo->col_buf[i]);
618       break;
619
620     case NUM_COL_FMTS:  /* keep compiler happy - shouldn't get here */
621       g_assert_not_reached();
622       break;
623     }
624   }
625 }