aboutsummaryrefslogtreecommitdiffstats
path: root/epan/proto.c
diff options
context:
space:
mode:
authorstig <stig@f5534014-38df-0310-8fa8-9805f1628bb7>2010-10-14 13:11:03 +0000
committerstig <stig@f5534014-38df-0310-8fa8-9805f1628bb7>2010-10-14 13:11:03 +0000
commite3cdbc3b5c76791e5d3294f5284aae493ab39f52 (patch)
treea53c3e714c6b3b6224e5266a75fb8533c312b98d /epan/proto.c
parent8203b8f0caba6f35c2595ae74469ee9217dc1f55 (diff)
Support multiple header fields with the same abbreviation in custom columns.
We have some different fields using the same abbreviation (e.g "eth.dst" used in both eth and tte), and this patch will fetch values from all fields. When using occurrences the entries listed first is from the field registered last when starting Wireshark, and not ordered from the occurrence in the packet, but I don't see how we can easily fix this. git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@34513 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/proto.c')
-rw-r--r--epan/proto.c58
1 files changed, 47 insertions, 11 deletions
diff --git a/epan/proto.c b/epan/proto.c
index ab1978513e..7a2a690254 100644
--- a/epan/proto.c
+++ b/epan/proto.c
@@ -3430,10 +3430,11 @@ proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
guint32 n_addr; /* network-order IPv4 address */
const true_false_string *tfstring;
- int len, last, i, offset_r=0, offset_e=0;
+ int len, prev_len=0, last, i, offset_r=0, offset_e=0;
GPtrArray *finfos;
field_info *finfo = NULL;
header_field_info* hfinfo;
+ const gchar *abbrev = NULL;
g_assert(field_id >= 0);
@@ -3443,30 +3444,50 @@ proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
if (!hfinfo)
return "";
+ if (occurrence < 0) {
+ /* Search other direction */
+ while (hfinfo->same_name_prev) {
+ hfinfo = hfinfo->same_name_prev;
+ }
+ }
+
while (hfinfo) {
finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
if (!finfos || !(len = g_ptr_array_len(finfos))) {
- hfinfo = hfinfo->same_name_next;
+ if (occurrence < 0) {
+ hfinfo = hfinfo->same_name_next;
+ } else {
+ hfinfo = hfinfo->same_name_prev;
+ }
continue;
}
/* Are there enough occurrences of the field? */
- if ((occurrence > len) || (occurrence < -len) )
- return "";
+ if ((occurrence-prev_len > len) || (occurrence+prev_len < -len)) {
+ if (occurrence < 0) {
+ hfinfo = hfinfo->same_name_next;
+ } else {
+ hfinfo = hfinfo->same_name_prev;
+ }
+ prev_len += len;
+ continue;
+ }
- /* calculate single index or set outer bounderies */
+ /* Calculate single index or set outer bounderies */
if (occurrence < 0) {
- i = occurrence + len;
+ i = occurrence + len + prev_len;
last = i;
} else if (occurrence > 0) {
- i = occurrence - 1;
+ i = occurrence - 1 - prev_len;
last = i;
} else {
i = 0;
last = len - 1;
}
+ prev_len += len; /* Count handled occurrences */
+
while (i <= last) {
finfo = g_ptr_array_index(finfos, i);
@@ -3479,7 +3500,11 @@ proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
switch(hfinfo->type) {
case FT_NONE: /* Nothing to add */
- result[0] = '\0';
+ if (offset_r == 0) {
+ result[0] = '\0';
+ } else if (result[offset_r-1] == ',') {
+ result[offset_r-1] = '\0';
+ }
break;
case FT_PROTOCOL:
@@ -3652,9 +3677,20 @@ proto_custom_set(proto_tree* tree, const int field_id, gint occurrence,
break;
}
- return hfinfo->abbrev;
- }
- return "";
+ if (!abbrev) {
+ /* Store abbrev for return value */
+ abbrev = hfinfo->abbrev;
+ }
+
+ if (occurrence == 0) {
+ /* Fetch next hfinfo with same name (abbrev) */
+ hfinfo = hfinfo->same_name_prev;
+ } else {
+ hfinfo = NULL;
+ }
+ }
+
+ return abbrev ? abbrev : "";
}