From Artem Tamazov:

Added: PW ATM 1:1, AAL5 SDU, AAL5 PDU support + BFD fix + PW ATM OAM fix

svn path=/trunk/; revision=28881
This commit is contained in:
Anders Broman 2009-06-29 19:24:14 +00:00
parent a539aa732c
commit a98ce52e80
12 changed files with 2412 additions and 693 deletions

View File

@ -1151,6 +1151,7 @@ DISSECTOR_INCLUDES = \
packet-ppi.h \
packet-ppp.h \
packet-pres.h \
packet-pw-atm.h \
packet-pw-common.h \
packet-q931.h \
packet-q932.h \

View File

@ -39,6 +39,7 @@
#include "packet-tr.h"
#include "packet-llc.h"
#include "prefs.h"
#include "packet-pw-atm.h"
static int proto_atm = -1;
static int hf_atm_aal = -1;
@ -50,7 +51,6 @@ static int proto_ilmi = -1;
static int proto_aal1 = -1;
static int proto_aal3_4 = -1;
static int proto_oamaal = -1;
static int proto_atm_4717 = -1;
static gint ett_atm = -1;
static gint ett_atm_lane = -1;
@ -934,6 +934,13 @@ dissect_reassembled_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
tvbuff_t *next_tvb;
guint32 crc;
guint32 calc_crc;
/*
* ATM dissector is used as "sub-dissector" for ATM pseudowires.
* In such cases, pinfo->private_data is used to pass info from/to
* PW dissector to ATM dissector. For decoding normal ATM traffic
* private_data should be NULL.
*/
gboolean pseudowire_mode = (NULL != pinfo->private_data);
/*
* This is reassembled traffic, so the cell headers are missing;
@ -965,20 +972,21 @@ dissect_reassembled_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
break;
}
}
proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 0,
if (!pseudowire_mode) {
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,
proto_tree_add_uint(atm_tree, hf_atm_vci, tvb, 0, 0,
pinfo->pseudo_header->atm.vci);
/* Also show vpi/vci in info column */
if (check_col(pinfo->cinfo, COL_INFO))
{
/* Also show vpi/vci in info column */
if (check_col(pinfo->cinfo, COL_INFO))
{
col_append_fstr(pinfo->cinfo, COL_INFO, " VPI=%u, VCI=%u",
pinfo->pseudo_header->atm.vpi,
pinfo->pseudo_header->atm.vci);
}
}
next_tvb = tvb;
if (truncated) {
/*
@ -1120,7 +1128,13 @@ dissect_reassembled_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
tvb_memcpy(next_tvb, octet, 0, sizeof(octet));
decoded = TRUE;
if ((pntohs(octet) & 0xff) == PPP_IP)
if (octet[0] == 0xaa
&& octet[1] == 0xaa
&& octet[2] == 0x03) /* LLC SNAP as per RFC2684 */
{
call_dissector(llc_handle, next_tvb, pinfo, tree);
}
else if ((pntohs(octet) & 0xff) == PPP_IP)
{
call_dissector(ppp_handle, next_tvb, pinfo, tree);
}
@ -1413,13 +1427,14 @@ get_header_err(const guint8 *cell_header)
return UNCORRECTIBLE_ERROR;
}
static const value_string pt_vals[] = {
const value_string atm_pt_vals[] = {
{ 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" },
{ 6, "VC resource management cell" },
{ 0, NULL }
};
@ -1522,6 +1537,19 @@ static const value_string ft_ad_vals[] = {
{ 0, NULL }
};
/*
* Check for OAM cells.
* OAM F4 is VCI 3 or 4 and PT 0X0.
* OAM F5 is PT 10X.
*/
gboolean atm_is_oam_cell(const guint16 vci, const guint8 pt)
{
return (((vci == 3 || vci == 4) && ((pt & 0x5) == 0))
|| ((pt & 0x6) == 0x4));
}
static void
dissect_atm_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_tree *atm_tree, guint aal, gboolean nni,
@ -1540,8 +1568,10 @@ dissect_atm_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
gint length;
guint16 crc10;
tvbuff_t *next_tvb;
const pwatm_private_data_t * pwpd = pinfo->private_data;
if (!nni) {
if (NULL == pwpd) {
if (!nni) {
/*
* FF: ITU-T I.361 (Section 2.2) defines the cell header format
* and encoding at UNI reference point as:
@ -1565,7 +1595,7 @@ dissect_atm_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
octet = tvb_get_guint8(tvb, 1);
vpi |= octet >> 4;
proto_tree_add_uint(atm_tree, hf_atm_vpi, tvb, 0, 2, vpi);
} else {
} else {
/*
* FF: ITU-T I.361 (Section 2.3) defines the cell header format
* and encoding at NNI reference point as:
@ -1588,21 +1618,21 @@ dissect_atm_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
octet = tvb_get_guint8(tvb, 1);
vpi |= (octet & 0xF0) >> 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);
pt = (octet >> 1) & 0x7;
proto_tree_add_text(atm_tree, tvb, 3, 1, "Payload Type: %s",
val_to_str(pt, pt_vals, "Unknown (%u)"));
proto_tree_add_text(atm_tree, tvb, 3, 1, "Cell Loss Priority: %s",
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);
pt = (octet >> 1) & 0x7;
proto_tree_add_text(atm_tree, tvb, 3, 1, "Payload Type: %s",
val_to_str(pt, atm_pt_vals, "Unknown (%u)"));
proto_tree_add_text(atm_tree, tvb, 3, 1, "Cell Loss Priority: %s",
(octet & 0x01) ? "Low priority" : "High priority");
if (!crc_stripped) {
if (!crc_stripped) {
/*
* FF: parse the Header Error Check (HEC).
*/
@ -1617,13 +1647,22 @@ dissect_atm_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
else
proto_item_append_text(ti, " (error in bit %d)", err);
offset = 5;
} else {
} else {
/*
* FF: in some encapsulation modes (e.g. RFC 4717, ATM N-to-One
* Cell Mode) the Header Error Check (HEC) field is stripped.
* So we do nothing here.
*/
offset = 4;
}
}
else
{
offset = 0; /* For PWs. Header is decoded by PW dissector.*/
pwpd = pinfo->private_data;
vpi = pwpd->vpi;
vci = pwpd->vci;
pt = pwpd->pti;
}
/*
@ -1632,13 +1671,9 @@ dissect_atm_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
* Wiretap got from the file?
*/
if (aal == AAL_USER) {
/*
* OAM F4 is VCI 3 or 4 and PT 0X0.
* OAM F5 is PT 10X.
*/
if (((vci == 3 || vci == 4) && ((pt & 0x5) == 0)) ||
((pt & 0x6) == 0x4))
aal = AAL_OAMCELL;
if (atm_is_oam_cell(vci,pt)) {
aal = AAL_OAMCELL;
}
}
switch (aal) {
@ -1706,16 +1741,22 @@ dissect_atm_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
break;
case AAL_OAMCELL:
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "OAM AAL");
if (check_col(pinfo->cinfo, COL_INFO))
col_clear(pinfo->cinfo, COL_INFO);
if (NULL == pwpd || pwpd->enable_fill_columns_by_atm_dissector)
{
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "OAM AAL");
if (check_col(pinfo->cinfo, COL_INFO))
col_clear(pinfo->cinfo, COL_INFO);
}
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);
if (check_col(pinfo->cinfo, COL_INFO))
col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
if (NULL == pwpd || pwpd->enable_fill_columns_by_atm_dissector)
{
if (check_col(pinfo->cinfo, COL_INFO))
col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
val_to_str(octet >> 4, oam_type_vals, "Unknown (%u)"));
}
proto_tree_add_text(aal_tree, tvb, offset, 1, "OAM Type: %s",
val_to_str(octet >> 4, oam_type_vals, "Unknown (%u)"));
switch (octet >> 4) {
@ -1767,6 +1808,7 @@ dissect_atm_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
{
proto_tree *atm_tree = NULL;
proto_item *atm_ti = NULL;
gboolean pseudowire_mode = (NULL != pinfo->private_data);
if ( pinfo->pseudo_header->atm.aal == AAL_5 &&
pinfo->pseudo_header->atm.type == TRAF_LANE &&
@ -1777,23 +1819,25 @@ dissect_atm_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM");
switch (pinfo->pseudo_header->atm.channel) {
if (!pseudowire_mode) {
switch (pinfo->pseudo_header->atm.channel) {
case 0:
/* Traffic from DTE to DCE. */
if (check_col(pinfo->cinfo, COL_RES_DL_DST))
col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE");
if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE");
break;
case 0:
/* Traffic from DTE to DCE. */
if (check_col(pinfo->cinfo, COL_RES_DL_DST))
col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE");
if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE");
break;
case 1:
/* Traffic from DCE to DTE. */
if (check_col(pinfo->cinfo, COL_RES_DL_DST))
col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE");
if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE");
break;
case 1:
/* Traffic from DCE to DTE. */
if (check_col(pinfo->cinfo, COL_RES_DL_DST))
col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE");
if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE");
break;
}
}
if (check_col(pinfo->cinfo, COL_INFO)) {
@ -1812,23 +1856,25 @@ dissect_atm_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
atm_ti = proto_tree_add_protocol_format(tree, proto_atm, tvb, 0, 0, "ATM");
atm_tree = proto_item_add_subtree(atm_ti, ett_atm);
switch (pinfo->pseudo_header->atm.channel) {
if (!pseudowire_mode) {
switch (pinfo->pseudo_header->atm.channel) {
case 0:
/* Traffic from DTE to DCE. */
proto_tree_add_text(atm_tree, tvb, 0, 0, "Channel: DTE->DCE");
break;
case 0:
/* Traffic from DTE to DCE. */
proto_tree_add_text(atm_tree, tvb, 0, 0, "Channel: DTE->DCE");
break;
case 1:
/* Traffic from DCE to DTE. */
proto_tree_add_text(atm_tree, tvb, 0, 0, "Channel: DCE->DTE");
break;
case 1:
/* Traffic from DCE to DTE. */
proto_tree_add_text(atm_tree, tvb, 0, 0, "Channel: DCE->DTE");
break;
default:
/* Sniffers shouldn't provide anything other than 0 or 1. */
proto_tree_add_text(atm_tree, tvb, 0, 0, "Channel: %u",
default:
/* Sniffers shouldn't provide anything other than 0 or 1. */
proto_tree_add_text(atm_tree, tvb, 0, 0, "Channel: %u",
pinfo->pseudo_header->atm.channel);
break;
break;
}
}
proto_tree_add_uint_format_value(atm_tree, hf_atm_aal, tvb, 0, 0,
@ -1865,59 +1911,21 @@ dissect_atm_oam_cell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_tree *atm_tree = NULL;
proto_item *atm_ti = NULL;
gboolean pseudowire_mode = (NULL != pinfo->private_data);
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM");
if (tree) {
atm_ti = proto_tree_add_protocol_format(tree, proto_atm, tvb, 0, 0, "ATM");
atm_tree = proto_item_add_subtree(atm_ti, ett_atm);
if (!pseudowire_mode) {
if (tree) {
atm_ti = proto_tree_add_protocol_format(tree, proto_atm, tvb, 0, 0, "ATM");
atm_tree = proto_item_add_subtree(atm_ti, ett_atm);
}
}
dissect_atm_cell(tvb, pinfo, tree, atm_tree, AAL_OAMCELL, FALSE, FALSE);
}
/*
* FF: this dissector is called directly from packet-pw-atm.c.
* it checks pinfo->pw_atm_encap_type, pinfo->pw_atm_flags
* in order to gather information about the used encapsulation
* format (defined in RFC 4717). The result (i.e. protocol tree
* and cinfo) of this dissector should look like, as close as
* possible, to the legacy one (i.e. dissect_atm_[untruncated|oam_cell]).
*/
static void
dissect_atm_4717(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_tree *atm_tree = NULL;
proto_item *atm_ti = NULL;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATM");
if (tree) {
atm_ti = proto_tree_add_protocol_format(tree,
proto_atm,
tvb, 0, 0, "ATM");
atm_tree = proto_item_add_subtree(atm_ti, ett_atm);
}
switch (pinfo->pw_atm_encap_type) {
case 1: /* ATM N-to-One Cell Mode */
if (check_col(pinfo->cinfo, COL_INFO)) {
col_add_str(pinfo->cinfo, COL_INFO, "Unknown AAL");
col_append_fstr(pinfo->cinfo, COL_INFO,
" (%u cell%s)",
pinfo->pw_atm_ncells,
pinfo->pw_atm_ncells == 1 ? "" : "s");
}
proto_item_set_len(atm_ti, 4);
dissect_atm_cell(tvb, pinfo, tree, atm_tree,
AAL_UNKNOWN, TRUE, TRUE);
break;
default:
break;
}
}
void
proto_register_atm(void)
@ -1971,8 +1979,8 @@ proto_register_atm(void)
register_dissector("lane", dissect_lane, proto_atm_lane);
register_dissector("atm_untruncated", dissect_atm_untruncated, proto_atm);
register_dissector("atm_truncated", dissect_atm, proto_atm);
register_dissector("atm_oam_cell", dissect_atm_oam_cell, proto_oamaal);
register_dissector("atm_4717", dissect_atm_4717, proto_atm_4717);
atm_module = prefs_register_protocol ( proto_atm, NULL );
prefs_register_bool_preference ( atm_module, "dissect_lane_as_sscop", "Dissect LANE as SSCOP",
@ -1983,7 +1991,7 @@ proto_register_atm(void)
void
proto_reg_handoff_atm(void)
{
dissector_handle_t atm_handle, atm_untruncated_handle, atm_4717_handle;
dissector_handle_t atm_handle, atm_untruncated_handle;
/*
* Get handles for the Ethernet, Token Ring, Frame Relay, LLC,
@ -2009,6 +2017,4 @@ proto_reg_handoff_atm(void)
proto_atm);
dissector_add("wtap_encap", WTAP_ENCAP_ATM_PDUS_UNTRUNCATED,
atm_untruncated_handle);
atm_4717_handle = create_dissector_handle(dissect_atm_4717, proto_atm);
}

View File

@ -27,4 +27,8 @@
void capture_atm(const union wtap_pseudo_header *, const guchar *, int,
packet_counts *);
gboolean atm_is_oam_cell(const guint16 vci, const guint8 pt); /*For pw-atm dissector*/
extern const value_string atm_pt_vals[]; /*For pw-atm dissector*/
#endif

View File

@ -685,6 +685,7 @@ void proto_register_bfd(void)
proto_bfd = proto_register_protocol("Bidirectional Forwarding Detection Control Message",
"BFD Control",
"bfd");
register_dissector("bfd", dissect_bfd_control, proto_bfd);
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array(proto_bfd, hf, array_length(hf));

View File

@ -58,6 +58,7 @@
#include <epan/addr_resolv.h>
#include "packet-ppp.h"
#include "packet-mpls.h"
#include "packet-pw-common.h"
static gint proto_mpls = -1;
static gint proto_pw_ach = -1;
@ -92,6 +93,7 @@ enum mpls_filter_keys {
static dissector_handle_t dissector_data;
static dissector_handle_t dissector_ipv6;
static dissector_handle_t dissector_ip;
static dissector_handle_t dissector_bfd;
static dissector_handle_t dissector_pw_eth_heuristic;
static dissector_handle_t dissector_pw_fr;
static dissector_handle_t dissector_pw_hdlc_nocw_fr;
@ -100,6 +102,10 @@ static dissector_handle_t dissector_pw_eth_cw;
static dissector_handle_t dissector_pw_eth_nocw;
static dissector_handle_t dissector_pw_satop;
static dissector_handle_t dissector_itdm;
static dissector_handle_t dissector_mpls_pw_atm_n1_cw;
static dissector_handle_t dissector_mpls_pw_atm_n1_nocw;
static dissector_handle_t dissector_mpls_pw_atm_11_aal5pdu;
static dissector_handle_t dissector_mpls_pw_atm_aal5_sdu;
static dissector_handle_t dissector_pw_cesopsn;
enum mpls_default_dissector_t {
@ -113,6 +119,10 @@ enum mpls_default_dissector_t {
,MDD_MPLS_PW_ETH_NOCW
,MDD_MPLS_PW_GENERIC
,MDD_ITDM
,MDD_MPLS_PW_ATM_N1_CW
,MDD_MPLS_PW_ATM_N1_NOCW
,MDD_MPLS_PW_ATM_11_OR_AAL5_PDU
,MDD_MPLS_PW_ATM_AAL5_SDU
};
/* TODO the content of mpls_default_payload menu
@ -123,12 +133,12 @@ enum mpls_default_dissector_t {
static enum_val_t mpls_default_payload_defs[] = {
{
"pw satop"
,"SAToP (no RTP support)"
,pwc_longname_pw_satop
,MDD_PW_SATOP
},
{
"pw cesopsn"
,"CESoPSN basic NxDS0 mode (no RTP support)"
,pwc_longname_pw_cesopsn
,MDD_PW_CESOPSN
},
{
@ -171,6 +181,26 @@ static enum_val_t mpls_default_payload_defs[] = {
,"Internal TDM"
,MDD_ITDM
},
{
"mpls pw atm n_to_one cw"
,pwc_longname_pw_atm_n1_cw
,MDD_MPLS_PW_ATM_N1_CW
},
{
"mpls pw atm n_to_one no_cw"
,pwc_longname_pw_atm_n1_nocw
,MDD_MPLS_PW_ATM_N1_NOCW
},
{
"mpls pw atm one_to_one or aal5_pdu"
,pwc_longname_pw_atm_11_or_aal5_pdu
,MDD_MPLS_PW_ATM_11_OR_AAL5_PDU
},
{
"mpls pw atm aal5_sdu"
,pwc_longname_pw_atm_aal5_sdu
,MDD_MPLS_PW_ATM_AAL5_SDU
},
{
NULL
,NULL
@ -181,6 +211,9 @@ static enum_val_t mpls_default_payload_defs[] = {
static int mpls_filter[MPLSF_MAX];
static gint mpls_default_payload = 0;
static gboolean mpls_pref_pwac_all_as_bfd_xipv4 = FALSE;
static gboolean mpls_pref_pwac_0x0_as_bfd = FALSE;
static gboolean mpls_pref_pwac_try_ppp = TRUE;
static int hf_mpls_1st_nibble = -1;
@ -236,6 +269,60 @@ static const value_string oam_defect_type_vals[] = {
{0, NULL }
};
#if 0 /*not used yet*/
/*
* MPLS PW types
* http://www.iana.org/assignments/pwe3-parameters
*/
static const value_string mpls_pw_types[] = {
{ 0x0001, "Frame Relay DLCI ( Martini Mode )" },
{ 0x0002, "ATM AAL5 SDU VCC transport" },
{ 0x0003, "ATM transparent cell transport" },
{ 0x0004, "Ethernet Tagged Mode" },
{ 0x0005, "Ethernet" },
{ 0x0006, "HDLC" },
{ 0x0007, "PPP" },
{ 0x0008, "SONET/SDH Circuit Emulation Service Over MPLS" },
{ 0x0009, "ATM n-to-one VCC cell transport" },
{ 0x000A, "ATM n-to-one VPC cell transport" },
{ 0x000B, "IP Layer2 Transport" },
{ 0x000C, "ATM one-to-one VCC Cell Mode" },
{ 0x000D, "ATM one-to-one VPC Cell Mode" },
{ 0x000E, "ATM AAL5 PDU VCC transport" },
{ 0x000F, "Frame-Relay Port mode" },
{ 0x0010, "SONET/SDH Circuit Emulation over Packet" },
{ 0x0011, "Structure-agnostic E1 over Packet" },
{ 0x0012, "Structure-agnostic T1 (DS1) over Packet" },
{ 0x0013, "Structure-agnostic E3 over Packet" },
{ 0x0014, "Structure-agnostic T3 (DS3) over Packet" },
{ 0x0015, "CESoPSN basic mode" },
{ 0x0016, "TDMoIP AAL1 Mode" },
{ 0x0017, "CESoPSN TDM with CAS" },
{ 0x0018, "TDMoIP AAL2 Mode" },
{ 0x0019, "Frame Relay DLCI" },
{ 0x001A, "ROHC Transport Header-compressed Packets" },/*[RFC4995][RFC4901]*/
{ 0x001B, "ECRTP Transport Header-compressed Packets" },/*[RFC3545][RFC4901]*/
{ 0x001C, "IPHC Transport Header-compressed Packets" },/*[RFC2507][RFC4901]*/
{ 0x001D, "cRTP Transport Header-compressed Packets" },/*[RFC2508][RFC4901]*/
{ 0x001E, "ATM VP Virtual Trunk" },/*[MFA9]*/
{ 0x001F, "Reserved" },/*[Bryant] 2008-04-17*/
{ 0, NULL }
};
#endif
/*
* MPLS PW Associated Channel Types
* as per http://www.iana.org/assignments/pwe3-parameters
* and http://tools.ietf.org/html/draft-ietf-pwe3-vccv-bfd-05 clause 3.2
*/
static const value_string mpls_pwac_types[] = {
{ 0x0007, "BFD Control, PW-ACH-encapsulated (BFD Without IP/UDP Headers)" },
{ 0x0021, "IPv4 packet" },
{ 0x0057, "IPv6 packet" },
{ 0, NULL }
};
static dissector_table_t ppp_subdissector_table;
static dissector_table_t mpls_subdissector_table;
@ -289,20 +376,49 @@ dissect_pw_ach(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
tvb, 0, 1, ver, "Version: %d", ver);
ti = proto_tree_add_uint_format(mpls_pw_ach_tree, hf_mpls_pw_ach_res,
tvb, 1, 1, res, "Reserved: 0x%02x", res);
PROTO_ITEM_SET_HIDDEN(ti);
if (res != 0)
proto_tree_add_text(mpls_pw_ach_tree, tvb, 1, 1,
"Error: this byte is reserved and must be 0");
else
PROTO_ITEM_SET_HIDDEN(ti);
proto_tree_add_uint_format(mpls_pw_ach_tree, hf_mpls_pw_ach_channel_type,
tvb, 2, 2, channel_type,
"Channel Type: %s (0x%04x)",
val_to_str(channel_type, ppp_vals, "Unknown"),
val_to_str(channel_type, mpls_pwac_types, "Unknown"),
channel_type);
}
next_tvb = tvb_new_subset(tvb, 4, -1, -1);
if (!dissector_try_port(ppp_subdissector_table, channel_type,
if (0x21 == channel_type /*IPv4, RFC4385 clause 6.*/)
{
call_dissector(dissector_ip, next_tvb, pinfo, tree);
}
else if (0x7 == channel_type /*PWACH-encapsulated BFD, draft-ietf-pwe3-vccv-bfd-05 3.2*/
|| mpls_pref_pwac_all_as_bfd_xipv4)
{
call_dissector(dissector_bfd, next_tvb, pinfo, tree);
}
else if (0x57 == channel_type /*IPv6, RFC4385 clause 6.*/)
{
call_dissector(dissector_ipv6, next_tvb, pinfo, tree);
}
else if (0x0 == channel_type && mpls_pref_pwac_0x0_as_bfd)
{
call_dissector(dissector_bfd, next_tvb, pinfo, tree);
}
else if (mpls_pref_pwac_try_ppp)
{
/* XXX perhaps this code should be reconsidered */
/* non-standard extension, therefore controlled by option*/
/* appeared in revision 10862 from Carlos M. Pignataro */
if (!dissector_try_port(ppp_subdissector_table, channel_type,
next_tvb, pinfo, tree)) {
call_dissector(dissector_data, next_tvb, pinfo, tree);
}
}
else
{
call_dissector(dissector_data, next_tvb, pinfo, tree);
}
}
@ -683,8 +799,20 @@ dissect_mpls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
case MDD_ITDM:
call_dissector(dissector_itdm, next_tvb, pinfo, tree);
break;
default: /*fallthrough*/
case MDD_MPLS_PW_GENERIC:
case MDD_MPLS_PW_ATM_N1_CW:
call_dissector(dissector_mpls_pw_atm_n1_cw, next_tvb, pinfo, tree);
break;
case MDD_MPLS_PW_ATM_N1_NOCW:
call_dissector(dissector_mpls_pw_atm_n1_nocw, next_tvb, pinfo, tree);
break;
case MDD_MPLS_PW_ATM_11_OR_AAL5_PDU:
call_dissector(dissector_mpls_pw_atm_11_aal5pdu, next_tvb, pinfo, tree);
break;
case MDD_MPLS_PW_ATM_AAL5_SDU:
call_dissector(dissector_mpls_pw_atm_aal5_sdu, next_tvb, pinfo, tree);
break;
default: /*fallthrough*/
case MDD_MPLS_PW_GENERIC:
dissect_pw_mcw(next_tvb, pinfo, tree);
break;
}
@ -806,6 +934,35 @@ proto_register_mpls(void)
&mpls_default_payload,
mpls_default_payload_defs,
FALSE );
prefs_register_bool_preference(module_mpls
,"mplspref.pwac_0x0_as_bfd"
,"Assume PWAC Channel Type 0x0 is raw BFD"
,"draft-ietf-pwe3-vccv-bfd-05 states that PWAC Channel Type 0x07 must be used"
" when VCCV carries PW-ACH-encapsulated BFD (i.e., BFD without IP/UDP Headers, or \"raw\" BFD)"
"\n\n"
"Legacy or buggy devices may not comply to this and use Channel Type 0x0 for BFD."
" Enable this preference to decode such BFD traffic."
" Disable for standard behavior of PWAC dissector (default)."
,&mpls_pref_pwac_0x0_as_bfd);
prefs_register_bool_preference(module_mpls
,"mplspref.pwac_all_as_bfd_xip"
,"Assume that all PWAC Channel Types (except 0x21) are raw BFD"
,"draft-ietf-pwe3-vccv-bfd-05 states that PWAC Channel Type 0x07 must be used"
" when VCCV carries PW-ACH-encapsulated BFD (i.e., \"raw\" BFD)"
"\n\n"
"Legacy or buggy devices may not comply to this and use voluntary Channel Type for BFD."
" Enable this preference to decode all PWAC Channel Types as raw BFD,"
" except Channel Type 0x21 (IPv4)."
" Disable for standard behavior of PWAC dissector (default)."
,&mpls_pref_pwac_all_as_bfd_xipv4);
prefs_register_bool_preference(module_mpls
,"mplspref.pwac_try_ppp"
,"As a last resort, try to decode PWAC payloads as PPP traffic"
,"Legacy devices may use MPLS PW Associated Channel for PPP traffic."
"\n\n"
"Enable this preference to allow PWAC dissector to try PPP,"
" if no other suitable dissector found (default)."
,&mpls_pref_pwac_try_ppp);
}
void
@ -836,6 +993,7 @@ proto_reg_handoff_mpls(void)
dissector_data = find_dissector("data");
dissector_ipv6 = find_dissector("ipv6");
dissector_ip = find_dissector("ip");
dissector_bfd = find_dissector("bfd");
dissector_pw_eth_heuristic = find_dissector("pw_eth_heuristic");
dissector_pw_fr = find_dissector("pw_fr");
dissector_pw_hdlc_nocw_fr = find_dissector("pw_hdlc_nocw_fr");
@ -844,6 +1002,10 @@ proto_reg_handoff_mpls(void)
dissector_pw_eth_nocw = find_dissector("pw_eth_nocw");
dissector_pw_satop = find_dissector("pw_satop");
dissector_itdm = find_dissector("itdm");
dissector_mpls_pw_atm_n1_cw = find_dissector("mpls_pw_atm_n1_cw");
dissector_mpls_pw_atm_n1_nocw = find_dissector("mpls_pw_atm_n1_nocw");
dissector_mpls_pw_atm_11_aal5pdu= find_dissector("mpls_pw_atm_11_or_aal5_pdu");
dissector_mpls_pw_atm_aal5_sdu = find_dissector("mpls_pw_atm_aal5_sdu");
dissector_pw_cesopsn = find_dissector("pw_cesopsn");
initialized = TRUE;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,101 @@
/* packet-pw-atm.h
* Interface of pw-atm module
* Copyright 2009, Artem Tamazov <artem.tamazov@tellabs.com>
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef PACKET_PW_ATM_H
#define PACKET_PW_ATM_H
#include "packet-pw-common.h"
typedef enum {
PWATM_MODE_UNKNOWN = 0
,PWATM_MODE_N1_NOCW
,PWATM_MODE_N1_CW
,PWATM_MODE_11_VCC
,PWATM_MODE_11_VPC
,PWATM_MODE_AAL5_SDU
,PWATM_MODE_AAL5_PDU
} pwatm_mode_t;
typedef enum {
PWATM_SUBMODE_DEFAULT = 0
,PWATM_SUBMODE_ADMIN_CELL /*used in aal5_sdu dissector only*/
} pwatm_submode_t;
typedef struct {
int pw_cell_number;
pwc_packet_properties_t props;
gint packet_size;
pwatm_mode_t mode;
pwatm_submode_t submode;
struct {
/*
* ATM-specific attributes which remain the same
* across all the cells in the pw packet. Values are filled
* by sub-dissectors and read by upper-level dissector.
* Meanings of values:
* (-1) - value is unknown
* (-2) - value is different among cells
* positive - value is the same in all cells
* Machinery is implemented in the UPDATE_CUMULATIVE_VALUE macro.
*/
gint32 vpi;
gint32 vci;
gint32 clp;
gint32 pti;
} cumulative;
gint32 vpi; /*-1 if unknown*/
gint32 vci; /*-1 if unknown*/
gint32 pti; /*-1 if unknown*/
struct {
/*
* Some fields from 3rd byte of CW. Filled by cell_header dissector.
* In in AAL5 PDU mode, this allows control_word dissector to print
* these values in the CW heading line in the tree.
* Meanings of values:
* (-1) - value is unknown
*/
gint32 m;
gint32 v;
gint32 rsv;
gint32 u;
gint32 e;
gint32 clp;
} cwb3;
gboolean aal5_sdu_frame_relay_cr_bit; /*see rfc4717 10.1*/
gboolean cell_mode_oam; /*atm admin cell*/
gboolean enable_fill_columns_by_atm_dissector;
} pwatm_private_data_t;
#define PWATM_PRIVATE_DATA_T_INITIALIZER { \
0, PWC_PACKET_PROPERTIES_T_INITIALIZER, 0 \
,PWATM_MODE_UNKNOWN, PWATM_SUBMODE_DEFAULT \
,{-1, -1, -1, -1 } \
,-1, -1, -1 \
,{-1, -1, -1, -1, -1, -1 } \
,FALSE, FALSE, TRUE \
}
#endif /*PACKET_PW_ATM_H*/

View File

@ -56,12 +56,12 @@ static int hf_cw_frg = -1;
static int hf_cw_len = -1;
static int hf_cw_seq = -1;
static int hf_payload = -1;
static int hf_padding = -1;
static int hf_padding_f = -1;
static int hf_payload_l = -1;
static dissector_handle_t data_handle;
static dissector_handle_t pw_padding_handle;
static const char pwc_longname_pw_cesopsn[] = "CESoPSN basic NxDS0 mode (no RTP support)";
const char pwc_longname_pw_cesopsn[] = "CESoPSN basic NxDS0 mode (no RTP support)";
static const char shortname[] = "CESoPSN basic (no RTP)";
static const value_string vals_cw_lm[] = {
@ -121,7 +121,7 @@ static void dissect_pw_cesopsn( tvbuff_t * tvb_original, packet_info * pinfo, pr
/* check how "good" is this packet */
/* also decide payload length from packet size and CW */
properties = 0;
properties = PWC_PACKET_PROPERTIES_T_INITIALIZER;
if (0 != (tvb_get_guint8(tvb_original, 0) & 0xf0 /*bits03*/))
{
properties |= PWC_CW_BAD_BITS03;
@ -188,7 +188,7 @@ static void dissect_pw_cesopsn( tvbuff_t * tvb_original, packet_info * pinfo, pr
{
guint8 cw_lm;
cw_lm = tvb_get_guint8(tvb_original, 0) & 0x0b /*l+mod*/;
if (!pwc_value_listed_in_vals(cw_lm, vals_cw_lm))
if (NULL == match_strval(cw_lm, vals_cw_lm))
{
properties |= PWC_CW_SUSPECT_LM;
}
@ -348,6 +348,9 @@ static void dissect_pw_cesopsn( tvbuff_t * tvb_original, packet_info * pinfo, pr
}
tree = proto_item_add_subtree(item, ett);
call_dissector(data_handle, tvb, pinfo, tree);
item = proto_tree_add_int(tree, hf_payload_l, tvb, 0, 0
,(int)payload_size); /* allow filtering */
PROTO_ITEM_SET_HIDDEN(item);
}
}
@ -357,12 +360,9 @@ static void dissect_pw_cesopsn( tvbuff_t * tvb_original, packet_info * pinfo, pr
proto_tree* tree;
tree = proto_item_add_subtree(item, ett);
{
proto_item* item;
tvbuff_t* tvb;
tvb = tvb_new_subset(tvb_original, PWC_SIZEOF_CW + payload_size, padding_size, -1);
item = proto_tree_add_item(tree, hf_padding, tvb, 0, -1, FALSE);
pwc_item_append_text_n_items(item,(int)padding_size,"octet");
call_dissector(data_handle, tvb, pinfo, tree);
call_dissector(pw_padding_handle, tvb, pinfo, tree);
}
}
}
@ -396,11 +396,8 @@ void proto_register_pw_cesopsn(void)
,{&hf_payload ,{"TDM payload" ,"pwcesopsn.payload"
,FT_BYTES ,BASE_NONE ,NULL
,0 ,NULL ,HFILL }}
,{&hf_padding ,{"Padding" ,"pwcesopsn.padding"
,FT_BYTES ,BASE_NONE ,NULL
,0 ,NULL ,HFILL }}
,{&hf_padding_f ,{"Padding (formatted)" ,""
,FT_BYTES ,BASE_NONE ,NULL
,{&hf_payload_l ,{"TDM payload length" ,"pwcesopsn.payload.len"
,FT_INT32 ,BASE_DEC ,NULL
,0 ,NULL ,HFILL }}
};
@ -420,6 +417,7 @@ void proto_reg_handoff_pw_cesopsn(void)
dissector_handle_t h;
h = find_dissector("pw_cesopsn");
data_handle = find_dissector("data");
pw_padding_handle = find_dissector("pw_padding");
dissector_add("mpls.label", LABEL_INVALID, h);
return;
}

View File

@ -28,6 +28,7 @@
#endif
#include <string.h>
#include <epan/packet.h>
#include "packet-pw-common.h"
static const char string_ok[] = "Ok";
@ -57,22 +58,6 @@ pwc_vals_cw_frag[] = {
};
int pwc_value_listed_in_vals(const guint32 val, const value_string * vals)
{
if (NULL != vals)
{
while (vals->strptr != NULL)
{
if (val == vals->value)
{
return (1==1);
}
++vals;
}
}
return 0;
}
void pwc_item_append_cw(proto_item* item, const guint32 cw, const gboolean append_text)
{
if (item != NULL)
@ -90,8 +75,61 @@ void pwc_item_append_cw(proto_item* item, const guint32 cw, const gboolean appen
void pwc_item_append_text_n_items(proto_item* item, const int n, const char * const item_text)
{
assert(item != 0);
proto_item_append_text(item, ", %d %s%s", n, item_text, plurality(n,"","s"));
if (n >=0)
{
proto_item_append_text(item, ", %d %s%s", n, item_text, plurality(n,"","s"));
}
return;
}
static gint proto_pw_padding = -1;
static gint ett = -1;
static int hf_padding_len = -1;
static dissector_handle_t dh_data;
static
void dissect_pw_padding(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
{
/* do not touch columns */
if (tree)
{
gint size;
proto_item* item;
size = tvb_reported_length_remaining(tvb, 0);
item = proto_tree_add_item(tree, proto_pw_padding, tvb, 0, -1, FALSE);
pwc_item_append_text_n_items(item,size,"byte");
{
proto_tree* tree;
tree = proto_item_add_subtree(item, ett);
call_dissector(dh_data, tvb, pinfo, tree);
item = proto_tree_add_int(tree, hf_padding_len, tvb, 0, 0, size);
PROTO_ITEM_SET_HIDDEN(item); /*allow filtering*/
}
}
return;
}
void proto_register_pw_padding(void)
{
static hf_register_info hfpadding[] = {
{&hf_padding_len ,{"Length" ,"pw.padding.len"
,FT_INT32 ,BASE_DEC ,NULL ,0
,NULL ,HFILL }}
};
static gint *ett_array[] = {
&ett
};
proto_pw_padding = proto_register_protocol("Pseudowire Padding","PW Padding","pwpadding");
proto_register_field_array(proto_pw_padding, hfpadding, array_length(hfpadding));
proto_register_subtree_array(ett_array, array_length(ett_array));
register_dissector("pw_padding", dissect_pw_padding, proto_pw_padding);
return;
}
void proto_reg_handoff_pw_padding(void)
{
dh_data = find_dissector("data");
return;
}

View File

@ -31,6 +31,13 @@
#define PWC_SIZEOF_CW 4
extern const char pwc_longname_pw_satop[];
extern const char pwc_longname_pw_cesopsn[];
extern const char pwc_longname_pw_atm_n1_cw[];
extern const char pwc_longname_pw_atm_n1_nocw[];
extern const char pwc_longname_pw_atm_11_or_aal5_pdu[];
extern const char pwc_longname_pw_atm_aal5_sdu[];
extern const value_string pwc_vals_cw_l_bit[];
extern const value_string pwc_vals_cw_r_bit[];
extern const value_string pwc_vals_cw_frag[];
@ -42,19 +49,26 @@ typedef enum {
,PWC_CW_BAD_LEN_MUST_BE_0 = 1 << 3
,PWC_CW_BAD_FRAG = 1 << 4
,PWC_CW_BAD_RSV = 1 << 5
,PWC_CW_BAD_FLAGS = 1 << 8
,PWC_CW_BAD_PAYLEN_LE_0 = 1 << 9
,PWC_CW_BAD_PADDING_NE_0 = 1 << 10
,PWC_ANYOF_CW_BAD = PWC_CW_BAD_BITS03
+ PWC_CW_BAD_PAYLEN_LT_0
+ PWC_CW_BAD_PAYLEN_GT_PACKET
+ PWC_CW_BAD_LEN_MUST_BE_0
+ PWC_CW_BAD_FRAG
+ PWC_CW_BAD_RSV
+ PWC_CW_BAD_FLAGS
+ PWC_CW_BAD_PAYLEN_LE_0
+ PWC_CW_BAD_PADDING_NE_0
,PWC_CW_SUSPECT_LM = 1 << 6
,PWC_ANYOF_CW_SUSPECT = PWC_CW_SUSPECT_LM
,PWC_PAY_SIZE_BAD = 1 << 7
} pwc_packet_properties_t;
}
pwc_packet_properties_t;
#define PWC_PACKET_PROPERTIES_T_INITIALIZER 0
extern void pwc_item_append_cw(proto_item* item, const guint32 cw, const gboolean append_text);
extern void pwc_item_append_text_n_items(proto_item* item, const int n, const char * const item_text);
extern int pwc_value_listed_in_vals(const guint32 val, const value_string * vals);
#endif

View File

@ -56,12 +56,12 @@ static int hf_cw_frg = -1;
static int hf_cw_len = -1;
static int hf_cw_seq = -1;
static int hf_payload = -1;
static int hf_padding = -1;
static int hf_padding_f = -1;
static int hf_payload_l = -1;
static dissector_handle_t data_handle;
static dissector_handle_t pw_padding_handle;
static const char pwc_longname_pw_satop[] = "SAToP (no RTP support)";
const char pwc_longname_pw_satop[] = "SAToP (no RTP support)";
static const char shortname[] = "SAToP (no RTP)";
@ -80,7 +80,7 @@ static void dissect_pw_satop(tvbuff_t * tvb_original, packet_info * pinfo, proto
,PAY_LIKE_OCTET_ALIGNED_T1
} payload_properties;
properties = 0;
properties = PWC_PACKET_PROPERTIES_T_INITIALIZER;
payload_properties = PAY_NO_IDEA;
packet_size = tvb_reported_length_remaining(tvb_original, 0);
/*
@ -364,6 +364,9 @@ static void dissect_pw_satop(tvbuff_t * tvb_original, packet_info * pinfo, proto
proto_item_append_text(item, "%s", s);
tree = proto_item_add_subtree(item, ett);
call_dissector(data_handle, tvb, pinfo, tree);
item = proto_tree_add_int(tree, hf_payload_l, tvb, 0, 0
,(int)payload_size); /* allow filtering */
PROTO_ITEM_SET_HIDDEN(item);
}
}
}
@ -374,16 +377,9 @@ static void dissect_pw_satop(tvbuff_t * tvb_original, packet_info * pinfo, proto
proto_tree* tree;
tree = proto_item_add_subtree(item, ett);
{
proto_item* item;
tvbuff_t* tvb;
tvb = tvb_new_subset(tvb_original, PWC_SIZEOF_CW + payload_size, padding_size, -1);
item = proto_tree_add_item(tree, hf_padding, tvb, 0, -1, FALSE);
pwc_item_append_text_n_items(item,(int)padding_size,"octet");
{
proto_tree* tree;
tree = proto_item_add_subtree(item, ett);
call_dissector(data_handle, tvb, pinfo, tree);
}
call_dissector(pw_padding_handle, tvb, pinfo, tree);
}
}
}
@ -421,11 +417,8 @@ void proto_register_pw_satop(void)
,{&hf_payload ,{"TDM payload" ,"pwsatop.payload"
,FT_BYTES ,BASE_NONE ,NULL
,0 ,NULL ,HFILL }}
,{&hf_padding ,{"Padding" ,"pwsatop.padding"
,FT_BYTES ,BASE_NONE ,NULL
,0 ,NULL ,HFILL }}
,{&hf_padding_f ,{"Padding (formatted)" ,""
,FT_BYTES ,BASE_NONE ,NULL
,{&hf_payload_l ,{"TDM payload length" ,"pwsatop.payload.len"
,FT_INT32 ,BASE_DEC ,NULL
,0 ,NULL ,HFILL }}
};
@ -445,5 +438,6 @@ void proto_reg_handoff_pw_satop(void)
dissector_handle_t h;
h = find_dissector("pw_satop");
data_handle = find_dissector("data");
pw_padding_handle = find_dissector("pw_padding");
dissector_add("mpls.label", LABEL_INVALID, h);
}

View File

@ -187,28 +187,6 @@ typedef struct _packet_info {
struct _sccp_msg_info_t* sccp_info;
guint16 clnp_srcref; /* clnp/cotp source reference (can't use srcport, this would confuse tpkt) */
guint16 clnp_dstref; /* clnp/cotp destination reference (can't use dstport, this would confuse tpkt) */
guint8 pw_atm_encap_type; /* FF: RFC 4717 is devilish, it describes many
* different types of ATM->PW encapsulation.
* None of which can correctly be interpreted by
* the packet-atm.c dissector. Thus I have to
* pass some info from packet-pw-atm.c to packet-
* -atm.c, and augment/change packet-atm.c
* dissector.
*
* 0: RFC4717::Sec. 9, ATM One-to-One Cell Mode
* 1: RFC4717::Sec. 8, ATM N-to-One Cell Mode
* 2: RFC4717::Sec. 10, ATM AAL5 CPCS-SDU Mode
* 3: RFC4717::Sec. 11, ATM AAL5 PDU Frame Mode
*/
guint16 pw_atm_flags; /* FF: all flags defined in RFC4717 compacted in a
* single guint16.
*
* T, E, C, U, M, V, PTI, C flag name
* 9 8 7 6 5 4 321 0 position
*/
guint16 pw_atm_ncells; /* FF: number of cells fitted in a single
* PW frame.
*/
guint16 zbee_cluster_id; /* ZigBee cluster ID, an application-specific message identifier that
* happens to be included in the transport (APS) layer header.