diff options
-rw-r--r-- | packet-atalk.c | 8 | ||||
-rw-r--r-- | packet-clnp.c | 4 | ||||
-rw-r--r-- | packet-dcerpc.c | 4 | ||||
-rw-r--r-- | packet-eap.c | 4 | ||||
-rw-r--r-- | packet-ieee80211.c | 4 | ||||
-rw-r--r-- | packet-ip.c | 4 | ||||
-rw-r--r-- | packet-ipv6.c | 4 | ||||
-rw-r--r-- | packet-netbios.c | 376 | ||||
-rw-r--r-- | packet-rpc.c | 4 | ||||
-rw-r--r-- | packet-smb-pipe.c | 4 | ||||
-rw-r--r-- | packet-smb.c | 4 | ||||
-rw-r--r-- | packet-wtp.c | 4 | ||||
-rw-r--r-- | reassemble.c | 79 | ||||
-rw-r--r-- | reassemble.h | 21 |
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); |