2 * Routines for CFM EOAM (IEEE 802.1ag) dissection
3 * Copyright 2007, Keith Mercer <keith.mercer@alcatel-lucent.com>
4 * Copyright 2011, Peter Nahas <pnahas@mrv.com>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 /* This code is based on the IEEE P802.1ag/D8.1 document, and on the ITU-T Y.1731
28 * recommendation (05/2006,) which is not formally released at the time of this
29 * dissector development. Any updates to these documents may require additional
30 * modifications to this code.
38 #include <epan/packet.h>
40 #include <epan/etypes.h>
42 /** Value declarations for CFM EOAM (IEEE 802.1ag) dissection */
69 #define SENDER_ID_TLV 0x01
70 #define PORT_STAT_TLV 0x02
72 #define INTERF_STAT_TLV 0x04
73 #define REPLY_ING_TLV 0x05
74 #define REPLY_EGR_TLV 0x06
75 #define LTM_EGR_ID_TLV 0x07
76 #define LTR_EGR_ID_TLV 0x08
77 #define ORG_SPEC_TLV 0x1F
80 static int proto_cfm = -1;
82 static const value_string opcodetypenames[] = {
83 { IEEE8021, "Reserved for IEEE 802.1" },
84 { CCM, "Continuity Check Message (CCM)" },
85 { LBR, "Loopback Reply (LBR)" },
86 { LBM, "Loopback Message (LBM)" },
87 { LTR, "Linktrace Reply (LTR)" },
88 { LTM, "Linktrace Message (LTM)" },
89 { AIS, "Alarm Indication Signal (AIS)" },
90 { LCK, "Lock Signal (LCK)" },
91 { TST, "Test Signal (TST)" },
92 { APS, "Automatic Protection Switching (APS)" },
93 { RAPS, "Ring-Automatic Protection Switching (R-APS)" },
94 { MCC, "Maintenance Communication Channel (MCC)" },
95 { LMM, "Loss Measurement Message (LMM)" },
96 { LMR, "Loss Measurement Reply (LMR)" },
97 { ODM, "One Way Delay Measurement (1DM)" },
98 { DMM, "Delay Measurement Message (DMM)" },
99 { DMR, "Delay Measurement Reply (DMR)" },
100 { EXM, "Experimental OAM Message (EXM)" },
101 { EXR, "Experimental OAM Reply (EXR)" },
102 { VSM, "Vendor Specific Message (VSM)" },
103 { VSR, "Vendor Specific Reply (VSR)" },
104 { SLM, "Synthetic Loss Message (SLM)"},
105 { SLR, "Synthetic Loss Reply (SLR))"},
108 static const value_string CCM_IntervalFieldEncoding[] = {
110 { 1, "Trans Int 3.33ms, max Lifetime 11.66ms, min Lifetime 10.83ms" },
111 { 2, "Trans Int 10ms, max Lifetime 35ms, min Lifetime 32.5ms" },
112 { 3, "Trans Int 100ms, max Lifetime 350ms, min Lifetime 325ms" },
113 { 4, "Trans Int 1s, max Lifetime 3.5s, min Lifetime 3.25s" },
114 { 5, "Trans Int 10s, max Lifetime 35s, min Lifetime 32.5s" },
115 { 6, "Trans Int 1min, max Lifetime 3.5min, min Lifetime 3.25min" },
116 { 7, "Trans Int 10min, max Lifetime 35min, min Lifetime 32.5min" },
119 static const value_string mdnameformattypes[] = {
120 { 0, "Reserved for IEEE 802.1" },
121 { 1, "No Maintenance Domain Name preset" },
122 { 2, "RFC1035 DNS Name" },
123 { 3, "MAC address + 2-octet integer" },
124 { 4, "Character String" },
127 static const value_string manameformattypes[] = {
128 { 0, "Reserved for IEEE 802.1" },
129 { 1, "Primary VID" },
130 { 2, "Character String" },
131 { 3, "2-octet integer" },
132 { 4, "RFC 2685 VPN ID" },
133 { 32, "ICC-based Format" },
136 static const value_string relayactiontypes[] = {
142 static const value_string aislckperiodtypes[] = {
143 { 0, "Invalid Value for AIS/LCK PDU's" },
144 { 1, "Invalid Value for AIS/LCK PDU's" },
145 { 2, "Invalid Value for AIS/LCK PDU's" },
146 { 3, "Invalid Value for AIS/LCK PDU's" },
147 { 4, "1 frame per second" },
148 { 5, "Invalid Value for AIS/LCK PDU's" },
149 { 6, "1 frame per minute" },
150 { 7, "Invalid Value for AIS/LCK PDU's" },
153 static const value_string tlvtypefieldvalues[] = {
154 { END_TLV , "End TLV" },
155 { SENDER_ID_TLV , "Sender ID TLV" },
156 { PORT_STAT_TLV , "Port Status TLV" },
157 { DATA_TLV , "Data TLV" },
158 { INTERF_STAT_TLV , "Interface Status TLV" },
159 { REPLY_ING_TLV , "Reply Ingress TLV" },
160 { REPLY_EGR_TLV , "Reply Egress TLV" },
161 { LTM_EGR_ID_TLV , "LTM Egress Identifier TLV" },
162 { LTR_EGR_ID_TLV , "LTR Egress Identifier TLV" },
163 { ORG_SPEC_TLV , "Organizational-Specific TLV" },
164 { TEST_TLV , "Test TLV" },
167 static const value_string portstatTLVvalues[] = {
172 static const value_string interfacestatTLVvalues[] = {
178 { 6, "isNotPresent" },
179 { 7, "isLowerLayerDown" },
182 static const value_string replyingressTLVvalues[] = {
189 static const value_string replyegressTLVvalues[] = {
196 static const value_string testTLVpatterntypes[] = {
197 { 0, "Null signal without CRC-32" },
198 { 1, "Null signal with CRC-32" },
199 { 2, "PRBS (2.e-31 -1), without CRC-32" },
200 { 3, "PRBS (2.e-31 -1), with CRC-32" },
203 static const value_string rapsrequeststatevalues[] = {
205 { 11, "Signal Failure" },
208 static const value_string rapsrplblockedvalues[] = {
209 { 0, "Not Blocked" },
213 static const value_string rapsdnfvalues[] = {
215 { 1, "Do Not Flush DB" },
220 static int hf_cfm_md_level = -1;
221 static int hf_cfm_version = -1;
222 static int hf_cfm_opcode = -1;
224 static int hf_cfm_flags = -1;
225 static int hf_cfm_flags_RDI = -1;
226 static int hf_cfm_flags_ccm_Reserved = -1;
227 static int hf_cfm_flags_Interval = -1;
228 static int hf_cfm_flags_UseFDBonly = -1;
229 static int hf_cfm_flags_ltm_Reserved = -1;
230 static int hf_cfm_flags_ltr_Reserved = -1;
231 static int hf_cfm_flags_FwdYes = -1;
232 static int hf_cfm_flags_TerminalMEP = -1;
233 static int hf_cfm_first_tlv_offset = -1;
235 static int hf_cfm_ccm_pdu = -1;
236 static int hf_cfm_ccm_seq_number = -1;
237 static int hf_cfm_ccm_ma_ep_id = -1;
238 static int hf_cfm_ccm_maid = -1;
239 static int hf_cfm_maid_md_name_format = -1;
240 static int hf_cfm_maid_md_name_length = -1;
241 static int hf_cfm_maid_md_name_string = -1;
242 static int hf_cfm_maid_md_name_hex = -1;
243 static int hf_cfm_maid_md_name_mac = -1;
244 static int hf_cfm_maid_md_name_mac_id = -1;
245 static int hf_cfm_maid_ma_name_format = -1;
246 static int hf_cfm_maid_ma_name_length = -1;
247 static int hf_cfm_maid_ma_name_string = -1;
248 static int hf_cfm_maid_ma_name_hex = -1;
249 static int hf_cfm_maid_padding = -1;
250 static int hf_cfm_ccm_itu_t_y1731 = -1;
251 static int hf_cfm_itu_TxFCf = -1;
252 static int hf_cfm_itu_RxFCb = -1;
253 static int hf_cfm_itu_TxFCb = -1;
254 static int hf_cfm_itu_reserved = -1;
256 static int hf_cfm_lbm_pdu = -1;
257 static int hf_cfm_lb_transaction_id = -1;
259 static int hf_cfm_lbr_pdu = -1;
261 static int hf_cfm_ltm_pdu = -1;
262 static int hf_cfm_lt_transaction_id = -1;
263 static int hf_cfm_lt_ttl = -1;
264 static int hf_cfm_ltm_orig_addr = -1;
265 static int hf_cfm_ltm_targ_addr = -1;
267 static int hf_cfm_ltr_pdu = -1;
268 static int hf_cfm_ltr_relay_action = -1;
270 static int hf_cfm_ais_pdu = -1;
271 static int hf_cfm_flags_ais_lck_Reserved = -1;
272 static int hf_cfm_flags_ais_lck_Period = -1;
274 static int hf_cfm_lck_pdu = -1;
276 static int hf_cfm_tst_pdu = -1;
277 static int hf_cfm_flags_Reserved = -1;
278 static int hf_cfm_tst_sequence_num = -1;
280 static int hf_cfm_aps_pdu = -1;
281 static int hf_cfm_aps_data = -1;
283 static int hf_cfm_raps_pdu = -1;
284 static int hf_cfm_raps_req_st = -1;
285 static int hf_cfm_raps_flags = -1;
286 static int hf_cfm_raps_flags_rb = -1;
287 static int hf_cfm_raps_flags_dnf = -1;
288 static int hf_cfm_raps_node_id = -1;
289 static int hf_cfm_raps_reserved = -1;
291 static int hf_cfm_mcc_pdu = -1;
292 static int hf_cfm_mcc_data = -1;
294 static int hf_cfm_lmm_pdu = -1;
295 static int hf_cfm_lmr_pdu = -1;
296 static int hf_cfm_lmm_lmr_TxFCf = -1;
297 static int hf_cfm_lmm_lmr_RxFCf = -1;
298 static int hf_cfm_lmm_lmr_TxFCb = -1;
300 static int hf_cfm_odm_pdu = -1;
301 static int hf_cfm_odm_dmm_dmr_TxTimestampf = -1;
302 static int hf_cfm_odm_dmm_dmr_RxTimestampf = -1;
304 static int hf_cfm_dmm_pdu = -1;
305 static int hf_cfm_dmr_pdu = -1;
306 static int hf_cfm_dmm_dmr_TxTimestampb = -1;
307 static int hf_cfm_dmm_dmr_RxTimestampb = -1;
309 static int hf_cfm_exm_pdu = -1;
310 static int hf_cfm_exr_pdu = -1;
311 static int hf_cfm_exm_exr_data = -1;
313 static int hf_cfm_vsm_pdu = -1;
314 static int hf_cfm_vsr_pdu = -1;
315 static int hf_cfm_vsm_vsr_data = -1;
317 static int hf_cfm_slm_pdu = -1;
318 static int hf_cfm_slr_pdu = -1;
319 static int hf_cfm_slm_src_mep = -1;
320 static int hf_cfm_slr_rsp_mep = -1;
321 static int hf_cfm_slm_testid = -1;
322 static int hf_cfm_slm_txfcf = -1;
323 static int hf_cfm_slr_txfcb = -1;
325 static int hf_cfm_all_tlvs = -1;
326 static int hf_cfm_tlv_type = -1;
327 static int hf_cfm_tlv_length = -1;
328 static int hf_tlv_chassis_id_length = -1;
329 static int hf_tlv_chassis_id_subtype = -1;
330 static int hf_tlv_chassis_id = -1;
331 static int hf_tlv_ma_domain_length = -1;
332 static int hf_tlv_ma_domain = -1;
333 static int hf_tlv_management_addr_length = -1;
334 static int hf_tlv_management_addr = -1;
335 static int hf_tlv_port_status_value = -1;
336 static int hf_tlv_data_value = -1;
337 static int hf_tlv_interface_status_value = -1;
339 static int hf_tlv_reply_ingress_action = -1;
340 static int hf_tlv_reply_ingress_mac_address = -1;
341 static int hf_tlv_reply_ing_egr_portid_length = -1;
342 static int hf_tlv_reply_ing_egr_portid_subtype = -1;
343 static int hf_tlv_reply_ing_egr_portid = -1;
344 static int hf_tlv_reply_egress_action = -1;
345 static int hf_tlv_reply_egress_mac_address = -1;
346 static int hf_tlv_ltr_egress_last_id_mac = -1;
347 static int hf_tlv_ltr_egress_last_id_unique_identifier = -1;
348 static int hf_tlv_ltr_egress_next_id_mac = -1;
349 static int hf_tlv_ltr_egress_next_id_unique_identifier = -1;
350 static int hf_tlv_ltm_egress_id_mac = -1;
351 static int hf_tlv_ltm_egress_id_unique_identifier = -1;
352 static int hf_tlv_org_spec_oui = -1;
353 static int hf_tlv_org_spec_subtype = -1;
354 static int hf_tlv_org_spec_value = -1;
355 static int hf_tlv_tst_test_pattern_type = -1;
356 static int hf_tlv_tst_test_pattern = -1;
357 static int hf_tlv_tst_CRC32 = -1;
359 static gint ett_cfm = -1;
360 static gint ett_cfm_flags = -1;
361 static gint ett_cfm_ccm_maid = -1;
362 static gint ett_cfm_ccm_itu = -1;
363 static gint ett_cfm_pdu = -1;
364 static gint ett_cfm_all_tlvs = -1;
365 static gint ett_cfm_tlv = -1;
366 static gint ett_cfm_raps_flags = -1;
368 /* CFM EOAM sub-protocol dissectors: CCM, LBM, LBR, LTM, LTR */
369 static int dissect_cfm_ccm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
374 guint8 cfm_maid_md_name_format;
375 guint8 cfm_maid_ma_name_format;
376 guint8 cfm_maid_ma_name_length;
382 proto_tree *cfm_pdu_tree;
383 proto_tree *cfm_flag_tree;
384 proto_tree *cfm_ccm_maid_tree;
385 proto_tree *cfm_ccm_itu_tree;
388 ti = proto_tree_add_item(tree, hf_cfm_ccm_pdu, tvb, offset, -1, ENC_NA);
389 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
391 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
392 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
393 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_RDI, tvb, offset, 1, ENC_BIG_ENDIAN);
394 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_ccm_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
395 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Interval, tvb, offset, 1, ENC_BIG_ENDIAN);
398 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
400 proto_tree_add_item(cfm_pdu_tree, hf_cfm_ccm_seq_number, tvb, offset, 4, ENC_BIG_ENDIAN);
402 proto_tree_add_item(cfm_pdu_tree, hf_cfm_ccm_ma_ep_id, tvb, offset, 2, ENC_BIG_ENDIAN);
405 /* dissect CCM MAID */
406 mi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_ccm_maid, tvb, offset, 48, ENC_NA);
407 cfm_ccm_maid_tree = proto_item_add_subtree(mi, ett_cfm_ccm_maid);
408 maid_offset = offset;
409 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_md_name_format, tvb, maid_offset, 1, ENC_BIG_ENDIAN);
410 cfm_maid_md_name_format = tvb_get_guint8(tvb, maid_offset);
412 if (cfm_maid_md_name_format != 1) {
413 guint8 cfm_maid_md_name_length;
414 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_md_name_length,
415 tvb, maid_offset, 1, ENC_BIG_ENDIAN);
416 cfm_maid_md_name_length = tvb_get_guint8(tvb, maid_offset);
418 if (cfm_maid_md_name_length) {
419 if (cfm_maid_md_name_format == 3) {
420 /* MD name format is MAC + 2 octet id */
421 if (cfm_maid_md_name_length != 8) {
422 /* the MD name of type MAC should be 8 octets but if
423 * it isn't we are going to try and process it anyways.*/
424 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_md_name_hex,
425 tvb, maid_offset, cfm_maid_md_name_length, ENC_NA);
427 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_md_name_mac,
428 tvb, maid_offset, 6, ENC_NA);
429 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_md_name_mac_id,
430 tvb, maid_offset+6, 2, ENC_NA);
433 /* MD name format is regular string or DNS string */
434 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_md_name_string,
435 tvb, maid_offset, cfm_maid_md_name_length, ENC_ASCII|ENC_NA);
437 maid_offset += cfm_maid_md_name_length;
440 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_ma_name_format, tvb, maid_offset, 1, ENC_BIG_ENDIAN);
441 cfm_maid_ma_name_format = tvb_get_guint8(tvb, maid_offset);
443 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_ma_name_length, tvb, maid_offset, 1, ENC_BIG_ENDIAN);
444 cfm_maid_ma_name_length = tvb_get_guint8(tvb, maid_offset);
446 if ((cfm_maid_ma_name_format == 2) ||
447 (cfm_maid_ma_name_format == 32)) {
448 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_ma_name_string,
449 tvb, maid_offset, cfm_maid_ma_name_length, ENC_ASCII|ENC_NA);
451 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_ma_name_hex,
452 tvb, maid_offset, cfm_maid_ma_name_length, ENC_NA);
454 maid_offset += cfm_maid_ma_name_length;
456 if (offset > maid_offset) {
458 padding_length = offset - maid_offset;
459 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_padding,
460 tvb, maid_offset, padding_length, ENC_NA);
463 /* Dissect 16 octets reserved for Y.1731, samples of the wrap-around frame counters */
464 wi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_ccm_itu_t_y1731, tvb, offset, 16, ENC_NA);
465 cfm_ccm_itu_tree = proto_item_add_subtree(wi, ett_cfm_ccm_itu);
467 proto_tree_add_item(cfm_ccm_itu_tree, hf_cfm_itu_TxFCf, tvb, itu_offset, 4, ENC_NA);
469 proto_tree_add_item(cfm_ccm_itu_tree, hf_cfm_itu_RxFCb, tvb, itu_offset, 4, ENC_NA);
471 proto_tree_add_item(cfm_ccm_itu_tree, hf_cfm_itu_TxFCb, tvb, itu_offset, 4, ENC_NA);
473 proto_tree_add_item(cfm_ccm_itu_tree, hf_cfm_itu_reserved, tvb, itu_offset, 4, ENC_NA);
480 static int dissect_cfm_lbm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
483 proto_tree *cfm_pdu_tree;
485 ti = proto_tree_add_item(tree, hf_cfm_lbm_pdu, tvb, offset, -1, ENC_NA);
486 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
488 proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
490 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
492 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lb_transaction_id, tvb, offset, 4, ENC_BIG_ENDIAN);
497 static int dissect_cfm_lbr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
500 proto_tree *cfm_pdu_tree;
502 ti = proto_tree_add_item(tree, hf_cfm_lbr_pdu, tvb, offset, -1, ENC_NA);
503 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
505 proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
507 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
509 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lb_transaction_id, tvb, offset, 4, ENC_BIG_ENDIAN);
514 static int dissect_cfm_ltm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
518 proto_tree *cfm_pdu_tree;
519 proto_tree *cfm_flag_tree;
521 ti = proto_tree_add_item(tree, hf_cfm_ltm_pdu, tvb, offset, -1, ENC_NA);
522 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
524 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
525 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
526 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_UseFDBonly, tvb, offset, 1, ENC_BIG_ENDIAN);
527 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_ltm_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
530 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
532 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lt_transaction_id, tvb, offset, 4, ENC_BIG_ENDIAN);
534 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lt_ttl, tvb, offset, 1, ENC_BIG_ENDIAN);
536 proto_tree_add_item(cfm_pdu_tree, hf_cfm_ltm_orig_addr, tvb, offset, 6, ENC_NA);
538 proto_tree_add_item(cfm_pdu_tree, hf_cfm_ltm_targ_addr, tvb, offset, 6, ENC_NA);
543 static int dissect_cfm_ltr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
547 proto_tree *cfm_pdu_tree;
548 proto_tree *cfm_flag_tree;
550 ti = proto_tree_add_item(tree, hf_cfm_ltr_pdu, tvb, offset, -1, ENC_NA);
551 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
553 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
554 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
555 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_UseFDBonly, tvb, offset, 1, ENC_BIG_ENDIAN);
556 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_FwdYes, tvb, offset, 1, ENC_BIG_ENDIAN);
557 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_TerminalMEP, tvb, offset, 1, ENC_BIG_ENDIAN);
558 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_ltr_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
561 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
563 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lt_transaction_id, tvb, offset, 4, ENC_BIG_ENDIAN);
565 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lt_ttl, tvb, offset, 1, ENC_BIG_ENDIAN);
567 proto_tree_add_item(cfm_pdu_tree, hf_cfm_ltr_relay_action, tvb, offset, 1, ENC_BIG_ENDIAN);
572 static int dissect_cfm_ais(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
576 proto_tree *cfm_pdu_tree;
577 proto_tree *cfm_flag_tree;
579 ti = proto_tree_add_item(tree, hf_cfm_ais_pdu, tvb, offset, -1, ENC_NA);
580 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
582 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
583 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
584 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_ais_lck_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
585 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_ais_lck_Period, tvb, offset, 1, ENC_BIG_ENDIAN);
588 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
594 static int dissect_cfm_lck(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
598 proto_tree *cfm_pdu_tree;
599 proto_tree *cfm_flag_tree;
601 ti = proto_tree_add_item(tree, hf_cfm_lck_pdu, tvb, offset, -1, ENC_NA);
602 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
604 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
605 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
606 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_ais_lck_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
607 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_ais_lck_Period, tvb, offset, 1, ENC_BIG_ENDIAN);
610 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
616 static int dissect_cfm_tst(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
620 proto_tree *cfm_pdu_tree;
621 proto_tree *cfm_flag_tree;
623 ti = proto_tree_add_item(tree, hf_cfm_tst_pdu, tvb, offset, -1, ENC_NA);
624 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
626 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
627 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
628 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
631 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
634 proto_tree_add_item(cfm_pdu_tree, hf_cfm_tst_sequence_num, tvb, offset, 4, ENC_BIG_ENDIAN);
640 static int dissect_cfm_aps(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
645 proto_tree *cfm_pdu_tree;
646 proto_tree *cfm_flag_tree;
648 ti = proto_tree_add_item(tree, hf_cfm_aps_pdu, tvb, offset, -1, ENC_NA);
649 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
651 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
652 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
653 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
656 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
659 /* The APS data field was not defined at the time of this code being written
660 * ITU-T Y.1731 (05/2006), so we are simply going to determine the length based on
661 * the TLV offset and perform a hex dump */
662 cfm_tlv_offset = tvb_get_guint8(tvb, 3);
663 if (cfm_tlv_offset > 0) {
664 proto_tree_add_item(cfm_pdu_tree, hf_cfm_aps_data, tvb, offset, cfm_tlv_offset, ENC_NA);
665 offset += cfm_tlv_offset;
671 static int dissect_cfm_raps(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
676 proto_tree *cfm_pdu_tree;
677 proto_tree *cfm_flag_tree;
678 proto_tree *raps_flag_tree;
680 ti = proto_tree_add_item(tree, hf_cfm_raps_pdu, tvb, offset, -1, ENC_NA);
681 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
683 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
684 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
685 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
688 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
691 proto_tree_add_item(cfm_pdu_tree, hf_cfm_raps_req_st, tvb, offset, 1, ENC_BIG_ENDIAN);
694 ri = proto_tree_add_item(cfm_pdu_tree, hf_cfm_raps_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
695 raps_flag_tree = proto_item_add_subtree(ri, ett_cfm_raps_flags);
696 proto_tree_add_item(raps_flag_tree, hf_cfm_raps_flags_rb, tvb, offset, 1, ENC_BIG_ENDIAN);
697 proto_tree_add_item(raps_flag_tree, hf_cfm_raps_flags_dnf, tvb, offset, 1, ENC_BIG_ENDIAN);
700 proto_tree_add_item(cfm_pdu_tree, hf_cfm_raps_node_id, tvb, offset, 6, ENC_NA);
703 proto_tree_add_item(cfm_pdu_tree, hf_cfm_raps_reserved, tvb, offset, 24, ENC_NA);
709 static int dissect_cfm_mcc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
714 proto_tree *cfm_pdu_tree;
715 proto_tree *cfm_flag_tree;
717 ti = proto_tree_add_item(tree, hf_cfm_mcc_pdu, tvb, offset, -1, ENC_NA);
718 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
720 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
721 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
722 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
725 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
728 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_oui, tvb, offset, 3, ENC_NA);
730 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_subtype, tvb, offset, 1, ENC_NA);
733 /* The MCC data field was not defined at the time of this code being written
734 * ITU-T Y.1731 (05/2006), so we are simply going to determine the length based on
735 * the TLV offset and perform a hex dump */
736 cfm_tlv_offset = tvb_get_guint8(tvb, 3);
737 /* Remove OUI and subtype from the offset */
739 if (cfm_tlv_offset > 0) {
740 proto_tree_add_item(cfm_pdu_tree, hf_cfm_mcc_data, tvb, offset, cfm_tlv_offset, ENC_NA);
741 offset += cfm_tlv_offset;
747 static int dissect_cfm_lmm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
751 proto_tree *cfm_pdu_tree;
752 proto_tree *cfm_flag_tree;
754 ti = proto_tree_add_item(tree, hf_cfm_lmm_pdu, tvb, offset, -1, ENC_NA);
755 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
757 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
758 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
759 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
762 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
765 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lmm_lmr_TxFCf, tvb, offset, 4, ENC_NA);
767 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lmm_lmr_RxFCf, tvb, offset, 4, ENC_NA);
769 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lmm_lmr_TxFCb, tvb, offset, 4, ENC_NA);
775 static int dissect_cfm_lmr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
779 proto_tree *cfm_pdu_tree;
780 proto_tree *cfm_flag_tree;
782 ti = proto_tree_add_item(tree, hf_cfm_lmr_pdu, tvb, offset, -1, ENC_NA);
783 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
785 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
786 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
787 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
790 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
793 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lmm_lmr_TxFCf, tvb, offset, 4, ENC_NA);
795 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lmm_lmr_RxFCf, tvb, offset, 4, ENC_NA);
797 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lmm_lmr_TxFCb, tvb, offset, 4, ENC_NA);
803 static int dissect_cfm_odm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
807 proto_tree *cfm_pdu_tree;
808 proto_tree *cfm_flag_tree;
810 ti = proto_tree_add_item(tree, hf_cfm_odm_pdu, tvb, offset, -1, ENC_NA);
811 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
813 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
814 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
815 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
818 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
821 proto_tree_add_item(cfm_pdu_tree, hf_cfm_odm_dmm_dmr_TxTimestampf, tvb, offset, 8, ENC_NA);
823 proto_tree_add_item(cfm_pdu_tree, hf_cfm_odm_dmm_dmr_RxTimestampf, tvb, offset, 8, ENC_NA);
829 static int dissect_cfm_dmm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
833 proto_tree *cfm_pdu_tree;
834 proto_tree *cfm_flag_tree;
836 ti = proto_tree_add_item(tree, hf_cfm_dmm_pdu, tvb, offset, -1, ENC_NA);
837 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
839 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
840 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
841 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
844 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
847 proto_tree_add_item(cfm_pdu_tree, hf_cfm_odm_dmm_dmr_TxTimestampf, tvb, offset, 8, ENC_NA);
849 proto_tree_add_item(cfm_pdu_tree, hf_cfm_odm_dmm_dmr_RxTimestampf, tvb, offset, 8, ENC_NA);
851 proto_tree_add_item(cfm_pdu_tree, hf_cfm_dmm_dmr_TxTimestampb, tvb, offset, 8, ENC_NA);
853 proto_tree_add_item(cfm_pdu_tree, hf_cfm_dmm_dmr_RxTimestampb, tvb, offset, 8, ENC_NA);
859 static int dissect_cfm_dmr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
863 proto_tree *cfm_pdu_tree;
864 proto_tree *cfm_flag_tree;
866 ti = proto_tree_add_item(tree, hf_cfm_dmr_pdu, tvb, offset, -1, ENC_NA);
867 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
869 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
870 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
871 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
874 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
877 proto_tree_add_item(cfm_pdu_tree, hf_cfm_odm_dmm_dmr_TxTimestampf, tvb, offset, 8, ENC_NA);
879 proto_tree_add_item(cfm_pdu_tree, hf_cfm_odm_dmm_dmr_RxTimestampf, tvb, offset, 8, ENC_NA);
881 proto_tree_add_item(cfm_pdu_tree, hf_cfm_dmm_dmr_TxTimestampb, tvb, offset, 8, ENC_NA);
883 proto_tree_add_item(cfm_pdu_tree, hf_cfm_dmm_dmr_RxTimestampb, tvb, offset, 8, ENC_NA);
889 static int dissect_cfm_exm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
894 proto_tree *cfm_pdu_tree;
895 proto_tree *cfm_flag_tree;
897 ti = proto_tree_add_item(tree, hf_cfm_exm_pdu, tvb, offset, -1, ENC_NA);
898 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
900 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
901 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
902 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
905 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
908 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_oui, tvb, offset, 3, ENC_NA);
910 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_subtype, tvb, offset, 1, ENC_NA);
913 /* The EXM data field was not defined at the time of this code being written
914 * ITU-T Y.1731 (05/2006), so we are simply going to determine the length based on
915 * the TLV offset and perform a hex dump */
916 cfm_tlv_offset = tvb_get_guint8(tvb, 3);
917 /* Remove OUI and subtype from the offset */
919 if (cfm_tlv_offset > 0) {
920 proto_tree_add_item(cfm_pdu_tree, hf_cfm_exm_exr_data, tvb, offset, cfm_tlv_offset, ENC_NA);
921 offset += cfm_tlv_offset;
927 static int dissect_cfm_exr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
932 proto_tree *cfm_pdu_tree;
933 proto_tree *cfm_flag_tree;
935 ti = proto_tree_add_item(tree, hf_cfm_exr_pdu, tvb, offset, -1, ENC_NA);
936 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
938 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
939 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
940 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
943 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
946 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_oui, tvb, offset, 3, ENC_NA);
948 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_subtype, tvb, offset, 1, ENC_NA);
951 /* The EXR data field was not defined at the time of this code being written
952 * ITU-T Y.1731 (05/2006), so we are simply going to determine the length based on
953 * the TLV offset and perform a hex dump */
954 cfm_tlv_offset = tvb_get_guint8(tvb, 3);
955 /* Remove OUI and subtype from the offset */
957 if (cfm_tlv_offset > 0) {
958 proto_tree_add_item(cfm_pdu_tree, hf_cfm_exm_exr_data, tvb, offset, cfm_tlv_offset, ENC_NA);
959 offset += cfm_tlv_offset;
965 static int dissect_cfm_vsm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
970 proto_tree *cfm_pdu_tree;
971 proto_tree *cfm_flag_tree;
973 ti = proto_tree_add_item(tree, hf_cfm_vsm_pdu, tvb, offset, -1, ENC_NA);
974 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
976 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
977 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
978 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
981 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
984 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_oui, tvb, offset, 3, ENC_NA);
986 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_subtype, tvb, offset, 1, ENC_NA);
989 /* The VSM data field was not defined at the time of this code being written
990 * ITU-T Y.1731 (05/2006), so we are simply going to determine the length based on
991 * the TLV offset and perform a hex dump */
992 cfm_tlv_offset = tvb_get_guint8(tvb, 3);
993 /* Remove OUI and subtype from the offset */
995 if (cfm_tlv_offset > 0) {
996 proto_tree_add_item(cfm_pdu_tree, hf_cfm_vsm_vsr_data, tvb, offset, cfm_tlv_offset, ENC_NA);
997 offset += cfm_tlv_offset;
1003 static int dissect_cfm_vsr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1005 gint cfm_tlv_offset;
1008 proto_tree *cfm_pdu_tree;
1009 proto_tree *cfm_flag_tree;
1011 ti = proto_tree_add_item(tree, hf_cfm_vsr_pdu, tvb, offset, -1, ENC_NA);
1012 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
1014 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
1015 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
1016 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
1019 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
1022 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_oui, tvb, offset, 3, ENC_NA);
1024 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_subtype, tvb, offset, 1, ENC_NA);
1027 /* The VSR data field was not defined at the time of this code being written
1028 * ITU-T Y.1731 (05/2006), so we are simply going to determine the length based on
1029 * the TLV offset and perform a hex dump */
1030 cfm_tlv_offset = tvb_get_guint8(tvb, 3);
1031 /* Remove OUI and subtype from the offset */
1032 cfm_tlv_offset -= 4;
1033 if (cfm_tlv_offset > 0) {
1034 proto_tree_add_item(cfm_pdu_tree, hf_cfm_vsm_vsr_data, tvb, offset, cfm_tlv_offset, ENC_NA);
1035 offset += cfm_tlv_offset;
1041 static int dissect_cfm_slm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1045 proto_tree *cfm_pdu_tree;
1046 proto_tree *cfm_flag_tree;
1048 ti = proto_tree_add_item(tree, hf_cfm_slm_pdu, tvb, offset, -1, ENC_NA);
1049 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
1051 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
1052 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
1053 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
1056 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
1059 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slm_src_mep, tvb, offset, 2, ENC_NA);
1061 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slr_rsp_mep, tvb, offset, 2, ENC_NA);
1063 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slm_testid, tvb, offset, 4, ENC_NA);
1065 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slm_txfcf, tvb, offset, 4, ENC_BIG_ENDIAN);
1067 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slr_txfcb, tvb, offset, 4, ENC_BIG_ENDIAN);
1073 static int dissect_cfm_slr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1077 proto_tree *cfm_pdu_tree;
1078 proto_tree *cfm_flag_tree;
1080 ti = proto_tree_add_item(tree, hf_cfm_slr_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_BIG_ENDIAN);
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_BIG_ENDIAN);
1088 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
1091 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slm_src_mep, tvb, offset, 2, ENC_NA);
1093 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slr_rsp_mep, tvb, offset, 2, ENC_NA);
1095 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slm_testid, tvb, offset, 4, ENC_NA);
1097 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slm_txfcf, tvb, offset, 4, ENC_BIG_ENDIAN);
1099 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slr_txfcb, tvb, offset, 4, ENC_BIG_ENDIAN);
1106 /* Main CFM EOAM protocol dissector */
1107 static void dissect_cfm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1110 guint8 cfm_pdu_type;
1112 /* display the CFM protol name */
1113 col_set_str(pinfo->cinfo, COL_PROTOCOL, "CFM");
1115 /* Clear out stuff in the info column */
1116 col_clear(pinfo->cinfo, COL_INFO);
1118 /* provide info column with CFM packet type (opcode)*/
1119 cfm_pdu_type = tvb_get_guint8(tvb, 1);
1121 col_add_fstr(pinfo->cinfo, COL_INFO, "Type %s",
1122 val_to_str(cfm_pdu_type, opcodetypenames, "Unknown (0x%02x)"));
1124 if (tree) { /* we are being asked for details */
1125 gint cfm_tlv_offset;
1127 proto_tree *cfm_tree;
1129 /* isolate the payload of the packet */
1130 ti = proto_tree_add_item(tree, proto_cfm, tvb, 0, -1, ENC_BIG_ENDIAN);
1133 /* report type of CFM packet to base of dissection tree */
1134 proto_item_append_text(ti, ", Type %s",
1135 val_to_str(cfm_pdu_type, opcodetypenames, "Unknown (0x%02x)"));
1137 /* dissecting the common CFM header */
1138 cfm_tree = proto_item_add_subtree(ti, ett_cfm);
1139 proto_tree_add_item(cfm_tree, hf_cfm_md_level, tvb, offset, 1, ENC_BIG_ENDIAN);
1140 proto_tree_add_item(cfm_tree, hf_cfm_version, tvb, offset, 1, ENC_BIG_ENDIAN);
1142 proto_tree_add_item(cfm_tree, hf_cfm_opcode, tvb, offset, 1, ENC_BIG_ENDIAN);
1145 switch(cfm_pdu_type) {
1147 offset = dissect_cfm_ccm(tvb, pinfo, tree, offset);
1150 offset = dissect_cfm_lbm(tvb, pinfo, tree, offset);
1153 offset = dissect_cfm_lbr(tvb, pinfo, tree, offset);
1156 offset = dissect_cfm_ltm(tvb, pinfo, tree, offset);
1159 offset = dissect_cfm_ltr(tvb, pinfo, tree, offset);
1162 offset = dissect_cfm_ais(tvb, pinfo, tree, offset);
1165 offset = dissect_cfm_lck(tvb, pinfo, tree, offset);
1168 offset = dissect_cfm_tst(tvb, pinfo, tree, offset);
1171 offset = dissect_cfm_aps(tvb, pinfo, tree, offset);
1174 offset = dissect_cfm_raps(tvb, pinfo, tree, offset);
1177 offset = dissect_cfm_mcc(tvb, pinfo, tree, offset);
1180 offset = dissect_cfm_lmm(tvb, pinfo, tree, offset);
1183 offset = dissect_cfm_lmr(tvb, pinfo, tree, offset);
1186 offset = dissect_cfm_odm(tvb, pinfo, tree, offset);
1189 offset = dissect_cfm_dmm(tvb, pinfo, tree, offset);
1192 offset = dissect_cfm_dmr(tvb, pinfo, tree, offset);
1195 offset = dissect_cfm_exm(tvb, pinfo, tree, offset);
1198 offset = dissect_cfm_exr(tvb, pinfo, tree, offset);
1201 offset = dissect_cfm_vsm(tvb, pinfo, tree, offset);
1204 offset = dissect_cfm_vsr(tvb, pinfo, tree, offset);
1207 offset = dissect_cfm_slm(tvb, pinfo, tree, offset);
1210 offset = dissect_cfm_slr(tvb, pinfo, tree, offset);
1214 /* Get the TLV offset and add the offset of the common CFM header*/
1215 cfm_tlv_offset = tvb_get_guint8(tvb, 3);
1216 cfm_tlv_offset += 4;
1218 /* Begin dissecting the TLV's */
1219 /* the TLV offset should be the same as where the pdu left off or we have a problem */
1220 if ((cfm_tlv_offset == offset) && (cfm_tlv_offset > 3)) {
1221 proto_tree *cfm_all_tlvs_tree;
1222 guint8 cfm_tlv_type = 255;
1223 ti = proto_tree_add_item(tree, hf_cfm_all_tlvs, tvb, cfm_tlv_offset, -1, ENC_NA);
1224 cfm_all_tlvs_tree = proto_item_add_subtree(ti, ett_cfm_all_tlvs);
1226 while (cfm_tlv_type != END_TLV)
1228 guint16 cfm_tlv_length;
1229 gint tlv_header_modifier;
1231 proto_tree *cfm_tlv_tree;
1232 cfm_tlv_type = tvb_get_guint8(tvb, cfm_tlv_offset);
1234 if (cfm_tlv_type == END_TLV) {
1235 tlv_header_modifier = 1;
1238 tlv_header_modifier = 3;
1239 cfm_tlv_length = tvb_get_ntohs(tvb, cfm_tlv_offset+1);
1242 fi = proto_tree_add_text(cfm_all_tlvs_tree, tvb, cfm_tlv_offset, cfm_tlv_length+tlv_header_modifier,
1243 "TLV: %s (t=%d,l=%d)", val_to_str(cfm_tlv_type, tlvtypefieldvalues, "Unknown (0x%02x)"),
1244 cfm_tlv_type, cfm_tlv_length);
1245 cfm_tlv_tree = proto_item_add_subtree(fi, ett_cfm_tlv);
1247 proto_tree_add_item(cfm_tlv_tree, hf_cfm_tlv_type, tvb, cfm_tlv_offset, 1, ENC_BIG_ENDIAN);
1248 cfm_tlv_offset += 1;
1249 if (cfm_tlv_type != END_TLV) {
1250 proto_tree_add_item(cfm_tlv_tree, hf_cfm_tlv_length, tvb, cfm_tlv_offset, 2, ENC_BIG_ENDIAN);
1251 cfm_tlv_offset += 2;
1253 if (cfm_tlv_length != 0) {
1254 gint tlv_data_offset;
1255 guint8 tlv_chassis_id_length;
1256 guint8 tlv_tst_test_pattern_type;
1258 tlv_data_offset = cfm_tlv_offset;
1260 switch(cfm_tlv_type) {
1262 proto_tree_add_item(cfm_tlv_tree, hf_tlv_chassis_id_length,
1263 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1264 tlv_chassis_id_length = tvb_get_guint8(tvb,tlv_data_offset);
1265 tlv_data_offset += 1;
1267 if (tlv_chassis_id_length > 0) {
1268 proto_tree_add_item(cfm_tlv_tree, hf_tlv_chassis_id_subtype,
1269 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1270 tlv_data_offset += 1;
1271 proto_tree_add_item(cfm_tlv_tree, hf_tlv_chassis_id,
1272 tvb, tlv_data_offset, tlv_chassis_id_length, ENC_NA);
1273 tlv_data_offset += tlv_chassis_id_length;
1276 /* If the TLV length is greater than the number of octets used for the
1277 * Chassis ID, then we must have a Management Address Domain */
1278 if (cfm_tlv_length > (2 + tlv_chassis_id_length)) {
1279 guint8 tlv_ma_domain_length;
1280 proto_tree_add_item(cfm_tlv_tree, hf_tlv_ma_domain_length,
1281 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1282 tlv_ma_domain_length = tvb_get_guint8(tvb,tlv_data_offset);
1283 tlv_data_offset += 1;
1284 if (tlv_ma_domain_length > 0) {
1285 proto_tree_add_item(cfm_tlv_tree, hf_tlv_ma_domain,
1286 tvb, tlv_data_offset, tlv_ma_domain_length, ENC_NA);
1287 tlv_data_offset += tlv_ma_domain_length;
1290 /* If the TLV length is greater than the number of octets used for the
1291 * Chassis ID and the Management Address Domain, then we must have a
1292 * Management Address */
1293 if (cfm_tlv_length > (2 + tlv_chassis_id_length + 1 + tlv_ma_domain_length)) {
1294 guint8 tlv_management_addr_length;
1295 proto_tree_add_item(cfm_tlv_tree, hf_tlv_management_addr_length,
1296 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1297 tlv_management_addr_length = tvb_get_guint8(tvb,tlv_data_offset);
1298 tlv_data_offset += 1;
1299 if (tlv_management_addr_length > 0) {
1300 proto_tree_add_item(cfm_tlv_tree, hf_tlv_management_addr,
1301 tvb, tlv_data_offset, tlv_management_addr_length, ENC_NA);
1302 tlv_data_offset += tlv_management_addr_length;
1308 proto_tree_add_item(cfm_tlv_tree, hf_tlv_port_status_value,
1309 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1310 tlv_data_offset += 1;
1313 proto_tree_add_item(cfm_tlv_tree, hf_tlv_data_value,
1314 tvb, tlv_data_offset, cfm_tlv_length, ENC_NA);
1315 tlv_data_offset += cfm_tlv_length;
1317 case INTERF_STAT_TLV:
1318 proto_tree_add_item(cfm_tlv_tree, hf_tlv_interface_status_value,
1319 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1320 tlv_data_offset += 1;
1323 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_ingress_action,
1324 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1325 tlv_data_offset += 1;
1326 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_ingress_mac_address,
1327 tvb, tlv_data_offset, 6, ENC_NA);
1328 tlv_data_offset += 6;
1330 /* For the IEEE standard if the TLV length is greater than 7 then we have
1331 * an ingress port ID
1333 if (cfm_tlv_length > 7) {
1334 guint8 tlv_reply_ingress_portid_length;
1335 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_ing_egr_portid_length,
1336 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1337 tlv_reply_ingress_portid_length = tvb_get_guint8(tvb,tlv_data_offset);
1338 tlv_data_offset += 1;
1340 if (tlv_reply_ingress_portid_length > 0) {
1341 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_ing_egr_portid_subtype,
1342 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1343 tlv_data_offset += 1;
1344 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_ing_egr_portid,
1345 tvb, tlv_data_offset, tlv_reply_ingress_portid_length, ENC_NA);
1346 tlv_data_offset += tlv_reply_ingress_portid_length;
1351 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_egress_action,
1352 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1353 tlv_data_offset += 1;
1354 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_egress_mac_address,
1355 tvb, tlv_data_offset, 6, ENC_NA);
1356 tlv_data_offset += 6;
1358 /* For the IEEE standard if the TLV length is greater than 7 then we have
1361 if (cfm_tlv_length > 7) {
1362 guint8 tlv_reply_egress_portid_length;
1363 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_ing_egr_portid_length,
1364 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1365 tlv_reply_egress_portid_length = tvb_get_guint8(tvb,tlv_data_offset);
1366 tlv_data_offset += 1;
1368 if (tlv_reply_egress_portid_length > 0) {
1369 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_ing_egr_portid_subtype,
1370 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1371 tlv_data_offset += 1;
1372 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_ing_egr_portid,
1373 tvb, tlv_data_offset, tlv_reply_egress_portid_length, ENC_NA);
1374 tlv_data_offset += tlv_reply_egress_portid_length;
1378 case LTM_EGR_ID_TLV:
1379 proto_tree_add_item(cfm_tlv_tree, hf_tlv_ltm_egress_id_unique_identifier,
1380 tvb, tlv_data_offset, 2, ENC_NA);
1381 tlv_data_offset += 2;
1382 proto_tree_add_item(cfm_tlv_tree, hf_tlv_ltm_egress_id_mac,
1383 tvb, tlv_data_offset, 6, ENC_NA);
1384 tlv_data_offset += 6;
1386 case LTR_EGR_ID_TLV:
1387 proto_tree_add_item(cfm_tlv_tree, hf_tlv_ltr_egress_last_id_unique_identifier,
1388 tvb, tlv_data_offset, 2, ENC_NA);
1389 tlv_data_offset += 2;
1390 proto_tree_add_item(cfm_tlv_tree, hf_tlv_ltr_egress_last_id_mac,
1391 tvb, tlv_data_offset, 6, ENC_NA);
1392 tlv_data_offset += 6;
1393 proto_tree_add_item(cfm_tlv_tree, hf_tlv_ltr_egress_next_id_unique_identifier,
1394 tvb, tlv_data_offset, 2, ENC_NA);
1395 tlv_data_offset += 2;
1396 proto_tree_add_item(cfm_tlv_tree, hf_tlv_ltr_egress_next_id_mac,
1397 tvb, tlv_data_offset, 6, ENC_NA);
1398 tlv_data_offset += 6;
1401 /* The TLV length must be long enough to include the OUI
1404 if (cfm_tlv_length > 3) {
1405 proto_tree_add_item(cfm_tlv_tree, hf_tlv_org_spec_oui,
1406 tvb, tlv_data_offset, 3, ENC_NA);
1407 tlv_data_offset += 3;
1408 proto_tree_add_item(cfm_tlv_tree, hf_tlv_org_spec_subtype,
1409 tvb, tlv_data_offset, 1, ENC_NA);
1410 tlv_data_offset += 1;
1411 proto_tree_add_item(cfm_tlv_tree, hf_tlv_org_spec_value,
1412 tvb, tlv_data_offset, cfm_tlv_length-4, ENC_NA);
1413 tlv_data_offset -= 4;
1415 tlv_data_offset += cfm_tlv_length;
1418 /* There is a discrepancy in the recommendation ITU-T Y.1731
1419 * where the test pattern type may or may not be included in
1420 * the TLV length. Going to assume that it is included in the
1421 * length which corresponds with the typical format for TLV's
1422 * until the recommendation is more clear in this regard. */
1423 proto_tree_add_item(cfm_tlv_tree, hf_tlv_tst_test_pattern_type,
1424 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1425 tlv_tst_test_pattern_type = tvb_get_guint8(tvb,tlv_data_offset);
1426 tlv_data_offset += 1;
1427 if (cfm_tlv_length > 0) {
1428 switch (tlv_tst_test_pattern_type) {
1431 proto_tree_add_item(cfm_tlv_tree, hf_tlv_tst_test_pattern,
1432 tvb, tlv_data_offset, cfm_tlv_length-1, ENC_NA);
1433 tlv_data_offset += cfm_tlv_length;
1437 proto_tree_add_item(cfm_tlv_tree, hf_tlv_tst_test_pattern,
1438 tvb, tlv_data_offset, cfm_tlv_length-5, ENC_NA);
1439 tlv_data_offset += (cfm_tlv_length-5);
1440 proto_tree_add_item(cfm_tlv_tree, hf_tlv_tst_CRC32,
1441 tvb, tlv_data_offset, 4, ENC_NA);
1442 tlv_data_offset += 4;
1450 cfm_tlv_offset += cfm_tlv_length;
1458 /* Register CFM EOAM protocol */
1459 void proto_register_cfm(void)
1461 static hf_register_info hf[] = {
1463 { "CFM MD Level", "cfm.md.level", FT_UINT8,
1464 BASE_DEC, NULL, 0xe0, NULL, HFILL }
1467 { "CFM Version", "cfm.version", FT_UINT8,
1468 BASE_DEC, NULL, 0x1f, NULL, HFILL }
1471 { "CFM OpCode", "cfm.opcode", FT_UINT8,
1472 BASE_DEC, VALS(opcodetypenames), 0x0, NULL, HFILL }
1477 { "CFM CCM PDU", "cfm.ccm.pdu", FT_NONE,
1478 BASE_NONE, NULL, 0x0, NULL, HFILL }
1481 { "Flags", "cfm.flags", FT_UINT8,
1482 BASE_HEX, NULL, 0x0, NULL, HFILL }
1484 { &hf_cfm_flags_RDI,
1485 { "RDI", "cfm.flags.rdi", FT_UINT8,
1486 BASE_DEC, NULL, 0x80, NULL, HFILL }
1488 { &hf_cfm_flags_ccm_Reserved,
1489 { "Reserved", "cfm.flags.ccm.reserved", FT_UINT8,
1490 BASE_DEC, NULL, 0x78, NULL, HFILL }
1492 { &hf_cfm_flags_Interval,
1493 { "Interval Field", "cfm.flags.interval", FT_UINT8,
1494 BASE_DEC, VALS(CCM_IntervalFieldEncoding), 0x07, NULL, HFILL }
1496 { &hf_cfm_first_tlv_offset,
1497 { "First TLV Offset", "cfm.first.tlv.offset", FT_UINT8,
1498 BASE_DEC, NULL, 0x0, NULL, HFILL }
1500 { &hf_cfm_ccm_seq_number,
1501 { "Sequence Number", "cfm.ccm.seq.num", FT_UINT32,
1502 BASE_DEC, NULL, 0x0, NULL, HFILL }
1504 { &hf_cfm_ccm_ma_ep_id,
1505 { "Maintenance Association End Point Identifier", "cfm.ccm.ma.ep.id",
1506 FT_UINT16, BASE_DEC, NULL, 0x1FFF, NULL, HFILL }
1509 { "Maintenance Association Identifier (MEG ID)", "cfm.ccm.maid", FT_NONE,
1510 BASE_NONE, NULL, 0x0, NULL, HFILL }
1512 { &hf_cfm_maid_md_name_format,
1513 { "MD Name Format", "cfm.maid.md.name.format", FT_UINT8,
1514 BASE_DEC, VALS(mdnameformattypes), 0x0, NULL, HFILL }
1516 { &hf_cfm_maid_md_name_length,
1517 { "MD Name Length", "cfm.maid.md.name.length", FT_UINT8,
1518 BASE_DEC, NULL, 0x0, NULL, HFILL }
1520 { &hf_cfm_maid_md_name_string,
1521 { "MD Name (String)", "cfm.maid.md.name", FT_STRING,
1522 BASE_NONE, NULL, 0x0, NULL, HFILL }
1524 { &hf_cfm_maid_md_name_hex,
1525 { "MD Name", "cfm.maid.md.name", FT_BYTES,
1526 BASE_NONE, NULL, 0x0, NULL, HFILL }
1528 { &hf_cfm_maid_md_name_mac,
1529 { "MD Name (MAC)", "cfm.maid.md.name.mac", FT_ETHER,
1530 BASE_NONE, NULL, 0x0, NULL, HFILL }
1532 { &hf_cfm_maid_md_name_mac_id,
1533 { "MD Name (MAC)", "cfm.maid.md.name.mac.id", FT_BYTES,
1534 BASE_NONE, NULL, 0x0, NULL, HFILL }
1536 { &hf_cfm_maid_ma_name_format,
1537 { "Short MA Name (MEG ID) Format", "cfm.maid.ma.name.format", FT_UINT8,
1538 BASE_DEC, VALS(manameformattypes), 0x0, NULL, HFILL }
1540 { &hf_cfm_maid_ma_name_length,
1541 { "Short MA Name (MEG ID) Length", "cfm.maid.ma.name.length", FT_UINT8,
1542 BASE_DEC, NULL, 0x0, NULL, HFILL }
1544 { &hf_cfm_maid_ma_name_string,
1545 { "Short MA Name", "cfm.maid.ma.name", FT_STRING,
1546 BASE_NONE, NULL, 0x0, NULL, HFILL }
1548 { &hf_cfm_maid_ma_name_hex,
1549 { "Short MA Name", "cfm.maid.ma.name", FT_BYTES,
1550 BASE_NONE, NULL, 0x0, NULL, HFILL }
1552 { &hf_cfm_maid_padding,
1553 { "Zero-Padding", "cfm.ccm.maid.padding", FT_NONE,
1554 BASE_NONE, NULL, 0x0, NULL, HFILL }
1556 { &hf_cfm_ccm_itu_t_y1731,
1557 { "Defined by ITU-T Y.1731", "cfm.ccm.itu.t.y1731", FT_NONE,
1558 BASE_NONE, NULL, 0x0, NULL, HFILL }
1560 { &hf_cfm_itu_TxFCf,
1561 { "TxFCf", "cfm.itu.txfcf", FT_BYTES,
1562 BASE_NONE, NULL, 0x0, NULL, HFILL }
1564 { &hf_cfm_itu_RxFCb,
1565 { "RxFCb", "cfm.itu.rxfcb", FT_BYTES,
1566 BASE_NONE, NULL, 0x0, NULL, HFILL }
1568 { &hf_cfm_itu_TxFCb,
1569 { "TxFCb", "cfm.itu.txfcb", FT_BYTES,
1570 BASE_NONE, NULL, 0x0, NULL, HFILL }
1572 { &hf_cfm_itu_reserved,
1573 { "Reserved", "cfm.itu.reserved", FT_BYTES,
1574 BASE_NONE, NULL, 0x0, NULL, HFILL }
1579 { "CFM LBM PDU", "cfm.lbm.pdu", FT_NONE,
1580 BASE_NONE, NULL, 0x0, NULL, HFILL }
1582 { &hf_cfm_lb_transaction_id,
1583 { "Loopback Transaction Identifier", "cfm.lb.transaction.id", FT_UINT32,
1584 BASE_DEC, NULL, 0x0, NULL, HFILL }
1589 { "CFM LBR PDU", "cfm.lbr.pdu", FT_NONE,
1590 BASE_NONE, NULL, 0x0, NULL, HFILL }
1595 { "CFM LTM PDU", "cfm.ltm.pdu", FT_NONE,
1596 BASE_NONE, NULL, 0x0, NULL, HFILL }
1598 { &hf_cfm_flags_UseFDBonly,
1599 { "UseFDBonly", "cfm.flags.usefdbonly", FT_UINT8,
1600 BASE_DEC, NULL, 0x80, NULL, HFILL }
1602 { &hf_cfm_flags_ltm_Reserved,
1603 { "Reserved", "cfm.flags.ltm.reserved", FT_UINT8,
1604 BASE_DEC, NULL, 0x7F, NULL, HFILL }
1606 { &hf_cfm_lt_transaction_id,
1607 { "Linktrace Transaction Identifier", "cfm.lt.transaction.id", FT_UINT32,
1608 BASE_DEC, NULL, 0x0, NULL, HFILL }
1611 { "Linktrace TTL", "cfm.lt.ttl", FT_UINT8,
1612 BASE_DEC, NULL, 0x0, NULL, HFILL }
1614 { &hf_cfm_ltm_orig_addr,
1615 { "Linktrace Message: Original Address", "cfm.ltm.orig.addr", FT_ETHER,
1616 BASE_NONE, NULL, 0x0, NULL, HFILL }
1618 { &hf_cfm_ltm_targ_addr,
1619 { "Linktrace Message: Target Address", "cfm.ltm.targ.addr", FT_ETHER,
1620 BASE_NONE, NULL, 0x0, NULL, HFILL }
1625 { "CFM LTR PDU", "cfm.ltr.pdu", FT_NONE,
1626 BASE_NONE, NULL, 0x0, NULL, HFILL }
1628 { &hf_cfm_flags_FwdYes,
1629 { "FwdYes", "cfm.flags.fwdyes", FT_UINT8,
1630 BASE_DEC, NULL, 0x40, NULL, HFILL }
1632 { &hf_cfm_flags_TerminalMEP,
1633 { "TerminalMEP", "cfm.flags.ltr.terminalmep", FT_UINT8,
1634 BASE_DEC, NULL, 0x20, NULL, HFILL }
1636 { &hf_cfm_flags_ltr_Reserved,
1637 { "Reserved", "cfm.flags.ltr.reserved", FT_UINT8,
1638 BASE_DEC, NULL, 0x1F, NULL, HFILL }
1640 { &hf_cfm_ltr_relay_action,
1641 { "Linktrace Reply Relay Action", "cfm.ltr.relay.action", FT_UINT8,
1642 BASE_DEC, VALS(relayactiontypes), 0x0, NULL, HFILL}
1647 { "CFM AIS PDU", "cfm.ais.pdu", FT_NONE,
1648 BASE_NONE, NULL, 0x0, NULL, HFILL }
1650 { &hf_cfm_flags_ais_lck_Reserved,
1651 { "Reserved", "cfm.flags.reserved", FT_UINT8,
1652 BASE_DEC, NULL, 0xF8, NULL, HFILL }
1654 { &hf_cfm_flags_ais_lck_Period,
1655 { "Period", "cfm.flags.period", FT_UINT8,
1656 BASE_DEC, VALS(aislckperiodtypes), 0x07, NULL, HFILL }
1661 { "CFM LCK PDU", "cfm.lck.pdu", FT_NONE,
1662 BASE_NONE, NULL, 0x0, NULL, HFILL }
1667 { "CFM TST PDU", "cfm.tst.pdu", FT_NONE,
1668 BASE_NONE, NULL, 0x0, NULL, HFILL }
1670 { &hf_cfm_flags_Reserved,
1671 { "Reserved", "cfm.flags.reserved", FT_UINT8,
1672 BASE_DEC, NULL, 0x0, NULL, HFILL }
1674 { &hf_cfm_tst_sequence_num,
1675 { "Sequence Number", "cfm.tst.sequence.num", FT_UINT32,
1676 BASE_DEC, NULL, 0x0, NULL, HFILL }
1681 { "CFM APS PDU", "cfm.aps.pdu", FT_NONE,
1682 BASE_NONE, NULL, 0x0, NULL, HFILL }
1685 { "APS data", "cfm.aps.data", FT_BYTES,
1686 BASE_NONE, NULL, 0x0, NULL, HFILL }
1691 { "CFM R-APS PDU", "cfm.raps.pdu", FT_NONE,
1692 BASE_NONE, NULL, 0x0, NULL, HFILL }
1694 { &hf_cfm_raps_req_st,
1695 { "Request/State", "cfm.raps.req.st", FT_UINT8,
1696 BASE_HEX, VALS(rapsrequeststatevalues), 0xF0, NULL, HFILL }
1698 { &hf_cfm_raps_flags,
1699 { "R-APS Flags", "cfm.raps.flags", FT_UINT8,
1700 BASE_HEX, NULL, 0x0, NULL, HFILL }
1702 { &hf_cfm_raps_flags_rb,
1703 { "RPL Blocked", "cfm.raps.flags.rb", FT_UINT8,
1704 BASE_HEX, VALS(rapsrplblockedvalues), 0x80, NULL, HFILL }
1706 { &hf_cfm_raps_flags_dnf,
1707 { "Do Not Flush", "cfm.raps.flags.dnf", FT_UINT8,
1708 BASE_HEX, VALS(rapsdnfvalues), 0x40, NULL, HFILL }
1710 { &hf_cfm_raps_node_id,
1711 { "R-APS Node ID", "cfm.raps.node.id", FT_ETHER,
1712 BASE_NONE, NULL, 0x0, NULL, HFILL }
1714 { &hf_cfm_raps_reserved,
1715 { "R-APS Reserved", "cfm.raps.reserved", FT_BYTES,
1716 BASE_NONE, NULL, 0x0, NULL, HFILL }
1721 { "CFM MCC PDU", "cfm.mcc.pdu", FT_NONE,
1722 BASE_NONE, NULL, 0x0, NULL, HFILL }
1725 { "MCC data", "cfm.mcc.data", FT_BYTES,
1726 BASE_NONE, NULL, 0x0, NULL, HFILL }
1731 { "CFM LMM PDU", "cfm.lmm.pdu", FT_NONE,
1732 BASE_NONE, NULL, 0x0, NULL, HFILL }
1734 { &hf_cfm_lmm_lmr_TxFCf,
1735 { "TxFCf", "cfm.lmm.lmr.txfcf", FT_BYTES,
1736 BASE_NONE, NULL, 0x0, NULL, HFILL }
1738 { &hf_cfm_lmm_lmr_RxFCf,
1739 { "RxFCf", "cfm.lmm.lmr.rxfcf", FT_BYTES,
1740 BASE_NONE, NULL, 0x0, NULL, HFILL }
1742 { &hf_cfm_lmm_lmr_TxFCb,
1743 { "TxFCb", "cfm.lmm.lmr.txfcb", FT_BYTES,
1744 BASE_NONE, NULL, 0x0, NULL, HFILL }
1750 { "CFM LMR PDU", "cfm.lmr.pdu", FT_NONE,
1751 BASE_NONE, NULL, 0x0, NULL, HFILL }
1756 { "CFM 1DM PDU", "cfm.odm.pdu", FT_NONE,
1757 BASE_NONE, NULL, 0x0, NULL, HFILL }
1759 { &hf_cfm_odm_dmm_dmr_TxTimestampf,
1760 { "TxTimestampf", "cfm.odm.dmm.dmr.txtimestampf", FT_BYTES,
1761 BASE_NONE, NULL, 0x0, NULL, HFILL }
1763 { &hf_cfm_odm_dmm_dmr_RxTimestampf,
1764 { "RxTimestampf", "cfm.odm.dmm.dmr.rxtimestampf", FT_BYTES,
1765 BASE_NONE, NULL, 0x0, NULL, HFILL }
1770 { "CFM DMM PDU", "cfm.dmm.pdu", FT_NONE,
1771 BASE_NONE, NULL, 0x0, NULL, HFILL }
1773 { &hf_cfm_dmm_dmr_TxTimestampb,
1774 { "TxTimestampb", "cfm.dmm.dmr.txtimestampb", FT_BYTES,
1775 BASE_NONE, NULL, 0x0, NULL, HFILL }
1777 { &hf_cfm_dmm_dmr_RxTimestampb,
1778 { "RxTimestampb", "cfm.dmm.dmr.rxtimestampb", FT_BYTES,
1779 BASE_NONE, NULL, 0x0, NULL, HFILL }
1784 { "CFM DMR PDU", "cfm.dmr.pdu", FT_NONE,
1785 BASE_NONE, NULL, 0x0, NULL, HFILL }
1790 { "CFM EXM PDU", "cfm.exm.pdu", FT_NONE,
1791 BASE_NONE, NULL, 0x0, NULL, HFILL }
1793 { &hf_cfm_exm_exr_data,
1794 { "EXM/EXR data", "cfm.mcc.data", FT_BYTES,
1795 BASE_NONE, NULL, 0x0, NULL, HFILL }
1800 { "CFM EXR PDU", "cfm.exr.pdu", FT_NONE,
1801 BASE_NONE, NULL, 0x0, NULL, HFILL }
1806 { "CFM VSM PDU", "cfm.vsm.pdu", FT_NONE,
1807 BASE_NONE, NULL, 0x0, NULL, HFILL }
1809 { &hf_cfm_vsm_vsr_data,
1810 { "VSM/VSR data", "cfm.mcc.data", FT_BYTES,
1811 BASE_NONE, NULL, 0x0, NULL, HFILL }
1816 { "CFM VSR PDU", "cfm.vsr.pdu", FT_NONE,
1817 BASE_NONE, NULL, 0x0, NULL, HFILL }
1820 /* Synthetic Loss values */
1822 { "CFM SLM PDU", "cfm.slm.pdu", FT_NONE,
1823 BASE_NONE, NULL, 0x0, NULL, HFILL }
1826 { "CFM SLR PDU", "cfm.slr.pdu", FT_NONE,
1827 BASE_NONE, NULL, 0x0, NULL, HFILL }
1829 { &hf_cfm_slm_src_mep,
1830 { "SrcMepID", "cfm.slm.src_mep_id", FT_BYTES,
1831 BASE_NONE, NULL, 0x0, NULL, HFILL }
1833 { &hf_cfm_slr_rsp_mep,
1834 { "RspMepID", "cfm.slr.rsp_mep_id", FT_BYTES,
1835 BASE_NONE, NULL, 0x0, NULL, HFILL }
1837 { &hf_cfm_slm_testid,
1838 { "TestID", "cfm.slm.test_id", FT_BYTES,
1839 BASE_NONE, NULL, 0x0, NULL, HFILL }
1841 { &hf_cfm_slm_txfcf,
1842 { "TxFcF", "cfm.slm.txfcf", FT_UINT32,
1843 BASE_DEC, NULL, 0x0, NULL, HFILL }
1845 { &hf_cfm_slr_txfcb,
1846 { "TxFcB", "cfm.slr.txfcb", FT_UINT32,
1847 BASE_DEC, NULL, 0x0, NULL, HFILL }
1850 /******************************* TLVs ****************************/
1852 { "CFM TLVs", "cfm.all.tlvs", FT_NONE,
1853 BASE_NONE, NULL, 0x0, NULL, HFILL }
1856 { "TLV Type", "cfm.tlv.type", FT_UINT8,
1857 BASE_DEC, VALS(tlvtypefieldvalues), 0x0, NULL, HFILL}
1859 { &hf_cfm_tlv_length,
1860 { "TLV Length", "cfm.tlv.length", FT_UINT16,
1861 BASE_DEC, NULL, 0x0, NULL, HFILL}
1864 { &hf_tlv_chassis_id_length,
1865 { "Chassis ID Length", "cfm.tlv.chassis.id.length", FT_UINT8,
1866 BASE_DEC, NULL, 0x0, NULL, HFILL}
1868 { &hf_tlv_chassis_id_subtype,
1869 { "Chassis ID Sub-type", "cfm.tlv.chassis.id.subtype", FT_UINT8,
1870 BASE_DEC, NULL, 0x0, NULL, HFILL}
1872 { &hf_tlv_chassis_id,
1873 { "Chassis ID", "cfm.tlv.chassis.id", FT_BYTES,
1874 BASE_NONE, NULL, 0x0, NULL, HFILL}
1876 { &hf_tlv_ma_domain_length,
1877 { "Management Address Domain Length", "cfm.tlv.ma.domain.length", FT_UINT8,
1878 BASE_DEC, NULL, 0x0, NULL, HFILL}
1880 { &hf_tlv_ma_domain,
1881 { "Management Address Domain", "cfm.tlv.ma.domain", FT_BYTES,
1882 BASE_NONE, NULL, 0x0, NULL, HFILL}
1884 { &hf_tlv_management_addr_length,
1885 { "Management Address Length", "cfm.tlv.management.addr.length", FT_UINT8,
1886 BASE_DEC, NULL, 0x0, NULL, HFILL}
1888 { &hf_tlv_management_addr,
1889 { "Management Address", "cfm.tlv.management.addr", FT_BYTES,
1890 BASE_NONE, NULL, 0x0, NULL, HFILL}
1893 /* Port Status TLV */
1894 { &hf_tlv_port_status_value,
1895 { "Port Status value", "cfm.tlv.port.status.value", FT_UINT8,
1896 BASE_DEC, VALS(portstatTLVvalues), 0x0, NULL, HFILL}
1900 { &hf_tlv_data_value,
1901 { "Data Value", "cfm.tlv.data.value", FT_BYTES,
1902 BASE_NONE, NULL, 0x0, NULL, HFILL}
1905 /* Interface status TLV */
1906 { &hf_tlv_interface_status_value,
1907 { "Interface Status value", "cfm.tlv.port.interface.value", FT_UINT8,
1908 BASE_DEC, VALS(interfacestatTLVvalues), 0x0, NULL, HFILL}
1911 /* Reply Ingress TLV */
1912 { &hf_tlv_reply_ingress_action,
1913 { "Ingress Action", "cfm.tlv.reply.ingress.action", FT_UINT8,
1914 BASE_DEC, VALS(replyingressTLVvalues), 0x0, NULL, HFILL}
1916 { &hf_tlv_reply_ingress_mac_address,
1917 { "Ingress MAC address", "cfm.tlv.reply.ingress.mac.address", FT_ETHER,
1918 BASE_NONE, NULL, 0x0, NULL, HFILL }
1920 { &hf_tlv_reply_ing_egr_portid_length,
1921 { "Chassis ID Length", "cfm.tlv.chassis.id.length", FT_UINT8,
1922 BASE_DEC, NULL, 0x0, NULL, HFILL}
1924 { &hf_tlv_reply_ing_egr_portid_subtype,
1925 { "Chassis ID Sub-type", "cfm.tlv.chassis.id.subtype", FT_UINT8,
1926 BASE_DEC, NULL, 0x0, NULL, HFILL}
1928 { &hf_tlv_reply_ing_egr_portid,
1929 { "Chassis ID", "cfm.tlv.chassis.id", FT_BYTES,
1930 BASE_NONE, NULL, 0x0, NULL, HFILL}
1933 /* Reply Egress TLV */
1934 { &hf_tlv_reply_egress_action,
1935 { "Egress Action", "cfm.tlv.reply.egress.action", FT_UINT8,
1936 BASE_DEC, VALS(replyegressTLVvalues), 0x0, NULL, HFILL}
1938 { &hf_tlv_reply_egress_mac_address,
1939 { "Egress MAC address", "cfm.tlv.reply.egress.mac.address", FT_ETHER,
1940 BASE_NONE, NULL, 0x0, NULL, HFILL }
1943 /* LTM Egress Identifier TLV */
1944 { &hf_tlv_ltm_egress_id_mac,
1945 { "Egress Identifier - MAC of LT Initiator/Responder", "cfm.tlv.ltm.egress.id.mac", FT_ETHER,
1946 BASE_NONE, NULL, 0x0, NULL, HFILL }
1948 { &hf_tlv_ltm_egress_id_unique_identifier,
1949 { "Egress Identifier - Unique Identifier", "cfm.tlv.ltm.egress.id.ui", FT_BYTES,
1950 BASE_NONE, NULL, 0x0, NULL, HFILL }
1953 /* LTR Egress Identifier TLV */
1954 { &hf_tlv_ltr_egress_last_id_mac,
1955 { "Last Egress Identifier - MAC address", "cfm.tlv.ltr.egress.last.id.mac", FT_ETHER,
1956 BASE_NONE, NULL, 0x0, NULL, HFILL }
1958 { &hf_tlv_ltr_egress_last_id_unique_identifier,
1959 { "Last Egress Identifier - Unique Identifier", "cfm.tlv.ltr.egress.last.id.ui", FT_BYTES,
1960 BASE_NONE, NULL, 0x0, NULL, HFILL }
1962 { &hf_tlv_ltr_egress_next_id_mac,
1963 { "Next Egress Identifier - MAC address", "cfm.tlv.ltr.egress.next.id.mac", FT_ETHER,
1964 BASE_NONE, NULL, 0x0, NULL, HFILL }
1966 { &hf_tlv_ltr_egress_next_id_unique_identifier,
1967 { "Next Egress Identifier - Unique Identifier", "cfm.tlv.ltr.egress.next.id.ui", FT_BYTES,
1968 BASE_NONE, NULL, 0x0, NULL, HFILL }
1971 /* Organization-Specific TLV */
1972 { &hf_tlv_org_spec_oui,
1973 { "OUI", "cfm.tlv.org.spec.oui", FT_BYTES,
1974 BASE_NONE, NULL, 0x0, NULL, HFILL }
1976 { &hf_tlv_org_spec_subtype,
1977 { "Sub-Type", "cfm.tlv.org.spec.subtype", FT_BYTES,
1978 BASE_NONE, NULL, 0x0, NULL, HFILL }
1980 { &hf_tlv_org_spec_value,
1981 { "Value", "cfm.tlv.org.spec.value", FT_BYTES,
1982 BASE_NONE, NULL, 0x0, NULL, HFILL }
1986 { &hf_tlv_tst_test_pattern_type,
1987 { "Test Pattern Type", "cfm.tlv.tst.test.pattern.type", FT_UINT8,
1988 BASE_DEC, VALS(testTLVpatterntypes), 0x0, NULL, HFILL}
1990 { &hf_tlv_tst_test_pattern,
1991 { "Test Pattern", "cfm.tlv.tst.test.pattern", FT_NONE,
1992 BASE_NONE, NULL, 0x0, NULL, HFILL }
1994 { &hf_tlv_tst_CRC32,
1995 { "CRC-32", "cfm.tlv.tst.crc32", FT_BYTES,
1996 BASE_NONE, NULL, 0x0, NULL, HFILL }
2000 /* Setup protocol subtree array */
2001 static gint *ett[] = {
2012 proto_cfm = proto_register_protocol (
2013 "CFM EOAM 802.1ag/ITU Protocol", /* name */
2014 "CFM", /* short name */
2018 register_dissector("cfm", dissect_cfm, proto_cfm);
2020 proto_register_field_array(proto_cfm, hf, array_length(hf));
2021 proto_register_subtree_array(ett, array_length(ett));
2025 /* Register CFM OEAM protocol handler */
2026 void proto_reg_handoff_cfm(void)
2028 dissector_handle_t cfm_handle;
2029 cfm_handle = create_dissector_handle(dissect_cfm, proto_cfm);
2030 dissector_add_uint("ethertype", ETHERTYPE_CFM, cfm_handle);