3 * Dissector for ANCP - Access Node Control Protocol
5 * More info on the protocol can be found on IETF:
6 * http://tools.ietf.org/wg/ancp/
7 * http://tools.ietf.org/html/draft-ietf-ancp-protocol-09
9 * Copyright 2010, Aniruddha.A (anira@cisco.com)
13 * Wireshark - Network traffic analyzer
14 * By Gerald Combs <gerald@wireshark.org>
15 * Copyright 1998 Gerald Combs
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
36 #include <epan/packet.h>
37 #include <epan/prefs.h>
38 #include <epan/dissectors/packet-tcp.h>
40 #include <epan/stats_tree.h>
42 #define ANCP_PORT 6068 /* The ANCP TCP port:draft-ietf-ancp-protocol-09.txt */
44 #define ANCP_MIN_HDR 4
45 #define ANCP_GSMP_ETHER_TYPE 0x880C
46 #define TECH_TYPE_DSL 0x5
48 #define ANCP_RESULT_MASK 0xF0
49 #define ANCP_CODE_MASK 0x0FFF
50 #define ANCP_I_FLAG_MASK 0x80
51 #define ANCP_SUBMSG_MASK 0x7FFF
52 #define ADJ_CODE_MASK 0x7F /* excluding MSB M-Flag */
54 #define ANCP_MTYPE_ADJ 10
55 #define ANCP_MTYPE_PORT_MGMT 32
56 #define ANCP_MTYPE_PORT_UP 80
57 #define ANCP_MTYPE_PORT_DN 81
59 /* Topology Discovery Extensions */
60 #define TLV_DSL_LINE_ATTRIBUTES 0x04
61 #define TLV_DSL_LINE_STATE 0x8F
62 #define TLV_DSL_TYPE 0x91
64 /* Port Management Extensions */
65 #define TLV_PING_PARAMS 0x07
66 #define TLV_PING_OPAQUE_DATA 0x08
67 #define TLV_PING_RES_STR 0x09
69 #define SKIPPADDING(_ofst, _len) \
72 _ofst += (4 - ((_len) % 4)); \
75 static int hf_ancp_len = -1;
76 static int hf_ancp_ver = -1;
77 static int hf_ancp_mtype = -1;
78 static int hf_ancp_timer = -1;
79 static int hf_ancp_adj_code = -1;
80 static int hf_ancp_sender_name = -1;
81 static int hf_ancp_receiver_name = -1;
82 static int hf_ancp_sender_port = -1;
83 static int hf_ancp_receiver_port = -1;
84 static int hf_ancp_p_info = -1;
85 static int hf_ancp_sender_instance = -1;
86 static int hf_ancp_p_id = -1;
87 static int hf_ancp_receiver_instance = -1;
88 static int hf_ancp_tech_type = -1;
89 static int hf_ancp_num_tlvs = -1;
90 static int hf_ancp_tot_len = -1;
91 static int hf_ancp_cap = -1;
92 static int hf_ancp_result = -1;
93 static int hf_ancp_code = -1;
94 static int hf_ancp_trans_id = -1;
95 static int hf_ancp_i_flag = -1;
96 static int hf_ancp_submsg_num = -1;
97 static int hf_ancp_port = -1;
98 static int hf_ancp_port_sess_num = -1;
99 static int hf_ancp_evt_seq_num = -1;
100 static int hf_ancp_label = -1;
101 static int hf_ancp_reserved = -1;
102 static int hf_ancp_blk_len = -1;
103 static int hf_ancp_num_ext_tlvs = -1;
104 static int hf_ancp_ext_tlv_type = -1;
105 static int hf_ancp_dsl_line_stlv_type = -1;
106 static int hf_ancp_dsl_line_stlv_value = -1;
107 static int hf_ancp_ext_tlv_value_str = -1;
108 static int hf_ancp_oam_opaque = -1;
109 static int hf_ancp_oam_loopb_cnt = -1;
110 static int hf_ancp_oam_timeout = -1;
112 static gint ett_ancp_len = -1;
113 static gint ett_ancp_ver = -1;
114 static gint ett_ancp_mtype = -1;
115 static gint ett_ancp_timer = -1;
116 static gint ett_ancp_adj_code = -1;
117 static gint ett_ancp_sender_name = -1;
118 static gint ett_ancp_receiver_name = -1;
119 static gint ett_ancp_sender_port = -1;
120 static gint ett_ancp_receiver_port = -1;
121 static gint ett_ancp_p_info = -1;
122 static gint ett_ancp_sender_instance = -1;
123 static gint ett_ancp_p_id = -1;
124 static gint ett_ancp_receiver_instance = -1;
125 static gint ett_ancp_tech_type = -1;
126 static gint ett_ancp_num_tlvs = -1;
127 static gint ett_ancp_tot_len = -1;
128 static gint ett_ancp_cap = -1;
129 static gint ett_ancp_result = -1;
130 static gint ett_ancp_code = -1;
131 static gint ett_ancp_trans_id = -1;
132 static gint ett_ancp_i_flag = -1;
133 static gint ett_ancp_submsg_num = -1;
134 static gint ett_ancp_port = -1;
135 static gint ett_ancp_port_sess_num= -1;
136 static gint ett_ancp_evt_seq_num = -1;
137 static gint ett_ancp_label = -1;
138 static gint ett_ancp_reserved = -1;
139 static gint ett_ancp_blk_len = -1;
140 static gint ett_ancp_num_ext_tlvs = -1;
141 static gint ett_ancp_ext_tlv_type = -1;
142 static gint ett_ancp_dsl_line_stlv_type = -1;
143 static gint ett_ancp_dsl_line_stlv_val = -1;
144 static gint ett_ancp_ext_tlv_value_str = -1;
145 static gint ett_ancp_oam_opaque = -1;
146 static gint ett_ancp_oam_loopb_cnt = -1;
147 static gint ett_ancp_oam_timeout = -1;
149 static int proto_ancp = -1;
151 /* ANCP stats - Tap interface */
152 static const guint8 *st_str_packets = "Total Packets";
153 static const guint8 *st_str_packet_types = "ANCP Packet Types";
154 static const guint8 *st_str_adj_pack_types = "ANCP Adjacency Packet Types";
156 static int st_node_packets = -1;
157 static int st_node_packet_types = -1;
158 static int st_node_adj_pack_types = -1;
159 static int ancp_tap = -1;
163 gint ancp_adjcode; /* valid for ancp adjacency message only */
167 static const value_string mtype_names[] = {
169 { 32, "Port-Management" },
175 static const value_string adj_code_names[] = {
183 static const value_string captype_names[] = {
184 { 1, "Dynamic-Topology-Discovery" },
185 { 2, "Line-Configuration" },
186 { 3, "Transactional-Multicast" },
191 static const value_string resulttype_names[] = {
200 static const value_string codetype_names[] = { /* For now, these are OAM codes*/
201 { 0x500, "Access-line-doesn't-exist" },
202 { 0x501, "Loopback-Test-Timeout" },
203 { 0x502, "Reserved" },
204 { 0x503, "DSL-line-status-showtime" },
205 { 0x504, "DSL-line-status-idle" },
206 { 0x505, "DSL-line-status-silent" },
207 { 0x506, "DSL-line-status-training" },
208 { 0x507, "DSL-line-integrity-error" },
209 { 0x508, "DSLAM resource-unavailable" },
210 { 0x509, "Invalid Test Parameter" },
214 static const value_string techtype_str[] = {
220 static const value_string dsl_line_attrs[] = {
221 { 0x91, "DSL-Type" },
222 { 0x81, "Actual-Net-Data-Upstream" },
223 { 0x82, "Actual-Net-Data-Rate-Downstream" },
224 { 0x83, "Minimum-Net-Data-Rate-Upstream" },
225 { 0x84, "Minimum-Net-Data-Rate-Downstream" },
226 { 0x85, "Attainable-Net-Data-Rate-Upstream" },
227 { 0x86, "Attainable-Net-Data-Rate-Downstream" },
228 { 0x87, "Maximum-Net-Data-Rate-Upstream" },
229 { 0x88, "Maximum-Net-Data-Rate-Downstream" },
230 { 0x89, "Minimum-Net-Low-Power-Data-Rate-Upstream" },
231 { 0x8A, "Minimum-Net-Low-Power-Data-Rate-Downstream" },
232 { 0x8B, "Maximum-Interleaving-Delay-Upstream" },
233 { 0x8C, "Actual-Interleaving-Delay-Upstream" },
234 { 0x8D, "Maximum-Interleaving-Delay-Downstream" },
235 { 0x8E, "Actual-Interleaving-Delay-Downstream" },
236 { 0x8F, "DSL line state" },
237 { 0x90, "Access Loop Encapsulation" },
241 static const value_string dsl_line_attr_units[] = {
262 static const value_string dsl_line_type_names[] = {
272 static const value_string dsl_line_state_names[] = {
279 static const value_string ext_tlv_types[] = {
280 { 0x01, "Access-Loop-Circuit-ID" },
281 { 0x02, "Access-Loop-Remote-ID" },
282 { 0x03, "Access-Aggregation-Circuit-ID-ASCII" },
283 { 0x04, "DSL Line Attributes" },
284 { 0x06, "Access-Aggregation-Circuit-ID-Binary" },
285 { 0x07, "OAM-Loopback-Test-Parameters" },
286 { 0x08, "Opaque-Data" },
287 { 0x09, "OAM-Loopback-Test-Response-String" },
292 dissect_ancp_port_up_dn_mgmt(tvbuff_t *tvb, proto_tree *ancp_tree, gint offset)
294 proto_item *sti = NULL;
295 proto_tree *tlv_tree = NULL, *dsl_tree = NULL;
297 guint16 blk_len, tlen, ttype, stlvtype, stlvlen;
298 gint16 num_tlvs, num_stlvs;
301 sti = proto_tree_add_item(ancp_tree, hf_ancp_port, tvb, offset, 4,
305 sti = proto_tree_add_item(ancp_tree, hf_ancp_port_sess_num, tvb, offset, 4,
309 sti = proto_tree_add_item(ancp_tree, hf_ancp_evt_seq_num, tvb, offset, 4,
313 proto_tree_add_item(ancp_tree, hf_ancp_label, tvb, offset, 8, FALSE);
316 /* Start of the Extension Block */
317 proto_tree_add_item(ancp_tree, hf_ancp_reserved, tvb, offset, 1, FALSE);
320 * We have already displayed the message type in the common header dissect
321 * need not display this again here - skip it
323 offset += 1; /* Message type in Ext Blk */
325 proto_tree_add_item(ancp_tree, hf_ancp_tech_type, tvb, offset, 1, FALSE);
326 tech_type = tvb_get_guint8(tvb, offset);
329 proto_tree_add_item(ancp_tree, hf_ancp_blk_len, tvb, offset, 1, FALSE);
332 if (tech_type == TECH_TYPE_DSL) {
333 proto_tree_add_item(ancp_tree, hf_ancp_num_ext_tlvs, tvb,
335 num_tlvs = tvb_get_ntohs(tvb, offset);
338 sti = proto_tree_add_item(ancp_tree, hf_ancp_len, tvb,
340 blk_len = tvb_get_ntohs(tvb, offset);
341 proto_item_append_text(sti, " (Extension Block)");
344 /* Create a TLV sub tree */
345 tlv_tree = proto_item_add_subtree(sti, ett_ancp_len);
347 for( ;num_tlvs; num_tlvs--) {
348 sti = proto_tree_add_item(tlv_tree, hf_ancp_ext_tlv_type, tvb,
350 ttype = tvb_get_ntohs(tvb, offset);
353 sti = proto_tree_add_item(tlv_tree, hf_ancp_len, tvb,
355 tlen = tvb_get_ntohs(tvb, offset);
359 * Extension Block is common for event message and port
360 * management message, but the TLVs that can appear
364 case TLV_DSL_LINE_ATTRIBUTES:
365 /* Create a DSL Attribute SubTree */
366 dsl_tree = proto_item_add_subtree(sti,
367 ett_ancp_ext_tlv_type);
368 num_stlvs = tlen / 8; /* TODO - better way? */
369 for ( ;num_stlvs; num_stlvs--) {
370 sti = proto_tree_add_item(dsl_tree,
371 hf_ancp_dsl_line_stlv_type, tvb, offset,
373 stlvtype = tvb_get_ntohs(tvb, offset);
375 /* Skip sub-tlv-len display for now */
376 stlvlen = tvb_get_ntohs(tvb, offset);
377 offset += 2; /* Sub TLV Length */
379 sti = proto_tree_add_item(dsl_tree,
380 hf_ancp_dsl_line_stlv_value, tvb, offset,
382 val = tvb_get_ntohl(tvb, offset);
383 offset += stlvlen; /* Except loop-encap, rest are 4B */
386 case TLV_DSL_LINE_STATE:
387 proto_item_append_text(sti, " (%s)",
388 val_to_str(val, dsl_line_state_names,
389 "Unknown (0x%02x)"));
392 proto_item_append_text(sti, " (%s)",
393 val_to_str(val, dsl_line_type_names,
394 "Unknown (0x%02x)"));
399 proto_item_append_text(sti, " %s",
402 "Unknown (0x%02x)"));
405 SKIPPADDING(offset, stlvlen);
408 case TLV_PING_OPAQUE_DATA:
410 proto_tree_add_item(tlv_tree, hf_ancp_oam_opaque,
411 tvb, offset, 4, FALSE);
413 proto_tree_add_item(tlv_tree, hf_ancp_oam_opaque,
414 tvb, offset, 4, FALSE);
417 case TLV_PING_PARAMS:
418 /* Count (1B) Timeout (1B), 2B empty */
419 proto_tree_add_item(tlv_tree,
420 hf_ancp_oam_loopb_cnt, tvb, offset, 1, FALSE);
422 proto_tree_add_item(tlv_tree,
423 hf_ancp_oam_timeout, tvb, offset, 1, FALSE);
425 /* Lets not bother about 2B until IETF WG figures out */
429 /* Assume TLV value is string - covers ALCID, OAM resp */
430 proto_tree_add_item(tlv_tree, hf_ancp_ext_tlv_value_str,
431 tvb, offset, tlen, FALSE);
433 SKIPPADDING(offset, tlen);
435 } /* end switch {ttype} */
436 } /* end for {numtlvs} */
441 dissect_ancp_adj_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ancp_tree,
442 gint offset, struct ancp_tap_t *ancp_info
445 proto_item *sti = NULL;
446 proto_tree *ancp_cap_tree = NULL;
447 guint8 byte, numcaps, adjcode;
450 sti = proto_tree_add_item(ancp_tree, hf_ancp_timer, tvb, offset, 1,
453 proto_item_append_text(sti, " msec");
455 sti = proto_tree_add_item(ancp_tree, hf_ancp_adj_code, tvb, offset, 1,
457 byte = tvb_get_guint8(tvb, offset);
459 adjcode = byte & ADJ_CODE_MASK;
460 ancp_info->ancp_adjcode = adjcode; /* stats */
461 proto_item_append_text(sti, " (%s, M Flag %s)",
462 val_to_str(adjcode, adj_code_names, "Unknown (0x%02x)"),
463 byte >> 7 ? "Set" : "Unset");
464 col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
465 val_to_str(adjcode, adj_code_names, "Unknown (0x%02x)"));
467 proto_tree_add_item(ancp_tree, hf_ancp_sender_name, tvb, offset, 6, FALSE);
470 proto_tree_add_item(ancp_tree, hf_ancp_receiver_name, tvb,offset, 6, FALSE);
473 proto_tree_add_item(ancp_tree, hf_ancp_sender_port, tvb, offset, 4, FALSE);
476 proto_tree_add_item(ancp_tree, hf_ancp_receiver_port, tvb,offset, 4, FALSE);
479 sti = proto_tree_add_item(ancp_tree, hf_ancp_p_info, tvb,
481 byte = tvb_get_guint8(tvb, offset);
483 proto_item_append_text(sti, " (Type = %d, Flag = %d)",
484 byte >> 4, byte & 0x0F);
486 proto_tree_add_item(ancp_tree, hf_ancp_sender_instance, tvb, offset, 3,
490 proto_tree_add_item(ancp_tree, hf_ancp_p_id, tvb, offset, 1, FALSE);
493 proto_tree_add_item(ancp_tree, hf_ancp_receiver_instance, tvb, offset, 3,
497 proto_tree_add_item(ancp_tree, hf_ancp_tech_type, tvb,
501 sti = proto_tree_add_item(ancp_tree, hf_ancp_num_tlvs, tvb, offset, 1,
503 numcaps = tvb_get_guint8(tvb, offset);
506 /* Start the capability subtree */
507 ancp_cap_tree = proto_item_add_subtree(sti, ett_ancp_tot_len);
509 sti = proto_tree_add_item(ancp_cap_tree, hf_ancp_tot_len, tvb,
511 tlv_len = tvb_get_ntohs(tvb, offset);
514 for ( ;numcaps; numcaps--) {
515 sti = proto_tree_add_item(ancp_cap_tree, hf_ancp_cap, tvb,
519 tlv_len = tvb_get_ntohs(tvb, offset);
521 proto_item_append_text(sti, " (%d bytes)", tlv_len);
522 /* TODO - if there are non boolean caps, validate before use */
527 ancp_stats_tree_init(stats_tree *st)
529 st_node_packets = stats_tree_create_node(st, st_str_packets, 0, TRUE);
530 st_node_packet_types = stats_tree_create_pivot(st, st_str_packet_types,
532 st_node_adj_pack_types = stats_tree_create_node(st, st_str_adj_pack_types,
533 st_node_packets, TRUE);
537 ancp_stats_tree_packet(stats_tree* st, packet_info* pinfo _U_,
538 epan_dissect_t* edt _U_ , const void* p)
540 struct ancp_tap_t *pi = (struct ancp_tap_t *) p;
542 tick_stat_node(st, st_str_packets, 0, FALSE);
543 stats_tree_tick_pivot(st, st_node_packet_types,
544 val_to_str(pi->ancp_mtype, mtype_names,
545 "Unknown packet type (%d)"));
546 if (pi->ancp_mtype == ANCP_MTYPE_ADJ)
547 stats_tree_tick_pivot(st, st_node_adj_pack_types,
548 val_to_str(pi->ancp_adjcode, adj_code_names,
549 "Unknown Adjacency packet (%d)"));
554 dissect_ancp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
558 struct ancp_tap_t *ancp_info;
561 if (tvb_get_ntohs(tvb, offset) != ANCP_GSMP_ETHER_TYPE)
564 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ANCP");
566 col_clear(pinfo->cinfo, COL_INFO);
568 ancp_info = ep_alloc(sizeof(struct ancp_tap_t));
569 ancp_info->ancp_mtype = 0;
570 ancp_info->ancp_adjcode = 0;
572 if (tree || have_tap_listener(ancp_tap)) { /* we are being asked for details */
573 proto_item *ti = NULL;
574 proto_item *sti = NULL;
575 proto_tree *ancp_tree = NULL;
579 ti = proto_tree_add_item(tree, proto_ancp, tvb, 0, -1, FALSE);
581 ancp_tree = proto_item_add_subtree(ti, ett_ancp_len);
583 offset = 2; /* skip ether type */
585 sti = proto_tree_add_item(ancp_tree, hf_ancp_len, tvb, offset, 2,
587 len = tvb_get_ntohs(tvb, offset);
590 sti = proto_tree_add_item(ancp_tree, hf_ancp_ver, tvb, offset, 1,
592 byte = tvb_get_guint8(tvb, offset);
594 proto_item_append_text(sti, " (%d.%d)", byte >> 4, byte & 0x0F);
596 sti = proto_tree_add_item(ancp_tree, hf_ancp_mtype, tvb, offset, 1,
598 mtype = tvb_get_guint8(tvb, offset); /* ANCP message type */
599 ancp_info->ancp_mtype = mtype; /* stats */
602 col_add_fstr(pinfo->cinfo, COL_INFO, "%s Message",
603 val_to_str(mtype, mtype_names, "Unknown (0x%02x)"));
605 if (mtype != ANCP_MTYPE_ADJ) {
606 /* Dissect common header */
607 proto_tree_add_item(ancp_tree, hf_ancp_result, tvb, offset, 1,
608 FALSE); /* treat as 1B, but dont change offset */
610 proto_tree_add_item(ancp_tree, hf_ancp_code, tvb, offset, 2,
614 proto_tree_add_item(ancp_tree, hf_ancp_p_id, tvb, offset,
618 proto_tree_add_item(ancp_tree, hf_ancp_trans_id, tvb,
622 proto_tree_add_item(ancp_tree, hf_ancp_i_flag, tvb, offset, 1,
623 FALSE); /* treat as 1B, but dont change offset */
625 sti = proto_tree_add_item(ancp_tree, hf_ancp_submsg_num, tvb,
630 * Lets not display the 'Length' field now, it is anyway same
632 * which we have already displayed at the start of the dissect
634 offset += 2; /* Length */
639 dissect_ancp_adj_msg(tvb, pinfo, ancp_tree, offset, ancp_info);
641 case ANCP_MTYPE_PORT_DN:
643 case ANCP_MTYPE_PORT_MGMT:
645 case ANCP_MTYPE_PORT_UP:
646 dissect_ancp_port_up_dn_mgmt(tvb, ancp_tree, offset);
649 proto_item_append_text(sti, " (Unknown Message %d)", mtype);
653 tap_queue_packet(ancp_tap, pinfo, ancp_info);
657 get_ancp_msg_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
659 return (guint)tvb_get_ntohs(tvb, offset + 2) + 4; /* 2B len + 4B hdr */
663 dissect_ancp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
665 tcp_dissect_pdus(tvb, pinfo, tree, TRUE, ANCP_MIN_HDR,
666 get_ancp_msg_len, dissect_ancp_message);
670 proto_register_ancp(void)
672 static hf_register_info hf[] = {
674 { "Length", "ancp.len",
680 { "Version", "ancp.ver",
686 { "Message Type", "ancp.mtype",
688 VALS(mtype_names), 0x0,
692 { "Timer", "ancp.timer",
698 { "Code", "ancp.adjcode", /* this is diff from code */
699 FT_UINT8, BASE_DEC, /* for Adjacency msg only */
703 { &hf_ancp_sender_name,
704 { "Sender Name", "ancp.sender_name",
709 { &hf_ancp_receiver_name,
710 { "Receiver Name", "ancp.receiver_name",
715 { &hf_ancp_sender_port,
716 { "Sender Port", "ancp.sender_port",
721 { &hf_ancp_receiver_port,
722 { "Receiver Port", "ancp.receiver_port",
728 { "Partition Info", "ancp.partition_info",
733 { &hf_ancp_sender_instance,
734 { "Sender Instance", "ancp.sender_instance",
740 { "Partition ID", "ancp.partition_id",
745 { &hf_ancp_receiver_instance,
746 { "Receiver Instance", "ancp.receiver_instance",
751 { &hf_ancp_tech_type,
752 { "Tech Type", "ancp.tech_type",
754 VALS(techtype_str), 0x0,
758 { "Num TLVs", "ancp.num_tlvs",
764 { "Length", "ancp.tot_len", /* name just Len to reuse*/
770 { "Capability", "ancp.capability",
772 VALS(captype_names), 0x0,
776 { "Result", "ancp.result",
778 VALS(resulttype_names), ANCP_RESULT_MASK,
782 { "Code", "ancp.code",
784 VALS(codetype_names), ANCP_CODE_MASK,
788 { "Transaction ID", "ancp.transaction_id",
794 { "I Flag", "ancp.i_flag",
796 TFS(&tfs_set_notset), ANCP_I_FLAG_MASK,
799 { &hf_ancp_submsg_num,
800 { "SubMessage Number", "ancp.submessage_number",
802 NULL, ANCP_SUBMSG_MASK,
806 { "Port", "ancp.port",
811 { &hf_ancp_port_sess_num,
812 { "Port Session Number", "ancp.port_sess_num",
817 { &hf_ancp_evt_seq_num,
818 { "Event Sequence Number", "ancp.evt_seq_num",
824 { "Label", "ancp.label", /* Not used in proto */
830 { "Reserved", "ancp.reserved",
836 { "Block Length", "ancp.blk_len",
841 { &hf_ancp_num_ext_tlvs,
842 { "Num TLVs", "ancp.ext_tlvs.count",
847 { &hf_ancp_ext_tlv_type,
848 { "TLV", "ancp.ext_tlv.type",
850 VALS(ext_tlv_types), 0x0,
853 { &hf_ancp_dsl_line_stlv_type,
854 { "Sub-TLV", "ancp.sub_tlv_type",
856 VALS(dsl_line_attrs), 0x0,
859 { &hf_ancp_dsl_line_stlv_value,
860 { "Value", "ancp.dsl_line_param",
865 { &hf_ancp_ext_tlv_value_str,
866 { "Value", "ancp.ext_tlv.value",
867 FT_STRING, BASE_NONE,
871 { &hf_ancp_oam_opaque,
872 { "Opaque", "ancp.oam.opaque", /* There will be 2 such 32b vals */
877 { &hf_ancp_oam_loopb_cnt,
878 { "OAM Loopback Count", "ancp.oam.loopback_count",
883 { &hf_ancp_oam_timeout,
884 { "OAM Timeout", "ancp.oam.timeout",
891 /* Setup protocol subtree array */
892 static gint *ett[] = {
898 &ett_ancp_sender_name,
899 &ett_ancp_receiver_name,
900 &ett_ancp_sender_port,
901 &ett_ancp_receiver_port,
903 &ett_ancp_sender_instance,
905 &ett_ancp_receiver_instance,
914 &ett_ancp_submsg_num,
916 &ett_ancp_port_sess_num,
917 &ett_ancp_evt_seq_num,
921 &ett_ancp_num_ext_tlvs,
922 &ett_ancp_ext_tlv_type,
923 &ett_ancp_dsl_line_stlv_type,
924 &ett_ancp_dsl_line_stlv_val,
925 &ett_ancp_ext_tlv_value_str,
926 &ett_ancp_oam_opaque,
927 &ett_ancp_oam_loopb_cnt,
928 &ett_ancp_oam_timeout,
931 proto_ancp = proto_register_protocol (
932 "Access Node Control Protocol",
937 proto_register_field_array(proto_ancp, hf, array_length(hf));
938 proto_register_subtree_array(ett, array_length(ett));
939 ancp_tap = register_tap("ancp");
943 proto_reg_handoff_ancp(void)
945 dissector_handle_t ancp_handle;
947 ancp_handle = create_dissector_handle(dissect_ancp, proto_ancp);
948 dissector_add_uint("tcp.port", ANCP_PORT, ancp_handle);
949 stats_tree_register("ancp", "ancp", "ANCP", 0,
950 ancp_stats_tree_packet, ancp_stats_tree_init, NULL);