2 * Routines for column utilities.
4 * $Id: column-utils.c,v 1.7 2001/11/21 23:16:23 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.
33 #ifdef HAVE_SYS_TYPES_H
34 # include <sys/types.h>
37 #ifdef NEED_SNPRINTF_H
38 # include "snprintf.h"
41 #ifdef NEED_INET_V6DEFS_H
42 # include "inet_v6defs.h"
45 #include "column-utils.h"
46 #include "timestamp.h"
47 #include "sna-utils.h"
48 #include "atalk-utils.h"
50 #include "packet_info.h"
53 #include "ipv6-utils.h"
54 #include "osi-utils.h"
56 /* Allocate all the data structures for constructing column data, given
57 the number of columns. */
59 col_init(column_info *col_info, gint num_cols)
61 col_info->num_cols = num_cols;
62 col_info->col_fmt = (gint *) g_malloc(sizeof(gint) * num_cols);
63 col_info->fmt_matx = (gboolean **) g_malloc(sizeof(gboolean *) * num_cols);
64 col_info->col_width = (gint *) g_malloc(sizeof(gint) * num_cols);
65 col_info->col_title = (gchar **) g_malloc(sizeof(gchar *) * num_cols);
66 col_info->col_data = (gchar **) g_malloc(sizeof(gchar *) * num_cols);
67 col_info->col_buf = (gchar **) g_malloc(sizeof(gchar *) * num_cols);
71 * This function does not appear to be used anywhere...
74 col_get_writable(frame_data *fd)
78 return (fd->cinfo ? fd->cinfo->writable : FALSE);
89 col_set_writable(frame_data *fd, gboolean writable)
92 fd->cinfo->writable = writable;
96 /* Checks to see if a particular packet information element is needed for
99 check_col(frame_data *fd, gint el) {
102 if (fd->cinfo && fd->cinfo->writable) {
103 for (i = 0; i < fd->cinfo->num_cols; i++) {
104 if (fd->cinfo->fmt_matx[i][el])
113 /* Use this to clear out a column, especially if you're going to be
114 appending to it later; at least on some platforms, it's more
115 efficient than using "col_add_str()" with a null string, and
116 more efficient than "col_set_str()" with a null string if you
117 later append to it, as the later append will cause a string
120 col_clear(frame_data *fd, gint el) {
123 for (i = 0; i < fd->cinfo->num_cols; i++) {
124 if (fd->cinfo->fmt_matx[i][el]) {
125 fd->cinfo->col_buf[i][0] = 0;
126 fd->cinfo->col_data[i] = fd->cinfo->col_buf[i];
131 /* Use this if "str" points to something that will stay around (and thus
132 needn't be copied). */
134 col_set_str(frame_data *fd, gint el, gchar* str) {
137 for (i = 0; i < fd->cinfo->num_cols; i++) {
138 if (fd->cinfo->fmt_matx[i][el])
139 fd->cinfo->col_data[i] = str;
143 /* Adds a vararg list to a packet info string. */
145 col_add_fstr(frame_data *fd, gint el, gchar *format, ...) {
151 max_len = COL_MAX_INFO_LEN;
153 max_len = COL_MAX_LEN;
155 va_start(ap, format);
156 for (i = 0; i < fd->cinfo->num_cols; i++) {
157 if (fd->cinfo->fmt_matx[i][el]) {
158 vsnprintf(fd->cinfo->col_buf[i], max_len, format, ap);
159 fd->cinfo->col_data[i] = fd->cinfo->col_buf[i];
164 /* Appends a vararg list to a packet info string. */
166 col_append_fstr(frame_data *fd, gint el, gchar *format, ...) {
172 max_len = COL_MAX_INFO_LEN;
174 max_len = COL_MAX_LEN;
176 va_start(ap, format);
177 for (i = 0; i < fd->cinfo->num_cols; i++) {
178 if (fd->cinfo->fmt_matx[i][el]) {
179 if (fd->cinfo->col_data[i] != fd->cinfo->col_buf[i]) {
180 /* This was set with "col_set_str()"; copy the string they
181 set it to into the buffer, so we can append to it. */
182 strncpy(fd->cinfo->col_buf[i], fd->cinfo->col_data[i], max_len);
183 fd->cinfo->col_buf[i][max_len - 1] = '\0';
185 len = strlen(fd->cinfo->col_buf[i]);
186 vsnprintf(&fd->cinfo->col_buf[i][len], max_len - len, format, ap);
187 fd->cinfo->col_data[i] = fd->cinfo->col_buf[i];
192 /* Use this if "str" points to something that won't stay around (and
193 must thus be copied). */
195 col_add_str(frame_data *fd, gint el, const gchar* str) {
200 max_len = COL_MAX_INFO_LEN;
202 max_len = COL_MAX_LEN;
204 for (i = 0; i < fd->cinfo->num_cols; i++) {
205 if (fd->cinfo->fmt_matx[i][el]) {
206 strncpy(fd->cinfo->col_buf[i], str, max_len);
207 fd->cinfo->col_buf[i][max_len - 1] = 0;
208 fd->cinfo->col_data[i] = fd->cinfo->col_buf[i];
214 col_append_str(frame_data *fd, gint el, gchar* str) {
219 max_len = COL_MAX_INFO_LEN;
221 max_len = COL_MAX_LEN;
223 for (i = 0; i < fd->cinfo->num_cols; i++) {
224 if (fd->cinfo->fmt_matx[i][el]) {
225 if (fd->cinfo->col_data[i] != fd->cinfo->col_buf[i]) {
226 /* This was set with "col_set_str()"; copy the string they
227 set it to into the buffer, so we can append to it. */
228 strncpy(fd->cinfo->col_buf[i], fd->cinfo->col_data[i], max_len);
229 fd->cinfo->col_buf[i][max_len - 1] = '\0';
231 len = strlen(fd->cinfo->col_buf[i]);
232 strncat(fd->cinfo->col_buf[i], str, max_len - len);
233 fd->cinfo->col_buf[i][max_len - 1] = 0;
234 fd->cinfo->col_data[i] = fd->cinfo->col_buf[i];
240 col_set_abs_date_time(frame_data *fd, int col)
246 tmp = localtime(&then);
248 snprintf(fd->cinfo->col_buf[col], COL_MAX_LEN,
249 "%04d-%02d-%02d %02d:%02d:%02d.%04ld",
256 (long)fd->abs_usecs/100);
258 fd->cinfo->col_buf[col][0] = '\0';
260 fd->cinfo->col_data[col] = fd->cinfo->col_buf[col];
264 col_set_rel_time(frame_data *fd, int col)
266 display_signed_time(fd->cinfo->col_buf[col], COL_MAX_LEN,
267 fd->rel_secs, fd->rel_usecs, USECS);
268 fd->cinfo->col_data[col] = fd->cinfo->col_buf[col];
272 col_set_delta_time(frame_data *fd, int col)
274 display_signed_time(fd->cinfo->col_buf[col], COL_MAX_LEN,
275 fd->del_secs, fd->del_usecs, USECS);
276 fd->cinfo->col_data[col] = fd->cinfo->col_buf[col];
279 /* To do: Add check_col checks to the col_add* routines */
282 col_set_abs_time(frame_data *fd, int col)
288 tmp = localtime(&then);
290 snprintf(fd->cinfo->col_buf[col], COL_MAX_LEN, "%02d:%02d:%02d.%04ld",
294 (long)fd->abs_usecs/100);
296 fd->cinfo->col_buf[col][0] = '\0';
298 fd->cinfo->col_data[col] = fd->cinfo->col_buf[col];
301 /* Add "command-line-specified" time.
302 XXX - this is called from "file.c" when the user changes the time
303 format they want for "command-line-specified" time; it's a bit ugly
304 that we have to export it, but if we go to a CList-like widget that
305 invokes callbacks to get the text for the columns rather than
306 requiring us to stuff the text into the widget from outside, we
307 might be able to clean this up. */
309 col_set_cls_time(frame_data *fd, int col)
311 switch (timestamp_type) {
313 col_set_abs_time(fd, col);
316 case ABSOLUTE_WITH_DATE:
317 col_set_abs_date_time(fd, col);
321 col_set_rel_time(fd, col);
325 col_set_delta_time(fd, col);
331 col_set_addr(frame_data *fd, int col, address *addr, gboolean is_res)
334 struct e_in6_addr ipv6_addr;
335 struct atalk_ddp_addr ddp_addr;
336 struct sna_fid_type_4_addr sna_fid_type_4_addr;
338 switch (addr->type) {
342 strncpy(fd->cinfo->col_buf[col], get_ether_name(addr->data), COL_MAX_LEN);
344 strncpy(fd->cinfo->col_buf[col], ether_to_str(addr->data), COL_MAX_LEN);
345 fd->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
346 fd->cinfo->col_data[col] = fd->cinfo->col_buf[col];
350 memcpy(&ipv4_addr, addr->data, sizeof ipv4_addr);
352 strncpy(fd->cinfo->col_buf[col], get_hostname(ipv4_addr), COL_MAX_LEN);
354 strncpy(fd->cinfo->col_buf[col], ip_to_str(addr->data), COL_MAX_LEN);
355 fd->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
356 fd->cinfo->col_data[col] = fd->cinfo->col_buf[col];
360 memcpy(&ipv6_addr.s6_addr, addr->data, sizeof ipv6_addr.s6_addr);
362 strncpy(fd->cinfo->col_buf[col], get_hostname6(&ipv6_addr), COL_MAX_LEN);
364 strncpy(fd->cinfo->col_buf[col], ip6_to_str(&ipv6_addr), COL_MAX_LEN);
365 fd->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
366 fd->cinfo->col_data[col] = fd->cinfo->col_buf[col];
370 strncpy(fd->cinfo->col_buf[col],
371 ipx_addr_to_str(pntohl(&addr->data[0]), &addr->data[4]), COL_MAX_LEN);
372 fd->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
373 fd->cinfo->col_data[col] = fd->cinfo->col_buf[col];
380 snprintf(fd->cinfo->col_buf[col], COL_MAX_LEN, "%04X", addr->data[0]);
384 snprintf(fd->cinfo->col_buf[col], COL_MAX_LEN, "%04X",
385 pntohs(&addr->data[0]));
388 case SNA_FID_TYPE_4_ADDR_LEN:
389 memcpy(&sna_fid_type_4_addr, addr->data, SNA_FID_TYPE_4_ADDR_LEN);
390 strncpy(fd->cinfo->col_buf[col],
391 sna_fid_type_4_addr_to_str(&sna_fid_type_4_addr), COL_MAX_LEN);
394 fd->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
395 fd->cinfo->col_data[col] = fd->cinfo->col_buf[col];
399 memcpy(&ddp_addr, addr->data, sizeof ddp_addr);
400 strncpy(fd->cinfo->col_buf[col], atalk_addr_to_str(&ddp_addr),
402 fd->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
403 fd->cinfo->col_data[col] = fd->cinfo->col_buf[col];
407 strncpy(fd->cinfo->col_buf[col], vines_addr_to_str(&addr->data[0]),
409 fd->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
410 fd->cinfo->col_data[col] = fd->cinfo->col_buf[col];
414 strncpy(fd->cinfo->col_buf[col], print_nsap_net(addr->data, addr->len),
416 fd->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
417 fd->cinfo->col_data[col] = fd->cinfo->col_buf[col];
426 col_set_port(frame_data *fd, int col, port_type ptype, guint32 port,
433 strncpy(fd->cinfo->col_buf[col], get_sctp_port(port), COL_MAX_LEN);
435 snprintf(fd->cinfo->col_buf[col], COL_MAX_LEN, "%u", port);
440 strncpy(fd->cinfo->col_buf[col], get_tcp_port(port), COL_MAX_LEN);
442 snprintf(fd->cinfo->col_buf[col], COL_MAX_LEN, "%u", port);
447 strncpy(fd->cinfo->col_buf[col], get_udp_port(port), COL_MAX_LEN);
449 snprintf(fd->cinfo->col_buf[col], COL_MAX_LEN, "%u", port);
455 fd->cinfo->col_buf[col][COL_MAX_LEN - 1] = '\0';
456 fd->cinfo->col_data[col] = fd->cinfo->col_buf[col];
460 fill_in_columns(frame_data *fd, packet_info *pinfo)
464 for (i = 0; i < fd->cinfo->num_cols; i++) {
465 switch (fd->cinfo->col_fmt[i]) {
468 snprintf(fd->cinfo->col_buf[i], COL_MAX_LEN, "%u", fd->num);
469 fd->cinfo->col_data[i] = fd->cinfo->col_buf[i];
473 col_set_cls_time(fd, i);
477 col_set_abs_time(fd, i);
480 case COL_ABS_DATE_TIME:
481 col_set_abs_date_time(fd, i);
485 col_set_rel_time(fd, i);
489 col_set_delta_time(fd, i);
493 case COL_RES_SRC: /* COL_DEF_SRC is currently just like COL_RES_SRC */
494 col_set_addr(fd, i, &pinfo->src, TRUE);
498 col_set_addr(fd, i, &pinfo->src, FALSE);
503 col_set_addr(fd, i, &pinfo->dl_src, TRUE);
506 case COL_UNRES_DL_SRC:
507 col_set_addr(fd, i, &pinfo->dl_src, FALSE);
510 case COL_DEF_NET_SRC:
511 case COL_RES_NET_SRC:
512 col_set_addr(fd, i, &pinfo->net_src, TRUE);
515 case COL_UNRES_NET_SRC:
516 col_set_addr(fd, i, &pinfo->net_src, FALSE);
520 case COL_RES_DST: /* COL_DEF_DST is currently just like COL_RES_DST */
521 col_set_addr(fd, i, &pinfo->dst, TRUE);
525 col_set_addr(fd, i, &pinfo->dst, FALSE);
530 col_set_addr(fd, i, &pinfo->dl_dst, TRUE);
533 case COL_UNRES_DL_DST:
534 col_set_addr(fd, i, &pinfo->dl_dst, FALSE);
537 case COL_DEF_NET_DST:
538 case COL_RES_NET_DST:
539 col_set_addr(fd, i, &pinfo->net_dst, TRUE);
542 case COL_UNRES_NET_DST:
543 col_set_addr(fd, i, &pinfo->net_dst, FALSE);
546 case COL_DEF_SRC_PORT:
547 case COL_RES_SRC_PORT: /* COL_DEF_SRC_PORT is currently just like COL_RES_SRC_PORT */
548 col_set_port(fd, i, pinfo->ptype, pinfo->srcport, TRUE);
551 case COL_UNRES_SRC_PORT:
552 col_set_port(fd, i, pinfo->ptype, pinfo->srcport, FALSE);
555 case COL_DEF_DST_PORT:
556 case COL_RES_DST_PORT: /* COL_DEF_DST_PORT is currently just like COL_RES_DST_PORT */
557 col_set_port(fd, i, pinfo->ptype, pinfo->destport, TRUE);
560 case COL_UNRES_DST_PORT:
561 col_set_port(fd, i, pinfo->ptype, pinfo->destport, FALSE);
564 case COL_PROTOCOL: /* currently done by dissectors */
565 case COL_INFO: /* currently done by dissectors */
568 case COL_PACKET_LENGTH:
569 snprintf(fd->cinfo->col_buf[i], COL_MAX_LEN, "%d", fd->pkt_len);
570 fd->cinfo->col_data[i] = fd->cinfo->col_buf[i];
573 case NUM_COL_FMTS: /* keep compiler happy - shouldn't get here */