epan/dissectors/pidl/ C99 drsuapi
[wireshark-sm.git] / epan / dissectors / packet-mpls-pm.c
blobe3a9c75b52fd4a4a73c19f7116bfdb35aa131bea
1 /* packet-mpls-pm.c
3 * Routines for MPLS delay and loss measurement: it should conform
4 * to RFC 6374. 'PM' stands for Performance Measurement.
6 * Copyright 2012 _FF_
8 * Francesco Fondelli <francesco dot fondelli, gmail dot com>
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * SPDX-License-Identifier: GPL-2.0-or-later
17 #include "config.h"
19 #include <epan/packet.h>
20 #include <epan/tfs.h>
21 #include <wsutil/array.h>
22 #include "packet-ip.h"
23 #include "packet-mpls.h"
25 void proto_register_mpls_pm(void);
26 void proto_reg_handoff_mpls_pm(void);
28 /* message control flags */
29 #define MPLS_PM_FLAGS_R 0x08
30 #define MPLS_PM_FLAGS_T 0x04
31 #define MPLS_PM_FLAGS_RES 0x03
32 #define MPLS_PM_FLAGS_MASK 0x0F
34 /* data format flags */
35 #define MPLS_PM_DFLAGS_X 0x80
36 #define MPLS_PM_DFLAGS_B 0x40
37 #define MPLS_PM_DFLAGS_RES 0x30
38 #define MPLS_PM_DFLAGS_MASK 0xF0
40 static int proto_mpls_pm_dlm;
41 static int proto_mpls_pm_ilm;
42 static int proto_mpls_pm_dm;
43 static int proto_mpls_pm_dlm_dm;
44 static int proto_mpls_pm_ilm_dm;
46 static int ett_mpls_pm;
47 static int ett_mpls_pm_flags;
48 static int ett_mpls_pm_dflags;
50 static int hf_mpls_pm_version;
51 static int hf_mpls_pm_flags;
52 static int hf_mpls_pm_flags_r;
53 static int hf_mpls_pm_flags_t;
54 static int hf_mpls_pm_flags_res;
55 static int hf_mpls_pm_query_ctrl_code;
56 static int hf_mpls_pm_response_ctrl_code;
57 static int hf_mpls_pm_length;
58 static int hf_mpls_pm_dflags;
59 static int hf_mpls_pm_dflags_x;
60 static int hf_mpls_pm_dflags_b;
61 static int hf_mpls_pm_dflags_res;
62 static int hf_mpls_pm_otf;
63 static int hf_mpls_pm_session_id;
64 static int hf_mpls_pm_ds;
65 static int hf_mpls_pm_origin_timestamp_null;
66 static int hf_mpls_pm_origin_timestamp_seq;
67 static int hf_mpls_pm_origin_timestamp_ntp;
68 static int hf_mpls_pm_origin_timestamp_ptp;
69 static int hf_mpls_pm_origin_timestamp_unk;
70 static int hf_mpls_pm_counter1;
71 static int hf_mpls_pm_counter2;
72 static int hf_mpls_pm_counter3;
73 static int hf_mpls_pm_counter4;
74 static int hf_mpls_pm_qtf;
75 static int hf_mpls_pm_qtf_combined;
76 static int hf_mpls_pm_rtf;
77 static int hf_mpls_pm_rtf_combined;
78 static int hf_mpls_pm_rptf;
79 static int hf_mpls_pm_rptf_combined;
80 static int hf_mpls_pm_timestamp1_q_null;
81 static int hf_mpls_pm_timestamp1_r_null;
82 static int hf_mpls_pm_timestamp1_q_seq;
83 static int hf_mpls_pm_timestamp1_r_seq;
84 static int hf_mpls_pm_timestamp1_q_ntp;
85 static int hf_mpls_pm_timestamp1_r_ntp;
86 static int hf_mpls_pm_timestamp1_q_ptp;
87 static int hf_mpls_pm_timestamp1_r_ptp;
88 static int hf_mpls_pm_timestamp1_unk;
89 static int hf_mpls_pm_timestamp2_q_null;
90 static int hf_mpls_pm_timestamp2_r_null;
91 static int hf_mpls_pm_timestamp2_q_seq;
92 static int hf_mpls_pm_timestamp2_r_seq;
93 static int hf_mpls_pm_timestamp2_q_ntp;
94 static int hf_mpls_pm_timestamp2_r_ntp;
95 static int hf_mpls_pm_timestamp2_q_ptp;
96 static int hf_mpls_pm_timestamp2_r_ptp;
97 static int hf_mpls_pm_timestamp2_unk;
98 static int hf_mpls_pm_timestamp3_null;
99 static int hf_mpls_pm_timestamp3_r_null;
100 static int hf_mpls_pm_timestamp3_r_seq;
101 static int hf_mpls_pm_timestamp3_r_ntp;
102 static int hf_mpls_pm_timestamp3_r_ptp;
103 static int hf_mpls_pm_timestamp3_unk;
104 static int hf_mpls_pm_timestamp4_null;
105 static int hf_mpls_pm_timestamp4_r_null;
106 static int hf_mpls_pm_timestamp4_r_seq;
107 static int hf_mpls_pm_timestamp4_r_ntp;
108 static int hf_mpls_pm_timestamp4_r_ptp;
109 static int hf_mpls_pm_timestamp4_unk;
112 * FF: please keep this list in sync with
113 * http://www.iana.org/assignments/mpls-lsp-ping-parameters
114 * Registry Name: 'Loss/Delay Measurement Control Code: Query Codes'
116 static const range_string mpls_pm_query_ctrl_code_rvals[] = {
117 { 0x00, 0x00, "In-band Response Requested" },
118 { 0x01, 0x01, "Out-of-band Response Requested" },
119 { 0x02, 0x02, "No Response Requested" },
120 { 0x03, 0xFF, "Unassigned" },
121 { 0x00, 0x00, NULL }
125 * FF: please keep this list in sync with
126 * http://www.iana.org/assignments/mpls-lsp-ping-parameters
127 * Registry Name: 'Loss/Delay Measurement Control Code: Response Codes'
129 static const range_string mpls_pm_response_ctrl_code_rvals[] = {
130 { 0x00, 0x00, "Reserved" },
131 { 0x01, 0x01, "Success" },
132 { 0x02, 0x02, "Data Format Invalid" },
133 { 0x03, 0x03, "Initialization in Progress" },
134 { 0x04, 0x04, "Data Reset Occurred" },
135 { 0x05, 0x05, "Resource Temporarily Unavailable" },
136 { 0x06, 0x0F, "Unassigned" },
137 { 0x10, 0x10, "Unspecified Error" },
138 { 0x11, 0x11, "Unsupported Version" },
139 { 0x12, 0x12, "Unsupported Control Code" },
140 { 0x13, 0x13, "Unsupported Data Format" },
141 { 0x14, 0x14, "Authentication Failure" },
142 { 0x15, 0x15, "Invalid Destination Node Identifier" },
143 { 0x16, 0x16, "Connection Mismatch" },
144 { 0x17, 0x17, "Unsupported Mandatory TLV Object" },
145 { 0x18, 0x18, "Unsupported Query Interval" },
146 { 0x19, 0x19, "Administrative Block" },
147 { 0x1A, 0x1A, "Resource Unavailable" },
148 { 0x1B, 0x1B, "Resource Released" },
149 { 0x1C, 0x1C, "Invalid Message" },
150 { 0x1D, 0x1D, "Protocol Error" },
151 { 0x1E, 0xFF, "Unassigned" },
152 { 0x00, 0x00, NULL }
155 #define DLM 1
156 #define ILM 2
157 #define DM 3
158 #define DLMDM 4
159 #define ILMDM 5
160 /* FF: internal */
161 static const value_string pmt_vals[] = {
162 { DLM, "DLM" },
163 { ILM, "ILM" },
164 { DM, "DM" },
165 { DLMDM, "DLM+DM" },
166 { ILMDM, "ILM+DM" },
167 { 0, NULL }
171 * FF: please keep this list in sync with
172 * http://www.iana.org/assignments/mpls-lsp-ping-parameters
173 * Registry Name: 'Loss/Delay Measurement Control Code: Response Codes'
175 #define MPLS_PM_TSF_NULL 0
176 #define MPLS_PM_TSF_SEQ 1
177 #define MPLS_PM_TSF_NTP 2
178 #define MPLS_PM_TSF_PTP 3
179 static const range_string mpls_pm_time_stamp_format_rvals[] = {
180 { MPLS_PM_TSF_NULL, MPLS_PM_TSF_NULL,
181 "Null Timestamp" },
182 { MPLS_PM_TSF_SEQ, MPLS_PM_TSF_SEQ,
183 "Sequence Number" },
184 { MPLS_PM_TSF_NTP, MPLS_PM_TSF_NTP,
185 "Network Time Protocol version 4 64-bit Timestamp" },
186 { MPLS_PM_TSF_PTP, MPLS_PM_TSF_PTP,
187 "Truncated IEEE 1588v2 PTP Timestamp" },
188 { 4, 15, "Unassigned" },
189 { 0, 0, NULL }
192 static void
193 mpls_pm_dissect_counter(tvbuff_t *tvb, proto_tree *pm_tree,
194 uint32_t offset, bool query, bool bflag,
195 uint8_t i)
197 proto_item *ti;
199 * FF: when bflag is true, indicates that the Counter 1-4
200 * fields represent octet counts. Otherwise Counter 1-4 fields
201 * represent packet counts
203 const char *unit = bflag ? "octets" : "packets";
205 if (query) {
206 switch (i) {
207 case 1:
208 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_counter1, tvb,
209 offset, 8, ENC_BIG_ENDIAN);
210 proto_item_append_text(ti, " %s (A_Tx)", unit);
211 break;
212 case 2:
213 proto_tree_add_item(pm_tree, hf_mpls_pm_counter2, tvb,
214 offset, 8, ENC_BIG_ENDIAN);
215 break;
216 case 3:
217 proto_tree_add_item(pm_tree, hf_mpls_pm_counter3, tvb,
218 offset, 8, ENC_BIG_ENDIAN);
219 break;
220 case 4:
221 proto_tree_add_item(pm_tree, hf_mpls_pm_counter4, tvb,
222 offset, 8, ENC_BIG_ENDIAN);
223 break;
224 default:
225 /* never here */
226 break;
228 } else {
229 /* response */
230 switch (i) {
231 case 1:
232 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_counter1, tvb,
233 offset, 8, ENC_BIG_ENDIAN);
234 proto_item_append_text(ti, " %s (B_Tx)", unit);
235 break;
236 case 2:
237 proto_tree_add_item(pm_tree, hf_mpls_pm_counter2, tvb,
238 offset, 8, ENC_BIG_ENDIAN);
239 break;
240 case 3:
241 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_counter3, tvb,
242 offset, 8, ENC_BIG_ENDIAN);
243 proto_item_append_text(ti, " %s (A_Tx)", unit);
244 break;
245 case 4:
246 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_counter4, tvb,
247 offset, 8, ENC_BIG_ENDIAN);
248 proto_item_append_text(ti, " %s (B_Rx)", unit);
249 break;
250 default:
251 /* never here */
252 break;
257 static void
258 mpls_pm_dissect_timestamp(tvbuff_t *tvb, proto_tree *pm_tree,
259 uint32_t offset, uint8_t qtf, uint8_t rtf,
260 bool query, uint8_t i)
262 if (query) {
264 * FF: when a query is sent from A, Timestamp 1 is set to T1 and the
265 * other timestamp fields are set to 0. Moreover, it might be useful
266 * to decode Timestamp 2 (set to T2) as well because data can be captured
267 * somewhere at the responder box after the timestamp has been taken.
269 switch (i) {
270 case 1:
271 switch (qtf) {
273 * FF: the actual formats of the timestamp fields written by A
274 * are indicated by the Querier Timestamp Format.
276 case MPLS_PM_TSF_NULL:
277 proto_tree_add_item(pm_tree,
278 hf_mpls_pm_timestamp1_q_null, tvb,
279 offset, 8, ENC_BIG_ENDIAN);
280 break;
281 case MPLS_PM_TSF_SEQ:
282 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_q_seq, tvb,
283 offset, 8, ENC_BIG_ENDIAN);
284 break;
285 case MPLS_PM_TSF_NTP:
286 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_q_ntp, tvb,
287 offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
288 break;
289 case MPLS_PM_TSF_PTP:
290 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_q_ptp, tvb,
291 offset, 8, ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN);
292 break;
293 default:
294 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_unk, tvb,
295 offset, 8, ENC_BIG_ENDIAN);
296 break;
298 break;
299 case 2:
300 switch (qtf) {
301 case MPLS_PM_TSF_NULL:
302 proto_tree_add_item(pm_tree,
303 hf_mpls_pm_timestamp2_q_null, tvb,
304 offset, 8, ENC_BIG_ENDIAN);
305 break;
306 case MPLS_PM_TSF_SEQ:
307 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp2_q_seq, tvb,
308 offset, 8, ENC_BIG_ENDIAN);
309 break;
310 case MPLS_PM_TSF_NTP:
311 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp2_q_ntp, tvb,
312 offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
313 break;
314 case MPLS_PM_TSF_PTP:
315 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp2_q_ptp, tvb,
316 offset, 8, ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN);
317 break;
318 default:
319 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp2_unk, tvb,
320 offset, 8, ENC_BIG_ENDIAN);
321 break;
323 break;
324 case 3:
325 proto_tree_add_item(pm_tree,
326 hf_mpls_pm_timestamp3_null, tvb,
327 offset, 8, ENC_BIG_ENDIAN);
328 break;
329 case 4:
330 proto_tree_add_item(pm_tree,
331 hf_mpls_pm_timestamp4_null, tvb,
332 offset, 8, ENC_BIG_ENDIAN);
333 break;
334 default:
335 /* never here */
336 break;
337 } /* end of switch (i) */
338 } else {
340 * FF: when B transmits the response, Timestamp 1 is set to T3,
341 * Timestamp 3 is set to T1 and Timestamp 4 is set to T2. Timestamp 2
342 * is set to 0. Moreover, it might be useful to decode Timestamp 2
343 * (set to T4) as well because data can be captured somewhere at the
344 * querier box after the timestamp has been taken.
346 switch (i) {
347 case 1:
348 switch (rtf) {
350 * FF: the actual formats of the timestamp fields written by B
351 * are indicated by the Responder Timestamp Format.
353 case MPLS_PM_TSF_NULL:
354 proto_tree_add_item(pm_tree,
355 hf_mpls_pm_timestamp1_r_null, tvb,
356 offset, 8, ENC_BIG_ENDIAN);
357 break;
358 case MPLS_PM_TSF_SEQ:
359 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_r_seq, tvb,
360 offset, 8, ENC_BIG_ENDIAN);
361 break;
362 case MPLS_PM_TSF_NTP:
363 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_r_ntp, tvb,
364 offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
365 break;
366 case MPLS_PM_TSF_PTP:
367 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_r_ptp, tvb,
368 offset, 8, ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN);
369 break;
370 default:
371 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_unk, tvb,
372 offset, 8, ENC_BIG_ENDIAN);
373 break;
375 break;
376 case 2:
377 switch (rtf) {
378 case MPLS_PM_TSF_NULL:
379 proto_tree_add_item(pm_tree,
380 hf_mpls_pm_timestamp2_r_null, tvb,
381 offset, 8, ENC_BIG_ENDIAN);
382 break;
383 case MPLS_PM_TSF_SEQ:
384 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp2_r_seq, tvb,
385 offset, 8, ENC_BIG_ENDIAN);
386 break;
387 case MPLS_PM_TSF_NTP:
388 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp2_r_ntp, tvb,
389 offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
390 break;
391 case MPLS_PM_TSF_PTP:
392 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp2_r_ptp, tvb,
393 offset, 8, ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN);
394 break;
395 default:
396 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp2_unk, tvb,
397 offset, 8, ENC_BIG_ENDIAN);
398 break;
400 break;
401 case 3:
402 switch (rtf) {
403 case MPLS_PM_TSF_NULL:
404 proto_tree_add_item(pm_tree,
405 hf_mpls_pm_timestamp3_r_null, tvb,
406 offset, 8, ENC_BIG_ENDIAN);
407 break;
408 case MPLS_PM_TSF_SEQ:
409 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp3_r_seq, tvb,
410 offset, 8, ENC_BIG_ENDIAN);
411 break;
412 case MPLS_PM_TSF_NTP:
413 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp3_r_ntp, tvb,
414 offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
415 break;
416 case MPLS_PM_TSF_PTP:
417 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp3_r_ptp, tvb,
418 offset, 8, ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN);
419 break;
420 default:
421 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp3_unk, tvb,
422 offset, 8, ENC_BIG_ENDIAN);
423 break;
425 break;
426 case 4:
427 switch (rtf) {
428 case MPLS_PM_TSF_NULL:
429 proto_tree_add_item(pm_tree,
430 hf_mpls_pm_timestamp4_r_null, tvb,
431 offset, 8, ENC_BIG_ENDIAN);
432 break;
433 case MPLS_PM_TSF_SEQ:
434 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp4_r_seq, tvb,
435 offset, 8, ENC_BIG_ENDIAN);
436 break;
437 case MPLS_PM_TSF_NTP:
438 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp4_r_ntp, tvb,
439 offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
440 break;
441 case MPLS_PM_TSF_PTP:
442 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp4_r_ptp, tvb,
443 offset, 8, ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN);
444 break;
445 default:
446 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp4_unk, tvb,
447 offset, 8, ENC_BIG_ENDIAN);
448 break;
450 break;
451 default:
452 /* never here */
453 break;
454 } /* end of switch (i) */
458 static void
459 mpls_pm_build_cinfo(tvbuff_t *tvb, packet_info *pinfo, const char *str_pmt,
460 bool *query, bool *response,
461 bool *class_specific,
462 uint32_t *sid, uint8_t *code)
464 col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "MPLS PM (%s)", str_pmt);
465 col_clear(pinfo->cinfo, COL_INFO);
467 *response = (tvb_get_uint8(tvb, 0) & 0x08) ? true : false;
468 *class_specific = (tvb_get_uint8(tvb, 0) & 0x04) ? true : false;
469 *query = !(*response);
470 *code = tvb_get_uint8(tvb, 1);
472 if (!(*class_specific)) {
474 * FF: when the T flag is set to 0 the DS field can be considered
475 * part of the Session Identifier.
477 *sid = tvb_get_ntohl(tvb, 8);
478 } else {
479 *sid = tvb_get_ntohl(tvb, 8) >> 6;
482 if (*query) {
483 col_add_fstr(pinfo->cinfo, COL_INFO,
484 "Query, sid: %u", *sid);
485 } else {
486 col_add_fstr(pinfo->cinfo, COL_INFO,
487 "Response, sid: %u, code: %s (%u)",
488 *sid,
489 rval_to_str_const(*code,
490 mpls_pm_response_ctrl_code_rvals,
491 "Unknown"),
492 *code);
496 /* FF: the message formats for direct and inferred LM are identical */
497 static void
498 dissect_mpls_pm_loss(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
499 uint8_t pmt)
501 proto_item *ti = NULL;
502 proto_tree *pm_tree;
503 proto_tree *pm_tree_flags;
504 proto_tree *pm_tree_dflags;
505 uint32_t offset = 0;
506 bool query = 0;
507 bool response = 0;
508 bool class_specific = 0;
509 uint32_t sid = 0;
510 uint8_t code = 0;
511 uint8_t otf;
512 bool bflag;
513 uint8_t i;
515 mpls_pm_build_cinfo(tvb, pinfo,
516 val_to_str_const(pmt, pmt_vals, ""),
517 &query, &response, &class_specific, &sid, &code);
519 if (!tree) {
520 return;
523 /* create display subtree for the protocol */
524 if (pmt == DLM) {
525 ti = proto_tree_add_item(tree, proto_mpls_pm_dlm, tvb, 0, -1, ENC_NA);
526 } else {
527 ti = proto_tree_add_item(tree, proto_mpls_pm_ilm, tvb, 0, -1, ENC_NA);
530 pm_tree = proto_item_add_subtree(ti, ett_mpls_pm);
532 /* add version to the subtree */
533 proto_tree_add_item(pm_tree, hf_mpls_pm_version, tvb, offset, 1, ENC_BIG_ENDIAN);
535 /* ctrl flags subtree */
537 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_flags, tvb,
538 offset, 1, ENC_BIG_ENDIAN);
539 pm_tree_flags = proto_item_add_subtree(ti, ett_mpls_pm_flags);
540 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_r, tvb,
541 offset, 1, ENC_NA);
542 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_t, tvb,
543 offset, 1, ENC_NA);
544 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_res, tvb,
545 offset, 1, ENC_NA);
546 offset += 1;
548 if (query) {
549 proto_tree_add_item(pm_tree, hf_mpls_pm_query_ctrl_code,
550 tvb, offset, 1, ENC_BIG_ENDIAN);
551 } else {
552 proto_tree_add_item(pm_tree, hf_mpls_pm_response_ctrl_code,
553 tvb, offset, 1, ENC_BIG_ENDIAN);
555 offset += 1;
557 proto_tree_add_item(pm_tree, hf_mpls_pm_length, tvb,
558 offset, 2, ENC_BIG_ENDIAN);
559 offset += 2;
561 /* data flags subtree */
562 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_dflags, tvb,
563 offset, 1, ENC_BIG_ENDIAN);
564 pm_tree_dflags = proto_item_add_subtree(ti, ett_mpls_pm_dflags);
565 proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_x, tvb,
566 offset, 1, ENC_NA);
567 bflag = (tvb_get_uint8(tvb, offset) & 0x40) ? true : false;
568 proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_b, tvb,
569 offset, 1, ENC_NA);
570 proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_res, tvb,
571 offset, 1, ENC_NA);
573 otf = tvb_get_uint8(tvb, offset) & 0x0F;
574 proto_tree_add_item(pm_tree, hf_mpls_pm_otf, tvb,
575 offset, 1, ENC_BIG_ENDIAN);
576 offset += 1;
578 /* skip 3 reserved bytes */
579 offset += 3;
581 proto_tree_add_uint(pm_tree, hf_mpls_pm_session_id, tvb, offset, 4, sid);
583 if (class_specific) {
584 proto_tree_add_item(pm_tree, hf_mpls_pm_ds, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
586 offset += 4;
588 switch (otf) {
589 case MPLS_PM_TSF_NULL:
590 proto_tree_add_item(pm_tree, hf_mpls_pm_origin_timestamp_null, tvb,
591 offset, 8, ENC_BIG_ENDIAN);
592 break;
593 case MPLS_PM_TSF_SEQ:
594 proto_tree_add_item(pm_tree, hf_mpls_pm_origin_timestamp_seq, tvb,
595 offset, 8, ENC_BIG_ENDIAN);
596 break;
597 case MPLS_PM_TSF_NTP:
598 proto_tree_add_item(pm_tree, hf_mpls_pm_origin_timestamp_ntp, tvb,
599 offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
600 break;
601 case MPLS_PM_TSF_PTP:
602 proto_tree_add_item(pm_tree, hf_mpls_pm_origin_timestamp_ptp, tvb,
603 offset, 8, ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN);
604 break;
605 default:
606 proto_tree_add_item(pm_tree, hf_mpls_pm_origin_timestamp_unk, tvb,
607 offset, 8, ENC_BIG_ENDIAN);
608 break;
610 offset += 8;
612 /* counters 1..4 */
613 for (i = 1; i <= 4; i++) {
614 mpls_pm_dissect_counter(tvb, pm_tree, offset, query, bflag, i);
615 offset += 8;
619 static int
620 dissect_mpls_pm_dlm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
622 /* the message formats for direct and inferred LM are identical */
623 dissect_mpls_pm_loss(tvb, pinfo, tree, DLM);
624 return tvb_captured_length(tvb);
627 static int
628 dissect_mpls_pm_ilm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
630 /* the message formats for direct and inferred LM are identical */
631 dissect_mpls_pm_loss(tvb, pinfo, tree, ILM);
632 return tvb_captured_length(tvb);
635 static int
636 dissect_mpls_pm_delay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
638 proto_item *ti;
639 proto_tree *pm_tree;
640 proto_tree *pm_tree_flags;
641 uint32_t offset = 0;
642 bool query = 0;
643 bool response = 0;
644 bool class_specific = 0;
645 uint32_t sid = 0;
646 uint8_t code = 0;
647 uint8_t qtf;
648 uint8_t rtf;
649 uint8_t i;
651 mpls_pm_build_cinfo(tvb, pinfo,
652 "DM",
653 &query, &response, &class_specific, &sid, &code);
655 /* create display subtree for the protocol */
656 ti = proto_tree_add_item(tree, proto_mpls_pm_dm, tvb, 0, -1, ENC_NA);
657 pm_tree = proto_item_add_subtree(ti, ett_mpls_pm);
659 /* add version to the subtree */
660 proto_tree_add_item(pm_tree, hf_mpls_pm_version, tvb, offset, 1, ENC_BIG_ENDIAN);
662 /* ctrl flags subtree */
663 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
664 pm_tree_flags = proto_item_add_subtree(ti, ett_mpls_pm_flags);
665 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_r, tvb,
666 offset, 1, ENC_NA);
667 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_t, tvb,
668 offset, 1, ENC_NA);
669 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_res, tvb,
670 offset, 1, ENC_NA);
671 offset += 1;
673 if (query) {
674 proto_tree_add_item(pm_tree, hf_mpls_pm_query_ctrl_code,
675 tvb, offset, 1, ENC_BIG_ENDIAN);
676 } else {
677 proto_tree_add_item(pm_tree, hf_mpls_pm_response_ctrl_code,
678 tvb, offset, 1, ENC_BIG_ENDIAN);
680 offset += 1;
682 proto_tree_add_item(pm_tree, hf_mpls_pm_length, tvb,
683 offset, 2, ENC_BIG_ENDIAN);
684 offset += 2;
686 /* qtf, rtf */
687 qtf = (tvb_get_uint8(tvb, offset) & 0xF0) >> 4;
688 proto_tree_add_item(pm_tree, hf_mpls_pm_qtf, tvb,
689 offset, 1, ENC_BIG_ENDIAN);
691 rtf = tvb_get_uint8(tvb, offset) & 0x0F;
692 proto_tree_add_item(pm_tree, hf_mpls_pm_rtf, tvb,
693 offset, 1, ENC_BIG_ENDIAN);
694 offset += 1;
696 /* rptf */
697 proto_tree_add_item(pm_tree, hf_mpls_pm_rptf, tvb,
698 offset, 1, ENC_BIG_ENDIAN);
700 /* skip 20 reserved bits */
701 offset += 3;
703 proto_tree_add_uint(pm_tree, hf_mpls_pm_session_id, tvb, offset, 4, sid);
705 if (class_specific) {
706 proto_tree_add_item(pm_tree, hf_mpls_pm_ds, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
708 offset += 4;
710 /* timestamps 1..4 */
711 for (i = 1; i <= 4; i++) {
712 mpls_pm_dissect_timestamp(tvb, pm_tree, offset, qtf, rtf, query, i);
713 offset += 8;
715 return tvb_captured_length(tvb);
718 static void
719 dissect_mpls_pm_combined(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
720 uint8_t pmt)
722 proto_item *ti = NULL;
723 proto_tree *pm_tree;
724 proto_tree *pm_tree_flags;
725 proto_tree *pm_tree_dflags;
726 uint32_t offset = 0;
727 bool query = 0;
728 bool response = 0;
729 bool class_specific = 0;
730 uint32_t sid = 0;
731 uint8_t code = 0;
732 uint8_t qtf;
733 uint8_t rtf;
734 bool bflag;
735 uint8_t i;
737 mpls_pm_build_cinfo(tvb, pinfo,
738 val_to_str_const(pmt, pmt_vals, ""),
739 &query, &response, &class_specific, &sid, &code);
741 if (!tree) {
742 return;
745 /* create display subtree for the protocol */
746 if (pmt == DLMDM) {
747 ti = proto_tree_add_item(tree, proto_mpls_pm_dlm_dm,
748 tvb, 0, -1, ENC_NA);
749 } else {
750 ti = proto_tree_add_item(tree, proto_mpls_pm_ilm_dm,
751 tvb, 0, -1, ENC_NA);
754 pm_tree = proto_item_add_subtree(ti, ett_mpls_pm);
756 /* add version to the subtree */
757 proto_tree_add_item(pm_tree, hf_mpls_pm_version, tvb, offset, 1, ENC_BIG_ENDIAN);
759 /* ctrl flags subtree */
760 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
761 pm_tree_flags = proto_item_add_subtree(ti, ett_mpls_pm_flags);
762 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_r, tvb,
763 offset, 1, ENC_NA);
764 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_t, tvb,
765 offset, 1, ENC_NA);
766 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_res, tvb,
767 offset, 1, ENC_NA);
768 offset += 1;
770 if (query) {
771 proto_tree_add_item(pm_tree, hf_mpls_pm_query_ctrl_code,
772 tvb, offset, 1, ENC_BIG_ENDIAN);
773 } else {
774 proto_tree_add_item(pm_tree, hf_mpls_pm_response_ctrl_code,
775 tvb, offset, 1, ENC_BIG_ENDIAN);
777 offset += 1;
779 proto_tree_add_item(pm_tree, hf_mpls_pm_length, tvb,
780 offset, 2, ENC_BIG_ENDIAN);
781 offset += 2;
783 /* data flags subtree */
784 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_dflags, tvb,
785 offset, 1, ENC_BIG_ENDIAN);
786 pm_tree_dflags = proto_item_add_subtree(ti, ett_mpls_pm_dflags);
787 proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_x, tvb,
788 offset, 1, ENC_NA);
789 bflag = (tvb_get_uint8(tvb, offset) & 0x40) ? true : false;
790 proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_b, tvb,
791 offset, 1, ENC_NA);
792 proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_res, tvb,
793 offset, 1, ENC_NA);
796 * FF: the roles of the OTF and Origin Timestamp fields for LM are
797 * here played by the QTF and Timestamp 1 fields, respectively.
799 qtf = tvb_get_uint8(tvb, offset) & 0x0F;
800 proto_tree_add_item(pm_tree, hf_mpls_pm_qtf_combined, tvb,
801 offset, 1, ENC_BIG_ENDIAN);
802 offset += 1;
804 /* rtf, rptf */
805 rtf = tvb_get_uint8(tvb, offset) & 0xF0 >> 4;
806 proto_tree_add_item(pm_tree, hf_mpls_pm_rtf_combined, tvb,
807 offset, 1, ENC_BIG_ENDIAN);
809 proto_tree_add_item(pm_tree, hf_mpls_pm_rptf_combined, tvb,
810 offset, 1, ENC_BIG_ENDIAN);
811 offset += 1;
813 /* skip 2 reserved bytes */
814 offset += 2;
816 proto_tree_add_uint(pm_tree, hf_mpls_pm_session_id, tvb, offset, 4, sid);
818 if (class_specific) {
819 proto_tree_add_item(pm_tree, hf_mpls_pm_ds, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
821 offset += 4;
823 /* timestamps 1..4 */
824 for (i = 1; i <= 4; i++) {
825 mpls_pm_dissect_timestamp(tvb, pm_tree, offset, qtf, rtf, query, i);
826 offset += 8;
829 /* counters 1..4 */
830 for (i = 1; i <= 4; i++) {
831 mpls_pm_dissect_counter(tvb, pm_tree, offset, query, bflag, i);
832 offset += 8;
836 static int
837 dissect_mpls_pm_dlm_dm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
839 /* the formats of the DLM+DM and ILM+DM messages are also identical */
840 dissect_mpls_pm_combined(tvb, pinfo, tree, DLMDM);
841 return tvb_captured_length(tvb);
844 static int
845 dissect_mpls_pm_ilm_dm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
847 /* the formats of the DLM+DM and ILM+DM messages are also identical */
848 dissect_mpls_pm_combined(tvb, pinfo, tree, ILMDM);
849 return tvb_captured_length(tvb);
852 void
853 proto_register_mpls_pm(void)
855 static hf_register_info hf[] = {
857 &hf_mpls_pm_version,
859 "Version", "mpls_pm.version", FT_UINT8, BASE_DEC, NULL,
860 0xF0, NULL, HFILL
864 &hf_mpls_pm_flags,
866 "Flags", "mpls_pm.flags", FT_UINT8,
867 BASE_HEX, NULL, MPLS_PM_FLAGS_MASK, NULL, HFILL
871 &hf_mpls_pm_flags_r,
873 "Response indicator (R)", "mpls_pm.flags.r",
874 FT_BOOLEAN, 8, TFS(&tfs_set_notset), MPLS_PM_FLAGS_R,
875 NULL, HFILL
879 &hf_mpls_pm_flags_t,
881 "Traffic-class-specific measurement indicator (T)",
882 "mpls_pm.flags.t",
883 FT_BOOLEAN, 8, TFS(&tfs_set_notset), MPLS_PM_FLAGS_T,
884 NULL, HFILL
888 &hf_mpls_pm_flags_res,
890 "Reserved",
891 "mpls_pm.flags.res",
892 FT_BOOLEAN, 8, TFS(&tfs_set_notset), MPLS_PM_FLAGS_RES,
893 NULL, HFILL
897 &hf_mpls_pm_query_ctrl_code,
899 "Control Code",
900 "mpls_pm.ctrl.code",
901 FT_UINT8, BASE_RANGE_STRING | BASE_HEX,
902 RVALS(mpls_pm_query_ctrl_code_rvals), 0x0,
903 "Code identifying the query type", HFILL
907 &hf_mpls_pm_response_ctrl_code,
909 "Control Code",
910 "mpls_pm.ctrl.code",
911 FT_UINT8, BASE_RANGE_STRING | BASE_HEX,
912 RVALS(mpls_pm_response_ctrl_code_rvals), 0x0,
913 "Code identifying the response type", HFILL
917 &hf_mpls_pm_length,
919 "Message Length",
920 "mpls_pm.length",
921 FT_UINT16, BASE_DEC, NULL, 0x0,
922 "Total length of this message in bytes", HFILL
926 &hf_mpls_pm_dflags,
928 "DFlags", "mpls_pm.dflags", FT_UINT8,
929 BASE_HEX, NULL, MPLS_PM_DFLAGS_MASK,
930 NULL, HFILL
934 &hf_mpls_pm_dflags_x,
936 "Extended counter format indicator (X)", "mpls_pm.dflags.x",
937 FT_BOOLEAN, 8, TFS(&tfs_set_notset), MPLS_PM_DFLAGS_X,
938 NULL, HFILL
942 &hf_mpls_pm_dflags_b,
944 "Octet/Byte count indicator (B)", "mpls_pm.dflags.b",
945 FT_BOOLEAN, 8, TFS(&tfs_set_notset), MPLS_PM_DFLAGS_B,
946 NULL, HFILL
950 &hf_mpls_pm_dflags_res,
952 "Reserved",
953 "mpls_pm.dflags.res",
954 FT_BOOLEAN, 8, NULL, MPLS_PM_DFLAGS_RES,
955 NULL, HFILL
959 &hf_mpls_pm_otf,
961 "Origin Timestamp Format (OTF)",
962 "mpls_pm.otf",
963 FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
964 RVALS(mpls_pm_time_stamp_format_rvals), 0x0F,
965 NULL, HFILL
969 &hf_mpls_pm_session_id,
971 "Session Identifier",
972 "mpls_pm.session.id",
973 FT_UINT32, BASE_DEC,
974 NULL, 0x0,
975 NULL, HFILL
979 &hf_mpls_pm_ds,
981 "Differentiated Services Codepoint",
982 "mpls_pm.ds",
983 FT_UINT8, BASE_DEC | BASE_EXT_STRING,
984 &dscp_vals_ext, 0x3F,
985 NULL, HFILL
989 &hf_mpls_pm_origin_timestamp_null,
991 "Origin Timestamp",
992 "mpls_pm.origin.timestamp.null",
993 FT_UINT64, BASE_DEC,
994 NULL, 0x0,
995 NULL, HFILL
999 &hf_mpls_pm_origin_timestamp_seq,
1001 "Origin Timestamp",
1002 "mpls_pm.origin.timestamp.seq",
1003 FT_UINT64, BASE_DEC,
1004 NULL, 0x0,
1005 NULL, HFILL
1009 &hf_mpls_pm_origin_timestamp_ntp,
1011 "Origin Timestamp",
1012 "mpls_pm.origin.timestamp.ntp",
1013 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC,
1014 NULL, 0x0,
1015 NULL, HFILL
1019 &hf_mpls_pm_origin_timestamp_ptp,
1021 "Origin Timestamp",
1022 "mpls_pm.origin.timestamp.ptp",
1023 FT_RELATIVE_TIME, BASE_NONE,
1024 NULL, 0x0,
1025 NULL, HFILL
1029 &hf_mpls_pm_origin_timestamp_unk,
1031 "Origin Timestamp (Unknown Type)",
1032 "mpls_pm.origin.timestamp.unk",
1033 FT_UINT64, BASE_DEC,
1034 NULL, 0x0,
1035 NULL, HFILL
1039 &hf_mpls_pm_counter1,
1041 "Counter 1",
1042 "mpls_pm.counter1",
1043 FT_UINT64, BASE_DEC,
1044 NULL, 0x0,
1045 NULL, HFILL
1049 &hf_mpls_pm_counter2,
1051 "Counter 2",
1052 "mpls_pm.counter2",
1053 FT_UINT64, BASE_DEC,
1054 NULL, 0x0,
1055 NULL, HFILL
1059 &hf_mpls_pm_counter3,
1061 "Counter 3",
1062 "mpls_pm.counter3",
1063 FT_UINT64, BASE_DEC,
1064 NULL, 0x0,
1065 NULL, HFILL
1069 &hf_mpls_pm_counter4,
1071 "Counter 4",
1072 "mpls_pm.counter4",
1073 FT_UINT64, BASE_DEC,
1074 NULL, 0x0,
1075 NULL, HFILL
1079 &hf_mpls_pm_qtf,
1081 "Querier timestamp format (QTF)",
1082 "mpls_pm.qtf",
1083 FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1084 RVALS(mpls_pm_time_stamp_format_rvals), 0xF0,
1085 NULL, HFILL
1089 &hf_mpls_pm_qtf_combined,
1091 "Querier timestamp format (QTF)",
1092 "mpls_pm.qtf",
1093 FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1094 RVALS(mpls_pm_time_stamp_format_rvals), 0x0F,
1095 NULL, HFILL
1099 &hf_mpls_pm_rtf,
1101 "Responder timestamp format (RTF)",
1102 "mpls_pm.rtf",
1103 FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1104 RVALS(mpls_pm_time_stamp_format_rvals), 0x0F,
1105 NULL, HFILL
1109 &hf_mpls_pm_rtf_combined,
1111 "Responder timestamp format (RTF)",
1112 "mpls_pm.rtf",
1113 FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1114 RVALS(mpls_pm_time_stamp_format_rvals), 0xF0,
1115 NULL, HFILL
1119 &hf_mpls_pm_rptf,
1121 "Responder's preferred timestamp format (RPTF)",
1122 "mpls_pm.rptf",
1123 FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1124 RVALS(mpls_pm_time_stamp_format_rvals), 0xF0,
1125 NULL, HFILL
1129 &hf_mpls_pm_rptf_combined,
1131 "Responder's preferred timestamp format (RPTF)",
1132 "mpls_pm.rptf",
1133 FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1134 RVALS(mpls_pm_time_stamp_format_rvals), 0x0F,
1135 NULL, HFILL
1139 &hf_mpls_pm_timestamp1_q_null,
1141 "Timestamp 1 (T1)",
1142 "mpls_pm.timestamp1.null",
1143 FT_UINT64, BASE_DEC,
1144 NULL, 0x0,
1145 NULL, HFILL
1149 &hf_mpls_pm_timestamp1_r_null,
1151 "Timestamp 1 (T3)",
1152 "mpls_pm.timestamp1.null",
1153 FT_UINT64, BASE_DEC,
1154 NULL, 0x0,
1155 NULL, HFILL
1159 &hf_mpls_pm_timestamp1_q_seq,
1161 "Timestamp 1 (T1)",
1162 "mpls_pm.timestamp1.seq",
1163 FT_UINT64, BASE_DEC,
1164 NULL, 0x0,
1165 NULL, HFILL
1169 &hf_mpls_pm_timestamp1_r_seq,
1171 "Timestamp 1 (T3)",
1172 "mpls_pm.timestamp1.seq",
1173 FT_UINT64, BASE_DEC,
1174 NULL, 0x0,
1175 NULL, HFILL
1179 &hf_mpls_pm_timestamp1_q_ntp,
1181 "Timestamp 1 (T1)",
1182 "mpls_pm.timestamp1.ntp",
1183 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC,
1184 NULL, 0x0,
1185 NULL, HFILL
1189 &hf_mpls_pm_timestamp1_r_ntp,
1191 "Timestamp 1 (T3)",
1192 "mpls_pm.timestamp1.ntp",
1193 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC,
1194 NULL, 0x0,
1195 NULL, HFILL
1199 &hf_mpls_pm_timestamp1_q_ptp,
1201 "Timestamp 1 (T1)",
1202 "mpls_pm.timestamp1.ptp",
1203 FT_RELATIVE_TIME, BASE_NONE,
1204 NULL, 0x0,
1205 NULL, HFILL
1209 &hf_mpls_pm_timestamp1_r_ptp,
1211 "Timestamp 1 (T3)",
1212 "mpls_pm.timestamp1.ptp",
1213 FT_RELATIVE_TIME, BASE_NONE,
1214 NULL, 0x0,
1215 NULL, HFILL
1219 &hf_mpls_pm_timestamp1_unk,
1221 "Timestamp 1 (Unknown Type)",
1222 "mpls_pm.timestamp1.unk",
1223 FT_UINT64, BASE_DEC,
1224 NULL, 0x0,
1225 NULL, HFILL
1229 &hf_mpls_pm_timestamp2_q_null,
1231 "Timestamp 2 (T2)",
1232 "mpls_pm.timestamp2.null",
1233 FT_UINT64, BASE_DEC,
1234 NULL, 0x0,
1235 NULL, HFILL
1239 &hf_mpls_pm_timestamp2_r_null,
1241 "Timestamp 2 (T4)",
1242 "mpls_pm.timestamp2.null",
1243 FT_UINT64, BASE_DEC,
1244 NULL, 0x0,
1245 NULL, HFILL
1249 &hf_mpls_pm_timestamp2_q_seq,
1251 "Timestamp 2 (T2)",
1252 "mpls_pm.timestamp2.seq",
1253 FT_UINT64, BASE_DEC,
1254 NULL, 0x0,
1255 NULL, HFILL
1259 &hf_mpls_pm_timestamp2_r_seq,
1261 "Timestamp 2 (T4)",
1262 "mpls_pm.timestamp2.seq",
1263 FT_UINT64, BASE_DEC,
1264 NULL, 0x0,
1265 NULL, HFILL
1269 &hf_mpls_pm_timestamp2_q_ntp,
1271 "Timestamp 2 (T2)",
1272 "mpls_pm.timestamp2.ntp",
1273 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC,
1274 NULL, 0x0,
1275 NULL, HFILL
1279 &hf_mpls_pm_timestamp2_r_ntp,
1281 "Timestamp 2 (T4)",
1282 "mpls_pm.timestamp2.ntp",
1283 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC,
1284 NULL, 0x0,
1285 NULL, HFILL
1289 &hf_mpls_pm_timestamp2_q_ptp,
1291 "Timestamp 2 (T2)",
1292 "mpls_pm.timestamp2.ptp",
1293 FT_RELATIVE_TIME, BASE_NONE,
1294 NULL, 0x0,
1295 NULL, HFILL
1299 &hf_mpls_pm_timestamp2_r_ptp,
1301 "Timestamp 2 (T4)",
1302 "mpls_pm.timestamp2.ptp",
1303 FT_RELATIVE_TIME, BASE_NONE,
1304 NULL, 0x0,
1305 NULL, HFILL
1309 &hf_mpls_pm_timestamp2_unk,
1311 "Timestamp 2 (Unknown Type)",
1312 "mpls_pm.timestamp2.unk",
1313 FT_UINT64, BASE_DEC,
1314 NULL, 0x0,
1315 NULL, HFILL
1319 &hf_mpls_pm_timestamp3_null,
1321 "Timestamp 3",
1322 "mpls_pm.timestamp3.null",
1323 FT_UINT64, BASE_DEC,
1324 NULL, 0x0,
1325 NULL, HFILL
1329 &hf_mpls_pm_timestamp3_r_null,
1331 "Timestamp 3 (T1)",
1332 "mpls_pm.timestamp3.null",
1333 FT_UINT64, BASE_DEC,
1334 NULL, 0x0,
1335 NULL, HFILL
1339 &hf_mpls_pm_timestamp3_r_seq,
1341 "Timestamp 3 (T1)",
1342 "mpls_pm.timestamp3.seq",
1343 FT_UINT64, BASE_DEC,
1344 NULL, 0x0,
1345 NULL, HFILL
1349 &hf_mpls_pm_timestamp3_r_ntp,
1351 "Timestamp 3 (T1)",
1352 "mpls_pm.timestamp3.ntp",
1353 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC,
1354 NULL, 0x0,
1355 NULL, HFILL
1359 &hf_mpls_pm_timestamp3_r_ptp,
1361 "Timestamp 3 (T1)",
1362 "mpls_pm.timestamp3_ptp",
1363 FT_RELATIVE_TIME, BASE_NONE,
1364 NULL, 0x0,
1365 NULL, HFILL
1369 &hf_mpls_pm_timestamp3_unk,
1371 "Timestamp 3 (Unknown Type)",
1372 "mpls_pm.timestamp3.unk",
1373 FT_UINT64, BASE_DEC,
1374 NULL, 0x0,
1375 NULL, HFILL
1379 &hf_mpls_pm_timestamp4_null,
1381 "Timestamp 4",
1382 "mpls_pm.timestamp4.null",
1383 FT_UINT64, BASE_DEC,
1384 NULL, 0x0,
1385 NULL, HFILL
1389 &hf_mpls_pm_timestamp4_r_null,
1391 "Timestamp 4 (T2)",
1392 "mpls_pm.timestamp4.null",
1393 FT_UINT64, BASE_DEC,
1394 NULL, 0x0,
1395 NULL, HFILL
1399 &hf_mpls_pm_timestamp4_r_seq,
1401 "Timestamp 4 (T2)",
1402 "mpls_pm.timestamp4.seq",
1403 FT_UINT64, BASE_DEC,
1404 NULL, 0x0,
1405 NULL, HFILL
1409 &hf_mpls_pm_timestamp4_r_ntp,
1411 "Timestamp 4 (T2)",
1412 "mpls_pm.timestamp4.ntp",
1413 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC,
1414 NULL, 0x0,
1415 NULL, HFILL
1419 &hf_mpls_pm_timestamp4_r_ptp,
1421 "Timestamp 4 (T2)",
1422 "mpls_pm.timestamp4.ptp",
1423 FT_RELATIVE_TIME, BASE_NONE,
1424 NULL, 0x0,
1425 NULL, HFILL
1429 &hf_mpls_pm_timestamp4_unk,
1431 "Timestamp 4 (Unknown Type)",
1432 "mpls_pm.timestamp4.unk",
1433 FT_UINT64, BASE_DEC,
1434 NULL, 0x0,
1435 NULL, HFILL
1440 static int *ett[] = {
1441 &ett_mpls_pm,
1442 &ett_mpls_pm_flags,
1443 &ett_mpls_pm_dflags
1446 proto_mpls_pm_dlm =
1447 proto_register_protocol("MPLS Direct Loss Measurement (DLM)",
1448 "MPLS Direct Loss Measurement (DLM)",
1449 "mplspmdlm");
1451 proto_mpls_pm_ilm =
1452 proto_register_protocol("MPLS Inferred Loss Measurement (ILM)",
1453 "MPLS Inferred Loss Measurement (ILM)",
1454 "mplspmilm");
1456 proto_mpls_pm_dm =
1457 proto_register_protocol("MPLS Delay Measurement (DM)",
1458 "MPLS Delay Measurement (DM)",
1459 "mplspmdm");
1461 proto_mpls_pm_dlm_dm =
1462 proto_register_protocol("MPLS Direct Loss and Delay "
1463 "Measurement (DLM+DM)",
1464 "MPLS Direct Loss and Delay "
1465 "Measurement (DLM+DM)",
1466 "mplspmdlmdm");
1468 proto_mpls_pm_ilm_dm =
1469 proto_register_protocol("MPLS Inferred Loss and Delay "
1470 "Measurement (ILM+DM)",
1471 "MPLS Inferred Loss and Delay "
1472 "Measurement (ILM+DM)",
1473 "mplspmilmdm");
1475 proto_register_field_array(proto_mpls_pm_dlm, hf, array_length(hf));
1476 proto_register_subtree_array(ett, array_length(ett));
1479 void
1480 proto_reg_handoff_mpls_pm(void)
1482 dissector_handle_t mpls_pm_dlm_handle, mpls_pm_ilm_handle, mpls_pm_dm_handle,
1483 mpls_pm_dlm_dm_handle, mpls_pm_ilm_dm_handle;
1485 mpls_pm_dlm_handle = create_dissector_handle( dissect_mpls_pm_dlm, proto_mpls_pm_dlm );
1486 dissector_add_uint("pwach.channel_type", PW_ACH_TYPE_DLM, mpls_pm_dlm_handle);
1487 mpls_pm_ilm_handle = create_dissector_handle( dissect_mpls_pm_ilm, proto_mpls_pm_ilm );
1488 dissector_add_uint("pwach.channel_type", PW_ACH_TYPE_ILM, mpls_pm_ilm_handle);
1489 mpls_pm_dm_handle = create_dissector_handle( dissect_mpls_pm_delay, proto_mpls_pm_dm );
1490 dissector_add_uint("pwach.channel_type", PW_ACH_TYPE_DM, mpls_pm_dm_handle);
1491 mpls_pm_dlm_dm_handle = create_dissector_handle( dissect_mpls_pm_dlm_dm, proto_mpls_pm_dlm_dm );
1492 dissector_add_uint("pwach.channel_type", PW_ACH_TYPE_DLM_DM, mpls_pm_dlm_dm_handle);
1493 mpls_pm_ilm_dm_handle = create_dissector_handle( dissect_mpls_pm_ilm_dm, proto_mpls_pm_ilm_dm );
1494 dissector_add_uint("pwach.channel_type", PW_ACH_TYPE_ILM_DM, mpls_pm_ilm_dm_handle);
1498 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1500 * Local variables:
1501 * c-basic-offset: 4
1502 * tab-width: 8
1503 * indent-tabs-mode: nil
1504 * End:
1506 * vi: set shiftwidth=4 tabstop=8 expandtab:
1507 * :indentSize=4:tabSize=8:noTabs=true: