2 * Routines for handling column preferences
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
36 #include <epan/timestamp.h>
37 #include <epan/prefs.h>
38 #include <epan/dfilter/dfilter.h>
39 #include <epan/column.h>
40 #include <epan/packet.h>
42 /* Given a format number (as defined in column_info.h), returns its equivalent
45 col_format_to_string(const gint fmt) {
46 static const gchar *const slist[NUM_COL_FMTS] = {
47 "%q", /* 0) COL_8021Q_VLAN_ID */
48 "%Yt", /* 1) COL_ABS_DATE_TIME */
49 "%At", /* 2) COL_ABS_TIME */
50 "%c", /* 3) COL_CIRCUIT_ID */
51 "%Xd", /* 4) COL_DSTIDX */
52 "%Xs", /* 5) COL_SRCIDX */
53 "%V", /* 6) COL_VSAN */
54 "%B", /* 7) COL_CUMULATIVE_BYTES */
55 "%Cus", /* 8) COL_CUSTOM */
56 "%y", /* 9) COL_DCE_CALL */
57 "%z", /* 10) COL_DCE_CTX */
58 "%Tt", /* 11) COL_DELTA_TIME */
59 "%dct", /* 12) COL_DELTA_CONV_TIME */
60 "%Gt", /* 13) COL_DELTA_TIME_DIS */
61 "%rd", /* 14) COL_RES_DST */
62 "%ud", /* 15) COL_UNRES_DST */
63 "%rD", /* 16) COL_RES_DST_PORT */
64 "%uD", /* 17) COL_UNRES_DST_PORT */
65 "%d", /* 18) COL_DEF_DST */
66 "%D", /* 19) COL_DEF_DST_PORT */
67 "%a", /* 20) COL_EXPERT */
68 "%I", /* 21) COL_IF_DIR */
69 "%XO", /* 22) COL_OXID */
70 "%XR", /* 23) COL_RXID */
71 "%C", /* 24) !! DEPRECATED !! - COL_FR_DLCI */
72 "%F", /* 25) COL_FREQ_CHAN */
73 "%l", /* 26) !! DEPRECATED !! - COL_BSSGP_TLLI */
74 "%P", /* 27) !! DEPRECATED !! - COL_HPUX_DEVID */
75 "%H", /* 28) !! DEPRECATED !! - COL_HPUX_SUBSYS */
76 "%hd", /* 29) COL_DEF_DL_DST */
77 "%hs", /* 30) COL_DEF_DL_SRC */
78 "%rhd", /* 31) COL_RES_DL_DST */
79 "%uhd", /* 32) COL_UNRES_DL_DST */
80 "%rhs", /* 33) COL_RES_DL_SRC*/
81 "%uhs", /* 34) COL_UNRES_DL_SRC */
82 "%e", /* 35) COL_RSSI */
83 "%x", /* 36) COL_TX_RATE */
84 "%f", /* 37) COL_DSCP_VALUE */
85 "%i", /* 38) COL_INFO */
86 "%U", /* 39) !! DEPRECATED !! - COL_COS_VALUE */
87 "%rnd", /* 40) COL_RES_NET_DST */
88 "%und", /* 41) COL_UNRES_NET_DST */
89 "%rns", /* 42) COL_RES_NET_SRC */
90 "%uns", /* 43) COL_UNRES_NET_SRC */
91 "%nd", /* 44) COL_DEF_NET_DST */
92 "%ns", /* 45) COL_DEF_NET_SRC */
93 "%m", /* 46) COL_NUMBER */
94 "%L", /* 47) COL_PACKET_LENGTH */
95 "%p", /* 48) COL_PROTOCOL */
96 "%Rt", /* 49) COL_REL_TIME */
97 "%rct", /* 50) !! DEPRECATED !! - COL_REL_CONV_TIME */
98 "%s", /* 51) COL_DEF_SRC */
99 "%S", /* 52) COL_DEF_SRC_PORT */
100 "%rs", /* 53) COL_RES_SRC */
101 "%us", /* 54) COL_UNRES_SRC */
102 "%rS", /* 55) COL_RES_SRC_PORT */
103 "%uS", /* 56) COL_UNRES_SRC_PORT */
104 "%E", /* 57) COL_TEI */
105 "%Yut", /* 58) COL_UTC_DATE_TIME */
106 "%Aut", /* 59) COL_UTC_TIME */
107 "%t" /* 60) COL_CLS_TIME */
110 if (fmt < 0 || fmt >= NUM_COL_FMTS)
116 /* Given a format number (as defined in column_info.h), returns its
119 col_format_desc(const gint fmt) {
120 static const gchar *const 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) !! DEPRECATED !! - COL_FR_DLCI */
146 "Frequency/Channel", /* 25) COL_FREQ_CHAN */
147 "GPRS BSSGP TLLI", /* 26) !! DEPRECATED !! - COL_BSSGP_TLLI */
148 "HP-UX Device ID", /* 27) !! DEPRECATED !! - COL_HPUX_DEVID */
149 "HP-UX Subsystem", /* 28) !! DEPRECATED !! - 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) !! DEPRECATED !! - 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) !! DEPRECATED !! - 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 "UTC date and time", /* 58) COL_UTC_DATE_TIME */
180 "UTC time", /* 59) COL_UTC_TIME */
181 "Time (format as specified)" /* 60) COL_CLS_TIME */
184 g_assert((fmt >= 0) && (fmt < NUM_COL_FMTS));
188 /* Marks each array element true if it can be substituted for the given
191 get_column_format_matches(gboolean *fmt_list, const gint format) {
193 /* Get the obvious: the format itself */
194 if ((format >= 0) && (format < NUM_COL_FMTS))
195 fmt_list[format] = TRUE;
197 /* Get any formats lower down on the chain */
200 fmt_list[COL_RES_DL_SRC] = TRUE;
201 fmt_list[COL_RES_NET_SRC] = TRUE;
204 fmt_list[COL_RES_DL_SRC] = TRUE;
205 fmt_list[COL_RES_NET_SRC] = TRUE;
208 fmt_list[COL_UNRES_DL_SRC] = TRUE;
209 fmt_list[COL_UNRES_NET_SRC] = TRUE;
212 fmt_list[COL_RES_DL_DST] = TRUE;
213 fmt_list[COL_RES_NET_DST] = TRUE;
216 fmt_list[COL_RES_DL_DST] = TRUE;
217 fmt_list[COL_RES_NET_DST] = TRUE;
220 fmt_list[COL_UNRES_DL_DST] = TRUE;
221 fmt_list[COL_UNRES_NET_DST] = TRUE;
224 fmt_list[COL_RES_DL_SRC] = TRUE;
227 fmt_list[COL_RES_DL_DST] = TRUE;
229 case COL_DEF_NET_SRC:
230 fmt_list[COL_RES_NET_SRC] = TRUE;
232 case COL_DEF_NET_DST:
233 fmt_list[COL_RES_NET_DST] = TRUE;
235 case COL_DEF_SRC_PORT:
236 fmt_list[COL_RES_SRC_PORT] = TRUE;
238 case COL_DEF_DST_PORT:
239 fmt_list[COL_RES_DST_PORT] = TRUE;
246 /* Returns a string representing the longest possible value for
247 a timestamp column type. */
249 get_timestamp_column_longest_string(const gint type, const gint precision)
253 case(TS_ABSOLUTE_WITH_DATE):
254 case(TS_UTC_WITH_DATE):
256 case(TS_PREC_AUTO_SEC):
257 case(TS_PREC_FIXED_SEC):
258 return "0000-00-00 00:00:00";
260 case(TS_PREC_AUTO_DSEC):
261 case(TS_PREC_FIXED_DSEC):
262 return "0000-00-00 00:00:00.0";
264 case(TS_PREC_AUTO_CSEC):
265 case(TS_PREC_FIXED_CSEC):
266 return "0000-00-00 00:00:00.00";
268 case(TS_PREC_AUTO_MSEC):
269 case(TS_PREC_FIXED_MSEC):
270 return "0000-00-00 00:00:00.000";
272 case(TS_PREC_AUTO_USEC):
273 case(TS_PREC_FIXED_USEC):
274 return "0000-00-00 00:00:00.000000";
276 case(TS_PREC_AUTO_NSEC):
277 case(TS_PREC_FIXED_NSEC):
278 return "0000-00-00 00:00:00.000000000";
281 g_assert_not_reached();
287 case(TS_PREC_AUTO_SEC):
288 case(TS_PREC_FIXED_SEC):
291 case(TS_PREC_AUTO_DSEC):
292 case(TS_PREC_FIXED_DSEC):
295 case(TS_PREC_AUTO_CSEC):
296 case(TS_PREC_FIXED_CSEC):
297 return "00:00:00.00";
299 case(TS_PREC_AUTO_MSEC):
300 case(TS_PREC_FIXED_MSEC):
301 return "00:00:00.000";
303 case(TS_PREC_AUTO_USEC):
304 case(TS_PREC_FIXED_USEC):
305 return "00:00:00.000000";
307 case(TS_PREC_AUTO_NSEC):
308 case(TS_PREC_FIXED_NSEC):
309 return "00:00:00.000000000";
312 g_assert_not_reached();
315 case(TS_RELATIVE): /* fallthrough */
319 case(TS_PREC_AUTO_SEC):
320 case(TS_PREC_FIXED_SEC):
323 case(TS_PREC_AUTO_DSEC):
324 case(TS_PREC_FIXED_DSEC):
327 case(TS_PREC_AUTO_CSEC):
328 case(TS_PREC_FIXED_CSEC):
331 case(TS_PREC_AUTO_MSEC):
332 case(TS_PREC_FIXED_MSEC):
335 case(TS_PREC_AUTO_USEC):
336 case(TS_PREC_FIXED_USEC):
337 return "0000.000000";
339 case(TS_PREC_AUTO_NSEC):
340 case(TS_PREC_FIXED_NSEC):
341 return "0000.000000000";
344 g_assert_not_reached();
348 /* This is enough to represent 2^63 (signed 64-bit integer) + fractions */
350 case(TS_PREC_AUTO_SEC):
351 case(TS_PREC_FIXED_SEC):
352 return "0000000000000000000";
354 case(TS_PREC_AUTO_DSEC):
355 case(TS_PREC_FIXED_DSEC):
356 return "0000000000000000000.0";
358 case(TS_PREC_AUTO_CSEC):
359 case(TS_PREC_FIXED_CSEC):
360 return "0000000000000000000.00";
362 case(TS_PREC_AUTO_MSEC):
363 case(TS_PREC_FIXED_MSEC):
364 return "0000000000000000000.000";
366 case(TS_PREC_AUTO_USEC):
367 case(TS_PREC_FIXED_USEC):
368 return "0000000000000000000.000000";
370 case(TS_PREC_AUTO_NSEC):
371 case(TS_PREC_FIXED_NSEC):
372 return "0000000000000000000.000000000";
375 g_assert_not_reached();
379 return "0000.000000";
382 g_assert_not_reached();
385 /* never reached, satisfy compiler */
389 /* Returns the longer string of the column title or the hard-coded width of
390 * its contents for building the packet list layout. */
392 get_column_width_string(const gint format, const gint col)
394 if(strlen(get_column_longest_string(format)) >
395 strlen(get_column_title(col)))
396 return get_column_longest_string(format);
398 return get_column_title(col);
401 /* Returns a string representing the longest possible value for a
402 particular column type. See also get_column_width_string() above.
404 Except for the COL...SRC and COL...DST columns, these are used
405 only when a capture is being displayed while it's taking place;
406 they are arguably somewhat fragile, as changes to the code that
407 generates them don't cause these widths to change, but that's
408 probably not too big a problem, given that the sizes are
409 recomputed based on the actual data in the columns when the capture
410 is done, and given that the width for COL...SRC and COL...DST columns
411 is somewhat arbitrary in any case. We should probably clean
412 that up eventually, though. */
414 get_column_longest_string(const gint format)
421 return get_timestamp_column_longest_string(timestamp_get_type(), timestamp_get_precision());
423 case COL_ABS_DATE_TIME:
424 return get_timestamp_column_longest_string(TS_ABSOLUTE_WITH_DATE, timestamp_get_precision());
426 case COL_UTC_DATE_TIME:
427 return get_timestamp_column_longest_string(TS_UTC_WITH_DATE, timestamp_get_precision());
430 return get_timestamp_column_longest_string(TS_ABSOLUTE, timestamp_get_precision());
433 return get_timestamp_column_longest_string(TS_UTC, timestamp_get_precision());
436 return get_timestamp_column_longest_string(TS_RELATIVE, timestamp_get_precision());
439 return get_timestamp_column_longest_string(TS_DELTA, timestamp_get_precision());
441 case COL_DELTA_TIME_DIS:
442 return get_timestamp_column_longest_string(TS_DELTA_DIS, timestamp_get_precision());
444 case COL_REL_CONV_TIME: /* 'abuse' TS_RELATIVE to set the time format */
445 case COL_DELTA_CONV_TIME: /* for the conversation related time columns */
446 return get_timestamp_column_longest_string(TS_RELATIVE, timestamp_get_precision());
453 case COL_UNRES_DL_SRC:
454 case COL_DEF_NET_SRC:
455 case COL_RES_NET_SRC:
456 case COL_UNRES_NET_SRC:
462 case COL_UNRES_DL_DST:
463 case COL_DEF_NET_DST:
464 case COL_RES_NET_DST:
465 case COL_UNRES_NET_DST:
466 return "00000000.000000000000"; /* IPX-style */
468 case COL_DEF_SRC_PORT:
469 case COL_RES_SRC_PORT:
470 case COL_UNRES_SRC_PORT:
471 case COL_DEF_DST_PORT:
472 case COL_RES_DST_PORT:
473 case COL_UNRES_DST_PORT:
477 return "Protocol"; /* not the longest, but the longest is too long */
479 case COL_PACKET_LENGTH:
482 case COL_CUMULATIVE_BYTES:
490 return "i 00000000 I";
508 case COL_HPUX_SUBSYS:
509 return "OTS9000-TRANSPORT";
520 case COL_8021Q_VLAN_ID:
542 return "9999 MHz [A 999]";
545 return "0000000000"; /* not the longest, but the longest is too long */
547 default: /* COL_INFO */
548 return "Source port: kerberos-master Destination port: kerberos-master";
553 /* Returns the longest possible width, in characters, for a particular
556 get_column_char_width(const gint format)
558 return (gint)strlen(get_column_longest_string(format));
562 get_column_format(const gint col)
564 GList *clp = g_list_nth(prefs.col_list, col);
567 if (!clp) /* Invalid column requested */
570 cfmt = (fmt_data *) clp->data;
576 set_column_format(const gint col, const gint fmt)
578 GList *clp = g_list_nth(prefs.col_list, col);
581 if (!clp) /* Invalid column requested */
584 cfmt = (fmt_data *) clp->data;
590 get_column_format_from_str(const gchar *str)
594 for (i = 0; i < NUM_COL_FMTS; i++) {
595 if (strcmp(str, col_format_to_string(i)) == 0)
598 return -1; /* illegal */
602 get_column_title(const gint col)
604 GList *clp = g_list_nth(prefs.col_list, col);
607 if (!clp) /* Invalid column requested */
610 cfmt = (fmt_data *) clp->data;
616 set_column_title(const gint col, const gchar *title)
618 GList *clp = g_list_nth(prefs.col_list, col);
621 if (!clp) /* Invalid column requested */
624 cfmt = (fmt_data *) clp->data;
626 g_free (cfmt->title);
627 cfmt->title = g_strdup (title);
631 get_column_visible(const gint col)
633 GList *clp = g_list_nth(prefs.col_list, col);
636 if (!clp) /* Invalid column requested */
639 cfmt = (fmt_data *) clp->data;
641 return(cfmt->visible);
645 set_column_visible(const gint col, gboolean visible)
647 GList *clp = g_list_nth(prefs.col_list, col);
650 if (!clp) /* Invalid column requested */
653 cfmt = (fmt_data *) clp->data;
655 cfmt->visible = visible;
659 get_column_resolved(const gint col)
661 GList *clp = g_list_nth(prefs.col_list, col);
664 if (!clp) /* Invalid column requested */
667 cfmt = (fmt_data *) clp->data;
669 return(cfmt->resolved);
673 set_column_resolved(const gint col, gboolean resolved)
675 GList *clp = g_list_nth(prefs.col_list, col);
678 if (!clp) /* Invalid column requested */
681 cfmt = (fmt_data *) clp->data;
683 cfmt->resolved = resolved;
687 get_column_custom_field(const gint col)
689 GList *clp = g_list_nth(prefs.col_list, col);
692 if (!clp) /* Invalid column requested */
695 cfmt = (fmt_data *) clp->data;
697 return(cfmt->custom_field);
701 set_column_custom_field(const gint col, const char *custom_field)
703 GList *clp = g_list_nth(prefs.col_list, col);
706 if (!clp) /* Invalid column requested */
709 cfmt = (fmt_data *) clp->data;
711 g_free (cfmt->custom_field);
712 cfmt->custom_field = g_strdup (custom_field);
716 get_column_custom_occurrence(const gint col)
718 GList *clp = g_list_nth(prefs.col_list, col);
721 if (!clp) /* Invalid column requested */
724 cfmt = (fmt_data *) clp->data;
726 return(cfmt->custom_occurrence);
730 set_column_custom_occurrence(const gint col, const gint custom_occurrence)
732 GList *clp = g_list_nth(prefs.col_list, col);
735 if (!clp) /* Invalid column requested */
738 cfmt = (fmt_data *) clp->data;
740 cfmt->custom_occurrence = custom_occurrence;
744 build_column_format_array(column_info *cinfo, const gint num_cols, const gboolean reset_fences)
748 /* Build the column format array */
749 col_setup(cinfo, num_cols);
751 for (i = 0; i < cinfo->num_cols; i++) {
752 cinfo->col_fmt[i] = get_column_format(i);
753 cinfo->col_title[i] = g_strdup(get_column_title(i));
755 if (cinfo->col_fmt[i] == COL_CUSTOM) {
756 cinfo->col_custom_field[i] = g_strdup(get_column_custom_field(i));
757 cinfo->col_custom_occurrence[i] = get_column_custom_occurrence(i);
758 if(!dfilter_compile(cinfo->col_custom_field[i], &cinfo->col_custom_dfilter[i])) {
759 /* XXX: Should we issue a warning? */
760 g_free(cinfo->col_custom_field[i]);
761 cinfo->col_custom_field[i] = NULL;
762 cinfo->col_custom_occurrence[i] = 0;
763 cinfo->col_custom_dfilter[i] = NULL;
766 cinfo->col_custom_field[i] = NULL;
767 cinfo->col_custom_occurrence[i] = 0;
768 cinfo->col_custom_dfilter[i] = NULL;
771 cinfo->fmt_matx[i] = (gboolean *) g_malloc0(sizeof(gboolean) * NUM_COL_FMTS);
772 get_column_format_matches(cinfo->fmt_matx[i], cinfo->col_fmt[i]);
773 cinfo->col_data[i] = NULL;
775 if (cinfo->col_fmt[i] == COL_INFO)
776 cinfo->col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_INFO_LEN);
778 cinfo->col_buf[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
781 cinfo->col_fence[i] = 0;
783 cinfo->col_expr.col_expr[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
784 cinfo->col_expr.col_expr_val[i] = (gchar *) g_malloc(sizeof(gchar) * COL_MAX_LEN);
787 cinfo->col_expr.col_expr[i] = NULL;
788 cinfo->col_expr.col_expr_val[i] = NULL;
790 for (i = 0; i < cinfo->num_cols; i++) {
793 for (j = 0; j < NUM_COL_FMTS; j++) {
794 if (!cinfo->fmt_matx[i][j])
797 if (cinfo->col_first[j] == -1)
798 cinfo->col_first[j] = i;
800 cinfo->col_last[j] = i;