Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-mpls-pm.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-mpls-pm.c
2
 *
3
 * Routines for MPLS delay and loss measurement: it should conform
4
 * to RFC 6374.  'PM' stands for Performance Measurement.
5
 *
6
 * Copyright 2012 _FF_
7
 *
8
 * Francesco Fondelli <francesco dot fondelli, gmail dot com>
9
 *
10
 * Wireshark - Network traffic analyzer
11
 * By Gerald Combs <gerald@wireshark.org>
12
 * Copyright 1998 Gerald Combs
13
 *
14
 * SPDX-License-Identifier: GPL-2.0-or-later
15
 */
16
17
#include "config.h"
18
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"
24
25
void proto_register_mpls_pm(void);
26
void proto_reg_handoff_mpls_pm(void);
27
28
/* message control flags */
29
14
#define MPLS_PM_FLAGS_R     0x08
30
14
#define MPLS_PM_FLAGS_T     0x04
31
14
#define MPLS_PM_FLAGS_RES   0x03
32
14
#define MPLS_PM_FLAGS_MASK  0x0F
33
34
/* data format flags */
35
14
#define MPLS_PM_DFLAGS_X    0x80
36
14
#define MPLS_PM_DFLAGS_B    0x40
37
14
#define MPLS_PM_DFLAGS_RES  0x30
38
14
#define MPLS_PM_DFLAGS_MASK 0xF0
39
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;
45
46
static int ett_mpls_pm;
47
static int ett_mpls_pm_flags;
48
static int ett_mpls_pm_dflags;
49
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;
110
111
/*
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'
115
 */
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                             }
122
};
123
124
/*
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'
128
 */
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                                  }
153
};
154
155
0
#define DLM 1
156
0
#define ILM 2
157
#define DM 3
158
0
#define DLMDM 4
159
0
#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     }
168
};
169
170
/*
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'
174
 */
175
0
#define MPLS_PM_TSF_NULL 0
176
0
#define MPLS_PM_TSF_SEQ 1
177
0
#define MPLS_PM_TSF_NTP 2
178
0
#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                                        }
190
};
191
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)
196
0
{
197
0
    proto_item *ti;
198
    /*
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
202
     */
203
0
    const char *unit = bflag ? "octets" : "packets";
204
205
0
    if (query) {
206
0
        switch (i) {
207
0
        case 1:
208
0
            ti = proto_tree_add_item(pm_tree, hf_mpls_pm_counter1, tvb,
209
0
                                     offset, 8, ENC_BIG_ENDIAN);
210
0
            proto_item_append_text(ti, " %s (A_Tx)", unit);
211
0
            break;
212
0
        case 2:
213
0
            proto_tree_add_item(pm_tree, hf_mpls_pm_counter2, tvb,
214
0
                                offset, 8, ENC_BIG_ENDIAN);
215
0
            break;
216
0
        case 3:
217
0
            proto_tree_add_item(pm_tree, hf_mpls_pm_counter3, tvb,
218
0
                                offset, 8, ENC_BIG_ENDIAN);
219
0
            break;
220
0
        case 4:
221
0
            proto_tree_add_item(pm_tree, hf_mpls_pm_counter4, tvb,
222
0
                                offset, 8, ENC_BIG_ENDIAN);
223
0
            break;
224
0
        default:
225
            /* never here */
226
0
            break;
227
0
        }
228
0
    } else {
229
        /* response */
230
0
        switch (i) {
231
0
        case 1:
232
0
            ti = proto_tree_add_item(pm_tree, hf_mpls_pm_counter1, tvb,
233
0
                                     offset, 8, ENC_BIG_ENDIAN);
234
0
            proto_item_append_text(ti, " %s (B_Tx)", unit);
235
0
            break;
236
0
        case 2:
237
0
            proto_tree_add_item(pm_tree, hf_mpls_pm_counter2, tvb,
238
0
                                offset, 8, ENC_BIG_ENDIAN);
239
0
            break;
240
0
        case 3:
241
0
            ti = proto_tree_add_item(pm_tree, hf_mpls_pm_counter3, tvb,
242
0
                                         offset, 8, ENC_BIG_ENDIAN);
243
0
            proto_item_append_text(ti, " %s (A_Tx)", unit);
244
0
            break;
245
0
        case 4:
246
0
            ti = proto_tree_add_item(pm_tree, hf_mpls_pm_counter4, tvb,
247
0
                                         offset, 8, ENC_BIG_ENDIAN);
248
0
            proto_item_append_text(ti, " %s (B_Rx)", unit);
249
0
            break;
250
0
        default:
251
            /* never here */
252
0
            break;
253
0
        }
254
0
    }
255
0
}
256
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)
261
0
{
262
0
    if (query) {
263
        /*
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.
268
         */
269
0
        switch (i) {
270
0
        case 1:
271
0
            switch (qtf) {
272
                /*
273
                 * FF: the actual formats of the timestamp fields written by A
274
                 * are indicated by the Querier Timestamp Format.
275
                 */
276
0
            case MPLS_PM_TSF_NULL:
277
0
                proto_tree_add_item(pm_tree,
278
0
                                    hf_mpls_pm_timestamp1_q_null, tvb,
279
0
                                    offset, 8, ENC_BIG_ENDIAN);
280
0
                break;
281
0
            case MPLS_PM_TSF_SEQ:
282
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_q_seq, tvb,
283
0
                                    offset, 8, ENC_BIG_ENDIAN);
284
0
                break;
285
0
            case MPLS_PM_TSF_NTP:
286
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_q_ntp, tvb,
287
0
                                    offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
288
0
                break;
289
0
            case MPLS_PM_TSF_PTP:
290
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_q_ptp, tvb,
291
0
                                    offset, 8, ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN);
292
0
                break;
293
0
            default:
294
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_unk, tvb,
295
0
                                    offset, 8, ENC_BIG_ENDIAN);
296
0
                break;
297
0
            }
298
0
            break;
299
0
        case 2:
300
0
            switch (qtf) {
301
0
            case MPLS_PM_TSF_NULL:
302
0
                proto_tree_add_item(pm_tree,
303
0
                                    hf_mpls_pm_timestamp2_q_null, tvb,
304
0
                                    offset, 8, ENC_BIG_ENDIAN);
305
0
                break;
306
0
            case MPLS_PM_TSF_SEQ:
307
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp2_q_seq, tvb,
308
0
                                    offset, 8, ENC_BIG_ENDIAN);
309
0
                break;
310
0
            case MPLS_PM_TSF_NTP:
311
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp2_q_ntp, tvb,
312
0
                                    offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
313
0
                break;
314
0
            case MPLS_PM_TSF_PTP:
315
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp2_q_ptp, tvb,
316
0
                                    offset, 8, ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN);
317
0
                break;
318
0
            default:
319
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp2_unk, tvb,
320
0
                                    offset, 8, ENC_BIG_ENDIAN);
321
0
                break;
322
0
            }
323
0
            break;
324
0
        case 3:
325
0
            proto_tree_add_item(pm_tree,
326
0
                                hf_mpls_pm_timestamp3_null, tvb,
327
0
                                offset, 8, ENC_BIG_ENDIAN);
