Custom column updates:
[obnox/wireshark/wip.git] / epan / column.c
1 /* column.c
2  * Routines for handling column preferences
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 <stdio.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <errno.h>
33
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37
38 #include <epan/timestamp.h>
39 #include <epan/prefs.h>
40 #include <epan/nstime.h>
41 #include <epan/dfilter/dfilter.h>
42 #include "cfile.h"
43 #include <epan/column.h>
44 #include <epan/packet.h>
45
46 /* Given a format number (as defined in column_info.h), returns its equivalent
47    string */
48 const gchar *
49 col_format_to_string(gint fmt) {
50   const gchar *slist[] = {
51     "%q",                                       /* 0) COL_8021Q_VLAN_ID */
52     "%Yt",                                      /* 1) COL_ABS_DATE_TIME */
53     "%At",                                      /* 2) COL_ABS_TIME */
54     "%c",                                       /* 3) COL_CIRCUIT_ID */
55     "%Xd",                                      /* 4) COL_DSTIDX */
56     "%Xs",                                      /* 5) COL_SRCIDX */
57     "%V",                                       /* 6) COL_VSAN */
58     "%B",                                       /* 7) COL_CUMULATIVE_BYTES */
59     "%Cus",                                     /* 8) COL_CUSTOM */
60     "%y",                                       /* 9) COL_DCE_CALL */
61     "%z",                                       /* 10) COL_DCE_CTX */
62     "%Tt",                                      /* 11) COL_DELTA_TIME */
63     "%dct",                                     /* 12) COL_DELTA_CONV_TIME */
64     "%Gt",                                      /* 13) COL_DELTA_TIME_DIS */
65     "%rd",                                      /* 14) COL_RES_DST */
66     "%ud",                                      /* 15) COL_UNRES_DST */
67     "%rD",                                      /* 16) COL_RES_DST_PORT */
68     "%uD",                                      /* 17) COL_UNRES_DST_PORT */
69     "%d",                                       /* 18) COL_DEF_DST */
70     "%D",                                       /* 19) COL_DEF_DST_PORT */
71     "%a",                                       /* 20) COL_EXPERT */
72     "%I",                                       /* 21) COL_IF_DIR */
73     "%XO",                                      /* 22) COL_OXID */
74     "%XR",                                      /* 23) COL_RXID */
75     "%C",                                       /* 24) COL_FR_DLCI */
76     "%F",                                       /* 25) COL_FREQ_CHAN */
77     "%l",                                       /* 26) COL_BSSGP_TLLI */
78     "%P",                                       /* 27) COL_HPUX_DEVID */
79     "%H",                                       /* 28) COL_HPUX_SUBSYS */
80     "%hd",                                      /* 29) COL_DEF_DL_DST */
81     "%hs",                                      /* 30) COL_DEF_DL_SRC */
82     "%rhd",                                     /* 31) COL_RES_DL_DST */
83     "%uhd",                                     /* 32) COL_UNRES_DL_DST */
84     "%rhs",                                     /* 33) COL_RES_DL_SRC*/
85     "%uhs",                                     /* 34) COL_UNRES_DL_SRC */
86     "%e",                                       /* 35) COL_RSSI */
87     "%x",                                       /* 36) COL_TX_RATE */
88     "%f",                                       /* 37) COL_DSCP_VALUE */
89     "%i",                                       /* 38) COL_INFO */
90     "%U",                                       /* 39) COL_COS_VALUE */
91     "%rnd",                                     /* 40) COL_RES_NET_DST */
92     "%und",                                     /* 41) COL_UNRES_NET_DST */
93     "%rns",                                     /* 42) COL_RES_NET_SRC */
94     "%uns",                                     /* 43) COL_UNRES_NET_SRC */
95     "%nd",                                      /* 44) COL_DEF_NET_DST */
96     "%ns",                                      /* 45) COL_DEF_NET_SRC */
97     "%m",                                       /* 46) COL_NUMBER */
98     "%L",                                       /* 47) COL_PACKET_LENGTH */
99     "%p",                                       /* 48) COL_PROTOCOL */
100     "%Rt",                                      /* 49) COL_REL_TIME */
101     "%rct",                                     /* 50) COL_REL_CONV_TIME */
102     "%s",                                       /* 51) COL_DEF_SRC */
103     "%S",                                       /* 52) COL_DEF_SRC_PORT */
104     "%rs",                                      /* 53) COL_RES_SRC */
105     "%us",                                      /* 54) COL_UNRES_SRC */
106     "%rS",                                      /* 55) COL_RES_SRC_PORT */
107     "%uS",                                      /* 56) COL_UNRES_SRC_PORT */
108     "%E",                                       /* 57) COL_TEI */
109     "%t"                                        /* 58) COL_CLS_TIME */
110   };
111
112   if (fmt < 0 || fmt >= NUM_COL_FMTS)
113     return NULL;
114
115   return(slist[fmt]);
116 }
117
118 /* Given a format number (as defined in column_info.h), returns its
119   description */
120 static const gchar *dlist[NUM_COL_FMTS] = {
121     "802.1Q VLAN id",                           /* 0) COL_8021Q_VLAN_ID */
122     "Absolute date and time",                   /* 1) COL_ABS_DATE_TIME */
123     "Absolute time",                            /* 2) COL_ABS_TIME */
124     "Circuit ID",                               /* 3) COL_CIRCUIT_ID */
125     "Cisco Dst PortIdx",                        /* 4) COL_DSTIDX */
126     "Cisco Src PortIdx",                        /* 5) COL_SRCIDX */
127     "Cisco VSAN",                               /* 6) COL_VSAN */
128     "Cumulative Bytes" ,                        /* 7) COL_CUMULATIVE_BYTES */
129     "Custom",                                   /* 8) COL_CUSTOM */
130     "DCE/RPC call (cn_call_id / dg_seqnum)",    /* 9) COL_DCE_CALL */
131     "DCE/RPC context ID (cn_ctx_id)",           /* 10) COL_DCE_CTX */
132     "Delta time",                               /* 11) COL_DELTA_TIME */
133     "Delta time (conversation)",                /* 12) COL_DELTA_CONV_TIME */
134     "Delta time displayed",                     /* 13) COL_DELTA_TIME_DIS */
135     "Dest addr (resolved)",                     /* 14) COL_RES_DST */
136     "Dest addr (unresolved)",                   /* 15) COL_UNRES_DST */
137     "Dest port (resolved)",                     /* 16) COL_RES_DST_PORT */
138     "Dest port (unresolved)",                   /* 17) COL_UNRES_DST_PORT */
139     "Destination address",                      /* 18) COL_DEF_DST */
140     "Destination port",                         /* 19) COL_DEF_DST_PORT */
141     "Expert Info Severity",                     /* 20) COL_EXPERT */
142     "FW-1 monitor if/direction",                /* 21) COL_IF_DIR */
143     "Fibre Channel OXID",                       /* 22) COL_OXID */
144     "Fibre Channel RXID",                       /* 23) COL_RXID */
145     "Frame Relay DLCI",                         /* 24) COL_FR_DLCI */
146     "Frequency/Channel",                        /* 25) COL_FREQ_CHAN */
147     "GPRS BSSGP TLLI",                          /* 26) COL_BSSGP_TLLI */
148     "HP-UX Device ID",                          /* 27) COL_HPUX_DEVID */
149     "HP-UX Subsystem",                          /* 28) COL_HPUX_SUBSYS */
150     "Hardware dest addr",                       /* 29) COL_DEF_DL_DST */
151     "Hardware src addr",                        /* 30) COL_DEF_DL_SRC */
152     "Hw dest addr (resolved)",                  /* 31) COL_RES_DL_DST */
153     "Hw dest addr (unresolved)",                /* 32) COL_UNRES_DL_DST */
154     "Hw src addr (resolved)",                   /* 33) COL_RES_DL_SRC*/
155     "Hw src addr (unresolved)",                 /* 34) COL_UNRES_DL_SRC */
156     "IEEE 802.11 RSSI",                         /* 35) COL_RSSI */
157     "IEEE 802.11 TX rate",                      /* 36) COL_TX_RATE */
158     "IP DSCP Value",                            /* 37) COL_DSCP_VALUE */
159     "Information",                              /* 38) COL_INFO */
160     "L2 COS Value (802.1p)",                    /* 39) COL_COS_VALUE */
161     "Net dest addr (resolved)",                 /* 40) COL_RES_NET_DST */
162     "Net dest addr (unresolved)",               /* 41) COL_UNRES_NET_DST */
163     "Net src addr (resolved)",                  /* 42) COL_RES_NET_SRC */
164     "Net src addr (unresolved)",                /* 43) COL_UNRES_NET_SRC */
165     "Network dest addr",                        /* 44) COL_DEF_NET_DST */
166     "Network src addr",                         /* 45) COL_DEF_NET_SRC */
167     "Number",                                   /* 46) COL_NUMBER */
168     "Packet length (bytes)" ,                   /* 47) COL_PACKET_LENGTH */
169     "Protocol",                                 /* 48) COL_PROTOCOL */
170     "Relative time",                            /* 49) COL_REL_TIME */
171     "Relative time (conversation)",             /* 50) COL_REL_CONV_TIME */
172     "Source address",                           /* 51) COL_DEF_SRC */
173     "Source port",                              /* 52) COL_DEF_SRC_PORT */
174     "Src addr (resolved)",                      /* 53) COL_RES_SRC */
175     "Src addr (unresolved)",                    /* 54) COL_UNRES_SRC */
176     "Src port (resolved)",                      /* 55) COL_RES_SRC_PORT */
177     "Src port (unresolved)",                    /* 56) COL_UNRES_SRC_PORT */
178     "TEI",                                      /* 57) COL_TEI */
179     "Time (format as specified)"                /* 58) COL_CLS_TIME */
180 };
181
182 const gchar *
183 col_format_desc(gint fmt) {
184   g_assert((fmt >= 0) && (fmt < NUM_COL_FMTS));
185   return(dlist[fmt]);
186 }
187
188 /* Marks each array element true if it can be substituted for the given
189    column format */
190 void
191 get_column_format_matches(gboolean *fmt_list, gint format) {
192
193   /* Get the obvious: the format itself */
194   if ((format >= 0) && (format < NUM_COL_FMTS))
195     fmt_list[format] = TRUE;
196
197   /* Get any formats lower down on the chain */
198   switch (format) {
199     case COL_DEF_SRC:
200       fmt_list[COL_RES_DL_SRC] = TRUE;
201       fmt_list[COL_RES_NET_SRC] = TRUE;
202       break;
203     case COL_RES_SRC:
204       fmt_list[COL_RES_DL_SRC] = TRUE;
205       fmt_list[COL_RES_NET_SRC] = TRUE;
206       break;
207     case COL_UNRES_SRC:
208       fmt_list[COL_UNRES_DL_SRC] = TRUE;
209       fmt_list[COL_UNRES_NET_SRC] = TRUE;
210       break;
211     case COL_DEF_DST:
212       fmt_list[COL_RES_DL_DST] = TRUE;
213       fmt_list[COL_RES_NET_DST] = TRUE;
214       break;
215     case COL_RES_DST:
216       fmt_list[COL_RES_DL_DST] = TRUE;
217       fmt_list[COL_RES_NET_DST] = TRUE;
218       break;
219     case COL_UNRES_DST:
220       fmt_list[COL_UNRES_DL_DST] = TRUE;
221       fmt_list[COL_UNRES_NET_DST] = TRUE;
222       break;
223     case COL_DEF_DL_SRC:
224       fmt_list[COL_RES_DL_SRC] = TRUE;
225       break;
226     case COL_DEF_DL_DST:
227       fmt_list[COL_RES_DL_DST] = TRUE;
228       break;
229     case COL_DEF_NET_SRC:
230       fmt_list[COL_RES_NET_SRC] = TRUE;
231       break;
232     case COL_DEF_NET_DST:
233       fmt_list[COL_RES_NET_DST] = TRUE;
234       break;
235     case COL_DEF_SRC_PORT:
236       fmt_list[COL_RES_SRC_PORT] = TRUE;
237       break;
238     case COL_DEF_DST_PORT:
239       fmt_list[COL_RES_DST_PORT] = TRUE;
240       break;
241     case COL_OXID:
242       fmt_list[COL_OXID] = TRUE;
243       break;
244     case COL_RXID:
245       fmt_list[COL_RXID] = TRUE;
246       break;
247     case COL_IF_DIR:
248       fmt_list[COL_IF_DIR] = TRUE;
249       break;
250     case COL_CIRCUIT_ID:
251       fmt_list[COL_CIRCUIT_ID] = TRUE;
252       break;
253     case COL_SRCIDX:
254       fmt_list[COL_SRCIDX] = TRUE;
255       break;
256     case COL_DSTIDX:
257       fmt_list[COL_DSTIDX] = TRUE;
258       break;
259     case COL_VSAN:
260       fmt_list[COL_VSAN] = TRUE;
261       break;
262     case COL_TX_RATE:
263       fmt_list[COL_TX_RATE] = TRUE;
264       break;
265     case COL_RSSI:
266       fmt_list[COL_RSSI] = TRUE;
267       break;
268     case COL_HPUX_SUBSYS:
269       fmt_list[COL_HPUX_SUBSYS] = TRUE;
270       break;
271     case COL_HPUX_DEVID:
272       fmt_list[COL_HPUX_DEVID] = TRUE;
273       break;
274     case COL_DCE_CALL:
275       fmt_list[COL_DCE_CALL] = TRUE;
276       break;
277     case COL_DCE_CTX:
278       fmt_list[COL_DCE_CTX] = TRUE;
279       break;
280     case COL_8021Q_VLAN_ID:
281       fmt_list[COL_8021Q_VLAN_ID] = TRUE;
282       break;
283     case COL_DSCP_VALUE:
284       fmt_list[COL_DSCP_VALUE] = TRUE;
285       break;
286     case COL_COS_VALUE:
287       fmt_list[COL_COS_VALUE] = TRUE;
288       break;
289     case COL_TEI:
290       fmt_list[COL_TEI] = TRUE;
291       break;
292     case COL_FR_DLCI:
293       fmt_list[COL_FR_DLCI] = TRUE;
294       break;
295     case COL_BSSGP_TLLI:
296       fmt_list[COL_BSSGP_TLLI] = TRUE;
297       break;
298     case COL_EXPERT:
299       fmt_list[COL_EXPERT] = TRUE;
300       break;
301     case COL_FREQ_CHAN:
302       fmt_list[COL_FREQ_CHAN] = TRUE;
303       break;
304     case COL_CUSTOM:
305       fmt_list[COL_CUSTOM] = TRUE;
306       break;
307     default:
308       break;
309   }
310 }
311
312 /* Returns a string representing the longest possible value for
313    a timestamp column type. */
314 static const char *
315 get_timestamp_column_longest_string(gint type, gint precision)
316 {
317
318         switch(type) {
319         case(TS_ABSOLUTE_WITH_DATE):
320                 switch(precision) {
321                         case(TS_PREC_AUTO_SEC):
322                         case(TS_PREC_FIXED_SEC):
323                                 return "0000-00-00 00:00:00";
324                                 break;
325                         case(TS_PREC_AUTO_DSEC):
326                         case(TS_PREC_FIXED_DSEC):
327                                 return "0000-00-00 00:00:00.0";
328                                 break;
329                         case(TS_PREC_AUTO_CSEC):
330                         case(TS_PREC_FIXED_CSEC):
331                                 return "0000-00-00 00:00:00.00";
332                                 break;
333                         case(TS_PREC_AUTO_MSEC):
334                         case(TS_PREC_FIXED_MSEC):
335                                 return "0000-00-00 00:00:00.000";
336                                 break;
337                         case(TS_PREC_AUTO_USEC):
338                         case(TS_PREC_FIXED_USEC):
339                                 return "0000-00-00 00:00:00.000000";
340                                 break;
341                         case(TS_PREC_AUTO_NSEC):
342                         case(TS_PREC_FIXED_NSEC):
343                                 return "0000-00-00 00:00:00.000000000";
344                                 break;
345                         default:
346                                 g_assert_not_reached();
347                 }
348                         break;
349         case(TS_ABSOLUTE):
350                 switch(precision) {
351                         case(TS_PREC_AUTO_SEC):
352                         case(TS_PREC_FIXED_SEC):
353                                 return "00:00:00";
354                                 break;
355                         case(TS_PREC_AUTO_DSEC):
356                         case(TS_PREC_FIXED_DSEC):
357                                 return "00:00:00.0";
358                                 break;
359                         case(TS_PREC_AUTO_CSEC):
360                         case(TS_PREC_FIXED_CSEC):
361                                 return "00:00:00.00";
362                                 break;
363                         case(TS_PREC_AUTO_MSEC):
364                         case(TS_PREC_FIXED_MSEC):
365                                 return "00:00:00.000";
366                                 break;
367                         case(TS_PREC_AUTO_USEC):
368                         case(TS_PREC_FIXED_USEC):
369                                 return "00:00:00.000000";
370                                 break;
371                         case(TS_PREC_AUTO_NSEC):
372                         case(TS_PREC_FIXED_NSEC):
373                                 return "00:00:00.000000000";
374                                 break;
375                         default:
376                                 g_assert_not_reached();
377                 }
378                 break;
379         case(TS_RELATIVE):      /* fallthrough */
380         case(TS_DELTA):
381         case(TS_DELTA_DIS):
382                 switch(precision) {
383                         case(TS_PREC_AUTO_SEC):
384                         case(TS_PREC_FIXED_SEC):
385                                 return "0000";
386                                 break;
387                         case(TS_PREC_AUTO_DSEC):
388                         case(TS_PREC_FIXED_DSEC):
389                                 return "0000.0";
390                                 break;
391                         case(TS_PREC_AUTO_CSEC):
392                         case(TS_PREC_FIXED_CSEC):
393                                 return "0000.00";
394                                 break;
395                         case(TS_PREC_AUTO_MSEC):
396                         case(TS_PREC_FIXED_MSEC):
397                                 return "0000.000";
398                                 break;
399                         case(TS_PREC_AUTO_USEC):
400                         case(TS_PREC_FIXED_USEC):
401                                 return "0000.000000";
402                                 break;
403                         case(TS_PREC_AUTO_NSEC):
404                         case(TS_PREC_FIXED_NSEC):
405                                 return "0000.000000000";
406                                 break;
407                         default:
408                                 g_assert_not_reached();
409                 }
410                 break;
411         case(TS_EPOCH):
412         /* This is enough to represent 2^63 (signed 64-bit integer) + fractions */
413                 switch(precision) {
414                         case(TS_PREC_AUTO_SEC):
415                         case(TS_PREC_FIXED_SEC):
416                                 return "0000000000000000000";
417                                 break;
418                         case(TS_PREC_AUTO_DSEC):
419                         case(TS_PREC_FIXED_DSEC):
420                                 return "0000000000000000000.0";
421                                 break;
422                         case(TS_PREC_AUTO_CSEC):
423                         case(TS_PREC_FIXED_CSEC):
424                                 return "0000000000000000000.00";
425                                 break;
426                         case(TS_PREC_AUTO_MSEC):
427                         case(TS_PREC_FIXED_MSEC):
428                                 return "0000000000000000000.000";
429                                 break;
430                         case(TS_PREC_AUTO_USEC):
431                         case(TS_PREC_FIXED_USEC):
432                                 return "0000000000000000000.000000";
433                                 break;
434                         case(TS_PREC_AUTO_NSEC):
435                         case(TS_PREC_FIXED_NSEC):
436                                 return "0000000000000000000.000000000";
437                                 break;
438                         default:
439                                 g_assert_not_reached();
440                 }
441                 break;
442         case(TS_NOT_SET):
443                 return "0000.000000";
444                 break;
445         default:
446                 g_assert_not_reached();
447         }
448
449         /* never reached, satisfy compiler */
450         return "";
451 }
452
453 /* Returns the longer string of the column title or the hard-coded width of
454  * its contents for building the packet list layout. */
455 const gchar *
456 get_column_width_string(gint format, gint col)
457 {
458         if(strlen(get_column_longest_string(format)) >
459            strlen(get_column_title(col)))
460                 return get_column_longest_string(format);
461         else
462                 return get_column_title(col);
463 }
464
465 /* Returns a string representing the longest possible value for a
466    particular column type.  See also get_column_width_string() above.
467
468    Except for the COL...SRC and COL...DST columns, these are used
469    only when a capture is being displayed while it's taking place;
470    they are arguably somewhat fragile, as changes to the code that
471    generates them don't cause these widths to change, but that's
472    probably not too big a problem, given that the sizes are
473    recomputed based on the actual data in the columns when the capture
474    is done, and given that the width for COL...SRC and COL...DST columns
475    is somewhat arbitrary in any case.  We should probably clean
476    that up eventually, though. */
477 const char *
478 get_column_longest_string(gint format)
479 {
480   switch (format) {
481     case COL_NUMBER:
482       return "0000000";
483       break;
484     case COL_CLS_TIME:
485       return get_timestamp_column_longest_string(timestamp_get_type(), timestamp_get_precision());
486       break;
487     case COL_ABS_DATE_TIME:
488       return get_timestamp_column_longest_string(TS_ABSOLUTE_WITH_DATE, timestamp_get_precision());
489       break;
490     case COL_ABS_TIME:
491       return get_timestamp_column_longest_string(TS_ABSOLUTE, timestamp_get_precision());
492       break;
493     case COL_REL_TIME:
494       return get_timestamp_column_longest_string(TS_RELATIVE, timestamp_get_precision());
495       break;
496     case COL_DELTA_TIME:
497       return get_timestamp_column_longest_string(TS_DELTA, timestamp_get_precision());
498       break;
499     case COL_DELTA_TIME_DIS:
500       return get_timestamp_column_longest_string(TS_DELTA_DIS, timestamp_get_precision());
501       break;
502     case COL_REL_CONV_TIME:     /* 'abuse' TS_RELATIVE to set the time format */
503     case COL_DELTA_CONV_TIME:   /* for the conversation related time columns */
504       return get_timestamp_column_longest_string(TS_RELATIVE, timestamp_get_precision());
505       break;
506     case COL_DEF_SRC:
507     case COL_RES_SRC:
508     case COL_UNRES_SRC:
509     case COL_DEF_DL_SRC:
510     case COL_RES_DL_SRC:
511     case COL_UNRES_DL_SRC:
512     case COL_DEF_NET_SRC:
513     case COL_RES_NET_SRC:
514     case COL_UNRES_NET_SRC:
515     case COL_DEF_DST:
516     case COL_RES_DST:
517     case COL_UNRES_DST:
518     case COL_DEF_DL_DST:
519     case COL_RES_DL_DST:
520     case COL_UNRES_DL_DST:
521     case COL_DEF_NET_DST:
522     case COL_RES_NET_DST:
523     case COL_UNRES_NET_DST:
524       return "00000000.000000000000"; /* IPX-style */
525       break;
526     case COL_DEF_SRC_PORT:
527     case COL_RES_SRC_PORT:
528     case COL_UNRES_SRC_PORT:
529     case COL_DEF_DST_PORT:
530     case COL_RES_DST_PORT:
531     case COL_UNRES_DST_PORT:
532       return "000000";
533       break;
534     case COL_PROTOCOL:
535       return "Protocol";        /* not the longest, but the longest is too long */
536       break;
537     case COL_PACKET_LENGTH:
538       return "00000";
539       break;
540     case COL_CUMULATIVE_BYTES:
541       return "00000000";
542       break;
543     case COL_RXID:
544     case COL_OXID:
545       return "000000";
546       break;
547     case COL_IF_DIR:
548       return "i 00000000 I";
549       break;
550     case COL_CIRCUIT_ID:
551       return "000000";
552       break;
553     case COL_SRCIDX:
554     case COL_DSTIDX:
555       return "0000000";
556       break;
557     case COL_VSAN:
558      return "000000";
559       break;
560     case COL_TX_RATE:
561       return "108.0";
562       break;
563     case COL_RSSI:
564       return "100";
565       break;
566     case COL_HPUX_SUBSYS:
567       return "OTS9000-TRANSPORT";
568       break;
569     case COL_HPUX_DEVID:
570       return "0000";
571       break;
572     case COL_DCE_CALL:
573       return "0000";
574       break;
575     case COL_DCE_CTX:
576       return "0000";
577       break;
578     case COL_8021Q_VLAN_ID:
579       return "0000";
580       break;
581     case COL_DSCP_VALUE:
582       return "00";
583       break;
584     case COL_COS_VALUE:
585       return "0";
586       break;
587     case COL_TEI:
588       return "127";
589       break;
590     case COL_FR_DLCI:
591       return "8388608";
592       break;
593     case COL_BSSGP_TLLI:
594       return "0xffffffff";
595       break;
596     case COL_EXPERT:
597       return "ERROR";
598       break;
599     case COL_FREQ_CHAN:
600       return "9999 MHz [A 999]";
601       break;
602     case COL_CUSTOM:
603       return "0000000000";      /* not the longest, but the longest is too long */
604       break;
605     default: /* COL_INFO */
606       return "Source port: kerberos-master  Destination port: kerberos-master";
607       break;
608   }
609 }
610
611 /* Returns the longest possible width, in characters, for a particular
612    column type. */
613 gint
614 get_column_char_width(gint format)
615 {
616   return strlen(get_column_longest_string(format));
617 }
618
619 gint
620 get_column_format(gint col) {
621   GList    *clp = g_list_nth(prefs.col_list, col);
622   fmt_data *cfmt;
623
624   cfmt = (fmt_data *) clp->data;
625
626   return(get_column_format_from_str(cfmt->fmt));
627 }
628
629 gint
630 get_column_format_from_str(gchar *str) {
631   gint i;
632
633   for (i = 0; i < NUM_COL_FMTS; i++) {
634     if (strcmp(str, col_format_to_string(i)) == 0)
635       return i;
636   }
637   return -1;    /* illegal */
638 }
639
640 gchar *
641 get_column_title(gint col) {
642   GList    *clp = g_list_nth(prefs.col_list, col);
643   fmt_data *cfmt;
644
645   cfmt = (fmt_data *) clp->data;
646
647   return(cfmt->title);
648 }
649
650 gchar *
651 get_column_custom_field(gint col) {
652   GList    *clp = g_list_nth(prefs.col_list, col);
653   fmt_data *cfmt;
654
655   cfmt = (fmt_data *) clp->data;
656
657   return(cfmt->custom_field);
658 }
659
660 void
661 build_column_format_array(capture_file *cfile, gboolean reset_fences)
662 {
663   int i, j;
664
665   col_setup(&cfile->cinfo, prefs.num_cols);
666
667   for (i = 0; i < cfile->cinfo.num_cols; i++) {
668     cfile->cinfo.col_fmt[i] = get_column_format(i);
669     cfile->cinfo.col_title[i] = g_strdup(get_column_title(i));
670     if (cfile->cinfo.col_fmt[i] == COL_CUSTOM) {
671       cfile->cinfo.col_custom_field[i] = g_strdup(get_column_custom_field(i));
672     } else {
673       cfile->cinfo.col_custom_field[i] = NULL;
674     }
675     cfile->cinfo.fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) *
676                                                      NUM_COL_FMTS);
677     get_column_format_matches(cfile->cinfo.fmt_matx[i],
678                               cfile->cinfo.col_fmt[i]);
679     cfile->cinfo.col_data[i] = NULL;
680
681     if (cfile->cinfo.col_fmt[i] == COL_INFO)
682       cfile->cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) *
683                                                   COL_MAX_INFO_LEN);
684     else
685       cfile->cinfo.col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
686
687     if(reset_fences)
688       cfile->cinfo.col_fence[i] = 0;
689
690     cfile->cinfo.col_expr.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) *
691                                                             COL_MAX_LEN);
692     cfile->cinfo.col_expr.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) *
693                                                                 COL_MAX_LEN);
694   }
695
696   for (i = 0; i < cfile->cinfo.num_cols; i++) {
697     for (j = 0; j < NUM_COL_FMTS; j++) {
698       if (!cfile->cinfo.fmt_matx[i][j])
699               continue;
700
701       if (cfile->cinfo.col_first[j] == -1)
702         cfile->cinfo.col_first[j] = i;
703
704       cfile->cinfo.col_last[j] = i;
705     }
706   }
707 }