Wireshark-dev: [Wireshark-dev] [PATCH] range_string and OSPF bcmodelid
From: "Francesco Fondelli" <francesco.fondelli@xxxxxxxxx>
Date: Fri, 24 Nov 2006 11:43:23 +0100
Hi all,
I needed to dissect a simple hf item in ospf, a integer one.
The possible values were in ranges like:
0 3 "foo"
1 4 "bar"
5 5 "shark"
6 100 "reserved"
101 200 "private use"
in such a case I normally use "switch" or "if" statements
and several proto_tree_add_uint_format() or
proto_tree_add_text() to properly handle the "reserved" and
"private use" cases. If I'm not wrong there is no
way to dissect such a hf in one shot using a
single proto_tree_add_xxx() call.
So I defined a range_string struct. It's like value_string
but stores range <-> string pairs.
Moreover I wrote rval_to_str(), match_strrval_idx()
match_strrval() which are behaving exactly as
val_to_str(), match_strval_idx() and match_strval().
(almost cut && paste :-))
now we can do something like:
static const range_string rvals[] = {
{ 0, 3, "foo"},
{ 1, 4, "bar"},
{ 5, 5, "shark" },
{ 6, 100, "reserved"},
{ 101, 200, "private"},
{ 0, 0, NULL}
};
proto_tree_add_uint_format(tree,
hf_augh,
tvb,
offset,
1,
value,
"bla bla: %u (%s)",
value,
rval_to_str(value, rvals, "Unknown"));
This way people can write less lines of code (yes I'm lazy ;-)))
and IMHO it's more readable.
if you like this solution please apply
"range_string_and_ospf_bcmodel_id.patch",
if you don't please apply "ospf_bcmodel_id.patch". You
find both in attachment, they are diffed against
svn rev. 19892.
Thanks
Ciao
FF
Index: AUTHORS
===================================================================
--- AUTHORS (revision 19892)
+++ AUTHORS (working copy)
@@ -2277,6 +2277,7 @@
MPLS OAM support, Y.1711
RSVP/OSPF Extensions for Support of Diffserv-aware MPLS-TE, RFC 4124
Linux Packet Generator support
+ rval_to_str() and alike
}
Bill Meier <wmeier [AT] newsguy.com> {
Index: epan/value_string.c
===================================================================
--- epan/value_string.c (revision 19892)
+++ epan/value_string.c (working copy)
@@ -109,3 +109,50 @@
g_snprintf(p, 1024-(p-buf), fmt, val_to_str((val & mask) >> shift, tab, "Unknown"));
return buf;
}
+
+
+/* FF: ranges aware versions */
+
+/* Tries to match val against each range in the range_string array rs.
+ Returns the associated string ptr on a match.
+ Formats val with fmt, and returns the resulting string, on failure. */
+const gchar *rval_to_str(guint32 val, const range_string *rs, const char *fmt)
+{
+ const gchar *ret = NULL;
+
+ g_assert(fmt != NULL);
+
+ ret = match_strrval(val, rs);
+ if(ret != NULL)
+ return ret;
+
+ return ep_strdup_printf(fmt, val);
+}
+
+/* Tries to match val against each range in the range_string array rs.
+ Returns the associated string ptr, and sets "*idx" to the index in
+ that table, on a match, and returns NULL, and sets "*idx" to -1,
+ on failure. */
+const gchar *match_strrval_idx(guint32 val, const range_string *rs, gint *idx)
+{
+ gint i = 0;
+
+ while(rs[i].strptr) {
+ if( (val >= rs[i].value_min) && (val <= rs[i].value_max) ) {
+ *idx = i;
+ return (rs[i].strptr);
+ }
+ i++;
+ }
+
+ *idx = -1;
+ return (NULL);
+}
+
+/* Like match_strrval_idx(), but doesn't return the index. */
+const gchar *match_strrval(guint32 val, const range_string *rs)
+{
+ gint ignore_me = 0;
+ return match_strrval_idx(val, rs, &ignore_me);
+}
+
Index: epan/value_string.h
===================================================================
--- epan/value_string.h (revision 19892)
+++ epan/value_string.h (working copy)
@@ -34,6 +34,13 @@
const gchar *strptr;
} value_string;
+/* Struct for the rval_to_str, match_strrval_idx, and match_strrval functions */
+typedef struct _range_string {
+ guint32 value_min;
+ guint32 value_max;
+ const gchar *strptr;
+} range_string;
+
/* #define VS_DEF(x) { x, #x } */
/* #define VS_END { 0, NULL } */
@@ -61,4 +68,21 @@
extern const char *decode_enumerated_bitfield_shifted(guint32 val, guint32 mask,
int width, const value_string *tab, const char *fmt);
+
+/* ranges aware versions */
+
+/* Tries to match val against each range in the range_string array rs.
+ Returns the associated string ptr on a match.
+ Formats val with fmt, and returns the resulting string, on failure. */
+extern const gchar* rval_to_str(guint32 val, const range_string *rs, const char *fmt);
+
+/* Tries to match val against each range in the range_string array rs.
+ Returns the associated string ptr, and sets "*idx" to the index in
+ that table, on a match, and returns NULL, and sets "*idx" to -1,
+ on failure. */
+extern const gchar *match_strrval_idx(guint32 val, const range_string *rs, gint *idx);
+
+/* Like match_strrval_idx(), but doesn't return the index. */
+extern const gchar *match_strrval(guint32 val, const range_string *rs);
+
#endif /* __VALUE_STRING_H__ */
Index: epan/dissectors/packet-ospf.c
===================================================================
--- epan/dissectors/packet-ospf.c (revision 19892)
+++ epan/dissectors/packet-ospf.c (working copy)
@@ -202,6 +202,16 @@
{0, NULL},
};
+/* FF: from www.iana.org/assignments/bandwidth-constraints-model-ids */
+static const range_string mpls_link_stlv_bcmodel_rvals[] = {
+ { 0, 0, "(Russian Dolls Model - RDM)" },
+ { 1, 1, "(Maximum Allocation Model - MAM)" },
+ { 2, 2, "(Maximum Allocation with Reservation Model - MAR)" },
+ { 3, 239, "(Unassigned, Specification Required)" },
+ { 240, 255, "(Reserved, Private Use)" },
+ { 0, 0, NULL }
+};
+
#define OSPF_V2_ROUTER_LSA_FLAG_B 0x01
#define OSPF_V2_ROUTER_LSA_FLAG_E 0x02
#define OSPF_V2_ROUTER_LSA_FLAG_V 0x04
@@ -585,7 +595,7 @@
BASE_HEX, NULL, 0x0, "MPLS/TE Link Resource Class/Color", HFILL }},
{&ospf_filter[OSPFF_LS_MPLS_BC_MODEL_ID],
{ "MPLS/DSTE Bandwidth Constraints Model Id", "ospf.mpls.bc", FT_UINT8,
- BASE_HEX, NULL, 0x0, "MPLS/DSTE Bandwidth Constraints Model Id", HFILL }},
+ BASE_DEC, NULL, 0x0, "MPLS/DSTE Bandwidth Constraints Model Id", HFILL }},
{&ospf_filter[OSPFF_V2_OPTIONS],
{ "Options", "ospf.v2.options", FT_UINT8, BASE_HEX,
@@ -1752,10 +1762,16 @@
proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
stlv_len);
- proto_tree_add_item(stlv_tree,
- ospf_filter[OSPFF_LS_MPLS_BC_MODEL_ID],
- tvb, stlv_offset+4, 1, FALSE);
-
+ proto_tree_add_uint_format(stlv_tree,
+ ospf_filter[OSPFF_LS_MPLS_BC_MODEL_ID],
+ tvb, stlv_offset+4, 1,
+ tvb_get_guint8(tvb, stlv_offset+4),
+ "MPLS/DSTE Bandwidth Constraints Model Id: %u %s",
+ tvb_get_guint8(tvb, stlv_offset+4),
+ rval_to_str(tvb_get_guint8(tvb, stlv_offset+4),
+ mpls_link_stlv_bcmodel_rvals,
+ "Unknown"));
+
/* 3 octets reserved +5, +6 and +7 (all 0x00) */
if(tvb_memeql(tvb, stlv_offset+5, allzero, 3) == -1) {
proto_tree_add_text(stlv_tree, tvb, stlv_offset+5, 3,
Index: epan/dissectors/packet-ospf.c
===================================================================
--- epan/dissectors/packet-ospf.c (revision 19892)
+++ epan/dissectors/packet-ospf.c (working copy)
@@ -202,6 +202,14 @@
{0, NULL},
};
+/* FF: from www.iana.org/assignments/bandwidth-constraints-model-ids */
+static const value_string mpls_link_stlv_bcmodel_vals[] = {
+ { 0, "Russian Dolls Model - RDM" },
+ { 1, "Maximum Allocation Model - MAM" },
+ { 2, "Maximum Allocation with Reservation Model - MAR" },
+ { 0, NULL }
+};
+
#define OSPF_V2_ROUTER_LSA_FLAG_B 0x01
#define OSPF_V2_ROUTER_LSA_FLAG_E 0x02
#define OSPF_V2_ROUTER_LSA_FLAG_V 0x04
@@ -585,7 +593,7 @@
BASE_HEX, NULL, 0x0, "MPLS/TE Link Resource Class/Color", HFILL }},
{&ospf_filter[OSPFF_LS_MPLS_BC_MODEL_ID],
{ "MPLS/DSTE Bandwidth Constraints Model Id", "ospf.mpls.bc", FT_UINT8,
- BASE_HEX, NULL, 0x0, "MPLS/DSTE Bandwidth Constraints Model Id", HFILL }},
+ BASE_DEC, VALS(mpls_link_stlv_bcmodel_vals), 0x0, "MPLS/DSTE Bandwidth Constraints Model Id", HFILL }},
{&ospf_filter[OSPFF_V2_OPTIONS],
{ "Options", "ospf.v2.options", FT_UINT8, BASE_HEX,
@@ -1752,9 +1760,23 @@
proto_tree_add_text(stlv_tree, tvb, stlv_offset+2, 2, "TLV Length: %u",
stlv_len);
- proto_tree_add_item(stlv_tree,
- ospf_filter[OSPFF_LS_MPLS_BC_MODEL_ID],
- tvb, stlv_offset+4, 1, FALSE);
+ {
+ guint8 bc_model_id = tvb_get_guint8(tvb, stlv_offset+4);
+
+ if(bc_model_id <= 2) {
+ proto_tree_add_item(stlv_tree,
+ ospf_filter[OSPFF_LS_MPLS_BC_MODEL_ID],
+ tvb, stlv_offset+4, 1, FALSE);
+ } else if((bc_model_id >= 3) && (bc_model_id <= 239)) {
+ proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1,
+ "MPLS/DSTE Bandwidth Constraints Model Id: Unassigned (%u)",
+ bc_model_id);
+ } else {
+ proto_tree_add_text(stlv_tree, tvb, stlv_offset+4, 1,
+ "MPLS/DSTE Bandwidth Constraints Model Id: Private (%u)",
+ bc_model_id);
+ }
+ }
/* 3 octets reserved +5, +6 and +7 (all 0x00) */
if(tvb_memeql(tvb, stlv_offset+5, allzero, 3) == -1) {
- Prev by Date: [Wireshark-dev] New feature about packets statistic
- Next by Date: Re: [Wireshark-dev] Compilation problem, SVN 19973
- Previous by thread: Re: [Wireshark-dev] New feature about packets statistic
- Next by thread: [Wireshark-dev] frame relay bugfix
- Index(es):