Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/dissectors/packet-elmi.c
Line
Count
Source (jump to first uncovered line)
1
/* packet-elmi.c
2
 * Routines for Ethernet Local Management Interface (E-LMI) dissection
3
 * Copyright 2014, Martin Kaiser <martin@kaiser.cx>
4
 *
5
 * based on a dissector written in lua
6
 * Copyright 2013, Werner Fischer (fischer-interactive.de)
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
/* E-LMI is defined in the MEF16 specification from Metro Ethernet Forum
16
   http://www.metroethernetforum.org/PDF_Documents/technical-specifications/MEF16.pdf */
17
18
#include "config.h"
19
20
#include <epan/packet.h>
21
#include <epan/etypes.h>
22
#include <epan/tfs.h>
23
24
static int proto_elmi;
25
26
void proto_register_elmi(void);
27
void proto_reg_handoff_elmi(void);
28
29
static dissector_handle_t elmi_handle;
30
31
static int ett_elmi;
32
static int ett_elmi_info_elem;
33
static int ett_elmi_sub_info_elem;
34
35
static int hf_elmi_ver;
36
static int hf_elmi_msg_type;
37
static int hf_elmi_info_elem;
38
static int hf_elmi_info_elem_len;
39
static int hf_elmi_report_type;
40
static int hf_elmi_snd_seq_num;
41
static int hf_elmi_rcv_seq_num;
42
static int hf_elmi_dat_inst;
43
static int hf_elmi_reserved;
44
static int hf_elmi_uni_status;
45
static int hf_elmi_evc_refid;
46
static int hf_elmi_evc_status;
47
static int hf_last_ie;
48
static int hf_map_seq;
49
static int hf_priority;
50
static int hf_default_evc;
51
static int hf_elmi_sub_info_elem;
52
static int hf_elmi_sub_info_elem_len;
53
static int hf_elmi_uni_id;
54
static int hf_elmi_evc_type;
55
static int hf_elmi_evc_id;
56
static int hf_elmi_ce_vlan_id;
57
static int hf_elmi_sub_info_color_mode_flag;
58
static int hf_elmi_sub_info_coupling_flag;
59
static int hf_elmi_sub_info_per_cos_bit;
60
static int hf_elmi_sub_cir_magnitude;
61
static int hf_elmi_sub_cir_multiplier;
62
static int hf_elmi_sub_cbs_magnitude;
63
static int hf_elmi_sub_cbs_multiplier;
64
static int hf_elmi_sub_eir_magnitude;
65
static int hf_elmi_sub_eir_multiplier;
66
static int hf_elmi_sub_ebs_magnitude;
67
static int hf_elmi_sub_ebs_multiplier;
68
static int hf_elmi_sub_user_prio_0;
69
static int hf_elmi_sub_user_prio_1;
70
static int hf_elmi_sub_user_prio_2;
71
static int hf_elmi_sub_user_prio_3;
72
static int hf_elmi_sub_user_prio_4;
73
static int hf_elmi_sub_user_prio_5;
74
static int hf_elmi_sub_user_prio_6;
75
static int hf_elmi_sub_user_prio_7;
76
77
static const value_string elmi_msg_type[] = {
78
    { 0x75, "Status enquiry" },
79
    { 0x7D, "Status" },
80
    { 0, NULL }
81
};
82
83
2
#define TAG_REPORT_TYPE 0x01
84
17
#define TAG_SEQ_NUM     0x02
85
8
#define TAG_DATA_INST   0x03
86
0
#define TAG_UNI_STATUS  0x11
87
3
#define TAG_EVC_STATUS  0x21
88
0
#define TAG_VLAN_EVC    0x22
89
90
static const value_string elmi_info_elem_tag[] = {
91
    { TAG_REPORT_TYPE, "Report type" },
92
    { TAG_SEQ_NUM,     "Sequence numbers" },
93
    { TAG_DATA_INST,   "Data instance" },
94
    { TAG_UNI_STATUS,  "UNI Status" },
95
    { TAG_EVC_STATUS,  "EVC Status" },
96
    { TAG_VLAN_EVC,    "CE-VLAN ID/EVC Map" },
97
    { 0, NULL }
98
};
99
100
static const value_string elmi_report_type[] = {
101
    { 0x00, "Full status" },
102
    { 0x01, "E-LMI check" },
103
    { 0x02, "Single EVC async status" },
104
    { 0x03, "Full status continued" },
105
    { 0, NULL }
106
};
107
108
0
#define SUB_TAG_UNI_ID  0x51
109
0
#define SUB_TAG_EVC_PRM 0x61
110
0
#define SUB_TAG_EVC_ID  0x62
111
0
#define SUB_TAG_EVC_MAP 0x63
112
0
#define SUB_TAG_BW_PRO  0x71
113
114
static const value_string elmi_sub_info_elem_tag[] = {
115
    { SUB_TAG_UNI_ID,   "UNI Identifier" },
116
    { SUB_TAG_EVC_PRM,  "EVC Parameters" },
117
    { SUB_TAG_EVC_ID,   "EVC Identifier" },
118
    { SUB_TAG_EVC_MAP,  "EVC Map Entry" },
119
    { SUB_TAG_BW_PRO,   "Bandwidth Profile" },
120
    { 0, NULL }
121
};
122
123
static const value_string elmi_vlan_id_evc_map_type[] = {
124
    { 0x01, "All to one binding" },
125
    { 0x02, "Service Multiplexing with no bundling" },
126
    { 0x03, "Bundling" },
127
    { 0, NULL }
128
};
129
130
static const value_string elmi_evc_status_type[] = {
131
    { 0x00, "Not Active" },
132
    { 0x01, "New and Not Active" },
133
    { 0x02, "Active" },
134
    { 0x03, "New and Active" },
135
    { 0x04, "Partially Active" },
136
    { 0x05, "New and Partially Active" },
137
    { 0, NULL }
138
};
139
140
static const value_string elmi_evc_type[] = {
141
    { 0x00, "Point-to-Point EVC" },
142
    { 0x01, "Multipoint-to-Multipoint EVC" },
143
    { 0, NULL }
144
};
145
146
static int
147
dissect_elmi_sub_info_elem(
148
        tvbuff_t *tvb, int offset, proto_tree *tree)
