2 * Routines for handling column preferences
4 * $Id: column.c,v 1.27 2000/01/10 01:43:47 guy Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@zing.org>
8 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #ifdef HAVE_SYS_TYPES_H
31 #include <sys/types.h>
44 #include "timestamp.h"
49 /* Given a format number (as defined in packet.h), returns its equivalent
52 col_format_to_string(gint fmt) {
53 gchar *slist[] = { "%m", "%t", "%Rt", "%At", "%Tt", "%s", "%rs", "%us",
54 "%hs", "%rhs", "%uhs", "%ns", "%rns", "%uns", "%d",
55 "%rd", "%ud", "%hd", "%rhd", "%uhd", "%nd", "%rnd",
56 "%und", "%S", "%rS", "%uS", "%D", "%rD", "%uD", "%p",
59 if (fmt < 0 || fmt > NUM_COL_FMTS)
65 /* Given a format number (as defined in packet.h), returns its
68 col_format_desc(gint fmt) {
69 gchar *dlist[] = { "Number", "Time (command line specified)",
70 "Relative time", "Absolute time", "Delta time",
71 "Source address", "Src addr (resolved)",
72 "Src addr (unresolved)", "Hardware src addr",
73 "Hw src addr (resolved)", "Hw src addr (unresolved)",
74 "Network src addr", "Net src addr (resolved)",
75 "Net src addr (unresolved)", "Destination address",
76 "Dest addr (resolved)", "Dest addr (unresolved)",
77 "Hardware dest addr", "Hw dest addr (resolved)",
78 "Hw dest addr (unresolved)", "Network dest addr",
79 "Net dest addr (resolved)", "Net dest addr (unresolved)",
80 "Source port", "Src port (resolved)",
81 "Src port (unresolved)", "Destination port",
82 "Dest port (resolved)", "Dest port (unresolved)",
83 "Protocol", "Information", "Packet length (bytes)" };
85 if (fmt < 0 || fmt > NUM_COL_FMTS)
91 /* Marks each array element true if it can be substituted for the given
94 get_column_format_matches(gboolean *fmt_list, gint format) {
97 for (i = 0; i < NUM_COL_FMTS; i++) {
98 /* Get the obvious: the format itself */
101 /* Get any formats lower down on the chain */
104 fmt_list[COL_RES_DL_SRC] = TRUE;
105 fmt_list[COL_RES_NET_SRC] = TRUE;
108 fmt_list[COL_RES_DL_SRC] = TRUE;
109 fmt_list[COL_RES_NET_SRC] = TRUE;
112 fmt_list[COL_UNRES_DL_SRC] = TRUE;
113 fmt_list[COL_UNRES_NET_SRC] = TRUE;
116 fmt_list[COL_RES_DL_DST] = TRUE;
117 fmt_list[COL_RES_NET_DST] = TRUE;
120 fmt_list[COL_RES_DL_DST] = TRUE;
121 fmt_list[COL_RES_NET_DST] = TRUE;
124 fmt_list[COL_UNRES_DL_DST] = TRUE;
125 fmt_list[COL_UNRES_NET_DST] = TRUE;
128 fmt_list[COL_RES_DL_SRC] = TRUE;
131 fmt_list[COL_RES_DL_DST] = TRUE;
133 case COL_DEF_NET_SRC:
134 fmt_list[COL_RES_NET_SRC] = TRUE;
136 case COL_DEF_NET_DST:
137 fmt_list[COL_RES_NET_DST] = TRUE;
139 case COL_DEF_SRC_PORT:
140 fmt_list[COL_RES_SRC_PORT] = TRUE;
142 case COL_DEF_DST_PORT:
143 fmt_list[COL_RES_DST_PORT] = TRUE;
151 /* Returns a string representing the longest possible value for a
152 particular column type.
154 Except for the COL...SRC and COL...DST columns, these are used
155 only when a capture is being displayed while it's taking place;
156 they are arguably somewhat fragile, as changes to the code that
157 generates them don't cause these widths to change, but that's
158 probably not too big a problem, given that the sizes are
159 recomputed based on the actual data in the columns when the capture
160 is done, and given that the width for COL...SRC and COL...DST columns
161 is somewhat arbitrary in any case. We should probably clean
162 that up eventually, though. */
164 get_column_longest_string(gint format)
171 if (timestamp_type == ABSOLUTE)
172 return "00:00:00.000000";
174 return "0000.000000";
177 return "00:00:00.000000";
181 return "0000.000000";
188 case COL_UNRES_DL_SRC:
189 case COL_DEF_NET_SRC:
190 case COL_RES_NET_SRC:
191 case COL_UNRES_NET_SRC:
197 case COL_UNRES_DL_DST:
198 case COL_DEF_NET_DST:
199 case COL_RES_NET_DST:
200 case COL_UNRES_NET_DST:
201 return "00000000.000000000000"; /* IPX-style */
203 case COL_DEF_SRC_PORT:
204 case COL_RES_SRC_PORT:
205 case COL_UNRES_SRC_PORT:
206 case COL_DEF_DST_PORT:
207 case COL_RES_DST_PORT:
208 case COL_UNRES_DST_PORT:
212 return "NetBIOS"; /* not the longest, but the longest is too long */
214 case COL_PACKET_LENGTH:
217 default: /* COL_INFO */
218 return "Source port: kerberos-master Destination port: kerberos-master";
223 /* Returns the longest possible width, in characters, for a particular
226 get_column_char_width(gint format)
228 return strlen(get_column_longest_string(format));
232 get_column_resize_type(gint format) {
239 case COL_DEF_SRC_PORT:
240 case COL_RES_SRC_PORT:
241 case COL_UNRES_SRC_PORT:
242 case COL_DEF_DST_PORT:
243 case COL_RES_DST_PORT:
244 case COL_UNRES_DST_PORT:
246 case COL_PACKET_LENGTH:
247 /* We don't want these to resize during a live capture, as that
248 gets in the way of trying to look at the data while it's being
250 return (RESIZE_AUTO);
257 case COL_UNRES_DL_SRC:
258 case COL_DEF_NET_SRC:
259 case COL_RES_NET_SRC:
260 case COL_UNRES_NET_SRC:
266 case COL_UNRES_DL_DST:
267 case COL_DEF_NET_DST:
268 case COL_RES_NET_DST:
269 case COL_UNRES_NET_DST:
270 /* We don't want these to resize dynamically; if they get resolved
271 to names, those names could be very long, and auto-resizing
272 columns showing those names may leave too little room for
273 other columns such as the "Info" column. */
274 return (RESIZE_MANUAL);
276 default: /* COL_INFO */
277 /* We want this to resize dynamically, even during a live capture,
278 because otherewise you won't be able to see all that's in
280 return (RESIZE_LIVE);
299 get_column_format(gint col) {
300 GList *clp = g_list_nth(prefs.col_list, col);
303 cfmt = (fmt_data *) clp->data;
305 return(get_column_format_from_str(cfmt->fmt));
309 get_column_format_from_str(gchar *str) {
311 gint res_off = RES_DEF, addr_off = ADDR_DEF, time_off = TIME_DEF;
313 /* To do: Make this parse %-formatted strings "for real" */
314 while (*cptr != '\0') {
316 case 't': /* To do: fix for absolute and delta */
317 return COL_CLS_TIME + time_off;
323 return COL_DEF_SRC + res_off + addr_off;
326 return COL_DEF_DST + res_off + addr_off;
329 return COL_DEF_SRC_PORT + res_off;
332 return COL_DEF_DST_PORT + res_off;
362 return COL_PACKET_LENGTH;
371 get_column_title(gint col) {
372 GList *clp = g_list_nth(prefs.col_list, col);
375 cfmt = (fmt_data *) clp->data;
380 #define MAX_FMT_PREF_LEN 1024
381 #define MAX_FMT_PREF_LINE_LEN 60
383 col_format_to_pref_str() {
384 static gchar pref_str[MAX_FMT_PREF_LEN] = "";
385 GList *clp = g_list_first(prefs.col_list);
387 int cur_pos = 0, cur_len = 0, fmt_len;
390 cfmt = (fmt_data *) clp->data;
392 fmt_len = strlen(cfmt->title) + 4;
393 if ((fmt_len + cur_len) < (MAX_FMT_PREF_LEN - 1)) {
394 if ((fmt_len + cur_pos) > MAX_FMT_PREF_LINE_LEN) {
397 pref_str[cur_len] = '\n'; cur_len++;
398 pref_str[cur_len] = '\t'; cur_len++;
400 sprintf(&pref_str[cur_len], "\"%s\", ", cfmt->title);
405 fmt_len = strlen(cfmt->fmt) + 4;
406 if ((fmt_len + cur_len) < (MAX_FMT_PREF_LEN - 1)) {
407 if ((fmt_len + cur_pos) > MAX_FMT_PREF_LINE_LEN) {
410 pref_str[cur_len] = '\n'; cur_len++;
411 pref_str[cur_len] = '\t'; cur_len++;
413 sprintf(&pref_str[cur_len], "\"%s\", ", cfmt->fmt);
422 pref_str[cur_len - 2] = '\0';