2 * Routines for handling column preferences
4 * $Id: column.c,v 1.30 2000/11/17 21:00:35 gram 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>
43 #ifdef HAVE_SYS_STAT_H
47 #include "timestamp.h"
52 /* Given a format number (as defined in packet.h), returns its equivalent
55 col_format_to_string(gint fmt) {
56 gchar *slist[] = { "%m", "%t", "%Rt", "%At", "%Yt", "%Tt", "%s", "%rs",
57 "%us","%hs", "%rhs", "%uhs", "%ns", "%rns", "%uns", "%d",
58 "%rd", "%ud", "%hd", "%rhd", "%uhd", "%nd", "%rnd",
59 "%und", "%S", "%rS", "%uS", "%D", "%rD", "%uD", "%p",
62 if (fmt < 0 || fmt > NUM_COL_FMTS)
68 /* Given a format number (as defined in packet.h), returns its
71 col_format_desc(gint fmt) {
72 gchar *dlist[] = { "Number", "Time (command line specified)",
73 "Relative time", "Absolute time",
74 "Absolute date and time", "Delta time",
75 "Source address", "Src addr (resolved)",
76 "Src addr (unresolved)", "Hardware src addr",
77 "Hw src addr (resolved)", "Hw src addr (unresolved)",
78 "Network src addr", "Net src addr (resolved)",
79 "Net src addr (unresolved)", "Destination address",
80 "Dest addr (resolved)", "Dest addr (unresolved)",
81 "Hardware dest addr", "Hw dest addr (resolved)",
82 "Hw dest addr (unresolved)", "Network dest addr",
83 "Net dest addr (resolved)", "Net dest addr (unresolved)",
84 "Source port", "Src port (resolved)",
85 "Src port (unresolved)", "Destination port",
86 "Dest port (resolved)", "Dest port (unresolved)",
87 "Protocol", "Information", "Packet length (bytes)" };
89 if (fmt < 0 || fmt > NUM_COL_FMTS)
95 /* Marks each array element true if it can be substituted for the given
98 get_column_format_matches(gboolean *fmt_list, gint format) {
101 for (i = 0; i < NUM_COL_FMTS; i++) {
102 /* Get the obvious: the format itself */
105 /* Get any formats lower down on the chain */
108 fmt_list[COL_RES_DL_SRC] = TRUE;
109 fmt_list[COL_RES_NET_SRC] = TRUE;
112 fmt_list[COL_RES_DL_SRC] = TRUE;
113 fmt_list[COL_RES_NET_SRC] = TRUE;
116 fmt_list[COL_UNRES_DL_SRC] = TRUE;
117 fmt_list[COL_UNRES_NET_SRC] = TRUE;
120 fmt_list[COL_RES_DL_DST] = TRUE;
121 fmt_list[COL_RES_NET_DST] = TRUE;
124 fmt_list[COL_RES_DL_DST] = TRUE;
125 fmt_list[COL_RES_NET_DST] = TRUE;
128 fmt_list[COL_UNRES_DL_DST] = TRUE;
129 fmt_list[COL_UNRES_NET_DST] = TRUE;
132 fmt_list[COL_RES_DL_SRC] = TRUE;
135 fmt_list[COL_RES_DL_DST] = TRUE;
137 case COL_DEF_NET_SRC:
138 fmt_list[COL_RES_NET_SRC] = TRUE;
140 case COL_DEF_NET_DST:
141 fmt_list[COL_RES_NET_DST] = TRUE;
143 case COL_DEF_SRC_PORT:
144 fmt_list[COL_RES_SRC_PORT] = TRUE;
146 case COL_DEF_DST_PORT:
147 fmt_list[COL_RES_DST_PORT] = TRUE;
155 /* Returns a string representing the longest possible value for a
156 particular column type.
158 Except for the COL...SRC and COL...DST columns, these are used
159 only when a capture is being displayed while it's taking place;
160 they are arguably somewhat fragile, as changes to the code that
161 generates them don't cause these widths to change, but that's
162 probably not too big a problem, given that the sizes are
163 recomputed based on the actual data in the columns when the capture
164 is done, and given that the width for COL...SRC and COL...DST columns
165 is somewhat arbitrary in any case. We should probably clean
166 that up eventually, though. */
168 get_column_longest_string(gint format)
175 if (timestamp_type == ABSOLUTE)
176 return "00:00:00.000000";
177 else if (timestamp_type == ABSOLUTE_WITH_DATE)
178 return "0000-00-00 00:00:00.000000";
180 return "0000.000000";
183 return "00:00:00.000000";
185 case COL_ABS_DATE_TIME:
186 return "0000-00-00 00:00:00.000000";
190 return "0000.000000";
197 case COL_UNRES_DL_SRC:
198 case COL_DEF_NET_SRC:
199 case COL_RES_NET_SRC:
200 case COL_UNRES_NET_SRC:
206 case COL_UNRES_DL_DST:
207 case COL_DEF_NET_DST:
208 case COL_RES_NET_DST:
209 case COL_UNRES_NET_DST:
210 return "00000000.000000000000"; /* IPX-style */
212 case COL_DEF_SRC_PORT:
213 case COL_RES_SRC_PORT:
214 case COL_UNRES_SRC_PORT:
215 case COL_DEF_DST_PORT:
216 case COL_RES_DST_PORT:
217 case COL_UNRES_DST_PORT:
221 return "NetBIOS"; /* not the longest, but the longest is too long */
223 case COL_PACKET_LENGTH:
226 default: /* COL_INFO */
227 return "Source port: kerberos-master Destination port: kerberos-master";
232 /* Returns the longest possible width, in characters, for a particular
235 get_column_char_width(gint format)
237 return strlen(get_column_longest_string(format));
241 get_column_resize_type(gint format) {
246 case COL_ABS_DATE_TIME:
249 case COL_DEF_SRC_PORT:
250 case COL_RES_SRC_PORT:
251 case COL_UNRES_SRC_PORT:
252 case COL_DEF_DST_PORT:
253 case COL_RES_DST_PORT:
254 case COL_UNRES_DST_PORT:
256 case COL_PACKET_LENGTH:
257 /* We don't want these to resize during a live capture, as that
258 gets in the way of trying to look at the data while it's being
260 return (RESIZE_AUTO);
267 case COL_UNRES_DL_SRC:
268 case COL_DEF_NET_SRC:
269 case COL_RES_NET_SRC:
270 case COL_UNRES_NET_SRC:
276 case COL_UNRES_DL_DST:
277 case COL_DEF_NET_DST:
278 case COL_RES_NET_DST:
279 case COL_UNRES_NET_DST:
280 /* We don't want these to resize dynamically; if they get resolved
281 to names, those names could be very long, and auto-resizing
282 columns showing those names may leave too little room for
283 other columns such as the "Info" column. */
284 return (RESIZE_MANUAL);
286 default: /* COL_INFO */
287 /* We want this to resize dynamically, even during a live capture,
288 because otherewise you won't be able to see all that's in
290 return (RESIZE_LIVE);
298 #define DATE_TIME_ABS 3
310 get_column_format(gint col) {
311 GList *clp = g_list_nth(prefs.col_list, col);
314 cfmt = (fmt_data *) clp->data;
316 return(get_column_format_from_str(cfmt->fmt));
320 get_column_format_from_str(gchar *str) {
322 gint res_off = RES_DEF, addr_off = ADDR_DEF, time_off = TIME_DEF;
324 /* To do: Make this parse %-formatted strings "for real" */
325 while (*cptr != '\0') {
327 case 't': /* To do: fix for absolute and delta */
328 return COL_CLS_TIME + time_off;
334 return COL_DEF_SRC + res_off + addr_off;
337 return COL_DEF_DST + res_off + addr_off;
340 return COL_DEF_SRC_PORT + res_off;
343 return COL_DEF_DST_PORT + res_off;
370 time_off = DATE_TIME_ABS;
376 return COL_PACKET_LENGTH;
385 get_column_title(gint col) {
386 GList *clp = g_list_nth(prefs.col_list, col);
389 cfmt = (fmt_data *) clp->data;
394 #define MAX_FMT_PREF_LEN 1024
395 #define MAX_FMT_PREF_LINE_LEN 60
397 col_format_to_pref_str() {
398 static gchar pref_str[MAX_FMT_PREF_LEN] = "";
399 GList *clp = g_list_first(prefs.col_list);
401 int cur_pos = 0, cur_len = 0, fmt_len;
404 cfmt = (fmt_data *) clp->data;
406 fmt_len = strlen(cfmt->title) + 4;
407 if ((fmt_len + cur_len) < (MAX_FMT_PREF_LEN - 1)) {
408 if ((fmt_len + cur_pos) > MAX_FMT_PREF_LINE_LEN) {
411 pref_str[cur_len] = '\n'; cur_len++;
412 pref_str[cur_len] = '\t'; cur_len++;
414 sprintf(&pref_str[cur_len], "\"%s\", ", cfmt->title);
419 fmt_len = strlen(cfmt->fmt) + 4;
420 if ((fmt_len + cur_len) < (MAX_FMT_PREF_LEN - 1)) {
421 if ((fmt_len + cur_pos) > MAX_FMT_PREF_LINE_LEN) {
424 pref_str[cur_len] = '\n'; cur_len++;
425 pref_str[cur_len] = '\t'; cur_len++;
427 sprintf(&pref_str[cur_len], "\"%s\", ", cfmt->fmt);
436 pref_str[cur_len - 2] = '\0';