328
0
            break;
329
0
        case 4:
330
0
            proto_tree_add_item(pm_tree,
331
0
                                hf_mpls_pm_timestamp4_null, tvb,
332
0
                                offset, 8, ENC_BIG_ENDIAN);
333
0
            break;
334
0
        default:
335
            /* never here */
336
0
            break;
337
0
        } /* end of switch (i) */
338
0
    } else {
339
        /*
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.
345
         */
346
0
        switch (i) {
347
0
        case 1:
348
0
            switch (rtf) {
349
                /*
350
                 * FF: the actual formats of the timestamp fields written by B
351
                 * are indicated by the Responder Timestamp Format.
352
                 */
353
0
            case MPLS_PM_TSF_NULL:
354
0
                proto_tree_add_item(pm_tree,
355
0
                                    hf_mpls_pm_timestamp1_r_null, tvb,
356
0
                                    offset, 8, ENC_BIG_ENDIAN);
357
0
                break;
358
0
            case MPLS_PM_TSF_SEQ:
359
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_r_seq, tvb,
360
0
                                    offset, 8, ENC_BIG_ENDIAN);
361
0
                break;
362
0
            case MPLS_PM_TSF_NTP:
363
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_r_ntp, tvb,
364
0
                                    offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
365
0
                break;
366
0
            case MPLS_PM_TSF_PTP:
367
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_r_ptp, tvb,
368
0
                                    offset, 8, ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN);
369
0
                break;
370
0
            default:
371
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp1_unk, tvb,
372
0
                                    offset, 8, ENC_BIG_ENDIAN);
373
0
                break;
374
0
            }
375
0
            break;
376
0
        case 2:
377
0
            switch (rtf) {
378
0
            case MPLS_PM_TSF_NULL:
379
0
                proto_tree_add_item(pm_tree,
380
0
                                    hf_mpls_pm_timestamp2_r_null, tvb,
381
0
                                    offset, 8, ENC_BIG_ENDIAN);
382
0
                break;
383
0
            case MPLS_PM_TSF_SEQ:
384
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp2_r_seq, tvb,
385
0
                                    offset, 8, ENC_BIG_ENDIAN);
386
0
                break;
387
0
            case MPLS_PM_TSF_NTP:
388
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp2_r_ntp, tvb,
389
0
                                    offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
390
0
                break;
391
0
            case MPLS_PM_TSF_PTP:
392
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp2_r_ptp, tvb,
393
0
                                    offset, 8, ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN);
394
0
                break;
395
0
            default:
396
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp2_unk, tvb,
397
0
                                    offset, 8, ENC_BIG_ENDIAN);
398
0
                break;
399
0
            }
400
0
            break;
401
0
        case 3:
402
0
            switch (rtf) {
403
0
            case MPLS_PM_TSF_NULL:
404
0
                proto_tree_add_item(pm_tree,
405
0
                                    hf_mpls_pm_timestamp3_r_null, tvb,
406
0
                                    offset, 8, ENC_BIG_ENDIAN);
407
0
                break;
408
0
            case MPLS_PM_TSF_SEQ:
409
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp3_r_seq, tvb,
410
0
                                    offset, 8, ENC_BIG_ENDIAN);
411
0
                break;
412
0
            case MPLS_PM_TSF_NTP:
413
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp3_r_ntp, tvb,
414
0
                                    offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
415
0
                break;
416
0
            case MPLS_PM_TSF_PTP:
417
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp3_r_ptp, tvb,
418
0
                                    offset, 8, ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN);
419
0
                break;
420
0
            default:
421
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp3_unk, tvb,
422
0
                                    offset, 8, ENC_BIG_ENDIAN);
423
0
                break;
424
0
            }
425
0
            break;
426
0
        case 4:
427
0
            switch (rtf) {
428
0
            case MPLS_PM_TSF_NULL:
429
0
                proto_tree_add_item(pm_tree,
430
0
                                    hf_mpls_pm_timestamp4_r_null, tvb,
431
0
                                    offset, 8, ENC_BIG_ENDIAN);
432
0
                break;
433
0
            case MPLS_PM_TSF_SEQ:
434
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp4_r_seq, tvb,
435
0
                                    offset, 8, ENC_BIG_ENDIAN);
436
0
                break;
437
0
            case MPLS_PM_TSF_NTP:
438
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp4_r_ntp, tvb,
439
0
                                    offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
440
0
                break;
441
0
            case MPLS_PM_TSF_PTP:
442
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp4_r_ptp, tvb,
443
0
                                    offset, 8, ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN);
444
0
                break;
445
0
            default:
446
0
                proto_tree_add_item(pm_tree, hf_mpls_pm_timestamp4_unk, tvb,
447
0
                                    offset, 8, ENC_BIG_ENDIAN);
448
0
                break;
449
0
            }
450
0
            break;
451
0
        default:
452
            /* never here */
453
0
            break;
454
0
        } /* end of switch (i) */
455
0
    }
456
0
}
457
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)
463
0
{
464
0
    col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "MPLS PM (%s)", str_pmt);
465
0
    col_clear(pinfo->cinfo, COL_INFO);
466
467
0
    *response = (tvb_get_uint8(tvb, 0) & 0x08) ? true : false;
468
0
    *class_specific = (tvb_get_uint8(tvb, 0) & 0x04) ? true : false;
469
0
    *query = !(*response);
470
0
    *code = tvb_get_uint8(tvb, 1);
471
472
0
    if (!(*class_specific)) {
473
        /*
474
         * FF: when the T flag is set to 0 the DS field can be considered
475
         * part of the Session Identifier.
476
         */
477
0
        *sid = tvb_get_ntohl(tvb, 8);
478
0
    } else {
479
0
        *sid = tvb_get_ntohl(tvb, 8) >> 6;
480
0
    }
481
482
0
    if (*query) {
483
0
        col_add_fstr(pinfo->cinfo, COL_INFO,
484
0
                     "Query, sid: %u", *sid);
485
0
    } else {
486
0
        col_add_fstr(pinfo->cinfo, COL_INFO,
487
0
                     "Response, sid: %u, code: %s (%u)",
488
0
                     *sid,
489
0
                     rval_to_str_const(*code,
490
0
                                       mpls_pm_response_ctrl_code_rvals,
491
0
                                       "Unknown"),
492
0
                     *code);
493
0
    }
