diff options
-rw-r--r-- | epan/dissectors/packet-atm.c | 150 | ||||
-rw-r--r-- | wiretap/netxray.c | 5 | ||||
-rw-r--r-- | wiretap/wtap.h | 6 |
3 files changed, 101 insertions, 60 deletions
diff --git a/epan/dissectors/packet-atm.c b/epan/dissectors/packet-atm.c index a9b253dd9a..653631c76e 100644 --- a/epan/dissectors/packet-atm.c +++ b/epan/dissectors/packet-atm.c @@ -30,6 +30,7 @@ #include <epan/oui.h> #include <epan/addr_resolv.h> #include <epan/ppptypes.h> +#include <epan/expert.h> #include "packet-atm.h" #include "packet-snmp.h" @@ -129,6 +130,8 @@ static gint ett_aal1 = -1; static gint ett_aal3_4 = -1; static gint ett_oamaal = -1; +static expert_field ei_atm_reassembly_failed = EI_INIT; + static dissector_handle_t atm_handle; static dissector_handle_t atm_untruncated_handle; @@ -962,6 +965,7 @@ dissect_reassembled_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 crc; guint32 calc_crc; gint type; + gboolean decoded; /* * This is reassembled traffic, so the cell headers are missing; @@ -999,10 +1003,11 @@ dissect_reassembled_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, } next_tvb = tvb; - if (truncated) { + if (truncated || pinfo->pseudo_header->atm.flags & ATM_REASSEMBLY_ERROR) { /* * The packet data does not include stuff such as the AAL5 - * trailer. + * trailer, either because it was explicitly left out or because + * reassembly failed. */ if (pinfo->pseudo_header->atm.cells != 0) { /* @@ -1026,7 +1031,8 @@ dissect_reassembled_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, } else { /* * The packet data includes stuff such as the AAL5 trailer, if - * it wasn't cut off by the snapshot length. + * it wasn't cut off by the snapshot length, and ATM reassembly + * succeeded. * Decode the trailer, if present, and then chop it off. */ length = tvb_length(tvb); @@ -1098,43 +1104,55 @@ dissect_reassembled_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, } } + decoded = FALSE; + /* + * Don't try to dissect the payload of PDUs with a reassembly + * error. + */ switch (pinfo->pseudo_header->atm.aal) { case AAL_SIGNALLING: - call_dissector(sscop_handle, next_tvb, pinfo, tree); + if (!(pinfo->pseudo_header->atm.flags & ATM_REASSEMBLY_ERROR)) { + call_dissector(sscop_handle, next_tvb, pinfo, tree); + decoded = TRUE; + } break; case AAL_5: - switch (pinfo->pseudo_header->atm.type) { - - case TRAF_SSCOP: - call_dissector(sscop_handle, next_tvb, pinfo, tree); - break; - - case TRAF_FR: - call_dissector(fr_handle, next_tvb, pinfo, tree); - break; - - case TRAF_LLCMX: - call_dissector(llc_handle, next_tvb, pinfo, tree); - break; - - case TRAF_LANE: - call_dissector(lane_handle, next_tvb, pinfo, tree); - break; - - case TRAF_ILMI: - call_dissector(ilmi_handle, next_tvb, pinfo, tree); - break; - - case TRAF_GPRS_NS: - call_dissector(gprs_ns_handle, next_tvb, pinfo, tree); - break; - - default: - { - gboolean decoded = FALSE; - + if (!(pinfo->pseudo_header->atm.flags & ATM_REASSEMBLY_ERROR)) { + switch (pinfo->pseudo_header->atm.type) { + + case TRAF_SSCOP: + call_dissector(sscop_handle, next_tvb, pinfo, tree); + decoded = TRUE; + break; + + case TRAF_FR: + call_dissector(fr_handle, next_tvb, pinfo, tree); + decoded = TRUE; + break; + + case TRAF_LLCMX: + call_dissector(llc_handle, next_tvb, pinfo, tree); + decoded = TRUE; + break; + + case TRAF_LANE: + call_dissector(lane_handle, next_tvb, pinfo, tree); + decoded = TRUE; + break; + + case TRAF_ILMI: + call_dissector(ilmi_handle, next_tvb, pinfo, tree); + decoded = TRUE; + break; + + case TRAF_GPRS_NS: + call_dissector(gprs_ns_handle, next_tvb, pinfo, tree); + decoded = TRUE; + break; + + default: if (tvb_length(next_tvb) > 7) /* sizeof(octet) */ { guint8 octet[8]; @@ -1204,38 +1222,44 @@ dissect_reassembled_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, pinfo->pseudo_header->atm.vci, pinfo->pseudo_header->atm.aal2_cid); - if (pinfo->pseudo_header->atm.flags & ATM_AAL2_NOPHDR) { - next_tvb = tvb; - } else { - /* Skip first 4 bytes of message - - side - - length - - UUI - Ignoring for now... */ - next_tvb = tvb_new_subset_remaining(tvb, 4); - } - - type = pinfo->pseudo_header->atm.type; - if (type == TRAF_UNKNOWN) { - type = unknown_aal2_type; - } - switch (type) { - case TRAF_UMTS_FP: - call_dissector(fp_handle, next_tvb, pinfo, tree); - break; + if (!(pinfo->pseudo_header->atm.flags & ATM_REASSEMBLY_ERROR)) { + if (pinfo->pseudo_header->atm.flags & ATM_AAL2_NOPHDR) { + next_tvb = tvb; + } else { + /* Skip first 4 bytes of message + - side + - length + - UUI + Ignoring for now... */ + next_tvb = tvb_new_subset_remaining(tvb, 4); + } - default: - /* Dump it as raw data. */ - call_dissector(data_handle, next_tvb, pinfo, tree); - break; + type = pinfo->pseudo_header->atm.type; + if (type == TRAF_UNKNOWN) { + type = unknown_aal2_type; + } + switch (type) { + case TRAF_UMTS_FP: + call_dissector(fp_handle, next_tvb, pinfo, tree); + decoded = TRUE; + break; + + default: + /* Dump it as raw data. */ + break; + } } break; default: /* Dump it as raw data. */ - call_dissector(data_handle, next_tvb, pinfo, tree); break; } + + if (tree && !decoded) { + /* Dump it as raw data. */ + call_dissector(data_handle, next_tvb, pinfo, tree); + } } /* @@ -1837,6 +1861,8 @@ dissect_atm_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, if (!pseudowire_mode) { proto_tree_add_uint(atm_tree, hf_atm_channel, tvb, 0, 0, pinfo->pseudo_header->atm.channel); + if (pinfo->pseudo_header->atm.flags & ATM_REASSEMBLY_ERROR) + expert_add_info(pinfo, atm_ti, &ei_atm_reassembly_failed); } proto_tree_add_uint_format_value(atm_tree, hf_atm_aal, tvb, 0, 0, @@ -2133,6 +2159,12 @@ proto_register_atm(void) &ett_atm_lane_lc_tlv, }; + static ei_register_info ei[] = { + { &ei_atm_reassembly_failed, { "atm.reassembly_failed", PI_REASSEMBLE, PI_ERROR, "PDU reassembly failed", EXPFILL }}, + }; + + expert_module_t* expert_atm; + static const enum_val_t unknown_aal2_options[] = { { "raw", "Raw data", TRAF_UNKNOWN }, { "umts_fp", "UMTS FP", TRAF_UMTS_FP }, @@ -2147,6 +2179,8 @@ proto_register_atm(void) proto_oamaal = proto_register_protocol("ATM OAM AAL", "OAM AAL", "oamaal"); proto_register_field_array(proto_atm, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); + expert_atm = expert_register_protocol(proto_atm); + expert_register_field_array(expert_atm, ei, array_length(ei)); proto_ilmi = proto_register_protocol("ILMI", "ILMI", "ilmi"); diff --git a/wiretap/netxray.c b/wiretap/netxray.c index 22267f312f..8c58325738 100644 --- a/wiretap/netxray.c +++ b/wiretap/netxray.c @@ -1460,6 +1460,8 @@ netxray_set_phdr(wtap *wth, struct wtap_pkthdr *phdr, union netxrayrec_hdr *hdr) * a cell is bad? */ phdr->pseudo_header.atm.flags = 0; + if (hdr->hdr_2_x.xxx[8] & 0x01) + phdr->pseudo_header.atm.flags |= ATM_REASSEMBLY_ERROR; /* * XXX - is 0x08 an "OAM cell" flag? * Are the 0x01 and 0x02 bits error indications? @@ -1649,7 +1651,8 @@ netxray_guess_atm_type(wtap *wth, struct wtap_pkthdr *phdr, Buffer *buf) { const guint8 *pd; - if (wth->file_encap == WTAP_ENCAP_ATM_PDUS_UNTRUNCATED) { + if (wth->file_encap == WTAP_ENCAP_ATM_PDUS_UNTRUNCATED && + !(phdr->pseudo_header.atm.flags & ATM_REASSEMBLY_ERROR)) { if (phdr->pseudo_header.atm.aal == AAL_UNKNOWN) { /* * Try to guess the type and subtype based diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 719ed0aeb5..cb09d44430 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -404,7 +404,10 @@ struct isdn_phdr { }; /* Packet "pseudo-header" for ATM capture files. - Not all of this information is supplied by all capture types. */ + Not all of this information is supplied by all capture types. + These originally came from the Network General (DOS-based) + ATM Sniffer file format, but we've added some additional + items. */ /* * Status bits. @@ -412,6 +415,7 @@ struct isdn_phdr { #define ATM_RAW_CELL 0x01 /* TRUE if the packet is a single cell */ #define ATM_NO_HEC 0x02 /* TRUE if the cell has HEC stripped out */ #define ATM_AAL2_NOPHDR 0x04 /* TRUE if the AAL2 PDU has no pseudo-header */ +#define ATM_REASSEMBLY_ERROR 0x08 /* TRUE if this is an incompletely-reassembled PDU */ /* * AAL types. |