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.

svn path=/trunk/; revision=34513
This commit is contained in:
Stig Bjørlykke 2010-10-14 13:11:03 +00:00
parent 9ccf7e431e
commit 6ead8f1ae5
1 changed files with 47 additions and 11 deletions

View File

@ -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 : "";
}