ANCP: Update to RFC6320

Updates ANCP dissector to final RFC6320.
Additional updates types and codes to current IANA registry values:
https://www.iana.org/assignments/ancp/ancp.xhtml

Bug: 13532
Change-Id: I15d3e66e049d425350a528d04d4a5ff24d9b26bd
Reviewed-on: https://code.wireshark.org/review/20964
Reviewed-by: Michael Mann <mmann78@netscape.net>
This commit is contained in:
Uli Heilmeier 2017-04-01 22:48:33 +02:00 committed by Michael Mann
parent 029c38d3fc
commit 6d204e5152
1 changed files with 229 additions and 86 deletions

View File

@ -5,8 +5,11 @@
* More info on the protocol can be found on IETF:
* http://tools.ietf.org/wg/ancp/
* http://tools.ietf.org/html/draft-ietf-ancp-protocol-09
* https://tools.ietf.org/html/rfc6320
* https://www.iana.org/assignments/ancp/ancp.xhtml
*
* Copyright 2010, Aniruddha.A (anira@cisco.com)
* Uli Heilmeier, 2017; Update to RFC6320; current IANA registry types
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
@ -38,6 +41,7 @@
#define ANCP_MIN_HDR 4
#define ANCP_GSMP_ETHER_TYPE 0x880C
#define TECH_TYPE_DSL 0x5
#define TECH_TYPE_PON 0x1
#define ANCP_RESULT_MASK 0xF0
#define ANCP_CODE_MASK 0x0FFF
@ -49,6 +53,9 @@
#define ANCP_MTYPE_PORT_MGMT 32
#define ANCP_MTYPE_PORT_UP 80
#define ANCP_MTYPE_PORT_DN 81
#define ANCP_MTYPE_ADJ_UPD 85
#define ANCP_MTYPE_GEN_RSP 91
#define ANCP_MTYPE_PROV 93
/* Topology Discovery Extensions */
#define TLV_DSL_LINE_ATTRIBUTES 0x04
@ -70,6 +77,7 @@ void proto_register_ancp(void);
void proto_reg_handoff_ancp(void);
static int hf_ancp_len = -1;
static int hf_ancp_len2 = -1;
static int hf_ancp_ver = -1;
static int hf_ancp_mtype = -1;
static int hf_ancp_timer = -1;
@ -91,6 +99,10 @@ static int hf_ancp_code = -1;
static int hf_ancp_trans_id = -1;
static int hf_ancp_i_flag = -1;
static int hf_ancp_submsg_num = -1;
static int hf_ancp_pudm_unused = -1;
static int hf_ancp_function = -1;
static int hf_ancp_x_function = -1;
static int hf_ancp_ext_flags_res = -1;
static int hf_ancp_port = -1;
static int hf_ancp_port_sess_num = -1;
static int hf_ancp_evt_seq_num = -1;
@ -99,7 +111,9 @@ static int hf_ancp_reserved = -1;
static int hf_ancp_blk_len = -1;
static int hf_ancp_num_ext_tlvs = -1;
static int hf_ancp_ext_tlv_type = -1;
static int hf_ancp_ext_tlv_len = -1;
static int hf_ancp_dsl_line_stlv_type = -1;
static int hf_ancp_dsl_line_stlv_len = -1;
static int hf_ancp_dsl_line_stlv_value = -1;
static int hf_ancp_ext_tlv_value_str = -1;
static int hf_ancp_oam_opaque = -1;
@ -166,6 +180,9 @@ static const value_string mtype_names[] = {
{ 32, "Port-Management" },
{ 80, "Port-Up" },
{ 81, "Port-Down" },
{ 85, "Adjacency Update" },
{ 91, "Generic Response" },
{ 93, "Provisioning" },
{ 0, NULL }
};
@ -194,23 +211,33 @@ static const value_string resulttype_names[] = {
{ 0, NULL }
};
static const value_string codetype_names[] = { /* For now, these are OAM codes*/
{ 0x500, "Access-line-doesn't-exist" },
{ 0x501, "Loopback-Test-Timeout" },
static const value_string codetype_names[] = {
{ 0x000, "No result" },
{ 0x002, "Invalid request message" },
{ 0x006, "One or more of the specified ports are down" },
{ 0x013, "Out of resources" },
{ 0x051, "Request message type not implemented" },
{ 0x053, "Malformed message" },
{ 0x054, "Mandatory TLV missing" },
{ 0x055, "Invalid TLV contents" },
{ 0x500, "One or more of the specified ports do not exist" },
{ 0x501, "Loopback test timed out" },
{ 0x502, "Reserved" },
{ 0x503, "DSL-line-status-showtime" },
{ 0x504, "DSL-line-status-idle" },
{ 0x505, "DSL-line-status-silent" },
{ 0x506, "DSL-line-status-training" },
{ 0x507, "DSL-line-integrity-error" },
{ 0x508, "DSLAM resource-unavailable" },
{ 0x509, "Invalid Test Parameter" },
{ 0x503, "DSL access line status showtime" },
{ 0x504, "DSL access line status idle" },
{ 0x505, "DSL access line status silent" },
{ 0x506, "DSL access line status training" },
{ 0x507, "DSL access line integrity error" },
{ 0x508, "DSLAM resource not available" },
{ 0x509, "Invalid test parameter" },
{ 0, NULL }
};
static const value_string techtype_str[] = {
{ 0x00, "Not technology dependent" },
{ 0x01, "PON" },
{ 0x05, "DSL" },
{ 0xFF, "Reserved" },
{ 0, NULL }
};
@ -273,74 +300,73 @@ static const value_string dsl_line_state_names[] = {
{ 0, NULL }
};
static const value_string ext_tlv_types[] = {
{ 0x01, "Access-Loop-Circuit-ID" },
{ 0x02, "Access-Loop-Remote-ID" },
{ 0x03, "Access-Aggregation-Circuit-ID-ASCII" },
{ 0x04, "DSL Line Attributes" },
{ 0x06, "Access-Aggregation-Circuit-ID-Binary" },
{ 0x07, "OAM-Loopback-Test-Parameters" },
{ 0x08, "Opaque-Data" },
{ 0x09, "OAM-Loopback-Test-Response-String" },
static const value_string function_names[] = {
{ 0, "Reserved" },
{ 8, "Configure Connection Service Data" },
{ 9, "Remote Loopback" },
{ 0, NULL }
};
static void
dissect_ancp_port_up_dn_mgmt(tvbuff_t *tvb, proto_tree *ancp_tree, gint offset)
static const value_string ext_tlv_types[] = {
{ 0x0001, "Access-Loop-Circuit-ID" },
{ 0x0002, "Access-Loop-Remote-ID" },
{ 0x0003, "Access-Aggregation-Circuit-ID-ASCII" },
{ 0x0004, "DSL Line Attributes" },
{ 0x0005, "Service-Profile-Name" },
{ 0x0006, "Access-Aggregation-Circuit-ID-Binary" },
{ 0x0007, "OAM-Loopback-Test-Parameters" },
{ 0x0008, "Opaque-Data" },
{ 0x0009, "OAM-Loopback-Test-Response-String" },
{ 0x0011, "Command" },
{ 0x0013, "Multicast-Service-Profile" },
{ 0x0015, "Bandwidth-Allocation" },
{ 0x0016, "Bandwidth-Request" },
{ 0x0018, "Multicast-Service-Profile-Name" },
{ 0x0019, "Multicast-Flow" },
{ 0x0021, "List-Action" },
{ 0x0022, "Sequence-Number" },
{ 0x0024, "White-List-CAC" },
{ 0x0025, "MRepCtl-CAC" },
{ 0x0081, "Actual-Net-Data-Rate-Upstream" },
{ 0x0082, "Actual-Net-Data-Rate-Downstream" },
{ 0x0083, "Minimum-Net-Data-Rate-Upstream" },
{ 0x0084, "Minimum-Net-Data-Rate-Downstream" },
{ 0x0085, "Attainable-Net-Data-Rate-Upstream" },
{ 0x0086, "Attainable-Net-Data-Rate-Downstream" },
{ 0x0087, "Maximum-Net-Data-Rate-Upstream" },
{ 0x0088, "Maximum-Net-Data-Rate-Downstream" },
{ 0x0089, "Minimum-Net-Low-Power-Data-Rate-Upstream" },
{ 0x008A, "Minimum-Net-Low-Power-Data-Rate-Downstream" },
{ 0x008B, "Maximum-Interleaving-Delay-Upstream" },
{ 0x008C, "Actual-Interleaving-Delay-Upstream" },
{ 0x008D, "Maximum-Interleaving-Delay-Downstream" },
{ 0x008E, "Actual-Interleaving-Delay-Downstream" },
{ 0x008F, "DSL-Line-State" },
{ 0x0090, "Access-Loop-Encapsulation" },
{ 0x0091, "DSL-Type" },
{ 0x0092, "Request-Source-IP" },
{ 0x0093, "Request-Source-MAC" },
{ 0x0094, "Report-Buffering-Time" },
{ 0x0095, "Committed-Bandwidth" },
{ 0x0096, "Request-Source-Device-Id" },
{ 0x0106, "Status-Info" },
{ 0x1000, "Target (single access line variant)" },
{ 0, NULL }
};
static value_string_ext ext_tlv_types_ext = VALUE_STRING_EXT_INIT(ext_tlv_types);
static gint
dissect_ancp_tlv(tvbuff_t *tvb, proto_tree *tlv_tree, gint offset)
{
guint8 tech_type;
proto_tree_add_item(ancp_tree, hf_ancp_port, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(ancp_tree, hf_ancp_port_sess_num, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(ancp_tree, hf_ancp_evt_seq_num, tvb, offset, 4, ENC_BIG_ENDIAN);
offset += 4;
proto_tree_add_item(ancp_tree, hf_ancp_label, tvb, offset, 8, ENC_BIG_ENDIAN);
offset += 8;
/* Start of the Extension Block */
proto_tree_add_item(ancp_tree, hf_ancp_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
/*
* We have already displayed the message type in the common header dissect
* so need not display this again here - skip it
*/
offset += 1; /* Message type in Ext Blk */
proto_tree_add_item(ancp_tree, hf_ancp_tech_type, tvb, offset, 1, ENC_BIG_ENDIAN);
tech_type = tvb_get_guint8(tvb, offset);
offset += 1;
proto_tree_add_item(ancp_tree, hf_ancp_blk_len, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
if (tech_type == TECH_TYPE_DSL) {
proto_item *sti;
proto_tree *tlv_tree;
guint16 tlen, ttype;
gint16 num_tlvs, num_stlvs;
gint16 num_stlvs;
proto_item *tti;
proto_tree_add_item(ancp_tree, hf_ancp_num_ext_tlvs, tvb, offset, 2, ENC_BIG_ENDIAN);
num_tlvs = tvb_get_ntohs(tvb, offset);
offset += 2;
sti = proto_tree_add_item(ancp_tree, hf_ancp_len, tvb, offset, 2, ENC_BIG_ENDIAN);
proto_item_append_text(sti, " (Extension Block)");
offset += 2;
/* Create a TLV sub tree */
tlv_tree = proto_item_add_subtree(sti, ett_ancp_len);
for( ;num_tlvs; num_tlvs--) {
proto_tree_add_item(tlv_tree, hf_ancp_ext_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN);
ttype = tvb_get_ntohs(tvb, offset);
offset += 2;
sti = proto_tree_add_item(tlv_tree, hf_ancp_len, tvb, offset, 2, ENC_BIG_ENDIAN);
tti = proto_tree_add_item(tlv_tree, hf_ancp_ext_tlv_len, tvb, offset, 2, ENC_BIG_ENDIAN);
tlen = tvb_get_ntohs(tvb, offset);
offset += 2;
@ -357,7 +383,7 @@ dissect_ancp_port_up_dn_mgmt(tvbuff_t *tvb, proto_tree *ancp_tree, gint offset)
gint val;
/* Create a DSL Attribute SubTree */
dsl_tree = proto_item_add_subtree(sti, ett_ancp_ext_tlv_type);
dsl_tree = proto_item_add_subtree(tti, ett_ancp_ext_tlv_type);
num_stlvs = tlen / 8; /* TODO - better way? */
for ( ;num_stlvs; num_stlvs--) {
proto_tree_add_item(dsl_tree,
@ -365,11 +391,13 @@ dissect_ancp_port_up_dn_mgmt(tvbuff_t *tvb, proto_tree *ancp_tree, gint offset)
2, ENC_BIG_ENDIAN);
stlvtype = tvb_get_ntohs(tvb, offset);
offset += 2;
/* Skip sub-tlv-len display for now */
proto_tree_add_item(dsl_tree,
hf_ancp_dsl_line_stlv_len, tvb, offset,
2, ENC_BIG_ENDIAN);
stlvlen = tvb_get_ntohs(tvb, offset);
offset += 2; /* Sub TLV Length */
sti = proto_tree_add_item(dsl_tree,
tti = proto_tree_add_item(dsl_tree,
hf_ancp_dsl_line_stlv_value, tvb, offset,
stlvlen, ENC_BIG_ENDIAN);
val = tvb_get_ntohl(tvb, offset);
@ -377,19 +405,19 @@ dissect_ancp_port_up_dn_mgmt(tvbuff_t *tvb, proto_tree *ancp_tree, gint offset)
switch (stlvtype) {
case TLV_DSL_LINE_STATE:
proto_item_append_text(sti, " (%s)",
proto_item_append_text(tti, " (%s)",
val_to_str(val, dsl_line_state_names,
"Unknown (0x%02x)"));
break;
case TLV_DSL_TYPE:
proto_item_append_text(sti, " (%s)",
proto_item_append_text(tti, " (%s)",
val_to_str(val, dsl_line_type_names,
"Unknown (0x%02x)"));
break;
default:
/* Add Unit */
proto_item_append_text(sti, " %s",
proto_item_append_text(tti, " %s",
val_to_str(stlvtype,
dsl_line_attr_units,
"Unknown (0x%02x)"));
@ -427,6 +455,67 @@ dissect_ancp_port_up_dn_mgmt(tvbuff_t *tvb, proto_tree *ancp_tree, gint offset)
SKIPPADDING(offset, tlen);
break;
} /* end switch {ttype} */
return offset;
}
static void
dissect_ancp_port_up_dn_mgmt(tvbuff_t *tvb, proto_tree *ancp_tree, gint offset, guint8 mtype)
{
guint8 tech_type;
gint16 num_tlvs;
proto_item *sti;
if (mtype == ANCP_MTYPE_PORT_MGMT) {
proto_tree_add_item(ancp_tree, hf_ancp_pudm_unused, tvb, offset, 14, ENC_NA);
offset += 14;
proto_tree_add_item(ancp_tree, hf_ancp_function, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(ancp_tree, hf_ancp_x_function, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
proto_tree_add_item(ancp_tree, hf_ancp_pudm_unused, tvb, offset, 4, ENC_NA);
offset += 4;
} else {
proto_tree_add_item(ancp_tree, hf_ancp_pudm_unused, tvb, offset, 20, ENC_NA);
offset += 20;
}
proto_tree_add_item(ancp_tree, hf_ancp_ext_flags_res, tvb, offset, 1, ENC_NA);
offset += 1;
proto_tree_add_item(ancp_tree, hf_ancp_mtype, tvb, offset, 1, ENC_BIG_ENDIAN);
offset += 1;
if (mtype == ANCP_MTYPE_PORT_MGMT) {
proto_tree_add_item(ancp_tree, hf_ancp_reserved, tvb, offset, 2, ENC_NA);
offset += 2;
tech_type = 0;
} else {
proto_tree_add_item(ancp_tree, hf_ancp_tech_type, tvb, offset, 1, ENC_BIG_ENDIAN);
tech_type = tvb_get_guint8(tvb, offset);
offset += 1;
proto_tree_add_item(ancp_tree, hf_ancp_reserved, tvb, offset, 1, ENC_NA);
offset += 1;
}
proto_tree_add_item(ancp_tree, hf_ancp_num_ext_tlvs, tvb, offset, 2, ENC_BIG_ENDIAN);
num_tlvs = tvb_get_ntohs(tvb, offset);
offset += 2;
sti = proto_tree_add_item(ancp_tree, hf_ancp_blk_len, tvb, offset, 2, ENC_BIG_ENDIAN);
offset += 2;
if (tech_type == TECH_TYPE_DSL || tech_type == TECH_TYPE_PON) {
proto_tree *tlv_tree;
/* Create a TLV sub tree */
tlv_tree = proto_item_add_subtree(sti, ett_ancp_len);
for( ;num_tlvs; num_tlvs--) {
offset = dissect_ancp_tlv(tvb, tlv_tree, offset);
} /* end for {numtlvs} */
} /* end if {DSL} */
}
@ -486,7 +575,7 @@ dissect_ancp_adj_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ancp_tree,
proto_tree_add_item(ancp_tree, hf_ancp_receiver_instance, tvb, offset, 3, ENC_BIG_ENDIAN);
offset += 3;
proto_tree_add_item(ancp_tree, hf_ancp_tech_type, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(ancp_tree, hf_ancp_reserved, tvb, offset, 1, ENC_NA);
offset += 1;
sti = proto_tree_add_item(ancp_tree, hf_ancp_num_tlvs, tvb, offset, 1, ENC_BIG_ENDIAN);
@ -545,8 +634,11 @@ dissect_ancp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
struct ancp_tap_t *ancp_info;
proto_item *ti;
proto_item *sti;
proto_item *tti;
proto_tree *ancp_tree;
proto_tree *tlv_tree;
guint8 byte;
guint16 len;
offset = 0;
if (tvb_get_ntohs(tvb, offset) != ANCP_GSMP_ETHER_TYPE)
@ -568,6 +660,7 @@ dissect_ancp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
offset = 2; /* skip ether type */
proto_tree_add_item(ancp_tree, hf_ancp_len, tvb, offset, 2, ENC_BIG_ENDIAN);
len = tvb_get_ntohs(tvb, offset);
offset += 2;
sti = proto_tree_add_item(ancp_tree, hf_ancp_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
@ -603,15 +696,12 @@ dissect_ancp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
proto_tree_add_item(ancp_tree, hf_ancp_i_flag, tvb, offset, 1,
ENC_BIG_ENDIAN); /* treat as 1B, but don't change offset */
sti = proto_tree_add_item(ancp_tree, hf_ancp_submsg_num, tvb,
proto_tree_add_item(ancp_tree, hf_ancp_submsg_num, tvb,
offset, 2, ENC_BIG_ENDIAN);
offset += 2;
/*
* Lets not display the 'Length' field now, it is anyway same
* as GSMP Length
* which we have already displayed at the start of the dissect
*/
tti = proto_tree_add_item(ancp_tree, hf_ancp_len2, tvb, offset,
2, ENC_BIG_ENDIAN);
offset += 2; /* Length */
}
@ -624,7 +714,18 @@ dissect_ancp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void*
case ANCP_MTYPE_PORT_MGMT:
/* FALL THRU */
case ANCP_MTYPE_PORT_UP:
dissect_ancp_port_up_dn_mgmt(tvb, ancp_tree, offset);
dissect_ancp_port_up_dn_mgmt(tvb, ancp_tree, offset, mtype);
break;
case ANCP_MTYPE_PROV:
/* FALL THRU */
case ANCP_MTYPE_GEN_RSP:
tlv_tree = proto_item_add_subtree(tti, ett_ancp_len);
while( offset < len + 4) {
offset = dissect_ancp_tlv(tvb, tlv_tree, offset);
}
break;
case ANCP_MTYPE_ADJ_UPD:
break;
default:
proto_item_append_text(sti, " (Unknown Message %d)", mtype);
@ -660,6 +761,12 @@ proto_register_ancp(void)
NULL, 0x0,
NULL, HFILL }
},
{ &hf_ancp_len2,
{ "Length", "ancp.len2",
FT_UINT16, BASE_DEC,
NULL, 0x0,
NULL, HFILL }
},
{ &hf_ancp_ver,
{ "Version", "ancp.ver",
FT_UINT8, BASE_HEX,
@ -786,6 +893,30 @@ proto_register_ancp(void)
NULL, ANCP_SUBMSG_MASK,
NULL, HFILL }
},
{ &hf_ancp_pudm_unused,
{ "Unused Bytes", "ancp.unused",
FT_BYTES, BASE_NONE,
NULL, 0x0,
NULL, HFILL }
},
{ &hf_ancp_function,
{ "Function", "ancp.function",
FT_UINT8, BASE_DEC,
VALS(function_names), 0x0,
NULL, HFILL }
},
{ &hf_ancp_x_function,
{ "X-Function", "ancp.x_function",
FT_UINT8, BASE_DEC,
NULL, 0x0,
NULL, HFILL }
},
{ &hf_ancp_ext_flags_res,
{ "Extension Flags Reserved", "ancp.ext_flags",
FT_BYTES, BASE_NONE,
NULL, 0x0,
NULL, HFILL }
},
{ &hf_ancp_port,
{ "Port", "ancp.port",
FT_UINT32, BASE_DEC,
@ -812,13 +943,13 @@ proto_register_ancp(void)
},
{ &hf_ancp_reserved,
{ "Reserved", "ancp.reserved",
FT_UINT8, BASE_DEC,
FT_BYTES, BASE_NONE,
NULL, 0x0,
NULL, HFILL }
},
{ &hf_ancp_blk_len,
{ "Block Length", "ancp.blk_len",
FT_UINT8, BASE_DEC,
FT_UINT16, BASE_DEC,
NULL, 0x0,
NULL, HFILL }
},
@ -829,9 +960,15 @@ proto_register_ancp(void)
NULL, HFILL }
},
{ &hf_ancp_ext_tlv_type,
{ "TLV", "ancp.ext_tlv.type",
{ "TLV Type", "ancp.ext_tlv.type",
FT_UINT16, BASE_DEC|BASE_EXT_STRING,
&ext_tlv_types_ext, 0x0,
NULL, HFILL }
},
{ &hf_ancp_ext_tlv_len,
{ "TLV Length", "ancp.ext_tlv.len",
FT_UINT16, BASE_DEC,
VALS(ext_tlv_types), 0x0,
NULL, 0x0,
NULL, HFILL }
},
{ &hf_ancp_dsl_line_stlv_type,
@ -840,6 +977,12 @@ proto_register_ancp(void)
VALS(dsl_line_attrs), 0x0,
NULL, HFILL }
},
{ &hf_ancp_dsl_line_stlv_len,
{ "Sub-TLV Length", "ancp.sub_tlv_len",
FT_UINT16, BASE_DEC,
NULL, 0x0,
NULL, HFILL }
},
{ &hf_ancp_dsl_line_stlv_value,
{ "Value", "ancp.dsl_line_param",
FT_UINT32, BASE_DEC,