summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--epan/column-utils.c54
-rw-r--r--epan/column-utils.h10
-rw-r--r--epan/column.c9
-rw-r--r--epan/column_info.h1
-rw-r--r--epan/proto.c13
-rw-r--r--file.c10
6 files changed, 90 insertions, 7 deletions
diff --git a/epan/column-utils.c b/epan/column-utils.c
index 814bef3d64..0aaf4b62cb 100644
--- a/epan/column-utils.c
+++ b/epan/column-utils.c
@@ -40,8 +40,10 @@
#include "ipv6-utils.h"
#include "osi-utils.h"
#include "value_string.h"
+#include "globals.h"
#include <epan/strutil.h>
+#include <epan/epan.h>
/* Allocate all the data structures for constructing column data, given
the number of columns. */
@@ -266,6 +268,55 @@ col_add_fstr(column_info *cinfo, gint el, const gchar *format, ...) {
va_end(ap);
}
+void
+col_custom_set_fstr(const gchar *field_name, const gchar *format, ...)
+{
+ va_list ap;
+ int i;
+
+ if (!check_col(&cfile.cinfo, COL_CUSTOM))
+ return;
+
+ va_start(ap, format);
+ for (i = cfile.cinfo.col_first[COL_CUSTOM];
+ i <= cfile.cinfo.col_last[COL_CUSTOM]; i++) {
+ if (strcmp(cfile.cinfo.col_title[i], field_name) == 0 &&
+ cfile.cinfo.fmt_matx[i][COL_CUSTOM]) {
+ cfile.cinfo.col_data[i] = cfile.cinfo.col_buf[i];
+ g_vsnprintf(cfile.cinfo.col_buf[i], COL_MAX_LEN, format, ap);
+ strncpy(cfile.cinfo.col_expr[i], field_name, COL_MAX_LEN);
+ strncpy(cfile.cinfo.col_expr_val[i], cfile.cinfo.col_buf[i], COL_MAX_LEN);
+ }
+ }
+ va_end(ap);
+}
+
+void
+col_custom_prime_edt(epan_dissect_t *edt)
+{
+ int i;
+ dfilter_t *dfilter_code;
+
+ for (i = cfile.cinfo.col_first[COL_CUSTOM];
+ i <= cfile.cinfo.col_last[COL_CUSTOM]; i++) {
+ if (cfile.cinfo.fmt_matx[i][COL_CUSTOM]) {
+ if(dfilter_compile(cfile.cinfo.col_title[i], &dfilter_code))
+ epan_dissect_prime_dfilter(edt, dfilter_code);
+ }
+ }
+}
+
+gboolean
+have_custom_cols(void)
+{
+ /* The same as check_col(), but without the check to see if the column
+ * is writable. */
+ if (cfile.cinfo.col_first[COL_CUSTOM] >= 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
static void
col_do_append_sep_va_fstr(column_info *cinfo, gint el, const gchar *separator,
const gchar *format, va_list ap)
@@ -1398,6 +1449,9 @@ col_fill_in(packet_info *pinfo)
case COL_FREQ_CHAN: /* done by radio dissectors */
break;
+ case COL_CUSTOM: /* done by col_custom_set_fstr() called from proto.c */
+ break;
+
case NUM_COL_FMTS: /* keep compiler happy - shouldn't get here */
g_assert_not_reached();
break;
diff --git a/epan/column-utils.h b/epan/column-utils.h
index 946df43680..7d9b8fe7d6 100644
--- a/epan/column-utils.h
+++ b/epan/column-utils.h
@@ -30,6 +30,7 @@
#include "gnuc_format_check.h"
#include "column_info.h"
#include "packet_info.h"
+#include <epan/epan.h>
#ifdef __cplusplus
extern "C" {
@@ -142,6 +143,15 @@ extern void col_add_str(column_info *cinfo, gint col, const gchar *str);
extern void col_add_fstr(column_info *cinfo, gint col, const gchar *format, ...)
GNUC_FORMAT_CHECK(printf, 3, 4);
+/* For internal Wireshark use only. Not to be called from dissectors. */
+void col_custom_set_fstr(const gchar *field_name, const gchar *format, ...)
+ GNUC_FORMAT_CHECK(printf, 2, 3);
+
+/* For internal Wireshark use only. Not to be called from dissectors. */
+void col_custom_prime_edt(epan_dissect_t *edt);
+
+gboolean have_custom_cols(void);
+
/** Append the given text to a column element, the text will be copied.
*
* @param cinfo the current packet row
diff --git a/epan/column.c b/epan/column.c
index 7afaded3e3..45cf19e78f 100644
--- a/epan/column.c
+++ b/epan/column.c
@@ -105,7 +105,8 @@ col_format_to_string(gint fmt) {
"%C",
"%l",
"%a",
- "%F"
+ "%F",
+ "%Cus"
};
if (fmt < 0 || fmt >= NUM_COL_FMTS)
@@ -174,7 +175,8 @@ static const gchar *dlist[NUM_COL_FMTS] = {
"Frame Relay DLCI", /* COL_FR_DLCI */
"GPRS BSSGP TLLI", /* COL_BSSGP_TLLI */
"Expert Info Severity", /* COL_EXPERT */
- "Frequency/Channel" /* COL_FREQ_CHAN */
+ "Frequency/Channel", /* COL_FREQ_CHAN */
+ "Custom" /* COL_CUSTOM */
};
const gchar *
@@ -299,6 +301,9 @@ get_column_format_matches(gboolean *fmt_list, gint format) {
case COL_FREQ_CHAN:
fmt_list[COL_FREQ_CHAN] = TRUE;
break;
+ case COL_CUSTOM:
+ fmt_list[COL_CUSTOM] = TRUE;
+ break;
default:
break;
}
diff --git a/epan/column_info.h b/epan/column_info.h
index a355797b99..e71c874529 100644
--- a/epan/column_info.h
+++ b/epan/column_info.h
@@ -115,6 +115,7 @@ enum {
COL_BSSGP_TLLI, /* GPRS BSSGP IE TLLI */
COL_EXPERT, /* Expert Info */
COL_FREQ_CHAN, /* IEEE 802.11 (and WiMax?) - Channel */
+ COL_CUSTOM, /* Custom column (any filter name's contents) */
NUM_COL_FMTS /* Should always be last */
};
diff --git a/epan/proto.c b/epan/proto.c
index d477d644f6..e0317e33de 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -45,6 +45,7 @@
#include "emem.h"
#include "charsets.h"
#include "asm_utils.h"
+#include "column-utils.h"
#ifdef NEED_G_ASCII_STRCASECMP_H
#include "g_ascii_strcasecmp.h"
@@ -1640,6 +1641,7 @@ proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint
static void
proto_tree_set_ipxnet(field_info *fi, guint32 value)
{
+ col_custom_set_fstr(fi->hfinfo->abbrev, "%u", value);
fvalue_set_uinteger(&fi->value, value);
}
@@ -2166,10 +2168,13 @@ proto_item_append_string(proto_item *pi, const char *str)
static void
proto_tree_set_string(field_info *fi, const char* value)
{
- if (value)
+ if (value) {
+ col_custom_set_fstr(fi->hfinfo->abbrev, "%s", value);
fvalue_set(&fi->value, (gpointer) value, FALSE);
- else
+ } else {
+ col_custom_set_fstr(fi->hfinfo->abbrev, "[ Null ]");
fvalue_set(&fi->value, (gpointer) "[ Null ]", FALSE);
+ }
}
static void
@@ -2278,6 +2283,7 @@ proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb, gint s
static void
proto_tree_set_ether(field_info *fi, const guint8* value)
{
+ col_custom_set_fstr(fi->hfinfo->abbrev, "%s", value);
fvalue_set(&fi->value, (gpointer) value, FALSE);
}
@@ -2634,6 +2640,7 @@ proto_tree_set_uint(field_info *fi, guint32 value)
integer >>= hfinfo->bitshift;
}
}
+ col_custom_set_fstr(hfinfo->abbrev, "%u", value);
fvalue_set_uinteger(&fi->value, integer);
}
@@ -2798,6 +2805,8 @@ proto_tree_set_int(field_info *fi, gint32 value)
integer >>= hfinfo->bitshift;
}
}
+
+ col_custom_set_fstr(hfinfo->abbrev, "%u", value);
fvalue_set_sinteger(&fi->value, integer);
}
diff --git a/file.c b/file.c
index 4e5a12e8a7..b50ab8a3df 100644
--- a/file.c
+++ b/file.c
@@ -77,8 +77,7 @@
#include <epan/timestamp.h>
#include <epan/dfilter/dfilter-macro.h>
#include "file_util.h"
-
-
+#include <epan/column-utils.h>
#ifdef HAVE_LIBPCAP
gboolean auto_scroll_live;
@@ -939,11 +938,13 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
we have tap listeners;
+ we have custom columns;
+
allocate a protocol tree root node, so that we'll construct
a protocol tree against which a filter expression can be
evaluated. */
if ((dfcode != NULL && refilter) || color_filters_used()
- || num_tap_filters != 0)
+ || num_tap_filters != 0 || have_custom_cols())
create_proto_tree = TRUE;
/* Dissect the frame. */
@@ -956,6 +957,9 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
if (color_filters_used()) {
color_filters_prime_edt(edt);
}
+
+ col_custom_prime_edt(edt);
+
tap_queue_init(edt);
epan_dissect_run(edt, pseudo_header, buf, fdata, &cf->cinfo);
tap_push_tapped_queue(edt);