494
0
}
495
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)
500
0
{
501
0
    proto_item *ti             = NULL;
502
0
    proto_tree *pm_tree;
503
0
    proto_tree *pm_tree_flags;
504
0
    proto_tree *pm_tree_dflags;
505
0
    uint32_t    offset         = 0;
506
0
    bool        query          = 0;
507
0
    bool        response       = 0;
508
0
    bool        class_specific = 0;
509
0
    uint32_t    sid            = 0;
510
0
    uint8_t     code           = 0;
511
0
    uint8_t     otf;
512
0
    bool        bflag;
513
0
    uint8_t     i;
514
515
0
    mpls_pm_build_cinfo(tvb, pinfo,
516
0
                        val_to_str_const(pmt, pmt_vals, ""),
517
0
                        &query, &response, &class_specific, &sid, &code);
518
519
0
    if (!tree) {
520
0
        return;
521
0
    }
522
523
    /* create display subtree for the protocol */
524
0
    if (pmt == DLM) {
525
0
        ti = proto_tree_add_item(tree, proto_mpls_pm_dlm, tvb, 0, -1, ENC_NA);
526
0
    } else {
527
0
        ti = proto_tree_add_item(tree, proto_mpls_pm_ilm, tvb, 0, -1, ENC_NA);
528
0
    }
529
530
0
    pm_tree = proto_item_add_subtree(ti, ett_mpls_pm);
531
532
    /* add version to the subtree */
533
0
    proto_tree_add_item(pm_tree, hf_mpls_pm_version, tvb, offset, 1, ENC_BIG_ENDIAN);
534
535
    /* ctrl flags subtree */
536
537
0
    ti = proto_tree_add_item(pm_tree, hf_mpls_pm_flags, tvb,
538
0
                             offset, 1, ENC_BIG_ENDIAN);
539
0
    pm_tree_flags = proto_item_add_subtree(ti, ett_mpls_pm_flags);
540
0
    proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_r, tvb,
541
0
                        offset, 1, ENC_NA);
542
0
    proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_t, tvb,
543
0
                        offset, 1, ENC_NA);
544
0
    proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_res, tvb,
545
0
                        offset, 1, ENC_NA);
546
0
    offset += 1;
547
548
0
    if (query) {
549
0
        proto_tree_add_item(pm_tree, hf_mpls_pm_query_ctrl_code,
550
0
                            tvb, offset, 1, ENC_BIG_ENDIAN);
551
0
    } else {
552
0
        proto_tree_add_item(pm_tree, hf_mpls_pm_response_ctrl_code,
553
0
                            tvb, offset, 1, ENC_BIG_ENDIAN);
554
0
    }
555
0
    offset += 1;
556
557
0
    proto_tree_add_item(pm_tree, hf_mpls_pm_length, tvb,
558
0
                        offset, 2, ENC_BIG_ENDIAN);
559
0
    offset += 2;
560
561
    /* data flags subtree */
562
0
    ti = proto_tree_add_item(pm_tree, hf_mpls_pm_dflags, tvb,
563
0
                             offset, 1, ENC_BIG_ENDIAN);
564
0
    pm_tree_dflags = proto_item_add_subtree(ti, ett_mpls_pm_dflags);
565
0
    proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_x, tvb,
566
0
                        offset, 1, ENC_NA);
567
0
    bflag = (tvb_get_uint8(tvb, offset) & 0x40) ? true : false;
568
0
    proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_b, tvb,
569
0
                        offset, 1, ENC_NA);
570
0
    proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_res, tvb,
571
0
                        offset, 1, ENC_NA);
572
573
0
    otf = tvb_get_uint8(tvb, offset) & 0x0F;
574
0
    proto_tree_add_item(pm_tree, hf_mpls_pm_otf, tvb,
575
0
                        offset, 1, ENC_BIG_ENDIAN);
576
0
    offset += 1;
577
578
    /* skip 3 reserved bytes */
579
0
    offset += 3;
580
581
0
    proto_tree_add_uint(pm_tree, hf_mpls_pm_session_id, tvb, offset, 4, sid);
