diff options
author | Guy Harris <guy@alum.mit.edu> | 2003-05-28 22:58:46 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2003-05-28 22:58:46 +0000 |
commit | d2f3215b6f18da757025484fc4f70b56efd16f67 (patch) | |
tree | 196c7a8f7b668a9fdcf5760c5cd4c5d0eb830a0a | |
parent | dbce18c42a74bf2eb7f32f6fe7c8d542823c6207 (diff) | |
download | wireshark-d2f3215b6f18da757025484fc4f70b56efd16f67.tar.gz wireshark-d2f3215b6f18da757025484fc4f70b56efd16f67.tar.bz2 wireshark-d2f3215b6f18da757025484fc4f70b56efd16f67.zip |
COTP reassembly, from Laurent Meyer.
svn path=/trunk/; revision=7760
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | packet-clnp.c | 180 |
3 files changed, 162 insertions, 22 deletions
@@ -1644,6 +1644,7 @@ Wayne Parrott <wayne_p [AT] pacific.net.au> { Laurent Meyer <laurent.meyer [AT] thales-avionics.com> { X.25 reassembly Filterable fields in COTP + COTP reassembly } Lars Roland <Lars.Roland [AT] gmx.net> { @@ -1,4 +1,4 @@ -$Id: TODO,v 1.11 2003/05/24 08:43:18 guy Exp $ +$Id: TODO,v 1.12 2003/05/28 22:58:46 guy Exp $ Things to do: ============= @@ -62,7 +62,6 @@ from $SSH_CLIENT). Any takers? for more TCP-based protocols; we might also want to reassemble: NBDS - OSI COTP PPP Multilink and possibly other protocols. diff --git a/packet-clnp.c b/packet-clnp.c index 0f54d442df..b0d3fda625 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.75 2003/05/24 19:51:48 gerald Exp $ + * $Id: packet-clnp.c,v 1.76 2003/05/28 22:58:46 guy Exp $ * Laurent Deniel <laurent.deniel@free.fr> * Ralf Schneider <Ralf.Schneider@t-online.de> * @@ -71,10 +71,20 @@ static int hf_clnp_reassembled_in = -1; static int proto_cotp = -1; static gint ett_cotp = -1; - -static int hf_cotp_srcref = -1; -static int hf_cotp_destref = -1; -static int hf_cotp_type = -1; +static gint ett_cotp_segments = -1; +static gint ett_cotp_segment = -1; + +static int hf_cotp_srcref = -1; +static int hf_cotp_destref = -1; +static int hf_cotp_type = -1; +static int hf_cotp_segments = -1; +static int hf_cotp_segment = -1; +static int hf_cotp_segment_overlap = -1; +static int hf_cotp_segment_overlap_conflict = -1; +static int hf_cotp_segment_multiple_tails = -1; +static int hf_cotp_segment_too_long_segment = -1; +static int hf_cotp_segment_error = -1; +static int hf_cotp_reassembled_in = -1; static int proto_cltp = -1; static gint ett_cltp = -1; @@ -95,6 +105,20 @@ static const fragment_items clnp_frag_items = { "segments" }; +static const fragment_items cotp_frag_items = { + &ett_cotp_segment, + &ett_cotp_segments, + &hf_cotp_segments, + &hf_cotp_segment, + &hf_cotp_segment_overlap, + &hf_cotp_segment_overlap_conflict, + &hf_cotp_segment_multiple_tails, + &hf_cotp_segment_too_long_segment, + &hf_cotp_segment_error, + &hf_cotp_reassembled_in, + "segments" +}; + static dissector_handle_t clnp_handle; static dissector_handle_t data_handle; @@ -315,10 +339,17 @@ static heur_dissector_list_t clnp_heur_subdissector_list; static GHashTable *clnp_segment_table = NULL; static GHashTable *clnp_reassembled_table = NULL; +/* + * Reassembly of COTP. + */ +static GHashTable *cotp_segment_table = NULL; +static GHashTable *cotp_reassembled_table = NULL; + /* options */ static guint tp_nsap_selector = NSEL_TP; static gboolean always_decode_transport = FALSE; static gboolean clnp_reassemble = FALSE; +static gboolean cotp_reassemble = FALSE; /* function definitions */ @@ -717,6 +748,8 @@ static int ositp_decode_DR(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu, reason = tvb_get_guint8(tvb, offset + P_REASON_IN_DR); + pinfo->srcport = src_ref; + pinfo->destport = dst_ref; switch(reason) { case (128+0): str = "Normal Disconnect"; break; case (128+1): str = "Remote transport entity congestion"; break; @@ -777,7 +810,10 @@ static int ositp_decode_DT(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu, guint16 dst_ref; guint tpdu_nr; guint fragment = 0; + guint32 fragment_length = 0; tvbuff_t *next_tvb; + tvbuff_t *reassembled_tvb = NULL; + fragment_data *fd_head; /* VP_CHECKSUM is the only parameter allowed in the variable part. (This means we may misdissect this if the packet is bad and @@ -833,6 +869,9 @@ static int ositp_decode_DT(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu, break; } + pinfo->destport = dst_ref; + pinfo->srcport = 0; + pinfo->fragmented = fragment; if (check_col(pinfo->cinfo, COL_INFO)) { if (is_class_234) { col_append_fstr(pinfo->cinfo, COL_INFO, "DT TPDU (%u) dst-ref: 0x%04x %s", @@ -893,22 +932,64 @@ static int ositp_decode_DT(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu, offset += li; next_tvb = tvb_new_subset(tvb, offset, -1, -1); - if (uses_inactive_subset){ - if (dissector_try_heuristic(cotp_is_heur_subdissector_list, next_tvb, - pinfo, tree)) { - *subdissector_found = TRUE; - } else { - /* Fill in other Dissectors using inactive subset here */ - call_dissector(data_handle,next_tvb, pinfo, tree); - } + if (cotp_reassemble) { + fragment_length = tvb_length(next_tvb); + fd_head = fragment_add_seq_check(next_tvb, 0, pinfo, dst_ref, + cotp_segment_table, + cotp_reassembled_table, + tpdu_nr, + fragment_length, fragment); + if (fd_head) { + if (fd_head->next) { + /* This is the last packet */ + reassembled_tvb = tvb_new_real_data(fd_head->data, + fd_head->len, + fd_head->len); + tvb_set_child_real_data_tvbuff(next_tvb, reassembled_tvb); + add_new_data_source(pinfo, reassembled_tvb, "Reassembled COTP"); + + show_fragment_seq_tree(fd_head, + &cotp_frag_items, + cotp_tree, + pinfo, reassembled_tvb); + pinfo->fragmented = fragment; + next_tvb = reassembled_tvb; + } + } + if (fragment && reassembled_tvb == NULL) { + proto_tree_add_text(cotp_tree, tvb, offset, -1, + "User data (%u byte%s)", fragment_length, + plurality(fragment_length, "", "s")); + } + + } + + if (uses_inactive_subset) { + if (dissector_try_heuristic(cotp_is_heur_subdissector_list, next_tvb, + pinfo, tree)) { + *subdissector_found = TRUE; + } else { + /* Fill in other Dissectors using inactive subset here */ + call_dissector(data_handle,next_tvb, pinfo, tree); + } } else { - if (dissector_try_heuristic(cotp_heur_subdissector_list, next_tvb, - pinfo, tree)) { - *subdissector_found = TRUE; - } else { - call_dissector(data_handle,next_tvb, pinfo, tree); - } - } + /* + * We dissect payload if one of the following is TRUE: + * + * - Reassembly option for COTP in preferences is unchecked + * - Reassembly option is checked and this packet is the last fragment + */ + if ( (!cotp_reassemble) || + ((cotp_reassemble) && (!fragment))) { + if (dissector_try_heuristic(cotp_heur_subdissector_list, next_tvb, + pinfo, tree)) { + *subdissector_found = TRUE; + } else { + call_dissector(data_handle,next_tvb, pinfo, tree); + } + } + } + offset += tvb_length_remaining(tvb, offset); /* we dissected all of the containing PDU */ @@ -968,6 +1049,9 @@ static int ositp_decode_ED(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu, } /* li */ dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF); + + pinfo->destport = dst_ref; + pinfo->srcport = 0; if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, "ED TPDU (%u) dst-ref: 0x%04x", tpdu_nr, dst_ref); @@ -1046,6 +1130,9 @@ static int ositp_decode_RJ(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu, } dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF); + + pinfo->destport = dst_ref; + pinfo->srcport = 0; if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, "RJ TPDU (%u) dst-ref: 0x%04x", tpdu_nr, dst_ref); @@ -1099,6 +1186,8 @@ static int ositp_decode_CC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu, return -1; dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF); + pinfo->srcport = src_ref; + pinfo->destport = dst_ref; if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, "%s TPDU src-ref: 0x%04x dst-ref: 0x%04x", @@ -1174,6 +1263,8 @@ static int ositp_decode_DC(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu, dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF); src_ref = tvb_get_ntohs(tvb, offset + P_SRC_REF); + pinfo->srcport = src_ref; + pinfo->destport = dst_ref; if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, "DC TPDU src-ref: 0x%04x dst-ref: 0x%04x", @@ -1230,6 +1321,8 @@ static int ositp_decode_AK(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu, dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF); tpdu_nr = tvb_get_guint8(tvb, offset + P_TPDU_NR_234); + pinfo->srcport = 0; + pinfo->destport = dst_ref; if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, "AK TPDU (%u) dst-ref: 0x%04x", tpdu_nr, dst_ref); @@ -1367,6 +1460,8 @@ static int ositp_decode_EA(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu, } /* li */ dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF); + pinfo->srcport = 0; + pinfo->destport = dst_ref; if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, "EA TPDU (%u) dst-ref: 0x%04x", tpdu_nr, dst_ref); @@ -1446,6 +1541,8 @@ static int ositp_decode_ER(tvbuff_t *tvb, int offset, guint8 li, guint8 tpdu, } dst_ref = tvb_get_ntohs(tvb, offset + P_DST_REF); + pinfo->srcport = 0; + pinfo->destport = dst_ref; if (check_col(pinfo->cinfo, COL_INFO)) col_append_fstr(pinfo->cinfo, COL_INFO, "ER TPDU dst-ref: 0x%04x", dst_ref); @@ -2003,6 +2100,13 @@ clnp_reassemble_init(void) reassembled_table_init(&clnp_reassembled_table); } +static void +cotp_reassemble_init(void) +{ + fragment_table_init(&cotp_segment_table); + reassembled_table_init(&cotp_reassembled_table); +} + void proto_register_clnp(void) { static hf_register_info hf[] = { @@ -2088,6 +2192,7 @@ void proto_register_clnp(void) register_dissector("clnp", dissect_clnp, proto_clnp); register_heur_dissector_list("clnp", &clnp_heur_subdissector_list); register_init_routine(clnp_reassemble_init); + register_init_routine(cotp_reassemble_init); clnp_module = prefs_register_protocol(proto_clnp, NULL); prefs_register_uint_preference(clnp_module, "tp_nsap_selector", @@ -2127,14 +2232,49 @@ void proto_register_cotp(void) { &hf_cotp_type, { "COTP PDU Type", "cotp.type", FT_UINT8, BASE_HEX, VALS(cotp_tpdu_type_abbrev_vals), 0x0, "COTP PDU Type", HFILL}}, + { &hf_cotp_segment_overlap, + { "Segment overlap", "cotp.segment.overlap", FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Segment overlaps with other segments", HFILL }}, + { &hf_cotp_segment_overlap_conflict, + { "Conflicting data in segment overlap", "cotp.segment.overlap.conflict", FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Overlapping segments contained conflicting data", HFILL }}, + { &hf_cotp_segment_multiple_tails, + { "Multiple tail segments found", "cotp.segment.multipletails", FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Several tails were found when reassembling the packet", HFILL }}, + { &hf_cotp_segment_too_long_segment, + { "Segment too long", "cotp.segment.toolongsegment", FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Segment contained data past end of packet", HFILL }}, + { &hf_cotp_segment_error, + { "Reassembly error", "cotp.segment.error", FT_FRAMENUM, BASE_NONE, NULL, 0x0, + "Reassembly error due to illegal segments", HFILL }}, + { &hf_cotp_segment, + { "COTP Segment", "cotp.segment", FT_FRAMENUM, BASE_NONE, NULL, 0x0, + "COTP Segment", HFILL }}, + { &hf_cotp_segments, + { "COTP Segments", "cotp.segments", FT_NONE, BASE_DEC, NULL, 0x0, + "COTP Segments", HFILL }}, + { &hf_cotp_reassembled_in, + { "Reassembled COTP in frame", "cotp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0, + "This COTP packet is reassembled in this frame", HFILL }}, + }; static gint *ett[] = { &ett_cotp, + &ett_cotp_segment, + &ett_cotp_segments, }; + module_t *cotp_module; + proto_cotp = proto_register_protocol(PROTO_STRING_COTP, "COTP", "cotp"); proto_register_field_array(proto_cotp, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); + cotp_module = prefs_register_protocol(proto_cotp, NULL); + + prefs_register_bool_preference(cotp_module, "reassemble", + "Reassemble segmented COTP datagrams", + "Whether segmented COTP datagrams should be reassembled", + &cotp_reassemble); /* subdissector code in inactive subset */ register_heur_dissector_list("cotp_is", &cotp_is_heur_subdissector_list); |