Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-ossp.c
bloba04e4930caf3024deb13f92fe9a6d1e7bc48c4cf
1 /* packet-ossp.c
2 * Routines for Organization Specific Slow Protocol dissection
3 * IEEE Std 802.3, Annex 57B
5 * Copyright 2002 Steve Housley <steve_housley@3com.com>
6 * Copyright 2009 Artem Tamazov <artem.tamazov@telllabs.com>
7 * Copyright 2010 Roberto Morro <roberto.morro[AT]tilab.com>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include "config.h"
18 #include <epan/packet.h>
20 #include <epan/slow_protocol_subtypes.h>
21 #include <epan/addr_resolv.h>
22 #include <epan/oui.h>
23 #include <epan/expert.h>
24 #include <epan/tfs.h>
25 #include <wsutil/array.h>
26 #include <wsutil/str_util.h>
28 /* General declarations */
29 void proto_register_ossp(void);
30 void proto_reg_handoff_ossp(void);
32 static dissector_handle_t ossp_handle;
35 * ESMC
37 #define OUI_SIZE 3
38 #define ESMC_ITU_SUBTYPE 0x0001
39 #define ESMC_VERSION_1 0x01
40 #define ESMC_QL_TLV_TYPE 0x01
41 #define ESMC_QL_TLV_LENGTH 0x04
42 #define ESMC_EXTENDED_QL_TLV_TYPE 0x02
43 #define ESMC_EXTENDED_QL_TLV_LENGTH 0x14
45 static const true_false_string esmc_event_flag_tfs =
46 { "Time-critical Event ESMC PDU", "Information ESMC PDU" };
48 static const value_string esmc_tlv_type_vals[] = {
49 { 1, "Quality Level" },
50 { 2, "Extended Quality Level" },
51 { 0, NULL }
54 /* G.781 5.5.1.1 Option I SDH (same in G.707) */
55 static const value_string esmc_quality_level_opt_1_vals[] = {
56 // SSM only codes
57 { 2, "QL-PRC, Primary reference clock (G.811)" },
58 { 4, "QL-SSU-A, Type I or V SSU clock (G.812), 'transit node clock'" },
59 { 8, "QL-SSU-B, Type VI SSU clock (G.812), 'local node clock'" },
60 { 11, "QL-EEC1, EEC (G.8262, Option I) or SEC clock (G.813, Option I)" },
61 { 15, "QL-DNU, 'Do Not Use'" },
62 // SSM+eSSM codes
63 { (0xFF<<8) | 2, "QL-PRC, Primary reference clock (G.811)" },
64 { (0xFF<<8) | 4, "QL-SSU-A, Type I or V SSU clock (G.812), 'transit node clock'" },
65 { (0xFF<<8) | 8, "QL-SSU-B, Type VI SSU clock (G.812), 'local node clock'" },
66 { (0xFF<<8) | 11, "QL-EEC1, EEC (G.8262, Option I) or SEC clock (G.813, Option I)" },
67 { (0xFF<<8) | 15, "QL-DNU, 'Do Not Use'" },
68 { (0x20<<8) | 2, "QL-PRTC, Primary Reference Time Clock" },
69 { (0x21<<8) | 2, "QL-ePRTC, Enhanced Primary Reference Time Clock"},
70 { (0x22<<8) | 11, "QL-eEEC, Enhanced Ethernet Equipment Clock" },
71 { (0x23<<8) | 2, "QL-ePRC, Enhanced Primary Reference Clock" },
72 { 0, NULL }
75 static const value_string esmc_quality_level_opt_1_vals_short[] = {
76 // SSM codes
77 { 2, "QL-PRC" },
78 { 4, "QL-SSU-A" },
79 { 8, "QL-SSU-B" },
80 { 11, "QL-EEC1" },
81 { 15, "QL-DNU" },
82 // SSM+eSSM codes
83 { (0xFF<<8) | 2, "QL-PRC" },
84 { (0xFF<<8) | 4, "QL-SSU-A" },
85 { (0xFF<<8) | 8, "QL-SSU-B" },
86 { (0xFF<<8) | 11, "QL-EEC1" },
87 { (0xFF<<8) | 15, "QL-DNU" },
88 { (0x20<<8) | 2, "QL-PRTC" },
89 { (0x21<<8) | 2, "QL-ePRTC"},
90 { (0x22<<8) | 11, "QL-eEEC" },
91 { (0x23<<8) | 2, "QL-ePRC" },
92 { 0, NULL }
95 /* G.781 5.5.1.2 Option II SDH synchronization networking */
96 static const value_string esmc_quality_level_opt_2_vals[] = {
97 // SSM codes
98 { 0, "QL-STU, unknown - signal does not carry the QL message of the source" },
99 { 1, "QL-PRS, PRS clock (G.811) / ST1, Stratum 1 Traceable" },
100 { 4, "QL-TNC, Transit Node Clock (G.812, Type V)" },
101 { 7, "QL-ST2, Stratum 2 clock (G.812, Type II)" },
102 { 10, "QL-ST3, Stratum 3 clock (G.812, Type IV) or QL-EEC2 (G.8262)" },
103 { 13, "QL-ST3E, Stratum 3E clock (G.812, Type III)" },
104 { 14, "QL-PROV, provisionable by the network operator / Reserved for Network Synchronization" },
105 { 15, "QL-DUS, shall not be used for synchronization" },
106 // SSM+eSSM codes
107 { (0xFF<<8) | 0, "QL-STU, unknown - signal does not carry the QL message of the source" },
108 { (0xFF<<8) | 1, "QL-PRS, PRS clock (G.811) / ST1, Stratum 1 Traceable" },
109 { (0xFF<<8) | 4, "QL-TNC, Transit Node Clock (G.812, Type V)" },
110 { (0xFF<<8) | 7, "QL-ST2, Stratum 2 clock (G.812, Type II)" },
111 { (0xFF<<8) | 10, "QL-ST3, Stratum 3 clock (G.812, Type IV) or QL-EEC2 (G.8262)" },
112 { (0xFF<<8) | 13, "QL-ST3E, Stratum 3E clock (G.812, Type III)" },
113 { (0xFF<<8) | 14, "QL-PROV, provisionable by the network operator / Reserved for Network Synchronization" },
114 { (0xFF<<8) | 15, "QL-DUS, shall not be used for synchronization" },
115 { (0x20<<8) | 1, "QL-PRTC, Primary Reference Time Clock" },
116 { (0x21<<8) | 1, "QL-ePRTC, Enhanced Primary Reference Time Clock" },
117 { (0x22<<8) | 10, "QL-eEEC, Enhanced Ethernet Equipment Clock" },
118 { (0x23<<8) | 1, "QL-ePRC, Enhanced Primary Reference Clock" },
119 { 0, NULL }
122 static const value_string esmc_quality_level_opt_2_vals_short[] = {
123 // SSM codes
124 { 0, "QL-STU" },
125 { 1, "QL-PRS" },
126 { 4, "QL-TNC" },
127 { 7, "QL-ST2" },
128 { 10, "QL-ST3" },
129 { 13, "QL-ST3E" },
130 { 14, "QL-PROV" },
131 { 15, "QL-DUS" },
132 // SSM+eSSM codes
133 { (0xFF<<8) | 0, "QL-STU" },
134 { (0xFF<<8) | 1, "QL-PRS" },
135 { (0xFF<<8) | 4, "QL-TNC" },
136 { (0xFF<<8) | 7, "QL-ST2" },
137 { (0xFF<<8) | 10, "QL-ST3" },
138 { (0xFF<<8) | 13, "QL-ST3E" },
139 { (0xFF<<8) | 14, "QL-PROV" },
140 { (0xFF<<8) | 15, "QL-DUS" },
141 { (0x20<<8) | 1, "QL-PRTC" },
142 { (0x21<<8) | 1, "QL-ePRTC" },
143 { (0x22<<8) | 10, "QL-eEEC" },
144 { (0x23<<8) | 1, "QL-ePRC" },
145 { 0, NULL }
148 /* G.781 5.5.1.3 Option III SDH synchronization networking */
149 static const value_string esmc_quality_level_opt_3_vals[] = {
150 // SSM
151 { 0, "QL-UNK, Unknown" },
152 { 11, "QL-EEC1, EEC (G.8262, Option I) or SEC clock (G.813, Option I)" },
153 // SSM+eSSM codes
154 { (0xFF<<8) | 0, "QL-UNK, Unknown" },
155 { (0xFF<<8) | 11, "QL-EEC1, EEC (G.8262, Option I) or SEC clock (G.813, Option I)" },
156 { 0, NULL }
159 static const value_string esmc_quality_level_opt_3_vals_short[] = {
160 // SSM
161 { 0, "QL-UNK" },
162 { 11, "QL-EEC1" },
163 // SSM+eSSM codes
164 { (0xFF<<8) | 0, "QL-UNK" },
165 { (0xFF<<8) | 11, "QL-EEC1" },
166 { 0, NULL }
170 static const value_string *esmc_quality_level_vals[] = {
171 NULL,
172 esmc_quality_level_opt_1_vals,
173 esmc_quality_level_opt_2_vals,
174 esmc_quality_level_opt_3_vals
177 static const value_string *esmc_quality_level_vals_short[] = {
178 NULL,
179 esmc_quality_level_opt_1_vals_short,
180 esmc_quality_level_opt_2_vals_short,
181 esmc_quality_level_opt_3_vals_short
184 /* Initialise the protocol and registered fields */
185 static int proto_ossp;
187 static int hf_ossp_oui;
188 static int hf_itu_subtype;
189 static int hf_esmc_version;
190 static int hf_esmc_event_flag;
191 static int hf_esmc_reserved_bits;
192 static int hf_esmc_reserved_octets;
193 static int hf_esmc_tlv;
194 static int hf_esmc_tlv_type;
195 static int hf_esmc_tlv_length;
196 static int hf_esmc_tlv_ql_unused;
197 static int hf_esmc_tlv_ql_ssm;
198 static int hf_esmc_tlv_ext_ql_essm;
199 static int hf_esmc_tlv_ext_ql_clockid;
200 static int hf_esmc_tlv_ext_ql_flag_reserved;
201 static int hf_esmc_tlv_ext_ql_flag_chain;
202 static int hf_esmc_tlv_ext_ql_flag_mixed;
203 static int hf_esmc_tlv_ext_ql_eeec;
204 static int hf_esmc_tlv_ext_ql_eec;
205 static int hf_esmc_tlv_ext_ql_reserved;
206 static int hf_esmc_quality_level;
207 static int hf_esmc_padding;
209 /* Initialise the subtree pointers */
211 static int ett_ossppdu;
212 static int ett_itu_ossp;
214 static int ett_esmc;
216 static expert_field ei_esmc_tlv_type_ql_type_not_first;
217 static expert_field ei_esmc_tlv_type_not_ext_ql;
218 static expert_field ei_esmc_quality_level_invalid;
219 static expert_field ei_esmc_tlv_ql_unused_not_zero;
220 static expert_field ei_esmc_tlv_type_decoded_as_ext_ql;
221 static expert_field ei_esmc_tlv_type_decoded_as_ql_type;
222 static expert_field ei_esmc_version_compliance;
223 static expert_field ei_esmc_tlv_length_bad;
224 static expert_field ei_esmc_reserved_not_zero;
226 static int pref_option_network = 1;
227 static const enum_val_t pref_option_network_vals[] =
229 { "1", "Option I network", 1 }, /* G.781 5.5.1.1 Option I SDH (same in G.707) */
230 { "2", "Option II network", 2 }, /* G.781 5.5.1.2 Option II SDH synchronization networking */
231 //{ "3", "Option III network", 3 }, /* G.781 5.5.1.3 Option III SDH synchronization networking */
232 { NULL, NULL, 0 }
235 static void
236 dissect_esmc_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *treex);
238 static void
239 dissect_itu_ossp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
242 * Name: dissect_ossp_pdu
244 * Description:
245 * This function is used to dissect the Organization Specific Slow
246 * Protocol defined in IEEE 802.3 Annex 57B. Currently only the ESMC
247 * slow protocol as defined in ITU-T G.8264 is implemented
249 * Input Arguments:
250 * tvb: buffer associated with the rcv packet (see tvbuff.h).
251 * pinfo: structure associated with the rcv packet (see packet_info.h).
252 * tree: the protocol tree associated with the rcv packet (see proto.h).
254 * Return Values: None
256 * Notes:
257 * Roberto Morro (roberto.morro[AT]tilab.com)
259 static int
260 dissect_ossp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
262 int offset = 0;
263 const char *str;
264 proto_item *ossp_item;
265 proto_tree *ossp_tree;
266 tvbuff_t *ossp_tvb;
267 uint32_t oui;
269 col_set_str(pinfo->cinfo, COL_PROTOCOL, "OSSP");
271 ossp_item = proto_tree_add_protocol_format(tree, proto_ossp, tvb, 0, -1,
272 "Organization Specific Slow Protocol");
273 ossp_tree = proto_item_add_subtree(ossp_item, ett_ossppdu);
275 proto_tree_add_item_ret_uint(ossp_tree, hf_ossp_oui, tvb, offset, OUI_SIZE, ENC_BIG_ENDIAN, &oui);
276 str = uint_get_manuf_name_if_known(oui);
277 col_add_fstr(pinfo->cinfo, COL_INFO, "OUI: %s", (str != NULL) ? str : "(Unknown OSSP organization)");
278 offset += 3;
281 * XXX - should have a dissector table here, but we don't yet
282 * support OUIs as keys in dissector tables.
284 ossp_tvb = tvb_new_subset_remaining(tvb, offset);
285 if (OUI_ITU_T == oui)
287 dissect_itu_ossp(ossp_tvb, pinfo, ossp_tree);
289 /* new Organization Specific Slow Protocols go hereafter */
290 #if 0
291 else if (OUI_XXX == oui)
293 dissect_xxx_ossp(ossp_tvb, pinfo, ossp_tree);
295 else if (OUI_YYY == oui)
297 dissect_yyy_ossp(ossp_tvb, pinfo, ossp_tree);
299 #endif
301 return tvb_captured_length(tvb);
305 * Name: dissect_itu_ossp
307 * Description:
308 * This function is used to dissect the ITU-T OSSP (Organization Specific
309 * Slow Protocol). Currently only the Ethernet Synchronization
310 * Messaging Channel (ESMC) slow protocol as defined in ITU-T G.8264
311 * is implemented
313 * Input Arguments:
314 * tvb: buffer associated with the rcv packet (see tvbuff.h).
315 * pinfo: structure associated with the rcv packet (see packet_info.h).
316 * tree: the protocol tree associated with the rcv packet (see proto.h).
317 * subtype: the protocol subtype (according to IEEE802.3 annex 57B)
319 * Return Values: None
321 * Notes:
322 * Roberto Morro (roberto.morro[AT]tilab.com)
325 static void
326 dissect_itu_ossp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
328 uint16_t subtype;
329 proto_item *ti;
330 proto_tree *itu_ossp_tree;
331 tvbuff_t *ossp_subtype_tvb;
333 /* ITU-T OSSP Subtype */
334 subtype = tvb_get_ntohs(tvb, 0);
335 ti = proto_tree_add_item(tree, hf_itu_subtype, tvb, 0, 2, ENC_BIG_ENDIAN);
337 itu_ossp_tree = proto_item_add_subtree(ti, ett_itu_ossp);
339 ossp_subtype_tvb = tvb_new_subset_remaining(tvb, 2);
341 switch (subtype)
343 case ESMC_ITU_SUBTYPE:
344 dissect_esmc_pdu(ossp_subtype_tvb, pinfo, itu_ossp_tree);
345 break;
347 /* Other ITU-T defined slow protocols go hereafter */
348 #if 0
349 case XXXX_ITU_SUBTYPE:
350 dissect_xxxx_pdu(tvb, pinfo, itu_ossp_tree);
351 break;
352 #endif
353 default:
354 proto_item_append_text(itu_ossp_tree, " (Unknown)");
358 * Description:
359 * This function is used to dissect ESMC PDU defined G.8264/Y.1364
360 * clause 11.3.1.
362 static void
363 dissect_esmc_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *treex)
365 int offset = 0;
366 bool event_flag;
367 int ssm = 0;
368 int essm = 0;
370 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ESMC");
372 proto_item_append_text(treex, ": ESMC");
374 proto_tree *tree_a;
375 tree_a = proto_item_add_subtree(treex, ett_esmc);
377 { /* version */
378 proto_item *item_b;
379 item_b = proto_tree_add_item(tree_a, hf_esmc_version, tvb, offset, 1, ENC_BIG_ENDIAN);
380 if ((tvb_get_uint8(tvb, offset) >> 4) != ESMC_VERSION_1)
382 expert_add_info_format(pinfo, item_b, &ei_esmc_version_compliance, "Version must be 0x%.1x claim compliance with Version 1 of this protocol", ESMC_VERSION_1);
384 /*stay at the same octet in tvb*/
386 { /* event flag */
387 event_flag = ((tvb_get_uint8(tvb, offset) & 0x08) != 0);
388 proto_tree_add_item(tree_a, hf_esmc_event_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
389 /*stay at the same octet in tvb*/
391 { /* reserved bits */
392 proto_item *item_b;
393 uint8_t reserved;
394 reserved = tvb_get_uint8(tvb, offset) & 0x07;
395 item_b = proto_tree_add_uint_format_value(tree_a, hf_esmc_reserved_bits, tvb, offset, 1, reserved, "0x%.2x", reserved);
396 if (reserved != 0x0)
398 expert_add_info_format(pinfo, item_b, &ei_esmc_reserved_not_zero, "Reserved bits must be set to all zero on transmitter");
400 offset += 1;
402 { /* reserved octets */
403 proto_item *item_b;
404 uint32_t reserved;
405 reserved = tvb_get_ntoh24(tvb, offset);
406 item_b = proto_tree_add_uint_format_value(tree_a, hf_esmc_reserved_octets, tvb, offset, 3, reserved, "0x%.6x", reserved);
407 if (reserved != 0x0)
409 expert_add_info_format(pinfo, item_b, &ei_esmc_reserved_not_zero, "Reserved octets must be set to all zero on transmitter");
411 offset += 3;
413 proto_item_append_text(treex, ", Event:%s", event_flag ?
414 "Time-critical" : "Information");
416 col_add_fstr(pinfo->cinfo, COL_INFO, "Event:%s", event_flag ?
417 "Time-critical" : "Information");
420 * Quality Level TLV is mandatory at fixed location.
423 proto_item *item_b;
424 uint8_t type;
425 item_b = proto_tree_add_item(tree_a, hf_esmc_tlv, tvb, offset, ESMC_QL_TLV_LENGTH, ENC_NA);
427 proto_tree *tree_b;
428 tree_b = proto_item_add_subtree(item_b, ett_esmc);
430 proto_item *item_c;
431 uint16_t length;
432 uint8_t unused;
434 /* type */
435 type = tvb_get_uint8(tvb, offset);
436 item_c = proto_tree_add_item(tree_b, hf_esmc_tlv_type, tvb, offset, 1, ENC_BIG_ENDIAN);
437 if (type != ESMC_QL_TLV_TYPE)
439 expert_add_info_format(pinfo, item_c, &ei_esmc_tlv_type_ql_type_not_first, "TLV Type must be == 0x%.2x (QL) because QL TLV must be first in the ESMC PDU", ESMC_QL_TLV_TYPE);
440 expert_add_info(pinfo, item_c, &ei_esmc_tlv_type_decoded_as_ql_type);
442 proto_item_append_text(item_b, ", %s", val_to_str_const(type, esmc_tlv_type_vals, "Unknown"));
443 offset += 1;
445 /* length */
446 length = tvb_get_ntohs(tvb, offset);
447 item_c = proto_tree_add_item(tree_b, hf_esmc_tlv_length, tvb, offset, 2, ENC_BIG_ENDIAN);
448 if (length != ESMC_QL_TLV_LENGTH)
450 expert_add_info_format(pinfo, item_c, &ei_esmc_tlv_length_bad, "QL TLV Length must be == 0x%.4x", ESMC_QL_TLV_LENGTH);
451 expert_add_info_format(pinfo, item_c, &ei_esmc_tlv_type_decoded_as_ql_type, "Let's decode this TLV as if Length has valid value");
453 offset += 2;
455 /* value */
456 ssm = tvb_get_uint8(tvb, offset);
457 unused = ssm & 0xf0;
458 ssm &= 0x0f;
459 item_c = proto_tree_add_item(tree_b, hf_esmc_tlv_ql_unused, tvb, offset, 1, ENC_BIG_ENDIAN);
460 if (unused != 0x00)
462 expert_add_info(pinfo, item_c, &ei_esmc_tlv_ql_unused_not_zero);
464 proto_tree_add_item(tree_b, hf_esmc_tlv_ql_ssm, tvb, offset, 1, ENC_BIG_ENDIAN);
465 offset += 1;
471 * Extended Quality Level TLV is optional at fixed location.
473 if (tvb_captured_length_remaining(tvb, offset) >= ESMC_EXTENDED_QL_TLV_LENGTH)
475 uint8_t type;
476 type = tvb_get_uint8(tvb, offset);
478 if (type == ESMC_EXTENDED_QL_TLV_TYPE)
480 proto_item *item_b;
481 item_b = proto_tree_add_item(tree_a, hf_esmc_tlv, tvb, offset, ESMC_EXTENDED_QL_TLV_LENGTH, ENC_NA);
483 proto_tree *tree_b;
484 tree_b = proto_item_add_subtree(item_b, ett_esmc);
486 proto_item *item_c;
487 uint16_t length;
488 uint64_t reserved;
490 /* type */
491 item_c = proto_tree_add_item(tree_b, hf_esmc_tlv_type, tvb, offset, 1, ENC_BIG_ENDIAN);
492 if (type != ESMC_EXTENDED_QL_TLV_TYPE)
494 expert_add_info_format(pinfo, item_c, &ei_esmc_tlv_type_not_ext_ql, "TLV Type must be == 0x%.2x (Extended QL)", ESMC_EXTENDED_QL_TLV_TYPE);
495 expert_add_info(pinfo, item_c, &ei_esmc_tlv_type_decoded_as_ext_ql);
497 proto_item_append_text(item_b, ", %s", val_to_str_const(type, esmc_tlv_type_vals, "Unknown"));
498 offset += 1;
500 /* length */
501 length = tvb_get_ntohs(tvb, offset);
502 item_c = proto_tree_add_item(tree_b, hf_esmc_tlv_length, tvb, offset, 2, ENC_BIG_ENDIAN);
503 if (length != ESMC_EXTENDED_QL_TLV_LENGTH)
505 expert_add_info_format(pinfo, item_c, &ei_esmc_tlv_length_bad, "Extended QL TLV Length must be == 0x%.4x", ESMC_EXTENDED_QL_TLV_LENGTH);
506 expert_add_info_format(pinfo, item_c, &ei_esmc_tlv_type_decoded_as_ext_ql, "Let's decode this TLV as if Length has valid value");
508 offset += 2;
510 /* Enhanced SSM code */
511 essm = tvb_get_uint8(tvb, offset);
512 proto_tree_add_item(tree_b, hf_esmc_tlv_ext_ql_essm, tvb, offset, 1, ENC_BIG_ENDIAN);
513 offset += 1;
515 /* SyncE clockIdentity */
516 proto_tree_add_item(tree_b, hf_esmc_tlv_ext_ql_clockid, tvb, offset, 8, ENC_BIG_ENDIAN);
517 offset += 8;
519 /* Flag */
520 reserved = tvb_get_uint8(tvb, offset) & 0xfc;
521 item_c = proto_tree_add_item(tree_b, hf_esmc_tlv_ext_ql_flag_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
522 if (reserved != 0x0)
524 expert_add_info(pinfo, item_c, &ei_esmc_reserved_not_zero);
526 proto_tree_add_item(tree_b, hf_esmc_tlv_ext_ql_flag_chain, tvb, offset, 1, ENC_BIG_ENDIAN);
527 proto_tree_add_item(tree_b, hf_esmc_tlv_ext_ql_flag_mixed, tvb, offset, 1, ENC_BIG_ENDIAN);
528 offset += 1;
530 /* Cascaded eEECs */
531 proto_tree_add_item(tree_b, hf_esmc_tlv_ext_ql_eeec, tvb, offset, 1, ENC_BIG_ENDIAN);
532 offset += 1;
534 /* Cascaded EECs */
535 proto_tree_add_item(tree_b, hf_esmc_tlv_ext_ql_eec, tvb, offset, 1, ENC_BIG_ENDIAN);
536 offset += 1;
538 /* Reserved */
539 reserved = tvb_get_uint40(tvb, offset, ENC_BIG_ENDIAN);
540 item_c = proto_tree_add_item(tree_b, hf_esmc_tlv_ext_ql_reserved, tvb, offset, 5, ENC_BIG_ENDIAN);
541 if (reserved != 0x0)
543 expert_add_info(pinfo, item_c, &ei_esmc_reserved_not_zero);
545 offset += 5;
552 /* Derive Quality Level from SSM/eSSM based on
553 * ITU-T G.8264/Y.1364 (2017)/Amd.1 (03.2018)
554 * Table 11-7 and Table 11-8.
557 const value_string *ql_vals;
558 const value_string *ql_vals_short;
559 const char *ql_str;
560 proto_item *item_b;
562 ql_vals = esmc_quality_level_vals[pref_option_network];
563 ql_vals_short = esmc_quality_level_vals_short[pref_option_network];
564 ql_str = try_val_to_str((essm<<8) | ssm, ql_vals);
565 item_b = proto_tree_add_uint_format_value(treex, hf_esmc_quality_level, tvb, 6, offset-6,
566 (essm<<8) | ssm, "%s", (NULL != ql_str) ? ql_str : "Unknown Quality Level");
567 proto_item_set_generated(item_b);
568 if (NULL == ql_str)
570 expert_add_info(pinfo, item_b, &ei_esmc_quality_level_invalid);
572 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
573 val_to_str_const((essm<<8) | ssm, ql_vals_short, "Unknown Quality Level"));
576 { /* padding */
577 int padding_size;
578 padding_size = tvb_captured_length_remaining(tvb, offset);
579 if (0 != padding_size)
581 proto_tree* tree_a;
582 tree_a = proto_item_add_subtree(treex, ett_esmc);
584 proto_item* item_b;
585 tvbuff_t* tvb_next;
586 tvb_next = tvb_new_subset_remaining(tvb, offset);
587 item_b = proto_tree_add_item(tree_a, hf_esmc_padding, tvb_next, 0, -1, ENC_NA);
588 proto_item_append_text(item_b, ", %d %s%s", padding_size,
589 "octet", plurality(padding_size,"","s"));
591 proto_tree* tree_b;
592 tree_b = proto_item_add_subtree(item_b, ett_esmc);
593 call_data_dissector(tvb_next, pinfo, tree_b);
600 /* Register the protocol with Wireshark */
601 void
602 proto_register_ossp(void)
604 /* Setup list of header fields */
606 static hf_register_info hf[] = {
607 { &hf_ossp_oui,
608 { "OUI", "ossp.oui",
609 FT_UINT24, BASE_OUI, NULL, 0,
610 "IEEE assigned Organizational Unique Identifier", HFILL }},
612 { &hf_itu_subtype,
613 { "ITU-T OSSP Subtype", "ossp.itu.subtype",
614 FT_UINT16, BASE_HEX, NULL, 0,
615 "Subtype assigned by the ITU-T", HFILL }},
617 { &hf_esmc_version,
618 { "Version", "ossp.esmc.version",
619 FT_UINT8, BASE_HEX, NULL, 0xf0,
620 "Version of ITU-T OSSP frame format", HFILL }},
622 { &hf_esmc_event_flag,
623 { "Event Flag", "ossp.esmc.event_flag",
624 FT_BOOLEAN, 8, TFS(&esmc_event_flag_tfs), 0x08,
625 "This bit distinguishes the critical, time sensitive behaviour of the "
626 "ESMC Event PDU from the ESMC Information PDU", HFILL }},
628 { &hf_esmc_reserved_bits,
629 { "Reserved", "ossp.esmc.reserved_bits",
630 FT_UINT8, BASE_HEX, NULL, 0x07,
631 "Reserved. Set to all zero at the transmitter and ignored by the receiver", HFILL }},
633 { &hf_esmc_reserved_octets,
634 { "Reserved", "ossp.esmc.reserved",
635 FT_UINT24, BASE_HEX, NULL, 0,
636 "Reserved. Set to all zero at the transmitter and ignored by the receiver", HFILL }},
638 { &hf_esmc_tlv,
639 { "ESMC TLV", "ossp.esmc.tlv",
640 FT_NONE, BASE_NONE, NULL, 0,
641 NULL, HFILL }},
643 { &hf_esmc_tlv_type,
644 { "TLV Type", "ossp.esmc.tlv_type",
645 FT_UINT8, BASE_HEX, VALS(esmc_tlv_type_vals), 0,
646 NULL, HFILL }},
648 { &hf_esmc_tlv_length,
649 { "TLV Length", "ossp.esmc.tlv_length",
650 FT_UINT16, BASE_HEX, NULL, 0,
651 NULL, HFILL }},
653 { &hf_esmc_tlv_ql_unused,
654 { "Unused", "ossp.esmc.tlv_ql_unused",
655 FT_UINT8, BASE_HEX, NULL, 0xf0,
656 "This field is not used in QL TLV", HFILL }},
658 { &hf_esmc_tlv_ql_ssm,
659 { "SSM Code", "ossp.esmc.tlv_ql_ssm",
660 FT_UINT8, BASE_HEX, NULL, 0x0f,
661 NULL, HFILL }},
663 { &hf_esmc_tlv_ext_ql_essm,
664 { "Enhanced SSM Code", "ossp.esmc.tlv_ext_ql_essm",
665 FT_UINT8, BASE_HEX, NULL, 0,
666 NULL, HFILL }},
668 { &hf_esmc_tlv_ext_ql_clockid,
669 { "SyncE clockID", "ossp.esmc.tlv_ext_ql_clockid",
670 FT_UINT64, BASE_HEX, NULL, 0,
671 NULL, HFILL }},
673 { &hf_esmc_tlv_ext_ql_flag_reserved,
674 { "Reserved", "ossp.esmc.tlv_ext_ql_flag_reserved",
675 FT_UINT8, BASE_HEX, NULL, 0xfc,
676 "Reserved. Set to all zero at the transmitter and ignored by the receiver", HFILL }},
678 { &hf_esmc_tlv_ext_ql_flag_chain,
679 { "Partial chain", "ossp.esmc.tlv_ext_ql_flag_chain",
680 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x02,
681 "Whether or not the TLV has been generated in the middle of the chain", HFILL }},
683 { &hf_esmc_tlv_ext_ql_flag_mixed,
684 { "Mixed EEC/eEEC clocks", "ossp.esmc.tlv_ext_ql_flag_mixed",
685 FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x01,
686 "Whether of not there is at least one non-eEEC clock in the chain", HFILL }},
688 { &hf_esmc_tlv_ext_ql_eeec,
689 { "Cascaded eEECs", "ossp.esmc.tlv_ext_ql_eeec",
690 FT_UINT8, BASE_DEC, NULL, 0,
691 "Number of cascaded eEECs from nearest SSU/PRC", HFILL }},
693 { &hf_esmc_tlv_ext_ql_eec,
694 { "Cascaded EECs", "ossp.esmc.tlv_ext_ql_eec",
695 FT_UINT8, BASE_DEC, NULL, 0,
696 "Number of cascaded EECs from nearest SSU/PRC", HFILL }},
698 { &hf_esmc_tlv_ext_ql_reserved,
699 { "Reserved", "ossp.esmc.tlv_ext_ql_reserved",
700 FT_UINT40, BASE_HEX, NULL, 0,
701 "Reserved. Set to all zero at the transmitter and ignored by the receiver", HFILL }},
703 { &hf_esmc_quality_level,
704 { "Quality Level", "ossp.esmc.ql",
705 FT_UINT16, BASE_HEX, NULL, 0,
706 NULL, HFILL }},
708 { &hf_esmc_padding,
709 { "Padding", "ossp.esmc.padding",
710 FT_BYTES, BASE_NONE, NULL, 0x0,
711 "This field contains necessary padding to achieve the minimum frame size of 64 bytes at least", HFILL }},
714 /* Setup protocol subtree array */
716 static int *ett[] = {
717 &ett_esmc,
718 &ett_ossppdu,
719 &ett_itu_ossp
722 /* Setup expert info array */
724 static ei_register_info ei[] = {
725 { &ei_esmc_version_compliance, { "ossp.esmc.version.compliance", PI_MALFORMED, PI_ERROR, "Version must claim compliance with Version 1 of this protocol", EXPFILL }},
726 { &ei_esmc_tlv_type_ql_type_not_first, { "ossp.esmc.tlv_type.ql_type_not_first", PI_MALFORMED, PI_ERROR, "TLV Type must be QL because QL TLV must be first in the ESMC PDU", EXPFILL }},
727 { &ei_esmc_tlv_type_decoded_as_ql_type, { "ossp.esmc.tlv_type.decoded_as_ql_type", PI_UNDECODED, PI_NOTE, "Let's decode as if this is QL TLV", EXPFILL }},
728 { &ei_esmc_tlv_length_bad, { "ossp.esmc.tlv_length.bad", PI_MALFORMED, PI_ERROR, "QL TLV Length must be X", EXPFILL }},
729 { &ei_esmc_tlv_ql_unused_not_zero, { "ossp.esmc.tlv_ql_unused.not_zero", PI_MALFORMED, PI_WARN, "Unused bits of TLV must be all zeroes", EXPFILL }},
730 { &ei_esmc_quality_level_invalid, { "ossp.esmc.ql.invalid", PI_UNDECODED, PI_WARN, "Invalid SSM message, unknown QL code", EXPFILL }},
731 { &ei_esmc_tlv_type_not_ext_ql, { "ossp.esmc.tlv_type.not_ext_ql", PI_MALFORMED, PI_ERROR, "TLV Type must be == Extended QL", EXPFILL }},
732 { &ei_esmc_tlv_type_decoded_as_ext_ql, { "ossp.esmc.tlv_type.decoded_as_ext_ql", PI_UNDECODED, PI_NOTE, "Let's decode as if this is Extended QL TLV", EXPFILL }},
733 { &ei_esmc_reserved_not_zero, { "ossp.esmc.reserved_bits_must_be_set_to_all_zero", PI_PROTOCOL, PI_WARN, "Reserved bits must be set to all zero", EXPFILL }},
736 expert_module_t *expert_ossp;
738 module_t *prefs_ossp;
740 /* Register the protocol name and description */
742 proto_ossp = proto_register_protocol("Organization Specific Slow Protocol", "OSSP", "ossp");
744 /* Required function calls to register the header fields and subtrees used */
746 proto_register_field_array(proto_ossp, hf, array_length(hf));
747 proto_register_subtree_array(ett, array_length(ett));
749 /* Register the exert items */
751 expert_ossp = expert_register_protocol(proto_ossp);
752 expert_register_field_array(expert_ossp, ei, array_length(ei));
754 /* Register the preferences */
756 prefs_ossp = prefs_register_protocol(proto_ossp, NULL);
757 prefs_register_enum_preference(prefs_ossp, "option_network",
758 "Regional option", "Select the option of the network to interpret the Quality Level for",
759 &pref_option_network, pref_option_network_vals, true);
761 /* Register the dissector */
763 ossp_handle = register_dissector("ossp", dissect_ossp_pdu, proto_ossp);
766 void
767 proto_reg_handoff_ossp(void)
769 dissector_add_uint("slow.subtype", OSSP_SUBTYPE, ossp_handle);
773 * Editor modelines - https://www.wireshark.org/tools/modelines.html
775 * Local variables:
776 * c-basic-offset: 4
777 * tab-width: 8
778 * indent-tabs-mode: nil
779 * End:
781 * vi: set shiftwidth=4 tabstop=8 expandtab:
782 * :indentSize=4:tabSize=8:noTabs=true: