aboutsummaryrefslogtreecommitdiffstats
path: root/packet-atm.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2003-01-08 23:07:44 +0000
committerGuy Harris <guy@alum.mit.edu>2003-01-08 23:07:44 +0000
commitf056d1dc8b62abee9bd6cfc47341839a2ca782d1 (patch)
tree7046e0548f62ae3777dfa9e1fda8a4cfb10a55dc /packet-atm.c
parent3c06116a05d9fac4cb8f7cb47b999b550372f1ea (diff)
Make the AAL for a packet a filterable field.
Put the code to handle AAL5 and Signalling AAL traffic, and to handle raw cells, into routines of their own. Don't put the VPI/VCI/cell count information from the pseudo-header into the protocol tree for raw cells - just get the VPI/VCI from the raw cell, and leave out the cell count. Set the Protocol and Info column for AAL1 and AAL3/4 cells. Clean up the names of some of the raw cell fields, as displayed. Make the payload type text match what's in various specs. Display the cell loss priority symbolically. Fix up the code that displays the AAL3/4 trailer information to use the AAL3/4 trailer rather than the AAL3/4 header. Show the number of cells if we have reassembled traffic complete with the AAL5 trailer. svn path=/trunk/; revision=6878
Diffstat (limited to 'packet-atm.c')
-rw-r--r--packet-atm.c572
1 files changed, 309 insertions, 263 deletions
diff --git a/packet-atm.c b/packet-atm.c
index ef2d311900..a037ffd47d 100644
--- a/packet-atm.c
+++ b/packet-atm.c
@@ -1,7 +1,7 @@
/* packet-atm.c
* Routines for ATM packet disassembly
*
- * $Id: packet-atm.c,v 1.51 2003/01/08 08:37:10 guy Exp $
+ * $Id: packet-atm.c,v 1.52 2003/01/08 23:07:44 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -39,6 +39,7 @@
#include "packet-llc.h"
static int proto_atm = -1;
+static int hf_atm_aal = -1;
static int hf_atm_vpi = -1;
static int hf_atm_vci = -1;
static int proto_atm_lane = -1;
@@ -787,11 +788,162 @@ capture_atm(const union wtap_pseudo_header *pseudo_header, const guchar *pd,
ld->other++;
}
+static void
+dissect_reassembled_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ proto_tree *atm_tree, gboolean truncated)
+{
+ guint length, reported_length;
+ guint16 aal5_length;
+ int pad_length;
+ tvbuff_t *next_tvb;
+
+ /*
+ * This is reassembled traffic, so the cell headers are missing;
+ * show the VPI and VCI from the pseudo-header.
+ */
+ proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 0,
+ pinfo->pseudo_header->atm.vpi);
+ proto_tree_add_uint(atm_tree, hf_atm_vci, tvb, 0, 0,
+ pinfo->pseudo_header->atm.vci);
+ if (pinfo->pseudo_header->atm.aal == AAL_5) {
+ proto_tree_add_text(atm_tree, tvb, 0, 0, "Traffic type: %s",
+ val_to_str(pinfo->pseudo_header->atm.type, aal5_hltype_vals,
+ "Unknown AAL5 traffic type (%u)"));
+ switch (pinfo->pseudo_header->atm.type) {
+
+ case TRAF_VCMX:
+ proto_tree_add_text(atm_tree, tvb, 0, 0, "VC multiplexed traffic type: %s",
+ val_to_str(pinfo->pseudo_header->atm.subtype,
+ vcmx_type_vals, "Unknown VCMX traffic type (%u)"));
+ break;
+
+ case TRAF_LANE:
+ proto_tree_add_text(atm_tree, tvb, 0, 0, "LANE traffic type: %s",
+ val_to_str(pinfo->pseudo_header->atm.subtype,
+ lane_type_vals, "Unknown LANE traffic type (%u)"));
+ break;
+
+ case TRAF_IPSILON:
+ proto_tree_add_text(atm_tree, tvb, 0, 0, "Ipsilon traffic type: %s",
+ val_to_str(pinfo->pseudo_header->atm.subtype,
+ ipsilon_type_vals, "Unknown Ipsilon traffic type (%u)"));
+ break;
+ }
+ }
+
+ next_tvb = tvb;
+ if (truncated) {
+ /*
+ * The packet data does not include stuff such as the AAL5
+ * trailer.
+ */
+ if (pinfo->pseudo_header->atm.cells != 0) {
+ /*
+ * If the cell count is 0, assume it means we don't know how
+ * many cells it was.
+ *
+ * XXX - also assume it means we don't know what was in the AAL5
+ * trailer. We may, however, find some capture program that can
+ * give us the AAL5 trailer information but not the cell count,
+ * in which case we need some other way of indicating whether we
+ * have the AAL5 trailer information.
+ */
+ if (tree) {
+ proto_tree_add_text(atm_tree, tvb, 0, 0, "Cells: %u",
+ pinfo->pseudo_header->atm.cells);
+ proto_tree_add_text(atm_tree, tvb, 0, 0, "AAL5 UU: 0x%02x",
+ pinfo->pseudo_header->atm.aal5t_u2u >> 8);
+ proto_tree_add_text(atm_tree, tvb, 0, 0, "AAL5 CPI: 0x%02x",
+ pinfo->pseudo_header->atm.aal5t_u2u & 0xFF);
+ proto_tree_add_text(atm_tree, tvb, 0, 0, "AAL5 len: %u",
+ pinfo->pseudo_header->atm.aal5t_len);
+ proto_tree_add_text(atm_tree, tvb, 0, 0, "AAL5 checksum: 0x%08X",
+ pinfo->pseudo_header->atm.aal5t_chksum);
+ }
+ }
+ } else {
+ /*
+ * The packet data includes stuff such as the AAL5 trailer, if
+ * it wasn't cut off by the snapshot length.
+ * Decode the trailer, if present, and then chop it off.
+ */
+ length = tvb_length(tvb);
+ reported_length = tvb_reported_length(tvb);
+ if ((reported_length % 48) == 0) {
+ /*
+ * Reported length is a multiple of 48, so we can presumably
+ * divide it by 48 to get the number of cells.
+ */
+ proto_tree_add_text(atm_tree, tvb, 0, 0, "Cells: %u",
+ reported_length/48);
+ }
+ if (length >= reported_length) {
+ /*
+ * XXX - what if the packet is truncated? Can that happen?
+ * What if you capture with Windows Sniffer on an ATM link
+ * and tell it not to save the entire packet? What happens
+ * to the trailer?
+ */
+ aal5_length = tvb_get_ntohs(tvb, length - 6);
+ if (tree) {
+ pad_length = length - aal5_length - 8;
+ if (pad_length > 0) {
+ proto_tree_add_text(atm_tree, tvb, aal5_length, pad_length,
+ "Padding");
+ }
+ proto_tree_add_text(atm_tree, tvb, length - 8, 1, "AAL5 UU: 0x%02x",
+ tvb_get_guint8(tvb, length - 8));
+ proto_tree_add_text(atm_tree, tvb, length - 7, 1, "AAL5 CPI: 0x%02x",
+ tvb_get_guint8(tvb, length - 7));
+ proto_tree_add_text(atm_tree, tvb, length - 6, 2, "AAL5 len: %u",
+ aal5_length);
+ /*
+ * XXX - check the checksum.
+ */
+ proto_tree_add_text(atm_tree, tvb, length - 4, 4, "AAL5 checksum: 0x%08X",
+ tvb_get_ntohl(tvb, length - 4));
+ }
+ next_tvb = tvb_new_subset(tvb, 0, aal5_length, aal5_length);
+ }
+ }
+
+ switch (pinfo->pseudo_header->atm.aal) {
+
+ case AAL_SIGNALLING:
+ call_dissector(sscop_handle, next_tvb, pinfo, tree);
+ break;
+
+ case AAL_5:
+ switch (pinfo->pseudo_header->atm.type) {
+
+ 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;
+
+ default:
+ if (tree) {
+ /* Dump it as raw data. */
+ call_dissector(data_handle, next_tvb, pinfo, tree);
+ break;
+ }
+ }
+ break;
+ }
+}
+
static const value_string pt_vals[] = {
- { 0, "User data, congestion not experienced, SDU-type 0" },
- { 1, "User data, congestion not experienced, SDU-type 1" },
- { 2, "User data, congestion experienced, SDU-type 0" },
- { 3, "User data, congestion experienced, SDU-type 1" },
+ { 0, "User data cell, congestion not experienced, SDU-type = 0" },
+ { 1, "User data cell, congestion not experienced, SDU-type = 1" },
+ { 2, "User data cell, congestion experienced, SDU-type = 0" },
+ { 3, "User data cell, congestion experienced, SDU-type = 1" },
{ 4, "Segment OAM F5 flow related cell" },
{ 5, "End-to-end OAM F5 flow related cell" },
{ 0, NULL }
@@ -838,21 +990,148 @@ static const value_string ft_ad_vals[] = {
};
static void
-dissect_atm_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- gboolean truncated)
+dissect_atm_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ proto_tree *atm_tree)
{
int offset;
- proto_tree *atm_tree = NULL, *aal_tree;
- proto_item *ti = NULL;
- tvbuff_t *next_tvb;
- guint length, reported_length;
- guint16 aal5_length;
- int pad_length;
+ proto_tree *aal_tree;
+ proto_item *ti;
guint8 octet;
guint8 vpi;
guint16 vci;
guint16 aal3_4_hdr, aal3_4_trlr;
guint16 oam_crc;
+ tvbuff_t *next_tvb;
+
+ octet = tvb_get_guint8(tvb, 0);
+ proto_tree_add_text(atm_tree, tvb, 0, 1, "GFC: 0x%x", octet >> 4);
+ vpi = (octet & 0xF0) << 4;
+ octet = tvb_get_guint8(tvb, 1);
+ vpi |= octet >> 4;
+ proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 2, vpi);
+ vci = (octet & 0x0F) << 12;
+ octet = tvb_get_guint8(tvb, 2);
+ vci |= octet << 4;
+ octet = tvb_get_guint8(tvb, 3);
+ vci |= octet >> 4;
+ proto_tree_add_uint(atm_tree, hf_atm_vci, tvb, 1, 3, vci);
+ proto_tree_add_text(atm_tree, tvb, 3, 1, "Payload Type: %s",
+ val_to_str((octet >> 1) & 0x7, pt_vals, "Unknown (%u)"));
+ proto_tree_add_text(atm_tree, tvb, 3, 1, "Cell Loss Priority: %s",
+ (octet & 0x01) ? "Low priority" : "High priority");
+ proto_tree_add_text(atm_tree, tvb, 4, 1, "Header Error Check: 0x%02x",
+ tvb_get_guint8(tvb, 4));
+ offset = 5;
+
+ switch (pinfo->pseudo_header->atm.aal) {
+
+ case AAL_1:
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "AAL1");
+ ti = proto_tree_add_item(tree, proto_aal1, tvb, offset, -1, FALSE);
+ aal_tree = proto_item_add_subtree(ti, ett_aal1);
+ octet = tvb_get_guint8(tvb, offset);
+ proto_tree_add_text(aal_tree, tvb, offset, 1, "CSI: %u", octet >> 7);
+ proto_tree_add_text(aal_tree, tvb, offset, 1, "Sequence Count: %u",
+ (octet >> 4) & 0x7);
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Sequence count = %u",
+ (octet >> 4) & 0x7);
+ }
+ proto_tree_add_text(aal_tree, tvb, offset, 1, "CRC: 0x%x",
+ (octet >> 1) & 0x7);
+ proto_tree_add_text(aal_tree, tvb, offset, 1, "Parity: %u",
+ octet & 0x1);
+ offset++;
+
+ proto_tree_add_text(aal_tree, tvb, offset, 47, "Payload");
+ break;
+
+ case AAL_3_4:
+ /*
+ * XXX - or should this be the CS PDU?
+ */
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "AAL3/4");
+ ti = proto_tree_add_item(tree, proto_aal3_4, tvb, offset, -1, FALSE);
+ aal_tree = proto_item_add_subtree(ti, ett_aal3_4);
+ aal3_4_hdr = tvb_get_ntohs(tvb, offset);
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_add_fstr(pinfo->cinfo, COL_INFO, "%s, sequence number = %u",
+ val_to_str(aal3_4_hdr >> 14, st_vals, "Unknown (%u)"),
+ (aal3_4_hdr >> 10) & 0xF);
+ }
+ proto_tree_add_text(aal_tree, tvb, offset, 2, "Segment Type: %s",
+ val_to_str(aal3_4_hdr >> 14, st_vals, "Unknown (%u)"));
+ proto_tree_add_text(aal_tree, tvb, offset, 2, "Sequence Number: %u",
+ (aal3_4_hdr >> 10) & 0xF);
+ proto_tree_add_text(aal_tree, tvb, offset, 2, "Multiplex ID: %u",
+ aal3_4_hdr & 0x3FF);
+ offset += 2;
+
+ proto_tree_add_text(aal_tree, tvb, offset, 44, "Information");
+ offset += 44;
+
+ aal3_4_trlr = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_text(aal_tree, tvb, offset, 2, "Length Indicator: %u",
+ (aal3_4_trlr >> 10) & 0x3F);
+ proto_tree_add_text(aal_tree, tvb, offset, 2, "CRC: 0x%03x",
+ aal3_4_trlr & 0x3FF);
+ break;
+
+ case AAL_OAMCELL:
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "OAM AAL");
+ ti = proto_tree_add_item(tree, proto_oamaal, tvb, offset, -1, FALSE);
+ aal_tree = proto_item_add_subtree(ti, ett_oamaal);
+ octet = tvb_get_guint8(tvb, offset);
+ proto_tree_add_text(aal_tree, tvb, offset, 2, "OAM Type: %s",
+ val_to_str(octet >> 4, oam_type_vals, "Unknown (%u)"));
+ switch (octet >> 4) {
+
+ case OAM_TYPE_FM:
+ proto_tree_add_text(aal_tree, tvb, offset, 2, "Function Type: %s",
+ val_to_str(octet & 0x0F, ft_fm_vals, "Unknown (%u)"));
+ break;
+
+ case OAM_TYPE_PM:
+ proto_tree_add_text(aal_tree, tvb, offset, 2, "Function Type: %s",
+ val_to_str(octet & 0x0F, ft_pm_vals, "Unknown (%u)"));
+ break;
+
+ case OAM_TYPE_AD:
+ proto_tree_add_text(aal_tree, tvb, offset, 2, "Function Type: %s",
+ val_to_str(octet & 0x0F, ft_ad_vals, "Unknown (%u)"));
+ break;
+
+ default:
+ proto_tree_add_text(aal_tree, tvb, offset, 2, "Function Type: %u",
+ octet & 0x0F);
+ break;
+ }
+ offset += 1;
+
+ proto_tree_add_text(aal_tree, tvb, offset, 45, "Function-specific information");
+ offset += 45;
+
+ oam_crc = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_text(aal_tree, tvb, offset, 2, "CRC-10: 0x%03x",
+ oam_crc & 0x3FF);
+ break;
+
+ default:
+ next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+ call_dissector(data_handle, next_tvb, pinfo, tree);
+ break;
+ }
+}
+
+static void
+dissect_atm_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ gboolean truncated)
+{
+ proto_tree *atm_tree = NULL;
+ proto_item *ti = NULL;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM");
@@ -892,38 +1171,6 @@ dissect_atm_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
ti = proto_tree_add_protocol_format(tree, proto_atm, tvb, 0, 0, "ATM");
atm_tree = proto_item_add_subtree(ti, ett_atm);
- proto_tree_add_text(atm_tree, tvb, 0, 0, "AAL: %s",
- val_to_str(pinfo->pseudo_header->atm.aal, aal_vals,
- "Unknown AAL (%u)"));
- if (pinfo->pseudo_header->atm.aal == AAL_5) {
- proto_tree_add_text(atm_tree, tvb, 0, 0, "Traffic type: %s",
- val_to_str(pinfo->pseudo_header->atm.type, aal5_hltype_vals,
- "Unknown AAL5 traffic type (%u)"));
- switch (pinfo->pseudo_header->atm.type) {
-
- case TRAF_VCMX:
- proto_tree_add_text(atm_tree, tvb, 0, 0, "VC multiplexed traffic type: %s",
- val_to_str(pinfo->pseudo_header->atm.subtype,
- vcmx_type_vals, "Unknown VCMX traffic type (%u)"));
- break;
-
- case TRAF_LANE:
- proto_tree_add_text(atm_tree, tvb, 0, 0, "LANE traffic type: %s",
- val_to_str(pinfo->pseudo_header->atm.subtype,
- lane_type_vals, "Unknown LANE traffic type (%u)"));
- break;
-
- case TRAF_IPSILON:
- proto_tree_add_text(atm_tree, tvb, 0, 0, "Ipsilon traffic type: %s",
- val_to_str(pinfo->pseudo_header->atm.subtype,
- ipsilon_type_vals, "Unknown Ipsilon traffic type (%u)"));
- break;
- }
- }
- proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 0,
- pinfo->pseudo_header->atm.vpi);
- proto_tree_add_uint(atm_tree, hf_atm_vci, tvb, 0, 0,
- pinfo->pseudo_header->atm.vci);
switch (pinfo->pseudo_header->atm.channel) {
case 0:
@@ -942,226 +1189,21 @@ dissect_atm_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
pinfo->pseudo_header->atm.channel);
break;
}
- }
- next_tvb = tvb;
- if (truncated) {
- /*
- * The packet data does not include stuff such as the AAL5
- * trailer.
- */
- if (pinfo->pseudo_header->atm.cells != 0) {
- /*
- * If the cell count is 0, assume it means we don't know how
- * many cells it was.
- *
- * XXX - also, if this is AAL5 traffic, assume it means we don't
- * know what was in the AAL5 trailer. We may, however, find
- * some capture program that can give us the AAL5 trailer
- * information but not the cell count, in which case we need
- * some other way of indicating whether we have the AAL5 trailer
- * information.
- */
- if (tree) {
- proto_tree_add_text(atm_tree, tvb, 0, 0, "Cells: %u",
- pinfo->pseudo_header->atm.cells);
- if (pinfo->pseudo_header->atm.aal == AAL_5) {
- proto_tree_add_text(atm_tree, tvb, 0, 0, "AAL5 UU: 0x%02x",
- pinfo->pseudo_header->atm.aal5t_u2u >> 8);
- proto_tree_add_text(atm_tree, tvb, 0, 0, "AAL5 CPI: 0x%02x",
- pinfo->pseudo_header->atm.aal5t_u2u & 0xFF);
- proto_tree_add_text(atm_tree, tvb, 0, 0, "AAL5 len: %u",
- pinfo->pseudo_header->atm.aal5t_len);
- proto_tree_add_text(atm_tree, tvb, 0, 0, "AAL5 checksum: 0x%08X",
- pinfo->pseudo_header->atm.aal5t_chksum);
- }
- }
- }
- } else {
- /*
- * The packet data includes stuff such as the AAL5 trailer.
- * If this is AAL5 or Signalling AAL traffic, process it,
- * and then strip off the trailer.
- */
- if (pinfo->pseudo_header->atm.aal == AAL_5 ||
- pinfo->pseudo_header->atm.aal == AAL_SIGNALLING) {
- length = tvb_length(tvb);
- reported_length = tvb_reported_length(tvb);
- if (length >= reported_length) {
- /*
- * XXX - what if the packet is truncated? Can that happen?
- * What if you capture with Windows Sniffer on an ATM link
- * and tell it not to save the entire packet? What happens
- * to the trailer?
- */
- aal5_length = tvb_get_ntohs(tvb, length - 6);
- if (tree) {
- pad_length = length - aal5_length - 8;
- if (pad_length > 0) {
- proto_tree_add_text(atm_tree, tvb, aal5_length, pad_length,
- "Padding");
- }
- proto_tree_add_text(atm_tree, tvb, length - 8, 1, "AAL5 UU: 0x%02x",
- tvb_get_guint8(tvb, length - 8));
- proto_tree_add_text(atm_tree, tvb, length - 7, 1, "AAL5 CPI: 0x%02x",
- tvb_get_guint8(tvb, length - 7));
- proto_tree_add_text(atm_tree, tvb, length - 6, 2, "AAL5 len: %u",
- aal5_length);
- /*
- * XXX - check the checksum.
- */
- proto_tree_add_text(atm_tree, tvb, length - 4, 4, "AAL5 checksum: 0x%08X",
- tvb_get_ntohl(tvb, length - 4));
- }
- next_tvb = tvb_new_subset(tvb, 0, aal5_length, aal5_length);
- }
- }
+ proto_tree_add_uint_format(atm_tree, hf_atm_aal, tvb, 0, 0,
+ pinfo->pseudo_header->atm.aal,
+ "AAL: %s",
+ val_to_str(pinfo->pseudo_header->atm.aal, aal_vals,
+ "Unknown AAL (%u)"));
}
-
- switch (pinfo->pseudo_header->atm.aal) {
-
- case AAL_SIGNALLING:
- call_dissector(sscop_handle, next_tvb, pinfo, tree);
- break;
-
- case AAL_5:
- switch (pinfo->pseudo_header->atm.type) {
-
- case TRAF_LLCMX:
- /* Dissect as WTAP_ENCAP_ATM_RFC1483 */
- /* The ATM iptrace capture that we have shows LLC at this point,
- * so that's what I'm calling */
- 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;
-
- default:
- if (tree) {
- /* Dump it as raw data. */
- call_dissector(data_handle, next_tvb, pinfo, tree);
- break;
- }
- }
- break;
-
- default:
- if (tree) {
- /* Assume this is a single cell. */
- proto_item_set_len(ti, 5);
- octet = tvb_get_guint8(tvb, 0);
- proto_tree_add_text(atm_tree, tvb, 0, 1, "GFC: 0x%x", octet >> 4);
- vpi = (octet & 0xF0) << 4;
- octet = tvb_get_guint8(tvb, 1);
- vpi |= octet >> 4;
- proto_tree_add_text(atm_tree, tvb, 0, 2, "VPI: %u", vpi);
- vci = (octet & 0x0F) << 12;
- octet = tvb_get_guint8(tvb, 2);
- vci |= octet << 4;
- octet = tvb_get_guint8(tvb, 3);
- vci |= octet >> 4;
- proto_tree_add_text(atm_tree, tvb, 1, 3, "VCI: %u", vci);
- proto_tree_add_text(atm_tree, tvb, 3, 1, "PT: %s",
- val_to_str((octet >> 1) & 0x7, pt_vals, "Unknown (%u)"));
- proto_tree_add_text(atm_tree, tvb, 3, 1, "CLP: %u", octet & 0x01);
- proto_tree_add_text(atm_tree, tvb, 4, 1, "HEC: 0x%02x",
- tvb_get_guint8(tvb, 4));
- offset = 5;
-
- switch (pinfo->pseudo_header->atm.aal) {
-
- case AAL_1:
- ti = proto_tree_add_item(tree, proto_aal1, tvb, offset, -1, FALSE);
- aal_tree = proto_item_add_subtree(ti, ett_aal1);
- octet = tvb_get_guint8(tvb, offset);
- proto_tree_add_text(aal_tree, tvb, offset, 1, "CSI: %u", octet >> 7);
- proto_tree_add_text(aal_tree, tvb, offset, 1, "SC: %u",
- (octet >> 4) & 0x7);
- proto_tree_add_text(aal_tree, tvb, offset, 1, "CRC: 0x%x",
- (octet >> 1) & 0x7);
- proto_tree_add_text(aal_tree, tvb, offset, 1, "Parity: %u",
- octet & 0x1);
- offset++;
-
- proto_tree_add_text(aal_tree, tvb, offset, 47, "Payload");
- break;
-
- case AAL_3_4:
- /*
- * XXX - or should this be the CS PDU?
- */
- ti = proto_tree_add_item(tree, proto_aal3_4, tvb, offset, -1, FALSE);
- aal_tree = proto_item_add_subtree(ti, ett_aal3_4);
- aal3_4_hdr = tvb_get_ntohs(tvb, offset);
- proto_tree_add_text(aal_tree, tvb, offset, 2, "ST: %s",
- val_to_str(aal3_4_hdr >> 14, st_vals, "Unknown (%u)"));
- proto_tree_add_text(aal_tree, tvb, offset, 2, "SN: %u",
- (aal3_4_hdr >> 10) & 0xF);
- proto_tree_add_text(aal_tree, tvb, offset, 2, "MID: %u",
- aal3_4_hdr & 0x3FF);
- offset += 2;
-
- proto_tree_add_text(aal_tree, tvb, offset, 44, "Information");
- offset += 44;
-
- aal3_4_trlr = tvb_get_ntohs(tvb, offset);
- proto_tree_add_text(aal_tree, tvb, offset, 2, "LI: %u",
- (aal3_4_hdr >> 10) & 0x3F);
- proto_tree_add_text(aal_tree, tvb, offset, 2, "CRC: 0x%03x",
- aal3_4_hdr & 0x3FF);
- break;
-
- case AAL_OAMCELL:
- ti = proto_tree_add_item(tree, proto_oamaal, tvb, offset, -1, FALSE);
- aal_tree = proto_item_add_subtree(ti, ett_oamaal);
- octet = tvb_get_guint8(tvb, offset);
- proto_tree_add_text(aal_tree, tvb, offset, 2, "OAM Type: %s",
- val_to_str(octet >> 4, oam_type_vals, "Unknown (%u)"));
- switch (octet >> 4) {
-
- case OAM_TYPE_FM:
- proto_tree_add_text(aal_tree, tvb, offset, 2, "Function Type: %s",
- val_to_str(octet & 0x0F, ft_fm_vals, "Unknown (%u)"));
- break;
-
- case OAM_TYPE_PM:
- proto_tree_add_text(aal_tree, tvb, offset, 2, "Function Type: %s",
- val_to_str(octet & 0x0F, ft_pm_vals, "Unknown (%u)"));
- break;
-
- case OAM_TYPE_AD:
- proto_tree_add_text(aal_tree, tvb, offset, 2, "Function Type: %s",
- val_to_str(octet & 0x0F, ft_ad_vals, "Unknown (%u)"));
- break;
-
- default:
- proto_tree_add_text(aal_tree, tvb, offset, 2, "Function Type: %u",
- octet & 0x0F);
- break;
- }
- offset += 1;
-
- proto_tree_add_text(aal_tree, tvb, offset, 45, "Function-specific information");
- offset += 45;
-
- oam_crc = tvb_get_ntohs(tvb, offset);
- proto_tree_add_text(aal_tree, tvb, offset, 2, "CRC-10: 0x%03x",
- oam_crc & 0x3FF);
- break;
-
- default:
- next_tvb = tvb_new_subset(tvb, offset, -1, -1);
- call_dissector(data_handle, next_tvb, pinfo, tree);
- break;
- }
- }
- break;
+ if (pinfo->pseudo_header->atm.aal == AAL_5 ||
+ pinfo->pseudo_header->atm.aal == AAL_SIGNALLING) {
+ /* This is a reassembled PDU. */
+ dissect_reassembled_pdu(tvb, pinfo, tree, atm_tree, truncated);
+ } else {
+ /* Assume this is a single cell, with the cell header at the beginning. */
+ proto_item_set_len(ti, 5);
+ dissect_atm_cell(tvb, pinfo, tree, atm_tree);
}
}
@@ -1181,6 +1223,10 @@ void
proto_register_atm(void)
{
static hf_register_info hf[] = {
+ { &hf_atm_aal,
+ { "AAL", "atm.aal", FT_UINT8, BASE_DEC, VALS(aal_vals), 0x0,
+ "", HFILL }},
+
{ &hf_atm_vpi,
{ "VPI", "atm.vpi", FT_UINT8, BASE_DEC, NULL, 0x0,
"", HFILL }},