2 * Routines for CFM EOAM dissection
3 * Copyright 2007, Keith Mercer <keith.mercer@alcatel-lucent.com>
4 * Copyright 2011, Peter Nahas <pnahas@mrv.com>
5 * Copyright 2012, Wim Leflere <wim.leflere-ext@oneaccess-net.com>
6 * Copyright 2013, Andreas Urke <arurke@gmail.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
15 /* This code is based on the following documents:
16 * - IEEE 802.1Q-2022 - IEEE Standard for Local and metropolitan area networks — Bridges and Bridged Networks
17 * - ITU-T Rec. G.8013/Y.1731 (08/2015) - OAM functions and mechanisms for Ethernet-based networks
18 * - ITU-T Rec. G.8031/Y.1342 (01/2015) - Ethernet linear protection switching
19 * - ITU-T Rec. G.8032/Y.1344 (03/2020) - Ethernet ring protection switching
20 * - ITU-T Rec. G.8113/Y.1372 (04/2016) - OAM mechanisms for MPLS-TP in packet transport networks
21 * - IEEE 802.1AB-2016 - IEEE Standard for Local and metropolitan area networks — Station and Media Access Control Connectivity Discovery
26 #include <epan/packet.h>
27 #include <epan/expert.h>
28 #include <epan/etypes.h>
31 #include "packet-mpls.h"
34 /* Value declarations for CFM EOAM dissection */
35 /* CFM Common header */
36 #define CFM_COMMON_HEADER_LEN 4
37 #define CFM_LEVEL_VERSION_OFFSET 0
38 #define CFM_LEVEL_MASK 0xE0
39 #define CFM_LEVEL_SHIFT 5
40 #define CFM_VERSION_MASK 0x1F
41 #define CFM_VERSION_SHIFT 0
42 #define CFM_OPCODE_OFFSET 1
43 #define CFM_FLAGS_OFFSET 2
44 #define CFM_1ST_TLV_OFFSET 3
46 /* Defined by IEEE 802.1Q */
56 /* Defined by ITU-T G.8013/Y.1731 */
78 /* Defined by IEEE 802.1Q */
80 #define SENDER_ID_TLV 0x01
81 #define PORT_STAT_TLV 0x02
83 #define INTERF_STAT_TLV 0x04
84 #define REPLY_ING_TLV 0x05
85 #define REPLY_EGR_TLV 0x06
86 #define LTM_EGR_ID_TLV 0x07
87 #define LTR_EGR_ID_TLV 0x08
88 #define PPB_TE_MIP_TLV 0x09
89 #define DATA_PART1_TLV 0x0A
90 #define DATA_PART2_TLV 0x0B
91 #define TRUNC_DATA_TLV 0x0C
92 // XXX - Does this TLV even exist?
94 #define ORG_SPEC_TLV 0x1F
95 /* Defined by ITU-T Y.1731 */
97 /* Defined by ITU-T Y.1372.1 */
98 #define TGT_MEP_MIP_ID_TLV 0x21
99 #define RPL_MEP_MIP_ID_TLV 0x22
100 #define REQ_MEP_ID_TLV 0x23
101 /* Defined by ITU-T Y.1731 */
102 #define TEST_ID_TLV 0x24
104 /* Sub-OpCode for GNM */
108 #define MD_NAME_FMT_RESVD 0
109 #define MD_NAME_FMT_NONE 1
110 #define MD_NAME_FMT_DOMAIN 2
111 #define MD_NAME_FMT_MAC_ID 3
112 #define MD_NAME_FMT_STRING 4
114 #define MA_NAME_FMT_RESVD 0
115 #define MA_NAME_FMT_PVID 1
116 #define MA_NAME_FMT_STRING 2
117 #define MA_NAME_FMT_ID 3
118 #define MA_NAME_FMT_VPN_ID 4
119 #define MA_NAME_FMT_ICC 32
120 #define MA_NAME_FMT_ICC_CC 33
123 #define RAPS_REQ_ST_MASK 0xF0
124 #define RAPS_REQ_ST_SHIFT 4
125 #define RAPS_SUB_CODE_MASK 0x0F
126 #define RAPS_SUB_CODE_SHIFT 0
128 #define RAPS_REQ_ST_NO_REQ 0
129 #define RAPS_REQ_ST_MAN_SW 7
130 #define RAPS_REQ_ST_SIG_FAIL 11
131 #define RAPS_REQ_ST_FCED_SW 13
132 #define RAPS_REQ_ST_EVENT 14
135 static const value_string opcode_type_name_vals
[] = {
136 { IEEE8021
, "Reserved for IEEE 802.1" },
137 { CCM
, "Continuity Check Message (CCM)" },
138 { LBR
, "Loopback Reply (LBR)" },
139 { LBM
, "Loopback Message (LBM)" },
140 { LTR
, "Linktrace Reply (LTR)" },
141 { LTM
, "Linktrace Message (LTM)" },
142 { RFM
, "Reflected Frame Message (RFM)" },
143 { SFM
, "Send Frame Message (SFM)" },
144 { GNM
, "Generic Notification Message (GNM)" },
145 { AIS
, "Alarm Indication Signal (AIS)" },
146 { LCK
, "Lock Signal (LCK)" },
147 { TST
, "Test Signal (TST)" },
148 { APS
, "Automatic Protection Switching (APS)" },
149 { RAPS
, "Ring-Automatic Protection Switching (R-APS)" },
150 { MCC
, "Maintenance Communication Channel (MCC)" },
151 { LMM
, "Loss Measurement Message (LMM)" },
152 { LMR
, "Loss Measurement Reply (LMR)" },
153 { ODM
, "One Way Delay Measurement (1DM)" },
154 { DMM
, "Delay Measurement Message (DMM)" },
155 { DMR
, "Delay Measurement Reply (DMR)" },
156 { EXM
, "Experimental OAM Message (EXM)" },
157 { EXR
, "Experimental OAM Reply (EXR)" },
158 { VSM
, "Vendor Specific Message (VSM)" },
159 { VSR
, "Vendor Specific Reply (VSR)" },
160 { CSF
, "Client Signal Fail (CSF)" },
161 { OSL
, "One Way Synthetic Loss Measurement (1SL)" },
162 { SLM
, "Synthetic Loss Message (SLM)" },
163 { SLR
, "Synthetic Loss Reply (SLR)" },
167 static const value_string tlv_type_field_vals
[] = {
168 { END_TLV
, "End TLV" },
169 { SENDER_ID_TLV
, "Sender ID TLV" },
170 { PORT_STAT_TLV
, "Port Status TLV" },
171 { DATA_TLV
, "Data TLV" },
172 { INTERF_STAT_TLV
, "Interface Status TLV" },
173 { REPLY_ING_TLV
, "Reply Ingress TLV" },
174 { REPLY_EGR_TLV
, "Reply Egress TLV" },
175 { LTM_EGR_ID_TLV
, "LTM Egress Identifier TLV" },
176 { LTR_EGR_ID_TLV
, "LTR Egress Identifier TLV" },
177 { PPB_TE_MIP_TLV
, "PBB-TE MIP TLV" },
178 { DATA_PART1_TLV
, "Data Part 1 TLV" },
179 { DATA_PART2_TLV
, "Data Part 2 TLV" },
180 { TRUNC_DATA_TLV
, "Truncated Data TLV" },
181 { GNM_TLV
, "Generic Notification Message TLV" },
182 { ORG_SPEC_TLV
, "Organizational-Specific TLV" },
183 { TEST_TLV
, "Test TLV" },
184 { TGT_MEP_MIP_ID_TLV
, "Target MEP/MIP ID TLV" },
185 { RPL_MEP_MIP_ID_TLV
, "Replying MEP/MIP ID TLV" },
186 { REQ_MEP_ID_TLV
, "Requesting MEP ID TLV" },
187 { TEST_ID_TLV
, "Test ID TLV" },
191 static const value_string md_name_format_type_vals
[] = {
192 { MD_NAME_FMT_RESVD
, "Reserved for IEEE 802.1" },
193 { MD_NAME_FMT_NONE
, "No Maintenance Domain Name present" },
194 { MD_NAME_FMT_DOMAIN
, "Domain Name-based string" },
195 { MD_NAME_FMT_MAC_ID
, "MAC address + 2-octet integer" },
196 { MD_NAME_FMT_STRING
, "Character String" },
200 static const value_string ma_name_format_type_vals
[] = {
202 { MA_NAME_FMT_RESVD
, "Reserved for IEEE 802.1" },
203 { MA_NAME_FMT_PVID
, "Primary VID" },
204 { MA_NAME_FMT_STRING
, "Character String" },
205 { MA_NAME_FMT_ID
, "2-octet integer" },
206 { MA_NAME_FMT_VPN_ID
, "RFC 2685 VPN ID" },
208 { MA_NAME_FMT_ICC
, "ICC-based Format" },
209 { MA_NAME_FMT_ICC_CC
, "ICC and CC based Format" },
213 static const value_string ccm_interval_field_encoding_vals
[] = {
215 { 1, "Trans Int 3.33ms, max Lifetime 11.66ms, min Lifetime 10.83ms" },
216 { 2, "Trans Int 10ms, max Lifetime 35ms, min Lifetime 32.5ms" },
217 { 3, "Trans Int 100ms, max Lifetime 350ms, min Lifetime 325ms" },
218 { 4, "Trans Int 1s, max Lifetime 3.5s, min Lifetime 3.25s" },
219 { 5, "Trans Int 10s, max Lifetime 35s, min Lifetime 32.5s" },
220 { 6, "Trans Int 1min, max Lifetime 3.5min, min Lifetime 3.25min" },
221 { 7, "Trans Int 10min, max Lifetime 35min, min Lifetime 32.5min" },
225 static const value_string relay_action_type_vals
[] = {
232 static const value_string ais_lck_period_type_vals
[] = {
233 { 0, "Invalid Value for AIS/LCK PDU's" },
234 { 1, "Invalid Value for AIS/LCK PDU's" },
235 { 2, "Invalid Value for AIS/LCK PDU's" },
236 { 3, "Invalid Value for AIS/LCK PDU's" },
237 { 4, "1 frame per second" },
238 { 5, "Invalid Value for AIS/LCK PDU's" },
239 { 6, "1 frame per minute" },
240 { 7, "Invalid Value for AIS/LCK PDU's" },
244 static const value_string sender_id_tlv_chassis_id_subtype_vals
[] = {
245 { 1, "Chassis component" },
246 { 2, "Interface alias" },
247 { 3, "Port component" },
248 { 4, "MAC address" },
249 { 5, "Network address" },
250 { 6, "Interface name" },
251 { 7, "Locally assigned" },
255 static const value_string port_stat_tlv_vals
[] = {
261 static const value_string interface_stat_tlv_vals
[] = {
267 { 6, "isNotPresent" },
268 { 7, "isLowerLayerDown" },
272 static const value_string reply_ingress_tlv_vals
[] = {
280 static const value_string reply_egress_tlv_vals
[] = {
288 static const value_string aps_request_state_vals
[] = {
290 { 1, "Do not revert" },
291 { 2, "Reverse request" },
294 { 5, "Wait to restore" },
295 { 6, "Depreciated" },
296 { 7, "Manual switch" },
298 { 9, "Signal degrade" },
300 { 11, "Signal fail for working" },
302 { 13, "Forced switch" },
303 { 14, "Signal fail on protection" },
304 { 15, "Lockout of protection" },
308 static const true_false_string tfs_aps_protection_type_A
= {
313 static const true_false_string tfs_aps_protection_type_B
= {
314 "1:1 (no permanent bridge)",
315 "1+1 (permanent bridge)"
318 static const true_false_string tfs_aps_protection_type_D
= {
319 "Bidirectional switching",
320 "Unidirectional switching"
323 static const true_false_string tfs_aps_protection_type_R
= {
324 "Revertive operation",
325 "Non-revertive operation"
328 static const value_string aps_requested_signal_values
[] = {
330 { 1, "Normal traffic" },
334 static const value_string aps_bridged_signal_values
[] = {
336 { 1, "Normal traffic" },
340 static const value_string aps_bridge_type_values
[] = {
346 static const value_string raps_request_state_values
[] = {
347 { RAPS_REQ_ST_NO_REQ
, "No Request" },
348 { RAPS_REQ_ST_MAN_SW
, "Manual Switch" },
349 { RAPS_REQ_ST_SIG_FAIL
, "Signal Fail" },
350 { RAPS_REQ_ST_FCED_SW
, "Forced Switch" },
351 { RAPS_REQ_ST_EVENT
, "Event" },
355 static const value_string rasp_event_subcode_vals
[] = {
356 { 0, "Flush Request" },
360 static const true_false_string tfs_rasp_rpl_blocked
= {
365 static const true_false_string tfs_rasp_dnf
= {
370 static const true_false_string tfs_rasp_bpr
= {
375 static const value_string gnm_sub_opcode_type_name_vals
[] = {
376 { BNM
, "Bandwidth Notification Message" },
380 static const value_string cfm_bnm_flags_period_vals
[] = {
382 { 1, "For further study" },
383 { 2, "For further study" },
384 { 3, "For further study" },
392 static const value_string cfm_csf_flags_type_vals
[] = {
400 static const value_string cfm_csf_flags_period_vals
[] = {
402 { 1, "For further study" },
403 { 2, "For further study" },
404 { 3, "For further study" },
406 { 5, "For further study" },
408 { 7, "For further study" },
412 static const true_false_string tfs_lmm_lmr_type
= {
417 static const true_false_string tfs_odm_dmm_dmr_type
= {
422 static const value_string test_tlv_pattern_type_vals
[] = {
423 { 0, "Null signal without CRC-32" },
424 { 1, "Null signal with CRC-32" },
425 { 2, "PRBS (2.e-31 -1), without CRC-32" },
426 { 3, "PRBS (2.e-31 -1), with CRC-32" },
430 static const value_string mep_mip_id_tlv_subtype_vals
[] = {
431 { 0x00, "Discovery ingress/node MEP/MIP" },
432 { 0x01, "Discovery egress MEP/MIP" },
438 static const value_string req_mep_id_tlv_lb_vals
[] = {
445 void proto_register_cfm(void);
446 void proto_reg_handoff_cfm(void);
448 static int proto_cfm
;
450 static int hf_cfm_md_level
;
451 static int hf_cfm_version
;
452 static int hf_cfm_opcode
;
453 static int hf_cfm_flags
;
454 static int hf_cfm_flags_Reserved
;
455 static int hf_cfm_first_tlv_offset
;
457 static int hf_cfm_mep_id
;
458 static int hf_cfm_maid
;
459 static int hf_cfm_maid_md_name_format
;
460 static int hf_cfm_maid_md_name_length
;
461 static int hf_cfm_maid_md_name_string
;
462 static int hf_cfm_maid_md_name_hex
;
463 static int hf_cfm_maid_md_name_mac
;
464 static int hf_cfm_maid_md_name_mac_id
;
465 static int hf_cfm_maid_ma_name_format
;
466 static int hf_cfm_maid_ma_name_length
;
467 static int hf_cfm_maid_ma_name_pvid
;
468 static int hf_cfm_maid_ma_name_string
;
469 static int hf_cfm_maid_ma_name_id
;
470 static int hf_cfm_maid_ma_name_vpnid_oui
;
471 static int hf_cfm_maid_ma_name_vpnid_index
;
472 static int hf_cfm_maid_ma_name_icc_umc
;
473 static int hf_cfm_maid_ma_name_cc
;
474 static int hf_cfm_maid_ma_name_hex
;
475 static int hf_cfm_maid_padding
;
477 static int hf_cfm_ccm_pdu
;
478 static int hf_cfm_ccm_flags_RDI
;
479 static int hf_cfm_ccm_flags_Traffic
;
480 static int hf_cfm_ccm_flags_Reserved
;
481 static int hf_cfm_ccm_flags_Interval
;
482 static int hf_cfm_ccm_seq_number
;
483 static int hf_cfm_ccm_itu_t_y1731
;
484 static int hf_cfm_ccm_itu_TxFCf
;
485 static int hf_cfm_ccm_itu_RxFCb
;
486 static int hf_cfm_ccm_itu_TxFCb
;
487 static int hf_cfm_ccm_itu_reserved
;
489 static int hf_cfm_lbm_pdu
;
490 static int hf_cfm_lbm_lbr_transaction_id
;
492 static int hf_cfm_lbr_pdu
;
494 static int hf_cfm_ltm_pdu
;
495 static int hf_cfm_ltm_flags_UseFDBonly
;
496 static int hf_cfm_ltm_flags_Reserved
;
497 static int hf_cfm_ltm_ltr_transaction_id
;
498 static int hf_cfm_ltm_ltr_ttl
;
499 static int hf_cfm_ltm_orig_addr
;
500 static int hf_cfm_ltm_targ_addr
;
502 static int hf_cfm_ltr_pdu
;
503 static int hf_cfm_ltr_flags_UseFDBonly
;
504 static int hf_cfm_ltr_flags_FwdYes
;
505 static int hf_cfm_ltr_flags_TerminalMEP
;
506 static int hf_cfm_ltr_flags_Reserved
;
507 static int hf_cfm_ltr_relay_action
;
509 static int hf_cfm_rfm_pdu
;
510 static int hf_cfm_rfm_transaction_id
;
512 static int hf_cfm_sfm_pdu
;
513 static int hf_cfm_sfm_transaction_id
;
515 static int hf_cfm_gnm_pdu
;
516 static int hf_cfm_gnm_unknown_flags
;
517 static int hf_cfm_gnm_subopcode
;
519 static int hf_cfm_bnm_flags_Reserved
;
520 static int hf_cfm_bnm_flags_Period
;
521 static int hf_cfm_bnm_pdu
;
522 static int hf_cfm_bnm_nominal_bw
;
523 static int hf_cfm_bnm_current_bw
;
524 static int hf_cfm_bnm_port_id
;
526 static int hf_cfm_ais_pdu
;
527 static int hf_cfm_ais_flags_Reserved
;
528 static int hf_cfm_ais_flags_Period
;
530 static int hf_cfm_lck_pdu
;
531 static int hf_cfm_lck_flags_Reserved
;
532 static int hf_cfm_lck_flags_Period
;
534 static int hf_cfm_tst_pdu
;
535 static int hf_cfm_tst_sequence_num
;
537 static int hf_cfm_aps_pdu
;
538 static int hf_cfm_aps_req_st
;
539 static int hf_cfm_aps_protection_type_A
;
540 static int hf_cfm_aps_protection_type_B
;
541 static int hf_cfm_aps_protection_type_D
;
542 static int hf_cfm_aps_protection_type_R
;
543 static int hf_cfm_aps_requested_signal
;
544 static int hf_cfm_aps_bridged_signal
;
545 static int hf_cfm_aps_bridge_type
;
547 static int hf_cfm_raps_pdu
;
548 static int hf_cfm_raps_req_st
;
549 static int hf_cfm_raps_event_subcode
;
550 static int hf_cfm_raps_subcode_reserved
;
551 static int hf_cfm_raps_status
;
552 static int hf_cfm_raps_status_rb
;
553 static int hf_cfm_raps_status_dnf
;
554 static int hf_cfm_raps_status_bpr
;
555 static int hf_cfm_raps_status_reserved_v1
;
556 static int hf_cfm_raps_status_reserved_v2
;
557 static int hf_cfm_raps_node_id
;
558 static int hf_cfm_raps_reserved
;
560 static int hf_cfm_mcc_pdu
;
561 static int hf_cfm_mcc_oui
;
562 static int hf_cfm_mcc_subopcode
;
563 static int hf_cfm_mcc_data
;
565 static int hf_cfm_lmm_pdu
;
566 static int hf_cfm_lmm_lmr_flags_Reserved
;
567 static int hf_cfm_lmm_lmr_flags_Type
;
568 static int hf_cfm_lmm_lmr_TxFCf
;
569 static int hf_cfm_lmm_lmr_RxFCf
;
570 static int hf_cfm_lmm_lmr_TxFCb
;
572 static int hf_cfm_lmr_pdu
;
574 static int hf_cfm_odm_pdu
;
575 static int hf_cfm_odm_dmm_dmr_flags_Reserved
;
576 static int hf_cfm_odm_dmm_dmr_flags_Type
;
577 static int hf_cfm_odm_dmm_dmr_TxTimestampf
;
578 static int hf_cfm_odm_dmm_dmr_RxTimestampf
;
580 static int hf_cfm_dmm_pdu
;
581 static int hf_cfm_dmm_dmr_TxTimestampb
;
582 static int hf_cfm_dmm_dmr_RxTimestampb
;
584 static int hf_cfm_dmr_pdu
;
586 static int hf_cfm_exm_pdu
;
587 static int hf_cfm_exm_oui
;
588 static int hf_cfm_exm_subopcode
;
589 static int hf_cfm_exm_data
;
591 static int hf_cfm_exr_pdu
;
592 static int hf_cfm_exr_oui
;
593 static int hf_cfm_exr_subopcode
;
594 static int hf_cfm_exr_data
;
596 static int hf_cfm_vsm_pdu
;
597 static int hf_cfm_vsm_oui
;
598 static int hf_cfm_vsm_subopcode
;
599 static int hf_cfm_vsm_data
;
601 static int hf_cfm_vsr_pdu
;
602 static int hf_cfm_vsr_oui
;
603 static int hf_cfm_vsr_subopcode
;
604 static int hf_cfm_vsr_data
;
606 static int hf_cfm_csf_pdu
;
607 static int hf_cfm_csf_flags_Reserved
;
608 static int hf_cfm_csf_flags_Type
;
609 static int hf_cfm_csf_flags_Period
;
611 static int hf_cfm_osl_pdu
;
612 static int hf_cfm_osl_src_mep
;
613 static int hf_cfm_osl_reserved
;
614 static int hf_cfm_osl_testid
;
615 static int hf_cfm_osl_txfcf
;
617 static int hf_cfm_slm_pdu
;
618 static int hf_cfm_slm_slr_src_mep
;
619 static int hf_cfm_slm_reserved
;
620 static int hf_cfm_slm_slr_testid
;
621 static int hf_cfm_slm_slr_txfcf
;
623 static int hf_cfm_slr_pdu
;
624 static int hf_cfm_slr_rsp_mep
;
625 static int hf_cfm_slr_txfcb
;
627 static int hf_cfm_unknown_pdu
;
628 static int hf_cfm_unknown_flags
;
629 static int hf_cfm_unknown_data
;
631 static int hf_cfm_all_tlvs
;
632 static int hf_cfm_tlv_type
;
633 static int hf_cfm_tlv_length
;
635 static int hf_tlv_chassis_id_length
;
636 static int hf_tlv_chassis_id_subtype
;
637 static int hf_tlv_chassis_id_chassis_component
;
638 static int hf_tlv_chassis_id_interface_alias
;
639 static int hf_tlv_chassis_id_port_component
;
640 static int hf_tlv_chassis_id_mac_address
;
641 static int hf_tlv_chassis_id_network_address_family
;
642 static int hf_tlv_chassis_id_network_address_ipv4
;
643 static int hf_tlv_chassis_id_network_address_ipv6
;
644 static int hf_tlv_chassis_id_network_address_unknown
;
645 static int hf_tlv_chassis_id_interface_name
;
646 static int hf_tlv_chassis_id_locally_assigned
;
647 static int hf_tlv_chassis_id_unknown
;
648 static int hf_tlv_ma_domain_length
;
649 static int hf_tlv_ma_domain
;
650 static int hf_tlv_management_addr_length
;
651 static int hf_tlv_management_addr_ipv4
;
652 static int hf_tlv_management_addr_ipv6
;
653 static int hf_tlv_management_addr_eth
;
654 static int hf_tlv_management_addr_unknown
;
655 static int hf_tlv_port_status_value
;
656 static int hf_tlv_data_value
;
657 static int hf_tlv_interface_status_value
;
659 static int hf_tlv_reply_ingress_action
;
660 static int hf_tlv_reply_ingress_mac_address
;
661 static int hf_tlv_reply_ing_egr_portid_length
;
662 static int hf_tlv_reply_ing_egr_portid_subtype
;
663 static int hf_tlv_reply_ing_egr_portid_interface_alias
;
664 static int hf_tlv_reply_ing_egr_portid_port_component
;
665 static int hf_tlv_reply_ing_egr_portid_mac_address
;
666 static int hf_tlv_reply_ing_egr_portid_network_address_family
;
667 static int hf_tlv_reply_ing_egr_portid_network_address_ipv4
;
668 static int hf_tlv_reply_ing_egr_portid_network_address_ipv6
;
669 static int hf_tlv_reply_ing_egr_portid_network_address_unknown
;
670 static int hf_tlv_reply_ing_egr_portid_interface_name
;
671 static int hf_tlv_reply_ing_egr_portid_agent_circuit_id
;
672 static int hf_tlv_reply_ing_egr_portid_locally_assigned
;
673 static int hf_tlv_reply_ing_egr_portid_unknown
;
674 static int hf_tlv_reply_egress_action
;
675 static int hf_tlv_reply_egress_mac_address
;
677 static int hf_tlv_ltr_egress_last_id_mac
;
678 static int hf_tlv_ltr_egress_last_id_unique_identifier
;
679 static int hf_tlv_ltr_egress_next_id_mac
;
680 static int hf_tlv_ltr_egress_next_id_unique_identifier
;
681 static int hf_tlv_ltm_egress_id_mac
;
682 static int hf_tlv_ltm_egress_id_unique_identifier
;
684 static int hf_tlv_pbb_te_mip_mac_address
;
685 static int hf_tlv_pbb_te_reverse_vid
;
686 static int hf_tlv_pbb_te_reverse_mac
;
688 static int hf_tlv_org_spec_oui
;
689 static int hf_tlv_org_spec_subtype
;
690 static int hf_tlv_org_spec_value
;
691 static int hf_tlv_tst_test_pattern_type
;
692 static int hf_tlv_tst_test_pattern
;
693 static int hf_tlv_tst_CRC32
;
695 static int hf_tlv_tgt_rpl_mep_mip_id_subtype
;
696 static int hf_tlv_tgt_rpl_padding
;
697 static int hf_tlv_tgt_rpl_mep_id
;
698 static int hf_tlv_tgt_rpl_mip_id_icc
;
699 static int hf_tlv_tgt_rpl_mip_id_node_id
;
700 static int hf_tlv_tgt_rpl_mip_id_if_num
;
701 static int hf_tlv_tgt_rpl_mip_id_cc
;
703 static int hf_tlv_req_mep_id_lb
;
704 static int hf_tlv_req_mep_id_reserved
;
706 static int hf_tlv_tst_id_test_id
;
708 static int hf_tlv_unknown_data
;
711 static int ett_cfm_pdu
;
712 static int ett_cfm_flags
;
713 static int ett_cfm_maid
;
714 static int ett_cfm_ccm_itu
;
715 static int ett_cfm_all_tlvs
;
716 static int ett_cfm_tlv
;
717 static int ett_cfm_raps_status
;
719 static expert_field ei_tlv_tst_id_length
;
720 static expert_field ei_tlv_management_addr_length
;
722 static dissector_handle_t cfm_handle
;
724 /* CFM EOAM sub-protocol dissectors */
726 static int dissect_mep_maid(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
729 proto_tree
*cfm_maid_tree
;
733 uint32_t maid_md_name_format
;
734 uint32_t maid_ma_name_format
;
735 uint32_t maid_ma_name_length
;
738 proto_tree_add_item(tree
, hf_cfm_mep_id
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
741 ti
= proto_tree_add_item(tree
, hf_cfm_maid
, tvb
, offset
, 48, ENC_NA
);
742 cfm_maid_tree
= proto_item_add_subtree(ti
, ett_cfm_maid
);
743 maid_offset
= offset
;
744 proto_tree_add_item_ret_uint(cfm_maid_tree
, hf_cfm_maid_md_name_format
, tvb
, maid_offset
, 1, ENC_NA
, &maid_md_name_format
);
747 if (maid_md_name_format
!= MD_NAME_FMT_NONE
) { // NOTE: true for IEEE 802.1Q CCM only
748 uint8_t maid_md_name_length
;
749 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_md_name_length
,
750 tvb
, maid_offset
, 1, ENC_NA
);
751 maid_md_name_length
= tvb_get_uint8(tvb
, maid_offset
);
753 if (maid_md_name_length
) { // NOTE: Between 1 and 43
754 switch (maid_md_name_format
) {
755 case MD_NAME_FMT_MAC_ID
:
756 if (maid_md_name_length
!= 8) {
757 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_md_name_hex
,
758 tvb
, maid_offset
, maid_md_name_length
, ENC_NA
);
760 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_md_name_mac
,
761 tvb
, maid_offset
, 6, ENC_NA
);
762 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_md_name_mac_id
,
763 tvb
, maid_offset
+ 6, 2, ENC_NA
);
766 case MD_NAME_FMT_DOMAIN
:
767 case MD_NAME_FMT_STRING
:
768 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_md_name_string
,
769 tvb
, maid_offset
, maid_md_name_length
, ENC_ASCII
|ENC_NA
);
772 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_md_name_hex
,
773 tvb
, maid_offset
, maid_md_name_length
, ENC_NA
);
776 maid_offset
+= maid_md_name_length
;
779 proto_tree_add_item_ret_uint(cfm_maid_tree
, hf_cfm_maid_ma_name_format
, tvb
, maid_offset
, 1, ENC_NA
, &maid_ma_name_format
);
781 proto_tree_add_item_ret_uint(cfm_maid_tree
, hf_cfm_maid_ma_name_length
, tvb
, maid_offset
, 1, ENC_NA
, &maid_ma_name_length
);
784 switch (maid_ma_name_format
) {
785 case MA_NAME_FMT_RESVD
:
786 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_ma_name_hex
,
787 tvb
, maid_offset
, maid_ma_name_length
, ENC_NA
);
789 case MA_NAME_FMT_PVID
:
790 if (maid_ma_name_length
!= 2) {
791 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_ma_name_hex
,
792 tvb
, maid_offset
, maid_ma_name_length
, ENC_NA
);
794 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_ma_name_pvid
,
795 tvb
, maid_offset
, 2, ENC_NA
);
798 case MA_NAME_FMT_STRING
:
799 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_ma_name_string
,
800 tvb
, maid_offset
, maid_ma_name_length
, ENC_ASCII
|ENC_NA
);
803 if (maid_ma_name_length
!= 2) {
804 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_ma_name_hex
,
805 tvb
, maid_offset
, maid_ma_name_length
, ENC_NA
);
807 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_ma_name_id
,
808 tvb
, maid_offset
, 2, ENC_NA
);
811 case MA_NAME_FMT_VPN_ID
:
812 if (maid_ma_name_length
!= 7) {
813 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_ma_name_hex
,
814 tvb
, maid_offset
, maid_ma_name_length
, ENC_NA
);
816 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_ma_name_vpnid_oui
,
817 tvb
, maid_offset
, 3, ENC_NA
);
818 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_ma_name_vpnid_index
,
819 tvb
, maid_offset
+ 3, 4, ENC_NA
);
822 case MA_NAME_FMT_ICC
:
823 if (maid_ma_name_length
!= 13) {
824 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_ma_name_hex
,
825 tvb
, maid_offset
, maid_ma_name_length
, ENC_NA
);
827 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_ma_name_icc_umc
,
828 tvb
, maid_offset
, 13, ENC_ASCII
|ENC_NA
);
831 case MA_NAME_FMT_ICC_CC
:
832 if (maid_ma_name_length
!= 15) {
833 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_ma_name_hex
,
834 tvb
, maid_offset
, maid_ma_name_length
, ENC_NA
);
836 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_ma_name_cc
,
837 tvb
, maid_offset
, 2, ENC_ASCII
|ENC_NA
);
838 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_ma_name_icc_umc
,
839 tvb
, maid_offset
+ 2, 13, ENC_ASCII
|ENC_NA
);
843 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_ma_name_hex
,
844 tvb
, maid_offset
, maid_ma_name_length
, ENC_NA
);
848 maid_offset
+= maid_ma_name_length
;
850 if (offset
> maid_offset
) {
852 padding_length
= offset
- maid_offset
;
853 proto_tree_add_item(cfm_maid_tree
, hf_cfm_maid_padding
,
854 tvb
, maid_offset
, padding_length
, ENC_NA
);
860 static int dissect_cfm_ccm(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
864 proto_tree
*cfm_pdu_tree
;
865 proto_tree
*cfm_flag_tree
;
866 uint32_t first_tlv_offset
;
867 int start_offset
= offset
;
868 int length_remaining
;
871 proto_tree
*cfm_ccm_itu_tree
;
873 ti
= proto_tree_add_item(tree
, hf_cfm_ccm_pdu
, tvb
, offset
, -1, ENC_NA
);
874 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
876 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
877 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
878 proto_tree_add_item(cfm_flag_tree
, hf_cfm_ccm_flags_RDI
, tvb
, offset
, 1, ENC_NA
);
879 proto_tree_add_item(cfm_flag_tree
, hf_cfm_ccm_flags_Traffic
, tvb
, offset
, 1, ENC_NA
);
880 proto_tree_add_item(cfm_flag_tree
, hf_cfm_ccm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
881 proto_tree_add_item(cfm_flag_tree
, hf_cfm_ccm_flags_Interval
, tvb
, offset
, 1, ENC_NA
);
884 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
887 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_ccm_seq_number
, tvb
, offset
, 4, ENC_BIG_ENDIAN
); // NOTE: Zero in Y.1731
890 /* dissect CCM MEP ID + MAID */
891 offset
= dissect_mep_maid(tvb
, pinfo
, cfm_pdu_tree
, offset
);
893 /* Dissect 16 octets reserved for Y.1731, samples of the wrap-around frame counters */
894 wi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_ccm_itu_t_y1731
, tvb
, offset
, 16, ENC_NA
);
895 cfm_ccm_itu_tree
= proto_item_add_subtree(wi
, ett_cfm_ccm_itu
);
896 proto_tree_add_item(cfm_ccm_itu_tree
, hf_cfm_ccm_itu_TxFCf
, tvb
, offset
, 4, ENC_NA
);
898 proto_tree_add_item(cfm_ccm_itu_tree
, hf_cfm_ccm_itu_RxFCb
, tvb
, offset
, 4, ENC_NA
);
900 proto_tree_add_item(cfm_ccm_itu_tree
, hf_cfm_ccm_itu_TxFCb
, tvb
, offset
, 4, ENC_NA
);
902 proto_tree_add_item(cfm_ccm_itu_tree
, hf_cfm_ccm_itu_reserved
, tvb
, offset
, 4, ENC_NA
);
905 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
907 if (length_remaining
> 0) {
908 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
909 offset
+= length_remaining
;
912 proto_item_set_len(ti
, offset
- start_offset
);
916 static int dissect_cfm_lbm(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
920 proto_tree
*cfm_pdu_tree
;
921 proto_tree
*cfm_flag_tree
;
922 uint32_t first_tlv_offset
;
923 int start_offset
= offset
;
924 int length_remaining
;
926 ti
= proto_tree_add_item(tree
, hf_cfm_lbm_pdu
, tvb
, offset
, -1, ENC_NA
);
927 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
929 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
930 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
931 proto_tree_add_item(cfm_flag_tree
, hf_cfm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
934 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
937 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_lbm_lbr_transaction_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
940 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
942 if (length_remaining
> 0) {
943 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
944 offset
+= length_remaining
;
947 proto_item_set_len(ti
, offset
- start_offset
);
951 static int dissect_cfm_lbr(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
955 proto_tree
*cfm_pdu_tree
;
956 proto_tree
*cfm_flag_tree
;
957 uint32_t first_tlv_offset
;
958 int start_offset
= offset
;
959 int length_remaining
;
961 ti
= proto_tree_add_item(tree
, hf_cfm_lbr_pdu
, tvb
, offset
, -1, ENC_NA
);
962 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
964 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
965 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
966 proto_tree_add_item(cfm_flag_tree
, hf_cfm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
969 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
972 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_lbm_lbr_transaction_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
975 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
977 if (length_remaining
> 0) {
978 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
979 offset
+= length_remaining
;
982 proto_item_set_len(ti
, offset
- start_offset
);
986 static int dissect_cfm_ltm(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
990 proto_tree
*cfm_pdu_tree
;
991 proto_tree
*cfm_flag_tree
;
992 uint32_t first_tlv_offset
;
993 int start_offset
= offset
;
994 int length_remaining
;
996 ti
= proto_tree_add_item(tree
, hf_cfm_ltm_pdu
, tvb
, offset
, -1, ENC_NA
);
997 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
999 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1000 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1001 proto_tree_add_item(cfm_flag_tree
, hf_cfm_ltm_flags_UseFDBonly
, tvb
, offset
, 1, ENC_NA
);
1002 proto_tree_add_item(cfm_flag_tree
, hf_cfm_ltm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1005 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1008 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_ltm_ltr_transaction_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1010 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_ltm_ltr_ttl
, tvb
, offset
, 1, ENC_NA
);
1012 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_ltm_orig_addr
, tvb
, offset
, 6, ENC_NA
);
1014 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_ltm_targ_addr
, tvb
, offset
, 6, ENC_NA
);
1017 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1019 if (length_remaining
> 0) {
1020 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1021 offset
+= length_remaining
;
1024 proto_item_set_len(ti
, offset
- start_offset
);
1028 static int dissect_cfm_ltr(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1032 proto_tree
*cfm_pdu_tree
;
1033 proto_tree
*cfm_flag_tree
;
1034 uint32_t first_tlv_offset
;
1035 int start_offset
= offset
;
1036 int length_remaining
;
1038 ti
= proto_tree_add_item(tree
, hf_cfm_ltr_pdu
, tvb
, offset
, -1, ENC_NA
);
1039 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1041 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1042 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1043 proto_tree_add_item(cfm_flag_tree
, hf_cfm_ltr_flags_UseFDBonly
, tvb
, offset
, 1, ENC_NA
);
1044 proto_tree_add_item(cfm_flag_tree
, hf_cfm_ltr_flags_FwdYes
, tvb
, offset
, 1, ENC_NA
);
1045 proto_tree_add_item(cfm_flag_tree
, hf_cfm_ltr_flags_TerminalMEP
, tvb
, offset
, 1, ENC_NA
);
1046 proto_tree_add_item(cfm_flag_tree
, hf_cfm_ltr_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1049 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1052 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_ltm_ltr_transaction_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1054 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_ltm_ltr_ttl
, tvb
, offset
, 1, ENC_NA
);
1056 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_ltr_relay_action
, tvb
, offset
, 1, ENC_NA
);
1059 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1061 if (length_remaining
> 0) {
1062 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1063 offset
+= length_remaining
;
1066 proto_item_set_len(ti
, offset
- start_offset
);
1070 static int dissect_cfm_rfm(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1074 proto_tree
*cfm_pdu_tree
;
1075 proto_tree
*cfm_flag_tree
;
1076 uint32_t first_tlv_offset
;
1077 int start_offset
= offset
;
1078 int length_remaining
;
1080 ti
= proto_tree_add_item(tree
, hf_cfm_rfm_pdu
, tvb
, offset
, -1, ENC_NA
);
1081 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1083 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1084 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1085 proto_tree_add_item(cfm_flag_tree
, hf_cfm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1088 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1091 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_rfm_transaction_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1094 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1096 if (length_remaining
> 0) {
1097 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1098 offset
+= length_remaining
;
1101 proto_item_set_len(ti
, offset
- start_offset
);
1105 static int dissect_cfm_sfm(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1109 proto_tree
*cfm_pdu_tree
;
1110 proto_tree
*cfm_flag_tree
;
1111 uint32_t first_tlv_offset
;
1112 int start_offset
= offset
;
1113 int length_remaining
;
1115 ti
= proto_tree_add_item(tree
, hf_cfm_sfm_pdu
, tvb
, offset
, -1, ENC_NA
);
1116 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1118 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1119 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1120 proto_tree_add_item(cfm_flag_tree
, hf_cfm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1123 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1126 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_sfm_transaction_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1129 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1131 if (length_remaining
> 0) {
1132 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1133 offset
+= length_remaining
;
1136 proto_item_set_len(ti
, offset
- start_offset
);
1140 static int dissect_cfm_bnm(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1144 proto_tree
*cfm_pdu_tree
;
1145 proto_tree
*cfm_flag_tree
;
1146 uint32_t first_tlv_offset
;
1147 int start_offset
= offset
;
1148 int length_remaining
;
1150 ti
= proto_tree_add_item(tree
, hf_cfm_bnm_pdu
, tvb
, offset
, -1, ENC_NA
);
1151 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1153 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1154 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1155 proto_tree_add_item(cfm_flag_tree
, hf_cfm_bnm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1156 proto_tree_add_item(cfm_flag_tree
, hf_cfm_bnm_flags_Period
, tvb
, offset
, 1, ENC_NA
);
1159 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1162 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_gnm_subopcode
, tvb
, offset
, 1, ENC_NA
);
1165 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_bnm_nominal_bw
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1167 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_bnm_current_bw
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1169 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_bnm_port_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1172 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1174 if (length_remaining
> 0) {
1175 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1176 offset
+= length_remaining
;
1179 proto_item_set_len(ti
, offset
- start_offset
);
1183 static int dissect_cfm_gnm_unknown(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1187 proto_tree
*cfm_pdu_tree
;
1188 proto_tree
*cfm_flag_tree
;
1189 uint32_t first_tlv_offset
;
1190 int start_offset
= offset
;
1191 int length_remaining
;
1193 ti
= proto_tree_add_item(tree
, hf_cfm_gnm_pdu
, tvb
, offset
, -1, ENC_NA
);
1194 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1196 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1197 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1198 proto_tree_add_item(cfm_flag_tree
, hf_cfm_gnm_unknown_flags
, tvb
, offset
, 1, ENC_NA
);
1201 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1204 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_gnm_subopcode
, tvb
, offset
, 1, ENC_NA
);
1207 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1209 if (length_remaining
> 0) {
1210 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1211 offset
+= length_remaining
;
1214 proto_item_set_len(ti
, offset
- start_offset
);
1218 static int dissect_cfm_gnm(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
)
1220 uint8_t cfm_gnm_pdu_type
= tvb_get_uint8(tvb
, offset
+ 4);
1222 switch (cfm_gnm_pdu_type
) {
1224 offset
= dissect_cfm_bnm(tvb
, pinfo
, tree
, offset
);
1227 offset
= dissect_cfm_gnm_unknown(tvb
, pinfo
, tree
, offset
);
1234 static int dissect_cfm_ais(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1238 proto_tree
*cfm_pdu_tree
;
1239 proto_tree
*cfm_flag_tree
;
1240 uint32_t first_tlv_offset
;
1241 int start_offset
= offset
;
1242 int length_remaining
;
1244 ti
= proto_tree_add_item(tree
, hf_cfm_ais_pdu
, tvb
, offset
, -1, ENC_NA
);
1245 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1247 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1248 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1249 proto_tree_add_item(cfm_flag_tree
, hf_cfm_ais_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1250 proto_tree_add_item(cfm_flag_tree
, hf_cfm_ais_flags_Period
, tvb
, offset
, 1, ENC_NA
);
1253 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1256 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1258 if (length_remaining
> 0) {
1259 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1260 offset
+= length_remaining
;
1263 proto_item_set_len(ti
, offset
- start_offset
);
1267 static int dissect_cfm_lck(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1271 proto_tree
*cfm_pdu_tree
;
1272 proto_tree
*cfm_flag_tree
;
1273 uint32_t first_tlv_offset
;
1274 int start_offset
= offset
;
1275 int length_remaining
;
1277 ti
= proto_tree_add_item(tree
, hf_cfm_lck_pdu
, tvb
, offset
, -1, ENC_NA
);
1278 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1280 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1281 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1282 proto_tree_add_item(cfm_flag_tree
, hf_cfm_lck_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1283 proto_tree_add_item(cfm_flag_tree
, hf_cfm_lck_flags_Period
, tvb
, offset
, 1, ENC_NA
);
1286 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1289 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1291 if (length_remaining
> 0) {
1292 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1293 offset
+= length_remaining
;
1296 proto_item_set_len(ti
, offset
- start_offset
);
1300 static int dissect_cfm_tst(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1304 proto_tree
*cfm_pdu_tree
;
1305 proto_tree
*cfm_flag_tree
;
1306 uint32_t first_tlv_offset
;
1307 int start_offset
= offset
;
1308 int length_remaining
;
1310 ti
= proto_tree_add_item(tree
, hf_cfm_tst_pdu
, tvb
, offset
, -1, ENC_NA
);
1311 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1313 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1314 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1315 proto_tree_add_item(cfm_flag_tree
, hf_cfm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1318 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1321 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_tst_sequence_num
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1324 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1326 if (length_remaining
> 0) {
1327 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1328 offset
+= length_remaining
;
1331 proto_item_set_len(ti
, offset
- start_offset
);
1335 static int dissect_cfm_aps(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1339 proto_tree
*cfm_pdu_tree
;
1340 proto_tree
*cfm_flag_tree
;
1341 uint32_t first_tlv_offset
;
1342 int start_offset
= offset
;
1343 int length_remaining
;
1345 ti
= proto_tree_add_item(tree
, hf_cfm_aps_pdu
, tvb
, offset
, -1, ENC_NA
);
1346 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1348 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1349 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1350 proto_tree_add_item(cfm_flag_tree
, hf_cfm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1353 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1356 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_aps_req_st
, tvb
, offset
, 1, ENC_NA
);
1357 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_aps_protection_type_A
, tvb
, offset
, 1, ENC_NA
);
1358 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_aps_protection_type_B
, tvb
, offset
, 1, ENC_NA
);
1359 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_aps_protection_type_D
, tvb
, offset
, 1, ENC_NA
);
1360 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_aps_protection_type_R
, tvb
, offset
, 1, ENC_NA
);
1363 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_aps_requested_signal
, tvb
, offset
, 1, ENC_NA
);
1366 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_aps_bridged_signal
, tvb
, offset
, 1, ENC_NA
);
1369 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_aps_bridge_type
, tvb
, offset
, 1, ENC_NA
);
1372 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1374 if (length_remaining
> 0) {
1375 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1376 offset
+= length_remaining
;
1379 proto_item_set_len(ti
, offset
- start_offset
);
1383 static int dissect_cfm_raps(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1387 proto_tree
*cfm_pdu_tree
;
1388 proto_tree
*cfm_flag_tree
;
1389 uint32_t first_tlv_offset
;
1390 int start_offset
= offset
;
1391 int length_remaining
;
1394 uint32_t raps_requeststate
;
1396 proto_tree
*raps_status_tree
;
1398 ti
= proto_tree_add_item(tree
, hf_cfm_raps_pdu
, tvb
, offset
, -1, ENC_NA
);
1399 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1401 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1402 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1403 proto_tree_add_item(cfm_flag_tree
, hf_cfm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1406 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1409 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_raps_req_st
, tvb
, offset
, 1, ENC_NA
, &raps_requeststate
);
1411 version
= (tvb_get_uint8(tvb
, CFM_LEVEL_VERSION_OFFSET
) & CFM_VERSION_MASK
) >> CFM_VERSION_SHIFT
;
1413 if (version
== 1 && raps_requeststate
== RAPS_REQ_ST_EVENT
) {
1414 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_raps_event_subcode
, tvb
, offset
, 1, ENC_NA
);
1416 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_raps_subcode_reserved
, tvb
, offset
, 1, ENC_NA
);
1421 ri
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_raps_status
, tvb
, offset
, 1, ENC_NA
);
1422 raps_status_tree
= proto_item_add_subtree(ri
, ett_cfm_raps_status
);
1423 proto_tree_add_item(raps_status_tree
, hf_cfm_raps_status_rb
, tvb
, offset
, 1, ENC_NA
);
1424 proto_tree_add_item(raps_status_tree
, hf_cfm_raps_status_dnf
, tvb
, offset
, 1, ENC_NA
);
1426 /* R-APS(G.8032) v2 only */
1428 proto_tree_add_item(raps_status_tree
, hf_cfm_raps_status_bpr
, tvb
, offset
, 1, ENC_NA
);
1429 proto_tree_add_item(raps_status_tree
, hf_cfm_raps_status_reserved_v2
, tvb
, offset
, 1, ENC_NA
);
1431 proto_tree_add_item(raps_status_tree
, hf_cfm_raps_status_reserved_v1
, tvb
, offset
, 1, ENC_NA
);
1436 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_raps_node_id
, tvb
, offset
, 6, ENC_NA
);
1439 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_raps_reserved
, tvb
, offset
, 24, ENC_NA
);
1442 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1444 if (length_remaining
> 0) {
1445 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1446 offset
+= length_remaining
;
1449 proto_item_set_len(ti
, offset
- start_offset
);
1453 static int find_end_tlv(tvbuff_t
*tvb
, int first_tlv_offset
)
1456 * XXX - how to handle TLVs in MCC, EXM, EXR, VSM or VSR PDU data?
1457 * The TLV Offset points to the first TLV, which may part of PDU Data, therefore defined
1458 * 'outside the scope of this standard'. Therefore these cannot be simply handed off the
1459 * standard TLV dissection functions. We do however want to find the End TLV.
1460 * All we can do is iterate over these unknown TLVs, under the assumption they use the
1461 * same format as defined in this standard, until we find the End TLV.
1462 * Don't break dissection if we can't find it this way, e.g. when the captured frame is
1463 * cut short. Then assume all remaining captured frame data is PDU data.
1466 int tlv_tvb_offset
= CFM_COMMON_HEADER_LEN
+ first_tlv_offset
;
1468 // Does a tag exist in the captured data?
1469 if (tvb_bytes_exist(tvb
, tlv_tvb_offset
, 1)) {
1470 // Is this the End TLV
1471 if (tvb_get_uint8(tvb
, tlv_tvb_offset
)) {
1472 // Following the tag, does the length exist in the captured data?
1473 if (tvb_captured_length_remaining(tvb
, tlv_tvb_offset
) < 3) {
1477 // Go to the next tag
1478 tlv_tvb_offset
+= tvb_get_ntohs(tvb
, tlv_tvb_offset
+ 1) + 3;
1480 break; // we found the END_TLV
1488 return tlv_tvb_offset
;
1491 static int dissect_cfm_mcc(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1495 proto_tree
*cfm_pdu_tree
;
1496 proto_tree
*cfm_flag_tree
;
1497 uint32_t first_tlv_offset
;
1498 int start_offset
= offset
;
1501 ti
= proto_tree_add_item(tree
, hf_cfm_mcc_pdu
, tvb
, offset
, -1, ENC_NA
);
1502 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1504 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1505 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1506 proto_tree_add_item(cfm_flag_tree
, hf_cfm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1509 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1512 /* XXX - Introducing a dissector table would allow to register subdissectors based on
1513 * their subopcode, per OUI. The OUI table creation would be similar to the registration
1514 * function in the IEEE 802a dissector.
1517 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_mcc_oui
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
1519 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_mcc_subopcode
, tvb
, offset
, 1, ENC_NA
);
1522 tlv_tvb_offset
= find_end_tlv(tvb
, first_tlv_offset
);
1524 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_mcc_data
, tvb
, offset
, (tlv_tvb_offset
) ? (tlv_tvb_offset
- offset
) : -1, ENC_NA
);
1525 offset
= (tlv_tvb_offset
) ? tlv_tvb_offset
: (int)tvb_captured_length(tvb
);
1527 proto_item_set_len(ti
, offset
- start_offset
);
1531 static int dissect_cfm_lmm(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1535 proto_tree
*cfm_pdu_tree
;
1536 proto_tree
*cfm_flag_tree
;
1537 uint32_t first_tlv_offset
;
1538 int start_offset
= offset
;
1539 int length_remaining
;
1541 ti
= proto_tree_add_item(tree
, hf_cfm_lmm_pdu
, tvb
, offset
, -1, ENC_NA
);
1542 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1544 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1545 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1546 proto_tree_add_item(cfm_flag_tree
, hf_cfm_lmm_lmr_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1547 proto_tree_add_item(cfm_flag_tree
, hf_cfm_lmm_lmr_flags_Type
, tvb
, offset
, 1, ENC_NA
);
1550 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1553 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_lmm_lmr_TxFCf
, tvb
, offset
, 4, ENC_NA
);
1555 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_lmm_lmr_RxFCf
, tvb
, offset
, 4, ENC_NA
);
1557 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_lmm_lmr_TxFCb
, tvb
, offset
, 4, ENC_NA
);
1560 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1562 if (length_remaining
> 0) {
1563 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1564 offset
+= length_remaining
;
1567 proto_item_set_len(ti
, offset
- start_offset
);
1571 static int dissect_cfm_lmr(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1575 proto_tree
*cfm_pdu_tree
;
1576 proto_tree
*cfm_flag_tree
;
1577 uint32_t first_tlv_offset
;
1578 int start_offset
= offset
;
1579 int length_remaining
;
1581 ti
= proto_tree_add_item(tree
, hf_cfm_lmr_pdu
, tvb
, offset
, -1, ENC_NA
);
1582 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1584 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1585 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1586 proto_tree_add_item(cfm_flag_tree
, hf_cfm_lmm_lmr_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1587 proto_tree_add_item(cfm_flag_tree
, hf_cfm_lmm_lmr_flags_Type
, tvb
, offset
, 1, ENC_NA
);
1590 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1593 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_lmm_lmr_TxFCf
, tvb
, offset
, 4, ENC_NA
);
1595 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_lmm_lmr_RxFCf
, tvb
, offset
, 4, ENC_NA
);
1597 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_lmm_lmr_TxFCb
, tvb
, offset
, 4, ENC_NA
);
1600 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1602 if (length_remaining
> 0) {
1603 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1604 offset
+= length_remaining
;
1607 proto_item_set_len(ti
, offset
- start_offset
);
1611 static int dissect_cfm_odm(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1615 proto_tree
*cfm_pdu_tree
;
1616 proto_tree
*cfm_flag_tree
;
1617 uint32_t first_tlv_offset
;
1618 int start_offset
= offset
;
1619 int length_remaining
;
1621 ti
= proto_tree_add_item(tree
, hf_cfm_odm_pdu
, tvb
, offset
, -1, ENC_NA
);
1622 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1624 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1625 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1626 proto_tree_add_item(cfm_flag_tree
, hf_cfm_odm_dmm_dmr_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1627 proto_tree_add_item(cfm_flag_tree
, hf_cfm_odm_dmm_dmr_flags_Type
, tvb
, offset
, 1, ENC_NA
);
1630 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1633 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_odm_dmm_dmr_TxTimestampf
, tvb
, offset
, 8, ENC_TIME_SECS_NSECS
|ENC_BIG_ENDIAN
);
1635 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_odm_dmm_dmr_RxTimestampf
, tvb
, offset
, 8, ENC_TIME_SECS_NSECS
|ENC_BIG_ENDIAN
);
1638 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1640 if (length_remaining
> 0) {
1641 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1642 offset
+= length_remaining
;
1645 proto_item_set_len(ti
, offset
- start_offset
);
1649 static int dissect_cfm_dmm(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1653 proto_tree
*cfm_pdu_tree
;
1654 proto_tree
*cfm_flag_tree
;
1655 uint32_t first_tlv_offset
;
1656 int start_offset
= offset
;
1657 int length_remaining
;
1659 ti
= proto_tree_add_item(tree
, hf_cfm_dmm_pdu
, tvb
, offset
, -1, ENC_NA
);
1660 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1662 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1663 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1664 proto_tree_add_item(cfm_flag_tree
, hf_cfm_odm_dmm_dmr_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1665 proto_tree_add_item(cfm_flag_tree
, hf_cfm_odm_dmm_dmr_flags_Type
, tvb
, offset
, 1, ENC_NA
);
1668 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1671 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_odm_dmm_dmr_TxTimestampf
, tvb
, offset
, 8, ENC_TIME_SECS_NSECS
|ENC_BIG_ENDIAN
);
1673 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_odm_dmm_dmr_RxTimestampf
, tvb
, offset
, 8, ENC_TIME_SECS_NSECS
|ENC_BIG_ENDIAN
);
1675 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_dmm_dmr_TxTimestampb
, tvb
, offset
, 8, ENC_TIME_SECS_NSECS
|ENC_BIG_ENDIAN
);
1677 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_dmm_dmr_RxTimestampb
, tvb
, offset
, 8, ENC_TIME_SECS_NSECS
|ENC_BIG_ENDIAN
);
1680 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1682 if (length_remaining
> 0) {
1683 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1684 offset
+= length_remaining
;
1687 proto_item_set_len(ti
, offset
- start_offset
);
1691 static int dissect_cfm_dmr(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1695 proto_tree
*cfm_pdu_tree
;
1696 proto_tree
*cfm_flag_tree
;
1697 uint32_t first_tlv_offset
;
1698 int start_offset
= offset
;
1699 int length_remaining
;
1701 ti
= proto_tree_add_item(tree
, hf_cfm_dmr_pdu
, tvb
, offset
, -1, ENC_NA
);
1702 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1704 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1705 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1706 proto_tree_add_item(cfm_flag_tree
, hf_cfm_odm_dmm_dmr_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1707 proto_tree_add_item(cfm_flag_tree
, hf_cfm_odm_dmm_dmr_flags_Type
, tvb
, offset
, 1, ENC_NA
);
1710 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1713 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_odm_dmm_dmr_TxTimestampf
, tvb
, offset
, 8, ENC_TIME_SECS_NSECS
|ENC_BIG_ENDIAN
);
1715 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_odm_dmm_dmr_RxTimestampf
, tvb
, offset
, 8, ENC_TIME_SECS_NSECS
|ENC_BIG_ENDIAN
);
1717 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_dmm_dmr_TxTimestampb
, tvb
, offset
, 8, ENC_TIME_SECS_NSECS
|ENC_BIG_ENDIAN
);
1719 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_dmm_dmr_RxTimestampb
, tvb
, offset
, 8, ENC_TIME_SECS_NSECS
|ENC_BIG_ENDIAN
);
1722 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1724 if (length_remaining
> 0) {
1725 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1726 offset
+= length_remaining
;
1729 proto_item_set_len(ti
, offset
- start_offset
);
1733 static int dissect_cfm_exm(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1737 proto_tree
*cfm_pdu_tree
;
1738 proto_tree
*cfm_flag_tree
;
1739 uint32_t first_tlv_offset
;
1740 int start_offset
= offset
;
1743 ti
= proto_tree_add_item(tree
, hf_cfm_exm_pdu
, tvb
, offset
, -1, ENC_NA
);
1744 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1746 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1747 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1748 proto_tree_add_item(cfm_flag_tree
, hf_cfm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1751 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1754 /* XXX - Introducing a dissector table would allow to register subdissectors based on
1755 * their subopcode, per OUI. The OUI table creation would be similar to the registration
1756 * function in the IEEE 802a dissector.
1759 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_exm_oui
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
1761 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_exm_subopcode
, tvb
, offset
, 1, ENC_NA
);
1764 tlv_tvb_offset
= find_end_tlv(tvb
, first_tlv_offset
);
1766 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_exm_data
, tvb
, offset
, (tlv_tvb_offset
) ? (tlv_tvb_offset
- offset
) : -1, ENC_NA
);
1767 offset
= (tlv_tvb_offset
) ? tlv_tvb_offset
: (int)tvb_captured_length(tvb
);
1769 proto_item_set_len(ti
, offset
- start_offset
);
1773 static int dissect_cfm_exr(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1777 proto_tree
*cfm_pdu_tree
;
1778 proto_tree
*cfm_flag_tree
;
1779 uint32_t first_tlv_offset
;
1780 int start_offset
= offset
;
1783 ti
= proto_tree_add_item(tree
, hf_cfm_exr_pdu
, tvb
, offset
, -1, ENC_NA
);
1784 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1786 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1787 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1788 proto_tree_add_item(cfm_flag_tree
, hf_cfm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1791 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1794 /* XXX - Introducing a dissector table would allow to register subdissectors based on
1795 * their subopcode, per OUI. The OUI table creation would be similar to the registration
1796 * function in the IEEE 802a dissector.
1799 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_exr_oui
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
1801 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_exr_subopcode
, tvb
, offset
, 1, ENC_NA
);
1804 tlv_tvb_offset
= find_end_tlv(tvb
, first_tlv_offset
);
1806 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_exr_data
, tvb
, offset
, (tlv_tvb_offset
) ? (tlv_tvb_offset
- offset
) : -1, ENC_NA
);
1807 offset
= (tlv_tvb_offset
) ? tlv_tvb_offset
: (int)tvb_captured_length(tvb
);
1809 proto_item_set_len(ti
, offset
- start_offset
);
1813 static int dissect_cfm_vsm(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1817 proto_tree
*cfm_pdu_tree
;
1818 proto_tree
*cfm_flag_tree
;
1819 uint32_t first_tlv_offset
;
1820 int start_offset
= offset
;
1823 ti
= proto_tree_add_item(tree
, hf_cfm_vsm_pdu
, tvb
, offset
, -1, ENC_NA
);
1824 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1826 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1827 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1828 proto_tree_add_item(cfm_flag_tree
, hf_cfm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1831 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1834 /* XXX - Introducing a dissector table would allow to register subdissectors based on
1835 * their subopcode, per OUI. The OUI table creation would be similar to the registration
1836 * function in the IEEE 802a dissector.
1839 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_vsm_oui
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
1841 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_vsm_subopcode
, tvb
, offset
, 1, ENC_NA
);
1844 tlv_tvb_offset
= find_end_tlv(tvb
, first_tlv_offset
);
1846 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_vsm_data
, tvb
, offset
, (tlv_tvb_offset
) ? (tlv_tvb_offset
- offset
) : -1, ENC_NA
);
1847 offset
= (tlv_tvb_offset
) ? tlv_tvb_offset
: (int)tvb_captured_length(tvb
);
1849 proto_item_set_len(ti
, offset
- start_offset
);
1853 static int dissect_cfm_vsr(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1857 proto_tree
*cfm_pdu_tree
;
1858 proto_tree
*cfm_flag_tree
;
1859 uint32_t first_tlv_offset
;
1860 int start_offset
= offset
;
1863 ti
= proto_tree_add_item(tree
, hf_cfm_vsr_pdu
, tvb
, offset
, -1, ENC_NA
);
1864 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1866 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1867 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1868 proto_tree_add_item(cfm_flag_tree
, hf_cfm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1871 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1874 /* XXX - Introducing a dissector table would allow to register subdissectors based on
1875 * their subopcode, per OUI. The OUI table creation would be similar to the registration
1876 * function in the IEEE 802a dissector.
1879 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_vsr_oui
, tvb
, offset
, 3, ENC_BIG_ENDIAN
);
1881 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_vsr_subopcode
, tvb
, offset
, 1, ENC_NA
);
1884 tlv_tvb_offset
= find_end_tlv(tvb
, first_tlv_offset
);
1886 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_vsr_data
, tvb
, offset
, (tlv_tvb_offset
) ? (tlv_tvb_offset
- offset
) : -1, ENC_NA
);
1887 offset
= (tlv_tvb_offset
) ? tlv_tvb_offset
: (int)tvb_captured_length(tvb
);
1889 proto_item_set_len(ti
, offset
- start_offset
);
1893 static int dissect_cfm_csf(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1897 proto_tree
*cfm_pdu_tree
;
1898 proto_tree
*cfm_flag_tree
;
1899 uint32_t first_tlv_offset
;
1900 int start_offset
= offset
;
1901 int length_remaining
;
1903 ti
= proto_tree_add_item(tree
, hf_cfm_csf_pdu
, tvb
, offset
, -1, ENC_NA
);
1904 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1906 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1907 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1908 proto_tree_add_item(cfm_flag_tree
, hf_cfm_csf_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1909 proto_tree_add_item(cfm_flag_tree
, hf_cfm_csf_flags_Type
, tvb
, offset
, 1, ENC_NA
);
1910 proto_tree_add_item(cfm_flag_tree
, hf_cfm_csf_flags_Period
, tvb
, offset
, 1, ENC_NA
);
1913 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1916 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1918 if (length_remaining
> 0) {
1919 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1920 offset
+= length_remaining
;
1923 proto_item_set_len(ti
, offset
- start_offset
);
1927 static int dissect_cfm_osl(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1931 proto_tree
*cfm_pdu_tree
;
1932 proto_tree
*cfm_flag_tree
;
1933 uint32_t first_tlv_offset
;
1934 int start_offset
= offset
;
1935 int length_remaining
;
1937 ti
= proto_tree_add_item(tree
, hf_cfm_osl_pdu
, tvb
, offset
, -1, ENC_NA
);
1938 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1940 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1941 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1942 proto_tree_add_item(cfm_flag_tree
, hf_cfm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1945 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1948 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_osl_src_mep
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1950 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_osl_reserved
, tvb
, offset
, 2, ENC_NA
);
1952 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_osl_testid
, tvb
, offset
, 4, ENC_NA
);
1954 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_osl_txfcf
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1956 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_osl_reserved
, tvb
, offset
, 4, ENC_NA
);
1959 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
1961 if (length_remaining
> 0) {
1962 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
1963 offset
+= length_remaining
;
1966 proto_item_set_len(ti
, offset
- start_offset
);
1970 static int dissect_cfm_slm(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
1974 proto_tree
*cfm_pdu_tree
;
1975 proto_tree
*cfm_flag_tree
;
1976 uint32_t first_tlv_offset
;
1977 int start_offset
= offset
;
1978 int length_remaining
;
1980 ti
= proto_tree_add_item(tree
, hf_cfm_slm_pdu
, tvb
, offset
, -1, ENC_NA
);
1981 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
1983 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
1984 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
1985 proto_tree_add_item(cfm_flag_tree
, hf_cfm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
1988 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
1991 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_slm_slr_src_mep
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1993 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_slm_reserved
, tvb
, offset
, 2, ENC_NA
);
1995 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_slm_slr_testid
, tvb
, offset
, 4, ENC_NA
);
1997 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_slm_slr_txfcf
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1999 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_slm_reserved
, tvb
, offset
, 4, ENC_NA
);
2002 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
2004 if (length_remaining
> 0) {
2005 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
2006 offset
+= length_remaining
;
2009 proto_item_set_len(ti
, offset
- start_offset
);
2013 static int dissect_cfm_slr(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
2017 proto_tree
*cfm_pdu_tree
;
2018 proto_tree
*cfm_flag_tree
;
2019 uint32_t first_tlv_offset
;
2020 int start_offset
= offset
;
2021 int length_remaining
;
2023 ti
= proto_tree_add_item(tree
, hf_cfm_slr_pdu
, tvb
, offset
, -1, ENC_NA
);
2024 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
2026 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
2027 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
2028 proto_tree_add_item(cfm_flag_tree
, hf_cfm_flags_Reserved
, tvb
, offset
, 1, ENC_NA
);
2031 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
2034 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_slm_slr_src_mep
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2036 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_slr_rsp_mep
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2038 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_slm_slr_testid
, tvb
, offset
, 4, ENC_NA
);
2040 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_slm_slr_txfcf
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2042 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_slr_txfcb
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2045 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
2047 if (length_remaining
> 0) {
2048 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
2049 offset
+= length_remaining
;
2052 proto_item_set_len(ti
, offset
- start_offset
);
2056 static int dissect_cfm_unknown(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, int offset
)
2060 proto_tree
*cfm_pdu_tree
;
2061 proto_tree
*cfm_flag_tree
;
2062 uint32_t first_tlv_offset
;
2063 int start_offset
= offset
;
2064 int length_remaining
;
2066 ti
= proto_tree_add_item(tree
, hf_cfm_unknown_pdu
, tvb
, offset
, -1, ENC_NA
);
2067 cfm_pdu_tree
= proto_item_add_subtree(ti
, ett_cfm_pdu
);
2069 fi
= proto_tree_add_item(cfm_pdu_tree
, hf_cfm_flags
, tvb
, offset
, 1, ENC_NA
);
2070 cfm_flag_tree
= proto_item_add_subtree(fi
, ett_cfm_flags
);
2071 proto_tree_add_item(cfm_flag_tree
, hf_cfm_unknown_flags
, tvb
, offset
, 1, ENC_NA
);
2074 proto_tree_add_item_ret_uint(cfm_pdu_tree
, hf_cfm_first_tlv_offset
, tvb
, offset
, 1, ENC_NA
, &first_tlv_offset
);
2077 length_remaining
= first_tlv_offset
- (offset
- (start_offset
+ 2));
2079 if (length_remaining
> 0) {
2080 proto_tree_add_item(cfm_pdu_tree
, hf_cfm_unknown_data
, tvb
, offset
, length_remaining
, ENC_NA
);
2081 offset
+= length_remaining
;
2084 proto_item_set_len(ti
, offset
- start_offset
);
2088 /* Inspired by packet-lldp.c:dissect_lldp_chassis_id() */
2089 static int sender_id_tlv_chassis_id(proto_tree
*cfm_tlv_tree
, tvbuff_t
*tvb
, int tlv_data_offset
, uint8_t tlv_chassis_id_length
)
2091 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_chassis_id_subtype
, tvb
, tlv_data_offset
, 1, ENC_NA
);
2092 uint8_t chassis_id_subtype
= tvb_get_uint8(tvb
, tlv_data_offset
);
2093 tlv_data_offset
+= 1;
2094 tlv_chassis_id_length
-= 1;
2096 switch (chassis_id_subtype
) {
2098 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_chassis_id_chassis_component
, tvb
, tlv_data_offset
, tlv_chassis_id_length
, ENC_UTF_8
);
2101 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_chassis_id_interface_alias
, tvb
, tlv_data_offset
, tlv_chassis_id_length
, ENC_UTF_8
);
2104 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_chassis_id_port_component
, tvb
, tlv_data_offset
, tlv_chassis_id_length
, ENC_NA
);
2107 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_chassis_id_mac_address
, tvb
, tlv_data_offset
, tlv_chassis_id_length
, ENC_NA
);
2110 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_chassis_id_network_address_family
, tvb
, tlv_data_offset
, 1, ENC_NA
);
2112 switch (tvb_get_uint8(tvb
, tlv_data_offset
)) {
2114 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_chassis_id_network_address_ipv4
, tvb
, tlv_data_offset
+1, tlv_chassis_id_length
-1, ENC_BIG_ENDIAN
);
2117 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_chassis_id_network_address_ipv6
, tvb
, tlv_data_offset
+1, tlv_chassis_id_length
-1, ENC_NA
);
2120 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_chassis_id_network_address_unknown
, tvb
, tlv_data_offset
+1, tlv_chassis_id_length
-1, ENC_NA
);
2125 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_chassis_id_interface_name
, tvb
, tlv_data_offset
, tlv_chassis_id_length
, ENC_UTF_8
);
2128 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_chassis_id_locally_assigned
, tvb
, tlv_data_offset
, tlv_chassis_id_length
, ENC_UTF_8
);
2131 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_chassis_id_unknown
, tvb
, tlv_data_offset
, tlv_chassis_id_length
, ENC_NA
);
2135 tlv_data_offset
+= tlv_chassis_id_length
;
2137 return tlv_data_offset
;
2140 static int sender_id_tlv_management_address(proto_tree
*cfm_tlv_tree
, tvbuff_t
*tvb
, void *tlv_ma_domain_oid
, uint8_t tlv_ma_domain_length
, int tlv_data_offset
, uint8_t tlv_management_addr_length
)
2143 const uint8_t *oid
; // BER encoded
2144 const size_t oid_length
;
2145 const int *header_field
;
2147 } management_address_type
[] = {
2148 // transportDomainUdpIpv4 : 1.3.6.1.2.1.100.1.1
2149 { (const uint8_t[]){ 0x2B, 0x06, 0x01, 0x02, 0x01, 0x64, 0x01, 0x01 }, 8, &hf_tlv_management_addr_ipv4
, ENC_BIG_ENDIAN
},
2150 // transportDomainUdpIpv6 : 1.3.6.1.2.1.100.1.2
2151 { (const uint8_t[]){ 0x2B, 0x06, 0x01, 0x02, 0x01, 0x64, 0x01, 0x02 }, 8, &hf_tlv_management_addr_ipv6
, ENC_NA
},
2152 // transportDomainTcpIpv4 : 1.3.6.1.2.1.100.1.5
2153 { (const uint8_t[]){ 0x2B, 0x06, 0x01, 0x02, 0x01, 0x64, 0x01, 0x05 }, 8, &hf_tlv_management_addr_ipv4
, ENC_BIG_ENDIAN
},
2154 // transportDomainTcpIpv6 : 1.3.6.1.2.1.100.1.6
2155 { (const uint8_t[]){ 0x2B, 0x06, 0x01, 0x02, 0x01, 0x64, 0x01, 0x06 }, 8, &hf_tlv_management_addr_ipv6
, ENC_NA
},
2156 // transportDomainSctpIpv4 : 1.3.6.1.2.1.100.1.9
2157 { (const uint8_t[]){ 0x2B, 0x06, 0x01, 0x02, 0x01, 0x64, 0x01, 0x09 }, 8, &hf_tlv_management_addr_ipv4
, ENC_BIG_ENDIAN
},
2158 // transportDomainSctpIpv6 : 1.3.6.1.2.1.100.1.10
2159 { (const uint8_t[]){ 0x2B, 0x06, 0x01, 0x02, 0x01, 0x64, 0x01, 0x0A }, 8, &hf_tlv_management_addr_ipv6
, ENC_NA
},
2160 // snmpIeee802Domain : 1.3.6.1.6.1.6
2161 { (const uint8_t[]){ 0x2B, 0x06, 0x01, 0x06, 0x01, 0x06 }, 6, &hf_tlv_management_addr_eth
, ENC_NA
},
2163 { NULL
, 0, NULL
, ENC_NA
}
2166 for (size_t i
= 0; i
< array_length(management_address_type
); i
++) {
2167 if (management_address_type
[i
].oid
== NULL
) {
2168 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_management_addr_unknown
,
2169 tvb
, tlv_data_offset
, tlv_management_addr_length
, ENC_NA
);
2172 if (tlv_ma_domain_length
== management_address_type
[i
].oid_length
) {
2173 if (!(memcmp(tlv_ma_domain_oid
, management_address_type
[i
].oid
, tlv_ma_domain_length
))) {
2174 proto_tree_add_item(cfm_tlv_tree
, *management_address_type
[i
].header_field
,
2175 tvb
, tlv_data_offset
, tlv_management_addr_length
, management_address_type
[i
].encoding
);
2181 tlv_data_offset
+= tlv_management_addr_length
;
2183 return tlv_data_offset
;
2186 /* Inspired by packet-lldp.c:dissect_lldp_port_id() */
2187 static int reply_ing_egr_tlv_port_id(proto_tree
*cfm_tlv_tree
, tvbuff_t
*tvb
, int tlv_data_offset
, uint8_t tlv_reply_ingress_portid_length
)
2189 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_ing_egr_portid_subtype
,
2190 tvb
, tlv_data_offset
, 1, ENC_NA
);
2191 uint8_t port_id_subtype
= tvb_get_uint8(tvb
, tlv_data_offset
);
2192 tlv_data_offset
+= 1;
2193 tlv_reply_ingress_portid_length
-= 1;
2195 switch (port_id_subtype
) {
2197 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_ing_egr_portid_interface_alias
, tvb
, tlv_data_offset
, tlv_reply_ingress_portid_length
, ENC_UTF_8
);
2200 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_ing_egr_portid_port_component
, tvb
, tlv_data_offset
, tlv_reply_ingress_portid_length
, ENC_NA
);
2203 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_ing_egr_portid_mac_address
, tvb
, tlv_data_offset
, tlv_reply_ingress_portid_length
, ENC_NA
);
2206 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_ing_egr_portid_network_address_family
, tvb
, tlv_data_offset
, 1, ENC_NA
);
2208 switch (tvb_get_uint8(tvb
, tlv_data_offset
)) {
2210 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_ing_egr_portid_network_address_ipv4
, tvb
, tlv_data_offset
+1, tlv_reply_ingress_portid_length
-1, ENC_BIG_ENDIAN
);
2213 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_ing_egr_portid_network_address_ipv6
, tvb
, tlv_data_offset
+1, tlv_reply_ingress_portid_length
-1, ENC_NA
);
2216 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_ing_egr_portid_network_address_unknown
, tvb
, tlv_data_offset
+1, tlv_reply_ingress_portid_length
-1, ENC_NA
);
2221 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_ing_egr_portid_interface_name
, tvb
, tlv_data_offset
, tlv_reply_ingress_portid_length
, ENC_UTF_8
);
2224 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_ing_egr_portid_agent_circuit_id
, tvb
, tlv_data_offset
, tlv_reply_ingress_portid_length
, ENC_NA
);
2227 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_ing_egr_portid_locally_assigned
, tvb
, tlv_data_offset
, tlv_reply_ingress_portid_length
, ENC_UTF_8
);
2230 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_ing_egr_portid_unknown
, tvb
, tlv_data_offset
, tlv_reply_ingress_portid_length
, ENC_NA
);
2234 tlv_data_offset
+= tlv_reply_ingress_portid_length
;
2236 return tlv_data_offset
;
2239 /* Main CFM EOAM protocol dissector */
2240 static int dissect_cfm(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
2243 uint8_t cfm_pdu_type
;
2245 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CFM");
2246 col_clear(pinfo
->cinfo
, COL_INFO
);
2248 cfm_pdu_type
= tvb_get_uint8(tvb
, CFM_OPCODE_OFFSET
);
2249 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Type %s",
2250 val_to_str(cfm_pdu_type
, opcode_type_name_vals
, "Unknown (0x%02x)"));
2253 proto_tree
*cfm_tree
;
2255 /* isolate the payload of the packet */
2256 ti
= proto_tree_add_item(tree
, proto_cfm
, tvb
, 0, -1, ENC_NA
);
2258 /* report type of CFM packet to base of dissection tree */
2259 proto_item_append_text(ti
, ", Type %s",
2260 val_to_str(cfm_pdu_type
, opcode_type_name_vals
, "Unknown (0x%02x)"));
2262 /* dissecting the common CFM header */
2263 cfm_tree
= proto_item_add_subtree(ti
, ett_cfm
);
2264 proto_tree_add_item(cfm_tree
, hf_cfm_md_level
, tvb
, offset
, 1, ENC_NA
);
2265 proto_tree_add_item(cfm_tree
, hf_cfm_version
, tvb
, offset
, 1, ENC_NA
);
2267 proto_tree_add_item(cfm_tree
, hf_cfm_opcode
, tvb
, offset
, 1, ENC_NA
);
2270 switch (cfm_pdu_type
) {
2272 offset
= dissect_cfm_ccm(tvb
, pinfo
, cfm_tree
, offset
);
2275 offset
= dissect_cfm_lbm(tvb
, pinfo
, cfm_tree
, offset
);
2278 offset
= dissect_cfm_lbr(tvb
, pinfo
, cfm_tree
, offset
);
2281 offset
= dissect_cfm_ltm(tvb
, pinfo
, cfm_tree
, offset
);
2284 offset
= dissect_cfm_ltr(tvb
, pinfo
, cfm_tree
, offset
);
2287 offset
= dissect_cfm_rfm(tvb
, pinfo
, cfm_tree
, offset
);
2290 offset
= dissect_cfm_sfm(tvb
, pinfo
, cfm_tree
, offset
);
2293 offset
= dissect_cfm_gnm(tvb
, pinfo
, cfm_tree
, offset
);
2296 offset
= dissect_cfm_ais(tvb
, pinfo
, cfm_tree
, offset
);
2299 offset
= dissect_cfm_lck(tvb
, pinfo
, cfm_tree
, offset
);
2302 offset
= dissect_cfm_tst(tvb
, pinfo
, cfm_tree
, offset
);
2305 offset
= dissect_cfm_aps(tvb
, pinfo
, cfm_tree
, offset
);
2308 offset
= dissect_cfm_raps(tvb
, pinfo
, cfm_tree
, offset
);
2311 offset
= dissect_cfm_mcc(tvb
, pinfo
, cfm_tree
, offset
);
2314 offset
= dissect_cfm_lmm(tvb
, pinfo
, cfm_tree
, offset
);
2317 offset
= dissect_cfm_lmr(tvb
, pinfo
, cfm_tree
, offset
);
2320 offset
= dissect_cfm_odm(tvb
, pinfo
, cfm_tree
, offset
);
2323 offset
= dissect_cfm_dmm(tvb
, pinfo
, cfm_tree
, offset
);
2326 offset
= dissect_cfm_dmr(tvb
, pinfo
, cfm_tree
, offset
);
2329 offset
= dissect_cfm_exm(tvb
, pinfo
, cfm_tree
, offset
);
2332 offset
= dissect_cfm_exr(tvb
, pinfo
, cfm_tree
, offset
);
2335 offset
= dissect_cfm_vsm(tvb
, pinfo
, cfm_tree
, offset
);
2338 offset
= dissect_cfm_vsr(tvb
, pinfo
, cfm_tree
, offset
);
2341 offset
= dissect_cfm_csf(tvb
, pinfo
, cfm_tree
, offset
);
2344 offset
= dissect_cfm_osl(tvb
, pinfo
, cfm_tree
, offset
);
2347 offset
= dissect_cfm_slm(tvb
, pinfo
, cfm_tree
, offset
);
2350 offset
= dissect_cfm_slr(tvb
, pinfo
, cfm_tree
, offset
);
2353 offset
= dissect_cfm_unknown(tvb
, pinfo
, cfm_tree
, offset
);
2357 /* Get the First TLV offset and add the offset of the common CFM header*/
2358 int cfm_first_tlv_offset
= tvb_get_uint8(tvb
, CFM_1ST_TLV_OFFSET
) + CFM_COMMON_HEADER_LEN
;
2360 /* The TLV offset should be the same as where the PDU left off or we have a problem */
2361 if (cfm_first_tlv_offset
!= offset
) {
2362 // TODO: Report error, recover and continue
2363 cfm_first_tlv_offset
= offset
;
2366 /* Begin dissecting the TLV's */
2367 proto_item
*cfm_all_tlvs_ti
;
2368 proto_tree
*cfm_all_tlvs_tree
;
2369 cfm_all_tlvs_ti
= proto_tree_add_item(cfm_tree
, hf_cfm_all_tlvs
, tvb
, cfm_first_tlv_offset
, -1, ENC_NA
);
2370 cfm_all_tlvs_tree
= proto_item_add_subtree(cfm_all_tlvs_ti
, ett_cfm_all_tlvs
);
2372 int cfm_tlv_offset
= cfm_first_tlv_offset
;
2376 uint8_t cfm_tlv_type
;
2377 uint16_t cfm_tlv_length
;
2378 proto_tree
*cfm_tlv_tree
;
2379 proto_item
*cfm_tlv_ti
, *expert_ti
;
2380 int tlv_data_offset
;
2381 bool test_id_length_bogus
= false;
2383 cfm_tlv_type
= tvb_get_uint8(tvb
, cfm_tlv_offset
);
2385 if (cfm_tlv_type
== END_TLV
) {
2386 cfm_tlv_tree
= proto_tree_add_subtree_format(cfm_all_tlvs_tree
, tvb
, cfm_tlv_offset
, 1,
2387 ett_cfm_tlv
, NULL
, "TLV: End TLV (t=0,l=0)");
2388 proto_tree_add_item(cfm_tlv_tree
, hf_cfm_tlv_type
, tvb
, cfm_tlv_offset
, 1, ENC_NA
);
2389 cfm_tlv_offset
+= 1;
2393 cfm_tlv_length
= tvb_get_ntohs(tvb
, cfm_tlv_offset
+1);
2394 if (cfm_tlv_type
== TEST_ID_TLV
&& cfm_tlv_length
== 32) {
2395 /* ITU-T G.8013/Y.1731 9.14.2 indicates that the
2396 * Length of the Test ID TLV "must be 32" (indicating
2397 * the bit length?) even though the Value is 4 octets,
2398 * contradicting IEEE 802.1Q 21.5 TLV format:
2399 * "The 16 bits of the Length field indicate the size,
2400 * in octets, of the Value field."
2403 test_id_length_bogus
= true;
2406 cfm_tlv_tree
= proto_tree_add_subtree_format(cfm_all_tlvs_tree
, tvb
, cfm_tlv_offset
, cfm_tlv_length
+3,
2407 ett_cfm_tlv
, NULL
, "TLV: %s (t=%d,l=%d)", val_to_str(cfm_tlv_type
, tlv_type_field_vals
, "Unknown (0x%02x)"),
2408 cfm_tlv_type
, cfm_tlv_length
);
2410 proto_tree_add_item(cfm_tlv_tree
, hf_cfm_tlv_type
, tvb
, cfm_tlv_offset
, 1, ENC_NA
);
2411 cfm_tlv_offset
+= 1;
2413 cfm_tlv_ti
= proto_tree_add_item(cfm_tlv_tree
, hf_cfm_tlv_length
, tvb
, cfm_tlv_offset
, 2, ENC_BIG_ENDIAN
);
2414 if (test_id_length_bogus
) {
2415 expert_add_info(pinfo
, cfm_tlv_ti
, &ei_tlv_tst_id_length
);
2417 cfm_tlv_offset
+= 2;
2419 if (cfm_tlv_length
== 0)
2422 tlv_data_offset
= cfm_tlv_offset
;
2424 switch(cfm_tlv_type
) {
2427 uint8_t tlv_chassis_id_length
;
2429 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_chassis_id_length
,
2430 tvb
, tlv_data_offset
, 1, ENC_NA
);
2431 tlv_chassis_id_length
= tvb_get_uint8(tvb
,tlv_data_offset
);
2432 tlv_data_offset
+= 1;
2434 if (tlv_chassis_id_length
> 0) {
2435 tlv_data_offset
= sender_id_tlv_chassis_id(cfm_tlv_tree
, tvb
, tlv_data_offset
, tlv_chassis_id_length
);
2438 /* IEEE 802.1Q 21.5.3.2 If the Chassis ID Length field
2439 * is 0, then the Chassis ID Subtype is not present.
2441 uint16_t chassis_id_tot_length
= tlv_chassis_id_length
? 2 + tlv_chassis_id_length
: 1;
2442 /* If the TLV length is greater than the number of octets used for the
2443 * Chassis ID, then we must have a Management Address Domain
2445 if (cfm_tlv_length
> chassis_id_tot_length
) {
2446 uint8_t tlv_ma_domain_length
;
2447 void *tlv_ma_domain_oid
= NULL
;
2448 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_ma_domain_length
,
2449 tvb
, tlv_data_offset
, 1, ENC_NA
);
2450 tlv_ma_domain_length
= tvb_get_uint8(tvb
, tlv_data_offset
);
2451 tlv_data_offset
+= 1;
2452 if (tlv_ma_domain_length
> 0) {
2453 // Ref ITU-T X690-2002 for OID. RFC 2579 for TDomain.
2454 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_ma_domain
,
2455 tvb
, tlv_data_offset
, tlv_ma_domain_length
, ENC_NA
);
2456 tlv_ma_domain_oid
= tvb_memdup(pinfo
->pool
, tvb
, tlv_data_offset
, tlv_ma_domain_length
);
2457 tlv_data_offset
+= tlv_ma_domain_length
;
2460 /* If the TLV length is greater than the number of octets used for the
2461 * Chassis ID and the Management Address Domain, then we must have a
2462 * Management Address
2464 if (cfm_tlv_length
> (chassis_id_tot_length
+ 1 + tlv_ma_domain_length
)) {
2465 uint8_t tlv_management_addr_length
;
2466 expert_ti
= proto_tree_add_item(cfm_tlv_tree
, hf_tlv_management_addr_length
,
2467 tvb
, tlv_data_offset
, 1, ENC_NA
);
2468 /* IEEE 802.1Q 21.5.3.6 "[Management Address Length] is not
2469 * present if the Management Address Domain Length is not
2470 * present or contains a 0."
2472 if (tlv_ma_domain_length
== 0) {
2473 expert_add_info(pinfo
, expert_ti
, &ei_tlv_management_addr_length
);
2475 tlv_management_addr_length
= tvb_get_uint8(tvb
, tlv_data_offset
);
2476 tlv_data_offset
+= 1;
2477 if (tlv_management_addr_length
> 0) {
2478 tlv_data_offset
= sender_id_tlv_management_address(cfm_tlv_tree
, tvb
, tlv_ma_domain_oid
,
2479 tlv_ma_domain_length
, tlv_data_offset
,
2480 tlv_management_addr_length
);
2487 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_port_status_value
,
2488 tvb
, tlv_data_offset
, 1, ENC_NA
);
2489 tlv_data_offset
+= 1;
2492 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_data_value
,
2493 tvb
, tlv_data_offset
, cfm_tlv_length
, ENC_NA
);
2494 tlv_data_offset
+= cfm_tlv_length
;
2496 case INTERF_STAT_TLV
:
2497 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_interface_status_value
,
2498 tvb
, tlv_data_offset
, 1, ENC_NA
);
2499 tlv_data_offset
+= 1;
2502 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_ingress_action
,
2503 tvb
, tlv_data_offset
, 1, ENC_NA
);
2504 tlv_data_offset
+= 1;
2505 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_ingress_mac_address
,
2506 tvb
, tlv_data_offset
, 6, ENC_NA
);
2507 tlv_data_offset
+= 6;
2509 /* For the IEEE standard if the TLV length is greater than 7 then we have an ingress port ID */
2510 if (cfm_tlv_length
> 7) {
2511 uint8_t tlv_reply_ingress_portid_length
;
2512 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_ing_egr_portid_length
,
2513 tvb
, tlv_data_offset
, 1, ENC_NA
);
2514 tlv_reply_ingress_portid_length
= tvb_get_uint8(tvb
,tlv_data_offset
);
2515 tlv_data_offset
+= 1;
2517 if (tlv_reply_ingress_portid_length
> 0) {
2518 tlv_data_offset
= reply_ing_egr_tlv_port_id(cfm_tlv_tree
, tvb
, tlv_data_offset
, tlv_reply_ingress_portid_length
);
2520 // TODO: Report error, cannot be zero.
2525 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_egress_action
,
2526 tvb
, tlv_data_offset
, 1, ENC_NA
);
2527 tlv_data_offset
+= 1;
2528 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_egress_mac_address
,
2529 tvb
, tlv_data_offset
, 6, ENC_NA
);
2530 tlv_data_offset
+= 6;
2532 /* For the IEEE standard if the TLV length is greater than 7 then we have an egress port ID */
2533 if (cfm_tlv_length
> 7) {
2534 uint8_t tlv_reply_egress_portid_length
;
2535 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_reply_ing_egr_portid_length
,
2536 tvb
, tlv_data_offset
, 1, ENC_NA
);
2537 tlv_reply_egress_portid_length
= tvb_get_uint8(tvb
,tlv_data_offset
);
2538 tlv_data_offset
+= 1;
2540 if (tlv_reply_egress_portid_length
> 0) {
2541 tlv_data_offset
= reply_ing_egr_tlv_port_id(cfm_tlv_tree
, tvb
, tlv_data_offset
, tlv_reply_egress_portid_length
);
2543 // TODO: Report error, cannot be zero.
2547 case LTM_EGR_ID_TLV
:
2548 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_ltm_egress_id_unique_identifier
,
2549 tvb
, tlv_data_offset
, 2, ENC_NA
);
2550 tlv_data_offset
+= 2;
2551 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_ltm_egress_id_mac
,
2552 tvb
, tlv_data_offset
, 6, ENC_NA
);
2553 tlv_data_offset
+= 6;
2555 case LTR_EGR_ID_TLV
:
2556 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_ltr_egress_last_id_unique_identifier
,
2557 tvb
, tlv_data_offset
, 2, ENC_NA
);
2558 tlv_data_offset
+= 2;
2559 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_ltr_egress_last_id_mac
,
2560 tvb
, tlv_data_offset
, 6, ENC_NA
);
2561 tlv_data_offset
+= 6;
2562 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_ltr_egress_next_id_unique_identifier
,
2563 tvb
, tlv_data_offset
, 2, ENC_NA
);
2564 tlv_data_offset
+= 2;
2565 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_ltr_egress_next_id_mac
,
2566 tvb
, tlv_data_offset
, 6, ENC_NA
);
2567 tlv_data_offset
+= 6;
2569 case PPB_TE_MIP_TLV
:
2570 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_pbb_te_mip_mac_address
,
2571 tvb
, tlv_data_offset
, 6, ENC_NA
);
2572 tlv_data_offset
+= 6;
2573 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_pbb_te_reverse_vid
,
2574 tvb
, tlv_data_offset
, 2, ENC_BIG_ENDIAN
);
2575 tlv_data_offset
+= 2;
2576 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_pbb_te_reverse_mac
,
2577 tvb
, tlv_data_offset
, 6, ENC_NA
);
2578 tlv_data_offset
+= 6;
2580 case DATA_PART1_TLV
:
2581 case TRUNC_DATA_TLV
:
2582 // TODO: hand off to ethertype dissector
2583 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_data_value
,
2584 tvb
, tlv_data_offset
, cfm_tlv_length
, ENC_NA
);
2585 tlv_data_offset
+= cfm_tlv_length
;
2587 case DATA_PART2_TLV
:
2588 // NOTE: Appended to DATA_PART1_TLV this makes a complete Ethernet frame
2589 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_data_value
,
2590 tvb
, tlv_data_offset
, cfm_tlv_length
, ENC_NA
);
2591 tlv_data_offset
+= cfm_tlv_length
;
2594 if (cfm_tlv_length
> 3) {
2595 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_org_spec_oui
,
2596 tvb
, tlv_data_offset
, 3, ENC_BIG_ENDIAN
);
2597 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_org_spec_subtype
,
2598 tvb
, tlv_data_offset
+ 3, 1, ENC_NA
);
2599 // TODO: introduce subdissector table for this
2600 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_org_spec_value
,
2601 tvb
, tlv_data_offset
+ 4, cfm_tlv_length
-4, ENC_NA
);
2603 // TODO: report error
2605 tlv_data_offset
+= cfm_tlv_length
;
2609 uint32_t tlv_tst_test_pattern_type
;
2611 proto_tree_add_item_ret_uint(cfm_tlv_tree
, hf_tlv_tst_test_pattern_type
,
2612 tvb
, tlv_data_offset
, 1, ENC_NA
, &tlv_tst_test_pattern_type
);
2613 tlv_data_offset
+= 1;
2614 if (cfm_tlv_length
> 1) {
2615 switch (tlv_tst_test_pattern_type
) {
2619 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_tst_test_pattern
,
2620 tvb
, tlv_data_offset
, cfm_tlv_length
- 1, ENC_NA
);
2621 tlv_data_offset
+= cfm_tlv_length
- 1;
2625 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_tst_test_pattern
,
2626 tvb
, tlv_data_offset
, cfm_tlv_length
- 5, ENC_NA
);
2627 tlv_data_offset
+= cfm_tlv_length
- 5;
2628 // TODO: look at using proto_tree_add_checksum()
2629 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_tst_CRC32
,
2630 tvb
, tlv_data_offset
, 4, ENC_NA
);
2631 tlv_data_offset
+= 4;
2635 // TODO: report error
2639 case TGT_MEP_MIP_ID_TLV
:
2640 case RPL_MEP_MIP_ID_TLV
:
2642 uint32_t mep_mip_id_subtype
;
2644 proto_tree_add_item_ret_uint(cfm_tlv_tree
, hf_tlv_tgt_rpl_mep_mip_id_subtype
,
2645 tvb
, tlv_data_offset
, 1, ENC_NA
, &mep_mip_id_subtype
);
2646 tlv_data_offset
+= 1;
2647 if (cfm_tlv_length
> 1) {
2648 switch (mep_mip_id_subtype
) {
2649 case 0x00: // Discovery ingress/node MEP/MIP
2650 case 0x01: // Discovery egress MEP/MIP
2651 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_tgt_rpl_padding
,
2652 tvb
, tlv_data_offset
, cfm_tlv_length
- 1, ENC_NA
);
2654 case 0x02: // MEP ID
2655 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_tgt_rpl_mep_id
,
2656 tvb
, tlv_data_offset
, 2, ENC_BIG_ENDIAN
);
2657 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_tgt_rpl_padding
,
2658 tvb
, tlv_data_offset
+ 2, cfm_tlv_length
- 3, ENC_NA
);
2660 case 0x03: // MIP ID
2661 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_tgt_rpl_mip_id_icc
,
2662 tvb
, tlv_data_offset
, 6, ENC_ASCII
|ENC_NA
);
2663 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_tgt_rpl_mip_id_node_id
,
2664 tvb
, tlv_data_offset
+ 6, 4, ENC_BIG_ENDIAN
);
2665 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_tgt_rpl_mip_id_if_num
,
2666 tvb
, tlv_data_offset
+ 10, 4, ENC_BIG_ENDIAN
);
2667 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_tgt_rpl_mip_id_cc
,
2668 tvb
, tlv_data_offset
+ 14, 2, ENC_ASCII
|ENC_NA
);
2669 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_tgt_rpl_padding
,
2670 tvb
, tlv_data_offset
+ 16, cfm_tlv_length
- 17, ENC_NA
);
2673 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_tgt_rpl_padding
,
2674 tvb
, tlv_data_offset
, cfm_tlv_length
- 1, ENC_NA
);
2677 tlv_data_offset
+= cfm_tlv_length
;
2679 // TODO: report error
2683 case REQ_MEP_ID_TLV
:
2684 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_req_mep_id_lb
,
2685 tvb
, tlv_data_offset
, 1, ENC_NA
);
2686 tlv_data_offset
+= 1;
2687 tlv_data_offset
= dissect_mep_maid(tvb
, pinfo
, cfm_tlv_tree
, tlv_data_offset
);
2688 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_req_mep_id_reserved
,
2689 tvb
, tlv_data_offset
, 2, ENC_NA
);
2690 tlv_data_offset
+= 2;
2693 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_tst_id_test_id
,
2694 tvb
, tlv_data_offset
, 4, ENC_NA
);
2695 tlv_data_offset
+= 4;
2698 // TODO: report error
2699 proto_tree_add_item(cfm_tlv_tree
, hf_tlv_unknown_data
,
2700 tvb
, tlv_data_offset
, cfm_tlv_length
, ENC_NA
);
2701 tlv_data_offset
+= cfm_tlv_length
;
2705 // TODO: add check here that matches tlv_data_offset to cfm_tlv_offset + cfm_tlv_length
2706 cfm_tlv_offset
= tlv_data_offset
;
2710 proto_item_set_len(cfm_all_tlvs_ti
, cfm_tlv_offset
- cfm_first_tlv_offset
);
2711 proto_item_set_len(ti
, cfm_tlv_offset
);
2713 return cfm_tlv_offset
;
2716 /* Register CFM EOAM protocol */
2717 void proto_register_cfm(void)
2719 static hf_register_info hf
[] = {
2720 /* CFM Common header */
2722 { "CFM MD Level", "cfm.md_level", FT_UINT8
,
2723 BASE_DEC
, NULL
, 0xe0, "MD level/MEG level", HFILL
}
2726 { "CFM Version", "cfm.version", FT_UINT8
,
2727 BASE_DEC
, NULL
, 0x1f, NULL
, HFILL
}
2730 { "CFM OpCode", "cfm.opcode", FT_UINT8
,
2731 BASE_DEC
, VALS(opcode_type_name_vals
), 0x0, NULL
, HFILL
}
2734 { "Flags", "cfm.flags", FT_UINT8
,
2735 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
2737 { &hf_cfm_flags_Reserved
,
2738 { "Reserved", "cfm.flags.reserved", FT_UINT8
,
2739 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
2741 { &hf_cfm_first_tlv_offset
,
2742 { "First TLV Offset", "cfm.first_tlv_offset", FT_UINT8
,
2743 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
2748 { "Maintenance Association Endpoint Identifier", "cfm.mep_id",
2749 FT_UINT16
, BASE_DEC
, NULL
, 0x1FFF, NULL
, HFILL
}
2752 { "Maintenance Association Identifier", "cfm.maid", FT_NONE
,
2753 BASE_NONE
, NULL
, 0x0, "MEG ID (G.8013/Y.1731)", HFILL
}
2755 { &hf_cfm_maid_md_name_format
,
2756 { "MD Name Format", "cfm.maid.md_name.format", FT_UINT8
,
2757 BASE_DEC
, VALS(md_name_format_type_vals
), 0x0, "Reserved (01) in G.8013/Y.1731", HFILL
}
2759 { &hf_cfm_maid_md_name_length
,
2760 { "MD Name Length", "cfm.maid.md_name.length", FT_UINT8
,
2761 BASE_DEC
, NULL
, 0x0, "MEG ID length (G.8013/Y.1731)", HFILL
}
2763 { &hf_cfm_maid_md_name_string
,
2764 { "MD Name (String)", "cfm.maid.md_name.string", FT_STRING
,
2765 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2767 { &hf_cfm_maid_md_name_hex
,
2768 { "MD Name", "cfm.maid.md_name.hex", FT_BYTES
,
2769 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2771 { &hf_cfm_maid_md_name_mac
,
2772 { "MD Name (MAC+ID)", "cfm.maid.md_name.mac", FT_ETHER
,
2773 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2775 { &hf_cfm_maid_md_name_mac_id
,
2776 { "MD Name (MAC+ID)", "cfm.maid.md_name.mac.id", FT_BYTES
,
2777 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2779 { &hf_cfm_maid_ma_name_format
,
2780 { "Short MA Name (MEG ID) Format", "cfm.maid.ma_name.format", FT_UINT8
,
2781 BASE_DEC
, VALS(ma_name_format_type_vals
), 0x0, NULL
, HFILL
}
2783 { &hf_cfm_maid_ma_name_length
,
2784 { "Short MA Name (MEG ID) Length", "cfm.maid.ma_name.length", FT_UINT8
,
2785 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
2787 { &hf_cfm_maid_ma_name_pvid
,
2788 { "Short MA Name PVID", "cfm.maid.ma_name.pvid", FT_UINT16
,
2789 BASE_DEC
, NULL
, 0x0FFF, NULL
, HFILL
},
2791 { &hf_cfm_maid_ma_name_string
,
2792 { "Short MA Name", "cfm.maid.ma_name.string", FT_STRING
,
2793 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2795 { &hf_cfm_maid_ma_name_id
,
2796 { "Short MA Name ID", "cfm.maid.ma_name.id", FT_UINT16
,
2797 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
},
2799 { &hf_cfm_maid_ma_name_vpnid_oui
,
2800 { "Short MA Name VPN ID OUI", "cfm.maid.ma_name.vpnid.oui", FT_UINT24
,
2801 BASE_OUI
, NULL
, 0x0, NULL
, HFILL
},
2803 { &hf_cfm_maid_ma_name_vpnid_index
,
2804 { "Short MA Name VPN ID index", "cfm.maid.ma_name.vpnid.index", FT_UINT32
,
2805 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
},
2807 { &hf_cfm_maid_ma_name_icc_umc
,
2808 { "MEG ID ICC", "cfm.maid.ma_name.icc", FT_STRING
,
2809 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2811 { &hf_cfm_maid_ma_name_cc
,
2812 { "MEG ID CC", "cfm.maid.ma_name.cc", FT_STRING
,
2813 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2815 { &hf_cfm_maid_ma_name_hex
,
2816 { "Short MA Name", "cfm.maid.ma_name.hex", FT_BYTES
,
2817 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2819 { &hf_cfm_maid_padding
,
2820 { "Zero-Padding", "cfm.ccm.maid.padding", FT_NONE
,
2821 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2826 { "CFM CCM PDU", "cfm.ccm.pdu", FT_NONE
,
2827 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2829 { &hf_cfm_ccm_flags_RDI
,
2830 { "RDI", "cfm.ccm.flags.rdi", FT_UINT8
,
2831 BASE_DEC
, NULL
, 0x80, NULL
, HFILL
}
2833 { &hf_cfm_ccm_flags_Traffic
,
2834 { "Traffic", "cfm.ccm.flags.traffic", FT_UINT8
,
2835 BASE_DEC
, NULL
, 0x40, NULL
, HFILL
}
2837 { &hf_cfm_ccm_flags_Reserved
,
2838 { "Reserved", "cfm.ccm.flags.reserved", FT_UINT8
,
2839 BASE_DEC
, NULL
, 0x38, NULL
, HFILL
}
2841 { &hf_cfm_ccm_flags_Interval
,
2842 { "Interval Field", "cfm.ccm.flags.interval", FT_UINT8
,
2843 BASE_DEC
, VALS(ccm_interval_field_encoding_vals
), 0x07, NULL
, HFILL
}
2845 { &hf_cfm_ccm_seq_number
,
2846 { "Sequence Number", "cfm.ccm.seq_num", FT_UINT32
,
2847 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
2849 { &hf_cfm_ccm_itu_t_y1731
,
2850 { "Defined by ITU-T Y.1731", "cfm.ccm.itu", FT_NONE
,
2851 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2853 { &hf_cfm_ccm_itu_TxFCf
,
2854 { "TxFCf", "cfm.ccm.itu.txfcf", FT_UINT32
,
2855 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
2857 { &hf_cfm_ccm_itu_RxFCb
,
2858 { "RxFCb", "cfm.ccm.itu.rxfcb", FT_UINT32
,
2859 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
2861 { &hf_cfm_ccm_itu_TxFCb
,
2862 { "TxFCb", "cfm.ccm.itu.txfcb", FT_UINT32
,
2863 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
2865 { &hf_cfm_ccm_itu_reserved
,
2866 { "Reserved", "cfm.ccm.itu.reserved", FT_BYTES
,
2867 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2872 { "CFM LBM PDU", "cfm.lbm.pdu", FT_NONE
,
2873 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2875 { &hf_cfm_lbm_lbr_transaction_id
,
2876 { "Loopback Transaction Identifier", "cfm.lbm.lbr.transaction_id", FT_UINT32
,
2877 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
2882 { "CFM LBR PDU", "cfm.lbr.pdu", FT_NONE
,
2883 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2888 { "CFM LTM PDU", "cfm.ltm.pdu", FT_NONE
,
2889 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2891 { &hf_cfm_ltm_flags_UseFDBonly
,
2892 { "UseFDBonly", "cfm.ltm.flags.usefdbonly", FT_UINT8
,
2893 BASE_DEC
, NULL
, 0x80, NULL
, HFILL
}
2895 { &hf_cfm_ltm_flags_Reserved
,
2896 { "Reserved", "cfm.ltm.flags.reserved", FT_UINT8
,
2897 BASE_DEC
, NULL
, 0x7F, NULL
, HFILL
}
2899 { &hf_cfm_ltm_ltr_transaction_id
,
2900 { "Linktrace Transaction Identifier", "cfm.ltm.ltr.transaction_id", FT_UINT32
,
2901 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
2903 { &hf_cfm_ltm_ltr_ttl
,
2904 { "Linktrace TTL", "cfm.ltm.ltr.ttl", FT_UINT8
,
2905 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
2907 { &hf_cfm_ltm_orig_addr
,
2908 { "Linktrace Message: Original Address", "cfm.ltm.orig_addr", FT_ETHER
,
2909 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2911 { &hf_cfm_ltm_targ_addr
,
2912 { "Linktrace Message: Target Address", "cfm.ltm.target_addr", FT_ETHER
,
2913 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2918 { "CFM LTR PDU", "cfm.ltr.pdu", FT_NONE
,
2919 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2921 { &hf_cfm_ltr_flags_UseFDBonly
,
2922 { "UseFDBonly", "cfm.ltr.flags.usefdbonly", FT_UINT8
,
2923 BASE_DEC
, NULL
, 0x80, NULL
, HFILL
}
2925 { &hf_cfm_ltr_flags_FwdYes
,
2926 { "FwdYes", "cfm.ltr.flags.fwdyes", FT_UINT8
,
2927 BASE_DEC
, NULL
, 0x40, NULL
, HFILL
}
2929 { &hf_cfm_ltr_flags_TerminalMEP
,
2930 { "TerminalMEP", "cfm.ltr.flags.terminalmep", FT_UINT8
,
2931 BASE_DEC
, NULL
, 0x20, NULL
, HFILL
}
2933 { &hf_cfm_ltr_flags_Reserved
,
2934 { "Reserved", "cfm.ltr.flags.reserved", FT_UINT8
,
2935 BASE_DEC
, NULL
, 0x1F, NULL
, HFILL
}
2937 { &hf_cfm_ltr_relay_action
,
2938 { "Linktrace Reply Relay Action", "cfm.ltr.relay_action", FT_UINT8
,
2939 BASE_DEC
, VALS(relay_action_type_vals
), 0x0, NULL
, HFILL
}
2944 { "CFM RFM PDU", "cfm.rfm.pdu", FT_NONE
,
2945 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2947 { &hf_cfm_rfm_transaction_id
,
2948 { "RFM Transaction Identifier", "cfm.rfm.transaction_id", FT_UINT32
,
2949 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
2954 { "CFM SFM PDU", "cfm.sfm.pdu", FT_NONE
,
2955 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2957 { &hf_cfm_sfm_transaction_id
,
2958 { "SFM Transaction Identifier", "cfm.sfm.transaction_id", FT_UINT32
,
2959 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
2964 { "CFM GNM PDU", "cfm.gnm.pdu", FT_NONE
,
2965 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2967 { &hf_cfm_gnm_unknown_flags
,
2968 { "Unknown flags", "cfm.gnm.unknown.flags", FT_UINT8
,
2969 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
2971 { &hf_cfm_gnm_subopcode
,
2972 { "Sub-OpCode", "cfm.gnm.subopcode", FT_UINT8
,
2973 BASE_HEX
, VALS(gnm_sub_opcode_type_name_vals
), 0x0, NULL
, HFILL
}
2977 { &hf_cfm_bnm_flags_Reserved
,
2978 { "Reserved", "cfm.bnm.flags.Reserved", FT_UINT8
,
2979 BASE_DEC
, NULL
, 0xF8, NULL
, HFILL
}
2981 { &hf_cfm_bnm_flags_Period
,
2982 { "Period", "cfm.bnm.flags.Period", FT_UINT8
,
2983 BASE_DEC
, VALS(cfm_bnm_flags_period_vals
), 0x07, NULL
, HFILL
}
2986 { "CFM BNM PDU", "cfm.bnm.pdu", FT_NONE
,
2987 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
2989 { &hf_cfm_bnm_nominal_bw
,
2990 { "Nominal Bandwidth", "cfm.bnm.nominal_bw", FT_UINT32
,
2991 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
2993 { &hf_cfm_bnm_current_bw
,
2994 { "Current Bandwidth", "cfm.bnm.current_bw", FT_UINT32
,
2995 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
2997 { &hf_cfm_bnm_port_id
,
2998 { "Port ID", "cfm.bnm.port_id", FT_UINT32
,
2999 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3004 { "CFM AIS PDU", "cfm.ais.pdu", FT_NONE
,
3005 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3007 { &hf_cfm_ais_flags_Reserved
,
3008 { "Reserved", "cfm.ais.flags.Reserved", FT_UINT8
,
3009 BASE_DEC
, NULL
, 0xF8, NULL
, HFILL
}
3011 { &hf_cfm_ais_flags_Period
,
3012 { "Period", "cfm.ais.flags.Period", FT_UINT8
,
3013 BASE_DEC
, VALS(ais_lck_period_type_vals
), 0x07, NULL
, HFILL
}
3018 { "CFM LCK PDU", "cfm.lck.pdu", FT_NONE
,
3019 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3021 { &hf_cfm_lck_flags_Reserved
,
3022 { "Reserved", "cfm.lck.flags.Reserved", FT_UINT8
,
3023 BASE_DEC
, NULL
, 0xF8, NULL
, HFILL
}
3025 { &hf_cfm_lck_flags_Period
,
3026 { "Period", "cfm.lck.flags.Period", FT_UINT8
,
3027 BASE_DEC
, VALS(ais_lck_period_type_vals
), 0x07, NULL
, HFILL
}
3032 { "CFM TST PDU", "cfm.tst.pdu", FT_NONE
,
3033 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3035 { &hf_cfm_tst_sequence_num
,
3036 { "Sequence Number", "cfm.tst.sequence_num", FT_UINT32
,
3037 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3042 { "CFM APS PDU", "cfm.aps.pdu", FT_NONE
,
3043 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3045 { &hf_cfm_aps_req_st
,
3046 { "Request/State", "cfm.aps.req_st", FT_UINT8
,
3047 BASE_DEC
, VALS(aps_request_state_vals
), 0xf0, NULL
, HFILL
}
3049 { &hf_cfm_aps_protection_type_A
,
3050 { "Protection type A", "cfm.aps.protec.type_A", FT_BOOLEAN
,
3051 8, TFS(&tfs_aps_protection_type_A
), 0x08, NULL
, HFILL
}
3053 { &hf_cfm_aps_protection_type_B
,
3054 { "Protection type B", "cfm.aps.protec.type_B", FT_BOOLEAN
,
3055 8, TFS(&tfs_aps_protection_type_B
), 0x04, NULL
, HFILL
}
3057 { &hf_cfm_aps_protection_type_D
,
3058 { "Protection type D", "cfm.aps.protec.type_D", FT_BOOLEAN
,
3059 8, TFS(&tfs_aps_protection_type_D
), 0x02, NULL
, HFILL
}
3061 { &hf_cfm_aps_protection_type_R
,
3062 { "Protection type R", "cfm.aps.protec.type_R", FT_BOOLEAN
,
3063 8, TFS(&tfs_aps_protection_type_R
), 0x01, NULL
, HFILL
}
3065 { &hf_cfm_aps_requested_signal
,
3066 { "Requested signal", "cfm.aps.req_signal", FT_UINT8
,
3067 BASE_HEX
, VALS(aps_requested_signal_values
), 0x0, NULL
, HFILL
}
3069 { &hf_cfm_aps_bridged_signal
,
3070 { "Bridged signal", "cfm.aps.bridged_signal", FT_UINT8
,
3071 BASE_HEX
, VALS(aps_bridged_signal_values
), 0x0, NULL
, HFILL
}
3073 { &hf_cfm_aps_bridge_type
,
3074 { "Bridge type", "cfm.aps.bridge_type", FT_UINT8
,
3075 BASE_HEX
, VALS(aps_bridge_type_values
), 0x80, NULL
, HFILL
}
3080 { "CFM R-APS PDU", "cfm.raps.pdu", FT_NONE
,
3081 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3083 { &hf_cfm_raps_req_st
,
3084 { "Request/State", "cfm.raps.req_st", FT_UINT8
,
3085 BASE_HEX
, VALS(raps_request_state_values
), RAPS_REQ_ST_MASK
, NULL
, HFILL
}
3087 { &hf_cfm_raps_event_subcode
,
3088 { "Sub-code", "cfm.raps.event.subcode", FT_UINT8
,
3089 BASE_HEX
, VALS(rasp_event_subcode_vals
), RAPS_SUB_CODE_MASK
, NULL
, HFILL
}
3091 { &hf_cfm_raps_subcode_reserved
,
3092 { "Reserved", "cfm.raps.subcode.reserved", FT_UINT8
,
3093 BASE_HEX
, NULL
, RAPS_SUB_CODE_MASK
, NULL
, HFILL
}
3095 { &hf_cfm_raps_status
,
3096 { "R-APS status", "cfm.raps.status", FT_UINT8
,
3097 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
3099 { &hf_cfm_raps_status_rb
,
3100 { "RPL Blocked", "cfm.raps.status.rb", FT_BOOLEAN
,
3101 8, TFS(&tfs_rasp_rpl_blocked
), 0x80, NULL
, HFILL
}
3103 { &hf_cfm_raps_status_dnf
,
3104 { "Do Not Flush", "cfm.raps.status.dnf", FT_BOOLEAN
,
3105 8, TFS(&tfs_rasp_dnf
), 0x40, NULL
, HFILL
}
3107 { &hf_cfm_raps_status_bpr
,
3108 { "Blocked Port Reference", "cfm.raps.status.bpr", FT_BOOLEAN
,
3109 8, TFS(&tfs_rasp_bpr
), 0x20, NULL
, HFILL
}
3111 { &hf_cfm_raps_status_reserved_v1
,
3112 { "Reserved", "cfm.raps.status.reserved_v1", FT_UINT8
,
3113 BASE_HEX
, NULL
, 0x3F, NULL
, HFILL
}
3115 { &hf_cfm_raps_status_reserved_v2
,
3116 { "Reserved", "cfm.raps.status.reserved_v2", FT_UINT8
,
3117 BASE_HEX
, NULL
, 0x1F, NULL
, HFILL
}
3119 { &hf_cfm_raps_node_id
,
3120 { "R-APS Node ID", "cfm.raps.node_id", FT_ETHER
,
3121 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3123 { &hf_cfm_raps_reserved
,
3124 { "R-APS Reserved", "cfm.raps.reserved", FT_BYTES
,
3125 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3130 { "CFM MCC PDU", "cfm.mcc.pdu", FT_NONE
,
3131 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3134 { "OUI", "cfm.mcc.oui", FT_UINT24
,
3135 BASE_OUI
, NULL
, 0x0, NULL
, HFILL
}
3137 { &hf_cfm_mcc_subopcode
,
3138 { "Subopcode", "cfm.mcc.subopcode", FT_UINT8
,
3139 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3142 { "MCC data", "cfm.mcc.data", FT_BYTES
,
3143 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3148 { "CFM LMM PDU", "cfm.lmm.pdu", FT_NONE
,
3149 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3151 { &hf_cfm_lmm_lmr_flags_Reserved
,
3152 { "Reserved", "cfm.lmm.lmr.flags.Reserved", FT_UINT8
,
3153 BASE_HEX
, NULL
, 0xFE, NULL
, HFILL
}
3155 { &hf_cfm_lmm_lmr_flags_Type
,
3156 { "Type", "cfm.lmm.lmr.flags.Type", FT_BOOLEAN
,
3157 8, TFS(&tfs_lmm_lmr_type
), 0x01, NULL
, HFILL
}
3159 { &hf_cfm_lmm_lmr_TxFCf
,
3160 { "TxFCf", "cfm.lmm.lmr.txfcf", FT_UINT32
,
3161 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3163 { &hf_cfm_lmm_lmr_RxFCf
,
3164 { "RxFCf", "cfm.lmm.lmr.rxfcf", FT_UINT32
,
3165 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3167 { &hf_cfm_lmm_lmr_TxFCb
,
3168 { "TxFCb", "cfm.lmm.lmr.txfcb", FT_UINT32
,
3169 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3174 { "CFM LMR PDU", "cfm.lmr.pdu", FT_NONE
,
3175 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3180 { "CFM 1DM PDU", "cfm.odm.pdu", FT_NONE
,
3181 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3183 { &hf_cfm_odm_dmm_dmr_flags_Reserved
,
3184 { "Reserved", "cfm.odm.dmm.dmr.flags.Reserved", FT_UINT8
,
3185 BASE_HEX
, NULL
, 0xFE, NULL
, HFILL
}
3187 { &hf_cfm_odm_dmm_dmr_flags_Type
,
3188 { "Type", "cfm.odm.dmm.dmr.flags.Type", FT_BOOLEAN
,
3189 8, TFS(&tfs_odm_dmm_dmr_type
), 0x01, NULL
, HFILL
}
3191 { &hf_cfm_odm_dmm_dmr_TxTimestampf
,
3192 { "TxTimestampf", "cfm.odm.dmm.dmr.txtimestampf", FT_RELATIVE_TIME
,
3193 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3195 { &hf_cfm_odm_dmm_dmr_RxTimestampf
,
3196 { "RxTimestampf", "cfm.odm.dmm.dmr.rxtimestampf", FT_RELATIVE_TIME
,
3197 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3202 { "CFM DMM PDU", "cfm.dmm.pdu", FT_NONE
,
3203 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3205 { &hf_cfm_dmm_dmr_TxTimestampb
,
3206 { "TxTimestampb", "cfm.dmm.dmr.txtimestampb", FT_RELATIVE_TIME
,
3207 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3209 { &hf_cfm_dmm_dmr_RxTimestampb
,
3210 { "RxTimestampb", "cfm.dmm.dmr.rxtimestampb", FT_RELATIVE_TIME
,
3211 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3216 { "CFM DMR PDU", "cfm.dmr.pdu", FT_NONE
,
3217 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3222 { "CFM EXM PDU", "cfm.exm.pdu", FT_NONE
,
3223 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3226 { "OUI", "cfm.exm.oui", FT_UINT24
,
3227 BASE_OUI
, NULL
, 0x0, NULL
, HFILL
}
3229 { &hf_cfm_exm_subopcode
,
3230 { "Subopcode", "cfm.exm.subopcode", FT_UINT8
,
3231 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3234 { "EXM data", "cfm.exm.data", FT_BYTES
,
3235 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3240 { "CFM EXR PDU", "cfm.exr.pdu", FT_NONE
,
3241 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3244 { "OUI", "cfm.exr.oui", FT_UINT24
,
3245 BASE_OUI
, NULL
, 0x0, NULL
, HFILL
}
3247 { &hf_cfm_exr_subopcode
,
3248 { "Subopcode", "cfm.exr.subopcode", FT_UINT8
,
3249 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3252 { "EXR data", "cfm.exr.data", FT_BYTES
,
3253 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3258 { "CFM VSM PDU", "cfm.vsm.pdu", FT_NONE
,
3259 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3262 { "OUI", "cfm.vsm.oui", FT_UINT24
,
3263 BASE_OUI
, NULL
, 0x0, NULL
, HFILL
}
3265 { &hf_cfm_vsm_subopcode
,
3266 { "Subopcode", "cfm.vsm.subopcode", FT_UINT8
,
3267 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3270 { "VSM data", "cfm.vsm.data", FT_BYTES
,
3271 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3276 { "CFM VSR PDU", "cfm.vsr.pdu", FT_NONE
,
3277 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3280 { "OUI", "cfm.vsr.oui", FT_UINT24
,
3281 BASE_OUI
, NULL
, 0x0, NULL
, HFILL
}
3283 { &hf_cfm_vsr_subopcode
,
3284 { "Subopcode", "cfm.vsr.subopcode", FT_UINT8
,
3285 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3288 { "VSR data", "cfm.vsr.data", FT_BYTES
,
3289 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3294 { "CFM CSF PDU", "cfm.csf.pdu", FT_NONE
,
3295 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3297 { &hf_cfm_csf_flags_Reserved
,
3298 { "Reserved", "cfm.csf.flags.Reserved", FT_UINT8
,
3299 BASE_HEX
, NULL
, 0xC0, NULL
, HFILL
}
3301 { &hf_cfm_csf_flags_Type
,
3302 { "Type", "cfm.csf.flags.Type", FT_UINT8
,
3303 BASE_DEC
, VALS(cfm_csf_flags_type_vals
), 0x38, NULL
, HFILL
}
3305 { &hf_cfm_csf_flags_Period
,
3306 { "Type", "cfm.csf.flags.Period", FT_UINT8
,
3307 BASE_DEC
, VALS(cfm_csf_flags_period_vals
), 0x07, NULL
, HFILL
}
3312 { "CFM 1SL PDU", "cfm.osf.pdu", FT_NONE
,
3313 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3315 { &hf_cfm_osl_src_mep
,
3316 { "Source MEP ID", "cfm.osl.src_mep_id", FT_UINT16
,
3317 BASE_DEC
, NULL
, 0x1FFF, NULL
, HFILL
}
3319 { &hf_cfm_osl_reserved
,
3320 { "1SL Reserved", "cfm.osl.reserved", FT_BYTES
,
3321 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3323 { &hf_cfm_osl_testid
,
3324 { "TestID", "cfm.osl.test_id", FT_BYTES
,
3325 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3327 { &hf_cfm_osl_txfcf
,
3328 { "TxFcF", "cfm.osl.txfcf", FT_UINT32
,
3329 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3334 { "CFM SLM PDU", "cfm.slm.pdu", FT_NONE
,
3335 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3337 { &hf_cfm_slm_slr_src_mep
,
3338 { "Source MEP ID", "cfm.slm.slr.src_mep_id", FT_UINT16
,
3339 BASE_DEC
, NULL
, 0x1FFF, NULL
, HFILL
}
3341 { &hf_cfm_slm_reserved
,
3342 { "SLM Reserved", "cfm.slm.reserved", FT_BYTES
,
3343 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3345 { &hf_cfm_slm_slr_testid
,
3346 { "TestID", "cfm.slm.slr.test_id", FT_BYTES
,
3347 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3349 { &hf_cfm_slm_slr_txfcf
,
3350 { "TxFcF", "cfm.slm.slr.txfcf", FT_UINT32
,
3351 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3356 { "CFM SLR PDU", "cfm.slr.pdu", FT_NONE
,
3357 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3359 { &hf_cfm_slr_rsp_mep
,
3360 { "Responder MEP ID", "cfm.slr.rsp_mep_id", FT_UINT16
,
3361 BASE_DEC
, NULL
, 0x1FFF, NULL
, HFILL
}
3363 { &hf_cfm_slr_txfcb
,
3364 { "TxFcB", "cfm.slr.txfcb", FT_UINT32
,
3365 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3369 { &hf_cfm_unknown_pdu
,
3370 { "Unknown PDU", "cfm.unknown.pdu", FT_NONE
,
3371 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3373 { &hf_cfm_unknown_flags
,
3374 { "Unknown flags", "cfm.unknown.flags", FT_UINT8
,
3375 BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}
3377 { &hf_cfm_unknown_data
,
3378 { "Unknown data", "cfm.unknown.data", FT_BYTES
,
3379 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3382 /******************************* TLVs ****************************/
3384 { "CFM TLVs", "cfm.all_tlvs", FT_NONE
,
3385 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3388 { "TLV Type", "cfm.tlv.type", FT_UINT8
,
3389 BASE_DEC
, VALS(tlv_type_field_vals
), 0x0, NULL
, HFILL
}
3391 { &hf_cfm_tlv_length
,
3392 { "TLV Length", "cfm.tlv.length", FT_UINT16
,
3393 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3396 { &hf_tlv_chassis_id_length
,
3397 { "Chassis ID Length", "cfm.tlv.sender_id.chassis_id.length", FT_UINT8
,
3398 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3400 { &hf_tlv_chassis_id_subtype
,
3401 { "Chassis ID Sub-type", "cfm.tlv.sender_id.chassis_id.subtype", FT_UINT8
,
3402 BASE_DEC
, VALS(sender_id_tlv_chassis_id_subtype_vals
), 0x0, NULL
, HFILL
}
3404 { &hf_tlv_chassis_id_chassis_component
,
3405 { "Chassis component", "cfm.tlv.sender_id.chassis_id.chassis_component", FT_STRINGZPAD
,
3406 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3408 { &hf_tlv_chassis_id_interface_alias
,
3409 { "Interface alias", "cfm.tlv.sender_id.chassis_id.intf_alias", FT_STRINGZPAD
,
3410 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3412 { &hf_tlv_chassis_id_port_component
,
3413 { "Port component", "cfm.tlv.sender_id.chassis_id.port_component", FT_BYTES
,
3414 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3416 { &hf_tlv_chassis_id_mac_address
,
3417 { "MAC address", "cfm.tlv.sender_id.chassis_id.mac_address", FT_ETHER
,
3418 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3420 { &hf_tlv_chassis_id_network_address_family
,
3421 { "Network address family", "cfm.tlv.sender_id.chassis_id.network_address.family", FT_UINT8
,
3422 BASE_DEC
, VALS(afn_vals
), 0x0, NULL
, HFILL
}
3424 { &hf_tlv_chassis_id_network_address_ipv4
,
3425 { "Network address", "cfm.tlv.sender_id.chassis_id.network_address.ipv4", FT_IPv4
,
3426 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3428 { &hf_tlv_chassis_id_network_address_ipv6
,
3429 { "Network address", "cfm.tlv.sender_id.chassis_id.network_address.ipv6", FT_IPv6
,
3430 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3432 { &hf_tlv_chassis_id_network_address_unknown
,
3433 { "Network address", "cfm.tlv.sender_id.chassis_id.network_address.unknown", FT_BYTES
,
3434 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3436 { &hf_tlv_chassis_id_interface_name
,
3437 { "Interface name", "cfm.tlv.sender_id.chassis_id.intf_name", FT_STRINGZPAD
,
3438 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3440 { &hf_tlv_chassis_id_locally_assigned
,
3441 { "Locally assigned", "cfm.tlv.sender_id.chassis_id.locally_assigned", FT_STRINGZPAD
,
3442 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3444 { &hf_tlv_chassis_id_unknown
,
3445 { "Unknown", "cfm.tlv.sender_id.chassis_id.unknown", FT_BYTES
,
3446 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3448 { &hf_tlv_ma_domain_length
,
3449 { "Management Address Domain Length", "cfm.tlv.sender_id.ma_domain.length", FT_UINT8
,
3450 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3452 { &hf_tlv_ma_domain
,
3453 { "Management Address Domain", "cfm.tlv.sender_id.ma_domain", FT_OID
,
3454 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3456 { &hf_tlv_management_addr_length
,
3457 { "Management Address Length", "cfm.tlv.sender_id.management_addr.length", FT_UINT8
,
3458 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3460 { &hf_tlv_management_addr_ipv4
,
3461 { "Management Address", "cfm.tlv.sender_id.management_addr.ipv4", FT_IPv4
,
3462 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3464 { &hf_tlv_management_addr_ipv6
,
3465 { "Management Address", "cfm.tlv.sender_id.management_addr.ipv6", FT_IPv6
,
3466 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3468 { &hf_tlv_management_addr_eth
,
3469 { "Management Address", "cfm.tlv.sender_id.management_addr.eth", FT_ETHER
,
3470 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3472 { &hf_tlv_management_addr_unknown
,
3473 { "Management Address", "cfm.tlv.sender_id.management_addr.unknown", FT_BYTES
,
3474 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3477 /* Port Status TLV */
3478 { &hf_tlv_port_status_value
,
3479 { "Port Status value", "cfm.tlv.port_status.value", FT_UINT8
,
3480 BASE_DEC
, VALS(port_stat_tlv_vals
), 0x0, NULL
, HFILL
}
3483 /* Data TLV, Truncated Data TLV, Data Part 1 TLV, Data Part 2 TLV */
3484 { &hf_tlv_data_value
,
3485 { "Data Value", "cfm.tlv.data.value", FT_BYTES
,
3486 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3489 /* Interface status TLV */
3490 { &hf_tlv_interface_status_value
,
3491 { "Interface Status value", "cfm.tlv.intf_status.value", FT_UINT8
,
3492 BASE_DEC
, VALS(interface_stat_tlv_vals
), 0x0, NULL
, HFILL
}
3495 /* Reply Ingress TLV, Reply Egress TLV */
3496 { &hf_tlv_reply_ingress_action
,
3497 { "Ingress Action", "cfm.tlv.reply_ingress.action", FT_UINT8
,
3498 BASE_DEC
, VALS(reply_ingress_tlv_vals
), 0x0, NULL
, HFILL
}
3500 { &hf_tlv_reply_ingress_mac_address
,
3501 { "Ingress MAC address", "cfm.tlv.reply_ingress.mac_address", FT_ETHER
,
3502 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3504 { &hf_tlv_reply_ing_egr_portid_length
,
3505 { "Chassis ID Length", "cfm.tlv.reply_ing_egr.portid.length", FT_UINT8
,
3506 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3508 { &hf_tlv_reply_ing_egr_portid_subtype
,
3509 { "Chassis ID Sub-type", "cfm.tlv.reply_ing_egr.portid.subtype", FT_UINT8
,
3510 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3512 { &hf_tlv_reply_ing_egr_portid_interface_alias
,
3513 { "Interface alias", "cfm.tlv.reply_ing_egr.portid.intf_alias", FT_STRING
,
3514 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3516 { &hf_tlv_reply_ing_egr_portid_port_component
,
3517 { "Port component", "cfm.tlv.reply_ing_egr.portid.port_comp", FT_BYTES
,
3518 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3520 { &hf_tlv_reply_ing_egr_portid_mac_address
,
3521 { "MAC address", "cfm.tlv.reply_ing_egr.portid.mac_address", FT_ETHER
,
3522 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3524 { &hf_tlv_reply_ing_egr_portid_network_address_family
,
3525 { "Network address family", "cfm.tlv.reply_ing_egr.portid.network_address.family", FT_UINT8
,
3526 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3528 { &hf_tlv_reply_ing_egr_portid_network_address_ipv4
,
3529 { "Network address", "cfm.tlv.reply_ing_egr.portid.network_address.ipv4", FT_IPv4
,
3530 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3532 { &hf_tlv_reply_ing_egr_portid_network_address_ipv6
,
3533 { "Network address", "cfm.tlv.reply_ing_egr.portid.network_address.ipv6", FT_IPv6
,
3534 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3536 { &hf_tlv_reply_ing_egr_portid_network_address_unknown
,
3537 { "Network address", "cfm.tlv.reply_ing_egr.portid.network_address.unknown", FT_BYTES
,
3538 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3540 { &hf_tlv_reply_ing_egr_portid_interface_name
,
3541 { "Interface name", "cfm.tlv.reply_ing_egr.portid.intf_name", FT_STRINGZPAD
,
3542 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3544 { &hf_tlv_reply_ing_egr_portid_agent_circuit_id
,
3545 { "Agent circuit ID", "cfm.tlv.reply_ing_egr.portid.agent_circuit_id", FT_BYTES
,
3546 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3548 { &hf_tlv_reply_ing_egr_portid_locally_assigned
,
3549 { "Locally assigned", "cfm.tlv.reply_ing_egr.portid.locally_assigned", FT_STRINGZPAD
,
3550 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3552 { &hf_tlv_reply_ing_egr_portid_unknown
,
3553 { "Chassis ID", "cfm.tlv.reply_ing_egr.portid.unknown", FT_BYTES
,
3554 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3557 /* Reply Egress TLV */
3558 { &hf_tlv_reply_egress_action
,
3559 { "Egress Action", "cfm.tlv.reply_egress.action", FT_UINT8
,
3560 BASE_DEC
, VALS(reply_egress_tlv_vals
), 0x0, NULL
, HFILL
}
3562 { &hf_tlv_reply_egress_mac_address
,
3563 { "Egress MAC address", "cfm.tlv.reply_egress.mac_address", FT_ETHER
,
3564 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3567 /* LTM Egress Identifier TLV */
3568 { &hf_tlv_ltm_egress_id_mac
,
3569 { "Egress Identifier - MAC of LT Initiator/Responder", "cfm.tlv.ltm_egress.id.mac", FT_ETHER
,
3570 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3572 { &hf_tlv_ltm_egress_id_unique_identifier
,
3573 { "Egress Identifier - Unique Identifier", "cfm.tlv.ltm_egress.id.ui", FT_BYTES
,
3574 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3577 /* LTR Egress Identifier TLV */
3578 { &hf_tlv_ltr_egress_last_id_mac
,
3579 { "Last Egress Identifier - MAC address", "cfm.tlv.ltr_egress.last_id.mac", FT_ETHER
,
3580 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3582 { &hf_tlv_ltr_egress_last_id_unique_identifier
,
3583 { "Last Egress Identifier - Unique Identifier", "cfm.tlv.ltr_egress.last_id.ui", FT_BYTES
,
3584 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3586 { &hf_tlv_ltr_egress_next_id_mac
,
3587 { "Next Egress Identifier - MAC address", "cfm.tlv.ltr_egress.next_id.mac", FT_ETHER
,
3588 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3590 { &hf_tlv_ltr_egress_next_id_unique_identifier
,
3591 { "Next Egress Identifier - Unique Identifier", "cfm.tlv.ltr_egress.next_id.ui", FT_BYTES
,
3592 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3596 { &hf_tlv_pbb_te_mip_mac_address
,
3597 { "MIP MAC address", "cfm.tlv.pbb_te.mip_mac", FT_ETHER
,
3598 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3600 { &hf_tlv_pbb_te_reverse_vid
,
3601 { "Reverse VID", "cfm.tlv.pbb_te.reverse_vid", FT_UINT16
,
3602 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3604 { &hf_tlv_pbb_te_reverse_mac
,
3605 { "Reverse MAC", "cfm.tlv.pbb_te.reverse_mac", FT_ETHER
,
3606 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3609 /* Organization-Specific TLV */
3610 { &hf_tlv_org_spec_oui
,
3611 { "OUI", "cfm.tlv.org_spec.oui", FT_UINT24
,
3612 BASE_OUI
, NULL
, 0x0, NULL
, HFILL
}
3614 { &hf_tlv_org_spec_subtype
,
3615 { "Sub-Type", "cfm.tlv.org_spec.subtype", FT_BYTES
,
3616 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3618 { &hf_tlv_org_spec_value
,
3619 { "Value", "cfm.tlv.org_spec.value", FT_BYTES
,
3620 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3624 { &hf_tlv_tst_test_pattern_type
,
3625 { "Test Pattern Type", "cfm.tlv.tst.test.pattern.type", FT_UINT8
,
3626 BASE_DEC
, VALS(test_tlv_pattern_type_vals
), 0x0, NULL
, HFILL
}
3628 { &hf_tlv_tst_test_pattern
,
3629 { "Test Pattern", "cfm.tlv.tst.test.pattern", FT_NONE
,
3630 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3632 { &hf_tlv_tst_CRC32
,
3633 { "CRC-32", "cfm.tlv.tst.crc32", FT_BYTES
,
3634 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3637 /* Target MEP/MIP ID TLV, Replying MEP/MIP ID TLV */
3638 { &hf_tlv_tgt_rpl_mep_mip_id_subtype
,
3639 { "ID subtype", "cfm.tlv.tgt_rpl_mep_mip.id_subtype", FT_UINT8
,
3640 BASE_DEC
, VALS(mep_mip_id_tlv_subtype_vals
), 0x0, NULL
, HFILL
}
3642 { &hf_tlv_tgt_rpl_padding
,
3643 { "Padding", "cfm.tlv.tgt_rpl_mep_mip.padding", FT_BYTES
,
3644 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3646 { &hf_tlv_tgt_rpl_mep_id
,
3647 { "MEP ID", "cfm.tlv.tgt_rpl_mep_mip.mep_id", FT_UINT16
,
3648 BASE_DEC
, NULL
, 0x1FFF, NULL
, HFILL
}
3650 { &hf_tlv_tgt_rpl_mip_id_icc
,
3651 { "ITU-T Carrier Code", "cfm.tlv.tgt_rpl_mep_mip.icc", FT_STRINGZPAD
,
3652 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3654 { &hf_tlv_tgt_rpl_mip_id_node_id
,
3655 { "Node ID", "cfm.tlv.tgt_rpl_mep_mip.node_id", FT_UINT32
,
3656 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3658 { &hf_tlv_tgt_rpl_mip_id_if_num
,
3659 { "IF Num", "cfm.tlv.tgt_rpl_mep_mip.if_num", FT_UINT32
,
3660 BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}
3662 { &hf_tlv_tgt_rpl_mip_id_cc
,
3663 { "Country Code", "cfm.tlv.tgt_rpl_mep_mip.cc", FT_STRINGZPAD
,
3664 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3667 /* Requesting MEP ID TLV */
3668 { &hf_tlv_req_mep_id_lb
,
3669 { "ID subtype", "cfm.tlv.req_mep_id.lb", FT_UINT8
,
3670 BASE_DEC
, VALS(req_mep_id_tlv_lb_vals
), 0x0, NULL
, HFILL
}
3672 { &hf_tlv_req_mep_id_reserved
,
3673 { "Reserved", "cfm.tlv.req_mep_id.reserved", FT_BYTES
,
3674 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3678 { &hf_tlv_tst_id_test_id
,
3679 { "Test ID", "cfm.tlv.tst_id.test_id", FT_BYTES
,
3680 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3684 { &hf_tlv_unknown_data
,
3685 { "TLV Data", "cfm.tlv.unknown.data", FT_BYTES
,
3686 BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}
3690 /* Setup protocol subtree array */
3691 static int *ett
[] = {
3699 &ett_cfm_raps_status
,
3702 static ei_register_info ei
[] = {
3703 { &ei_tlv_tst_id_length
,
3704 { "cfm.tlv.tst_id.length", PI_PROTOCOL
, PI_NOTE
,
3705 "Test ID TLV length is bits, not octets, unlike other TLVs",
3708 { &ei_tlv_management_addr_length
,
3709 { "cfm.tlv.sender_id.management_addr.length.zero",
3710 PI_PROTOCOL
, PI_WARN
,
3711 "Management Address Length should not be present if Management Address Domain Length is 0",
3716 expert_module_t
* expert_cfm
;
3718 proto_cfm
= proto_register_protocol("CFM EOAM IEEE 802.1Q/ITU-T Y.1731 Protocol", "CFM", "cfm");
3720 cfm_handle
= register_dissector("cfm", dissect_cfm
, proto_cfm
);
3722 proto_register_field_array(proto_cfm
, hf
, array_length(hf
));
3723 proto_register_subtree_array(ett
, array_length(ett
));
3724 expert_cfm
= expert_register_protocol(proto_cfm
);
3725 expert_register_field_array(expert_cfm
, ei
, array_length(ei
));
3728 /* Register CFM EOAM protocol handler */
3729 void proto_reg_handoff_cfm(void)
3731 dissector_add_uint("ethertype", ETHERTYPE_CFM
, cfm_handle
);
3732 dissector_add_uint("pwach.channel_type", PW_ACH_TYPE_MPLSTP_OAM
, cfm_handle
);
3736 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3741 * indent-tabs-mode: t
3744 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3745 * :indentSize=8:tabSize=8:noTabs=false: