aboutsummaryrefslogtreecommitdiffstats
path: root/epan/packet.c
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2005-05-11 10:40:53 +0000
committerRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2005-05-11 10:40:53 +0000
commitfcab322ada6b72863c18bfbf92cb7324c312529a (patch)
tree4a98b2534f93e14a8a47f11a20fb930fed85b87f /epan/packet.c
parente3e4f52245627029b832875a5bbf438350484678 (diff)
Some applications do very naughty things like reusing a port for a different protocol during different stages of an application cycle.
This is very naughty and will cause problems when we have assigned a dissector to a dynamic port using conversation_set_dissector(). To make ethereal handle this case I have changed the try_conversation_dissector() to allow it to fail and return 0, meaning yes there is indeed a protocol registered for this conversation but that protocol rejected this packet. (which only happens for "new" style dissectors, "old" style dissectors will never reject a packet that way) When this happens the decode_udp_port() helper will still allow other dissectors to be tried, in the hope that the conversation is now used for some other protocol and thus someone else might be able to decode the packet. Update SNMP and TFTP dissectors to check that even if there already is a conversation but that conversation does NOT have snmp/tftp registered as the dissector for it, then create a new conversation anyway and attach the proper dissector. Since ethereal keeps track of which frame number a conversation started in, this actually works really well. svn path=/trunk/; revision=14345
Diffstat (limited to 'epan/packet.c')
-rw-r--r--epan/packet.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/epan/packet.c b/epan/packet.c
index 9f2ca913fb..a012ef7c2d 100644
--- a/epan/packet.c
+++ b/epan/packet.c
@@ -365,6 +365,16 @@ struct dissector_handle {
protocol_t *protocol;
};
+/* This function will return
+ * old style dissector :
+ * length of the payload or 1 of the payload is empty
+ * new dissector :
+ * >0 this protocol was successfully dissected and this was this protocol.
+ * 0 this packet did not match this protocol.
+ *
+ * The only time this function will return 0 is if it is a new style dissector
+ * and if the dissector rejected the packet.
+ */
static int
call_dissector_through_handle(dissector_handle_t handle, tvbuff_t *tvb,
packet_info *pinfo, proto_tree *tree)
@@ -379,9 +389,9 @@ call_dissector_through_handle(dissector_handle_t handle, tvbuff_t *tvb,
proto_get_protocol_short_name(handle->protocol);
}
- if (handle->is_new)
+ if (handle->is_new) {
ret = (*handle->dissector.new)(tvb, pinfo, tree);
- else {
+ } else {
(*handle->dissector.old)(tvb, pinfo, tree);
ret = tvb_length(tvb);
if (ret == 0) {
@@ -1691,7 +1701,9 @@ new_register_dissector(const char *name, new_dissector_t dissector, int proto)
(gpointer) handle);
}
-/* Call a dissector through a handle. */
+/* Call a dissector through a handle and if this fails call the "data"
+ * dissector.
+ */
int
call_dissector(dissector_handle_t handle, tvbuff_t *tvb,
packet_info *pinfo, proto_tree *tree)
@@ -1712,6 +1724,19 @@ call_dissector(dissector_handle_t handle, tvbuff_t *tvb,
return ret;
}
+/* Call a dissector through a handle but if the dissector rejected it
+ * return 0 instead of using the default "data" dissector.
+ */
+int
+call_dissector_only(dissector_handle_t handle, tvbuff_t *tvb,
+ packet_info *pinfo, proto_tree *tree)
+{
+ int ret;
+
+ ret = call_dissector_work(handle, tvb, pinfo, tree);
+ return ret;
+}
+
/*
* Dumps the "layer type"/"decode as" associations to stdout, similar
* to the proto_registrar_dump_*() routines.