aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-tipc.c
diff options
context:
space:
mode:
authorstig <stig@f5534014-38df-0310-8fa8-9805f1628bb7>2007-09-17 14:10:34 +0000
committerstig <stig@f5534014-38df-0310-8fa8-9805f1628bb7>2007-09-17 14:10:34 +0000
commit877c1045fa1fa7812cc4605764966ea2ce5c6803 (patch)
treea421a7e8c297cafaaeb2b83b8f5d56fae156c554 /epan/dissectors/packet-tipc.c
parenta34edfa87077d7db4182a535324dbf327d80863a (diff)
From Martin Peylo:
- reassembling of fragmented TIPCv2 messages - calling of heuristic subdissectors - multicast upper+lower bound header fields are now shown - corrects few typos in the comments in packet-tipc.c git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@22889 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors/packet-tipc.c')
-rw-r--r--epan/dissectors/packet-tipc.c202
1 files changed, 180 insertions, 22 deletions
diff --git a/epan/dissectors/packet-tipc.c b/epan/dissectors/packet-tipc.c
index bc27f12aee..185cc4f1be 100644
--- a/epan/dissectors/packet-tipc.c
+++ b/epan/dissectors/packet-tipc.c
@@ -6,7 +6,7 @@
* Copyright 2005-2006, Anders Broman <anders.broman@ericsson.com>
*
* TIPCv2 protocol updates
- * Copyright 2006-2007, Martin Peylo <martin.peylo@nsn.com>
+ * Copyright 2006-2007, Martin Peylo <wireshark@izac.de>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
@@ -126,6 +126,8 @@ static int hf_tipcv2_orig_node = -1;
static int hf_tipcv2_dest_node = -1;
static int hf_tipcv2_port_name_type = -1;
static int hf_tipcv2_port_name_instance = -1;
+static int hf_tipcv2_multicast_lower = -1;
+static int hf_tipcv2_multicast_upper = -1;
static int hf_tipcv2_bcast_seq_gap = -1;
static int hf_tipcv2_sequence_gap = -1;
@@ -164,6 +166,7 @@ static gint ett_tipc_data = -1;
static gboolean tipc_defragment = TRUE;
static gboolean dissect_tipc_data = TRUE;
+static gboolean try_heuristic_first = FALSE;
static gboolean extra_ethertype = FALSE;
@@ -175,6 +178,8 @@ static dissector_handle_t ip_handle;
static dissector_table_t tipc_user_dissector;
static dissector_table_t tipc_type_dissector;
+static heur_dissector_list_t tipc_heur_subdissector_list;
+
static dissector_handle_t data_handle;
static proto_tree *top_tree;
@@ -247,6 +252,10 @@ const value_string tipc_user_values[] = {
#define TIPCv2_MSG_FRAGMENTER 12
#define TIPCv2_NEIGHBOUR_DISCOVERY 13
+#define TIPCv2_USER_FIRST_FRAGMENT 0
+#define TIPCv2_USER_FRAGMENT 1
+#define TIPCv2_USER_LAST_FRAGMENT 2
+
const value_string tipcv2_user_values[] = {
{ TIPCv2_DATA_LOW, "Low Priority Payload Data"},
{ TIPCv2_DATA_NORMAL, "Normal Priority Payload Data"},
@@ -715,7 +724,6 @@ tipc_v1_set_col_msgtype(packet_info *pinfo, guint8 user,guint8 msg_type){
static void
dissect_tipc_v2_internal_msg(tvbuff_t *tipc_tvb, proto_tree *tipc_tree, packet_info *pinfo, int offset, guint8 user, guint32 msg_size, guint8 orig_hdr_size)
{
-
guint32 dword;
gchar *addr_str_ptr;
tvbuff_t *data_tvb;
@@ -724,6 +732,13 @@ dissect_tipc_v2_internal_msg(tvbuff_t *tipc_tvb, proto_tree *tipc_tree, packet_i
guint msg_no = 0;
guint32 msg_in_bundle_size;
+ /* for fragmented messages */
+ gint len, reported_len;
+ gboolean save_fragmented;
+ guint32 frag_no, frag_msg_no;
+ tvbuff_t* new_tvb = NULL;
+ fragment_data *frag_msg = NULL;
+
dword = tvb_get_ntohl(tipc_tvb,offset+8);
addr_str_ptr = tipc_addr_to_str(dword);
message_type = (tvb_get_guint8(tipc_tvb,offset) >>5) & 0x7;
@@ -857,7 +872,7 @@ dissect_tipc_v2_internal_msg(tvbuff_t *tipc_tvb, proto_tree *tipc_tree, packet_i
proto_tree_add_item(tipc_tree, hf_tipcv2_lookup_scope, tipc_tvb, offset, 4, FALSE);
/* Options Position: 3 bits */
- /* is this not used by this user according to Jon Maloy in tipc-discussion mailing list
+ /* this is not used by this user according to Jon Maloy in tipc-discussion mailing list
opt_p = tvb_get_guint8(tipc_tvb, offset+1) & 0x7;
proto_tree_add_item(tipc_tree, hf_tipcv2_opt_p , tipc_tvb, offset, 4, FALSE);
if (opt_p != 0){
@@ -902,7 +917,7 @@ dissect_tipc_v2_internal_msg(tvbuff_t *tipc_tvb, proto_tree *tipc_tree, packet_i
proto_tree_add_item(tipc_tree, hf_tipcv2_transport_seq_no, tipc_tvb, offset, 4, FALSE);
offset = offset + 4;
- /* is this not used here according to Jon Maloy in tipc-discussion mailing list
+ /* this is not used here according to Jon Maloy in tipc-discussion mailing list
* Options
if (opt_p != 0){
@@ -1054,14 +1069,71 @@ dissect_tipc_v2_internal_msg(tvbuff_t *tipc_tvb, proto_tree *tipc_tree, packet_i
proto_tree_add_string(tipc_tree, hf_tipcv2_prev_node, tipc_tvb, offset, 4, addr_str_ptr);
offset = offset + 4;
/* W4 */
+ dword = tvb_get_ntohl(tipc_tvb,offset);
/* Fragment Number: 16 Bits. */
proto_tree_add_item(tipc_tree, hf_tipcv2_fragment_number, tipc_tvb, offset, 4, FALSE);
+ frag_no = (dword >> 16) & 0x0000ffff;
/* Fragment msg Number: 16 bits */
proto_tree_add_item(tipc_tree, hf_tipcv2_fragment_msg_number, tipc_tvb, offset, 4, FALSE);
+ frag_msg_no = dword & 0x0000ffff;
offset = offset + 4;
/* W5-W9 */
proto_tree_add_text(tipc_tree, tipc_tvb, offset, 20,"Words 5-9 Unused for this user");
offset = offset + 20;
+
+ len = (msg_size - (orig_hdr_size<<2));
+ reported_len = tvb_reported_length_remaining(tipc_tvb, offset);
+
+ if (tipc_defragment){
+ /* reassemble fragmented packages */
+ save_fragmented = pinfo->fragmented;
+ pinfo->fragmented = TRUE;
+
+ frag_msg = fragment_add_seq_check(tipc_tvb, offset, pinfo,
+ frag_msg_no, /* ID for fragments belonging together */
+ /* TODO: make sure that fragments are on the same LINK */
+ tipc_msg_fragment_table, /* list of message fragments */
+ tipc_msg_reassembled_table, /* list of reassembled messages */
+ /* TIPC starts with "1" but we * need "0" */
+ (frag_no-1), /* number of the fragment */
+ len, /* fragment length - to the end of the data */
+ (message_type != TIPCv2_USER_LAST_FRAGMENT)); /* More fragments? */
+
+ new_tvb = process_reassembled_data(tipc_tvb, offset, pinfo,
+ "Reassembled Message", frag_msg, &tipc_msg_frag_items,
+ NULL, tipc_tree);
+
+ if (frag_msg) { /* Reassembled */
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_str(pinfo->cinfo, COL_INFO,
+ " (Message Reassembled)");
+ } else { /* Not last packet of reassembled Short Message */
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ " (Message fragment %u)", frag_no);
+ }
+ if (new_tvb) { /* take it all */
+ data_tvb = new_tvb;
+
+ /* the info column shall not be deleted by the
+ * encapsulated messages */
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_append_str(pinfo->cinfo, COL_INFO, " | ");
+ col_set_fence(pinfo->cinfo, COL_INFO);
+ }
+ dissect_tipc( new_tvb, pinfo, top_tree);
+ } else { /* make a new subset */
+ data_tvb = tvb_new_subset(tipc_tvb, offset, len, reported_len);
+ call_dissector(data_handle, data_tvb, pinfo, top_tree);
+ }
+
+ pinfo->fragmented = save_fragmented;
+ } else {
+ /* don't reassemble is set in the "preferences" */
+ data_tvb = tvb_new_subset(tipc_tvb, offset, len, reported_len);
+ call_dissector(data_handle, data_tvb, pinfo, top_tree);
+ }
+
break;
case TIPCv2_NEIGHBOUR_DISCOVERY:
/*
@@ -1171,6 +1243,76 @@ wA:| multicast upper bound |
*/
+/* this function tries to call subdissectors for encapsulated data
+ * @name_type pointer to the used port name type, NULL if not available
+ * @user guint8 holding the used TIPC user, is allways available
+ */
+static void
+call_tipc_v2_data_subdissectors(tvbuff_t *data_tvb, packet_info *pinfo, guint32 *name_type_p, guint8 user)
+{
+ if( dissect_tipc_data) {
+ /* dissection of TIPC data is set in preferences */
+
+ /* check for heuristic dissectors if specified in the
+ * preferences to try them first */
+ if (try_heuristic_first) {
+ if (dissector_try_heuristic(tipc_heur_subdissector_list, data_tvb, pinfo, top_tree))
+ return;
+ }
+ /* This triggers if a dissectors if
+ * tipc.user is just set to a TIPC user holding data */
+ if( dissector_try_port(tipc_user_dissector, user, data_tvb, pinfo, top_tree))
+ return;
+ /* The Name Type is not always explicitly set in a TIPC Data
+ * Message.
+ *
+ * On the tipc-discussion mailinglist, Allan Stephens described
+ * where the Port Name is not set with the following words:
+ *
+ * <cite>
+ * The "named" and "mcast" message types have info in the TIPC header to
+ * specify the message's destination (a port name and port name sequence,
+ * respectively); these message types typically occur when an application
+ * sends connectionless traffic. The "conn" type is used to carry
+ * connection-oriented traffic over an already established connection;
+ * since the sending socket/port already knows the port ID of the other end
+ * of the connection, there is no need for any port name information to be
+ * present in the TIPC header.
+ *
+ * The "direct" type is used to carry connectionless traffic to a
+ * destination that was specified using a port ID, rather than a port name;
+ * again, no port name info is present in the TIPC header because it is not
+ * required. Situations where this sort of message might be generated
+ * include: a) an application obtains a port ID as part of a subscription
+ * event generated by TIPC's topology server and then sends a message to
+ * that port ID (using sendto() or sendmsg()), and b) a server obtains a
+ * client's port ID when it receives a message from the client (using
+ * recvfrom() or recvmsg()) and then sends a reply back to that client port
+ * ID (using sendto() or sendmsg()).
+ * </cite>
+ *
+ * TODO: it should be determined by
+ * some kind of static function which port name type a message
+ * is going to, if it is not specified explicitly in a message */
+ if( name_type_p)
+ if( dissector_try_port(tipc_type_dissector, *name_type_p, data_tvb, pinfo, top_tree))
+ return;
+ /* check for heuristic dissectors if specified in the
+ * preferences not to try them first */
+ if (!try_heuristic_first) {
+ if (dissector_try_heuristic(tipc_heur_subdissector_list, data_tvb, pinfo, top_tree))
+ return;
+ }
+ }
+
+ /* dissection of TIPC data is not set in preferences or no subdissector
+ * found */
+
+ call_dissector(data_handle, data_tvb, pinfo, top_tree);
+ return;
+}
+
+
static void
dissect_tipc_v2(tvbuff_t *tipc_tvb, proto_tree *tipc_tree, packet_info *pinfo, int offset, guint8 user, guint32 msg_size, guint8 hdr_size, gboolean datatype_hdr)
{
@@ -1181,7 +1323,8 @@ dissect_tipc_v2(tvbuff_t *tipc_tvb, proto_tree *tipc_tree, packet_info *pinfo, i
/* The unit used is 32 bit words */
guint8 orig_hdr_size;
- guint32 type=0;
+ guint32 name_type=0;
+ guint32 *name_type_p=NULL;
tvbuff_t *data_tvb;
gint len, reported_len;
@@ -1273,19 +1416,26 @@ dissect_tipc_v2(tvbuff_t *tipc_tvb, proto_tree *tipc_tree, packet_info *pinfo, i
/* Transport Level Sequence Number: 32 bits */
/* Port Name Type: 32 bits */
proto_tree_add_item(tipc_tree, hf_tipcv2_port_name_type, tipc_tvb, offset, 4, FALSE);
- type = tvb_get_ntohl(tipc_tvb, offset);
+ name_type = tvb_get_ntohl(tipc_tvb, offset);
+ name_type_p = &name_type;
offset = offset + 4;
if (hdr_size > 9 ){
/* W9 name instance/multicast lower bound */
- /* Port Name Instance: 32 bits */
- proto_tree_add_item(tipc_tree, hf_tipcv2_port_name_instance, tipc_tvb, offset, 4, FALSE);
- /* Port Name Sequence Lower: 32 bits */
+ if (hdr_size < 11)
+ /* no multicast */
+ /* Port Name Instance: 32 bits */
+ proto_tree_add_item(tipc_tree, hf_tipcv2_port_name_instance, tipc_tvb, offset, 4, FALSE);
+ else
+ /* multicast */
+ /* Port Name Sequence Lower: 32 bits */
+ proto_tree_add_item(tipc_tree, hf_tipcv2_multicast_lower, tipc_tvb, offset, 4, FALSE);
offset = offset + 4;
if (hdr_size > 10 ){
/* W10 multicast upper bound */
/* Port Name Sequence Upper: 32 bits */
+ proto_tree_add_item(tipc_tree, hf_tipcv2_multicast_upper, tipc_tvb, offset, 4, FALSE);
offset = offset + 4;
}
}
@@ -1300,18 +1450,8 @@ dissect_tipc_v2(tvbuff_t *tipc_tvb, proto_tree *tipc_tree, packet_info *pinfo, i
len = (msg_size - (orig_hdr_size<<2));
reported_len = tvb_reported_length_remaining(tipc_tvb, offset);
data_tvb = tvb_new_subset(tipc_tvb, offset, len, reported_len);
- if( dissect_tipc_data) {
- /* This e.g. triggers if a dissectors if the
- * tipc.user is just set to TIPC data */
- if( dissector_try_port(tipc_user_dissector, user, data_tvb, pinfo, top_tree))
- return;
- /* XXX To make this work, it actually should be determined by
- * some kind of momory function which port name type a message
- * is going to if it is not specified explicitly in a message */
- if( dissector_try_port(tipc_type_dissector, type, data_tvb, pinfo, top_tree))
- return;
- }
- call_dissector(data_handle, data_tvb, pinfo, top_tree);
+
+ call_tipc_v2_data_subdissectors( data_tvb, pinfo, name_type_p, user);
}
/* From message.h (http://cvs.sourceforge.net/viewcvs.py/tipc/source/stable_ericsson/TIPC_SCC/src/Message.h?rev=1.2&view=markup)
@@ -1497,7 +1637,7 @@ dissect_tipc_int_prot_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tipc_tr
TRUE); /* More fragments? */
if (msg_type == TIPC_FIRST_SEGMENT ){
reassembled_msg_length = tvb_get_ntohl(tvb,offset) & 0x1ffff;
- /* The number of segments needed fot he complete message (Including header) will be
+ /* The number of segments needed for he complete message (Including header) will be
* The size of the data section of the first message, divided by the complete message size
* + one segment for the remainder (if any).
*/
@@ -2234,6 +2374,16 @@ proto_register_tipc(void)
FT_UINT32, BASE_DEC, NULL, 0xffffffff,
"Port name instance", HFILL }
},
+ { &hf_tipcv2_multicast_lower,
+ { "Multicast lower bound", "tipcv2.multicast_lower",
+ FT_UINT32, BASE_DEC, NULL, 0xffffffff,
+ "Multicast port name instance lower bound", HFILL }
+ },
+ { &hf_tipcv2_multicast_upper,
+ { "Multicast upper bound", "tipcv2.multicast_upper",
+ FT_UINT32, BASE_DEC, NULL, 0xffffffff,
+ "Multicast port name instance upper bound", HFILL }
+ },
{ &hf_tipcv2_bcast_seq_gap,
{ "Broadcast Sequence Gap", "tipcv2.bcast_seq_gap",
FT_UINT32, BASE_DEC, NULL, 0x1F000000,
@@ -2396,6 +2546,9 @@ proto_register_tipc(void)
tipc_type_dissector = register_dissector_table("tipcv2.port_name_type",
"TIPC port name type", FT_UINT32, BASE_DEC);
+ /* make heuristic dissectors possible */
+ register_heur_dissector_list("tipc", &tipc_heur_subdissector_list);
+
register_init_routine(tipc_defragment_init);
/* Register configuration options */
@@ -2410,6 +2563,11 @@ proto_register_tipc(void)
"Dissect TIPC data",
"Whether to try to dissect TIPC data or not",
&dissect_tipc_data);
+
+ prefs_register_bool_preference(tipc_module, "try_heuristic_first",
+ "Try heuristic sub-dissectors first",
+ "Try to decode a TIPCv2 packet using an heuristic sub-dissector before using a registered sub-dissector",
+ &try_heuristic_first);
}
void