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

svn path=/trunk/; revision=22889
This commit is contained in:
Stig Bjørlykke 2007-09-17 14:10:34 +00:00
parent c50da9f742
commit 4ab93c6602
2 changed files with 182 additions and 23 deletions

View File

@ -2664,7 +2664,7 @@ Karen Feng <kfeng [AT] fas.harvard.edu> {
802.1ad and 802.1ah support
}
Stephen Croll <croll@mobilemetrics.net> {
Stephen Croll <croll [AT] mobilemetrics.net> {
WiMAX ASN Control Plane dissection
}
@ -2809,6 +2809,7 @@ Joe Eykholt <joe [AT] nuovasystems.com>
Ian Brumby <ian.brumby [AT] baesystems.com>
Todd J Martin <todd.martin [AT] acm.org>
Scott Robinson <scott.robinson [AT] flukenetworks.com>
Martin Peylo <wireshark [AT] izac.de>
Alain Magloire <alainm[AT]rcsm.ece.mcgill.ca> was kind enough to
give his permission to use his version of snprintf.c.

View File

@ -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