582
583
0
    if (class_specific) {
584
0
        proto_tree_add_item(pm_tree, hf_mpls_pm_ds, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
585
0
    }
586
0
    offset += 4;
587
588
0
    switch (otf) {
589
0
    case MPLS_PM_TSF_NULL:
590
0
        proto_tree_add_item(pm_tree, hf_mpls_pm_origin_timestamp_null, tvb,
591
0
                            offset, 8, ENC_BIG_ENDIAN);
592
0
        break;
593
0
    case MPLS_PM_TSF_SEQ:
594
0
        proto_tree_add_item(pm_tree, hf_mpls_pm_origin_timestamp_seq, tvb,
595
0
                            offset, 8, ENC_BIG_ENDIAN);
596
0
        break;
597
0
    case MPLS_PM_TSF_NTP:
598
0
        proto_tree_add_item(pm_tree, hf_mpls_pm_origin_timestamp_ntp, tvb,
599
0
                            offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
600
0
        break;
601
0
    case MPLS_PM_TSF_PTP:
602
0
        proto_tree_add_item(pm_tree, hf_mpls_pm_origin_timestamp_ptp, tvb,
603
0
                            offset, 8, ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN);
604
0
        break;
605
0
    default:
606
0
        proto_tree_add_item(pm_tree, hf_mpls_pm_origin_timestamp_unk, tvb,
607
0
                            offset, 8, ENC_BIG_ENDIAN);
608
0
        break;
609
0
    }
610
0
    offset += 8;
611
612
    /* counters 1..4 */
613
0
    for (i = 1; i <= 4; i++) {
614
0
        mpls_pm_dissect_counter(tvb, pm_tree, offset, query, bflag, i);
615
0
        offset += 8;
616
0
    }
617
0
}
618
619
static int
620
dissect_mpls_pm_dlm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
621
0
{
622
    /* the message formats for direct and inferred LM are identical */
623
0
    dissect_mpls_pm_loss(tvb, pinfo, tree, DLM);
624
0
    return tvb_captured_length(tvb);
625
0
}
626
627
static int
628
dissect_mpls_pm_ilm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
629
0
{
630
    /* the message formats for direct and inferred LM are identical */
631
0
    dissect_mpls_pm_loss(tvb, pinfo, tree, ILM);
632
0
    return tvb_captured_length(tvb);
633
0
}
634
635
static int
636
dissect_mpls_pm_delay(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
637
0
{
638
0
    proto_item *ti;
639
0
    proto_tree *pm_tree;
640
0
    proto_tree *pm_tree_flags;
641
0
    uint32_t    offset         = 0;
642
0
    bool        query          = 0;
643
0
    bool        response       = 0;
644
0
    bool        class_specific = 0;
645
0
    uint32_t    sid            = 0;
646
0
    uint8_t     code           = 0;
647
0
    uint8_t     qtf;
648
0
    uint8_t     rtf;
649
0
    uint8_t     i;
650
651
0
    mpls_pm_build_cinfo(tvb, pinfo,
652
0
                        "DM",
653
0
                        &query, &response, &class_specific, &sid, &code);
654
655
    /* create display subtree for the protocol */
656
0
    ti = proto_tree_add_item(tree, proto_mpls_pm_dm, tvb, 0, -1, ENC_NA);
657
0
    pm_tree = proto_item_add_subtree(ti, ett_mpls_pm);
658
659
    /* add version to the subtree */
660
0
    proto_tree_add_item(pm_tree, hf_mpls_pm_version, tvb, offset, 1, ENC_BIG_ENDIAN);
661
662
    /* ctrl flags subtree */
663
0
    ti = proto_tree_add_item(pm_tree, hf_mpls_pm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
664
0
    pm_tree_flags = proto_item_add_subtree(ti, ett_mpls_pm_flags);
665
0
    proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_r, tvb,
666
0
                        offset, 1, ENC_NA);
667
0
    proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_t, tvb,
668
0
                        offset, 1, ENC_NA);
669
0
    proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_res, tvb,
670
0
                        offset, 1, ENC_NA);
671
0
    offset += 1;
672
673
0
    if (query) {
674
0
        proto_tree_add_item(pm_tree, hf_mpls_pm_query_ctrl_code,
675
0
                            tvb, offset, 1, ENC_BIG_ENDIAN);
676
0
    } else {
677
0
        proto_tree_add_item(pm_tree, hf_mpls_pm_response_ctrl_code,
678
0
                            tvb, offset, 1, ENC_BIG_ENDIAN);
679
0
    }
680
0
    offset += 1;
681
682
0
    proto_tree_add_item(pm_tree, hf_mpls_pm_length, tvb,
683
0
                        offset, 2, ENC_BIG_ENDIAN);
684
0
    offset += 2;
685
686
    /* qtf, rtf */
687
0
    qtf = (tvb_get_uint8(tvb, offset) & 0xF0) >> 4;
688
0
    proto_tree_add_item(pm_tree, hf_mpls_pm_qtf, tvb,
689
0
                        offset, 1, ENC_BIG_ENDIAN);
690
691
0
    rtf = tvb_get_uint8(tvb, offset) & 0x0F;
692
0
    proto_tree_add_item(pm_tree, hf_mpls_pm_rtf, tvb,
693
0
                        offset, 1, ENC_BIG_ENDIAN);
694
0
    offset += 1;
695
696
    /* rptf */
697
0
    proto_tree_add_item(pm_tree, hf_mpls_pm_rptf, tvb,
698
0
                        offset, 1, ENC_BIG_ENDIAN);
699
700
    /* skip 20 reserved bits */
701
0
    offset += 3;
702
703
0
    proto_tree_add_uint(pm_tree, hf_mpls_pm_session_id, tvb, offset, 4, sid);
704
705
0
    if (class_specific) {
706
0
        proto_tree_add_item(pm_tree, hf_mpls_pm_ds, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
707
0
    }
708
0
    offset += 4;
709
710
    /* timestamps 1..4 */
711
0
    for (i = 1; i <= 4; i++) {
712
0
        mpls_pm_dissect_timestamp(tvb, pm_tree, offset, qtf, rtf, query, i);
713
0
        offset += 8;
714
0
    }
715
0
    return tvb_captured_length(tvb);
716
0
}
717
718
static void
719
dissect_mpls_pm_combined(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
720
                         uint8_t pmt)
721
0
{
722
0
    proto_item *ti             = NULL;
723
0
    proto_tree *pm_tree;
724
0
    proto_tree *pm_tree_flags;
725
0
    proto_tree *pm_tree_dflags;
726
0
    uint32_t    offset         = 0;
727
0
    bool        query          = 0;
728
0
    bool        response       = 0;
729
0
    bool        class_specific = 0;
730
0
    uint32_t    sid            = 0;
731
0
    uint8_t     code           = 0;
732
0
    uint8_t     qtf;
733
0
    uint8_t     rtf;
734
0
    bool        bflag;
735
0
    uint8_t     i;
736
737
0
    mpls_pm_build_cinfo(tvb, pinfo,
738
0
                        val_to_str_const(pmt, pmt_vals, ""),
739
0
                        &query, &response, &class_specific, &sid, &code);
740
741
0
    if (!tree) {
742
0
        return;
743
0
    }
744
745
    /* create display subtree for the protocol */
746
0
    if (pmt == DLMDM) {
747
0
        ti = proto_tree_add_item(tree, proto_mpls_pm_dlm_dm,
748
0
                                 tvb, 0, -1, ENC_NA);
749
0
    } else {
750
0
        ti = proto_tree_add_item(tree, proto_mpls_pm_ilm_dm,
751
0
                                 tvb, 0, -1, ENC_NA);
752
0
    }
753
754
0
    pm_tree = proto_item_add_subtree(ti, ett_mpls_pm);
755
756
    /* add version to the subtree */
757
0
    proto_tree_add_item(pm_tree, hf_mpls_pm_version, tvb, offset, 1, ENC_BIG_ENDIAN);
758
759
    /* ctrl flags subtree */
760
0
    ti = proto_tree_add_item(pm_tree, hf_mpls_pm_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
761
0
    pm_tree_flags = proto_item_add_subtree(ti, ett_mpls_pm_flags);
762
0
    proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_r, tvb,
763
0
                        offset, 1, ENC_NA);
764
0
    proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_t, tvb,
765
0
                        offset, 1, ENC_NA);
766
0
    proto_tree_add_item(pm_tree_flags, hf_mpls_pm_flags_res, tvb,
767
0
                        offset, 1, ENC_NA);
768
0
    offset += 1;
769
770
0
    if (query) {
771
0
        proto_tree_add_item(pm_tree, hf_mpls_pm_query_ctrl_code,
772
0
                            tvb, offset, 1, ENC_BIG_ENDIAN);
773
0
    } else {
774
0
        proto_tree_add_item(pm_tree, hf_mpls_pm_response_ctrl_code,
775
0
                            tvb, offset, 1, ENC_BIG_ENDIAN);
776
0
    }
777
0
    offset += 1;
778
779
0
    proto_tree_add_item(pm_tree, hf_mpls_pm_length, tvb,
780
0
                        offset, 2, ENC_BIG_ENDIAN);
781
0
    offset += 2;
782
783
    /* data flags subtree */
784
0
    ti = proto_tree_add_item(pm_tree, hf_mpls_pm_dflags, tvb,
785
0
                             offset, 1, ENC_BIG_ENDIAN);
786
0
    pm_tree_dflags = proto_item_add_subtree(ti, ett_mpls_pm_dflags);
787
0
    proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_x, tvb,
788
0
                        offset, 1, ENC_NA);
789
0
    bflag = (tvb_get_uint8(tvb, offset) & 0x40) ? true : false;
790
0
    proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_b, tvb,
791
0
                        offset, 1, ENC_NA);
792
0
    proto_tree_add_item(pm_tree_dflags, hf_mpls_pm_dflags_res, tvb,
793
0
                        offset, 1, ENC_NA);
794
795
    /*
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.
798
     */
799
0
    qtf = tvb_get_uint8(tvb, offset) & 0x0F;
800
0
    proto_tree_add_item(pm_tree, hf_mpls_pm_qtf_combined, tvb,
801
0
                        offset, 1, ENC_BIG_ENDIAN);
802
0
    offset += 1;
803
804
    /* rtf, rptf */
805
0
    rtf = tvb_get_uint8(tvb, offset) & 0xF0 >> 4;
806
0
    proto_tree_add_item(pm_tree, hf_mpls_pm_rtf_combined, tvb,
807
0
                        offset, 1, ENC_BIG_ENDIAN);
808
809
0
    proto_tree_add_item(pm_tree, hf_mpls_pm_rptf_combined, tvb,
810
0
                        offset, 1, ENC_BIG_ENDIAN);
811
0
    offset += 1;
812
813
    /* skip 2 reserved bytes */
814
0
    offset += 2;
815
816
0
    proto_tree_add_uint(pm_tree, hf_mpls_pm_session_id, tvb, offset, 4, sid);
