Coverage Report

Created: 2026-07-12 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-cisco-erspan.c
Line
Count
Source
1
/* packet-cisco-erspan.c
2
 * Routines for the disassembly of Cisco's ERSPAN protocol
3
 *
4
 * Copyright 2005 Joerg Mayer (see AUTHORS file)
5
 * Updates for newer versions by Jason Masker <jason at masker.net>
6
 * Updates to support ERSPAN3 by Peter Membrey <peter@membrey.hk>
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
 * Protocol Spec:
15
 *   https://tools.ietf.org/html/draft-foschiano-erspan-03
16
 *
17
 * For ERSPAN packets, the "protocol type" field value in the GRE header
18
 * is 0x88BE (types I and II) or 0x22EB (type III).
19
 *
20
 * For 0x88BE, if the GRE header doesn't have the "sequence number present"
21
 * flag set, it's type I, with no ERSPAN header, otherwise it has an
22
 * ERSPAN header (it's supposed to be type II, but we look at the version
23
 * in the ERSPAN header; should we report an error if it's not version 1?).
24
 *
25
 * For 0x22EB, it always has an ERSPAN header (it's supposed to be type III,
26
 * but we look at the version in the ERSPAN header; should we report an
27
 * error if it's not version 2?).
28
 */
29
30
#include "config.h"
31
32
#include <epan/packet.h>
33
#include <epan/expert.h>
34
#include <epan/tfs.h>
35
#include "packet-gre.h"
36
37
void proto_register_erspan(void);
38
void proto_reg_handoff_erspan(void);
39
40
static int proto_erspan;
41
42
static int ett_erspan;
43
44
static int hf_erspan_version;
45
static int hf_erspan_vlan;
46
static int hf_erspan_cos;
47
static int hf_erspan_encap;
48
static int hf_erspan_truncated;
49
static int hf_erspan_spanid;
50
static int hf_erspan_reserved;
51
static int hf_erspan_index;
52
static int hf_erspan_timestamp;
53
static int hf_erspan_direction;
54
55
static int hf_erspan_bso;
56
static int hf_erspan_sgt;
57
static int hf_erspan_p;
58
static int hf_erspan_ft;
59
static int hf_erspan_hw;
60
static int hf_erspan_gra;
61
static int hf_erspan_o;
62
63
/* Optional Sub-header */
64
static int hf_erspan_platid;
65
/* Platform ID = 1 */
66
static int hf_erspan_pid1_rsvd1;
67
static int hf_erspan_pid1_domain_id;
68
static int hf_erspan_pid1_port_index;
69
/* Platform ID = 3 */
70
static int hf_erspan_pid3_rsvd1;
71
static int hf_erspan_pid3_port_index;
72
static int hf_erspan_pid3_timestamp;
73
/* Platform ID = 4 */
74
static int hf_erspan_pid4_rsvd1;
75
static int hf_erspan_pid4_rsvd2;
76
static int hf_erspan_pid4_rsvd3;
77
/* Platform ID = 5 or 6 */
78
static int hf_erspan_pid5_switchid;
79
static int hf_erspan_pid5_port_index;
80
static int hf_erspan_pid5_timestamp;
81
/* Platform ID = 7 (or 0) */
82
static int hf_erspan_pid7_rsvd1;
83
static int hf_erspan_pid7_source_index;
84
static int hf_erspan_pid7_timestamp;
85
/* ID: 0x0, 0x2, 0x8-0x63 are reserved. */
86
static int hf_erspan_pid_rsvd;
87
88
static expert_field ei_erspan_version_unknown;
89
90
static const true_false_string tfs_direction = { "Egress", "Ingress" };
91
92
#define ERSPAN_ENCAP_00 0
93
#define ERSPAN_ENCAP_01 1
94
#define ERSPAN_ENCAP_10 2
95
0
#define ERSPAN_ENCAP_11 3
96
static const value_string erspan_encap_vals[] = {
97
  {ERSPAN_ENCAP_00, "Originally without VLAN tag"},
98
  {ERSPAN_ENCAP_01, "Originally ISL encapsulated"},
99
  {ERSPAN_ENCAP_10, "Originally 802.1Q encapsulated"},
100
  {ERSPAN_ENCAP_11, "VLAN tag preserved in frame"},
101
102
  {0, NULL}
103
};
104
105
static const value_string erspan_bso_vals[] = {
106
  {0, "Good or unknown integrity"},
107
  {1, "Short frame"},
108
  {2, "Oversized frame"},
109
  {3, "CRC or alignment error"},
110
111
  {0, NULL},
112
};
113
114
static const value_string erspan_truncated_vals[] = {
115
  {0, "Not truncated"},
116
  {1, "Truncated"},
117
118
  {0, NULL},
119
};
120
121
2
#define ERSPAN_FT_ETHERNET  0
122
#define ERSPAN_FT_IP    2
123
124
static const value_string erspan_ft_vals[] = {
125
  {ERSPAN_FT_ETHERNET, "Ethernet"},
126
  {ERSPAN_FT_IP, "IP"},
127
128
  {0, NULL},
129
};
130
131
static const value_string erspan_version_vals[] = {
132
  {1, "Type II"},
133
  {2, "Type III"},
134
135
  {0, NULL},
136
};
137
138
static const value_string erspan_granularity_vals[] = {
139
  {0, "100 microseconds"},
140
  {1, "100 nanoseconds"},
141
  {2, "IEEE 1588"},
142
  {3, "Custom granularity"},
143
144
  {0, NULL}
145
};
146
147
static dissector_handle_t ethnofcs_handle;
148
149
static int
150
dissect_erspan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
151
1
{
152
1
  proto_item *ti;
153
1
  proto_tree *erspan_tree = NULL;
154
1
  tvbuff_t *frame_tvb;
155
1
  uint32_t offset = 0;
156
1
  uint32_t version;
157
1
  uint32_t frame_type = ERSPAN_FT_ETHERNET;
158
159
1
  ti = proto_tree_add_item(tree, proto_erspan, tvb, offset, -1,
160
1
      ENC_NA);
161
1
  erspan_tree = proto_item_add_subtree(ti, ett_erspan);
162
163
1
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "ERSPAN");
164
1
  col_set_str(pinfo->cinfo, COL_INFO, "ERSPAN:");
165
166
  /*
167
   * Dissect the version field, which is present in all versions
168
   * of the header.
169
   */
170
1
  proto_tree_add_item_ret_uint(erspan_tree, hf_erspan_version, tvb,
171
1
    offset, 2, ENC_BIG_ENDIAN, &version);
172
173
  /* Put the version in the header. */
174
1
  proto_item_append_text(ti, " %s", val_to_str_const(version, erspan_version_vals, "Unknown"));
175
176
  /*
177
   * Now dissect the rest of the header, based on the version.
178
   */
179
1
  switch (version) {
180
0
  case 1: {
181
0
    uint32_t vlan, vlan_encap;
182
183
0
    proto_tree_add_item_ret_uint(erspan_tree, hf_erspan_vlan, tvb, offset, 2,
184
0
      ENC_BIG_ENDIAN, &vlan);
185
0
    offset += 2;
186
187
0
    proto_tree_add_item(erspan_tree, hf_erspan_cos, tvb, offset, 2,
188
0
      ENC_BIG_ENDIAN);
189
0
    proto_tree_add_item_ret_uint(erspan_tree, hf_erspan_encap, tvb,
190
0
      offset, 2, ENC_BIG_ENDIAN, &vlan_encap);
191
0
    if (pinfo->vlan_id == 0 && vlan_encap != ERSPAN_ENCAP_11) {
192
0
      pinfo->vlan_id = vlan;
193
0
    }
194
0
    proto_tree_add_item(erspan_tree, hf_erspan_truncated, tvb, offset, 2,
195
0
      ENC_BIG_ENDIAN);
196
0
    proto_tree_add_item(erspan_tree, hf_erspan_spanid, tvb, offset, 2,
197
0
      ENC_BIG_ENDIAN);
198
0
    offset += 2;
199
200
0
    proto_tree_add_item(erspan_tree, hf_erspan_reserved, tvb,
201
0
      offset, 4, ENC_BIG_ENDIAN);
202
0
    proto_tree_add_item(erspan_tree, hf_erspan_index, tvb,
203
0
      offset, 4, ENC_BIG_ENDIAN);
204
0
    offset += 4;
205
0
    break;
206
0
    }
207
1
  case 2: {
208
1
    uint32_t subheader = 0;
209
1
    uint32_t vlan;
210
211
1
    proto_tree_add_item_ret_uint(erspan_tree, hf_erspan_vlan, tvb, offset, 2,
212
1
      ENC_BIG_ENDIAN, &vlan);
213
1
    pinfo->vlan_id = vlan;
214
1
    offset += 2;
215
216
1
    proto_tree_add_item(erspan_tree, hf_erspan_cos, tvb, offset, 2,
217
1
      ENC_BIG_ENDIAN);
218
1
    proto_tree_add_item(erspan_tree, hf_erspan_bso, tvb, offset, 2,
219
1
      ENC_BIG_ENDIAN);
220
1
    proto_tree_add_item(erspan_tree, hf_erspan_truncated, tvb, offset, 2,
221
1
      ENC_BIG_ENDIAN);
222
1
    proto_tree_add_item(erspan_tree, hf_erspan_spanid, tvb, offset, 2,
223
1
      ENC_BIG_ENDIAN);
224
1
    offset += 2;
225
226
1
    proto_tree_add_item(erspan_tree, hf_erspan_timestamp, tvb,
227
1
      offset, 4, ENC_BIG_ENDIAN);
228
1
    offset += 4;
229
230
1
    proto_tree_add_item(erspan_tree, hf_erspan_sgt, tvb,
231
1
      offset, 2, ENC_BIG_ENDIAN);
232
1
    offset += 2;
233
234
1
    proto_tree_add_item(erspan_tree, hf_erspan_p, tvb,
235
1
      offset, 2, ENC_BIG_ENDIAN);
236
237
1
    proto_tree_add_item_ret_uint(erspan_tree, hf_erspan_ft, tvb,
238
1
      offset, 2, ENC_BIG_ENDIAN, &frame_type);
239
240
1
    proto_tree_add_item(erspan_tree, hf_erspan_hw, tvb,
241
1
      offset, 2, ENC_BIG_ENDIAN);
242
243
1
    proto_tree_add_item(erspan_tree, hf_erspan_direction, tvb,
244
1
      offset, 2, ENC_BIG_ENDIAN);
245
246
1
    proto_tree_add_item(erspan_tree, hf_erspan_gra, tvb,
247
1
      offset, 2, ENC_BIG_ENDIAN);
248
249
1
    proto_tree_add_item_ret_uint(erspan_tree, hf_erspan_o, tvb,
250
1
      offset, 2, ENC_BIG_ENDIAN, &subheader);
251
1
    offset += 2;
252
253
    /* Platform Specific SubHeader, 8 octets, optional */
254
1
    if (subheader) {
255
0
      int32_t platform_id = tvb_get_ntohl(tvb, offset) >> 26;
256
257
0
      proto_tree_add_item(erspan_tree, hf_erspan_platid, tvb,
258
0
          offset, 4, ENC_BIG_ENDIAN);
259
260
0
      switch (platform_id) {
261
0
        case 1:
262
0
          proto_tree_add_item(erspan_tree, hf_erspan_pid1_rsvd1,
263
0
            tvb, offset, 4, ENC_BIG_ENDIAN);
264
0
          proto_tree_add_item(erspan_tree, hf_erspan_pid1_domain_id,
265
0
            tvb, offset, 4, ENC_BIG_ENDIAN);
266
0
          offset += 4;
267
268
0
          proto_tree_add_item(erspan_tree, hf_erspan_pid1_port_index,
269
0
            tvb, offset, 4, ENC_BIG_ENDIAN);
270
0
          offset += 4;
271
0
          break;
272
273
0
        case 3:
274
0
          proto_tree_add_item(erspan_tree, hf_erspan_pid3_rsvd1,
275
0
            tvb, offset, 4, ENC_BIG_ENDIAN);
276
0
          proto_tree_add_item(erspan_tree, hf_erspan_pid3_port_index,
277
0
            tvb, offset, 4, ENC_BIG_ENDIAN);
278
0
          offset += 4;
279
280
0
          proto_tree_add_item(erspan_tree, hf_erspan_pid3_timestamp,
281
0
            tvb, offset, 4, ENC_BIG_ENDIAN);
282
0
          offset += 4;
283
0
          break;
284
285
0
        case 4:
286
0
          proto_tree_add_item(erspan_tree, hf_erspan_pid4_rsvd1, tvb,
287
0
            offset, 4, ENC_BIG_ENDIAN);
288
0
          proto_tree_add_item(erspan_tree, hf_erspan_pid4_rsvd2, tvb,
289
0
            offset, 4, ENC_BIG_ENDIAN);
290
0
          offset += 4;
291
292
0
          proto_tree_add_item(erspan_tree, hf_erspan_pid4_rsvd3, tvb,
293
0
            offset, 4, ENC_BIG_ENDIAN);
294
0
          offset += 4;
295
0
          break;
296
297
0
        case 5:
298
0
        case 6:
299
0
          proto_tree_add_item(erspan_tree, hf_erspan_pid5_switchid,
300
0
            tvb, offset, 4, ENC_BIG_ENDIAN);
301
0
          proto_tree_add_item(erspan_tree, hf_erspan_pid5_port_index,
302
0
            tvb, offset, 4, ENC_BIG_ENDIAN);
303
0
          offset += 4;
304
305
0
          proto_tree_add_item(erspan_tree, hf_erspan_pid5_timestamp,
306
0
            tvb, offset, 4, ENC_BIG_ENDIAN);
307
0
          offset += 4;
308
0
          break;
309
310
0
        case 7:
311
0
        case 0: /* In some implementations it is used as an alias to 0x07. */
312
0
          proto_tree_add_item(erspan_tree, hf_erspan_pid7_rsvd1,
313
0
            tvb, offset, 4, ENC_BIG_ENDIAN);
314
0
          proto_tree_add_item(erspan_tree, hf_erspan_pid7_source_index,
315
0
            tvb, offset, 4, ENC_BIG_ENDIAN);
316
0
          offset += 4;
317
318
0
          proto_tree_add_item(erspan_tree, hf_erspan_pid7_timestamp,
319
0
            tvb, offset, 4, ENC_BIG_ENDIAN);
320
0
          offset += 4;
321
0
          break;
322
0
        default:
323
          /* ID: 0x0, 0x2, 0x8-0x63 are reserved. */
324
0
          proto_tree_add_item(erspan_tree, hf_erspan_pid_rsvd,
325
0
            tvb, offset, 8, ENC_BIG_ENDIAN);
326
0
          offset += 8;
327
0
          break;
328
329
0
      }
330
0
    }
331
1
    break;
332
1
    }
333
1
  default: {
334
0
    proto_item *ti_ver;
335
336
0
    ti_ver = proto_tree_add_item(erspan_tree, hf_erspan_version, tvb, offset, 2,
337
0
      ENC_BIG_ENDIAN);
338
0
    expert_add_info(pinfo, ti_ver, &ei_erspan_version_unknown);
339
0
    return 2;
340
1
    }
341
1
  }
342
343
1
  frame_tvb = tvb_new_subset_remaining(tvb, offset);
344
1
  switch (frame_type) {
345
346
1
  case ERSPAN_FT_ETHERNET:
347
1
    call_dissector(ethnofcs_handle, frame_tvb, pinfo, tree);
348
1
    break;
349
350
0
  default:
351
0
    call_data_dissector(frame_tvb, pinfo, tree);
352
0
    break;
353
1
  }
354
1
  return tvb_captured_length(tvb);
355
1
}
356
357
static int
358
dissect_erspan_88BE(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
359
1
{
360
1
  bool has_erspan_header;
361
362
  /*
363
   * Frames with a GRE type of 0x88BE have an ERSPAN header iff
364
   * the "sequence number present" flag is set in the GRE header.
365
   */
366
1
  if (data == NULL) {
367
    /*
368
     * We weren't handed the GRE flags or version.
369
     *
370
     * This can happen if a Linux cooked capture is done and
371
     * we get a packet from an "ipgre" interface.
372
     *
373
     * For now, we just assume this is Type I, with no
374
     * header.
375
     */
376
0
    has_erspan_header = false;
377
1
  } else {
378
1
    gre_hdr_info_t *gre_hdr_info = (gre_hdr_info_t *)data;
379
380
1
    if (gre_hdr_info->flags_and_ver & GRE_SEQUENCE) {
381
      /*
382
       * "sequence number present" set, so it has a
383
       * header.
384
       */
385
1
      has_erspan_header = true;
386
1
    } else {
387
      /*
388
       * Not present, so no header.
389
       */
390
0
      has_erspan_header = false;
391
0
    }
392
1
  }
393
394
1
  if (has_erspan_header) {
395
    /*
396
     * We have a header, so dissect it, and then handle
397
     * the payload.
398
     */
399
1
    return dissect_erspan(tvb, pinfo, tree, data);
400
1
  } else {
401
    /*
402
     * No header, so just hand the payload off to the
403
     * Ethernet dissector.  Put in a placeholder for
404
     * ERSPAN.
405
     */
406
0
    proto_item *ti;
407
408
0
    ti = proto_tree_add_item(tree, proto_erspan, tvb, 0, 0,
409
0
        ENC_NA);
410
0
    proto_item_append_text(ti, " Type I");
411
412
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "ERSPAN");
413
0
    col_set_str(pinfo->cinfo, COL_INFO, "ERSPAN:");
414
415
0
    call_dissector(ethnofcs_handle, tvb, pinfo, tree);
416
0
    return tvb_captured_length(tvb);
417
0
  }
418
1
}
419
420
static int
421
dissect_erspan_22EB(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
422
0
{
423
  /*
424
   * Frames with a GRE type of 0x22EB always have an ERSPAN
425
   * header.
426
   */
427
0
  return dissect_erspan(tvb, pinfo, tree, data);
428
0
}
429
430
void
431
proto_register_erspan(void)
432
15
{
433
15
  expert_module_t* expert_erspan;
434
435
15
  static hf_register_info hf[] = {
436
437
15
    { &hf_erspan_version,
438
15
    { "Version",  "erspan.version", FT_UINT16, BASE_DEC, VALS(erspan_version_vals),
439
15
      0xf000, NULL, HFILL }},
440
441
15
    { &hf_erspan_vlan,
442
15
    { "Vlan", "erspan.vlan", FT_UINT16, BASE_DEC, NULL,
443
15
      0x0fff, NULL, HFILL }},
444
445
15
    { &hf_erspan_cos,
446
15
    { "COS",  "erspan.cos", FT_UINT16, BASE_DEC, NULL,
447
15
      0xe000, NULL, HFILL }},
448
449
15
    { &hf_erspan_encap,
450
15
    { "Encap",  "erspan.encap", FT_UINT16, BASE_DEC, VALS(erspan_encap_vals),
451
15
      0x1800, NULL, HFILL }},
452
453
15
    { &hf_erspan_bso,
454
15
    { "Bad/Short/Oversized",  "erspan.bso", FT_UINT16, BASE_DEC, VALS(erspan_bso_vals),
455
15
      0x1800, NULL, HFILL }},
456
457
458
15
    { &hf_erspan_truncated,
459
15
    { "Truncated",  "erspan.truncated", FT_UINT16, BASE_DEC, VALS(erspan_truncated_vals),
460
15
      0x0400, "ERSPAN packet exceeded the MTU size", HFILL }},
461
462
15
    { &hf_erspan_spanid,
463
15
    { "SpanID", "erspan.spanid", FT_UINT16, BASE_DEC, NULL,
464
15
      0x03ff, NULL, HFILL }},
465
466
15
    { &hf_erspan_reserved,
467
15
    { "Reserved", "erspan.reserved", FT_UINT32, BASE_DEC, NULL,
468
15
      0xfff00000, NULL, HFILL }},
469
470
15
    { &hf_erspan_index,
471
15
    { "Index",  "erspan.index", FT_UINT32, BASE_DEC, NULL,
472
15
      0x000fffff, NULL, HFILL }},
473
474
15
    { &hf_erspan_timestamp,
475
15
    { "Timestamp",  "erspan.timestamp", FT_UINT32, BASE_DEC, NULL,
476
15
      0x0, NULL, HFILL }},
477
478
479
15
    { &hf_erspan_sgt,
480
15
    { "Security Group Tag", "erspan.sgt", FT_UINT16, BASE_DEC, NULL,
481
15
      0x0, NULL, HFILL }},
482
483
15
    { &hf_erspan_p,
484
15
    { "Has Ethernet PDU", "erspan.p", FT_UINT16, BASE_DEC, NULL,
485
15
      0x8000, NULL, HFILL }},
486
487
488
15
    { &hf_erspan_ft,
489
15
    { "Frame Type", "erspan.ft", FT_UINT16, BASE_DEC, VALS(erspan_ft_vals),
490
15
      0x7C00, NULL, HFILL }},
491
492
15
    { &hf_erspan_hw,
493
15
    { "Hardware ID", "erspan.hw", FT_UINT16, BASE_DEC, NULL,
494
15
      0x03f0, NULL, HFILL }},
495
496
15
    { &hf_erspan_gra,
497
15
    { "Timestamp granularity", "erspan.gra", FT_UINT16, BASE_DEC, VALS(erspan_granularity_vals),
498
15
      0x0006, NULL, HFILL }},
499
500
15
    { &hf_erspan_direction,
501
15
    { "Direction",  "erspan.direction", FT_BOOLEAN, 16, TFS(&tfs_direction),
502
15
      0x0008, NULL, HFILL }},
503
504
15
    { &hf_erspan_o,
505
15
    { "Optional Sub headers", "erspan.o", FT_UINT16, BASE_DEC, NULL,
506
15
      0x0001, NULL, HFILL }},
507
508
    /* Sub-header Fields, optional */
509
15
    { &hf_erspan_platid,
510
15
    { "Platform ID", "erspan.platid", FT_UINT32, BASE_DEC, NULL,
511
15
      0xfc000000, NULL, HFILL }},
512
513
    /* ID = 1 */
514
15
    { &hf_erspan_pid1_rsvd1,
515
15
    { "Reserved", "erspan.pid1.rsvd1", FT_UINT32, BASE_DEC, NULL,
516
15
      0x03fff000, NULL, HFILL }},
517
518
15
    { &hf_erspan_pid1_domain_id,
519
15
    { "VSM Domain ID", "erspan.pid1.vsmid", FT_UINT32, BASE_DEC, NULL,
520
15
      0x00000fff, NULL, HFILL }},
521
522
15
    { &hf_erspan_pid1_port_index,
523
15
    { "Port ID/Index", "erspan.pid1.port_index", FT_UINT32, BASE_DEC, NULL,
524
15
      0x0, NULL, HFILL }},
525
526
    /* ID = 3 */
527
15
    { &hf_erspan_pid3_rsvd1,
528
15
    { "Reserved", "erspan.pid3.rsvd1", FT_UINT32, BASE_DEC, NULL,
529
15
      0x03ffc000, NULL, HFILL }},
530
531
15
    { &hf_erspan_pid3_port_index,
532
15
    { "Port ID/Index", "erspan.pid3.port_index", FT_UINT32, BASE_DEC, NULL,
533
15
      0x00003fff, NULL, HFILL }},
534
535
15
    { &hf_erspan_pid3_timestamp,
536
15
    { "Upper 32-bit Timestamp", "erspan.pid3.timestamp", FT_UINT32, BASE_DEC, NULL,
537
15
      0x0, NULL, HFILL }},
538
539
    /* ID = 4 */
540
15
    { &hf_erspan_pid4_rsvd1,
541
15
    { "Reserved", "erspan.pid4.rsvd1", FT_UINT32, BASE_DEC, NULL,
542
15
      0x03ffc000, NULL, HFILL }},
543
544
15
    { &hf_erspan_pid4_rsvd2,
545
15
    { "Reserved", "erspan.pid4.rsvd2", FT_UINT32, BASE_DEC, NULL,
546
15
      0x00003fff, NULL, HFILL }},
547
548
15
    { &hf_erspan_pid4_rsvd3,
549
15
    { "Reserved", "erspan.pid4.rsvd3", FT_UINT32, BASE_DEC, NULL,
550
15
      0xffffffff, NULL, HFILL }},
551
552
    /* ID = 5 or 6 */
553
15
    { &hf_erspan_pid5_switchid,
554
15
    { "Switch ID", "erspan.pid5.switchid", FT_UINT32, BASE_DEC, NULL,
555
15
      0x03ff0000, NULL, HFILL }},
556
557
15
    { &hf_erspan_pid5_port_index,
558
15
    { "Port ID/Index", "erspan.pid5.port_index", FT_UINT32, BASE_DEC, NULL,
559
15
      0x0000ffff, NULL, HFILL }},
560
561
15
    { &hf_erspan_pid5_timestamp,
562
15
    { "Timestamp (seconds)", "erspan.pid5.timestamp", FT_UINT32, BASE_DEC, NULL,
563
15
      0x0, NULL, HFILL }},
564
565
    /* ID = 7 (or 0) */
566
15
    { &hf_erspan_pid7_rsvd1,
567
15
    { "Reserved", "erspan.pid7.rsvd1", FT_UINT32, BASE_DEC, NULL,
568
15
      0x03f00000, NULL, HFILL }},
569
570
15
    { &hf_erspan_pid7_source_index,
571
15
    { "Source Index", "erspan.pid7.source_index", FT_UINT32, BASE_DEC, NULL,
572
15
      0x000fffff, NULL, HFILL }},
573
574
15
    { &hf_erspan_pid7_timestamp,
575
15
    { "Upper 32-bit Timestamp", "erspan.pid7.timestamp", FT_UINT32, BASE_DEC, NULL,
576
15
      0x0, NULL, HFILL }},
577
578
    /* Reserved */
579
15
    { &hf_erspan_pid_rsvd,
580
15
    { "Reserved", "erspan.pid.rsvd", FT_UINT64, BASE_DEC, NULL,
581
15
      0x03ffffff, NULL, HFILL }},
582
583
15
  };
584
585
15
  static int *ett[] = {
586
15
    &ett_erspan,
587
15
  };
588
589
15
  static ei_register_info ei[] = {
590
15
    { &ei_erspan_version_unknown, { "erspan.version.unknown", PI_UNDECODED, PI_WARN, "Unknown version, please report or test to use fake ERSPAN preference", EXPFILL }},
591
15
  };
592
593
15
  proto_erspan = proto_register_protocol("Encapsulated Remote Switch Packet ANalysis", "ERSPAN", "erspan");
594
15
  proto_register_field_array(proto_erspan, hf, array_length(hf));
595
15
  proto_register_subtree_array(ett, array_length(ett));
596
15
  expert_erspan = expert_register_protocol(proto_erspan);
597
15
  expert_register_field_array(expert_erspan, ei, array_length(ei));
598
599
15
  register_dissector("erspan", dissect_erspan, proto_erspan);
600
15
}
601
602
void
603
proto_reg_handoff_erspan(void)
604
15
{
605
15
  dissector_handle_t erspan_88BE_handle;
606
15
  dissector_handle_t erspan_22EB_handle;
607
608
15
  ethnofcs_handle = find_dissector_add_dependency("eth_withoutfcs", proto_erspan);
609
610
15
  erspan_88BE_handle = create_dissector_handle(dissect_erspan_88BE, proto_erspan);
611
15
  dissector_add_uint("gre.proto", GRE_ERSPAN_88BE, erspan_88BE_handle);
612
15
  erspan_22EB_handle = create_dissector_handle(dissect_erspan_22EB, proto_erspan);
613
15
  dissector_add_uint("gre.proto", GRE_ERSPAN_22EB, erspan_22EB_handle);
614
615
15
}
616
617
/*
618
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
619
 *
620
 * Local variables:
621
 * c-basic-offset: 8
622
 * tab-width: 8
623
 * indent-tabs-mode: t
624
 * End:
625
 *
626
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
627
 * :indentSize=8:tabSize=8:noTabs=false:
628
 */