aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-diameter.c
diff options
context:
space:
mode:
authorJeff Morriss <jeff.morriss.ws@gmail.com>2013-07-18 15:08:15 +0000
committerJeff Morriss <jeff.morriss.ws@gmail.com>2013-07-18 15:08:15 +0000
commit7d76eb0ad34517188df694d606656526ff9833a9 (patch)
tree0f8702f02579b3ef71597219286d6f443d9c0fdc /epan/dissectors/packet-diameter.c
parent6dd1cb7f8e2cfd95a44ebdc3af9973806f436016 (diff)
Catch exceptions from AVP subdissectors in case the AVPs following the one
that threw the exception are OK--this allows us to view as much of the message as possible even when Wireshark doesn't like whatever was in a particular AVP. Instead of using the 'volatile' keyword to avoid variable-clobbering warnings, put the exception-catching code in its own function with no local variables. svn path=/trunk/; revision=50728
Diffstat (limited to 'epan/dissectors/packet-diameter.c')
-rw-r--r--epan/dissectors/packet-diameter.c62
1 files changed, 43 insertions, 19 deletions
diff --git a/epan/dissectors/packet-diameter.c b/epan/dissectors/packet-diameter.c
index 329b35c6ca..4bde5dd232 100644
--- a/epan/dissectors/packet-diameter.c
+++ b/epan/dissectors/packet-diameter.c
@@ -62,6 +62,7 @@
#include <epan/exported_pdu.h>
#include <epan/diam_dict.h>
#include <epan/sctpppids.h>
+#include <epan/show_exception.h>
#include "packet-tcp.h"
#include "packet-diameter.h"
@@ -321,7 +322,7 @@ export_diameter_pdu(packet_info *pinfo, tvbuff_t *tvb)
exp_pdu_data = load_export_pdu_tags(pinfo, "diameter", -1, tags_bit_field);
- exp_pdu_data->tvb_length = tvb_length(tvb);
+ exp_pdu_data->tvb_length = tvb_length(tvb);
exp_pdu_data->pdu_tvb = tvb;
tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
@@ -393,6 +394,39 @@ dissect_diameter_base_framed_ipv6_prefix(tvbuff_t *tvb, packet_info *pinfo _U_,
return(prefix_len_bytes+2);
}
+/* Call subdissectors for AVPs.
+ * This is a separate function to avoid having any local variables that might
+ * get clobbered by the exception longjmp() (without having to declare the
+ * variables as volatile and deal with casting them).
+ */
+static void
+call_avp_subdissector(guint32 vendorid, guint32 code, tvbuff_t *subtvb, packet_info *pinfo, proto_tree *avp_tree)
+{
+ TRY {
+ switch (vendorid) {
+ case 0:
+ dissector_try_uint(diameter_dissector_table, code, subtvb, pinfo, avp_tree);
+ break;
+ case VENDOR_ERICSSON:
+ dissector_try_uint(diameter_ericsson_avp_dissector_table, code, subtvb, pinfo, avp_tree);
+ break;
+ case VENDOR_THE3GPP:
+ dissector_try_uint(diameter_3gpp_avp_dissector_table, code, subtvb, pinfo, avp_tree);
+ break;
+ default:
+ break;
+ }
+
+ /* Debug
+ proto_tree_add_text(avp_tree, subtvb, 0, -1, "AVP %u data, Vendor Id %u ",code,vendorid);
+ */
+ }
+ CATCH_NONFATAL_ERRORS {
+ show_exception(subtvb, pinfo, avp_tree, EXCEPT_CODE, GET_MESSAGE);
+ }
+ ENDTRY;
+}
+
/* Dissect an AVP at offset */
static int
dissect_diameter_avp(diam_ctx_t *c, tvbuff_t *tvb, int offset)
@@ -533,23 +567,7 @@ dissect_diameter_avp(diam_ctx_t *c, tvbuff_t *tvb, int offset)
if (avp_str) proto_item_append_text(avp_item," val=%s", avp_str);
- /* Call subdissectors for AVPs */
- switch (vendorid) {
- case 0:
- dissector_try_uint(diameter_dissector_table, code, subtvb, c->pinfo, avp_tree);
- break;
- case VENDOR_ERICSSON:
- dissector_try_uint(diameter_ericsson_avp_dissector_table, code, subtvb, c->pinfo, avp_tree);
- break;
- case VENDOR_THE3GPP:
- dissector_try_uint(diameter_3gpp_avp_dissector_table, code, subtvb, c->pinfo, avp_tree);
- break;
- default:
- break;
- }
- /* Debug
- proto_tree_add_text(avp_tree, subtvb, 0, -1, "AVP %u data, Vendor Id %u ",code,vendorid);
- */
+ call_avp_subdissector(vendorid, code, subtvb, c->pinfo, avp_tree);
if (pad_len) {
guint8 i;
@@ -616,7 +634,13 @@ proto_avp(diam_ctx_t *c, diam_avp_t *a, tvbuff_t *tvb)
if(!t->handle) t->handle = data_handle;
}
- call_dissector(t->handle, tvb, c->pinfo, c->tree);
+ TRY {
+ call_dissector(t->handle, tvb, c->pinfo, c->tree);
+ }
+ CATCH_NONFATAL_ERRORS {
+ show_exception(tvb, c->pinfo, c->tree, EXCEPT_CODE, GET_MESSAGE);
+ }
+ ENDTRY;
return "";
}