149
34
{
150
34
    int         offset_start;
151
34
    uint8_t     sub_tag, len;
152
34
    proto_item *tree_pi;
153
34
    proto_tree *sub_info_elem_tree = tree;
154
155
34
    offset_start = offset;
156
157
34
    sub_tag = tvb_get_uint8(tvb, offset);
158
34
    len = tvb_get_uint8(tvb, offset + 1);
159
160
34
    sub_info_elem_tree = proto_tree_add_subtree_format(
161
34
            tree, tvb, offset, len + 2, ett_elmi_sub_info_elem, &tree_pi,
162
34
            "Sub-information element: %s", val_to_str_const(sub_tag, elmi_sub_info_elem_tag, "unknown"));
163
164
34
    proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_info_elem, tvb, offset, 1, ENC_BIG_ENDIAN);
165
34
    offset++;
166
167
34
    proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_info_elem_len, tvb, offset, 1, ENC_BIG_ENDIAN);
168
34
    offset++;
169
170
34
    switch (sub_tag) {
171
0
        case SUB_TAG_UNI_ID:
172
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_uni_id, tvb, offset, len, ENC_ASCII);
173
0
            offset += len;
174
0
            break;
175
0
        case SUB_TAG_EVC_PRM:
176
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_evc_type, tvb, offset, 1, ENC_BIG_ENDIAN);
177
0
            offset++;
178
0
            break;
179
0
        case SUB_TAG_EVC_ID:
180
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_evc_id, tvb, offset, len, ENC_ASCII);
181
0
            offset += len;
182
0
            break;
183
0
        case SUB_TAG_EVC_MAP:
184
0
            while(offset < (offset_start + len + 2)) {
185
0
                proto_tree_add_item(sub_info_elem_tree, hf_elmi_ce_vlan_id, tvb, offset, 2, ENC_BIG_ENDIAN);
186
0
                offset += 2;
187
0
            }
188
0
            break;
189
0
        case SUB_TAG_BW_PRO:
190
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_info_color_mode_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
191
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_info_coupling_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
192
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_info_per_cos_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
193
0
            offset++;
194
195
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_cir_magnitude, tvb, offset, 1, ENC_BIG_ENDIAN);
196
0
            offset++;
197
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_cir_multiplier, tvb, offset, 2, ENC_BIG_ENDIAN);
198
0
            offset += 2;
199
200
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_cbs_magnitude, tvb, offset, 1, ENC_BIG_ENDIAN);
201
0
            offset++;
202
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_cbs_multiplier, tvb, offset, 1, ENC_BIG_ENDIAN);
203
0
            offset++;
204
205
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_eir_magnitude, tvb, offset, 1, ENC_BIG_ENDIAN);
206
0
            offset++;
207
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_eir_multiplier, tvb, offset, 2, ENC_BIG_ENDIAN);
208
0
            offset += 2;
209
210
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_ebs_magnitude, tvb, offset, 1, ENC_BIG_ENDIAN);
211
0
            offset++;
212
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_ebs_multiplier, tvb, offset, 1, ENC_BIG_ENDIAN);
213
0
            offset++;
214
215
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_user_prio_0, tvb, offset, 1, ENC_BIG_ENDIAN);
216
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_user_prio_1, tvb, offset, 1, ENC_BIG_ENDIAN);
217
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_user_prio_2, tvb, offset, 1, ENC_BIG_ENDIAN);
218
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_user_prio_3, tvb, offset, 1, ENC_BIG_ENDIAN);
219
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_user_prio_4, tvb, offset, 1, ENC_BIG_ENDIAN);
220
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_user_prio_5, tvb, offset, 1, ENC_BIG_ENDIAN);
221
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_user_prio_6, tvb, offset, 1, ENC_BIG_ENDIAN);
222
0
            proto_tree_add_item(sub_info_elem_tree, hf_elmi_sub_user_prio_7, tvb, offset, 1, ENC_BIG_ENDIAN);
223
224
0
            offset ++;
225
0
            break;
226
34
        default:
227
34
            offset += len;
228
34
            break;
229
34
    }
230
231
34
    proto_item_set_len(tree_pi, offset-offset_start);
232
34
    return offset-offset_start;
233
234
34
}
235
236
static int
237
dissect_elmi_info_elem(
238
        tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
239
85
{
240
85
    int         offset_start;
241
85
    uint8_t     tag, len, ret;
242
85
    proto_item *tree_pi;
243
85
    proto_tree *info_elem_tree;
244
245
85
    offset_start = offset;
246
247
85
    tag = tvb_get_uint8(tvb, offset);
248
85
    if (tag==0)
249
5
        return -1;
250
251
80
    info_elem_tree = proto_tree_add_subtree_format(
252
80
            tree, tvb, offset, -1, ett_elmi_info_elem, &tree_pi,
253
80
            "Information element: %s", val_to_str_const(tag, elmi_info_elem_tag, "unknown"));
254
255
80
    proto_tree_add_item(info_elem_tree, hf_elmi_info_elem,
256
80
            tvb, offset, 1, ENC_BIG_ENDIAN);
257
80
    offset++;
258
259
80
    len = tvb_get_uint8(tvb, offset);
260
80
    proto_tree_add_item(info_elem_tree, hf_elmi_info_elem_len,
261
80
            tvb, offset, 1, ENC_BIG_ENDIAN);
262
80
    offset++;
263
264
80
    switch (tag) {
265
2
        case TAG_REPORT_TYPE:
266
2
            proto_tree_add_item(info_elem_tree, hf_elmi_report_type,
267
2
                    tvb, offset, 1, ENC_BIG_ENDIAN);
268
2
            offset++;
269
2
            break;
270
17
        case TAG_SEQ_NUM:
271
17
            proto_tree_add_item(info_elem_tree, hf_elmi_snd_seq_num,
272
17
                    tvb, offset, 1, ENC_BIG_ENDIAN);
273
17
            offset++;
274
17
            proto_tree_add_item(info_elem_tree, hf_elmi_rcv_seq_num,
275
17
                    tvb, offset, 1, ENC_BIG_ENDIAN);
276
17
            offset++;
277
17
            break;
278
8
        case TAG_DATA_INST:
279
8
            proto_tree_add_item(info_elem_tree, hf_elmi_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
280
8
            offset++;
281
8
            proto_tree_add_item(info_elem_tree, hf_elmi_dat_inst,
282
8
                    tvb, offset, 4, ENC_BIG_ENDIAN);
283
8
            offset+=4;
284
8
            break;
285
0
        case TAG_UNI_STATUS:
286
0
            proto_tree_add_item(info_elem_tree, hf_elmi_uni_status, tvb, offset, 1, ENC_BIG_ENDIAN);
287
0
            offset++;
288
289
0
            while(offset < (offset_start + len + 2)) {
290
0
                ret = dissect_elmi_sub_info_elem(tvb, offset, info_elem_tree);
291
0
                if (ret<=0)
292
0
                    break;
293
0
                offset += ret;
294
0
            }
295
0
            break;
296
3
        case TAG_EVC_STATUS:
297
3
            proto_tree_add_item(info_elem_tree, hf_elmi_evc_refid, tvb, offset, 2, ENC_BIG_ENDIAN);
298
3
            offset+=2;
299
3
            proto_tree_add_item(info_elem_tree, hf_elmi_evc_status, tvb, offset, 1, ENC_BIG_ENDIAN);
300
3
            offset++;
301
302
37
            while(offset < (offset_start + len + 2)) {
303
34
                ret = dissect_elmi_sub_info_elem(tvb, offset, info_elem_tree);
304
34
                if (ret<=0)
305
0
                    break;
306
34
                offset += ret;
307
34
            }
308
3
            break;
309
0
        case TAG_VLAN_EVC:
310
0
            proto_tree_add_item(info_elem_tree, hf_elmi_evc_refid, tvb, offset, 2, ENC_BIG_ENDIAN);
311
0
            offset+=2;
312
0
            proto_tree_add_item(info_elem_tree, hf_last_ie, tvb, offset, 1, ENC_BIG_ENDIAN);
313
0
            proto_tree_add_item(info_elem_tree, hf_map_seq, tvb, offset, 1, ENC_BIG_ENDIAN);
314
0
            offset++;
315
0
            proto_tree_add_item(info_elem_tree, hf_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
316
0
            proto_tree_add_item(info_elem_tree, hf_default_evc, tvb, offset, 1, ENC_BIG_ENDIAN);
317
0
            offset++;
318
319
0
            while(offset < (offset_start + len + 2)) {
320
0
                ret = dissect_elmi_sub_info_elem(tvb, offset, info_elem_tree);
321
0
                if (ret<=0)
322
0
                    break;
323
0
                offset += ret;
324
0
            }
325
0
            break;
326
50
        default:
327
50
            offset += len;
328
50
            break;
329
80
    }
330
331
80
    proto_item_set_len(tree_pi, offset-offset_start);
332
80
    return offset-offset_start;
333
80
}
334
335
336
static int
337
dissect_elmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
338
21
{
339
21
    proto_item *pi;
340
21
    proto_tree *elmi_tree;
341
21
    int         offset=0;
342
21
    uint8_t     msg_type;
343
21
    int         ret;
344
345
21
    col_clear(pinfo->cinfo, COL_INFO);
346
21
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "E-LMI");
347
348
21
    pi = proto_tree_add_protocol_format(tree, proto_elmi,
349
21
            tvb, 0, tvb_captured_length(tvb),
350
21
            "Ethernet Local Management Interface (E-LMI)");
351
21
    elmi_tree = proto_item_add_subtree(pi, ett_elmi);
352
353
21
    proto_tree_add_item(elmi_tree, hf_elmi_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
354
21
    offset++;
355
356
21
    msg_type = tvb_get_uint8(tvb, offset);
357
21
    proto_tree_add_item(elmi_tree, hf_elmi_msg_type,
358
21
            tvb, offset, 1, ENC_BIG_ENDIAN);
359
21
    col_append_str(pinfo->cinfo, COL_INFO,
360
21
            val_to_str(msg_type, elmi_msg_type, "unknown (0x%x)"));
361
21
    offset++;
362
363
101
    while (tvb_reported_length_remaining(tvb, offset) > 0) {
364
85
        ret = dissect_elmi_info_elem(tvb, offset, pinfo, elmi_tree);
365
85
        if (ret<=0)
366
5
            break;
367
80
        offset += ret;
368
80
    }
369
370
    /* XXX - can we make the eth dissector handle our (standard) padding
371
     * and FCS? */
372
21
    return tvb_captured_length(tvb);
373
21
}
374
375
376
void
377
proto_register_elmi(void)
378
14
{
379
14
    static hf_register_info hf[] = {
380
14
        { &hf_elmi_ver,
381
14
            { "Version", "elmi.version", FT_UINT8, BASE_DEC,
382
14
                NULL, 0, NULL, HFILL } },
383
14
        { &hf_elmi_msg_type,
384
14
            { "Message type", "elmi.message_type", FT_UINT8, BASE_HEX,
385
14
                VALS(elmi_msg_type), 0, NULL, HFILL } },
386
14
        { &hf_elmi_info_elem,
387
14
            { "Tag", "elmi.info_element.tag", FT_UINT8, BASE_HEX,
388
14
                VALS(elmi_info_elem_tag), 0, NULL, HFILL } },
389
14
        { &hf_elmi_info_elem_len,
390
14
            { "Length", "elmi.info_element.length", FT_UINT8, BASE_DEC,
391
14
                NULL, 0, NULL, HFILL } },
392
14
        { &hf_elmi_report_type,
393
14
            { "Report type", "elmi.report_type", FT_UINT8, BASE_DEC,
394
14
                VALS(elmi_report_type), 0, NULL, HFILL } },
395
14
        { &hf_elmi_snd_seq_num,
396
14
            { "Send sequence number", "elmi.snd_seq_num", FT_UINT8, BASE_DEC,
397
14
                NULL, 0, NULL, HFILL } },
398
14
        { &hf_elmi_rcv_seq_num,
399
14
            { "Receive sequence number", "elmi.rcv_seq_num", FT_UINT8, BASE_DEC,
400
14
                NULL, 0, NULL, HFILL } },
401
14
        { &hf_elmi_dat_inst,
402
14
            { "Data instance", "elmi.data_instance", FT_UINT32, BASE_HEX,
403
14
                NULL, 0, NULL, HFILL } },
404
14
        { &hf_elmi_reserved,
405
14
            { "Reserved", "elmi.reserved", FT_UINT8, BASE_HEX,
406
14
                NULL, 0, NULL, HFILL } },
407
14
        { &hf_elmi_uni_status,
408
14
            { "CE-VLAN ID/EVC Map Type", "elmi.map_type", FT_UINT8, BASE_HEX,
409
14
                VALS(elmi_vlan_id_evc_map_type), 0, NULL, HFILL } },
410
14
        { &hf_elmi_evc_refid,
411
14
            { "EVC Reference Id", "elmi.evc.refid", FT_UINT16, BASE_DEC,
412
14
                NULL, 0, NULL, HFILL } },
413
14
        { &hf_elmi_evc_status,
414
14
            { "EVC Status Type", "elmi.evc.status", FT_UINT8, BASE_HEX,
415
14
                VALS(elmi_evc_status_type), 0x7, NULL, HFILL } },
416
14
        { &hf_last_ie,
417
14
            { "Last Information Element", "elmi.map.last_ie", FT_BOOLEAN, 8,
418
14
                TFS(&tfs_yes_no), 0x40, NULL, HFILL } },
419
14
        { &hf_map_seq,
420
14
            { "CE-VLAN ID/EVC Map Sequence", "elmi.map.seq", FT_UINT8, BASE_DEC,
421
14
                NULL, 0x3F, NULL, HFILL } },
422
14
        { &hf_priority,
423
14
            { "Priority Tagged", "elmi.map.priority", FT_BOOLEAN, 8,
424
14
                TFS(&tfs_yes_no), 0x2, NULL, HFILL } },
425
14
        { &hf_default_evc,
426
14
            { "Default EVC", "elmi.map.evc", FT_BOOLEAN, 8,
427
14
                TFS(&tfs_set_notset), 0x1, NULL, HFILL } },
428
14
        { &hf_elmi_sub_info_elem,
429
14
            { "Sub-Info Element", "elmi.sub_info.tag", FT_UINT8, BASE_HEX,
430
14
                VALS(elmi_sub_info_elem_tag), 0, NULL, HFILL } },
431
14
        { &hf_elmi_sub_info_elem_len,
432
14
            { "Sub-Info Length", "elmi.sub_info.len", FT_UINT8, BASE_DEC,
433
14
                NULL, 0, NULL, HFILL } },
434
14
        { &hf_elmi_uni_id,
435
14
            { "UNI Identifier", "elmi.sub_info.uni_id", FT_STRING, BASE_NONE,
436
14
                NULL, 0, NULL, HFILL } },
437
14
        { &hf_elmi_evc_type,
438
14
            { "EVC Type", "elmi.sub_info.evc_type", FT_UINT8, BASE_DEC,
439
14
                VALS(elmi_evc_type), 0x7, NULL, HFILL } },
440
14
        { &hf_elmi_evc_id,
441
14
            { "EVC Identifier", "elmi.sub_info.evc_id", FT_STRING, BASE_NONE,
442
14
                NULL, 0, NULL, HFILL } },
443
14
        { &hf_elmi_ce_vlan_id,
444
14
            { "CE-VLAN ID", "elmi.sub_info.vlan_id", FT_UINT16, BASE_DEC,
445
14
                NULL, 0, NULL, HFILL } },
446
14
        { &hf_elmi_sub_info_color_mode_flag,
447
14
            { "Color Mode Flag", "elmi.sub_info.color_mode_flag", FT_BOOLEAN, 8,
448
14
                TFS(&tfs_set_notset), 0x4, NULL, HFILL } },
449
14
        { &hf_elmi_sub_info_coupling_flag,
450
14
            { "Coupling Flag", "elmi.sub_info.coupling_flag", FT_BOOLEAN, 8,
451
14
                TFS(&tfs_set_notset), 0x2, NULL, HFILL } },
452
14
        { &hf_elmi_sub_info_per_cos_bit,
453
14
            { "Per CoS bit values", "elmi.sub_info.per_cos_bit", FT_BOOLEAN, 8,
454
14
                TFS(&tfs_used_notused), 0x1, NULL, HFILL } },
455
14
        { &hf_elmi_sub_cir_magnitude,
456
14
            { "CIR Magnitude", "elmi.sub_info.cir_mag", FT_UINT8, BASE_DEC,
457
14
                NULL, 0, NULL, HFILL } },
458
14
        { &hf_elmi_sub_cir_multiplier,
459
14
            { "CIR Multiplier", "elmi.sub_info.cir_mult", FT_UINT16, BASE_DEC,
460
14
                NULL, 0, NULL, HFILL } },
461
14
        { &hf_elmi_sub_cbs_magnitude,
462
14
            { "CBS Magnitude", "elmi.sub_info.cbs_mag", FT_UINT8, BASE_DEC,
463
14
                NULL, 0, NULL, HFILL } },
464
14
        { &hf_elmi_sub_cbs_multiplier,
465
14
            { "CBS Multiplier", "elmi.sub_info.cbs_mult", FT_UINT8, BASE_DEC,
466
14
                NULL, 0, NULL, HFILL } },
467
14
        { &hf_elmi_sub_eir_magnitude,
468
14
            { "EIR Magnitude", "elmi.sub_info.eir_mag", FT_UINT8, BASE_DEC,
469
14
                NULL, 0, NULL, HFILL } },
470
14
        { &hf_elmi_sub_eir_multiplier,
471
14
            { "EIR Multiplier", "elmi.sub_info.eir_mult", FT_UINT16, BASE_DEC,
472
14
                NULL, 0, NULL, HFILL } },
473
14
        { &hf_elmi_sub_ebs_magnitude,
474
14
            { "EBS Magnitude", "elmi.sub_info.ebs_mag", FT_UINT8, BASE_DEC,
475
14
                NULL, 0, NULL, HFILL } },
476
14
        { &hf_elmi_sub_ebs_multiplier,
477
14
            { "EBS Multiplier", "elmi.sub_info.ebs_mult", FT_UINT8, BASE_DEC,
478
14
                NULL, 0, NULL, HFILL } },
479
14
        { &hf_elmi_sub_user_prio_0,
480
14
            { "User Priority 0", "elmi.sub_info.bw_prio0", FT_BOOLEAN, 8,
481
14
                TFS(&tfs_applicable_not_applicable), 0x1, NULL, HFILL } },
482
14
        { &hf_elmi_sub_user_prio_1,
483
14
            { "User Priority 1", "elmi.sub_info.bw_prio1", FT_BOOLEAN, 8,
484
14
                TFS(&tfs_applicable_not_applicable), 0x2, NULL, HFILL } },
485
14
        { &hf_elmi_sub_user_prio_2,
486
14
            { "User Priority 2", "elmi.sub_info.bw_prio2", FT_BOOLEAN, 8,
487
14
                TFS(&tfs_applicable_not_applicable), 0x4, NULL, HFILL } },
488
14
        { &hf_elmi_sub_user_prio_3,
489
14
            { "User Priority 3", "elmi.sub_info.bw_prio3", FT_BOOLEAN, 8,
490
14
                TFS(&tfs_applicable_not_applicable), 0x8, NULL, HFILL } },
491
14
        { &hf_elmi_sub_user_prio_4,
492
14
            { "User Priority 4", "elmi.sub_info.bw_prio4", FT_BOOLEAN, 8,
493
14
                TFS(&tfs_applicable_not_applicable), 0x10, NULL, HFILL } },
494
14
        { &hf_elmi_sub_user_prio_5,
495
14
            { "User Priority 5", "elmi.sub_info.bw_prio5", FT_BOOLEAN, 8,
496
14
                TFS(&tfs_applicable_not_applicable), 0x20, NULL, HFILL } },
497
14
        { &hf_elmi_sub_user_prio_6,
498
14
            { "User Priority 6", "elmi.sub_info.bw_prio6", FT_BOOLEAN, 8,
499
14
                TFS(&tfs_applicable_not_applicable), 0x40, NULL, HFILL } },
500
14
        { &hf_elmi_sub_user_prio_7,
501
14
            { "User Priority 7", "elmi.sub_info.bw_prio7", FT_BOOLEAN, 8,
502
14
                TFS(&tfs_applicable_not_applicable), 0x80, NULL, HFILL } },
503
14
    };
504
505
14
    static int *ett[] = {
506
14
        &ett_elmi,
507
14
        &ett_elmi_info_elem,
508
14
        &ett_elmi_sub_info_elem
509
14
    };
510
511
512
14
    proto_elmi = proto_register_protocol("Ethernet Local Management Interface", "E-LMI", "elmi");
513
514
14
    proto_register_field_array(proto_elmi, hf, array_length(hf));
515
14
    proto_register_subtree_array(ett, array_length(ett));
516
517
14
    elmi_handle = register_dissector("elmi", dissect_elmi, proto_elmi);
518
14
}
519
520
521
void
522
proto_reg_handoff_elmi(void)
523
14
{
524
14
    dissector_add_uint("ethertype", ETHERTYPE_ELMI, elmi_handle);
525
14
}
526
527
/*
528
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
529
 *
530
 * Local variables:
531
 * c-basic-offset: 4
532
 * tab-width: 8
533
 * indent-tabs-mode: nil
534
 * End:
535
 *
536
 * vi: set shiftwidth=4 tabstop=8 expandtab:
537
 * :indentSize=4:tabSize=8:noTabs=true:
538
 */