HACK: 2nd try to match RowsetProperties
[wireshark-wip.git] / epan / dissectors / packet-mpls-pm.c
blob89570ef9d7220af11696e7e28a01683466c504b3
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 * $Id$
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include "config.h"
33 #include <glib.h>
35 #include <epan/packet.h>
36 #include <packet-ip.h>
38 /* message control flags */
39 #define MPLS_PM_FLAGS_R 0x08
40 #define MPLS_PM_FLAGS_T 0x04
41 #define MPLS_PM_FLAGS_RES 0x03
42 #define MPLS_PM_FLAGS_MASK 0x0F
44 /* data format flags */
45 #define MPLS_PM_DFLAGS_X 0x80
46 #define MPLS_PM_DFLAGS_B 0x40
47 #define MPLS_PM_DFLAGS_RES 0x30
48 #define MPLS_PM_DFLAGS_MASK 0xF0
50 static gint proto_mpls_pm_dlm = -1;
51 static gint proto_mpls_pm_ilm = -1;
52 static gint proto_mpls_pm_dm = -1;
53 static gint proto_mpls_pm_dlm_dm = -1;
54 static gint proto_mpls_pm_ilm_dm = -1;
56 static gint ett_mpls_pm = -1;
57 static gint ett_mpls_pm_flags = -1;
58 static gint ett_mpls_pm_dflags = -1;
60 static int hf_mpls_pm_version = -1;
61 static int hf_mpls_pm_flags = -1;
62 static int hf_mpls_pm_flags_r = -1;
63 static int hf_mpls_pm_flags_t = -1;
64 static int hf_mpls_pm_flags_res = -1;
65 static int hf_mpls_pm_query_ctrl_code = -1;
66 static int hf_mpls_pm_response_ctrl_code = -1;
67 static int hf_mpls_pm_length = -1;
68 static int hf_mpls_pm_dflags = -1;
69 static int hf_mpls_pm_dflags_x = -1;
70 static int hf_mpls_pm_dflags_b = -1;
71 static int hf_mpls_pm_dflags_res = -1;
72 static int hf_mpls_pm_otf = -1;
73 static int hf_mpls_pm_session_id = -1;
74 static int hf_mpls_pm_ds = -1;
75 static int hf_mpls_pm_origin_timestamp_null = -1;
76 static int hf_mpls_pm_origin_timestamp_seq = -1;
77 static int hf_mpls_pm_origin_timestamp_ntp = -1;
78 static int hf_mpls_pm_origin_timestamp_ptp = -1;
79 static int hf_mpls_pm_origin_timestamp_unk = -1;
80 static int hf_mpls_pm_counter1 = -1;
81 static int hf_mpls_pm_counter2 = -1;
82 static int hf_mpls_pm_counter3 = -1;
83 static int hf_mpls_pm_counter4 = -1;
84 static int hf_mpls_pm_qtf = -1;
85 static int hf_mpls_pm_qtf_combined = -1;
86 static int hf_mpls_pm_rtf = -1;
87 static int hf_mpls_pm_rtf_combined = -1;
88 static int hf_mpls_pm_rptf = -1;
89 static int hf_mpls_pm_rptf_combined = -1;
90 static int hf_mpls_pm_timestamp1_q_null = -1;
91 static int hf_mpls_pm_timestamp1_r_null = -1;
92 static int hf_mpls_pm_timestamp1_q_seq = -1;
93 static int hf_mpls_pm_timestamp1_r_seq = -1;
94 static int hf_mpls_pm_timestamp1_q_ntp = -1;
95 static int hf_mpls_pm_timestamp1_r_ntp = -1;
96 static int hf_mpls_pm_timestamp1_q_ptp = -1;
97 static int hf_mpls_pm_timestamp1_r_ptp = -1;
98 static int hf_mpls_pm_timestamp1_unk = -1;
99 static int hf_mpls_pm_timestamp2_null = -1;
100 static int hf_mpls_pm_timestamp3_null = -1;
101 static int hf_mpls_pm_timestamp3_r_null = -1;
102 static int hf_mpls_pm_timestamp3_r_seq = -1;
103 static int hf_mpls_pm_timestamp3_r_ntp = -1;
104 static int hf_mpls_pm_timestamp3_r_ptp = -1;
105 static int hf_mpls_pm_timestamp3_unk = -1;
106 static int hf_mpls_pm_timestamp4_null = -1;
107 static int hf_mpls_pm_timestamp4_r_null = -1;
108 static int hf_mpls_pm_timestamp4_r_seq = -1;
109 static int hf_mpls_pm_timestamp4_r_ntp = -1;
110 static int hf_mpls_pm_timestamp4_r_ptp = -1;
111 static int hf_mpls_pm_timestamp4_unk = -1;
113 static dissector_handle_t mpls_pm_dlm_handle;
114 static dissector_handle_t mpls_pm_ilm_handle;
115 static dissector_handle_t mpls_pm_dm_handle;
116 static dissector_handle_t mpls_pm_dlm_dm_handle;
117 static dissector_handle_t mpls_pm_ilm_dm_handle;
120 * FF: please keep this list in sync with
121 * http://www.iana.org/assignments/mpls-lsp-ping-parameters
122 * Registry Name: 'Loss/Delay Measurement Control Code: Query Codes'
124 const range_string mpls_pm_query_ctrl_code_rvals[] = {
125 { 0x00, 0x00, "In-band Response Requested" },
126 { 0x01, 0x01, "Out-of-band Response Requested" },
127 { 0x02, 0x02, "No Response Requested" },
128 { 0x03, 0xFF, "Unassigned" },
129 { 0x00, 0x00, NULL }
133 * FF: please keep this list in sync with
134 * http://www.iana.org/assignments/mpls-lsp-ping-parameters
135 * Registry Name: 'Loss/Delay Measurement Control Code: Response Codes'
137 const range_string mpls_pm_response_ctrl_code_rvals[] = {
138 { 0x00, 0x00, "Reserved" },
139 { 0x01, 0x01, "Success" },
140 { 0x02, 0x02, "Data Format Invalid" },
141 { 0x03, 0x03, "Initialization in Progress" },
142 { 0x04, 0x04, "Data Reset Occurred" },
143 { 0x05, 0x05, "Resource Temporarily Unavailable" },
144 { 0x06, 0x0F, "Unassigned" },
145 { 0x10, 0x10, "Unspecified Error" },
146 { 0x11, 0x11, "Unsupported Version" },
147 { 0x12, 0x12, "Unsupported Control Code" },
148 { 0x13, 0x13, "Unsupported Data Format" },
149 { 0x14, 0x14, "Authentication Failure" },
150 { 0x15, 0x15, "Invalid Destination Node Identifier" },
151 { 0x16, 0x16, "Connection Mismatch" },
152 { 0x17, 0x17, "Unsupported Mandatory TLV Object" },
153 { 0x18, 0x18, "Unsupported Query Interval" },
154 { 0x19, 0x19, "Administrative Block" },
155 { 0x1A, 0x1A, "Resource Unavailable" },
156 { 0x1B, 0x1B, "Resource Released" },
157 { 0x1C, 0x1C, "Invalid Message" },
158 { 0x1D, 0x1D, "Protocol Error" },
159 { 0x1E, 0xFF, "Unassigned" },
160 { 0x00, 0x00, NULL }
163 #define DLM 1
164 #define ILM 2
165 #define DM 3
166 #define DLMDM 4
167 #define ILMDM 5
168 /* FF: internal */
169 static const value_string pmt_vals[] = {
170 { DLM, "DLM" },
171 { ILM, "ILM" },
172 { DM, "DM" },
173 { DLMDM, "DLM+DM" },
174 { ILMDM, "ILM+DM" },
175 { 0, NULL }
179 * FF: please keep this list in sync with
180 * http://www.iana.org/assignments/mpls-lsp-ping-parameters
181 * Registry Name: 'Loss/Delay Measurement Control Code: Response Codes'
183 #define MPLS_PM_TSF_NULL 0
184 #define MPLS_PM_TSF_SEQ 1
185 #define MPLS_PM_TSF_NTP 2
186 #define MPLS_PM_TSF_PTP 3
187 const range_string mpls_pm_time_stamp_format_rvals[] = {
188 { MPLS_PM_TSF_NULL, MPLS_PM_TSF_NULL,
189 "Null Timestamp" },
190 { MPLS_PM_TSF_SEQ, MPLS_PM_TSF_SEQ,
191 "Sequence Number" },
192 { MPLS_PM_TSF_NTP, MPLS_PM_TSF_NTP,
193 "Network Time Protocol version 4 64-bit Timestamp" },
194 { MPLS_PM_TSF_PTP, MPLS_PM_TSF_PTP,
195 "Truncated IEEE 1588v2 PTP Timestamp" },
196 { 4, 15, "Unassigned" },
197 { 0, 0, NULL }
200 static void
201 mpls_pm_dissect_counter(tvbuff_t *tvb, proto_tree *pm_tree,
202 guint32 offset, gboolean query, gboolean bflag,
203 guint8 i)
205 proto_item *ti;
207 * FF: when bflag is true, indicates that the Counter 1-4
208 * fields represent octet counts. Otherwise Counter 1-4 fields
209 * represent packet counts
211 const gchar *unit = bflag ? "octets" : "packets";
213 if (query) {
214 switch (i) {
215 case 1:
216 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_counter1, tvb,
217 offset, 8, ENC_BIG_ENDIAN);
218 proto_item_append_text(ti, " %s (A_Tx)", unit);
219 break;
220 case 2:
221 proto_tree_add_item(pm_tree, hf_mpls_pm_counter2, tvb,
222 offset, 8, ENC_BIG_ENDIAN);
223 break;
224 case 3:
225 proto_tree_add_item(pm_tree, hf_mpls_pm_counter3, tvb,
226 offset, 8, ENC_BIG_ENDIAN);
227 break;
228 case 4:
229 proto_tree_add_item(pm_tree, hf_mpls_pm_counter4, tvb,
230 offset, 8, ENC_BIG_ENDIAN);
231 break;
232 default:
233 /* never here */
234 break;
236 } else {
237 /* response */
238 switch (i) {
239 case 1:
240 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_counter1, tvb,
241 offset, 8, ENC_BIG_ENDIAN);
242 proto_item_append_text(ti, " %s (B_Tx)", unit);
243 break;
244 case 2:
245 proto_tree_add_item(pm_tree, hf_mpls_pm_counter2, tvb,
246 offset, 8, ENC_BIG_ENDIAN);
247 break;
248 case 3:
249 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_counter3, tvb,
250 offset, 8, ENC_BIG_ENDIAN);
251 proto_item_append_text(ti, " %s (A_Tx)", unit);
252 break;
253 case 4:
254 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_counter4, tvb,
255 offset, 8, ENC_BIG_ENDIAN);
256 proto_item_append_text(ti, " %s (B_Rx)", unit);
257 break;
258 default:
259 /* never here */
260 break;
265 static void
266 mpls_pm_dissect_timestamp(tvbuff_t *tvb, proto_tree *pm_tree,
267 guint32 offset, guint8 qtf, guint8 rtf,
268 gboolean query, guint8 i)
270 if (query) {
272 * FF: when a query is sent from A, Timestamp 1 is set to T1 and the
273 * other timestamp fields are set to 0.
275 switch (i) {
276 case 1:
277 switch (qtf) {
279 * FF: the actual formats of the timestamp fields written by A
280 * are indicated by the Querier Timestamp Format.
282 case MPLS_PM_TSF_NULL:
283 proto_tree_add_item(pm_tree,
284 hf_mpls_pm_timestamp1_q_null, tvb,
285 offset, 8, ENC_BIG_ENDIAN);
286 break;
287 case MPLS_PM_TSF_SEQ:
288 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_q_seq, tvb,
289 offset, 8, ENC_BIG_ENDIAN);
290 break;
291 case MPLS_PM_TSF_NTP:
292 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_q_ntp, tvb,
293 offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
294 break;
295 case MPLS_PM_TSF_PTP:
297 nstime_t ts;
298 ts.secs = tvb_get_ntohl(tvb, offset);
299 ts.nsecs = tvb_get_ntohl(tvb, offset + 4);
300 proto_tree_add_time(pm_tree, hf_mpls_pm_timestamp1_q_ptp,
301 tvb, offset, 8, &ts);
303 break;
304 default:
305 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_unk, tvb,
306 offset, 8, ENC_BIG_ENDIAN);
307 break;
309 break;
310 case 2:
311 proto_tree_add_item(pm_tree,
312 hf_mpls_pm_timestamp2_null, tvb,
313 offset, 8, ENC_BIG_ENDIAN);
314 break;
315 case 3:
316 proto_tree_add_item(pm_tree,
317 hf_mpls_pm_timestamp3_null, tvb,
318 offset, 8, ENC_BIG_ENDIAN);
319 break;
320 case 4:
321 proto_tree_add_item(pm_tree,
322 hf_mpls_pm_timestamp4_null, tvb,
323 offset, 8, ENC_BIG_ENDIAN);
324 break;
325 default:
326 /* never here */
327 break;
328 } /* end of switch (i) */
329 } else {
331 * FF: when B transmits the response, Timestamp 1 is set to T3,
332 * Timestamp 3 is set to T1 and Timestamp 4 is set to T2. Timestamp 2
333 * is set to 0.
335 switch (i) {
336 case 1:
337 switch (rtf) {
339 * FF: the actual formats of the timestamp fields written by B
340 * are indicated by the Responder Timestamp Format.
342 case MPLS_PM_TSF_NULL:
343 proto_tree_add_item(pm_tree,
344 hf_mpls_pm_timestamp1_r_null, tvb,
345 offset, 8, ENC_BIG_ENDIAN);
346 break;
347 case MPLS_PM_TSF_SEQ:
348 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_r_seq, tvb,
349 offset, 8, ENC_BIG_ENDIAN);
350 break;
351 case MPLS_PM_TSF_NTP:
352 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_r_ntp, tvb,
353 offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
354 break;
355 case MPLS_PM_TSF_PTP:
357 nstime_t ts;
358 ts.secs = tvb_get_ntohl(tvb, offset);
359 ts.nsecs = tvb_get_ntohl(tvb, offset + 4);
360 proto_tree_add_time(pm_tree, hf_mpls_pm_timestamp1_r_ptp,
361 tvb, offset, 8, &ts);
363 break;
364 default:
365 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_unk, tvb,
366 offset, 8, ENC_BIG_ENDIAN);
367 break;
369 break;
370 case 2:
371 proto_tree_add_item(pm_tree,
372 hf_mpls_pm_timestamp2_null, tvb,
373 offset, 8, ENC_BIG_ENDIAN);
374 break;
375 case 3:
376 switch (rtf) {
377 case MPLS_PM_TSF_NULL:
378 proto_tree_add_item(pm_tree,
379 hf_mpls_pm_timestamp3_r_null, tvb,
380 offset, 8, ENC_BIG_ENDIAN);
381 break;
382 case MPLS_PM_TSF_SEQ:
383 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp3_r_seq, tvb,
384 offset, 8, ENC_BIG_ENDIAN);
385 break;
386 case MPLS_PM_TSF_NTP:
387 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp3_r_ntp, tvb,
388 offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
389 break;
390 case MPLS_PM_TSF_PTP:
392 nstime_t ts;
393 ts.secs = tvb_get_ntohl(tvb, offset);
394 ts.nsecs = tvb_get_ntohl(tvb, offset + 4);
395 proto_tree_add_time(pm_tree, hf_mpls_pm_timestamp3_r_ptp,
396 tvb, offset, 8, &ts);
398 break;
399 default:
400 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp3_unk, tvb,
401 offset, 8, ENC_BIG_ENDIAN);
402 break;
404 break;
405 case 4:
406 switch (rtf) {
407 case MPLS_PM_TSF_NULL:
408 proto_tree_add_item(pm_tree,
409 hf_mpls_pm_timestamp4_r_null, tvb,
410 offset, 8, ENC_BIG_ENDIAN);
411 break;
412 case MPLS_PM_TSF_SEQ:
413 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp4_r_seq, tvb,
414 offset, 8, ENC_BIG_ENDIAN);
415 break;
416 case MPLS_PM_TSF_NTP:
417 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp4_r_ntp, tvb,
418 offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
419 break;
420 case MPLS_PM_TSF_PTP:
422 nstime_t ts;
423 ts.secs = tvb_get_ntohl(tvb, offset);
424 ts.nsecs = tvb_get_ntohl(tvb, offset + 4);
425 proto_tree_add_time(pm_tree, hf_mpls_pm_timestamp4_r_ptp,
426 tvb, offset, 8, &ts);
428 break;
429 default:
430 proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp4_unk, tvb,
431 offset, 8, ENC_BIG_ENDIAN);
432 break;
434 break;
435 default:
436 /* never here */
437 break;
438 } /* end of switch (i) */
442 static void
443 mpls_pm_build_cinfo(tvbuff_t *tvb, packet_info *pinfo, const char *str_pmt,
444 gboolean *query, gboolean *response,
445 gboolean *class_specific,
446 guint32 *sid, guint8 *code)
448 col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "MPLS PM (%s)", str_pmt);
449 col_clear(pinfo->cinfo, COL_INFO);
451 *response = (tvb_get_guint8(tvb, 0) & 0x08) ? TRUE : FALSE;
452 *class_specific = (tvb_get_guint8(tvb, 0) & 0x04) ? TRUE : FALSE;
453 *query = !(*response);
454 *code = tvb_get_guint8(tvb, 1);
456 if (!(*class_specific)) {
458 * FF: when the T flag is set to 0 the DS field can be considered
459 * part of the Session Identifier.
461 *sid = tvb_get_ntohl(tvb, 8);
462 } else {
463 *sid = tvb_get_ntohl(tvb, 8) >> 6;
466 if (*query) {
467 col_add_fstr(pinfo->cinfo, COL_INFO,
468 "Query, sid: %u", *sid);
469 } else {
470 col_add_fstr(pinfo->cinfo, COL_INFO,
471 "Response, sid: %u, code: %s (%u)",
472 *sid,
473 rval_to_str(*code,
474 mpls_pm_response_ctrl_code_rvals,
475 "Unknown"),
476 *code);
480 /* FF: the message formats for direct and inferred LM are identical */
481 static void
482 dissect_mpls_pm_loss(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
483 guint8 pmt)
485 proto_item *ti = NULL;
486 proto_tree *pm_tree;
487 proto_tree *pm_tree_flags;
488 proto_tree *pm_tree_dflags;
489 guint32 offset = 0;
490 gboolean query = 0;
491 gboolean response = 0;
492 gboolean class_specific = 0;
493 guint32 sid = 0;
494 guint8 code = 0;
495 guint8 otf;
496 gboolean bflag;
497 guint8 i;
499 mpls_pm_build_cinfo(tvb, pinfo,
500 val_to_str_const(pmt, pmt_vals, ""),
501 &query, &response, &class_specific, &sid, &code);
503 if (!tree) {
504 return;
507 /* create display subtree for the protocol */
508 if (pmt == DLM) {
509 ti = proto_tree_add_item(tree, proto_mpls_pm_dlm, tvb, 0, -1, ENC_NA);
510 } else {
511 ti = proto_tree_add_item(tree, proto_mpls_pm_ilm, tvb, 0, -1, ENC_NA);
514 pm_tree = proto_item_add_subtree(ti, ett_mpls_pm);
516 /* add version to the subtree */
517 proto_tree_add_item(pm_tree, hf_mpls_pm_version, tvb, offset, 1, ENC_NA);
519 /* ctrl flags subtree */
521 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_flags, tvb,
522 offset, 1, ENC_NA);
523 pm_tree_flags = proto_item_add_subtree(ti, ett_mpls_pm_flags);
524 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_r, tvb,
525 offset, 1, ENC_NA);
526 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_t, tvb,
527 offset, 1, ENC_NA);
528 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_res, tvb,
529 offset, 1, ENC_NA);
530 offset += 1;
532 if (query) {
533 proto_tree_add_item(pm_tree, hf_mpls_pm_query_ctrl_code,
534 tvb, offset, 1, ENC_NA);
535 } else {
536 proto_tree_add_item(pm_tree, hf_mpls_pm_response_ctrl_code,
537 tvb, offset, 1, ENC_NA);
539 offset += 1;
541 proto_tree_add_item(pm_tree, hf_mpls_pm_length, tvb,
542 offset, 2, ENC_BIG_ENDIAN);
543 offset += 2;
545 /* data flags subtree */
546 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_dflags, tvb,
547 offset, 1, ENC_NA);
548 pm_tree_dflags = proto_item_add_subtree(ti, ett_mpls_pm_dflags);
549 proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_x, tvb,
550 offset, 1, ENC_NA);
551 bflag = (tvb_get_guint8(tvb, offset) & 0x40) ? TRUE : FALSE;
552 proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_b, tvb,
553 offset, 1, ENC_NA);
554 proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_res, tvb,
555 offset, 1, ENC_NA);
557 otf = tvb_get_guint8(tvb, offset) & 0x0F;
558 proto_tree_add_item(pm_tree, hf_mpls_pm_otf, tvb,
559 offset, 1, ENC_BIG_ENDIAN);
560 offset += 1;
562 /* skip 3 reserved bytes */
563 offset += 3;
565 proto_tree_add_uint(pm_tree, hf_mpls_pm_session_id, tvb, offset, 4, sid);
567 if (class_specific) {
568 proto_tree_add_item(pm_tree, hf_mpls_pm_ds, tvb, offset + 3, 1, ENC_NA);
570 offset += 4;
572 switch (otf) {
573 case MPLS_PM_TSF_NULL:
574 proto_tree_add_item(pm_tree, hf_mpls_pm_origin_timestamp_null, tvb,
575 offset, 8, ENC_BIG_ENDIAN);
576 break;
577 case MPLS_PM_TSF_SEQ:
578 proto_tree_add_item(pm_tree, hf_mpls_pm_origin_timestamp_seq, tvb,
579 offset, 8, ENC_BIG_ENDIAN);
580 break;
581 case MPLS_PM_TSF_NTP:
582 proto_tree_add_item(pm_tree, hf_mpls_pm_origin_timestamp_ntp, tvb,
583 offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
584 break;
585 case MPLS_PM_TSF_PTP:
587 nstime_t ts;
588 ts.secs = tvb_get_ntohl(tvb, offset);
589 ts.nsecs = tvb_get_ntohl(tvb, offset + 4);
590 proto_tree_add_time(pm_tree, hf_mpls_pm_origin_timestamp_ptp, tvb,
591 offset, 8, &ts);
593 break;
594 default:
595 proto_tree_add_item(pm_tree, hf_mpls_pm_origin_timestamp_unk, tvb,
596 offset, 8, ENC_BIG_ENDIAN);
597 break;
599 offset += 8;
601 /* counters 1..4 */
602 for (i = 1; i <= 4; i++) {
603 mpls_pm_dissect_counter(tvb, pm_tree, offset, query, bflag, i);
604 offset += 8;
608 static void
609 dissect_mpls_pm_dlm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
611 /* the message formats for direct and inferred LM are identical */
612 dissect_mpls_pm_loss(tvb, pinfo, tree, DLM);
615 static void
616 dissect_mpls_pm_ilm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
618 /* the message formats for direct and inferred LM are identical */
619 dissect_mpls_pm_loss(tvb, pinfo, tree, ILM);
622 static void
623 dissect_mpls_pm_delay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
625 proto_item *ti;
626 proto_tree *pm_tree;
627 proto_tree *pm_tree_flags;
628 guint32 offset = 0;
629 gboolean query = 0;
630 gboolean response = 0;
631 gboolean class_specific = 0;
632 guint32 sid = 0;
633 guint8 code = 0;
634 guint8 qtf;
635 guint8 rtf;
636 guint8 i;
638 mpls_pm_build_cinfo(tvb, pinfo,
639 "DM",
640 &query, &response, &class_specific, &sid, &code);
642 if (!tree) {
643 return;
646 /* create display subtree for the protocol */
647 ti = proto_tree_add_item(tree, proto_mpls_pm_dm, tvb, 0, -1, ENC_NA);
648 pm_tree = proto_item_add_subtree(ti, ett_mpls_pm);
650 /* add version to the subtree */
651 proto_tree_add_item(pm_tree, hf_mpls_pm_version, tvb, offset, 1, ENC_NA);
653 /* ctrl flags subtree */
654 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_flags, tvb, offset, 1, ENC_NA);
655 pm_tree_flags = proto_item_add_subtree(ti, ett_mpls_pm_flags);
656 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_r, tvb,
657 offset, 1, ENC_NA);
658 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_t, tvb,
659 offset, 1, ENC_NA);
660 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_res, tvb,
661 offset, 1, ENC_NA);
662 offset += 1;
664 if (query) {
665 proto_tree_add_item(pm_tree, hf_mpls_pm_query_ctrl_code,
666 tvb, offset, 1, ENC_NA);
667 } else {
668 proto_tree_add_item(pm_tree, hf_mpls_pm_response_ctrl_code,
669 tvb, offset, 1, ENC_NA);
671 offset += 1;
673 proto_tree_add_item(pm_tree, hf_mpls_pm_length, tvb,
674 offset, 2, ENC_BIG_ENDIAN);
675 offset += 2;
677 /* qtf, rtf */
678 qtf = (tvb_get_guint8(tvb, offset) & 0xF0) >> 4;
679 proto_tree_add_item(pm_tree, hf_mpls_pm_qtf, tvb,
680 offset, 1, ENC_BIG_ENDIAN);
682 rtf = tvb_get_guint8(tvb, offset) & 0x0F;
683 proto_tree_add_item(pm_tree, hf_mpls_pm_rtf, tvb,
684 offset, 1, ENC_BIG_ENDIAN);
685 offset += 1;
687 /* rptf */
688 proto_tree_add_item(pm_tree, hf_mpls_pm_rptf, tvb,
689 offset, 1, ENC_BIG_ENDIAN);
691 /* skip 20 reserved bits */
692 offset += 3;
694 proto_tree_add_uint(pm_tree, hf_mpls_pm_session_id, tvb, offset, 4, sid);
696 if (class_specific) {
697 proto_tree_add_item(pm_tree, hf_mpls_pm_ds, tvb, offset + 3, 1, ENC_NA);
699 offset += 4;
701 /* timestamps 1..4 */
702 for (i = 1; i <= 4; i++) {
703 mpls_pm_dissect_timestamp(tvb, pm_tree, offset, qtf, rtf, query, i);
704 offset += 8;
708 static void
709 dissect_mpls_pm_combined(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
710 guint8 pmt)
712 proto_item *ti = NULL;
713 proto_tree *pm_tree;
714 proto_tree *pm_tree_flags;
715 proto_tree *pm_tree_dflags;
716 guint32 offset = 0;
717 gboolean query = 0;
718 gboolean response = 0;
719 gboolean class_specific = 0;
720 guint32 sid = 0;
721 guint8 code = 0;
722 guint8 qtf;
723 guint8 rtf;
724 gboolean bflag;
725 guint8 i;
727 mpls_pm_build_cinfo(tvb, pinfo,
728 val_to_str_const(pmt, pmt_vals, ""),
729 &query, &response, &class_specific, &sid, &code);
731 if (!tree) {
732 return;
735 /* create display subtree for the protocol */
736 if (pmt == DLMDM) {
737 ti = proto_tree_add_item(tree, proto_mpls_pm_dlm_dm,
738 tvb, 0, -1, ENC_NA);
739 } else {
740 ti = proto_tree_add_item(tree, proto_mpls_pm_ilm_dm,
741 tvb, 0, -1, ENC_NA);
744 pm_tree = proto_item_add_subtree(ti, ett_mpls_pm);
746 /* add version to the subtree */
747 proto_tree_add_item(pm_tree, hf_mpls_pm_version, tvb, offset, 1, ENC_NA);
749 /* ctrl flags subtree */
750 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_flags, tvb, offset, 1, ENC_NA);
751 pm_tree_flags = proto_item_add_subtree(ti, ett_mpls_pm_flags);
752 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_r, tvb,
753 offset, 1, ENC_NA);
754 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_t, tvb,
755 offset, 1, ENC_NA);
756 proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_res, tvb,
757 offset, 1, ENC_NA);
758 offset += 1;
760 if (query) {
761 proto_tree_add_item(pm_tree, hf_mpls_pm_query_ctrl_code,
762 tvb, offset, 1, ENC_NA);
763 } else {
764 proto_tree_add_item(pm_tree, hf_mpls_pm_response_ctrl_code,
765 tvb, offset, 1, ENC_NA);
767 offset += 1;
769 proto_tree_add_item(pm_tree, hf_mpls_pm_length, tvb,
770 offset, 2, ENC_BIG_ENDIAN);
771 offset += 2;
773 /* data flags subtree */
774 ti = proto_tree_add_item(pm_tree, hf_mpls_pm_dflags, tvb,
775 offset, 1, ENC_NA);
776 pm_tree_dflags = proto_item_add_subtree(ti, ett_mpls_pm_dflags);
777 proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_x, tvb,
778 offset, 1, ENC_NA);
779 bflag = (tvb_get_guint8(tvb, offset) & 0x40) ? TRUE : FALSE;
780 proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_b, tvb,
781 offset, 1, ENC_NA);
782 proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_res, tvb,
783 offset, 1, ENC_NA);
786 * FF: the roles of the OTF and Origin Timestamp fields for LM are
787 * here played by the QTF and Timestamp 1 fields, respectively.
789 qtf = tvb_get_guint8(tvb, offset) & 0x0F;
790 proto_tree_add_item(pm_tree, hf_mpls_pm_qtf_combined, tvb,
791 offset, 1, ENC_BIG_ENDIAN);
792 offset += 1;
794 /* rtf, rptf */
795 rtf = tvb_get_guint8(tvb, offset) & 0xF0 >> 4;
796 proto_tree_add_item(pm_tree, hf_mpls_pm_rtf_combined, tvb,
797 offset, 1, ENC_BIG_ENDIAN);
799 proto_tree_add_item(pm_tree, hf_mpls_pm_rptf_combined, tvb,
800 offset, 1, ENC_BIG_ENDIAN);
801 offset += 1;
803 /* skip 2 reserved bytes */
804 offset += 2;
806 proto_tree_add_uint(pm_tree, hf_mpls_pm_session_id, tvb, offset, 4, sid);
808 if (class_specific) {
809 proto_tree_add_item(pm_tree, hf_mpls_pm_ds, tvb, offset + 3, 1, ENC_NA);
811 offset += 4;
813 /* timestamps 1..4 */
814 for (i = 1; i <= 4; i++) {
815 mpls_pm_dissect_timestamp(tvb, pm_tree, offset, qtf, rtf, query, i);
816 offset += 8;
819 /* counters 1..4 */
820 for (i = 1; i <= 4; i++) {
821 mpls_pm_dissect_counter(tvb, pm_tree, offset, query, bflag, i);
822 offset += 8;
826 static void
827 dissect_mpls_pm_dlm_dm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
829 /* the formats of the DLM+DM and ILM+DM messages are also identical */
830 dissect_mpls_pm_combined(tvb, pinfo, tree, DLMDM);
833 static void
834 dissect_mpls_pm_ilm_dm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
836 /* the formats of the DLM+DM and ILM+DM messages are also identical */
837 dissect_mpls_pm_combined(tvb, pinfo, tree, ILMDM);
840 void
841 proto_register_mpls_pm(void)
843 static hf_register_info hf[] = {
845 &hf_mpls_pm_version,
847 "Version", "mpls_pm.version", FT_UINT8, BASE_DEC, NULL,
848 0xF0, NULL, HFILL
852 &hf_mpls_pm_flags,
854 "Flags", "mpls_pm.flags", FT_UINT8,
855 BASE_HEX, NULL, MPLS_PM_FLAGS_MASK, NULL, HFILL
859 &hf_mpls_pm_flags_r,
861 "Response indicator (R)", "mpls_pm.flags.r",
862 FT_BOOLEAN, 4, TFS(&tfs_set_notset), MPLS_PM_FLAGS_R,
863 NULL, HFILL
867 &hf_mpls_pm_flags_t,
869 "Traffic-class-specific measurement indicator (T)",
870 "mpls_pm.flags.t",
871 FT_BOOLEAN, 4, TFS(&tfs_set_notset), MPLS_PM_FLAGS_T,
872 NULL, HFILL
876 &hf_mpls_pm_flags_res,
878 "Reserved",
879 "mpls_pm.flags.res",
880 FT_BOOLEAN, 4, TFS(&tfs_set_notset), MPLS_PM_FLAGS_RES,
881 NULL, HFILL
885 &hf_mpls_pm_query_ctrl_code,
887 "Control Code",
888 "mpls_pm.ctrl.code",
889 FT_UINT8, BASE_RANGE_STRING | BASE_HEX,
890 RVALS(mpls_pm_query_ctrl_code_rvals), 0x0,
891 "Code identifying the query type", HFILL
895 &hf_mpls_pm_response_ctrl_code,
897 "Control Code",
898 "mpls_pm.ctrl.code",
899 FT_UINT8, BASE_RANGE_STRING | BASE_HEX,
900 RVALS(mpls_pm_response_ctrl_code_rvals), 0x0,
901 "Code identifying the response type", HFILL
905 &hf_mpls_pm_length,
907 "Message Length",
908 "mpls_pm.length",
909 FT_UINT16, BASE_DEC, NULL, 0x0,
910 "Total length of this message in bytes", HFILL
914 &hf_mpls_pm_dflags,
916 "DFlags", "mpls_pm.dflags", FT_UINT8,
917 BASE_HEX, NULL, MPLS_PM_DFLAGS_MASK,
918 NULL, HFILL
922 &hf_mpls_pm_dflags_x,
924 "Extended counter format indicator (X)", "mpls_pm.dflags.x",
925 FT_BOOLEAN, 4, TFS(&tfs_set_notset), MPLS_PM_DFLAGS_X,
926 NULL, HFILL
930 &hf_mpls_pm_dflags_b,
932 "Octet/Byte count indicator (B)", "mpls_pm.dflags.b",
933 FT_BOOLEAN, 4, TFS(&tfs_set_notset), MPLS_PM_DFLAGS_B,
934 NULL, HFILL
938 &hf_mpls_pm_dflags_res,
940 "Reserved",
941 "mpls_pm.dflags.res",
942 FT_BOOLEAN, 4, NULL, MPLS_PM_DFLAGS_RES,
943 NULL, HFILL
947 &hf_mpls_pm_otf,
949 "Origin Timestamp Format (OTF)",
950 "mpls_pm.otf",
951 FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
952 RVALS(mpls_pm_time_stamp_format_rvals), 0x0F,
953 NULL, HFILL
957 &hf_mpls_pm_session_id,
959 "Session Identifier",
960 "mpls_pm.session.id",
961 FT_UINT32, BASE_DEC,
962 NULL, 0x0,
963 NULL, HFILL
967 &hf_mpls_pm_ds,
969 "Differentiated Services Codepoint",
970 "mpls_pm.ds",
971 FT_UINT8, BASE_DEC | BASE_EXT_STRING,
972 &dscp_vals_ext, 0x3F,
973 NULL, HFILL
977 &hf_mpls_pm_origin_timestamp_null,
979 "Origin Timestamp",
980 "mpls_pm.origin.timestamp.null",
981 FT_UINT64, BASE_DEC,
982 NULL, 0x0,
983 NULL, HFILL
987 &hf_mpls_pm_origin_timestamp_seq,
989 "Origin Timestamp",
990 "mpls_pm.origin.timestamp.seq",
991 FT_UINT64, BASE_DEC,
992 NULL, 0x0,
993 NULL, HFILL
997 &hf_mpls_pm_origin_timestamp_ntp,
999 "Origin Timestamp",
1000 "mpls_pm.origin.timestamp.ntp",
1001 FT_RELATIVE_TIME, BASE_NONE,
1002 NULL, 0x0,
1003 NULL, HFILL
1007 &hf_mpls_pm_origin_timestamp_ptp,
1009 "Origin Timestamp",
1010 "mpls_pm.origin.timestamp.ptp",
1011 FT_RELATIVE_TIME, BASE_NONE,
1012 NULL, 0x0,
1013 NULL, HFILL
1017 &hf_mpls_pm_origin_timestamp_unk,
1019 "Origin Timestamp (Unknown Type)",
1020 "mpls_pm.origin.timestamp.unk",
1021 FT_UINT64, BASE_DEC,
1022 NULL, 0x0,
1023 NULL, HFILL
1027 &hf_mpls_pm_counter1,
1029 "Counter 1",
1030 "mpls_pm.counter1",
1031 FT_UINT64, BASE_DEC,
1032 NULL, 0x0,
1033 NULL, HFILL
1037 &hf_mpls_pm_counter2,
1039 "Counter 2",
1040 "mpls_pm.counter2",
1041 FT_UINT64, BASE_DEC,
1042 NULL, 0x0,
1043 NULL, HFILL
1047 &hf_mpls_pm_counter3,
1049 "Counter 3",
1050 "mpls_pm.counter3",
1051 FT_UINT64, BASE_DEC,
1052 NULL, 0x0,
1053 NULL, HFILL
1057 &hf_mpls_pm_counter4,
1059 "Counter 4",
1060 "mpls_pm.counter4",
1061 FT_UINT64, BASE_DEC,
1062 NULL, 0x0,
1063 NULL, HFILL
1067 &hf_mpls_pm_qtf,
1069 "Querier timestamp format (QTF)",
1070 "mpls_pm.qtf",
1071 FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1072 RVALS(mpls_pm_time_stamp_format_rvals), 0xF0,
1073 NULL, HFILL
1077 &hf_mpls_pm_qtf_combined,
1079 "Querier timestamp format (QTF)",
1080 "mpls_pm.qtf",
1081 FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1082 RVALS(mpls_pm_time_stamp_format_rvals), 0x0F,
1083 NULL, HFILL
1087 &hf_mpls_pm_rtf,
1089 "Responder timestamp format (RTF)",
1090 "mpls_pm.rtf",
1091 FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1092 RVALS(mpls_pm_time_stamp_format_rvals), 0x0F,
1093 NULL, HFILL
1097 &hf_mpls_pm_rtf_combined,
1099 "Responder timestamp format (RTF)",
1100 "mpls_pm.rtf",
1101 FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1102 RVALS(mpls_pm_time_stamp_format_rvals), 0xF0,
1103 NULL, HFILL
1107 &hf_mpls_pm_rptf,
1109 "Responder's preferred timestamp format (RPTF)",
1110 "mpls_pm.rptf",
1111 FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1112 RVALS(mpls_pm_time_stamp_format_rvals), 0xF0,
1113 NULL, HFILL
1117 &hf_mpls_pm_rptf_combined,
1119 "Responder's preferred timestamp format (RPTF)",
1120 "mpls_pm.rptf",
1121 FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1122 RVALS(mpls_pm_time_stamp_format_rvals), 0x0F,
1123 NULL, HFILL
1127 &hf_mpls_pm_timestamp1_q_null,
1129 "Timestamp 1 (T1)",
1130 "mpls_pm.timestamp1.null",
1131 FT_UINT64, BASE_DEC,
1132 NULL, 0x0,
1133 NULL, HFILL
1137 &hf_mpls_pm_timestamp1_r_null,
1139 "Timestamp 1 (T3)",
1140 "mpls_pm.timestamp1.null",
1141 FT_UINT64, BASE_DEC,
1142 NULL, 0x0,
1143 NULL, HFILL
1147 &hf_mpls_pm_timestamp1_q_seq,
1149 "Timestamp 1 (T1)",
1150 "mpls_pm.timestamp1.seq",
1151 FT_UINT64, BASE_DEC,
1152 NULL, 0x0,
1153 NULL, HFILL
1157 &hf_mpls_pm_timestamp1_r_seq,
1159 "Timestamp 1 (T3)",
1160 "mpls_pm.timestamp1.seq",
1161 FT_UINT64, BASE_DEC,
1162 NULL, 0x0,
1163 NULL, HFILL
1167 &hf_mpls_pm_timestamp1_q_ntp,
1169 "Timestamp 1 (T1)",
1170 "mpls_pm.timestamp1.ntp",
1171 FT_RELATIVE_TIME, BASE_NONE,
1172 NULL, 0x0,
1173 NULL, HFILL
1177 &hf_mpls_pm_timestamp1_r_ntp,
1179 "Timestamp 1 (T3)",
1180 "mpls_pm.timestamp1.ntp",
1181 FT_RELATIVE_TIME, BASE_NONE,
1182 NULL, 0x0,
1183 NULL, HFILL
1187 &hf_mpls_pm_timestamp1_q_ptp,
1189 "Timestamp 1 (T1)",
1190 "mpls_pm.timestamp1.ptp",
1191 FT_RELATIVE_TIME, BASE_NONE,
1192 NULL, 0x0,
1193 NULL, HFILL
1197 &hf_mpls_pm_timestamp1_r_ptp,
1199 "Timestamp 1 (T3)",
1200 "mpls_pm.timestamp1.ptp",
1201 FT_RELATIVE_TIME, BASE_NONE,
1202 NULL, 0x0,
1203 NULL, HFILL
1207 &hf_mpls_pm_timestamp1_unk,
1209 "Timestamp 1 (Unknown Type)",
1210 "mpls_pm.timestamp1.unk",
1211 FT_UINT64, BASE_DEC,
1212 NULL, 0x0,
1213 NULL, HFILL
1217 &hf_mpls_pm_timestamp2_null,
1219 "Timestamp 2",
1220 "mpls_pm.timestamp2.null",
1221 FT_UINT64, BASE_DEC,
1222 NULL, 0x0,
1223 NULL, HFILL
1227 &hf_mpls_pm_timestamp3_null,
1229 "Timestamp 3",
1230 "mpls_pm.timestamp3.null",
1231 FT_UINT64, BASE_DEC,
1232 NULL, 0x0,
1233 NULL, HFILL
1237 &hf_mpls_pm_timestamp3_r_null,
1239 "Timestamp 3 (T1)",
1240 "mpls_pm.timestamp3.null",
1241 FT_UINT64, BASE_DEC,
1242 NULL, 0x0,
1243 NULL, HFILL
1247 &hf_mpls_pm_timestamp3_r_seq,
1249 "Timestamp 3 (T1)",
1250 "mpls_pm.timestamp3.seq",
1251 FT_UINT64, BASE_DEC,
1252 NULL, 0x0,
1253 NULL, HFILL
1257 &hf_mpls_pm_timestamp3_r_ntp,
1259 "Timestamp 3 (T1)",
1260 "mpls_pm.timestamp3.ntp",
1261 FT_RELATIVE_TIME, BASE_NONE,
1262 NULL, 0x0,
1263 NULL, HFILL
1267 &hf_mpls_pm_timestamp3_r_ptp,
1269 "Timestamp 3 (T1)",
1270 "mpls_pm.timestamp3_ptp",
1271 FT_RELATIVE_TIME, BASE_NONE,
1272 NULL, 0x0,
1273 NULL, HFILL
1277 &hf_mpls_pm_timestamp3_unk,
1279 "Timestamp 3 (Unknown Type)",
1280 "mpls_pm.timestamp3.unk",
1281 FT_UINT64, BASE_DEC,
1282 NULL, 0x0,
1283 NULL, HFILL
1287 &hf_mpls_pm_timestamp4_null,
1289 "Timestamp 4",
1290 "mpls_pm.timestamp4.null",
1291 FT_UINT64, BASE_DEC,
1292 NULL, 0x0,
1293 NULL, HFILL
1297 &hf_mpls_pm_timestamp4_r_null,
1299 "Timestamp 4 (T2)",
1300 "mpls_pm.timestamp4.null",
1301 FT_UINT64, BASE_DEC,
1302 NULL, 0x0,
1303 NULL, HFILL
1307 &hf_mpls_pm_timestamp4_r_seq,
1309 "Timestamp 4 (T2)",
1310 "mpls_pm.timestamp4.seq",
1311 FT_UINT64, BASE_DEC,
1312 NULL, 0x0,
1313 NULL, HFILL
1317 &hf_mpls_pm_timestamp4_r_ntp,
1319 "Timestamp 4 (T2)",
1320 "mpls_pm.timestamp4.ntp",
1321 FT_RELATIVE_TIME, BASE_NONE,
1322 NULL, 0x0,
1323 NULL, HFILL
1327 &hf_mpls_pm_timestamp4_r_ptp,
1329 "Timestamp 4 (T2)",
1330 "mpls_pm.timestamp4.ptp",
1331 FT_RELATIVE_TIME, BASE_NONE,
1332 NULL, 0x0,
1333 NULL, HFILL
1337 &hf_mpls_pm_timestamp4_unk,
1339 "Timestamp 4 (Unknown Type)",
1340 "mpls_pm.timestamp4.unk",
1341 FT_UINT64, BASE_DEC,
1342 NULL, 0x0,
1343 NULL, HFILL
1348 static gint *ett[] = {
1349 &ett_mpls_pm,
1350 &ett_mpls_pm_flags,
1351 &ett_mpls_pm_dflags
1354 proto_mpls_pm_dlm =
1355 proto_register_protocol("MPLS Direct Loss Measurement (DLM)",
1356 "MPLS Direct Loss Measurement (DLM)",
1357 "mplspmdlm");
1359 proto_mpls_pm_ilm =
1360 proto_register_protocol("MPLS Inferred Loss Measurement (ILM)",
1361 "MPLS Inferred Loss Measurement (ILM)",
1362 "mplspmilm");
1364 proto_mpls_pm_dm =
1365 proto_register_protocol("MPLS Delay Measurement (DM)",
1366 "MPLS Delay Measurement (DM)",
1367 "mplspmdm");
1369 proto_mpls_pm_dlm_dm =
1370 proto_register_protocol("MPLS Direct Loss and Delay "
1371 "Measurement (DLM+DM)",
1372 "MPLS Direct Loss and Delay "
1373 "Measurement (DLM+DM)",
1374 "mplspmdlmdm");
1376 proto_mpls_pm_ilm_dm =
1377 proto_register_protocol("MPLS Inferred Loss and Delay "
1378 "Measurement (ILM+DM)",
1379 "MPLS Inferred Loss and Delay "
1380 "Measurement (ILM+DM)",
1381 "mplspmilmdm");
1383 proto_register_field_array(proto_mpls_pm_dlm, hf, array_length(hf));
1384 proto_register_subtree_array(ett, array_length(ett));
1386 register_dissector("mpls_pm_dlm", dissect_mpls_pm_dlm,
1387 proto_mpls_pm_dlm);
1389 register_dissector("mpls_pm_ilm", dissect_mpls_pm_ilm,
1390 proto_mpls_pm_ilm);
1392 register_dissector("mpls_pm_dm", dissect_mpls_pm_delay,
1393 proto_mpls_pm_dm);
1395 register_dissector("mpls_pm_dlm_dm", dissect_mpls_pm_dlm_dm,
1396 proto_mpls_pm_dlm_dm);
1398 register_dissector("mpls_pm_ilm_dm", dissect_mpls_pm_ilm_dm,
1399 proto_mpls_pm_ilm_dm);
1402 void
1403 proto_reg_handoff_mpls_pm(void)
1405 mpls_pm_dlm_handle = find_dissector("mpls_pm_dlm");
1406 mpls_pm_ilm_handle = find_dissector("mpls_pm_ilm");
1407 mpls_pm_dm_handle = find_dissector("mpls_pm_dm");
1408 mpls_pm_dlm_dm_handle = find_dissector("mpls_pm_dlm_dm");
1409 mpls_pm_ilm_dm_handle = find_dissector("mpls_pm_ilm_dm");
1413 * Editor modelines - http://www.wireshark.org/tools/modelines.html
1415 * Local variables:
1416 * c-basic-offset: 4
1417 * tab-width: 8
1418 * indent-tabs-mode: nil
1419 * End:
1421 * vi: set shiftwidth=4 tabstop=8 expandtab:
1422 * :indentSize=4:tabSize=8:noTabs=true: