summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packet-atalk.c8
-rw-r--r--packet-clnp.c4
-rw-r--r--packet-dcerpc.c4
-rw-r--r--packet-eap.c4
-rw-r--r--packet-ieee80211.c4
-rw-r--r--packet-ip.c4
-rw-r--r--packet-ipv6.c4
-rw-r--r--packet-netbios.c376
-rw-r--r--packet-rpc.c4
-rw-r--r--packet-smb-pipe.c4
-rw-r--r--packet-smb.c4
-rw-r--r--packet-wtp.c4
-rw-r--r--reassemble.c79
-rw-r--r--reassemble.h21
14 files changed, 406 insertions, 118 deletions
diff --git a/packet-atalk.c b/packet-atalk.c
index 4790a40afd..45ea847a93 100644
--- a/packet-atalk.c
+++ b/packet-atalk.c
@@ -2,7 +2,7 @@
* Routines for AppleTalk packet disassembly: LLAP, DDP, NBP, ATP, ASP,
* RTMP.
*
- * $Id: packet-atalk.c,v 1.82 2002/10/17 22:38:19 guy Exp $
+ * $Id: packet-atalk.c,v 1.83 2002/10/24 06:17:28 guy Exp $
*
* Simon Wilkinson <sxw@dcs.ed.ac.uk>
*
@@ -335,7 +335,7 @@ static gint ett_ddp = -1;
static gint ett_llap = -1;
static gint ett_pstring = -1;
-fragment_items atp_frag_items = {
+static const fragment_items atp_frag_items = {
&ett_atp_segment,
&ett_atp_segments,
&hf_atp_segments,
@@ -1940,7 +1940,7 @@ proto_register_atalk(void)
NULL, 0x0, "Segment overlaps with other segments", HFILL }},
{ &hf_atp_segment_overlap_conflict,
- { "Conflicting data in seagment overlap", "atp.segment.overlap.conflict",
+ { "Conflicting data in segment overlap", "atp.segment.overlap.conflict",
FT_BOOLEAN, BASE_NONE,
NULL, 0x0, "Overlapping segments contained conflicting data", HFILL }},
@@ -1954,7 +1954,7 @@ proto_register_atalk(void)
NULL, 0x0, "Segment contained data past end of packet", HFILL }},
{ &hf_atp_segment_error,
- {" Desegmentation error", "atp.segment.error", FT_NONE, BASE_NONE,
+ {"Desegmentation error", "atp.segment.error", FT_NONE, BASE_NONE,
NULL, 0x0, "Desegmentation error due to illegal segments", HFILL }},
{ &hf_atp_segment,
diff --git a/packet-clnp.c b/packet-clnp.c
index 228b899928..47590edcf6 100644
--- a/packet-clnp.c
+++ b/packet-clnp.c
@@ -1,7 +1,7 @@
/* packet-clnp.c
* Routines for ISO/OSI network and transport protocol packet disassembly
*
- * $Id: packet-clnp.c,v 1.59 2002/08/28 21:00:08 jmayer Exp $
+ * $Id: packet-clnp.c,v 1.60 2002/10/24 06:17:34 guy Exp $
* Laurent Deniel <deniel@worldnet.fr>
* Ralf Schneider <Ralf.Schneider@t-online.de>
*
@@ -73,7 +73,7 @@ static int hf_clnp_segment_multiple_tails = -1;
static int hf_clnp_segment_too_long_segment = -1;
static int hf_clnp_segment_error = -1;
-fragment_items clnp_frag_items = {
+static const fragment_items clnp_frag_items = {
&ett_clnp_segment,
&ett_clnp_segments,
&hf_clnp_segments,
diff --git a/packet-dcerpc.c b/packet-dcerpc.c
index 2d78e52b48..d18d440087 100644
--- a/packet-dcerpc.c
+++ b/packet-dcerpc.c
@@ -2,7 +2,7 @@
* Routines for DCERPC packet disassembly
* Copyright 2001, Todd Sabin <tas@webspan.net>
*
- * $Id: packet-dcerpc.c,v 1.81 2002/10/23 03:49:10 guy Exp $
+ * $Id: packet-dcerpc.c,v 1.82 2002/10/24 06:17:34 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -406,7 +406,7 @@ static gint ett_decrpc_krb5_auth_verf = -1;
static dissector_handle_t ntlmssp_handle, gssapi_handle;
-fragment_items dcerpc_frag_items = {
+static const fragment_items dcerpc_frag_items = {
&ett_dcerpc_fragments,
&ett_dcerpc_fragment,
diff --git a/packet-eap.c b/packet-eap.c
index 7bd71f33c3..6877341601 100644
--- a/packet-eap.c
+++ b/packet-eap.c
@@ -2,7 +2,7 @@
* Routines for EAP Extensible Authentication Protocol dissection
* RFC 2284
*
- * $Id: packet-eap.c,v 1.30 2002/09/08 00:07:40 guy Exp $
+ * $Id: packet-eap.c,v 1.31 2002/10/24 06:17:34 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -194,7 +194,7 @@ static int hf_eaptls_fragment_error = -1;
static gint ett_eaptls_fragment = -1;
static gint ett_eaptls_fragments = -1;
-fragment_items eaptls_frag_items = {
+static const fragment_items eaptls_frag_items = {
&ett_eaptls_fragment,
&ett_eaptls_fragments,
&hf_eaptls_fragments,
diff --git a/packet-ieee80211.c b/packet-ieee80211.c
index ed6129f44e..88eb0f3ec0 100644
--- a/packet-ieee80211.c
+++ b/packet-ieee80211.c
@@ -3,7 +3,7 @@
* Copyright 2000, Axis Communications AB
* Inquiries/bugreports should be sent to Johan.Jorgensen@axis.com
*
- * $Id: packet-ieee80211.c,v 1.75 2002/10/21 19:05:21 guy Exp $
+ * $Id: packet-ieee80211.c,v 1.76 2002/10/24 06:17:34 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -385,7 +385,7 @@ static gint ett_fixed_parameters = -1;
static gint ett_tagged_parameters = -1;
static gint ett_wep_parameters = -1;
-fragment_items frag_items = {
+static const fragment_items frag_items = {
&ett_fragment,
&ett_fragments,
&hf_fragments,
diff --git a/packet-ip.c b/packet-ip.c
index 9ec5ce89d0..a6a1edb929 100644
--- a/packet-ip.c
+++ b/packet-ip.c
@@ -1,7 +1,7 @@
/* packet-ip.c
* Routines for IP and miscellaneous IP protocol packet disassembly
*
- * $Id: packet-ip.c,v 1.174 2002/10/18 20:59:57 guy Exp $
+ * $Id: packet-ip.c,v 1.175 2002/10/24 06:17:34 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -106,7 +106,7 @@ static gint ett_ip_option_timestamp = -1;
static gint ett_ip_fragments = -1;
static gint ett_ip_fragment = -1;
-fragment_items ip_frag_items = {
+static const fragment_items ip_frag_items = {
&ett_ip_fragment,
&ett_ip_fragments,
&hf_ip_fragments,
diff --git a/packet-ipv6.c b/packet-ipv6.c
index eb8a41ec7c..64b57a08c8 100644
--- a/packet-ipv6.c
+++ b/packet-ipv6.c
@@ -1,7 +1,7 @@
/* packet-ipv6.c
* Routines for IPv6 packet disassembly
*
- * $Id: packet-ipv6.c,v 1.88 2002/10/22 22:04:21 jmayer Exp $
+ * $Id: packet-ipv6.c,v 1.89 2002/10/24 06:17:34 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -94,7 +94,7 @@ static gint ett_ipv6 = -1;
static gint ett_ipv6_fragments = -1;
static gint ett_ipv6_fragment = -1;
-fragment_items ipv6_frag_items = {
+static const fragment_items ipv6_frag_items = {
&ett_ipv6_fragment,
&ett_ipv6_fragments,
&hf_ipv6_fragments,
diff --git a/packet-netbios.c b/packet-netbios.c
index 431062ad8b..8fcd7e8a46 100644
--- a/packet-netbios.c
+++ b/packet-netbios.c
@@ -5,7 +5,7 @@
*
* derived from the packet-nbns.c
*
- * $Id: packet-netbios.c,v 1.51 2002/08/28 21:00:23 jmayer Exp $
+ * $Id: packet-netbios.c,v 1.52 2002/10/24 06:17:34 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -36,7 +36,8 @@
#include <epan/packet.h>
#include "llcsaps.h"
-#include "packet-tr.h"
+#include "reassemble.h"
+#include "prefs.h"
#include "packet-netbios.h"
/* Netbios command numbers */
@@ -105,11 +106,33 @@ static int hf_netb_local_ses_no = -1;
static int hf_netb_remote_ses_no = -1;
static int hf_netb_data1 = -1;
static int hf_netb_data2 = -1;
+static int hf_netb_fragments = -1;
+static int hf_netb_fragment = -1;
+static int hf_netb_fragment_overlap = -1;
+static int hf_netb_fragment_overlap_conflict = -1;
+static int hf_netb_fragment_multiple_tails = -1;
+static int hf_netb_fragment_too_long_segment = -1;
+static int hf_netb_fragment_error = -1;
static gint ett_netb = -1;
static gint ett_netb_name = -1;
static gint ett_netb_flags = -1;
static gint ett_netb_status = -1;
+static gint ett_netb_fragments = -1;
+static gint ett_netb_fragment = -1;
+
+fragment_items netbios_frag_items = {
+ &ett_netb_fragment,
+ &ett_netb_fragments,
+ &hf_netb_fragments,
+ &hf_netb_fragment,
+ &hf_netb_fragment_overlap,
+ &hf_netb_fragment_overlap_conflict,
+ &hf_netb_fragment_multiple_tails,
+ &hf_netb_fragment_too_long_segment,
+ &hf_netb_fragment_error,
+ "fragments"
+};
static dissector_handle_t data_handle;
@@ -155,6 +178,13 @@ static const value_string nb_name_type_vals[] = {
{0x00, NULL}
};
+/* Tables for reassembly of fragments. */
+static GHashTable *netbios_fragment_table = NULL;
+static GHashTable *netbios_reassembled_table = NULL;
+
+/* desegmentation of NetBIOS Frame */
+static gboolean netbios_defragment = TRUE;
+
/* See
http://www.s390.ibm.com/bookmgr-cgi/bookmgr.cmd/BOOKS/BK8P7001/CCONTENTS
@@ -206,7 +236,7 @@ static const true_false_string flags_set = {
};
static const true_false_string flags_allowed = {
"Allowed",
- "Not allowrd"
+ "Not allowed"
};
static const true_false_string flags_yes_no = {
"Yes",
@@ -469,23 +499,29 @@ static void nb_call_name_type( tvbuff_t *tvb, int offset, proto_tree *tree)
}
-static void nb_local_session( tvbuff_t *tvb, int offset, proto_tree *tree)
+static guint8 nb_local_session( tvbuff_t *tvb, int offset, proto_tree *tree)
-{/* add the local session to tree */
+{/* add the local session to tree, and return its value */
+
+ guint8 local_session = tvb_get_guint8( tvb, offset + NB_LOCAL_SES);
proto_tree_add_uint( tree, hf_netb_local_ses_no, tvb, offset + NB_LOCAL_SES, 1,
- tvb_get_guint8( tvb, offset + NB_LOCAL_SES));
+ local_session);
+ return local_session;
}
-static void nb_remote_session( tvbuff_t *tvb, int offset, proto_tree *tree)
+static guint8 nb_remote_session( tvbuff_t *tvb, int offset, proto_tree *tree)
+
+{/* add the remote session to tree, and return its value */
-{/* add the remote session to tree */
+ guint8 remote_session = tvb_get_guint8( tvb, offset + NB_RMT_SES);
proto_tree_add_uint( tree, hf_netb_remote_ses_no, tvb, offset + NB_RMT_SES, 1,
- tvb_get_guint8( tvb, offset + NB_RMT_SES));
+ remote_session);
+ return remote_session;
}
@@ -537,17 +573,20 @@ static void nb_resync_indicator( tvbuff_t *tvb, int offset, proto_tree *tree, ch
/* */
/************************************************************************/
-static void dissect_netb_unknown( tvbuff_t *tvb, int offset, proto_tree *tree)
+static guint32
+dissect_netb_unknown( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle any unknown commands, do nothing */
proto_tree_add_text(tree, tvb, offset + NB_COMMAND + 1, -1,
"Unknown NetBIOS command data");
+
+ return 0;
}
-static void dissect_netb_add_group_name( tvbuff_t *tvb, int offset,
- proto_tree *tree)
+static guint32
+dissect_netb_add_group_name( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the ADD GROUP NAME QUERY command */
@@ -555,32 +594,39 @@ static void dissect_netb_add_group_name( tvbuff_t *tvb, int offset,
netbios_add_name("Group name to add", tvb, offset + NB_SENDER_NAME,
tree);
+
+ return 0;
}
-static void dissect_netb_add_name( tvbuff_t *tvb, int offset,
- proto_tree *tree)
+static guint32
+dissect_netb_add_name( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the ADD NAME QUERY command */
nb_resp_corrl( tvb, offset, tree);
netbios_add_name("Name to add", tvb, offset + NB_SENDER_NAME, tree);
+
+ return 0;
}
-static void dissect_netb_name_in_conflict( tvbuff_t *tvb, int offset,
- proto_tree *tree)
+static guint32
+dissect_netb_name_in_conflict( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the NAME IN CONFLICT command */
netbios_add_name("Name In Conflict", tvb, offset + NB_RECVER_NAME,
tree);
netbios_add_name("Sender's Name", tvb, offset + NB_SENDER_NAME, tree);
+
+ return 0;
}
-static void dissect_netb_status_query( tvbuff_t *tvb, int offset, proto_tree *tree)
+static guint32
+dissect_netb_status_query( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the STATUS QUERY command */
@@ -608,11 +654,13 @@ static void dissect_netb_status_query( tvbuff_t *tvb, int offset, proto_tree *t
nb_resp_corrl( tvb, offset, tree);
netbios_add_name("Receiver's Name", tvb, offset + NB_RECVER_NAME, tree);
netbios_add_name("Sender's Name", tvb, offset + NB_SENDER_NAME, tree);
+
+ return 0;
}
-static void dissect_netb_terminate_trace( tvbuff_t *tvb _U_, int offset _U_,
- proto_tree *tree _U_)
+static guint32
+dissect_netb_terminate_trace( tvbuff_t *tvb _U_, int offset _U_, proto_tree *tree _U_)
{/* Handle the TERMINATE TRACE command */
@@ -620,12 +668,15 @@ static void dissect_netb_terminate_trace( tvbuff_t *tvb _U_, int offset _U_,
* XXX - are any of the fields in this message significant?
* The IBM NetBIOS document shows them as "Reserved".
*/
+
+ return 0;
}
static guchar zeroes[10];
-static void dissect_netb_datagram( tvbuff_t *tvb, int offset, proto_tree *tree)
+static guint32
+dissect_netb_datagram( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the DATAGRAM command */
@@ -641,11 +692,13 @@ static void dissect_netb_datagram( tvbuff_t *tvb, int offset, proto_tree *tree)
netbios_add_name("Sender's Name", tvb, offset + NB_SENDER_NAME,
tree);
}
+
+ return 0;
}
-static void dissect_netb_datagram_bcast( tvbuff_t *tvb, int offset,
- proto_tree *tree)
+static guint32
+dissect_netb_datagram_bcast( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the DATAGRAM BROADCAST command */
@@ -658,10 +711,13 @@ static void dissect_netb_datagram_bcast( tvbuff_t *tvb, int offset,
netbios_add_name("Sender's Name", tvb, offset + NB_SENDER_NAME,
tree);
}
+
+ return 0;
}
-static void dissect_netb_name_query( tvbuff_t *tvb, int offset, proto_tree *tree)
+static guint32
+dissect_netb_name_query( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the NAME QUERY command */
guint8 local_session_number = tvb_get_guint8( tvb, offset + NB_DATA2);
@@ -680,11 +736,13 @@ static void dissect_netb_name_query( tvbuff_t *tvb, int offset, proto_tree *tre
netbios_add_name("Sender's Name", tvb, offset + NB_SENDER_NAME,
tree);
}
+
+ return 0;
}
-static void dissect_netb_add_name_resp( tvbuff_t *tvb, int offset,
- proto_tree *tree)
+static guint32
+dissect_netb_add_name_resp( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the ADD NAME RESPONSE command */
@@ -695,11 +753,13 @@ static void dissect_netb_add_name_resp( tvbuff_t *tvb, int offset,
tree);
netbios_add_name("Name to be added", tvb, offset + NB_SENDER_NAME,
tree);
+
+ return 0;
}
-static void dissect_netb_name_resp( tvbuff_t *tvb, int offset,
- proto_tree *tree)
+static guint32
+dissect_netb_name_resp( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the NAME RECOGNIZED command */
guint8 local_session_number = tvb_get_guint8( tvb, offset + NB_DATA2);
@@ -730,10 +790,13 @@ static void dissect_netb_name_resp( tvbuff_t *tvb, int offset,
netbios_add_name("Sender's Name", tvb, offset + NB_SENDER_NAME,
tree);
}
+
+ return 0;
}
-static void dissect_netb_status_resp( tvbuff_t *tvb, int offset, proto_tree *tree)
+static guint32
+dissect_netb_status_resp( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the STATUS RESPONSE command */
guint8 status_response = tvb_get_guint8( tvb, offset + NB_DATA1);
@@ -772,27 +835,41 @@ static void dissect_netb_status_resp( tvbuff_t *tvb, int offset, proto_tree *tr
netbios_add_name("Receiver's Name", tvb, offset + NB_RECVER_NAME, tree);
netbios_add_name("Sender's Name", tvb, offset + NB_SENDER_NAME,
tree);
+
+ return 0;
}
-static void dissect_netb_data_ack( tvbuff_t* tvb, int offset, proto_tree *tree)
+static guint32
+dissect_netb_data_ack( tvbuff_t* tvb, int offset, proto_tree *tree)
{/* Handle the DATA ACK command */
nb_xmit_corrl( tvb, offset, tree);
nb_remote_session( tvb, offset, tree);
nb_local_session( tvb, offset, tree);
+
+ return 0;
}
-static void dissect_netb_data_first_middle( tvbuff_t *tvb, int offset,
- proto_tree *tree)
+static guint32
+dissect_netb_data_first_middle( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the DATA FIRST MIDDLE command */
+ guint8 remote_session, local_session;
+
/*
- * This could be thought of as a packet with the "more fragments"
- * flag set, were we to do reassembly.
+ * This is the first frame, or the middle frame, of a fragmented
+ * packet.
+ *
+ * XXX - there are no sequence numbers, so we have to assume
+ * that fragments arrive in order with no duplicates.
+ * In fact, 802.2 LLC is supposed to handle that, so we
+ * might have to have the LLC dissector do so (but the TCP
+ * dissector doesn't currently handle out-of-order or duplicate
+ * data, either).
*/
netbios_data_first_middle_flags( tvb, tree, offset + NB_FLAGS);
@@ -800,19 +877,27 @@ static void dissect_netb_data_first_middle( tvbuff_t *tvb, int offset,
nb_resync_indicator( tvb, offset, tree, "DATA FIRST MIDDLE");
nb_xmit_corrl( tvb, offset, tree);
nb_resp_corrl( tvb, offset, tree);
- nb_remote_session( tvb, offset, tree);
- nb_local_session( tvb, offset, tree);
+ remote_session = nb_remote_session( tvb, offset, tree);
+ local_session = nb_local_session( tvb, offset, tree);
+
+ /*
+ * Return a combination of the remote and local session numbers,
+ * for use when reassembling.
+ */
+ return (remote_session << 8) + local_session;
}
-static void dissect_netb_data_only_last( tvbuff_t *tvb, int offset,
- proto_tree *tree)
+static guint32
+dissect_netb_data_only_last( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the DATA ONLY LAST command */
+ guint8 remote_session, local_session;
+
/*
- * This could be thought of as a packet with the "more fragments"
- * flag not set, were we to do reassembly.
+ * This is a complete packet, or the last frame of a fragmented
+ * packet.
*/
netbios_data_only_flags( tvb, tree, offset + NB_FLAGS);
@@ -820,13 +905,19 @@ static void dissect_netb_data_only_last( tvbuff_t *tvb, int offset,
nb_resync_indicator( tvb, offset, tree, "DATA ONLY LAST");
nb_xmit_corrl( tvb, offset, tree);
nb_resp_corrl( tvb, offset, tree);
- nb_remote_session( tvb, offset, tree);
- nb_local_session( tvb, offset, tree);
+ remote_session = nb_remote_session( tvb, offset, tree);
+ local_session = nb_local_session( tvb, offset, tree);
+
+ /*
+ * Return a combination of the remote and local session numbers,
+ * for use when reassembling.
+ */
+ return (remote_session << 8) + local_session;
}
-static void dissect_netb_session_confirm( tvbuff_t *tvb, int offset,
- proto_tree *tree)
+static guint32
+dissect_netb_session_confirm( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the SESSION CONFIRM command */
@@ -837,22 +928,26 @@ static void dissect_netb_session_confirm( tvbuff_t *tvb, int offset,
nb_resp_corrl( tvb, offset, tree);
nb_remote_session( tvb, offset, tree);
nb_local_session( tvb, offset, tree);
+
+ return 0;
}
-static void dissect_netb_session_end( tvbuff_t *tvb, int offset,
- proto_tree *tree)
+static guint32
+dissect_netb_session_end( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the SESSION END command */
nb_data2( hf_netb_termination_indicator, tvb, offset, tree);
nb_remote_session( tvb, offset, tree);
nb_local_session( tvb, offset, tree);
+
+ return 0;
}
-static void dissect_netb_session_init( tvbuff_t *tvb, int offset,
- proto_tree *tree)
+static guint32
+dissect_netb_session_init( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the SESSION INITIALIZE command */
@@ -863,10 +958,12 @@ static void dissect_netb_session_init( tvbuff_t *tvb, int offset,
nb_xmit_corrl( tvb, offset, tree);
nb_remote_session( tvb, offset, tree);
nb_local_session( tvb, offset, tree);
+
+ return 0;
}
-static void dissect_netb_no_receive( tvbuff_t *tvb, int offset,
- proto_tree *tree)
+static guint32
+dissect_netb_no_receive( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the NO RECEIVE command */
@@ -875,33 +972,39 @@ static void dissect_netb_no_receive( tvbuff_t *tvb, int offset,
nb_data2( hf_netb_num_data_bytes_accepted, tvb, offset, tree);
nb_remote_session( tvb, offset, tree);
nb_local_session( tvb, offset, tree);
+
+ return 0;
}
-static void dissect_netb_receive_outstanding( tvbuff_t *tvb, int offset,
- proto_tree *tree)
+static guint32
+dissect_netb_receive_outstanding( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the RECEIVE OUTSTANDING command */
nb_data2( hf_netb_num_data_bytes_accepted, tvb, offset, tree);
nb_remote_session( tvb, offset, tree);
nb_local_session( tvb, offset, tree);
+
+ return 0;
}
-static void dissect_netb_receive_continue( tvbuff_t *tvb, int offset,
- proto_tree *tree)
+static guint32
+dissect_netb_receive_continue( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the RECEIVE CONTINUE command */
nb_xmit_corrl( tvb, offset, tree);
nb_remote_session( tvb, offset, tree);
nb_local_session( tvb, offset, tree);
+
+ return 0;
}
-static void dissect_netb_session_alive( tvbuff_t *tvb, int offset,
- proto_tree *tree)
+static guint32
+dissect_netb_session_alive( tvbuff_t *tvb, int offset, proto_tree *tree)
{/* Handle the SESSION ALIVE command */
@@ -916,6 +1019,8 @@ static void dissect_netb_session_alive( tvbuff_t *tvb, int offset,
*/
nb_remote_session( tvb, offset, tree);
nb_local_session( tvb, offset, tree);
+
+ return 0;
}
@@ -926,7 +1031,7 @@ static void dissect_netb_session_alive( tvbuff_t *tvb, int offset,
/************************************************************************/
-void (*dissect_netb[])(tvbuff_t *, int, proto_tree *) = {
+static guint32 (*dissect_netb[])(tvbuff_t *, int, proto_tree *) = {
dissect_netb_add_group_name, /* Add Group Name 0x00 */
dissect_netb_add_name, /* Add Name 0x01 */
@@ -981,12 +1086,16 @@ static void
dissect_netbios(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- proto_tree *netb_tree;
+ proto_tree *netb_tree = NULL;
proto_item *ti;
guint16 hdr_len, command;
char *command_name;
char name[(NETBIOS_NAME_LEN - 1)*4 + 1];
int name_type;
+ guint16 session_id;
+ gboolean save_fragmented;
+ int len;
+ fragment_data *fd_head;
tvbuff_t *next_tvb;
int offset = 0;
@@ -1051,31 +1160,111 @@ dissect_netbios(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
"Delimiter: EFFF (NetBIOS)");
proto_tree_add_uint(netb_tree, hf_netb_cmd, tvb, offset + NB_COMMAND, 1, command);
+ }
- /* if command in table range */
- if ( command < sizeof( dissect_netb)/ sizeof(void *))
+ /* if command in table range */
+ if ( command < sizeof( dissect_netb)/ sizeof(void *)) {
- /* branch to handle commands */
- (dissect_netb[ command])( tvb, offset, netb_tree);
- }
+ /* branch to handle commands */
+ session_id = (dissect_netb[ command])( tvb, offset, netb_tree);
- offset += hdr_len; /* move past header */
+ offset += hdr_len; /* move past header */
- switch (command) {
+ save_fragmented = pinfo->fragmented;
- case NB_DATAGRAM:
- case NB_DATAGRAM_BCAST:
- case NB_DATA_FIRST_MIDDLE:
- case NB_DATA_ONLY_LAST:
/*
- * These are the frames with user data.
+ * Process user data in frames that have it.
*/
- next_tvb = tvb_new_subset(tvb, offset, -1, -1);
- dissect_netbios_payload(next_tvb, pinfo, tree);
- break;
+ switch (command) {
+
+ case NB_DATAGRAM:
+ case NB_DATAGRAM_BCAST:
+ /*
+ * No fragmentation here.
+ */
+ next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+ dissect_netbios_payload(next_tvb, pinfo, tree);
+ break;
+
+ case NB_DATA_FIRST_MIDDLE:
+ case NB_DATA_ONLY_LAST:
+ /*
+ * Possibly fragmented.
+ */
+ if (netbios_defragment) {
+ len = tvb_length_remaining(tvb, offset);
+ fd_head = fragment_add_seq_next(tvb, offset,
+ pinfo, session_id,
+ netbios_fragment_table,
+ netbios_reassembled_table,
+ len, command == NB_DATA_FIRST_MIDDLE);
+ if (fd_head != NULL) {
+ if (fd_head->next != NULL) {
+ next_tvb = tvb_new_real_data(fd_head->data,
+ fd_head->len, fd_head->len);
+ tvb_set_child_real_data_tvbuff(tvb,
+ next_tvb);
+ add_new_data_source(pinfo,
+ next_tvb,
+ "Reassembled NetBIOS");
+ /* Show all fragments. */
+ if (tree) {
+ show_fragment_seq_tree(fd_head,
+ &netbios_frag_items,
+ netb_tree, pinfo,
+ next_tvb);
+ }
+ } else {
+ next_tvb = tvb_new_subset(tvb,
+ offset, -1, -1);
+ }
+ } else {
+ next_tvb = NULL;
+ }
+ } else {
+ /*
+ * If this is NB_DATA_FIRST_MIDDLE,
+ * just show it as a fragment.
+ * (XXX - it'd be nice to dissect it
+ * if it's the first fragment, but we'd
+ * need to do reassembly in order to
+ * discover that.)
+ *
+ * If this is NB_DATA_ONLY_LAST, dissect
+ * it. (XXX - it'd be nice to show it
+ * as a fragment if it's part of a
+ * fragmented datagram, but we'd need
+ * to do reassembly in order to discover
+ * that.)
+ */
+ if (command == NB_DATA_FIRST_MIDDLE)
+ next_tvb = NULL;
+ else {
+ next_tvb = tvb_new_subset(tvb, offset,
+ -1, -1);
+ }
+ }
+ if (next_tvb != NULL)
+ dissect_netbios_payload(next_tvb, pinfo, tree);
+ else {
+ next_tvb = tvb_new_subset (tvb, offset, -1, -1);
+ call_dissector(data_handle, next_tvb, pinfo,
+ tree);
+ }
+ break;
+ }
}
}
+static void
+netbios_init(void)
+{
+ /*
+ * Initialize the fragment and reassembly tables.
+ */
+ fragment_table_init(&netbios_fragment_table);
+ reassembled_table_init(&netbios_reassembled_table);
+}
void proto_register_netbios(void)
{
@@ -1084,6 +1273,8 @@ void proto_register_netbios(void)
&ett_netb_name,
&ett_netb_flags,
&ett_netb_status,
+ &ett_netb_fragments,
+ &ett_netb_fragment,
};
static hf_register_info hf_netb[] = {
@@ -1182,13 +1373,52 @@ void proto_register_netbios(void)
{ &hf_netb_data2,
{ "DATA2 value", "netbios.data2", FT_UINT16, BASE_HEX, NULL, 0x0,
"", HFILL }},
- };
+
+ { &hf_netb_fragment_overlap,
+ { "Segment overlap", "netbios.segment.overlap", FT_BOOLEAN, BASE_NONE,
+ NULL, 0x0, "Segment overlaps with other segments", HFILL }},
+
+ { &hf_netb_fragment_overlap_conflict,
+ { "Conflicting data in segment overlap", "netbios.segment.overlap.conflict",
+ FT_BOOLEAN, BASE_NONE,
+ NULL, 0x0, "Overlapping segments contained conflicting data", HFILL }},
+
+ { &hf_netb_fragment_multiple_tails,
+ { "Multiple tail segments found", "netbios.segment.multipletails",
+ FT_BOOLEAN, BASE_NONE,
+ NULL, 0x0, "Several tails were found when desegmenting the packet", HFILL }},
+
+ { &hf_netb_fragment_too_long_segment,
+ { "Segment too long", "netbios.segment.toolongsegment", FT_BOOLEAN, BASE_NONE,
+ NULL, 0x0, "Segment contained data past end of packet", HFILL }},
+
+ { &hf_netb_fragment_error,
+ {"Desegmentation error", "netbios.segment.error", FT_NONE, BASE_NONE,
+ NULL, 0x0, "Desegmentation error due to illegal segments", HFILL }},
+
+ { &hf_netb_fragment,
+ { "NetBIOS Fragment", "netbios.fragment", FT_NONE, BASE_NONE,
+ NULL, 0x0, "NetBIOS Fragment", HFILL }},
+
+ { &hf_netb_fragments,
+ { "NetBIOS Fragments", "netbios.fragments", FT_NONE, BASE_NONE,
+ NULL, 0x0, "NetBIOS Fragments", HFILL }},
+ };
+ module_t *netbios_module;
proto_netbios = proto_register_protocol("NetBIOS", "NetBIOS", "netbios");
proto_register_subtree_array(ett, array_length(ett));
proto_register_field_array(proto_netbios, hf_netb, array_length(hf_netb));
register_heur_dissector_list("netbios", &netbios_heur_subdissector_list);
+
+ netbios_module = prefs_register_protocol(proto_netbios, NULL);
+ prefs_register_bool_preference(netbios_module, "defragment",
+ "Defragment all NetBIOS messages spanning multiple frames",
+ "Whether the NetBIOS dissector should defragment all messages spanning multiple framess",
+ &netbios_defragment);
+
+ register_init_routine(netbios_init);
}
void
diff --git a/packet-rpc.c b/packet-rpc.c
index b8c8cbe4cb..79b0a7b42d 100644
--- a/packet-rpc.c
+++ b/packet-rpc.c
@@ -2,7 +2,7 @@
* Routines for rpc dissection
* Copyright 1999, Uwe Girlich <Uwe.Girlich@philosys.de>
*
- * $Id: packet-rpc.c,v 1.106 2002/10/24 03:54:11 guy Exp $
+ * $Id: packet-rpc.c,v 1.107 2002/10/24 06:17:34 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -214,7 +214,7 @@ static dissector_handle_t rpc_handle;
static dissector_handle_t gssapi_handle;
static dissector_handle_t data_handle;
-fragment_items rpc_frag_items = {
+static const fragment_items rpc_frag_items = {
&ett_rpc_fragment,
&ett_rpc_fragments,
&hf_rpc_fragments,
diff --git a/packet-smb-pipe.c b/packet-smb-pipe.c
index b918a8ec68..1ed7cc4e70 100644
--- a/packet-smb-pipe.c
+++ b/packet-smb-pipe.c
@@ -8,7 +8,7 @@ XXX Fixme : shouldnt show [malformed frame] for long packets
* significant rewrite to tvbuffify the dissector, Ronnie Sahlberg and
* Guy Harris 2001
*
- * $Id: packet-smb-pipe.c,v 1.82 2002/08/28 21:00:31 jmayer Exp $
+ * $Id: packet-smb-pipe.c,v 1.83 2002/10/24 06:17:34 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -76,7 +76,7 @@ static gint ett_smb_pipe = -1;
static gint ett_smb_pipe_fragment = -1;
static gint ett_smb_pipe_fragments = -1;
-fragment_items smb_pipe_frag_items = {
+static const fragment_items smb_pipe_frag_items = {
&ett_smb_pipe_fragment,
&ett_smb_pipe_fragments,
&hf_pipe_fragments,
diff --git a/packet-smb.c b/packet-smb.c
index 85429915a2..f9c3113e1d 100644
--- a/packet-smb.c
+++ b/packet-smb.c
@@ -3,7 +3,7 @@
* Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
* 2001 Rewrite by Ronnie Sahlberg and Guy Harris
*
- * $Id: packet-smb.c,v 1.294 2002/09/20 07:43:02 sharpe Exp $
+ * $Id: packet-smb.c,v 1.295 2002/10/24 06:17:35 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -674,7 +674,7 @@ static gint ett_smb_ntlmssp = -1;
static dissector_handle_t gssapi_handle = NULL;
static dissector_handle_t ntlmssp_handle = NULL;
-fragment_items smb_frag_items = {
+static const fragment_items smb_frag_items = {
&ett_smb_segment,
&ett_smb_segments,
diff --git a/packet-wtp.c b/packet-wtp.c
index 3ab9b816b7..69143c3973 100644
--- a/packet-wtp.c
+++ b/packet-wtp.c
@@ -2,7 +2,7 @@
*
* Routines to dissect WTP component of WAP traffic.
*
- * $Id: packet-wtp.c,v 1.39 2002/08/28 21:00:39 jmayer Exp $
+ * $Id: packet-wtp.c,v 1.40 2002/10/24 06:17:36 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -203,7 +203,7 @@ static gint ett_tpilist = ETT_EMPTY;
static gint ett_wsp_fragments = ETT_EMPTY;
static gint ett_wtp_fragment = ETT_EMPTY;
-fragment_items wtp_frag_items = {
+static const fragment_items wtp_frag_items = {
&ett_wtp_fragment,
&ett_wsp_fragments,
&hf_wtp_fragments,
diff --git a/reassemble.c b/reassemble.c
index 6ee00863ea..064c774a44 100644
--- a/reassemble.c
+++ b/reassemble.c
@@ -1,7 +1,7 @@
/* reassemble.c
* Routines for {fragment,segment} reassembly
*
- * $Id: reassemble.c,v 1.25 2002/10/17 21:14:17 guy Exp $
+ * $Id: reassemble.c,v 1.26 2002/10/24 06:17:36 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -957,7 +957,19 @@ fragment_reassembled(fragment_data *fd_head, packet_info *pinfo,
}
/*
- * This function adds a new fragment to the fragment hash table.
+ * This does the work for "fragment_add_seq_check()" and
+ * "fragment_add_seq_next()".
+ *
+ * This function assumes frag_number being a block sequence number.
+ * The bsn for the first block is 0.
+ *
+ * If "no_frag_number" is TRUE, it uses the next expected fragment number
+ * as the fragment number if there is a reassembly in progress, otherwise
+ * it uses 0.
+ *
+ * If "no_frag_number" is FALSE, it uses the "frag_number" argument as
+ * the fragment number.
+ *
* If this is the first fragment seen for this datagram, a new
* "fragment_data" structure is allocated to refer to the reassembled,
* packet, and:
@@ -978,19 +990,17 @@ fragment_reassembled(fragment_data *fd_head, packet_info *pinfo,
* table of reassembled fragments, if we have all the fragments or if
* this is the only fragment and "more_frags" is false, returns NULL
* otherwise.
- *
- * This function assumes frag_number being a block sequence number.
- * The bsn for the first block is 0.
*/
fragment_data *
-fragment_add_seq_check(tvbuff_t *tvb, int offset, packet_info *pinfo,
+fragment_add_seq_check_work(tvbuff_t *tvb, int offset, packet_info *pinfo,
guint32 id, GHashTable *fragment_table,
GHashTable *reassembled_table, guint32 frag_number,
- guint32 frag_data_len, gboolean more_frags)
+ guint32 frag_data_len, gboolean more_frags,
+ gboolean no_frag_number)
{
fragment_key key, *new_key, *old_key;
gpointer orig_key, value;
- fragment_data *fd_head;
+ fragment_data *fd_head, *fd;
/*
* Have we already seen this frame?
@@ -1047,20 +1057,38 @@ fragment_add_seq_check(tvbuff_t *tvb, int offset, packet_info *pinfo,
g_hash_table_insert(fragment_table, new_key, fd_head);
orig_key = new_key; /* for unhashing it later */
+
+ /*
+ * If we weren't given an initial fragment number,
+ * make it 0.
+ */
+ if (no_frag_number)
+ frag_number = 0;
} else {
/*
* We found it.
*/
fd_head = value;
+
+ /*
+ * If we weren't given an initial fragment number,
+ * use the next expected fragment number as the fragment
+ * number for this fragment.
+ */
+ if (no_frag_number) {
+ for (fd = fd_head; fd != NULL; fd = fd->next) {
+ if (fd->next == NULL)
+ frag_number = fd->offset + 1;
+ }
+ }
}
/*
* If this is a short frame, then we can't, and don't, do
* reassembly on it.
*
- * If it's the first frame (fragment number is 0), handle it
- * as an unfragmented packet. Otherwise, just handle it
- * as a fragment.
+ * If it's the first frame, handle it as an unfragmented packet.
+ * Otherwise, just handle it as a fragment.
*
* If "more_frags" isn't set, we get rid of the entry in the
* hash table for this reassembly, as we don't need it any more.
@@ -1107,12 +1135,33 @@ fragment_add_seq_check(tvbuff_t *tvb, int offset, packet_info *pinfo,
}
}
+fragment_data *
+fragment_add_seq_check(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ guint32 id, GHashTable *fragment_table,
+ GHashTable *reassembled_table, guint32 frag_number,
+ guint32 frag_data_len, gboolean more_frags)
+{
+ return fragment_add_seq_check_work(tvb, offset, pinfo, id,
+ fragment_table, reassembled_table, frag_number, frag_data_len,
+ more_frags, FALSE);
+}
+
+fragment_data *
+fragment_add_seq_next(tvbuff_t *tvb, int offset, packet_info *pinfo,
+ guint32 id, GHashTable *fragment_table,
+ GHashTable *reassembled_table, guint32 frag_data_len,
+ gboolean more_frags)
+{
+ return fragment_add_seq_check_work(tvb, offset, pinfo, id,
+ fragment_table, reassembled_table, 0, frag_data_len,
+ more_frags, TRUE);
+}
/*
* Show a single fragment in a fragment subtree.
*/
static void
-show_fragment(fragment_data *fd, int offset, fragment_items *fit,
+show_fragment(fragment_data *fd, int offset, const fragment_items *fit,
proto_tree *ft, tvbuff_t *tvb)
{
if (fd->flags & (FD_OVERLAP|FD_OVERLAPCONFLICT
@@ -1174,7 +1223,7 @@ show_fragment(fragment_data *fd, int offset, fragment_items *fit,
}
static gboolean
-show_fragment_errs_in_col(fragment_data *fd_head, fragment_items *fit,
+show_fragment_errs_in_col(fragment_data *fd_head, const fragment_items *fit,
packet_info *pinfo)
{
if (fd_head->flags & (FD_OVERLAPCONFLICT
@@ -1196,7 +1245,7 @@ show_fragment_errs_in_col(fragment_data *fd_head, fragment_items *fit,
or FALSE if fragmentation was ok.
*/
gboolean
-show_fragment_tree(fragment_data *fd_head, fragment_items *fit,
+show_fragment_tree(fragment_data *fd_head, const fragment_items *fit,
proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb)
{
fragment_data *fd;
@@ -1222,7 +1271,7 @@ show_fragment_tree(fragment_data *fd_head, fragment_items *fit,
or FALSE if fragmentation was ok.
*/
gboolean
-show_fragment_seq_tree(fragment_data *fd_head, fragment_items *fit,
+show_fragment_seq_tree(fragment_data *fd_head, const fragment_items *fit,
proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb)
{
guint32 offset, next_offset;
diff --git a/reassemble.h b/reassemble.h
index 90d5db35d7..9c8287f662 100644
--- a/reassemble.h
+++ b/reassemble.h
@@ -1,7 +1,7 @@
/* reassemble.h
* Declarations of outines for {fragment,segment} reassembly
*
- * $Id: reassemble.h,v 1.10 2002/08/28 21:00:41 jmayer Exp $
+ * $Id: reassemble.h,v 1.11 2002/10/24 06:17:36 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -98,7 +98,7 @@ fragment_data *fragment_add_seq(tvbuff_t *tvb, int offset, packet_info *pinfo,
guint32 frag_data_len, gboolean more_frags);
/*
- * This function adds a new fragment to the fragment hash table.
+ * These functions add a new fragment to the fragment hash table.
* If this is the first fragment seen for this datagram, a new
* "fragment_data" structure is allocated to refer to the reassembled,
* packet, and:
@@ -114,14 +114,18 @@ fragment_data *fragment_add_seq(tvbuff_t *tvb, int offset, packet_info *pinfo,
* Otherwise, this fragment is just added to the linked list of fragments
* for this packet.
*
- * Returns a pointer to the head of the fragment data list, and removes
+ * They return a pointer to the head of the fragment data list, and removes
* that from the fragment hash table if necessary and adds it to the
* table of reassembled fragments, if we have all the fragments or if
* this is the only fragment and "more_frags" is false, returns NULL
* otherwise.
*
- * This function assumes frag_number being a block sequence number.
+ * They assumes frag_number is a block sequence number.
* The bsn for the first block is 0.
+ *
+ * "fragment_add_seq_check()" takes the sequence number as an argument;
+ * "fragment_add_seq_next()" is for protocols with no sequence number,
+ * and assumes fragments always appear in sequence.
*/
fragment_data *
fragment_add_seq_check(tvbuff_t *tvb, int offset, packet_info *pinfo,
@@ -129,6 +133,11 @@ fragment_add_seq_check(tvbuff_t *tvb, int offset, packet_info *pinfo,
GHashTable *reassembled_table, guint32 frag_number,
guint32 frag_data_len, gboolean more_frags);
+fragment_data *
+fragment_add_seq_next(tvbuff_t *tvb, int offset, packet_info *pinfo, guint32 id,
+ GHashTable *fragment_table, GHashTable *reassembled_table,
+ guint32 frag_data_len, gboolean more_frags);
+
/* to specify how much to reassemble, for fragmentation where last fragment can not be
* identified by flags or such.
* note that for FD_BLOCKSEQUENCE tot_len is the index for the tail fragment.
@@ -189,9 +198,9 @@ typedef struct _fragment_items {
} fragment_items;
extern gboolean
-show_fragment_tree(fragment_data *ipfd_head, fragment_items *fit,
+show_fragment_tree(fragment_data *ipfd_head, const fragment_items *fit,
proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb);
extern gboolean
-show_fragment_seq_tree(fragment_data *ipfd_head, fragment_items *fit,
+show_fragment_seq_tree(fragment_data *ipfd_head, const fragment_items *fit,
proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb);