Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-mpls-y1711.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-mpls-y1711.c
2
 * Routines for (old) ITU-T MPLS OAM: it conforms to ITU-T Y.1711 and RFC 3429
3
 *
4
 * Copyright 2006, 2011 _FF_
5
 *
6
 * Francesco Fondelli <francesco dot fondelli, gmail dot com>
7
 *
8
 * Wireshark - Network traffic analyzer
9
 * By Gerald Combs <gerald@wireshark.org>
10
 * Copyright 1998 Gerald Combs
11
 *
12
 * SPDX-License-Identifier: GPL-2.0-or-later
13
 */
14
15
/*
16
 * FF: NOTES
17
 *
18
 * - this should dissect OAM pdus (identified by the MPLS_LABEL_OAM_ALERT = 14
19
 *   label) as described in ITU-T Y.1711 and RFC 3429.
20
 *
21
 * - this code used to be (since 2006) in packet-mpls.c ... nobody on this
22
 *   planet is using Y.1711 today (?), so thanks to the mpls subdissector
23
 *   table indexed by label value it has been moved here.
24
 */
25
26
#include "config.h"
27
28
#include <epan/packet.h>
29
#include <epan/expert.h>
30
31
#include "packet-mpls.h"
32
33
void proto_register_mpls_y1711(void);
34
void proto_reg_handoff_mpls_y1711(void);
35
36
static int proto_mpls_y1711;
37
38
static int hf_mpls_y1711_function_type;
39
/* static int hf_mpls_y1711_ttsi; */
40
static int hf_mpls_y1711_frequency;
41
static int hf_mpls_y1711_defect_type;
42
static int hf_mpls_y1711_defect_location;
43
static int hf_mpls_y1711_bip16;
44
/* Generated from convert_proto_tree_add_text.pl */
45
static int hf_mpls_y1711_lsr_id;
46
static int hf_mpls_y1711_lsp_id;
47
48
static int ett_mpls_y1711;
49
50
/* Generated from convert_proto_tree_add_text.pl */
51
static expert_field ei_mpls_y1711_padding_not_ff;
52
static expert_field ei_mpls_y1711_reserved_not_zero;
53
static expert_field ei_mpls_y1711_ttsi_not_preset;
54
static expert_field ei_mpls_y1711_minimum_payload;
55
static expert_field ei_mpls_y1711_s_bit_not_one;
56
static expert_field ei_mpls_y1711_no_OAM_alert_label;
57
static expert_field ei_mpls_y1711_exp_bits_not_zero;
58
static expert_field ei_mpls_y1711_ttl_not_one;
59
static expert_field ei_mpls_y1711_padding_not_zero;
60
static expert_field ei_mpls_y1711_unknown_pdu;
61
62
static dissector_handle_t mpls_y1711_handle;
63
64
static const value_string y1711_function_type_vals[] = {
65
    {0x00, "Reserved"                               },
66
    {0x01, "CV (Connectivity Verification)"         },
67
    {0x02, "FDI (Forward Defect Indicator)"         },
68
    {0x03, "BDI (Backward Defect Indicator)"        },
69
    {0x04, "Reserved for Performance packets"       },
70
    {0x05, "Reserved for LB-Req (Loopback Request)" },
71
    {0x06, "Reserved for LB-Rsp (Loopback Response)"},
72
    {0x07, "FDD (Fast Failure Detection)"           },
73
    {0,    NULL                                     }
74
};
75
76
static const value_string y1711_frequency_vals[] = {
77
    {0x00, "Reserved"             },
78
    {0x01, "10 ms"                },
79
    {0x02, "20 ms"                },
80
    {0x03, "50 ms (default value)"},
81
    {0x04, "100 ms"               },
82
    {0x05, "200 ms"               },
83
    {0x06, "500 ms"               },
84
    /* 7-255 Reserved */
85
    {0,    NULL                   }
86
};
87
88
static const value_string y1711_defect_type_vals[] = {
89
    {0x0000, "Reserved"      },
90
    {0x0101, "dServer"       },
91
    {0x0102, "dPeerME"       },
92
    {0x0201, "dLOCV"         },
93
    {0x0202, "dTTSI_Mismatch"},
94
    {0x0203, "dTTSI_Mismerge"},
95
    {0x0204, "dExcess"       },
96
    {0x02FF, "dUnknown"      },
97
    {0xFFFF, "Reserved"      },
98
    {0,      NULL            }
99
};
100
101
static int
102
dissect_mpls_y1711(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
103
5
{
104
5
    struct mplsinfo *mplsinfo;
105
5
    int              offset          = 0;
106
5
    proto_tree      *mpls_y1711_tree;
107
5
    int              functype;
108
5
    tvbuff_t        *data_tvb;
109
110
5
    static const uint8_t allone[]  = { 0xff, 0xff };
111
5
    static const uint8_t allzero[] = { 0x00, 0x00, 0x00, 0x00, 0x00,
112
5
                                      0x00, 0x00, 0x00, 0x00, 0x00,
113
5
                                      0x00, 0x00, 0x00, 0x00, 0x00,
114
5
                                      0x00, 0x00, 0x00, 0x00, 0x00 };
115
116
    /* Reject the packet if data is NULL */
117
5
    if (data == NULL)
118
0
        return 0;
119
5
    mplsinfo = (struct mplsinfo *)data;
120
121
5
    functype = tvb_get_uint8(tvb, offset);
122
5
    col_append_fstr(pinfo->cinfo, COL_INFO, " (Y.1711: %s)",
123
5
                    (functype == 0x01) ? "CV" :
124
5
                    (functype == 0x02) ? "FDI" :
125
5
                    (functype == 0x03) ? "BDI" :
126
5
                    (functype == 0x07) ? "FDD" :
127
4
                    "reserved/unknown");
128
129
    /* sanity checks */
130
5
    if (tvb_reported_length(tvb) < 44) {
131
        /*
132
         * ITU-T Y.1711, 5.3: PDUs must have a minimum payload length of
133
         * 44 bytes
134
         */
135
3
        proto_tree_add_expert(tree, pinfo, &ei_mpls_y1711_minimum_payload, tvb, offset, -1);
136
3
        data_tvb = tvb_new_subset_remaining(tvb, offset);
137
3
        call_data_dissector(data_tvb, pinfo, tree);
138
139
3
        return tvb_reported_length(tvb);
140
3
    }
141
142
2
    mpls_y1711_tree = proto_tree_add_subtree(tree, tvb, offset, 44, ett_mpls_y1711, NULL, "Y.1711 OAM");
143
144
    /* checks for exp, bos and ttl encoding */
145
2
    if (mplsinfo->label != MPLS_LABEL_OAM_ALERT)
146
0
        proto_tree_add_expert_format(mpls_y1711_tree, pinfo, &ei_mpls_y1711_no_OAM_alert_label, tvb, offset - 4, 3,
147
0
                                     "Warning: Y.1711 but no OAM alert label (%d) ?!", MPLS_LABEL_OAM_ALERT);
148
149
2
    if (mplsinfo->exp != 0)
150
2
        proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_exp_bits_not_zero, tvb, offset - 2, 1);
151
152
2
    if (mplsinfo->bos != 1)
153
0
        proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_s_bit_not_one, tvb, offset - 2, 1);
154
155
2
    if (mplsinfo->ttl != 1)
156
2
        proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_ttl_not_one, tvb, offset - 1, 1);
157
158
    /* starting dissection */
159
2
    functype = tvb_get_uint8(tvb, offset);
160
2
    proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_function_type, tvb,
161
2
                        offset, 1,
162
2
                        ENC_LITTLE_ENDIAN);
163
2
    offset++;
164
165
2
    switch (functype) {
166
0
    case 0x01: /* CV */
167
0
    {
168
        /* 3 octets reserved (all 0x00) */
169
0
        if (tvb_memeql(tvb, offset, allzero, 3) == -1) {
170
0
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_reserved_not_zero, tvb, offset, 3);
171
0
        }
172
0
        offset += 3;
173
174
        /* ttsi (ipv4 flavor as in RFC 2373) */
175
0
        if (tvb_memeql(tvb, offset, allzero, 10) == -1) {
176
0
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 10);
177
0
        }
178
0
        offset += 10;
179
180
0
        if (tvb_memeql(tvb, offset, allone, 2) == -1) {
181
0
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_ff, tvb, offset, 2);
182
0
        }
183
0
        offset += 2;
184
185
0
        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsr_id, tvb, offset, 4, ENC_BIG_ENDIAN);
186
0
        offset += 4;
187
188
0
        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
189
0
        offset += 4;
190
191
        /* 18 octets of padding (all 0x00) */
192
0
        if (tvb_memeql(tvb, offset, allzero, 18) == -1) {
193
0
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 18);
194
0
        }
195
0
        offset += 18;
196
0
    }
197
0
    break;
198
199
0
    case 0x02: /* FDI */
200
0
    case 0x03: /* BDI */
201
0
    {
202
        /* 1 octets reserved (all 0x00) */
203
0
        if (tvb_memeql(tvb, offset, allzero, 1) == -1) {
204
0
            proto_tree_add_expert_format(mpls_y1711_tree, pinfo, &ei_mpls_y1711_reserved_not_zero, tvb, offset, 3,
205
0
                                         "Error: this byte is reserved and must be 0x00");
206
0
        }
207
0
        offset++;
208
209
0
        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_defect_type, tvb,
210
0
                            offset, 2,
211
0
                            ENC_BIG_ENDIAN);
212
0
        offset += 2;
213
214
        /*
215
         * ttsi (ipv4 flavor as in RFC 2373) is optional if not used must
216
         * be set to all 0x00
217
         */
218
0
        if (tvb_memeql(tvb, offset, allzero, 20) == 0) {
219
0
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_ttsi_not_preset, tvb, offset, 20);
220
0
            offset += 20;
221
0
        } else {
222
0
            if (tvb_memeql(tvb, offset, allzero, 10) == -1) {
223
0
                proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 10);
224
0
            }
225
0
            offset += 10;
226
227
0
            if (tvb_memeql(tvb, offset, allone, 2) == -1) {
228
0
                proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_ff, tvb, offset, 2);
229
0
            }
230
0
            offset += 2;
231
232
0
            proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsr_id, tvb, offset, 4, ENC_BIG_ENDIAN);
233
0
            offset += 4;
234
235
0
            proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
236
0
            offset += 4;
237
0
        }
238
239
        /* defect location */
240
0
        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_defect_location, tvb,
241
0
                            offset, 4,
242
0
                            ENC_BIG_ENDIAN);
243
0
        offset += 4;
244
245
        /* 14 octets of padding (all 0x00) */
246
0
        if (tvb_memeql(tvb, offset, allzero, 14) == -1) {
247
0
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 14);
248
0
        }
249
0
        offset += 14;
250
0
    }
251
0
    break;
252
253
0
    case 0x07: /* FDD */
254
0
    {
255
        /* 3 octets reserved (all 0x00) */
256
0
        if (tvb_memeql(tvb, offset, allzero, 3) == -1) {
257
0
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_reserved_not_zero, tvb, offset, 3);
258
0
        }
259
0
        offset += 3;
260
261
        /* ttsi (ipv4 flavor as in RFC 2373) */
262
0
        if (tvb_memeql(tvb, offset, allzero, 10) == -1) {
263
0
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 10);
264
0
        }
265
0
        offset += 10;
266
267
0
        if (tvb_memeql(tvb, offset, allone, 2) == -1) {
268
0
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_ff, tvb, offset, 2);
269
0
        }
270
0
        offset += 2;
271
272
0
        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsr_id, tvb, offset, 4, ENC_BIG_ENDIAN);
273
0
        offset += 4;
274
275
0
        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_lsp_id, tvb, offset, 4, ENC_BIG_ENDIAN);
276
0
        offset += 4;
277
278
0
        proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_frequency, tvb,
279
0
                            offset, 1,
280
0
                            ENC_LITTLE_ENDIAN);
281
0
        offset++;
282
283
        /* 17 octets of padding (all 0x00) */
284
0
        if (tvb_memeql(tvb, offset, allzero, 17) == -1) {
285
0
            proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_padding_not_zero, tvb, offset, 17);
286
0
        }
287
0
        offset += 17;
288
0
    }
289
0
    break;
290
291
2
    default:
292
2
        proto_tree_add_expert(mpls_y1711_tree, pinfo, &ei_mpls_y1711_unknown_pdu, tvb, offset - 1, -1);
293
2
        return offset;
294
2
    }
295
296
    /* BIP16 */
297
0
    proto_tree_add_item(mpls_y1711_tree, hf_mpls_y1711_bip16, tvb, offset, 2,
298
0
                        ENC_BIG_ENDIAN);
299
0
    offset += 2;
300
301
0
    return offset;
302
2
}
303
304
void
305
proto_register_mpls_y1711(void)
306
14
{
307
14
    static hf_register_info hf[] = {
308
14
        {
309
14
            &hf_mpls_y1711_function_type,
310
14
            {
311
14
                "Function Type", "mpls_y1711.function_type", FT_UINT8,
312
14
                BASE_HEX, VALS(y1711_function_type_vals),
313
14
                0x0, "Function Type codepoint", HFILL
314
14
            }
315
14
        },
316
#if 0
317
        {
318
            &hf_mpls_y1711_ttsi,
319
            {
320
                "Trail Termination Source Identifier",
321
                "mpls_y1711.ttsi",
322
                FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL
323
            }
324
        },
325
#endif
326
14
        {
327
14
            &hf_mpls_y1711_frequency,
328
14
            {
329
14
                "Frequency", "mpls_y1711.frequency", FT_UINT8,
330
14
                BASE_HEX, VALS(y1711_frequency_vals), 0x0,
331
14
                "Frequency of probe injection", HFILL
332
14
            }
333
14
        },
334
14
        {
335
14
            &hf_mpls_y1711_defect_type,
336
14
            {
337
14
                "Defect Type", "mpls_y1711.defect_type", FT_UINT16,
338
14
                BASE_HEX, VALS(y1711_defect_type_vals), 0x0, NULL, HFILL
339
14
            }
340
14
        },
341
14
        {
342
14
            &hf_mpls_y1711_defect_location,
343
14
            {
344
14
                "Defect Location (AS)", "mpls_y1711.defect_location",
345
14
                FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL
346
14
            }
347
14
        },
348
14
        {
349
14
            &hf_mpls_y1711_bip16,
350
14
            {
351
14
                "BIP16", "mpls_y1711.bip16", FT_UINT16,
352
14
                BASE_HEX, NULL, 0x0, NULL, HFILL
353
14
            }
354
14
        },
355
      /* Generated from convert_proto_tree_add_text.pl */
356
14
      { &hf_mpls_y1711_lsr_id, { "LSR ID", "mpls_y1711.lsr_id", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
357
14
      { &hf_mpls_y1711_lsp_id, { "LSP ID", "mpls_y1711.lsp_id", FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
358
14
    };
359
360
14
    static int *ett[] = {
361
14
        &ett_mpls_y1711
362
14
    };
363
364
14
    static ei_register_info ei[] = {
365
        /* Generated from convert_proto_tree_add_text.pl */
366
14
        { &ei_mpls_y1711_minimum_payload, { "mpls_y1711.minimum_payload", PI_MALFORMED, PI_ERROR, "Must have a minimum payload length of 44 bytes", EXPFILL }},
367
14
        { &ei_mpls_y1711_no_OAM_alert_label, { "mpls_y1711.no_OAM_alert_label", PI_PROTOCOL, PI_WARN, "Y.1711 but no OAM alert label", EXPFILL }},
368
14
        { &ei_mpls_y1711_exp_bits_not_zero, { "mpls_y1711.exp_bits_not_0", PI_PROTOCOL, PI_WARN, "Exp bits should be 0", EXPFILL }},
369
14
        { &ei_mpls_y1711_s_bit_not_one, { "mpls_y1711.s_bit_not_1", PI_PROTOCOL, PI_WARN, "S bit should be 1", EXPFILL }},
370
14
        { &ei_mpls_y1711_ttl_not_one, { "mpls_y1711.ttl_not_1", PI_PROTOCOL, PI_WARN, "TTL should be 1", EXPFILL }},
371
14
        { &ei_mpls_y1711_reserved_not_zero, { "mpls_y1711.reserved_not_zero", PI_PROTOCOL, PI_WARN, "These bytes are reserved and must be 0x00", EXPFILL }},
372
14
        { &ei_mpls_y1711_padding_not_zero, { "mpls_y1711.padding_not_zero", PI_PROTOCOL, PI_WARN, "These bytes are padding and must be 0x00", EXPFILL }},
373
14
        { &ei_mpls_y1711_padding_not_ff, { "mpls_y1711.padding_not_ff", PI_PROTOCOL, PI_ERROR, "Error: these bytes are padding and must be 0xFF", EXPFILL }},
374
14
        { &ei_mpls_y1711_ttsi_not_preset, { "mpls_y1711.ttsi_not_preset", PI_PROTOCOL, PI_NOTE, "TTSI not preset (optional for FDI/BDI)", EXPFILL }},
375
14
        { &ei_mpls_y1711_unknown_pdu, { "mpls_y1711.unknown_pdu", PI_PROTOCOL, PI_WARN, "Unknown MPLS Y.1711 PDU", EXPFILL }},
376
14
    };
377
378
14
    expert_module_t* expert_mpls_y1711;
379
380
14
    proto_mpls_y1711 =
381
14
        proto_register_protocol("MPLS ITU-T Y.1711 OAM",
382
14
                                "MPLS ITU-T Y.1711 OAM",
383
14
                                "mpls_y1711");
384
14
    proto_register_field_array(proto_mpls_y1711, hf, array_length(hf));
385
14
    proto_register_subtree_array(ett, array_length(ett));
386
14
    expert_mpls_y1711 = expert_register_protocol(proto_mpls_y1711);
387
14
    expert_register_field_array(expert_mpls_y1711, ei, array_length(ei));
388
14
    mpls_y1711_handle = register_dissector("mpls_y1711", dissect_mpls_y1711, proto_mpls_y1711);
389
14
}
390
391
void
392
proto_reg_handoff_mpls_y1711(void)
393
14
{
394
14
    dissector_add_uint("mpls.label",
395
14
                       MPLS_LABEL_OAM_ALERT /* 14 */,
396
14
                       mpls_y1711_handle);
397
14
}
398
399
/*
400
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
401
 *
402
 * Local variables:
403
 * c-basic-offset: 4
404
 * tab-width: 8
405
 * indent-tabs-mode: nil
406
 * End:
407
 *
408
 * vi: set shiftwidth=4 tabstop=8 expandtab:
409
 * :indentSize=4:tabSize=8:noTabs=true:
410
 */