817
818
0
    if (class_specific) {
819
0
        proto_tree_add_item(pm_tree, hf_mpls_pm_ds, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
820
0
    }
821
0
    offset += 4;
822
823
    /* timestamps 1..4 */
824
0
    for (i = 1; i <= 4; i++) {
825
0
        mpls_pm_dissect_timestamp(tvb, pm_tree, offset, qtf, rtf, query, i);
826
0
        offset += 8;
827
0
    }
828
829
    /* counters 1..4 */
830
0
    for (i = 1; i <= 4; i++) {
831
0
        mpls_pm_dissect_counter(tvb, pm_tree, offset, query, bflag, i);
832
0
        offset += 8;
833
0
    }
834
0
}
835
836
static int
837
dissect_mpls_pm_dlm_dm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
838
0
{
839
    /* the formats of the DLM+DM and ILM+DM messages are also identical */
840
0
    dissect_mpls_pm_combined(tvb, pinfo, tree, DLMDM);
841
0
    return tvb_captured_length(tvb);
842
0
}
843
844
static int
845
dissect_mpls_pm_ilm_dm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
846
0
{
847
    /* the formats of the DLM+DM and ILM+DM messages are also identical */
848
0
    dissect_mpls_pm_combined(tvb, pinfo, tree, ILMDM);
849
0
    return tvb_captured_length(tvb);
850
0
}
851
852
void
853
proto_register_mpls_pm(void)
854
14
{
855
14
    static hf_register_info hf[] = {
856
14
        {
857
14
            &hf_mpls_pm_version,
858
14
            {
859
14
                "Version", "mpls_pm.version", FT_UINT8, BASE_DEC, NULL,
860
14
                0xF0, NULL, HFILL
861
14
            }
862
14
        },
863
14
        {
864
14
            &hf_mpls_pm_flags,
865
14
            {
866
14
                "Flags", "mpls_pm.flags", FT_UINT8,
867
14
                BASE_HEX, NULL, MPLS_PM_FLAGS_MASK, NULL, HFILL
868
14
            }
869
14
        },
870
14
        {
871
14
            &hf_mpls_pm_flags_r,
872
14
            {
873
14
                "Response indicator (R)", "mpls_pm.flags.r",
874
14
                FT_BOOLEAN, 8, TFS(&tfs_set_notset), MPLS_PM_FLAGS_R,
875
14
                NULL, HFILL
876
14
            }
877
14
        },
878
14
        {
879
14
            &hf_mpls_pm_flags_t,
880
14
            {
881
14
                "Traffic-class-specific measurement indicator (T)",
882
14
                "mpls_pm.flags.t",
883
14
                FT_BOOLEAN, 8, TFS(&tfs_set_notset), MPLS_PM_FLAGS_T,
884
14
                NULL, HFILL
885
14
            }
886
14
        },
887
14
        {
888
14
            &hf_mpls_pm_flags_res,
889
14
            {
890
14
                "Reserved",
891
14
                "mpls_pm.flags.res",
892
14
                FT_BOOLEAN, 8, TFS(&tfs_set_notset), MPLS_PM_FLAGS_RES,
893
14
                NULL, HFILL
894
14
            }
895
14
        },
896
14
        {
897
14
            &hf_mpls_pm_query_ctrl_code,
898
14
            {
899
14
                "Control Code",
900
14
                "mpls_pm.ctrl.code",
901
14
                FT_UINT8, BASE_RANGE_STRING | BASE_HEX,
902
14
                RVALS(mpls_pm_query_ctrl_code_rvals), 0x0,
903
14
                "Code identifying the query type", HFILL
904
14
            }
905
14
        },
906
14
        {
907
14
            &hf_mpls_pm_response_ctrl_code,
908
14
            {
909
14
                "Control Code",
910
14
                "mpls_pm.ctrl.code",
911
14
                FT_UINT8, BASE_RANGE_STRING | BASE_HEX,
912
14
                RVALS(mpls_pm_response_ctrl_code_rvals), 0x0,
913
14
                "Code identifying the response type", HFILL
914
14
            }
915
14
        },
916
14
        {
917
14
            &hf_mpls_pm_length,
918
14
            {
919
14
                "Message Length",
920
14
                "mpls_pm.length",
921
14
                FT_UINT16, BASE_DEC, NULL, 0x0,
922
14
                "Total length of this message in bytes", HFILL
923
14
            }
924
14
        },
925
14
        {
926
14
            &hf_mpls_pm_dflags,
927
14
            {
928
14
                "DFlags", "mpls_pm.dflags", FT_UINT8,
929
14
                BASE_HEX, NULL, MPLS_PM_DFLAGS_MASK,
930
14
                NULL, HFILL
931
14
            }
932
14
        },
933
14
        {
934
14
            &hf_mpls_pm_dflags_x,
935
14
            {
936
14
                "Extended counter format indicator (X)", "mpls_pm.dflags.x",
937
14
                FT_BOOLEAN, 8, TFS(&tfs_set_notset), MPLS_PM_DFLAGS_X,
938
14
                NULL, HFILL
939
14
            }
940
14
        },
941
14
        {
942
14
            &hf_mpls_pm_dflags_b,
943
14
            {
944
14
                "Octet/Byte count indicator (B)", "mpls_pm.dflags.b",
945
14
                FT_BOOLEAN, 8, TFS(&tfs_set_notset), MPLS_PM_DFLAGS_B,
946
14
                NULL, HFILL
947
14
            }
948
14
        },
949
14
        {
950
14
            &hf_mpls_pm_dflags_res,
951
14
            {
952
14
                "Reserved",
953
14
                "mpls_pm.dflags.res",
954
14
                FT_BOOLEAN, 8, NULL, MPLS_PM_DFLAGS_RES,
955
14
                NULL, HFILL
956
14
            }
957
14
        },
958
14
        {
959
14
            &hf_mpls_pm_otf,
960
14
            {
961
14
                "Origin Timestamp Format (OTF)",
962
14
                "mpls_pm.otf",
963
14
                FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
964
14
                RVALS(mpls_pm_time_stamp_format_rvals), 0x0F,
965
14
                NULL, HFILL
966
14
            }
967
14
        },
968
14
        {
969
14
            &hf_mpls_pm_session_id,
970
14
            {
971
14
                "Session Identifier",
972
14
                "mpls_pm.session.id",
973
14
                FT_UINT32, BASE_DEC,
974
14
                NULL, 0x0,
975
14
                NULL, HFILL
976
14
            }
977
14
        },
978
14
        {
979
14
            &hf_mpls_pm_ds,
980
14
            {
981
14
                "Differentiated Services Codepoint",
982
14
                "mpls_pm.ds",
983
14
                FT_UINT8, BASE_DEC | BASE_EXT_STRING,
984
14
                &dscp_vals_ext, 0x3F,
985
14
                NULL, HFILL
986
14
            }
987
14
        },
988
14
        {
989
14
            &hf_mpls_pm_origin_timestamp_null,
990
14
            {
991
14
                "Origin Timestamp",
992
14
                "mpls_pm.origin.timestamp.null",
993
14
                FT_UINT64, BASE_DEC,
994
14
                NULL, 0x0,
995
14
                NULL, HFILL
996
14
            }
997
14
        },
998
14
        {
999
14
            &hf_mpls_pm_origin_timestamp_seq,
1000
14
            {
1001
14
                "Origin Timestamp",
1002
14
                "mpls_pm.origin.timestamp.seq",
1003
14
                FT_UINT64, BASE_DEC,
1004
14
                NULL, 0x0,
1005
14
                NULL, HFILL
1006
14
            }
1007
14
        },
1008
14
        {
1009
14
            &hf_mpls_pm_origin_timestamp_ntp,
1010
14
            {
1011
14
                "Origin Timestamp",
1012
14
                "mpls_pm.origin.timestamp.ntp",
1013
14
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC,
1014
14
                NULL, 0x0,
1015
14
                NULL, HFILL
1016
14
            }
1017
14
        },
1018
14
        {
1019
14
            &hf_mpls_pm_origin_timestamp_ptp,
1020
14
            {
1021
14
                "Origin Timestamp",
1022
14
                "mpls_pm.origin.timestamp.ptp",
1023
14
                FT_RELATIVE_TIME, BASE_NONE,
1024
14
                NULL, 0x0,
1025
14
                NULL, HFILL
1026
14
            }
1027
14
        },
1028
14
        {
1029
14
            &hf_mpls_pm_origin_timestamp_unk,
1030
14
            {
1031
14
                "Origin Timestamp (Unknown Type)",
1032
14
                "mpls_pm.origin.timestamp.unk",
1033
14
                FT_UINT64, BASE_DEC,
1034
14
                NULL, 0x0,
1035
14
                NULL, HFILL
1036
14
            }
1037
14
        },
1038
14
        {
1039
14
            &hf_mpls_pm_counter1,
1040
14
            {
1041
14
                "Counter 1",
1042
14
                "mpls_pm.counter1",
1043
14
                FT_UINT64, BASE_DEC,
1044
14
                NULL, 0x0,
1045
14
                NULL, HFILL
1046
14
            }
1047
14
        },
1048
14
        {
1049
14
            &hf_mpls_pm_counter2,
1050
14
            {
1051
14
                "Counter 2",
1052
14
                "mpls_pm.counter2",
1053
14
                FT_UINT64, BASE_DEC,
1054
14
                NULL, 0x0,
1055
14
                NULL, HFILL
1056
14
            }
1057
14
        },
1058
14
        {
1059
14
            &hf_mpls_pm_counter3,
1060
14
            {
1061
14
                "Counter 3",
1062
14
                "mpls_pm.counter3",
1063
14
                FT_UINT64, BASE_DEC,
1064
14
                NULL, 0x0,
1065
14
                NULL, HFILL
1066
14
            }
1067
14
        },
1068
14
        {
1069
14
            &hf_mpls_pm_counter4,
1070
14
            {
1071
14
                "Counter 4",
1072
14
                "mpls_pm.counter4",
1073
14
                FT_UINT64, BASE_DEC,
1074
14
                NULL, 0x0,
1075
14
                NULL, HFILL
1076
14
            }
1077
14
        },
1078
14
        {
1079
14
            &hf_mpls_pm_qtf,
1080
14
            {
1081
14
                "Querier timestamp format (QTF)",
1082
14
                "mpls_pm.qtf",
1083
14
                FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1084
14
                RVALS(mpls_pm_time_stamp_format_rvals), 0xF0,
1085
14
                NULL, HFILL
1086
14
            }
1087
14
        },
1088
14
        {
1089
14
            &hf_mpls_pm_qtf_combined,
1090
14
            {
1091
14
                "Querier timestamp format (QTF)",
1092
14
                "mpls_pm.qtf",
1093
14
                FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1094
14
                RVALS(mpls_pm_time_stamp_format_rvals), 0x0F,
1095
14
                NULL, HFILL
1096
14
            }
1097
14
        },
1098
14
        {
1099
14
            &hf_mpls_pm_rtf,
1100
14
            {
1101
14
                "Responder timestamp format (RTF)",
1102
14
                "mpls_pm.rtf",
1103
14
                FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1104
14
                RVALS(mpls_pm_time_stamp_format_rvals), 0x0F,
1105
14
                NULL, HFILL
1106
14
            }
1107
14
        },
1108
14
        {
1109
14
            &hf_mpls_pm_rtf_combined,
1110
14
            {
1111
14
                "Responder timestamp format (RTF)",
1112
14
                "mpls_pm.rtf",
1113
14
                FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1114
14
                RVALS(mpls_pm_time_stamp_format_rvals), 0xF0,
1115
14
                NULL, HFILL
1116
14
            }
1117
14
        },
1118
14
        {
1119
14
            &hf_mpls_pm_rptf,
1120
14
            {
1121
14
                "Responder's preferred timestamp format (RPTF)",
1122
14
                "mpls_pm.rptf",
1123
14
                FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1124
14
                RVALS(mpls_pm_time_stamp_format_rvals), 0xF0,
1125
14
                NULL, HFILL
1126
14
            }
1127
14
        },
1128
14
        {
1129
14
            &hf_mpls_pm_rptf_combined,
1130
14
            {
1131
14
                "Responder's preferred timestamp format (RPTF)",
1132
14
                "mpls_pm.rptf",
1133
14
                FT_UINT8, BASE_RANGE_STRING | BASE_DEC,
1134
14
                RVALS(mpls_pm_time_stamp_format_rvals), 0x0F,
1135
14
                NULL, HFILL
1136
14
            }
1137
14
        },
1138
14
        {
1139
14
            &hf_mpls_pm_timestamp1_q_null,
1140
14
            {
1141
14
                "Timestamp 1 (T1)",
1142
14
                "mpls_pm.timestamp1.null",
1143
14
                FT_UINT64, BASE_DEC,
1144
14
                NULL, 0x0,
1145
14
                NULL, HFILL
1146
14
            }
1147
14
        },
1148
14
        {
1149
14
            &hf_mpls_pm_timestamp1_r_null,
1150
14
            {
1151
14
                "Timestamp 1 (T3)",
1152
14
                "mpls_pm.timestamp1.null",
1153
14
                FT_UINT64, BASE_DEC,
1154
14
                NULL, 0x0,
1155
14
                NULL, HFILL
1156
14
            }
1157
14
        },
1158
14
        {
1159
14
            &hf_mpls_pm_timestamp1_q_seq,
1160
14
            {
1161
14
                "Timestamp 1 (T1)",
1162
14
                "mpls_pm.timestamp1.seq",
1163
14
                FT_UINT64, BASE_DEC,
1164
14
                NULL, 0x0,
1165
14
                NULL, HFILL
1166
14
            }
1167
14
        },
1168
14
        {
1169
14
            &hf_mpls_pm_timestamp1_r_seq,
1170
14
            {
1171
14
                "Timestamp 1 (T3)",
1172
14
                "mpls_pm.timestamp1.seq",
1173
14
                FT_UINT64, BASE_DEC,
1174
14
                NULL, 0x0,
1175
14
                NULL, HFILL
1176
14
            }
1177
14
        },
1178
14
        {
1179
14
            &hf_mpls_pm_timestamp1_q_ntp,
1180
14
            {
1181
14
                "Timestamp 1 (T1)",
1182
14
                "mpls_pm.timestamp1.ntp",
1183
14
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC,
1184
14
                NULL, 0x0,
1185
14
                NULL, HFILL
1186
14
            }
1187
14
        },
1188
14
        {
1189
14
            &hf_mpls_pm_timestamp1_r_ntp,
1190
14
            {
1191
14
                "Timestamp 1 (T3)",
1192
14
                "mpls_pm.timestamp1.ntp",
1193
14
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC,
1194
14
                NULL, 0x0,
1195
14
                NULL, HFILL
1196
14
            }
1197
14
        },
1198
14
        {
1199
14
            &hf_mpls_pm_timestamp1_q_ptp,
1200
14
            {
1201
14
                "Timestamp 1 (T1)",
1202
14
                "mpls_pm.timestamp1.ptp",
1203
14
                FT_RELATIVE_TIME, BASE_NONE,
1204
14
                NULL, 0x0,
1205
14
                NULL, HFILL
1206
14
            }
1207
14
        },
1208
14
        {
1209
14
            &hf_mpls_pm_timestamp1_r_ptp,
1210
14
            {
1211
14
                "Timestamp 1 (T3)",
1212
14
                "mpls_pm.timestamp1.ptp",
1213
14
                FT_RELATIVE_TIME, BASE_NONE,
1214
14
                NULL, 0x0,
1215
14
                NULL, HFILL
1216
14
            }
1217
14
        },
1218
14
        {
1219
14
            &hf_mpls_pm_timestamp1_unk,
1220
14
            {
1221
14
                "Timestamp 1 (Unknown Type)",
1222
14
                "mpls_pm.timestamp1.unk",
1223
14
                FT_UINT64, BASE_DEC,
1224
14
                NULL, 0x0,
1225
14
                NULL, HFILL
1226
14
            }
1227
14
        },
1228
14
        {
1229
14
            &hf_mpls_pm_timestamp2_q_null,
1230
14
            {
1231
14
                "Timestamp 2 (T2)",
1232
14
                "mpls_pm.timestamp2.null",
1233
14
                FT_UINT64, BASE_DEC,
1234
14
                NULL, 0x0,
1235
14
                NULL, HFILL
1236
14
            }
1237
14
        },
1238
14
        {
1239
14
            &hf_mpls_pm_timestamp2_r_null,
1240
14
            {
1241
14
                "Timestamp 2 (T4)",
1242
14
                "mpls_pm.timestamp2.null",
1243
14
                FT_UINT64, BASE_DEC,
1244
14
                NULL, 0x0,
1245
14
                NULL, HFILL
1246
14
            }
1247
14
        },
1248
14
        {
1249
14
            &hf_mpls_pm_timestamp2_q_seq,
1250
14
            {
1251
14
                "Timestamp 2 (T2)",
1252
14
                "mpls_pm.timestamp2.seq",
1253
14
                FT_UINT64, BASE_DEC,
1254
14
                NULL, 0x0,
1255
14
                NULL, HFILL
1256
14
            }
1257
14
        },
1258
14
        {
1259
14
            &hf_mpls_pm_timestamp2_r_seq,
1260
14
            {
1261
14
                "Timestamp 2 (T4)",
1262
14
                "mpls_pm.timestamp2.seq",
1263
14
                FT_UINT64, BASE_DEC,
1264
14
                NULL, 0x0,
1265
14
                NULL, HFILL
1266
14
            }
1267
14
        },
1268
14
        {
1269
14
            &hf_mpls_pm_timestamp2_q_ntp,
1270
14
            {
1271
14
                "Timestamp 2 (T2)",
1272
14
                "mpls_pm.timestamp2.ntp",
1273
14
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC,
1274
14
                NULL, 0x0,
1275
14
                NULL, HFILL
1276
14
            }
1277
14
        },
1278
14
        {
1279
14
            &hf_mpls_pm_timestamp2_r_ntp,
1280
14
            {
1281
14
                "Timestamp 2 (T4)",
1282
14
                "mpls_pm.timestamp2.ntp",
1283
14
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC,
1284
14
                NULL, 0x0,
1285
14
                NULL, HFILL
1286
14
            }
1287
14
        },
1288
14
        {
1289
14
            &hf_mpls_pm_timestamp2_q_ptp,
1290
14
            {
1291
14
                "Timestamp 2 (T2)",
1292
14
                "mpls_pm.timestamp2.ptp",
1293
14
                FT_RELATIVE_TIME, BASE_NONE,
1294
14
                NULL, 0x0,
1295
14
                NULL, HFILL
1296
14
            }
1297
14
        },
1298
14
        {
1299
14
            &hf_mpls_pm_timestamp2_r_ptp,
1300
14
            {
1301
14
                "Timestamp 2 (T4)",
1302
14
                "mpls_pm.timestamp2.ptp",
1303
14
                FT_RELATIVE_TIME, BASE_NONE,
1304
14
                NULL, 0x0,
1305
14
                NULL, HFILL
1306
14
            }
1307
14
        },
1308
14
        {
1309
14
            &hf_mpls_pm_timestamp2_unk,
1310
14
            {
1311
14
                "Timestamp 2 (Unknown Type)",
1312
14
                "mpls_pm.timestamp2.unk",
1313
14
                FT_UINT64, BASE_DEC,
1314
14
                NULL, 0x0,
1315
14
                NULL, HFILL
1316
14
            }
1317
14
        },
1318
14
        {
1319
14
            &hf_mpls_pm_timestamp3_null,
1320
14
            {
1321
14
                "Timestamp 3",
1322
14
                "mpls_pm.timestamp3.null",
1323
14
                FT_UINT64, BASE_DEC,
1324
14
                NULL, 0x0,
1325
14
                NULL, HFILL
1326
14
            }
1327
14
        },
1328
14
        {
1329
14
            &hf_mpls_pm_timestamp3_r_null,
1330
14
            {
1331
14
                "Timestamp 3 (T1)",
1332
14
                "mpls_pm.timestamp3.null",
1333
14
                FT_UINT64, BASE_DEC,
1334
14
                NULL, 0x0,
1335
14
                NULL, HFILL
1336
14
            }
1337
14
        },
1338
14
        {
1339
14
            &hf_mpls_pm_timestamp3_r_seq,
1340
14
            {
1341
14
                "Timestamp 3 (T1)",
1342
14
                "mpls_pm.timestamp3.seq",
1343
14
                FT_UINT64, BASE_DEC,
1344
14
                NULL, 0x0,
1345
14
                NULL, HFILL
1346
14
            }
1347
14
        },
1348
14
        {
1349
14
            &hf_mpls_pm_timestamp3_r_ntp,
1350
14
            {
1351
14
                "Timestamp 3 (T1)",
1352
14
                "mpls_pm.timestamp3.ntp",
1353
14
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC,
1354
14
                NULL, 0x0,
1355
14
                NULL, HFILL
1356
14
            }
1357
14
        },
1358
14
        {
1359
14
            &hf_mpls_pm_timestamp3_r_ptp,
1360
14
            {
1361
14
                "Timestamp 3 (T1)",
1362
14
                "mpls_pm.timestamp3_ptp",
1363
14
                FT_RELATIVE_TIME, BASE_NONE,
1364
14
                NULL, 0x0,
1365
14
                NULL, HFILL
1366
14
            }
1367
14
        },
1368
14
        {
1369
14
            &hf_mpls_pm_timestamp3_unk,
1370
14
            {
1371
14
                "Timestamp 3 (Unknown Type)",
1372
14
                "mpls_pm.timestamp3.unk",
1373
14
                FT_UINT64, BASE_DEC,
1374
14
                NULL, 0x0,
1375
14
                NULL, HFILL
1376
14
            }
1377
14
        },
1378
14
        {
1379
14
            &hf_mpls_pm_timestamp4_null,
1380
14
            {
1381
14
                "Timestamp 4",
1382
14
                "mpls_pm.timestamp4.null",
1383
14
                FT_UINT64, BASE_DEC,
1384
14
                NULL, 0x0,
1385
14
                NULL, HFILL
1386
14
            }
1387
14
        },
1388
14
        {
1389
14
            &hf_mpls_pm_timestamp4_r_null,
1390
14
            {
1391
14
                "Timestamp 4 (T2)",
1392
14
                "mpls_pm.timestamp4.null",
1393
14
                FT_UINT64, BASE_DEC,
1394
14
                NULL, 0x0,
1395
14
                NULL, HFILL
1396
14
            }
1397
14
        },
1398
14
        {
1399
14
            &hf_mpls_pm_timestamp4_r_seq,
1400
14
            {
1401
14
                "Timestamp 4 (T2)",
1402
14
                "mpls_pm.timestamp4.seq",
1403
14
                FT_UINT64, BASE_DEC,
1404
14
                NULL, 0x0,
1405
14
                NULL, HFILL
1406
14
            }
1407
14
        },
1408
14
        {
1409
14
            &hf_mpls_pm_timestamp4_r_ntp,
1410
14
            {
1411
14
                "Timestamp 4 (T2)",
1412
14
                "mpls_pm.timestamp4.ntp",
1413
14
                FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC,
1414
14
                NULL, 0x0,
1415
14
                NULL, HFILL
1416
14
            }
1417
14
        },
1418
14
        {
1419
14
            &hf_mpls_pm_timestamp4_r_ptp,
1420
14
            {
1421
14
                "Timestamp 4 (T2)",
1422
14
                "mpls_pm.timestamp4.ptp",
1423
14
                FT_RELATIVE_TIME, BASE_NONE,
1424
14
                NULL, 0x0,
1425
14
                NULL, HFILL
1426
14
            }
1427
14
        },
1428
14
        {
1429
14
            &hf_mpls_pm_timestamp4_unk,
1430
14
            {
1431
14
                "Timestamp 4 (Unknown Type)",
1432
14
                "mpls_pm.timestamp4.unk",
1433
14
                FT_UINT64, BASE_DEC,
1434
14
                NULL, 0x0,
1435
14
                NULL, HFILL
1436
14
            }
1437
14
        }
1438
14
    };
1439
1440
14
    static int *ett[] = {
1441
14
        &ett_mpls_pm,
1442
14
        &ett_mpls_pm_flags,
1443
14
        &ett_mpls_pm_dflags
1444
14
    };
1445
1446
14
    proto_mpls_pm_dlm =
1447
14
        proto_register_protocol("MPLS Direct Loss Measurement (DLM)",
1448
14
                                "MPLS Direct Loss Measurement (DLM)",
1449
14
                                "mplspmdlm");
1450
1451
14
    proto_mpls_pm_ilm =
1452
14
        proto_register_protocol("MPLS Inferred Loss Measurement (ILM)",
1453
14
                                "MPLS Inferred Loss Measurement (ILM)",
1454
14
                                "mplspmilm");
1455
1456
14
    proto_mpls_pm_dm =
1457
14
        proto_register_protocol("MPLS Delay Measurement (DM)",
1458
14
                                "MPLS Delay Measurement (DM)",
1459
14
                                "mplspmdm");
1460
1461
14
    proto_mpls_pm_dlm_dm =
1462
14
        proto_register_protocol("MPLS Direct Loss and Delay "
1463
14
                                "Measurement (DLM+DM)",
1464
14
                                "MPLS Direct Loss and Delay "
1465
14
                                "Measurement (DLM+DM)",
1466
14
                                "mplspmdlmdm");
1467
1468
14
    proto_mpls_pm_ilm_dm =
1469
14
        proto_register_protocol("MPLS Inferred Loss and Delay "
1470
14
                                "Measurement (ILM+DM)",
1471
14
                                "MPLS Inferred Loss and Delay "
1472
14
                                "Measurement (ILM+DM)",
1473
14
                                "mplspmilmdm");
1474
1475
14
    proto_register_field_array(proto_mpls_pm_dlm, hf, array_length(hf));
1476
14
    proto_register_subtree_array(ett, array_length(ett));
1477
14
}
1478
1479
void
1480
proto_reg_handoff_mpls_pm(void)
1481
14
{
1482
14
    dissector_handle_t mpls_pm_dlm_handle, mpls_pm_ilm_handle, mpls_pm_dm_handle,
1483
14
                       mpls_pm_dlm_dm_handle, mpls_pm_ilm_dm_handle;
1484
1485
14
    mpls_pm_dlm_handle = create_dissector_handle( dissect_mpls_pm_dlm, proto_mpls_pm_dlm );
1486
14
    dissector_add_uint("pwach.channel_type", PW_ACH_TYPE_DLM, mpls_pm_dlm_handle);
1487
14
    mpls_pm_ilm_handle = create_dissector_handle( dissect_mpls_pm_ilm, proto_mpls_pm_ilm );
1488
14
    dissector_add_uint("pwach.channel_type", PW_ACH_TYPE_ILM, mpls_pm_ilm_handle);
1489
14
    mpls_pm_dm_handle = create_dissector_handle( dissect_mpls_pm_delay, proto_mpls_pm_dm );
1490
14
    dissector_add_uint("pwach.channel_type", PW_ACH_TYPE_DM, mpls_pm_dm_handle);
1491
14
    mpls_pm_dlm_dm_handle = create_dissector_handle( dissect_mpls_pm_dlm_dm, proto_mpls_pm_dlm_dm );
1492
14
    dissector_add_uint("pwach.channel_type", PW_ACH_TYPE_DLM_DM, mpls_pm_dlm_dm_handle);
1493
14
    mpls_pm_ilm_dm_handle = create_dissector_handle( dissect_mpls_pm_ilm_dm, proto_mpls_pm_ilm_dm );
1494
14
    dissector_add_uint("pwach.channel_type", PW_ACH_TYPE_ILM_DM, mpls_pm_ilm_dm_handle);
1495
14
}
1496
1497
/*
1498
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1499
 *
1500
 * Local variables:
1501
 * c-basic-offset: 4
1502
 * tab-width: 8
1503
 * indent-tabs-mode: nil
1504
 * End:
1505
 *
1506
 * vi: set shiftwidth=4 tabstop=8 expandtab:
1507
 * :indentSize=4:tabSize=8:noTabs=true:
1508
 */