HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-cfm.c
blob3af4617ad6b731f86e4fadc76edac59137e7b196
1 /* packet-cfm.c
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>
5 * Copyright 2012, Wim Leflere <wim.leflere-ext@oneaccess-net.com>
6 * Copyright 2013, Andreas Urke <arurke@gmail.com>
8 * $Id$
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 /* This code is based on the IEEE P802.1ag/D8.1 document,
30 * the ITU-T Rec. G.8031/Y.1342 (06/2011) - Ethernet linear protection switching document,
31 * the ITU-T Rec. G.8032/Y.1344 (02/2012) - Ethernet ring protection switching document,
32 * and on the ITU-T Y.1731 recommendation (05/2006,) which is not formally released
33 * at the time of this dissector development.
34 * Any updates to these documents may require additional modifications to this code.
38 #include "config.h"
40 #include <epan/packet.h>
41 #include <glib.h>
42 #include <epan/etypes.h>
44 /** Value declarations for CFM EOAM (IEEE 802.1ag) dissection */
45 #define IEEE8021 0x00
46 #define CCM 0x01
47 #define LBR 0x02
48 #define LBM 0x03
49 #define LTR 0x04
50 #define LTM 0X05
52 #define AIS 0x21
53 #define LCK 0x23
54 #define TST 0x25
55 #define APS 0x27
56 #define RAPS 0x28
57 #define MCC 0x29
58 #define LMM 0x2B
59 #define LMR 0x2A
60 #define ODM 0x2D
61 #define DMM 0x2F
62 #define DMR 0x2E
63 #define EXM 0x31
64 #define EXR 0x30
65 #define VSM 0x33
66 #define VSR 0x32
67 #define SLM 0x37
68 #define SLR 0x36
70 #define END_TLV 0x00
71 #define SENDER_ID_TLV 0x01
72 #define PORT_STAT_TLV 0x02
73 #define DATA_TLV 0x03
74 #define INTERF_STAT_TLV 0x04
75 #define REPLY_ING_TLV 0x05
76 #define REPLY_EGR_TLV 0x06
77 #define LTM_EGR_ID_TLV 0x07
78 #define LTR_EGR_ID_TLV 0x08
79 #define ORG_SPEC_TLV 0x1F
80 #define TEST_TLV 0x20
82 /* Offsets of fields within CFM PDU */
83 #define CFM_VERSION 0
84 #define CFM_OPCODE 1
86 #define RAPS_REQUESTSTATE_EVENT 14
88 void proto_register_cfm(void);
89 void proto_reg_handoff_cfm(void);
91 static int proto_cfm = -1;
93 static const value_string opcodetypenames[] = {
94 { IEEE8021, "Reserved for IEEE 802.1" },
95 { CCM, "Continuity Check Message (CCM)" },
96 { LBR, "Loopback Reply (LBR)" },
97 { LBM, "Loopback Message (LBM)" },
98 { LTR, "Linktrace Reply (LTR)" },
99 { LTM, "Linktrace Message (LTM)" },
100 { AIS, "Alarm Indication Signal (AIS)" },
101 { LCK, "Lock Signal (LCK)" },
102 { TST, "Test Signal (TST)" },
103 { APS, "Automatic Protection Switching (APS)" },
104 { RAPS, "Ring-Automatic Protection Switching (R-APS)" },
105 { MCC, "Maintenance Communication Channel (MCC)" },
106 { LMM, "Loss Measurement Message (LMM)" },
107 { LMR, "Loss Measurement Reply (LMR)" },
108 { ODM, "One Way Delay Measurement (1DM)" },
109 { DMM, "Delay Measurement Message (DMM)" },
110 { DMR, "Delay Measurement Reply (DMR)" },
111 { EXM, "Experimental OAM Message (EXM)" },
112 { EXR, "Experimental OAM Reply (EXR)" },
113 { VSM, "Vendor Specific Message (VSM)" },
114 { VSR, "Vendor Specific Reply (VSR)" },
115 { SLM, "Synthetic Loss Message (SLM)"},
116 { SLR, "Synthetic Loss Reply (SLR))"},
117 { 0, NULL }
119 static const value_string CCM_IntervalFieldEncoding[] = {
120 { 0, "invalid" },
121 { 1, "Trans Int 3.33ms, max Lifetime 11.66ms, min Lifetime 10.83ms" },
122 { 2, "Trans Int 10ms, max Lifetime 35ms, min Lifetime 32.5ms" },
123 { 3, "Trans Int 100ms, max Lifetime 350ms, min Lifetime 325ms" },
124 { 4, "Trans Int 1s, max Lifetime 3.5s, min Lifetime 3.25s" },
125 { 5, "Trans Int 10s, max Lifetime 35s, min Lifetime 32.5s" },
126 { 6, "Trans Int 1min, max Lifetime 3.5min, min Lifetime 3.25min" },
127 { 7, "Trans Int 10min, max Lifetime 35min, min Lifetime 32.5min" },
128 { 0, NULL }
130 static const value_string mdnameformattypes[] = {
131 { 0, "Reserved for IEEE 802.1" },
132 { 1, "No Maintenance Domain Name preset" },
133 { 2, "RFC1035 DNS Name" },
134 { 3, "MAC address + 2-octet integer" },
135 { 4, "Character String" },
136 { 0, NULL }
138 static const value_string manameformattypes[] = {
139 { 0, "Reserved for IEEE 802.1" },
140 { 1, "Primary VID" },
141 { 2, "Character String" },
142 { 3, "2-octet integer" },
143 { 4, "RFC 2685 VPN ID" },
144 { 32, "ICC-based Format" },
145 { 0, NULL }
147 static const value_string relayactiontypes[] = {
148 { 1, "RlyHit" },
149 { 2, "RlyFDB" },
150 { 3, "RlyMPDB" },
151 { 0, NULL }
153 static const value_string aislckperiodtypes[] = {
154 { 0, "Invalid Value for AIS/LCK PDU's" },
155 { 1, "Invalid Value for AIS/LCK PDU's" },
156 { 2, "Invalid Value for AIS/LCK PDU's" },
157 { 3, "Invalid Value for AIS/LCK PDU's" },
158 { 4, "1 frame per second" },
159 { 5, "Invalid Value for AIS/LCK PDU's" },
160 { 6, "1 frame per minute" },
161 { 7, "Invalid Value for AIS/LCK PDU's" },
162 { 0, NULL }
164 static const value_string tlvtypefieldvalues[] = {
165 { END_TLV , "End TLV" },
166 { SENDER_ID_TLV , "Sender ID TLV" },
167 { PORT_STAT_TLV , "Port Status TLV" },
168 { DATA_TLV , "Data TLV" },
169 { INTERF_STAT_TLV , "Interface Status TLV" },
170 { REPLY_ING_TLV , "Reply Ingress TLV" },
171 { REPLY_EGR_TLV , "Reply Egress TLV" },
172 { LTM_EGR_ID_TLV , "LTM Egress Identifier TLV" },
173 { LTR_EGR_ID_TLV , "LTR Egress Identifier TLV" },
174 { ORG_SPEC_TLV , "Organizational-Specific TLV" },
175 { TEST_TLV , "Test TLV" },
176 { 0 , NULL }
178 static const value_string portstatTLVvalues[] = {
179 { 1, "psBlocked" },
180 { 2, "psUp" },
181 { 0, NULL }
183 static const value_string interfacestatTLVvalues[] = {
184 { 1, "isUp" },
185 { 2, "isDown" },
186 { 3, "isTesting" },
187 { 4, "isUnknown" },
188 { 5, "isDormant" },
189 { 6, "isNotPresent" },
190 { 7, "isLowerLayerDown" },
191 { 0, NULL }
193 static const value_string replyingressTLVvalues[] = {
194 { 1, "IngOK" },
195 { 2, "IngDown" },
196 { 3, "IngBlocked" },
197 { 4, "IngVID" },
198 { 0, NULL }
200 static const value_string replyegressTLVvalues[] = {
201 { 1, "EgrOK" },
202 { 2, "EgrDown" },
203 { 3, "EgrBlocked" },
204 { 4, "EgrVID" },
205 { 0, NULL }
207 static const value_string testTLVpatterntypes[] = {
208 { 0, "Null signal without CRC-32" },
209 { 1, "Null signal with CRC-32" },
210 { 2, "PRBS (2.e-31 -1), without CRC-32" },
211 { 3, "PRBS (2.e-31 -1), with CRC-32" },
212 { 0, NULL }
214 static const value_string aps_request_state_values[] = {
215 { 0, "No request" },
216 { 1, "Do not revert" },
217 { 2, "Reverse request" },
218 { 3, "Unknown"},
219 { 4, "Exersise" },
220 { 5, "Wait to restore" },
221 { 6, "Depreciated" },
222 { 7, "Manual switch" },
223 { 8, "Unknown"},
224 { 9, "Signal degrade" },
225 { 10, "Unknown"},
226 { 11, "Signal fail working" },
227 { 12, "Unknown"},
228 { 13, "Forced switch" },
229 { 14, "Signal fail protection" },
230 { 15, "Lockout" },
231 { 0, NULL }
233 static const true_false_string aps_protection_type_A_values = {
234 "APS channel",
235 "No APS channel"
237 static const true_false_string aps_protection_type_B_values = {
238 "1:1 (no permanent bridge)",
239 "1+1 (permanent bridge)"
241 static const true_false_string aps_protection_type_D_values = {
242 "Bidirectional switching",
243 "Unidirectional switching"
245 static const true_false_string aps_protection_type_R_values = {
246 "Revertive operation",
247 "Non-revertive operation"
249 static const value_string aps_requested_signal_values[] = {
250 { 0, "Null" },
251 { 1, "Normal traffic" },
252 { 0, NULL }
254 static const value_string aps_bridged_signal_values[] = {
255 { 0, "Null" },
256 { 1, "Normal traffic" },
257 { 0, NULL }
259 static const value_string aps_bridge_type_values[] = {
260 { 0, "Selector" },
261 { 1, "Broadcast" },
262 { 0, NULL }
264 static const value_string rapsrequeststatevalues[] = {
265 { 0, "No Request" },
266 { 7, "Manual Switch"},
267 { 11, "Signal Failure" },
268 { 13, "Forced Switch"},
269 { 14, "Event"},
270 { 0, NULL }
272 static const value_string rapseventsubcode[] = {
273 { 0, "Flush Request" },
274 { 0, NULL }
276 static const true_false_string rapsrplblockedvalues = {
277 "Blocked",
278 "Not Blocked"
280 static const true_false_string rapsdnfvalues = {
281 "Do Not Flush DB",
282 "May Flush DB"
284 static const true_false_string rapsbprvalues = {
285 "Ring link 1",
286 "Ring link 0"
290 static int hf_cfm_md_level = -1;
291 static int hf_cfm_version = -1;
292 static int hf_cfm_opcode = -1;
294 static int hf_cfm_flags = -1;
295 static int hf_cfm_flags_RDI = -1;
296 static int hf_cfm_flags_ccm_Reserved = -1;
297 static int hf_cfm_flags_Interval = -1;
298 static int hf_cfm_flags_UseFDBonly = -1;
299 static int hf_cfm_flags_ltm_Reserved = -1;
300 static int hf_cfm_flags_ltr_Reserved = -1;
301 static int hf_cfm_flags_FwdYes = -1;
302 static int hf_cfm_flags_TerminalMEP = -1;
303 static int hf_cfm_first_tlv_offset = -1;
305 static int hf_cfm_ccm_pdu = -1;
306 static int hf_cfm_ccm_seq_number = -1;
307 static int hf_cfm_ccm_ma_ep_id = -1;
308 static int hf_cfm_ccm_maid = -1;
309 static int hf_cfm_maid_md_name_format = -1;
310 static int hf_cfm_maid_md_name_length = -1;
311 static int hf_cfm_maid_md_name_string = -1;
312 static int hf_cfm_maid_md_name_hex = -1;
313 static int hf_cfm_maid_md_name_mac = -1;
314 static int hf_cfm_maid_md_name_mac_id = -1;
315 static int hf_cfm_maid_ma_name_format = -1;
316 static int hf_cfm_maid_ma_name_length = -1;
317 static int hf_cfm_maid_ma_name_string = -1;
318 static int hf_cfm_maid_ma_name_hex = -1;
319 static int hf_cfm_maid_padding = -1;
320 static int hf_cfm_ccm_itu_t_y1731 = -1;
321 static int hf_cfm_itu_TxFCf = -1;
322 static int hf_cfm_itu_RxFCb = -1;
323 static int hf_cfm_itu_TxFCb = -1;
324 static int hf_cfm_itu_reserved = -1;
326 static int hf_cfm_lbm_pdu = -1;
327 static int hf_cfm_lb_transaction_id = -1;
329 static int hf_cfm_lbr_pdu = -1;
331 static int hf_cfm_ltm_pdu = -1;
332 static int hf_cfm_lt_transaction_id = -1;
333 static int hf_cfm_lt_ttl = -1;
334 static int hf_cfm_ltm_orig_addr = -1;
335 static int hf_cfm_ltm_targ_addr = -1;
337 static int hf_cfm_ltr_pdu = -1;
338 static int hf_cfm_ltr_relay_action = -1;
340 static int hf_cfm_ais_pdu = -1;
341 static int hf_cfm_flags_ais_lck_Reserved = -1;
342 static int hf_cfm_flags_ais_lck_Period = -1;
344 static int hf_cfm_lck_pdu = -1;
346 static int hf_cfm_tst_pdu = -1;
347 static int hf_cfm_flags_Reserved = -1;
348 static int hf_cfm_tst_sequence_num = -1;
350 static int hf_cfm_aps_pdu = -1;
351 static int hf_cfm_aps_req_st = -1;
352 static int hf_cfm_aps_protection_type_A = -1;
353 static int hf_cfm_aps_protection_type_B = -1;
354 static int hf_cfm_aps_protection_type_D = -1;
355 static int hf_cfm_aps_protection_type_R = -1;
356 static int hf_cfm_aps_requested_signal = -1;
357 static int hf_cfm_aps_bridged_signal = -1;
358 static int hf_cfm_aps_bridge_type = -1;
360 static int hf_cfm_raps_pdu = -1;
361 static int hf_cfm_raps_req_st = -1;
362 static int hf_cfm_raps_event_subcode = -1;
363 static int hf_cfm_raps_flags = -1;
364 static int hf_cfm_raps_flags_rb = -1;
365 static int hf_cfm_raps_flags_dnf = -1;
366 static int hf_cfm_raps_flags_bpr = -1;
367 static int hf_cfm_raps_node_id = -1;
368 static int hf_cfm_raps_reserved = -1;
370 static int hf_cfm_mcc_pdu = -1;
371 static int hf_cfm_mcc_data = -1;
373 static int hf_cfm_lmm_pdu = -1;
374 static int hf_cfm_lmr_pdu = -1;
375 static int hf_cfm_lmm_lmr_TxFCf = -1;
376 static int hf_cfm_lmm_lmr_RxFCf = -1;
377 static int hf_cfm_lmm_lmr_TxFCb = -1;
379 static int hf_cfm_odm_pdu = -1;
380 static int hf_cfm_odm_dmm_dmr_TxTimestampf = -1;
381 static int hf_cfm_odm_dmm_dmr_RxTimestampf = -1;
383 static int hf_cfm_dmm_pdu = -1;
384 static int hf_cfm_dmr_pdu = -1;
385 static int hf_cfm_dmm_dmr_TxTimestampb = -1;
386 static int hf_cfm_dmm_dmr_RxTimestampb = -1;
388 static int hf_cfm_exm_pdu = -1;
389 static int hf_cfm_exr_pdu = -1;
390 static int hf_cfm_exm_exr_data = -1;
392 static int hf_cfm_vsm_pdu = -1;
393 static int hf_cfm_vsr_pdu = -1;
394 static int hf_cfm_vsm_vsr_data = -1;
396 static int hf_cfm_slm_pdu = -1;
397 static int hf_cfm_slr_pdu = -1;
398 static int hf_cfm_slm_src_mep = -1;
399 static int hf_cfm_slr_rsp_mep = -1;
400 static int hf_cfm_slm_testid = -1;
401 static int hf_cfm_slm_txfcf = -1;
402 static int hf_cfm_slr_txfcb = -1;
404 static int hf_cfm_all_tlvs = -1;
405 static int hf_cfm_tlv_type = -1;
406 static int hf_cfm_tlv_length = -1;
407 static int hf_tlv_chassis_id_length = -1;
408 static int hf_tlv_chassis_id_subtype = -1;
409 static int hf_tlv_chassis_id = -1;
410 static int hf_tlv_ma_domain_length = -1;
411 static int hf_tlv_ma_domain = -1;
412 static int hf_tlv_management_addr_length = -1;
413 static int hf_tlv_management_addr = -1;
414 static int hf_tlv_port_status_value = -1;
415 static int hf_tlv_data_value = -1;
416 static int hf_tlv_interface_status_value = -1;
418 static int hf_tlv_reply_ingress_action = -1;
419 static int hf_tlv_reply_ingress_mac_address = -1;
420 static int hf_tlv_reply_ing_egr_portid_length = -1;
421 static int hf_tlv_reply_ing_egr_portid_subtype = -1;
422 static int hf_tlv_reply_ing_egr_portid = -1;
423 static int hf_tlv_reply_egress_action = -1;
424 static int hf_tlv_reply_egress_mac_address = -1;
425 static int hf_tlv_ltr_egress_last_id_mac = -1;
426 static int hf_tlv_ltr_egress_last_id_unique_identifier = -1;
427 static int hf_tlv_ltr_egress_next_id_mac = -1;
428 static int hf_tlv_ltr_egress_next_id_unique_identifier = -1;
429 static int hf_tlv_ltm_egress_id_mac = -1;
430 static int hf_tlv_ltm_egress_id_unique_identifier = -1;
431 static int hf_tlv_org_spec_oui = -1;
432 static int hf_tlv_org_spec_subtype = -1;
433 static int hf_tlv_org_spec_value = -1;
434 static int hf_tlv_tst_test_pattern_type = -1;
435 static int hf_tlv_tst_test_pattern = -1;
436 static int hf_tlv_tst_CRC32 = -1;
438 static gint ett_cfm = -1;
439 static gint ett_cfm_flags = -1;
440 static gint ett_cfm_ccm_maid = -1;
441 static gint ett_cfm_ccm_itu = -1;
442 static gint ett_cfm_pdu = -1;
443 static gint ett_cfm_all_tlvs = -1;
444 static gint ett_cfm_tlv = -1;
445 static gint ett_cfm_raps_flags = -1;
447 static dissector_handle_t cfm_handle;
449 /* CFM EOAM sub-protocol dissectors: CCM, LBM, LBR, LTM, LTR */
450 static int dissect_cfm_ccm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
452 gint maid_offset;
454 guint8 cfm_maid_md_name_format;
455 guint8 cfm_maid_ma_name_format;
456 guint8 cfm_maid_ma_name_length;
458 proto_item *ti;
459 proto_item *fi;
460 proto_item *mi;
461 proto_item *wi;
462 proto_tree *cfm_pdu_tree;
463 proto_tree *cfm_flag_tree;
464 proto_tree *cfm_ccm_maid_tree;
465 proto_tree *cfm_ccm_itu_tree;
468 ti = proto_tree_add_item(tree, hf_cfm_ccm_pdu, tvb, offset, -1, ENC_NA);
469 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
471 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
472 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
473 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_RDI, tvb, offset, 1, ENC_BIG_ENDIAN);
474 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_ccm_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
475 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Interval, tvb, offset, 1, ENC_BIG_ENDIAN);
477 offset += 1;
478 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
479 offset += 1;
480 proto_tree_add_item(cfm_pdu_tree, hf_cfm_ccm_seq_number, tvb, offset, 4, ENC_BIG_ENDIAN);
481 offset += 4;
482 proto_tree_add_item(cfm_pdu_tree, hf_cfm_ccm_ma_ep_id, tvb, offset, 2, ENC_BIG_ENDIAN);
483 offset += 2;
485 /* dissect CCM MAID */
486 mi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_ccm_maid, tvb, offset, 48, ENC_NA);
487 cfm_ccm_maid_tree = proto_item_add_subtree(mi, ett_cfm_ccm_maid);
488 maid_offset = offset;
489 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_md_name_format, tvb, maid_offset, 1, ENC_BIG_ENDIAN);
490 cfm_maid_md_name_format = tvb_get_guint8(tvb, maid_offset);
491 maid_offset += 1;
492 if (cfm_maid_md_name_format != 1) {
493 guint8 cfm_maid_md_name_length;
494 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_md_name_length,
495 tvb, maid_offset, 1, ENC_BIG_ENDIAN);
496 cfm_maid_md_name_length = tvb_get_guint8(tvb, maid_offset);
497 maid_offset += 1;
498 if (cfm_maid_md_name_length) {
499 if (cfm_maid_md_name_format == 3) {
500 /* MD name format is MAC + 2 octet id */
501 if (cfm_maid_md_name_length != 8) {
502 /* the MD name of type MAC should be 8 octets but if
503 * it isn't we are going to try and process it anyways.*/
504 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_md_name_hex,
505 tvb, maid_offset, cfm_maid_md_name_length, ENC_NA);
506 } else {
507 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_md_name_mac,
508 tvb, maid_offset, 6, ENC_NA);
509 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_md_name_mac_id,
510 tvb, maid_offset+6, 2, ENC_NA);
512 } else {
513 /* MD name format is regular string or DNS string */
514 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_md_name_string,
515 tvb, maid_offset, cfm_maid_md_name_length, ENC_ASCII|ENC_NA);
517 maid_offset += cfm_maid_md_name_length;
520 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_ma_name_format, tvb, maid_offset, 1, ENC_BIG_ENDIAN);
521 cfm_maid_ma_name_format = tvb_get_guint8(tvb, maid_offset);
522 maid_offset += 1;
523 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_ma_name_length, tvb, maid_offset, 1, ENC_BIG_ENDIAN);
524 cfm_maid_ma_name_length = tvb_get_guint8(tvb, maid_offset);
525 maid_offset += 1;
526 if ((cfm_maid_ma_name_format == 2) ||
527 (cfm_maid_ma_name_format == 32)) {
528 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_ma_name_string,
529 tvb, maid_offset, cfm_maid_ma_name_length, ENC_ASCII|ENC_NA);
530 } else {
531 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_ma_name_hex,
532 tvb, maid_offset, cfm_maid_ma_name_length, ENC_NA);
534 maid_offset += cfm_maid_ma_name_length;
535 offset += 48;
536 if (offset > maid_offset) {
537 gint padding_length;
538 padding_length = offset - maid_offset;
539 proto_tree_add_item(cfm_ccm_maid_tree, hf_cfm_maid_padding,
540 tvb, maid_offset, padding_length, ENC_NA);
543 /* Dissect 16 octets reserved for Y.1731, samples of the wrap-around frame counters */
544 wi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_ccm_itu_t_y1731, tvb, offset, 16, ENC_NA);
545 cfm_ccm_itu_tree = proto_item_add_subtree(wi, ett_cfm_ccm_itu);
546 proto_tree_add_item(cfm_ccm_itu_tree, hf_cfm_itu_TxFCf, tvb, offset, 4, ENC_NA);
547 offset += 4;
548 proto_tree_add_item(cfm_ccm_itu_tree, hf_cfm_itu_RxFCb, tvb, offset, 4, ENC_NA);
549 offset += 4;
550 proto_tree_add_item(cfm_ccm_itu_tree, hf_cfm_itu_TxFCb, tvb, offset, 4, ENC_NA);
551 offset += 4;
552 proto_tree_add_item(cfm_ccm_itu_tree, hf_cfm_itu_reserved, tvb, offset, 4, ENC_NA);
553 offset += 4;
555 return offset;
558 static int dissect_cfm_lbm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
560 proto_item *ti;
561 proto_tree *cfm_pdu_tree;
563 ti = proto_tree_add_item(tree, hf_cfm_lbm_pdu, tvb, offset, -1, ENC_NA);
564 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
566 proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
567 offset += 1;
568 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
569 offset += 1;
570 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lb_transaction_id, tvb, offset, 4, ENC_BIG_ENDIAN);
571 offset += 4;
572 return offset;
575 static int dissect_cfm_lbr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
577 proto_item *ti;
578 proto_tree *cfm_pdu_tree;
580 ti = proto_tree_add_item(tree, hf_cfm_lbr_pdu, tvb, offset, -1, ENC_NA);
581 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
583 proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
584 offset += 1;
585 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
586 offset += 1;
587 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lb_transaction_id, tvb, offset, 4, ENC_BIG_ENDIAN);
588 offset += 4;
589 return offset;
592 static int dissect_cfm_ltm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
594 proto_item *ti;
595 proto_item *fi;
596 proto_tree *cfm_pdu_tree;
597 proto_tree *cfm_flag_tree;
599 ti = proto_tree_add_item(tree, hf_cfm_ltm_pdu, tvb, offset, -1, ENC_NA);
600 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
602 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
603 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
604 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_UseFDBonly, tvb, offset, 1, ENC_BIG_ENDIAN);
605 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_ltm_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
606 offset += 1;
608 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
609 offset += 1;
610 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lt_transaction_id, tvb, offset, 4, ENC_BIG_ENDIAN);
611 offset += 4;
612 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lt_ttl, tvb, offset, 1, ENC_BIG_ENDIAN);
613 offset += 1;
614 proto_tree_add_item(cfm_pdu_tree, hf_cfm_ltm_orig_addr, tvb, offset, 6, ENC_NA);
615 offset += 6;
616 proto_tree_add_item(cfm_pdu_tree, hf_cfm_ltm_targ_addr, tvb, offset, 6, ENC_NA);
617 offset += 6;
618 return offset;
621 static int dissect_cfm_ltr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
623 proto_item *ti;
624 proto_item *fi;
625 proto_tree *cfm_pdu_tree;
626 proto_tree *cfm_flag_tree;
628 ti = proto_tree_add_item(tree, hf_cfm_ltr_pdu, tvb, offset, -1, ENC_NA);
629 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
631 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
632 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
633 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_UseFDBonly, tvb, offset, 1, ENC_BIG_ENDIAN);
634 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_FwdYes, tvb, offset, 1, ENC_BIG_ENDIAN);
635 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_TerminalMEP, tvb, offset, 1, ENC_BIG_ENDIAN);
636 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_ltr_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
637 offset += 1;
639 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
640 offset += 1;
641 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lt_transaction_id, tvb, offset, 4, ENC_BIG_ENDIAN);
642 offset += 4;
643 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lt_ttl, tvb, offset, 1, ENC_BIG_ENDIAN);
644 offset += 1;
645 proto_tree_add_item(cfm_pdu_tree, hf_cfm_ltr_relay_action, tvb, offset, 1, ENC_BIG_ENDIAN);
646 offset += 1;
647 return offset;
650 static int dissect_cfm_ais(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
652 proto_item *ti;
653 proto_item *fi;
654 proto_tree *cfm_pdu_tree;
655 proto_tree *cfm_flag_tree;
657 ti = proto_tree_add_item(tree, hf_cfm_ais_pdu, tvb, offset, -1, ENC_NA);
658 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
660 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
661 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
662 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_ais_lck_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
663 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_ais_lck_Period, tvb, offset, 1, ENC_BIG_ENDIAN);
664 offset += 1;
666 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
667 offset += 1;
669 return offset;
672 static int dissect_cfm_lck(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
674 proto_item *ti;
675 proto_item *fi;
676 proto_tree *cfm_pdu_tree;
677 proto_tree *cfm_flag_tree;
679 ti = proto_tree_add_item(tree, hf_cfm_lck_pdu, tvb, offset, -1, ENC_NA);
680 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
682 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
683 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
684 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_ais_lck_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
685 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_ais_lck_Period, tvb, offset, 1, ENC_BIG_ENDIAN);
686 offset += 1;
688 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
689 offset += 1;
691 return offset;
694 static int dissect_cfm_tst(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
696 proto_item *ti;
697 proto_item *fi;
698 proto_tree *cfm_pdu_tree;
699 proto_tree *cfm_flag_tree;
701 ti = proto_tree_add_item(tree, hf_cfm_tst_pdu, tvb, offset, -1, ENC_NA);
702 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
704 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
705 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
706 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
707 offset += 1;
709 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
710 offset += 1;
712 proto_tree_add_item(cfm_pdu_tree, hf_cfm_tst_sequence_num, tvb, offset, 4, ENC_BIG_ENDIAN);
713 offset += 4;
715 return offset;
718 static int dissect_cfm_aps(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
720 proto_item *ti;
721 proto_item *fi;
722 proto_tree *cfm_pdu_tree;
723 proto_tree *cfm_flag_tree;
725 ti = proto_tree_add_item(tree, hf_cfm_aps_pdu, tvb, offset, -1, ENC_NA);
726 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
728 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
729 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
730 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
731 offset += 1;
733 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
734 offset += 1;
736 proto_tree_add_item(cfm_pdu_tree, hf_cfm_aps_req_st, tvb, offset, 1, ENC_BIG_ENDIAN);
737 proto_tree_add_item(cfm_pdu_tree, hf_cfm_aps_protection_type_A, tvb, offset, 1, ENC_BIG_ENDIAN);
738 proto_tree_add_item(cfm_pdu_tree, hf_cfm_aps_protection_type_B, tvb, offset, 1, ENC_BIG_ENDIAN);
739 proto_tree_add_item(cfm_pdu_tree, hf_cfm_aps_protection_type_D, tvb, offset, 1, ENC_BIG_ENDIAN);
740 proto_tree_add_item(cfm_pdu_tree, hf_cfm_aps_protection_type_R, tvb, offset, 1, ENC_BIG_ENDIAN);
741 offset += 1;
743 proto_tree_add_item(cfm_pdu_tree, hf_cfm_aps_requested_signal, tvb, offset, 1, ENC_BIG_ENDIAN);
744 offset += 1;
746 proto_tree_add_item(cfm_pdu_tree, hf_cfm_aps_bridged_signal, tvb, offset, 1, ENC_BIG_ENDIAN);
747 offset += 1;
749 proto_tree_add_item(cfm_pdu_tree, hf_cfm_aps_bridge_type, tvb, offset, 1, ENC_BIG_ENDIAN);
750 offset += 1;
752 return offset;
755 static int dissect_cfm_raps(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
757 proto_item *ti;
758 proto_item *fi;
759 proto_item *ri;
760 proto_tree *cfm_pdu_tree;
761 proto_tree *cfm_flag_tree;
762 proto_tree *raps_flag_tree;
763 guint8 raps_version;
764 guint8 raps_requeststate;
766 raps_version = tvb_get_guint8(tvb, CFM_VERSION);
767 raps_version &= 0x1F;
769 ti = proto_tree_add_item(tree, hf_cfm_raps_pdu, tvb, offset, -1, ENC_NA);
770 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
772 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
773 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
774 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
775 offset += 1;
777 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
778 offset += 1;
780 proto_tree_add_item(cfm_pdu_tree, hf_cfm_raps_req_st, tvb, offset, 1, ENC_BIG_ENDIAN);
782 raps_requeststate = tvb_get_guint8(tvb, offset);
783 raps_requeststate >>= 4;
785 /* R-APS(G.8032) v2 & Request/state "Event" only */
786 if(raps_version == 1 && raps_requeststate == RAPS_REQUESTSTATE_EVENT){
787 proto_tree_add_item(cfm_pdu_tree, hf_cfm_raps_event_subcode, tvb, offset, 1, ENC_BIG_ENDIAN);
790 offset += 1;
792 ri = proto_tree_add_item(cfm_pdu_tree, hf_cfm_raps_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
793 raps_flag_tree = proto_item_add_subtree(ri, ett_cfm_raps_flags);
794 proto_tree_add_item(raps_flag_tree, hf_cfm_raps_flags_rb, tvb, offset, 1, ENC_BIG_ENDIAN);
795 proto_tree_add_item(raps_flag_tree, hf_cfm_raps_flags_dnf, tvb, offset, 1, ENC_BIG_ENDIAN);
797 /* R-APS(G.8032) v2 only */
798 if(raps_version == 1){
799 proto_tree_add_item(raps_flag_tree, hf_cfm_raps_flags_bpr, tvb, offset, 1, ENC_BIG_ENDIAN);
802 offset += 1;
804 proto_tree_add_item(cfm_pdu_tree, hf_cfm_raps_node_id, tvb, offset, 6, ENC_NA);
805 offset += 6;
807 proto_tree_add_item(cfm_pdu_tree, hf_cfm_raps_reserved, tvb, offset, 24, ENC_NA);
808 offset += 24;
810 return offset;
813 static int dissect_cfm_mcc(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
815 gint cfm_tlv_offset;
816 proto_item *ti;
817 proto_item *fi;
818 proto_tree *cfm_pdu_tree;
819 proto_tree *cfm_flag_tree;
821 ti = proto_tree_add_item(tree, hf_cfm_mcc_pdu, tvb, offset, -1, ENC_NA);
822 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
824 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
825 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
826 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
827 offset += 1;
829 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
830 offset += 1;
832 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_oui, tvb, offset, 3, ENC_NA);
833 offset += 3;
834 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_subtype, tvb, offset, 1, ENC_NA);
835 offset += 1;
837 /* The MCC data field was not defined at the time of this code being written
838 * ITU-T Y.1731 (05/2006), so we are simply going to determine the length based on
839 * the TLV offset and perform a hex dump */
840 cfm_tlv_offset = tvb_get_guint8(tvb, 3);
841 /* Remove OUI and subtype from the offset */
842 cfm_tlv_offset -= 4;
843 if (cfm_tlv_offset > 0) {
844 proto_tree_add_item(cfm_pdu_tree, hf_cfm_mcc_data, tvb, offset, cfm_tlv_offset, ENC_NA);
845 offset += cfm_tlv_offset;
848 return offset;
851 static int dissect_cfm_lmm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
853 proto_item *ti;
854 proto_item *fi;
855 proto_tree *cfm_pdu_tree;
856 proto_tree *cfm_flag_tree;
858 ti = proto_tree_add_item(tree, hf_cfm_lmm_pdu, tvb, offset, -1, ENC_NA);
859 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
861 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
862 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
863 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
864 offset += 1;
866 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
867 offset += 1;
869 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lmm_lmr_TxFCf, tvb, offset, 4, ENC_NA);
870 offset += 4;
871 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lmm_lmr_RxFCf, tvb, offset, 4, ENC_NA);
872 offset += 4;
873 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lmm_lmr_TxFCb, tvb, offset, 4, ENC_NA);
874 offset += 4;
876 return offset;
879 static int dissect_cfm_lmr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
881 proto_item *ti;
882 proto_item *fi;
883 proto_tree *cfm_pdu_tree;
884 proto_tree *cfm_flag_tree;
886 ti = proto_tree_add_item(tree, hf_cfm_lmr_pdu, tvb, offset, -1, ENC_NA);
887 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
889 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
890 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
891 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
892 offset += 1;
894 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
895 offset += 1;
897 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lmm_lmr_TxFCf, tvb, offset, 4, ENC_NA);
898 offset += 4;
899 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lmm_lmr_RxFCf, tvb, offset, 4, ENC_NA);
900 offset += 4;
901 proto_tree_add_item(cfm_pdu_tree, hf_cfm_lmm_lmr_TxFCb, tvb, offset, 4, ENC_NA);
902 offset += 4;
904 return offset;
907 static int dissect_cfm_odm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
909 proto_item *ti;
910 proto_item *fi;
911 proto_tree *cfm_pdu_tree;
912 proto_tree *cfm_flag_tree;
914 ti = proto_tree_add_item(tree, hf_cfm_odm_pdu, tvb, offset, -1, ENC_NA);
915 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
917 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
918 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
919 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
920 offset += 1;
922 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
923 offset += 1;
925 proto_tree_add_item(cfm_pdu_tree, hf_cfm_odm_dmm_dmr_TxTimestampf, tvb, offset, 8, ENC_NA);
926 offset += 8;
927 proto_tree_add_item(cfm_pdu_tree, hf_cfm_odm_dmm_dmr_RxTimestampf, tvb, offset, 8, ENC_NA);
928 offset += 8;
930 return offset;
933 static int dissect_cfm_dmm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
935 proto_item *ti;
936 proto_item *fi;
937 proto_tree *cfm_pdu_tree;
938 proto_tree *cfm_flag_tree;
940 ti = proto_tree_add_item(tree, hf_cfm_dmm_pdu, tvb, offset, -1, ENC_NA);
941 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
943 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
944 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
945 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
946 offset += 1;
948 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
949 offset += 1;
951 proto_tree_add_item(cfm_pdu_tree, hf_cfm_odm_dmm_dmr_TxTimestampf, tvb, offset, 8, ENC_NA);
952 offset += 8;
953 proto_tree_add_item(cfm_pdu_tree, hf_cfm_odm_dmm_dmr_RxTimestampf, tvb, offset, 8, ENC_NA);
954 offset += 8;
955 proto_tree_add_item(cfm_pdu_tree, hf_cfm_dmm_dmr_TxTimestampb, tvb, offset, 8, ENC_NA);
956 offset += 8;
957 proto_tree_add_item(cfm_pdu_tree, hf_cfm_dmm_dmr_RxTimestampb, tvb, offset, 8, ENC_NA);
958 offset += 8;
960 return offset;
963 static int dissect_cfm_dmr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
965 proto_item *ti;
966 proto_item *fi;
967 proto_tree *cfm_pdu_tree;
968 proto_tree *cfm_flag_tree;
970 ti = proto_tree_add_item(tree, hf_cfm_dmr_pdu, tvb, offset, -1, ENC_NA);
971 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
973 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
974 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
975 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
976 offset += 1;
978 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
979 offset += 1;
981 proto_tree_add_item(cfm_pdu_tree, hf_cfm_odm_dmm_dmr_TxTimestampf, tvb, offset, 8, ENC_NA);
982 offset += 8;
983 proto_tree_add_item(cfm_pdu_tree, hf_cfm_odm_dmm_dmr_RxTimestampf, tvb, offset, 8, ENC_NA);
984 offset += 8;
985 proto_tree_add_item(cfm_pdu_tree, hf_cfm_dmm_dmr_TxTimestampb, tvb, offset, 8, ENC_NA);
986 offset += 8;
987 proto_tree_add_item(cfm_pdu_tree, hf_cfm_dmm_dmr_RxTimestampb, tvb, offset, 8, ENC_NA);
988 offset += 8;
990 return offset;
993 static int dissect_cfm_exm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
995 gint cfm_tlv_offset;
996 proto_item *ti;
997 proto_item *fi;
998 proto_tree *cfm_pdu_tree;
999 proto_tree *cfm_flag_tree;
1001 ti = proto_tree_add_item(tree, hf_cfm_exm_pdu, tvb, offset, -1, ENC_NA);
1002 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
1004 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
1005 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
1006 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
1007 offset += 1;
1009 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
1010 offset += 1;
1012 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_oui, tvb, offset, 3, ENC_NA);
1013 offset += 3;
1014 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_subtype, tvb, offset, 1, ENC_NA);
1015 offset += 1;
1017 /* The EXM data field was not defined at the time of this code being written
1018 * ITU-T Y.1731 (05/2006), so we are simply going to determine the length based on
1019 * the TLV offset and perform a hex dump */
1020 cfm_tlv_offset = tvb_get_guint8(tvb, 3);
1021 /* Remove OUI and subtype from the offset */
1022 cfm_tlv_offset -= 4;
1023 if (cfm_tlv_offset > 0) {
1024 proto_tree_add_item(cfm_pdu_tree, hf_cfm_exm_exr_data, tvb, offset, cfm_tlv_offset, ENC_NA);
1025 offset += cfm_tlv_offset;
1028 return offset;
1031 static int dissect_cfm_exr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1033 gint cfm_tlv_offset;
1034 proto_item *ti;
1035 proto_item *fi;
1036 proto_tree *cfm_pdu_tree;
1037 proto_tree *cfm_flag_tree;
1039 ti = proto_tree_add_item(tree, hf_cfm_exr_pdu, tvb, offset, -1, ENC_NA);
1040 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
1042 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
1043 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
1044 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
1045 offset += 1;
1047 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
1048 offset += 1;
1050 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_oui, tvb, offset, 3, ENC_NA);
1051 offset += 3;
1052 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_subtype, tvb, offset, 1, ENC_NA);
1053 offset += 1;
1055 /* The EXR data field was not defined at the time of this code being written
1056 * ITU-T Y.1731 (05/2006), so we are simply going to determine the length based on
1057 * the TLV offset and perform a hex dump */
1058 cfm_tlv_offset = tvb_get_guint8(tvb, 3);
1059 /* Remove OUI and subtype from the offset */
1060 cfm_tlv_offset -= 4;
1061 if (cfm_tlv_offset > 0) {
1062 proto_tree_add_item(cfm_pdu_tree, hf_cfm_exm_exr_data, tvb, offset, cfm_tlv_offset, ENC_NA);
1063 offset += cfm_tlv_offset;
1066 return offset;
1069 static int dissect_cfm_vsm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1071 gint cfm_tlv_offset;
1072 proto_item *ti;
1073 proto_item *fi;
1074 proto_tree *cfm_pdu_tree;
1075 proto_tree *cfm_flag_tree;
1077 ti = proto_tree_add_item(tree, hf_cfm_vsm_pdu, tvb, offset, -1, ENC_NA);
1078 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
1080 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
1081 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
1082 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
1083 offset += 1;
1085 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
1086 offset += 1;
1088 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_oui, tvb, offset, 3, ENC_NA);
1089 offset += 3;
1090 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_subtype, tvb, offset, 1, ENC_NA);
1091 offset += 1;
1093 /* The VSM data field was not defined at the time of this code being written
1094 * ITU-T Y.1731 (05/2006), so we are simply going to determine the length based on
1095 * the TLV offset and perform a hex dump */
1096 cfm_tlv_offset = tvb_get_guint8(tvb, 3);
1097 /* Remove OUI and subtype from the offset */
1098 cfm_tlv_offset -= 4;
1099 if (cfm_tlv_offset > 0) {
1100 proto_tree_add_item(cfm_pdu_tree, hf_cfm_vsm_vsr_data, tvb, offset, cfm_tlv_offset, ENC_NA);
1101 offset += cfm_tlv_offset;
1104 return offset;
1107 static int dissect_cfm_vsr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1109 gint cfm_tlv_offset;
1110 proto_item *ti;
1111 proto_item *fi;
1112 proto_tree *cfm_pdu_tree;
1113 proto_tree *cfm_flag_tree;
1115 ti = proto_tree_add_item(tree, hf_cfm_vsr_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_BIG_ENDIAN);
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_BIG_ENDIAN);
1121 offset += 1;
1123 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
1124 offset += 1;
1126 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_oui, tvb, offset, 3, ENC_NA);
1127 offset += 3;
1128 proto_tree_add_item(cfm_pdu_tree, hf_tlv_org_spec_subtype, tvb, offset, 1, ENC_NA);
1129 offset += 1;
1131 /* The VSR data field was not defined at the time of this code being written
1132 * ITU-T Y.1731 (05/2006), so we are simply going to determine the length based on
1133 * the TLV offset and perform a hex dump */
1134 cfm_tlv_offset = tvb_get_guint8(tvb, 3);
1135 /* Remove OUI and subtype from the offset */
1136 cfm_tlv_offset -= 4;
1137 if (cfm_tlv_offset > 0) {
1138 proto_tree_add_item(cfm_pdu_tree, hf_cfm_vsm_vsr_data, tvb, offset, cfm_tlv_offset, ENC_NA);
1139 offset += cfm_tlv_offset;
1142 return offset;
1145 static int dissect_cfm_slm(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1147 proto_item *ti;
1148 proto_item *fi;
1149 proto_tree *cfm_pdu_tree;
1150 proto_tree *cfm_flag_tree;
1152 ti = proto_tree_add_item(tree, hf_cfm_slm_pdu, tvb, offset, -1, ENC_NA);
1153 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
1155 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
1156 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
1157 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
1158 offset += 1;
1160 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
1161 offset += 1;
1163 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slm_src_mep, tvb, offset, 2, ENC_NA);
1164 offset += 2;
1165 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slr_rsp_mep, tvb, offset, 2, ENC_NA);
1166 offset += 2;
1167 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slm_testid, tvb, offset, 4, ENC_NA);
1168 offset += 4;
1169 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slm_txfcf, tvb, offset, 4, ENC_BIG_ENDIAN);
1170 offset += 4;
1171 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slr_txfcb, tvb, offset, 4, ENC_BIG_ENDIAN);
1172 offset += 4;
1174 return offset;
1177 static int dissect_cfm_slr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
1179 proto_item *ti;
1180 proto_item *fi;
1181 proto_tree *cfm_pdu_tree;
1182 proto_tree *cfm_flag_tree;
1184 ti = proto_tree_add_item(tree, hf_cfm_slr_pdu, tvb, offset, -1, ENC_NA);
1185 cfm_pdu_tree = proto_item_add_subtree(ti, ett_cfm_pdu);
1187 fi = proto_tree_add_item(cfm_pdu_tree, hf_cfm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
1188 cfm_flag_tree = proto_item_add_subtree(fi, ett_cfm_flags);
1189 proto_tree_add_item(cfm_flag_tree, hf_cfm_flags_Reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
1190 offset += 1;
1192 proto_tree_add_item(cfm_pdu_tree, hf_cfm_first_tlv_offset, tvb, offset, 1, ENC_BIG_ENDIAN);
1193 offset += 1;
1195 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slm_src_mep, tvb, offset, 2, ENC_NA);
1196 offset += 2;
1197 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slr_rsp_mep, tvb, offset, 2, ENC_NA);
1198 offset += 2;
1199 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slm_testid, tvb, offset, 4, ENC_NA);
1200 offset += 4;
1201 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slm_txfcf, tvb, offset, 4, ENC_BIG_ENDIAN);
1202 offset += 4;
1203 proto_tree_add_item(cfm_pdu_tree, hf_cfm_slr_txfcb, tvb, offset, 4, ENC_BIG_ENDIAN);
1204 offset += 4;
1206 return offset;
1210 /* Main CFM EOAM protocol dissector */
1211 static void dissect_cfm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1213 gint offset = 0;
1214 guint8 cfm_pdu_type;
1216 /* display the CFM protol name */
1217 col_set_str(pinfo->cinfo, COL_PROTOCOL, "CFM");
1219 /* Clear out stuff in the info column */
1220 col_clear(pinfo->cinfo, COL_INFO);
1222 /* provide info column with CFM packet type (opcode)*/
1223 cfm_pdu_type = tvb_get_guint8(tvb, CFM_OPCODE);
1225 col_add_fstr(pinfo->cinfo, COL_INFO, "Type %s",
1226 val_to_str(cfm_pdu_type, opcodetypenames, "Unknown (0x%02x)"));
1228 if (tree) { /* we are being asked for details */
1229 gint cfm_tlv_offset;
1230 proto_item *ti;
1231 proto_tree *cfm_tree;
1233 /* isolate the payload of the packet */
1234 ti = proto_tree_add_item(tree, proto_cfm, tvb, 0, -1, ENC_NA);
1237 /* report type of CFM packet to base of dissection tree */
1238 proto_item_append_text(ti, ", Type %s",
1239 val_to_str(cfm_pdu_type, opcodetypenames, "Unknown (0x%02x)"));
1241 /* dissecting the common CFM header */
1242 cfm_tree = proto_item_add_subtree(ti, ett_cfm);
1243 proto_tree_add_item(cfm_tree, hf_cfm_md_level, tvb, offset, 1, ENC_BIG_ENDIAN);
1244 proto_tree_add_item(cfm_tree, hf_cfm_version, tvb, offset, 1, ENC_BIG_ENDIAN);
1245 offset += 1;
1246 proto_tree_add_item(cfm_tree, hf_cfm_opcode, tvb, offset, 1, ENC_BIG_ENDIAN);
1247 offset += 1;
1249 switch(cfm_pdu_type) {
1250 case CCM:
1251 offset = dissect_cfm_ccm(tvb, pinfo, tree, offset);
1252 break;
1253 case LBM:
1254 offset = dissect_cfm_lbm(tvb, pinfo, tree, offset);
1255 break;
1256 case LBR:
1257 offset = dissect_cfm_lbr(tvb, pinfo, tree, offset);
1258 break;
1259 case LTM:
1260 offset = dissect_cfm_ltm(tvb, pinfo, tree, offset);
1261 break;
1262 case LTR:
1263 offset = dissect_cfm_ltr(tvb, pinfo, tree, offset);
1264 break;
1265 case AIS:
1266 offset = dissect_cfm_ais(tvb, pinfo, tree, offset);
1267 break;
1268 case LCK:
1269 offset = dissect_cfm_lck(tvb, pinfo, tree, offset);
1270 break;
1271 case TST:
1272 offset = dissect_cfm_tst(tvb, pinfo, tree, offset);
1273 break;
1274 case APS:
1275 offset = dissect_cfm_aps(tvb, pinfo, tree, offset);
1276 break;
1277 case RAPS:
1278 offset = dissect_cfm_raps(tvb, pinfo, tree, offset);
1279 break;
1280 case MCC:
1281 offset = dissect_cfm_mcc(tvb, pinfo, tree, offset);
1282 break;
1283 case LMM:
1284 offset = dissect_cfm_lmm(tvb, pinfo, tree, offset);
1285 break;
1286 case LMR:
1287 offset = dissect_cfm_lmr(tvb, pinfo, tree, offset);
1288 break;
1289 case ODM:
1290 offset = dissect_cfm_odm(tvb, pinfo, tree, offset);
1291 break;
1292 case DMM:
1293 offset = dissect_cfm_dmm(tvb, pinfo, tree, offset);
1294 break;
1295 case DMR:
1296 offset = dissect_cfm_dmr(tvb, pinfo, tree, offset);
1297 break;
1298 case EXM:
1299 offset = dissect_cfm_exm(tvb, pinfo, tree, offset);
1300 break;
1301 case EXR:
1302 offset = dissect_cfm_exr(tvb, pinfo, tree, offset);
1303 break;
1304 case VSM:
1305 offset = dissect_cfm_vsm(tvb, pinfo, tree, offset);
1306 break;
1307 case VSR:
1308 offset = dissect_cfm_vsr(tvb, pinfo, tree, offset);
1309 break;
1310 case SLM:
1311 offset = dissect_cfm_slm(tvb, pinfo, tree, offset);
1312 break;
1313 case SLR:
1314 offset = dissect_cfm_slr(tvb, pinfo, tree, offset);
1315 break;
1318 /* Get the TLV offset and add the offset of the common CFM header*/
1319 cfm_tlv_offset = tvb_get_guint8(tvb, 3);
1320 cfm_tlv_offset += 4;
1322 /* Begin dissecting the TLV's */
1323 /* the TLV offset should be the same as where the pdu left off or we have a problem */
1324 if ((cfm_tlv_offset == offset) && (cfm_tlv_offset > 3)) {
1325 proto_tree *cfm_all_tlvs_tree;
1326 guint8 cfm_tlv_type = 255;
1327 ti = proto_tree_add_item(tree, hf_cfm_all_tlvs, tvb, cfm_tlv_offset, -1, ENC_NA);
1328 cfm_all_tlvs_tree = proto_item_add_subtree(ti, ett_cfm_all_tlvs);
1330 while (cfm_tlv_type != END_TLV)
1332 guint16 cfm_tlv_length;
1333 gint tlv_header_modifier;
1334 proto_item *fi;
1335 proto_tree *cfm_tlv_tree;
1336 cfm_tlv_type = tvb_get_guint8(tvb, cfm_tlv_offset);
1338 if (cfm_tlv_type == END_TLV) {
1339 tlv_header_modifier = 1;
1340 cfm_tlv_length = 0;
1341 } else {
1342 tlv_header_modifier = 3;
1343 cfm_tlv_length = tvb_get_ntohs(tvb, cfm_tlv_offset+1);
1346 fi = proto_tree_add_text(cfm_all_tlvs_tree, tvb, cfm_tlv_offset, cfm_tlv_length+tlv_header_modifier,
1347 "TLV: %s (t=%d,l=%d)", val_to_str(cfm_tlv_type, tlvtypefieldvalues, "Unknown (0x%02x)"),
1348 cfm_tlv_type, cfm_tlv_length);
1349 cfm_tlv_tree = proto_item_add_subtree(fi, ett_cfm_tlv);
1351 proto_tree_add_item(cfm_tlv_tree, hf_cfm_tlv_type, tvb, cfm_tlv_offset, 1, ENC_BIG_ENDIAN);
1352 cfm_tlv_offset += 1;
1353 if (cfm_tlv_type != END_TLV) {
1354 proto_tree_add_item(cfm_tlv_tree, hf_cfm_tlv_length, tvb, cfm_tlv_offset, 2, ENC_BIG_ENDIAN);
1355 cfm_tlv_offset += 2;
1357 if (cfm_tlv_length != 0) {
1358 gint tlv_data_offset;
1359 guint8 tlv_chassis_id_length;
1360 guint8 tlv_tst_test_pattern_type;
1362 tlv_data_offset = cfm_tlv_offset;
1364 switch(cfm_tlv_type) {
1365 case SENDER_ID_TLV:
1366 proto_tree_add_item(cfm_tlv_tree, hf_tlv_chassis_id_length,
1367 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1368 tlv_chassis_id_length = tvb_get_guint8(tvb,tlv_data_offset);
1369 tlv_data_offset += 1;
1371 if (tlv_chassis_id_length > 0) {
1372 proto_tree_add_item(cfm_tlv_tree, hf_tlv_chassis_id_subtype,
1373 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1374 tlv_data_offset += 1;
1375 proto_tree_add_item(cfm_tlv_tree, hf_tlv_chassis_id,
1376 tvb, tlv_data_offset, tlv_chassis_id_length, ENC_NA);
1377 tlv_data_offset += tlv_chassis_id_length;
1380 /* If the TLV length is greater than the number of octets used for the
1381 * Chassis ID, then we must have a Management Address Domain */
1382 if (cfm_tlv_length > (2 + tlv_chassis_id_length)) {
1383 guint8 tlv_ma_domain_length;
1384 proto_tree_add_item(cfm_tlv_tree, hf_tlv_ma_domain_length,
1385 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1386 tlv_ma_domain_length = tvb_get_guint8(tvb,tlv_data_offset);
1387 tlv_data_offset += 1;
1388 if (tlv_ma_domain_length > 0) {
1389 proto_tree_add_item(cfm_tlv_tree, hf_tlv_ma_domain,
1390 tvb, tlv_data_offset, tlv_ma_domain_length, ENC_NA);
1391 tlv_data_offset += tlv_ma_domain_length;
1394 /* If the TLV length is greater than the number of octets used for the
1395 * Chassis ID and the Management Address Domain, then we must have a
1396 * Management Address */
1397 if (cfm_tlv_length > (2 + tlv_chassis_id_length + 1 + tlv_ma_domain_length)) {
1398 guint8 tlv_management_addr_length;
1399 proto_tree_add_item(cfm_tlv_tree, hf_tlv_management_addr_length,
1400 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1401 tlv_management_addr_length = tvb_get_guint8(tvb,tlv_data_offset);
1402 tlv_data_offset += 1;
1403 if (tlv_management_addr_length > 0) {
1404 proto_tree_add_item(cfm_tlv_tree, hf_tlv_management_addr,
1405 tvb, tlv_data_offset, tlv_management_addr_length, ENC_NA);
1406 tlv_data_offset += tlv_management_addr_length;
1410 break;
1411 case PORT_STAT_TLV:
1412 proto_tree_add_item(cfm_tlv_tree, hf_tlv_port_status_value,
1413 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1414 tlv_data_offset += 1;
1415 break;
1416 case DATA_TLV:
1417 proto_tree_add_item(cfm_tlv_tree, hf_tlv_data_value,
1418 tvb, tlv_data_offset, cfm_tlv_length, ENC_NA);
1419 tlv_data_offset += cfm_tlv_length;
1420 break;
1421 case INTERF_STAT_TLV:
1422 proto_tree_add_item(cfm_tlv_tree, hf_tlv_interface_status_value,
1423 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1424 tlv_data_offset += 1;
1425 break;
1426 case REPLY_ING_TLV:
1427 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_ingress_action,
1428 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1429 tlv_data_offset += 1;
1430 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_ingress_mac_address,
1431 tvb, tlv_data_offset, 6, ENC_NA);
1432 tlv_data_offset += 6;
1434 /* For the IEEE standard if the TLV length is greater than 7 then we have
1435 * an ingress port ID
1437 if (cfm_tlv_length > 7) {
1438 guint8 tlv_reply_ingress_portid_length;
1439 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_ing_egr_portid_length,
1440 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1441 tlv_reply_ingress_portid_length = tvb_get_guint8(tvb,tlv_data_offset);
1442 tlv_data_offset += 1;
1444 if (tlv_reply_ingress_portid_length > 0) {
1445 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_ing_egr_portid_subtype,
1446 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1447 tlv_data_offset += 1;
1448 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_ing_egr_portid,
1449 tvb, tlv_data_offset, tlv_reply_ingress_portid_length, ENC_NA);
1450 tlv_data_offset += tlv_reply_ingress_portid_length;
1453 break;
1454 case REPLY_EGR_TLV:
1455 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_egress_action,
1456 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1457 tlv_data_offset += 1;
1458 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_egress_mac_address,
1459 tvb, tlv_data_offset, 6, ENC_NA);
1460 tlv_data_offset += 6;
1462 /* For the IEEE standard if the TLV length is greater than 7 then we have
1463 * an egress port ID
1465 if (cfm_tlv_length > 7) {
1466 guint8 tlv_reply_egress_portid_length;
1467 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_ing_egr_portid_length,
1468 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1469 tlv_reply_egress_portid_length = tvb_get_guint8(tvb,tlv_data_offset);
1470 tlv_data_offset += 1;
1472 if (tlv_reply_egress_portid_length > 0) {
1473 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_ing_egr_portid_subtype,
1474 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1475 tlv_data_offset += 1;
1476 proto_tree_add_item(cfm_tlv_tree, hf_tlv_reply_ing_egr_portid,
1477 tvb, tlv_data_offset, tlv_reply_egress_portid_length, ENC_NA);
1478 tlv_data_offset += tlv_reply_egress_portid_length;
1481 break;
1482 case LTM_EGR_ID_TLV:
1483 proto_tree_add_item(cfm_tlv_tree, hf_tlv_ltm_egress_id_unique_identifier,
1484 tvb, tlv_data_offset, 2, ENC_NA);
1485 tlv_data_offset += 2;
1486 proto_tree_add_item(cfm_tlv_tree, hf_tlv_ltm_egress_id_mac,
1487 tvb, tlv_data_offset, 6, ENC_NA);
1488 tlv_data_offset += 6;
1489 break;
1490 case LTR_EGR_ID_TLV:
1491 proto_tree_add_item(cfm_tlv_tree, hf_tlv_ltr_egress_last_id_unique_identifier,
1492 tvb, tlv_data_offset, 2, ENC_NA);
1493 tlv_data_offset += 2;
1494 proto_tree_add_item(cfm_tlv_tree, hf_tlv_ltr_egress_last_id_mac,
1495 tvb, tlv_data_offset, 6, ENC_NA);
1496 tlv_data_offset += 6;
1497 proto_tree_add_item(cfm_tlv_tree, hf_tlv_ltr_egress_next_id_unique_identifier,
1498 tvb, tlv_data_offset, 2, ENC_NA);
1499 tlv_data_offset += 2;
1500 proto_tree_add_item(cfm_tlv_tree, hf_tlv_ltr_egress_next_id_mac,
1501 tvb, tlv_data_offset, 6, ENC_NA);
1502 tlv_data_offset += 6;
1503 break;
1504 case ORG_SPEC_TLV:
1505 /* The TLV length must be long enough to include the OUI
1506 * and the subtype.
1508 if (cfm_tlv_length > 3) {
1509 proto_tree_add_item(cfm_tlv_tree, hf_tlv_org_spec_oui,
1510 tvb, tlv_data_offset, 3, ENC_NA);
1511 tlv_data_offset += 3;
1512 proto_tree_add_item(cfm_tlv_tree, hf_tlv_org_spec_subtype,
1513 tvb, tlv_data_offset, 1, ENC_NA);
1514 tlv_data_offset += 1;
1515 proto_tree_add_item(cfm_tlv_tree, hf_tlv_org_spec_value,
1516 tvb, tlv_data_offset, cfm_tlv_length-4, ENC_NA);
1517 tlv_data_offset -= 4;
1519 tlv_data_offset += cfm_tlv_length;
1520 break;
1521 case TEST_TLV:
1522 /* There is a discrepancy in the recommendation ITU-T Y.1731
1523 * where the test pattern type may or may not be included in
1524 * the TLV length. Going to assume that it is included in the
1525 * length which corresponds with the typical format for TLV's
1526 * until the recommendation is more clear in this regard. */
1527 proto_tree_add_item(cfm_tlv_tree, hf_tlv_tst_test_pattern_type,
1528 tvb, tlv_data_offset, 1, ENC_BIG_ENDIAN);
1529 tlv_tst_test_pattern_type = tvb_get_guint8(tvb,tlv_data_offset);
1530 tlv_data_offset += 1;
1531 if (cfm_tlv_length > 0) {
1532 switch (tlv_tst_test_pattern_type) {
1533 case 0:
1534 case 2:
1535 proto_tree_add_item(cfm_tlv_tree, hf_tlv_tst_test_pattern,
1536 tvb, tlv_data_offset, cfm_tlv_length-1, ENC_NA);
1537 tlv_data_offset += cfm_tlv_length;
1538 break;
1539 case 1:
1540 case 3:
1541 proto_tree_add_item(cfm_tlv_tree, hf_tlv_tst_test_pattern,
1542 tvb, tlv_data_offset, cfm_tlv_length-5, ENC_NA);
1543 tlv_data_offset += (cfm_tlv_length-5);
1544 proto_tree_add_item(cfm_tlv_tree, hf_tlv_tst_CRC32,
1545 tvb, tlv_data_offset, 4, ENC_NA);
1546 tlv_data_offset += 4;
1547 break;
1550 break;
1554 cfm_tlv_offset += tlv_data_offset;
1562 /* Register CFM EOAM protocol */
1563 void proto_register_cfm(void)
1565 static hf_register_info hf[] = {
1566 { &hf_cfm_md_level,
1567 { "CFM MD Level", "cfm.md.level", FT_UINT8,
1568 BASE_DEC, NULL, 0xe0, NULL, HFILL }
1570 { &hf_cfm_version,
1571 { "CFM Version", "cfm.version", FT_UINT8,
1572 BASE_DEC, NULL, 0x1f, NULL, HFILL }
1574 { &hf_cfm_opcode,
1575 { "CFM OpCode", "cfm.opcode", FT_UINT8,
1576 BASE_DEC, VALS(opcodetypenames), 0x0, NULL, HFILL }
1579 /* CFM CCM*/
1580 { &hf_cfm_ccm_pdu,
1581 { "CFM CCM PDU", "cfm.ccm.pdu", FT_NONE,
1582 BASE_NONE, NULL, 0x0, NULL, HFILL }
1584 { &hf_cfm_flags,
1585 { "Flags", "cfm.flags", FT_UINT8,
1586 BASE_HEX, NULL, 0x0, NULL, HFILL }
1588 { &hf_cfm_flags_RDI,
1589 { "RDI", "cfm.flags.rdi", FT_UINT8,
1590 BASE_DEC, NULL, 0x80, NULL, HFILL }
1592 { &hf_cfm_flags_ccm_Reserved,
1593 { "Reserved", "cfm.flags.ccm.reserved", FT_UINT8,
1594 BASE_DEC, NULL, 0x78, NULL, HFILL }
1596 { &hf_cfm_flags_Interval,
1597 { "Interval Field", "cfm.flags.interval", FT_UINT8,
1598 BASE_DEC, VALS(CCM_IntervalFieldEncoding), 0x07, NULL, HFILL }
1600 { &hf_cfm_first_tlv_offset,
1601 { "First TLV Offset", "cfm.first.tlv.offset", FT_UINT8,
1602 BASE_DEC, NULL, 0x0, NULL, HFILL }
1604 { &hf_cfm_ccm_seq_number,
1605 { "Sequence Number", "cfm.ccm.seq.num", FT_UINT32,
1606 BASE_DEC, NULL, 0x0, NULL, HFILL }
1608 { &hf_cfm_ccm_ma_ep_id,
1609 { "Maintenance Association End Point Identifier", "cfm.ccm.ma.ep.id",
1610 FT_UINT16, BASE_DEC, NULL, 0x1FFF, NULL, HFILL }
1612 { &hf_cfm_ccm_maid,
1613 { "Maintenance Association Identifier (MEG ID)", "cfm.ccm.maid", FT_NONE,
1614 BASE_NONE, NULL, 0x0, NULL, HFILL }
1616 { &hf_cfm_maid_md_name_format,
1617 { "MD Name Format", "cfm.maid.md.name.format", FT_UINT8,
1618 BASE_DEC, VALS(mdnameformattypes), 0x0, NULL, HFILL }
1620 { &hf_cfm_maid_md_name_length,
1621 { "MD Name Length", "cfm.maid.md.name.length", FT_UINT8,
1622 BASE_DEC, NULL, 0x0, NULL, HFILL }
1624 { &hf_cfm_maid_md_name_string,
1625 { "MD Name (String)", "cfm.maid.md.name.string", FT_STRING,
1626 BASE_NONE, NULL, 0x0, NULL, HFILL }
1628 { &hf_cfm_maid_md_name_hex,
1629 { "MD Name", "cfm.maid.md.name.hex", FT_BYTES,
1630 BASE_NONE, NULL, 0x0, NULL, HFILL }
1632 { &hf_cfm_maid_md_name_mac,
1633 { "MD Name (MAC)", "cfm.maid.md.name.mac", FT_ETHER,
1634 BASE_NONE, NULL, 0x0, NULL, HFILL }
1636 { &hf_cfm_maid_md_name_mac_id,
1637 { "MD Name (MAC)", "cfm.maid.md.name.mac.id", FT_BYTES,
1638 BASE_NONE, NULL, 0x0, NULL, HFILL }
1640 { &hf_cfm_maid_ma_name_format,
1641 { "Short MA Name (MEG ID) Format", "cfm.maid.ma.name.format", FT_UINT8,
1642 BASE_DEC, VALS(manameformattypes), 0x0, NULL, HFILL }
1644 { &hf_cfm_maid_ma_name_length,
1645 { "Short MA Name (MEG ID) Length", "cfm.maid.ma.name.length", FT_UINT8,
1646 BASE_DEC, NULL, 0x0, NULL, HFILL }
1648 { &hf_cfm_maid_ma_name_string,
1649 { "Short MA Name", "cfm.maid.ma.name.string", FT_STRING,
1650 BASE_NONE, NULL, 0x0, NULL, HFILL }
1652 { &hf_cfm_maid_ma_name_hex,
1653 { "Short MA Name", "cfm.maid.ma.name.hex", FT_BYTES,
1654 BASE_NONE, NULL, 0x0, NULL, HFILL }
1656 { &hf_cfm_maid_padding,
1657 { "Zero-Padding", "cfm.ccm.maid.padding", FT_NONE,
1658 BASE_NONE, NULL, 0x0, NULL, HFILL }
1660 { &hf_cfm_ccm_itu_t_y1731,
1661 { "Defined by ITU-T Y.1731", "cfm.ccm.itu.t.y1731", FT_NONE,
1662 BASE_NONE, NULL, 0x0, NULL, HFILL }
1664 { &hf_cfm_itu_TxFCf,
1665 { "TxFCf", "cfm.itu.txfcf", FT_BYTES,
1666 BASE_NONE, NULL, 0x0, NULL, HFILL }
1668 { &hf_cfm_itu_RxFCb,
1669 { "RxFCb", "cfm.itu.rxfcb", FT_BYTES,
1670 BASE_NONE, NULL, 0x0, NULL, HFILL }
1672 { &hf_cfm_itu_TxFCb,
1673 { "TxFCb", "cfm.itu.txfcb", FT_BYTES,
1674 BASE_NONE, NULL, 0x0, NULL, HFILL }
1676 { &hf_cfm_itu_reserved,
1677 { "Reserved", "cfm.itu.reserved", FT_BYTES,
1678 BASE_NONE, NULL, 0x0, NULL, HFILL }
1681 /* CFM LBM*/
1682 { &hf_cfm_lbm_pdu,
1683 { "CFM LBM PDU", "cfm.lbm.pdu", FT_NONE,
1684 BASE_NONE, NULL, 0x0, NULL, HFILL }
1686 { &hf_cfm_lb_transaction_id,
1687 { "Loopback Transaction Identifier", "cfm.lb.transaction.id", FT_UINT32,
1688 BASE_DEC, NULL, 0x0, NULL, HFILL }
1691 /* CFM LBR*/
1692 { &hf_cfm_lbr_pdu,
1693 { "CFM LBR PDU", "cfm.lbr.pdu", FT_NONE,
1694 BASE_NONE, NULL, 0x0, NULL, HFILL }
1697 /* CFM LTM*/
1698 { &hf_cfm_ltm_pdu,
1699 { "CFM LTM PDU", "cfm.ltm.pdu", FT_NONE,
1700 BASE_NONE, NULL, 0x0, NULL, HFILL }
1702 { &hf_cfm_flags_UseFDBonly,
1703 { "UseFDBonly", "cfm.flags.usefdbonly", FT_UINT8,
1704 BASE_DEC, NULL, 0x80, NULL, HFILL }
1706 { &hf_cfm_flags_ltm_Reserved,
1707 { "Reserved", "cfm.flags.ltm.reserved", FT_UINT8,
1708 BASE_DEC, NULL, 0x7F, NULL, HFILL }
1710 { &hf_cfm_lt_transaction_id,
1711 { "Linktrace Transaction Identifier", "cfm.lt.transaction.id", FT_UINT32,
1712 BASE_DEC, NULL, 0x0, NULL, HFILL }
1714 { &hf_cfm_lt_ttl,
1715 { "Linktrace TTL", "cfm.lt.ttl", FT_UINT8,
1716 BASE_DEC, NULL, 0x0, NULL, HFILL }
1718 { &hf_cfm_ltm_orig_addr,
1719 { "Linktrace Message: Original Address", "cfm.ltm.orig.addr", FT_ETHER,
1720 BASE_NONE, NULL, 0x0, NULL, HFILL }
1722 { &hf_cfm_ltm_targ_addr,
1723 { "Linktrace Message: Target Address", "cfm.ltm.targ.addr", FT_ETHER,
1724 BASE_NONE, NULL, 0x0, NULL, HFILL }
1727 /* CFM LTR*/
1728 { &hf_cfm_ltr_pdu,
1729 { "CFM LTR PDU", "cfm.ltr.pdu", FT_NONE,
1730 BASE_NONE, NULL, 0x0, NULL, HFILL }
1732 { &hf_cfm_flags_FwdYes,
1733 { "FwdYes", "cfm.flags.fwdyes", FT_UINT8,
1734 BASE_DEC, NULL, 0x40, NULL, HFILL }
1736 { &hf_cfm_flags_TerminalMEP,
1737 { "TerminalMEP", "cfm.flags.ltr.terminalmep", FT_UINT8,
1738 BASE_DEC, NULL, 0x20, NULL, HFILL }
1740 { &hf_cfm_flags_ltr_Reserved,
1741 { "Reserved", "cfm.flags.ltr.reserved", FT_UINT8,
1742 BASE_DEC, NULL, 0x1F, NULL, HFILL }
1744 { &hf_cfm_ltr_relay_action,
1745 { "Linktrace Reply Relay Action", "cfm.ltr.relay.action", FT_UINT8,
1746 BASE_DEC, VALS(relayactiontypes), 0x0, NULL, HFILL}
1749 /* CFM AIS*/
1750 { &hf_cfm_ais_pdu,
1751 { "CFM AIS PDU", "cfm.ais.pdu", FT_NONE,
1752 BASE_NONE, NULL, 0x0, NULL, HFILL }
1754 { &hf_cfm_flags_ais_lck_Reserved,
1755 { "Reserved", "cfm.flags.ais_lck_Reserved", FT_UINT8,
1756 BASE_DEC, NULL, 0xF8, NULL, HFILL }
1758 { &hf_cfm_flags_ais_lck_Period,
1759 { "Period", "cfm.flags.ais_lck_Period", FT_UINT8,
1760 BASE_DEC, VALS(aislckperiodtypes), 0x07, NULL, HFILL }
1763 /* CFM LCK */
1764 { &hf_cfm_lck_pdu,
1765 { "CFM LCK PDU", "cfm.lck.pdu", FT_NONE,
1766 BASE_NONE, NULL, 0x0, NULL, HFILL }
1769 /* CFM TST */
1770 { &hf_cfm_tst_pdu,
1771 { "CFM TST PDU", "cfm.tst.pdu", FT_NONE,
1772 BASE_NONE, NULL, 0x0, NULL, HFILL }
1774 { &hf_cfm_flags_Reserved,
1775 { "Reserved", "cfm.flags.reserved", FT_UINT8,
1776 BASE_DEC, NULL, 0x0, NULL, HFILL }
1778 { &hf_cfm_tst_sequence_num,
1779 { "Sequence Number", "cfm.tst.sequence.num", FT_UINT32,
1780 BASE_DEC, NULL, 0x0, NULL, HFILL }
1783 /* CFM APS */
1784 { &hf_cfm_aps_pdu,
1785 { "CFM APS PDU", "cfm.aps.pdu", FT_NONE,
1786 BASE_NONE, NULL, 0x0, NULL, HFILL }
1788 { &hf_cfm_aps_req_st,
1789 { "Request/State", "cfm.raps.req.st", FT_UINT8,
1790 BASE_DEC, VALS(aps_request_state_values), 0xf0, NULL, HFILL }
1792 { &hf_cfm_aps_protection_type_A,
1793 { "Protection type A", "cfm.aps.protec.type.A", FT_BOOLEAN,
1794 8, TFS(&aps_protection_type_A_values), 0x08, NULL, HFILL }
1796 { &hf_cfm_aps_protection_type_B,
1797 { "Protection type B", "cfm.aps.protec.type.B", FT_BOOLEAN,
1798 8, TFS(&aps_protection_type_B_values), 0x04, NULL, HFILL }
1800 { &hf_cfm_aps_protection_type_D,
1801 { "Protection type D", "cfm.aps.protec.type.D", FT_BOOLEAN,
1802 8, TFS(&aps_protection_type_D_values), 0x02, NULL, HFILL }
1804 { &hf_cfm_aps_protection_type_R,
1805 { "Protection type R", "cfm.aps.protec.type.R", FT_BOOLEAN,
1806 8, TFS(&aps_protection_type_R_values), 0x01, NULL, HFILL }
1808 { &hf_cfm_aps_requested_signal,
1809 { "Requested signal", "cfm.aps.req.sgnl", FT_UINT8,
1810 BASE_HEX, VALS(aps_requested_signal_values), 0x0, NULL, HFILL }
1812 { &hf_cfm_aps_bridged_signal,
1813 { "Bridged signal", "cfm.aps.brdgd.sgnl", FT_UINT8,
1814 BASE_HEX, VALS(aps_bridged_signal_values), 0x0, NULL, HFILL }
1816 { &hf_cfm_aps_bridge_type,
1817 { "Bridge type", "cfm.aps.bridge.type", FT_UINT8,
1818 BASE_HEX, VALS(aps_bridge_type_values), 0x80, NULL, HFILL }
1821 /* CFM R-APS */
1822 { &hf_cfm_raps_pdu,
1823 { "CFM R-APS PDU", "cfm.raps.pdu", FT_NONE,
1824 BASE_NONE, NULL, 0x0, NULL, HFILL }
1826 { &hf_cfm_raps_req_st,
1827 { "Request/State", "cfm.raps.req.st", FT_UINT8,
1828 BASE_HEX, VALS(rapsrequeststatevalues), 0xF0, NULL, HFILL }
1830 { &hf_cfm_raps_event_subcode,
1831 { "Sub-code", "cfm.raps.event.subcode", FT_UINT8,
1832 BASE_HEX, VALS(rapseventsubcode), 0x0F, NULL, HFILL }
1834 { &hf_cfm_raps_flags,
1835 { "R-APS Flags", "cfm.raps.flags", FT_UINT8,
1836 BASE_HEX, NULL, 0x0, NULL, HFILL }
1838 { &hf_cfm_raps_flags_rb,
1839 { "RPL Blocked", "cfm.raps.flags.rb", FT_BOOLEAN,
1840 8, TFS(&rapsrplblockedvalues), 0x80, NULL, HFILL }
1842 { &hf_cfm_raps_flags_dnf,
1843 { "Do Not Flush", "cfm.raps.flags.dnf", FT_BOOLEAN,
1844 8, TFS(&rapsdnfvalues), 0x40, NULL, HFILL }
1846 { &hf_cfm_raps_flags_bpr,
1847 { "Blocked Port Reference", "cfm.raps.flags.bpr", FT_BOOLEAN,
1848 8, TFS(&rapsbprvalues), 0x20, NULL, HFILL }
1850 { &hf_cfm_raps_node_id,
1851 { "R-APS Node ID", "cfm.raps.node.id", FT_ETHER,
1852 BASE_NONE, NULL, 0x0, NULL, HFILL }
1854 { &hf_cfm_raps_reserved,
1855 { "R-APS Reserved", "cfm.raps.reserved", FT_BYTES,
1856 BASE_NONE, NULL, 0x0, NULL, HFILL }
1859 /* CFM MCC */
1860 { &hf_cfm_mcc_pdu,
1861 { "CFM MCC PDU", "cfm.mcc.pdu", FT_NONE,
1862 BASE_NONE, NULL, 0x0, NULL, HFILL }
1864 { &hf_cfm_mcc_data,
1865 { "MCC data", "cfm.mcc.data", FT_BYTES,
1866 BASE_NONE, NULL, 0x0, NULL, HFILL }
1869 /* CFM LMM */
1870 { &hf_cfm_lmm_pdu,
1871 { "CFM LMM PDU", "cfm.lmm.pdu", FT_NONE,
1872 BASE_NONE, NULL, 0x0, NULL, HFILL }
1874 { &hf_cfm_lmm_lmr_TxFCf,
1875 { "TxFCf", "cfm.lmm.lmr.txfcf", FT_BYTES,
1876 BASE_NONE, NULL, 0x0, NULL, HFILL }
1878 { &hf_cfm_lmm_lmr_RxFCf,
1879 { "RxFCf", "cfm.lmm.lmr.rxfcf", FT_BYTES,
1880 BASE_NONE, NULL, 0x0, NULL, HFILL }
1882 { &hf_cfm_lmm_lmr_TxFCb,
1883 { "TxFCb", "cfm.lmm.lmr.txfcb", FT_BYTES,
1884 BASE_NONE, NULL, 0x0, NULL, HFILL }
1888 /* CFM LMR */
1889 { &hf_cfm_lmr_pdu,
1890 { "CFM LMR PDU", "cfm.lmr.pdu", FT_NONE,
1891 BASE_NONE, NULL, 0x0, NULL, HFILL }
1894 /* CFM 1DM */
1895 { &hf_cfm_odm_pdu,
1896 { "CFM 1DM PDU", "cfm.odm.pdu", FT_NONE,
1897 BASE_NONE, NULL, 0x0, NULL, HFILL }
1899 { &hf_cfm_odm_dmm_dmr_TxTimestampf,
1900 { "TxTimestampf", "cfm.odm.dmm.dmr.txtimestampf", FT_BYTES,
1901 BASE_NONE, NULL, 0x0, NULL, HFILL }
1903 { &hf_cfm_odm_dmm_dmr_RxTimestampf,
1904 { "RxTimestampf", "cfm.odm.dmm.dmr.rxtimestampf", FT_BYTES,
1905 BASE_NONE, NULL, 0x0, NULL, HFILL }
1908 /* CFM DMM */
1909 { &hf_cfm_dmm_pdu,
1910 { "CFM DMM PDU", "cfm.dmm.pdu", FT_NONE,
1911 BASE_NONE, NULL, 0x0, NULL, HFILL }
1913 { &hf_cfm_dmm_dmr_TxTimestampb,
1914 { "TxTimestampb", "cfm.dmm.dmr.txtimestampb", FT_BYTES,
1915 BASE_NONE, NULL, 0x0, NULL, HFILL }
1917 { &hf_cfm_dmm_dmr_RxTimestampb,
1918 { "RxTimestampb", "cfm.dmm.dmr.rxtimestampb", FT_BYTES,
1919 BASE_NONE, NULL, 0x0, NULL, HFILL }
1922 /* CFM DMR */
1923 { &hf_cfm_dmr_pdu,
1924 { "CFM DMR PDU", "cfm.dmr.pdu", FT_NONE,
1925 BASE_NONE, NULL, 0x0, NULL, HFILL }
1928 /* CFM EXM */
1929 { &hf_cfm_exm_pdu,
1930 { "CFM EXM PDU", "cfm.exm.pdu", FT_NONE,
1931 BASE_NONE, NULL, 0x0, NULL, HFILL }
1933 { &hf_cfm_exm_exr_data,
1934 { "EXM/EXR data", "cfm.exm_exr.data", FT_BYTES,
1935 BASE_NONE, NULL, 0x0, NULL, HFILL }
1938 /* CFM EXR */
1939 { &hf_cfm_exr_pdu,
1940 { "CFM EXR PDU", "cfm.exr.pdu", FT_NONE,
1941 BASE_NONE, NULL, 0x0, NULL, HFILL }
1944 /* CFM VSM */
1945 { &hf_cfm_vsm_pdu,
1946 { "CFM VSM PDU", "cfm.vsm.pdu", FT_NONE,
1947 BASE_NONE, NULL, 0x0, NULL, HFILL }
1949 { &hf_cfm_vsm_vsr_data,
1950 { "VSM/VSR data", "cfm.vsm_vsr.data", FT_BYTES,
1951 BASE_NONE, NULL, 0x0, NULL, HFILL }
1954 /* CFM VSR */
1955 { &hf_cfm_vsr_pdu,
1956 { "CFM VSR PDU", "cfm.vsr.pdu", FT_NONE,
1957 BASE_NONE, NULL, 0x0, NULL, HFILL }
1960 /* Synthetic Loss values */
1961 { &hf_cfm_slm_pdu,
1962 { "CFM SLM PDU", "cfm.slm.pdu", FT_NONE,
1963 BASE_NONE, NULL, 0x0, NULL, HFILL }
1965 { &hf_cfm_slr_pdu,
1966 { "CFM SLR PDU", "cfm.slr.pdu", FT_NONE,
1967 BASE_NONE, NULL, 0x0, NULL, HFILL }
1969 { &hf_cfm_slm_src_mep,
1970 { "SrcMepID", "cfm.slm.src_mep_id", FT_BYTES,
1971 BASE_NONE, NULL, 0x0, NULL, HFILL }
1973 { &hf_cfm_slr_rsp_mep,
1974 { "RspMepID", "cfm.slr.rsp_mep_id", FT_BYTES,
1975 BASE_NONE, NULL, 0x0, NULL, HFILL }
1977 { &hf_cfm_slm_testid,
1978 { "TestID", "cfm.slm.test_id", FT_BYTES,
1979 BASE_NONE, NULL, 0x0, NULL, HFILL }
1981 { &hf_cfm_slm_txfcf,
1982 { "TxFcF", "cfm.slm.txfcf", FT_UINT32,
1983 BASE_DEC, NULL, 0x0, NULL, HFILL }
1985 { &hf_cfm_slr_txfcb,
1986 { "TxFcB", "cfm.slr.txfcb", FT_UINT32,
1987 BASE_DEC, NULL, 0x0, NULL, HFILL }
1990 /******************************* TLVs ****************************/
1991 { &hf_cfm_all_tlvs,
1992 { "CFM TLVs", "cfm.all.tlvs", FT_NONE,
1993 BASE_NONE, NULL, 0x0, NULL, HFILL }
1995 { &hf_cfm_tlv_type,
1996 { "TLV Type", "cfm.tlv.type", FT_UINT8,
1997 BASE_DEC, VALS(tlvtypefieldvalues), 0x0, NULL, HFILL}
1999 { &hf_cfm_tlv_length,
2000 { "TLV Length", "cfm.tlv.length", FT_UINT16,
2001 BASE_DEC, NULL, 0x0, NULL, HFILL}
2003 /* Sender ID TLV */
2004 { &hf_tlv_chassis_id_length,
2005 { "Chassis ID Length", "cfm.tlv.chassis.id.length", FT_UINT8,
2006 BASE_DEC, NULL, 0x0, NULL, HFILL}
2008 { &hf_tlv_chassis_id_subtype,
2009 { "Chassis ID Sub-type", "cfm.tlv.chassis.id.subtype", FT_UINT8,
2010 BASE_DEC, NULL, 0x0, NULL, HFILL}
2012 { &hf_tlv_chassis_id,
2013 { "Chassis ID", "cfm.tlv.chassis.id", FT_BYTES,
2014 BASE_NONE, NULL, 0x0, NULL, HFILL}
2016 { &hf_tlv_ma_domain_length,
2017 { "Management Address Domain Length", "cfm.tlv.ma.domain.length", FT_UINT8,
2018 BASE_DEC, NULL, 0x0, NULL, HFILL}
2020 { &hf_tlv_ma_domain,
2021 { "Management Address Domain", "cfm.tlv.ma.domain", FT_BYTES,
2022 BASE_NONE, NULL, 0x0, NULL, HFILL}
2024 { &hf_tlv_management_addr_length,
2025 { "Management Address Length", "cfm.tlv.management.addr.length", FT_UINT8,
2026 BASE_DEC, NULL, 0x0, NULL, HFILL}
2028 { &hf_tlv_management_addr,
2029 { "Management Address", "cfm.tlv.management.addr", FT_BYTES,
2030 BASE_NONE, NULL, 0x0, NULL, HFILL}
2033 /* Port Status TLV */
2034 { &hf_tlv_port_status_value,
2035 { "Port Status value", "cfm.tlv.port.status.value", FT_UINT8,
2036 BASE_DEC, VALS(portstatTLVvalues), 0x0, NULL, HFILL}
2039 /* Data TLV */
2040 { &hf_tlv_data_value,
2041 { "Data Value", "cfm.tlv.data.value", FT_BYTES,
2042 BASE_NONE, NULL, 0x0, NULL, HFILL}
2045 /* Interface status TLV */
2046 { &hf_tlv_interface_status_value,
2047 { "Interface Status value", "cfm.tlv.port.interface.value", FT_UINT8,
2048 BASE_DEC, VALS(interfacestatTLVvalues), 0x0, NULL, HFILL}
2051 /* Reply Ingress TLV */
2052 { &hf_tlv_reply_ingress_action,
2053 { "Ingress Action", "cfm.tlv.reply.ingress.action", FT_UINT8,
2054 BASE_DEC, VALS(replyingressTLVvalues), 0x0, NULL, HFILL}
2056 { &hf_tlv_reply_ingress_mac_address,
2057 { "Ingress MAC address", "cfm.tlv.reply.ingress.mac.address", FT_ETHER,
2058 BASE_NONE, NULL, 0x0, NULL, HFILL }
2060 { &hf_tlv_reply_ing_egr_portid_length,
2061 { "Chassis ID Length", "cfm.tlv.reply.ing.egr.portid.length", FT_UINT8,
2062 BASE_DEC, NULL, 0x0, NULL, HFILL}
2064 { &hf_tlv_reply_ing_egr_portid_subtype,
2065 { "Chassis ID Sub-type", "cfm.tlv.reply.ing.egr.portid.subtype", FT_UINT8,
2066 BASE_DEC, NULL, 0x0, NULL, HFILL}
2068 { &hf_tlv_reply_ing_egr_portid,
2069 { "Chassis ID", "cfm.tlv.reply.ing.egr.portid", FT_BYTES,
2070 BASE_NONE, NULL, 0x0, NULL, HFILL}
2073 /* Reply Egress TLV */
2074 { &hf_tlv_reply_egress_action,
2075 { "Egress Action", "cfm.tlv.reply.egress.action", FT_UINT8,
2076 BASE_DEC, VALS(replyegressTLVvalues), 0x0, NULL, HFILL}
2078 { &hf_tlv_reply_egress_mac_address,
2079 { "Egress MAC address", "cfm.tlv.reply.egress.mac.address", FT_ETHER,
2080 BASE_NONE, NULL, 0x0, NULL, HFILL }
2083 /* LTM Egress Identifier TLV */
2084 { &hf_tlv_ltm_egress_id_mac,
2085 { "Egress Identifier - MAC of LT Initiator/Responder", "cfm.tlv.ltm.egress.id.mac", FT_ETHER,
2086 BASE_NONE, NULL, 0x0, NULL, HFILL }
2088 { &hf_tlv_ltm_egress_id_unique_identifier,
2089 { "Egress Identifier - Unique Identifier", "cfm.tlv.ltm.egress.id.ui", FT_BYTES,
2090 BASE_NONE, NULL, 0x0, NULL, HFILL }
2093 /* LTR Egress Identifier TLV */
2094 { &hf_tlv_ltr_egress_last_id_mac,
2095 { "Last Egress Identifier - MAC address", "cfm.tlv.ltr.egress.last.id.mac", FT_ETHER,
2096 BASE_NONE, NULL, 0x0, NULL, HFILL }
2098 { &hf_tlv_ltr_egress_last_id_unique_identifier,
2099 { "Last Egress Identifier - Unique Identifier", "cfm.tlv.ltr.egress.last.id.ui", FT_BYTES,
2100 BASE_NONE, NULL, 0x0, NULL, HFILL }
2102 { &hf_tlv_ltr_egress_next_id_mac,
2103 { "Next Egress Identifier - MAC address", "cfm.tlv.ltr.egress.next.id.mac", FT_ETHER,
2104 BASE_NONE, NULL, 0x0, NULL, HFILL }
2106 { &hf_tlv_ltr_egress_next_id_unique_identifier,
2107 { "Next Egress Identifier - Unique Identifier", "cfm.tlv.ltr.egress.next.id.ui", FT_BYTES,
2108 BASE_NONE, NULL, 0x0, NULL, HFILL }
2111 /* Organization-Specific TLV */
2112 { &hf_tlv_org_spec_oui,
2113 { "OUI", "cfm.tlv.org.spec.oui", FT_BYTES,
2114 BASE_NONE, NULL, 0x0, NULL, HFILL }
2116 { &hf_tlv_org_spec_subtype,
2117 { "Sub-Type", "cfm.tlv.org.spec.subtype", FT_BYTES,
2118 BASE_NONE, NULL, 0x0, NULL, HFILL }
2120 { &hf_tlv_org_spec_value,
2121 { "Value", "cfm.tlv.org.spec.value", FT_BYTES,
2122 BASE_NONE, NULL, 0x0, NULL, HFILL }
2125 /* Test TLV */
2126 { &hf_tlv_tst_test_pattern_type,
2127 { "Test Pattern Type", "cfm.tlv.tst.test.pattern.type", FT_UINT8,
2128 BASE_DEC, VALS(testTLVpatterntypes), 0x0, NULL, HFILL}
2130 { &hf_tlv_tst_test_pattern,
2131 { "Test Pattern", "cfm.tlv.tst.test.pattern", FT_NONE,
2132 BASE_NONE, NULL, 0x0, NULL, HFILL }
2134 { &hf_tlv_tst_CRC32,
2135 { "CRC-32", "cfm.tlv.tst.crc32", FT_BYTES,
2136 BASE_NONE, NULL, 0x0, NULL, HFILL }
2140 /* Setup protocol subtree array */
2141 static gint *ett[] = {
2142 &ett_cfm,
2143 &ett_cfm_flags,
2144 &ett_cfm_ccm_maid,
2145 &ett_cfm_ccm_itu,
2146 &ett_cfm_pdu,
2147 &ett_cfm_all_tlvs,
2148 &ett_cfm_tlv,
2149 &ett_cfm_raps_flags
2152 proto_cfm = proto_register_protocol (
2153 "CFM EOAM 802.1ag/ITU Protocol", /* name */
2154 "CFM", /* short name */
2155 "cfm" /* abbrev */
2158 cfm_handle = register_dissector("cfm", dissect_cfm, proto_cfm);
2160 proto_register_field_array(proto_cfm, hf, array_length(hf));
2161 proto_register_subtree_array(ett, array_length(ett));
2165 /* Register CFM OEAM protocol handler */
2166 void proto_reg_handoff_cfm(void)
2168 dissector_add_uint("ethertype", ETHERTYPE_CFM, cfm_handle);