Coverage Report

Created: 2026-08-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-erf.c
Line
Count
Source
1
/* packet-erf.c
2
 * Routines for ERF encapsulation dissection
3
 *
4
 * Wireshark - Network traffic analyzer
5
 * By Gerald Combs <gerald@wireshark.org>
6
 * Copyright 1998 Gerald Combs
7
 *
8
 * SPDX-License-Identifier: GPL-2.0-or-later
9
 */
10
11
#include "config.h"
12
13
#include <epan/packet.h>
14
#include <epan/expert.h>
15
#include <epan/prefs.h>
16
#include <epan/tfs.h>
17
#include <epan/unit_strings.h>
18
#include <epan/iana-info.h>
19
#include <wsutil/str_util.h>
20
#include <wiretap/wtap.h>
21
#include <wiretap/erf_record.h>
22
23
#include "packet-erf.h"
24
#include "packet-ptp.h"
25
26
/*
27
*/
28
29
void proto_register_erf(void);
30
void proto_reg_handoff_erf(void);
31
32
0
#define DECHAN_MAX_LINE_RATE 5
33
0
#define DECHAN_MAX_VC_SIZE 5
34
0
#define DECHAN_MAX_AUG_INDEX 4
35
36
typedef struct sdh_g707_format_s
37
{
38
  uint8_t m_sdh_line_rate;
39
  uint8_t m_vc_size ;
40
  int8_t m_vc_index_array[DECHAN_MAX_AUG_INDEX];
41
        /* i = 3 --> ITU-T letter #D - index of AUG-16
42
         * i = 2 --> ITU-T letter #C - index of AUG-4,
43
         * i = 1 --> ITU-T letter #B - index of AUG-1
44
         * i = 0 --> ITU-T letter #A - index of AU3*/
45
} sdh_g707_format_t;
46
47
static dissector_handle_t erf_handle;
48
static dissector_table_t erf_dissector_table;
49
50
/* Initialize the protocol and registered fields */
51
static int proto_erf;
52
53
static int hf_erf_ts;
54
static int hf_erf_rectype;
55
static int hf_erf_type;
56
static int hf_erf_ehdr;
57
static int hf_erf_ehdr_t;
58
static int hf_erf_flags;
59
static int hf_erf_flags_cap;
60
static int hf_erf_flags_if_raw;
61
static int hf_erf_flags_vlen;
62
static int hf_erf_flags_trunc;
63
static int hf_erf_flags_rxe;
64
static int hf_erf_flags_dse;
65
static int hf_erf_flags_res;
66
67
static int hf_erf_rlen;
68
static int hf_erf_lctr;
69
static int hf_erf_color;
70
static int hf_erf_wlen;
71
72
/* Classification extension header */
73
74
/* InterceptID extension header */
75
static int hf_erf_ehdr_int_res1;
76
static int hf_erf_ehdr_int_id;
77
static int hf_erf_ehdr_int_res2;
78
79
/* Raw Link extension header */
80
static int hf_erf_ehdr_raw_link_res;
81
static int hf_erf_ehdr_raw_link_seqnum;
82
static int hf_erf_ehdr_raw_link_rate;
83
static int hf_erf_ehdr_raw_link_type;
84
85
/* Classification extension header */
86
static int hf_erf_ehdr_class_flags;
87
static int hf_erf_ehdr_class_flags_sh;
88
static int hf_erf_ehdr_class_flags_shm;
89
static int hf_erf_ehdr_class_flags_res1;
90
static int hf_erf_ehdr_class_flags_user;
91
static int hf_erf_ehdr_class_flags_res2;
92
static int hf_erf_ehdr_class_flags_drop;
93
static int hf_erf_ehdr_class_flags_str;
94
static int hf_erf_ehdr_class_seqnum;
95
96
/* BFS extension header */
97
static int hf_erf_ehdr_bfs_hash;
98
static int hf_erf_ehdr_bfs_color;
99
static int hf_erf_ehdr_bfs_raw_hash;
100
101
/* Channelised extension header */
102
static int hf_erf_ehdr_chan_morebits;
103
static int hf_erf_ehdr_chan_morefrag;
104
static int hf_erf_ehdr_chan_seqnum;
105
static int hf_erf_ehdr_chan_res;
106
static int hf_erf_ehdr_chan_virt_container_id;
107
static int hf_erf_ehdr_chan_assoc_virt_container_size;
108
static int hf_erf_ehdr_chan_rate;
109
static int hf_erf_ehdr_chan_type;
110
111
/* Filter Hash extension header */
112
static int hf_erf_ehdr_signature_payload_hash;
113
static int hf_erf_ehdr_signature_color;
114
static int hf_erf_ehdr_signature_flow_hash;
115
116
/* Flow ID extension header */
117
static int hf_erf_ehdr_flow_id_source_id;
118
static int hf_erf_ehdr_flow_id_hash_type;
119
static int hf_erf_ehdr_flow_id_hash_type_type;
120
static int hf_erf_ehdr_flow_id_hash_type_inner;
121
static int hf_erf_ehdr_flow_id_stack_type;
122
static int hf_erf_ehdr_flow_id_flow_hash;
123
124
/* Host ID extension header */
125
static int hf_erf_ehdr_host_id_sourceid;
126
static int hf_erf_ehdr_host_id_hostid;
127
128
/* Anchor ID extension header */
129
static int hf_erf_ehdr_anchor_id_definition;
130
static int hf_erf_ehdr_anchor_id_reserved;
131
static int hf_erf_ehdr_anchor_id_anchorid;
132
static int hf_erf_ehdr_anchor_id_flags;
133
134
static int hf_erf_anchor_linked;
135
static int hf_erf_anchor_anchorid;
136
static int hf_erf_anchor_hostid;
137
138
/* Generated Host ID/Source ID */
139
static int hf_erf_sourceid;
140
static int hf_erf_hostid;
141
static int hf_erf_source_current;
142
static int hf_erf_source_next;
143
static int hf_erf_source_prev;
144
145
/* Entropy extension header */
146
static int hf_erf_ehdr_entropy_entropy;
147
static int hf_erf_ehdr_entropy_entropy_raw;
148
static int hf_erf_ehdr_entropy_reserved;
149
150
/* Unknown extension header */
151
static int hf_erf_ehdr_unk;
152
153
/* MC HDLC Header */
154
static int hf_erf_mc_hdlc;
155
static int hf_erf_mc_hdlc_cn;
156
static int hf_erf_mc_hdlc_res1;
157
static int hf_erf_mc_hdlc_res2;
158
static int hf_erf_mc_hdlc_fcse;
159
static int hf_erf_mc_hdlc_sre;
160
static int hf_erf_mc_hdlc_lre;
161
static int hf_erf_mc_hdlc_afe;
162
static int hf_erf_mc_hdlc_oe;
163
static int hf_erf_mc_hdlc_lbe;
164
static int hf_erf_mc_hdlc_first;
165
static int hf_erf_mc_hdlc_res3;
166
167
/* MC RAW Header */
168
static int hf_erf_mc_raw;
169
static int hf_erf_mc_raw_int;
170
static int hf_erf_mc_raw_res1;
171
static int hf_erf_mc_raw_sre;
172
static int hf_erf_mc_raw_lre;
173
static int hf_erf_mc_raw_res2;
174
static int hf_erf_mc_raw_lbe;
175
static int hf_erf_mc_raw_first;
176
static int hf_erf_mc_raw_res3;
177
178
/* MC ATM Header */
179
static int hf_erf_mc_atm;
180
static int hf_erf_mc_atm_cn;
181
static int hf_erf_mc_atm_res1;
182
static int hf_erf_mc_atm_mul;
183
static int hf_erf_mc_atm_port;
184
static int hf_erf_mc_atm_res2;
185
static int hf_erf_mc_atm_lbe;
186
static int hf_erf_mc_atm_hec;
187
static int hf_erf_mc_atm_crc10;
188
static int hf_erf_mc_atm_oamcell;
189
static int hf_erf_mc_atm_first;
190
static int hf_erf_mc_atm_res3;
191
192
/* MC Raw link Header */
193
static int hf_erf_mc_rawl;
194
static int hf_erf_mc_rawl_cn;
195
static int hf_erf_mc_rawl_res1;
196
static int hf_erf_mc_rawl_lbe;
197
static int hf_erf_mc_rawl_first;
198
static int hf_erf_mc_rawl_res2;
199
200
/* MC AAL5 Header */
201
static int hf_erf_mc_aal5;
202
static int hf_erf_mc_aal5_cn;
203
static int hf_erf_mc_aal5_res1;
204
static int hf_erf_mc_aal5_port;
205
static int hf_erf_mc_aal5_crcck;
206
static int hf_erf_mc_aal5_crce;
207
static int hf_erf_mc_aal5_lenck;
208
static int hf_erf_mc_aal5_lene;
209
static int hf_erf_mc_aal5_res2;
210
static int hf_erf_mc_aal5_first;
211
static int hf_erf_mc_aal5_res3;
212
213
/* MC AAL2 Header */
214
static int hf_erf_mc_aal2;
215
static int hf_erf_mc_aal2_cn;
216
static int hf_erf_mc_aal2_res1;
217
static int hf_erf_mc_aal2_res2;
218
static int hf_erf_mc_aal2_port;
219
static int hf_erf_mc_aal2_res3;
220
static int hf_erf_mc_aal2_first;
221
static int hf_erf_mc_aal2_maale;
222
static int hf_erf_mc_aal2_lene;
223
static int hf_erf_mc_aal2_cid;
224
225
/* AAL2 Header */
226
static int hf_erf_aal2;
227
static int hf_erf_aal2_cid;
228
static int hf_erf_aal2_maale;
229
static int hf_erf_aal2_maalei;
230
static int hf_erf_aal2_first;
231
static int hf_erf_aal2_res1;
232
233
/* ERF Ethernet header/pad */
234
static int hf_erf_eth;
235
static int hf_erf_eth_off;
236
static int hf_erf_eth_pad;
237
238
/* ERF Meta record tag */
239
static int hf_erf_meta_tag_type;
240
static int hf_erf_meta_tag_len;
241
static int hf_erf_meta_tag_unknown;
242
243
/* Initialize the subtree pointers */
244
static int ett_erf;
245
static int ett_erf_pseudo_hdr;
246
static int ett_erf_rectype;
247
static int ett_erf_hash_type;
248
static int ett_erf_flags;
249
static int ett_erf_mc_hdlc;
250
static int ett_erf_mc_raw;
251
static int ett_erf_mc_atm;
252
static int ett_erf_mc_rawlink;
253
static int ett_erf_mc_aal5;
254
static int ett_erf_mc_aal2;
255
static int ett_erf_aal2;
256
static int ett_erf_eth;
257
static int ett_erf_meta;
258
static int ett_erf_meta_tag;
259
static int ett_erf_source;
260
static int ett_erf_anchor;
261
static int ett_erf_anchor_flags;
262
static int ett_erf_entropy_value;
263
264
static expert_field ei_erf_extension_headers_not_shown;
265
static expert_field ei_erf_packet_loss;
266
static expert_field ei_erf_mc_hdlc_checksum_error;
267
static expert_field ei_erf_mc_hdlc_short_error;
268
static expert_field ei_erf_mc_hdlc_long_error;
269
static expert_field ei_erf_mc_hdlc_abort_error;
270
static expert_field ei_erf_mc_hdlc_octet_error;
271
static expert_field ei_erf_mc_hdlc_lost_byte_error;
272
static expert_field ei_erf_rx_error;
273
static expert_field ei_erf_ds_error;
274
static expert_field ei_erf_truncation_error;
275
static expert_field ei_erf_meta_section_len_error;
276
static expert_field ei_erf_meta_truncated_record;
277
static expert_field ei_erf_meta_truncated_tag;
278
static expert_field ei_erf_meta_zero_len_tag;
279
static expert_field ei_erf_meta_reset;
280
281
typedef enum {
282
  ERF_HDLC_CHDLC  = 0,
283
  ERF_HDLC_PPP    = 1,
284
  ERF_HDLC_FRELAY = 2,
285
  ERF_HDLC_MTP2   = 3,
286
  ERF_HDLC_GUESS  = 4,
287
  ERF_HDLC_MAX    = 5
288
} erf_hdlc_type_vals;
289
290
static int erf_hdlc_type = ERF_HDLC_GUESS;
291
static dissector_handle_t chdlc_handle, ppp_handle, frelay_handle, mtp2_handle;
292
293
static bool erf_rawcell_first;
294
295
typedef enum {
296
  ERF_AAL5_GUESS  = 0,
297
  ERF_AAL5_LLC    = 1,
298
  ERF_AAL5_UNSPEC = 2
299
} erf_aal5_type_val;
300
301
static int erf_aal5_type = ERF_AAL5_GUESS;
302
static dissector_handle_t atm_untruncated_handle;
303
304
static dissector_handle_t sdh_handle;
305
306
/* ERF Extension Header */
307
0
#define ERF_EHDR_FLOW_ID_HASH_TYPE_TYPE_MASK 0x7f
308
0
#define ERF_EHDR_FLOW_ID_HASH_TYPE_INNER_MASK 0x80
309
310
/* Classification */
311
0
#define EHDR_CLASS_FLAGS_MASK 0x00ffffff
312
0
#define EHDR_CLASS_SH_MASK    0x00800000
313
0
#define EHDR_CLASS_SHM_MASK   0x00400000
314
0
#define EHDR_CLASS_RES1_MASK  0x00300000
315
0
#define EHDR_CLASS_USER_MASK  0x000FFFF0
316
0
#define EHDR_CLASS_RES2_MASK  0x00000008
317
0
#define EHDR_CLASS_DROP_MASK  0x00000004
318
0
#define EHDR_CLASS_STER_MASK  0x00000003
319
320
/* Header for ATM traffic identification */
321
0
#define ATM_HDR_LENGTH 4
322
323
/* Multi Channel HDLC */
324
0
#define MC_HDLC_CN_MASK    0x000003ff
325
0
#define MC_HDLC_RES1_MASK  0x0000fc00
326
0
#define MC_HDLC_RES2_MASK  0x00ff0000
327
0
#define MC_HDLC_FCSE_MASK  0x01000000
328
0
#define MC_HDLC_SRE_MASK   0x02000000
329
0
#define MC_HDLC_LRE_MASK   0x04000000
330
0
#define MC_HDLC_AFE_MASK   0x08000000
331
0
#define MC_HDLC_OE_MASK    0x10000000
332
0
#define MC_HDLC_LBE_MASK   0x20000000
333
0
#define MC_HDLC_FIRST_MASK 0x40000000
334
0
#define MC_HDLC_RES3_MASK  0x80000000
335
336
/* Multi Channel RAW */
337
0
#define MC_RAW_INT_MASK   0x0000000f
338
0
#define MC_RAW_RES1_MASK  0x01fffff0
339
0
#define MC_RAW_SRE_MASK   0x02000000
340
0
#define MC_RAW_LRE_MASK   0x04000000
341
0
#define MC_RAW_RES2_MASK  0x18000000
342
0
#define MC_RAW_LBE_MASK   0x20000000
343
0
#define MC_RAW_FIRST_MASK 0x40000000
344
0
#define MC_RAW_RES3_MASK  0x80000000
345
346
/* Multi Channel ATM */
347
0
#define MC_ATM_CN_MASK      0x000003ff
348
0
#define MC_ATM_RES1_MASK    0x00007c00
349
0
#define MC_ATM_MUL_MASK     0x00008000
350
0
#define MC_ATM_PORT_MASK    0x000f0000
351
0
#define MC_ATM_RES2_MASK    0x00f00000
352
0
#define MC_ATM_LBE_MASK     0x01000000
353
0
#define MC_ATM_HEC_MASK     0x02000000
354
0
#define MC_ATM_CRC10_MASK   0x04000000
355
0
#define MC_ATM_OAMCELL_MASK 0x08000000
356
0
#define MC_ATM_FIRST_MASK   0x10000000
357
0
#define MC_ATM_RES3_MASK    0xe0000000
358
359
/* Multi Channel RAW Link */
360
0
#define MC_RAWL_CN_MASK    0x000003ff
361
#define MC_RAWL_RES1_MASK  0x1ffffc00
362
0
#define MC_RAWL_LBE_MASK   0x20000000
363
0
#define MC_RAWL_FIRST_MASK 0x40000000
364
0
#define MC_RAWL_RES2_MASK  0x80000000
365
366
/* Multi Channel AAL5 */
367
0
#define MC_AAL5_CN_MASK    0x000003ff
368
0
#define MC_AAL5_RES1_MASK  0x0000fc00
369
0
#define MC_AAL5_PORT_MASK  0x000f0000
370
0
#define MC_AAL5_CRCCK_MASK 0x00100000
371
0
#define MC_AAL5_CRCE_MASK  0x00200000
372
0
#define MC_AAL5_LENCK_MASK 0x00400000
373
0
#define MC_AAL5_LENE_MASK  0x00800000
374
0
#define MC_AAL5_RES2_MASK  0x0f000000
375
0
#define MC_AAL5_FIRST_MASK 0x10000000
376
0
#define MC_AAL5_RES3_MASK  0xe0000000
377
378
/* Multi Channel AAL2 */
379
0
#define MC_AAL2_CN_MASK    0x000003ff
380
0
#define MC_AAL2_RES1_MASK  0x00001c00
381
0
#define MC_AAL2_RES2_MASK  0x0000e000
382
0
#define MC_AAL2_PORT_MASK  0x000f0000
383
0
#define MC_AAL2_RES3_MASK  0x00100000
384
0
#define MC_AAL2_FIRST_MASK 0x00200000
385
0
#define MC_AAL2_MAALE_MASK 0x00400000
386
0
#define MC_AAL2_LENE_MASK  0x00800000
387
0
#define MC_AAL2_CID_MASK   0xff000000
388
0
#define MC_AAL2_CID_SHIFT  24
389
390
/* AAL2 */
391
0
#define AAL2_CID_MASK    0x000000ff
392
0
#define AAL2_CID_SHIFT   0
393
0
#define AAL2_MAALE_MASK  0x0000ff00
394
0
#define AAL2_MAALEI_MASK 0x00010000
395
0
#define AAL2_FIRST_MASK  0x00020000
396
0
#define AAL2_RES1_MASK   0xfffc0000
397
398
/* ETH */
399
#define ETH_OFF_MASK  0x00
400
#define ETH_RES1_MASK 0x00
401
402
/* Invalid Provenance sections used for special lookup */
403
0
#define ERF_META_SECTION_NONE 0
404
0
#define ERF_META_SECTION_UNKNOWN 1
405
406
0
#define NS_PER_S 1000000000
407
408
/* Record type defines */
409
static const value_string erf_type_vals[] = {
410
  { ERF_TYPE_LEGACY             ,"LEGACY"},
411
  { ERF_TYPE_HDLC_POS           ,"HDLC_POS"},
412
  { ERF_TYPE_ETH                ,"ETH"},
413
  { ERF_TYPE_ATM                ,"ATM"},
414
  { ERF_TYPE_AAL5               ,"AAL5"},
415
  { ERF_TYPE_MC_HDLC            ,"MC_HDLC"},
416
  { ERF_TYPE_MC_RAW             ,"MC_RAW"},
417
  { ERF_TYPE_MC_ATM             ,"MC_ATM"},
418
  { ERF_TYPE_MC_RAW_CHANNEL     ,"MC_RAW_CHANNEL"},
419
  { ERF_TYPE_MC_AAL5            ,"MC_AAL5"},
420
  { ERF_TYPE_COLOR_HDLC_POS     ,"COLOR_HDLC_POS"},
421
  { ERF_TYPE_COLOR_ETH          ,"COLOR_ETH"},
422
  { ERF_TYPE_COLOR_HASH_POS     ,"COLOR_HASH_POS"},
423
  { ERF_TYPE_COLOR_HASH_ETH     ,"COLOR_HASH_ETH"},
424
  { ERF_TYPE_MC_AAL2            ,"MC_AAL2 "},
425
  { ERF_TYPE_IP_COUNTER         ,"IP_COUNTER"},
426
  { ERF_TYPE_TCP_FLOW_COUNTER   ,"TCP_FLOW_COUNTER"},
427
  { ERF_TYPE_DSM_COLOR_HDLC_POS ,"DSM_COLOR_HDLC_POS"},
428
  { ERF_TYPE_DSM_COLOR_ETH      ,"DSM_COLOR_ETH "},
429
  { ERF_TYPE_COLOR_MC_HDLC_POS  ,"COLOR_MC_HDLC_POS"},
430
  { ERF_TYPE_AAL2               ,"AAL2"},
431
  { ERF_TYPE_PAD                ,"PAD"},
432
  { ERF_TYPE_INFINIBAND         , "INFINIBAND"},
433
  { ERF_TYPE_IPV4               , "IPV4"},
434
  { ERF_TYPE_IPV6               , "IPV6"},
435
  { ERF_TYPE_RAW_LINK           , "RAW_LINK"},
436
  { ERF_TYPE_INFINIBAND_LINK    , "INFINIBAND_LINK"},
437
  { ERF_TYPE_META               , "META"},
438
  { ERF_TYPE_OPA_SNC            , "OMNI-PATH_SNC"},
439
  { ERF_TYPE_OPA_9B             , "OMNI-PATH"},
440
  {0, NULL}
441
};
442
443
/* Extended headers type defines */
444
static const value_string ehdr_type_vals[] = {
445
  { ERF_EXT_HDR_TYPE_CLASSIFICATION , "Classification"},
446
  { ERF_EXT_HDR_TYPE_INTERCEPTID    , "InterceptID"},
447
  { ERF_EXT_HDR_TYPE_RAW_LINK       , "Raw Link"},
448
  { ERF_EXT_HDR_TYPE_BFS            , "BFS Filter/Hash"},
449
  { ERF_EXT_HDR_TYPE_CHANNELISED    , "Channelised"},
450
  { ERF_EXT_HDR_TYPE_SIGNATURE      , "Signature"},
451
  { ERF_EXT_HDR_TYPE_PKT_ID         , "Packet ID"},
452
  { ERF_EXT_HDR_TYPE_FLOW_ID        , "Flow ID"},
453
  { ERF_EXT_HDR_TYPE_HOST_ID        , "Host ID"},
454
  { ERF_EXT_HDR_TYPE_ANCHOR_ID      , "Anchor ID"},
455
  { ERF_EXT_HDR_TYPE_ENTROPY        , "Entropy"},
456
  { 0, NULL }
457
};
458
459
/* Used for Provenance ext_hdrs_added/removed, should match the field abbreviation */
460
static const value_string ehdr_type_vals_short[] = {
461
  { ERF_EXT_HDR_TYPE_CLASSIFICATION , "class"},
462
  { ERF_EXT_HDR_TYPE_INTERCEPTID    , "int"},
463
  { ERF_EXT_HDR_TYPE_RAW_LINK       , "raw"},
464
  { ERF_EXT_HDR_TYPE_BFS            , "bfs"},
465
  { ERF_EXT_HDR_TYPE_CHANNELISED    , "chan"},
466
  { ERF_EXT_HDR_TYPE_SIGNATURE      , "signature"},
467
  { ERF_EXT_HDR_TYPE_PKT_ID         , "packetid"},
468
  { ERF_EXT_HDR_TYPE_FLOW_ID        , "flowid"},
469
  { ERF_EXT_HDR_TYPE_HOST_ID        , "hostid"},
470
  { ERF_EXT_HDR_TYPE_ANCHOR_ID      , "anchorid"},
471
  { ERF_EXT_HDR_TYPE_ENTROPY        , "entropy"},
472
  { 0, NULL }
473
};
474
475
/* XXX: Must be at least array_length(ehdr_type_vals). */
476
#define ERF_HF_VALUES_PER_TAG 32
477
478
static const value_string raw_link_types[] = {
479
  { 0x00, "raw SONET"},
480
  { 0x01, "raw SDH"},
481
  { 0x02, "SONET spe"},
482
  { 0x03, "SDH spe"},
483
  { 0x04, "ds3"},
484
  { 0x05, "SONET spe w/o POH"},
485
  { 0x06, "SDH spe w/o POH"},
486
  { 0x07, "SONET line mode 2"},
487
  { 0x08, "SHD line mode 2"},
488
  { 0x09, "raw bit-level"},
489
  { 0x0A, "raw 10Gbe 66b"},
490
  { 0, NULL },
491
};
492
493
static const value_string raw_link_rates[] = {
494
  { 0x00, "reserved"},
495
  { 0x01, "oc3/stm1"},
496
  { 0x02, "oc12/stm4"},
497
  { 0x03, "oc48/stm16"},
498
  { 0x04, "oc192/stm64"},
499
  { 0, NULL },
500
};
501
502
static const value_string channelised_assoc_virt_container_size[] = {
503
  { 0x00, "unused field"},
504
  { 0x01, "VC-3 / STS-1"},
505
  { 0x02, "VC-4 / STS-3"},
506
  { 0x03, "VC-4-4c / STS-12"},
507
  { 0x04, "VC-4-16c / STS-48"},
508
  { 0x05, "VC-4-64c / STS-192"},
509
  { 0, NULL }
510
};
511
512
static const value_string channelised_rate[] = {
513
  { 0x00, "Reserved"},
514
  { 0x01, "STM-0 / STS-1"},
515
  { 0x02, "STM-1 / STS-3"},
516
  { 0x03, "STM-4 / STS-12"},
517
  { 0x04, "STM-16 / STS-48"},
518
  { 0x05, "STM-64 / STS-192"},
519
  { 0, NULL}
520
};
521
522
static const value_string channelised_type[] = {
523
  { 0x00, "SOH / TOH"},
524
  { 0x01, "POH"},
525
  { 0x02, "Container"},
526
  { 0x03, "POS Packet"},
527
  { 0x04, "ATM Cell"},
528
  { 0x05, "Positive justification bytes"},
529
  { 0x06, "Raw demultiplexed channel"},
530
  { 0, NULL}
531
};
532
533
static const value_string erf_hash_type[] = {
534
  { 0x00, "Not set"},
535
  { 0x01, "Non-IP (Src/Dst MACs, EtherType)"},
536
  { 0x02, "2-tuple (Src/Dst IPs)"},
537
  { 0x03, "3-tuple (Src/Dst IPs, IP Protocol)"},
538
  { 0x04, "4-tuple (Src/Dst IPs, IP Protocol, Interface ID)"},
539
  { 0x05, "5-tuple (Src/Dst IPs, IP Protocol, Src/Dst L4 Ports)"},
540
  { 0x06, "6-tuple (Src/Dst IPs, IP Protocol, Src/Dst L4 Ports, Interface ID)"},
541
  { 0, NULL}
542
};
543
544
static const value_string erf_hash_mode[] = {
545
  { 0x00, "Reserved"},
546
  { 0x01, "Reserved"},
547
  { 0x02, "2-tuple (Src/Dst IPs)"},
548
  { 0x03, "3-tuple (Src/Dst IPs, IP Protocol)"},
549
  { 0x04, "4-tuple (Src/Dst IPs, IP Protocol, Interface ID)"},
550
  { 0x05, "5-tuple (Src/Dst IPs, IP Protocol, Src/Dst L4 Ports)"},
551
  { 0x06, "6-tuple (Src/Dst IPs, IP Protocol, Src/Dst L4 Ports, Interface ID)"},
552
  { 0x07, "2-tuple (Inner Src/Dst IPs)"},
553
  { 0x08, "4-tuple (Inner Src/Dst IPs, Outer Src/Dst IPs)"},
554
  { 0x09, "4-tuple (Inner Src/Dst IPs, Inner Src/Dst L4 Ports)"},
555
  { 0x0A, "6-tuple (Inner Src/Dst IPs, Outer Src/Dst IPs, Inner Src/Dst L4 Ports)"},
556
  { 0, NULL}
557
};
558
559
static const value_string erf_stack_type[] = {
560
  { 0x00, "Not set"},
561
  { 0x01, "Non-IP"},
562
  { 0x02, "No VLAN, IPv4"},
563
  { 0x03, "No VLAN, IPv6"},
564
  { 0x04, "One VLAN, IPv4"},
565
  { 0x05, "One VLAN, IPv6"},
566
  { 0x06, "Two VLANs, IPv4"},
567
  { 0x07, "Two VLANs, IPv6"},
568
  { 0, NULL}
569
};
570
static const value_string erf_port_type[] = {
571
  { 0x00, "Reserved"},
572
  { 0x01, "Capture Port"},
573
  { 0x02, "Timing Port"},
574
  { 0, NULL}
575
};
576
577
static const value_string erf_clk_source[] = {
578
  { 0x00, "Invalid"},
579
  { 0x01, "None" },
580
  { 0x02, "External"},
581
  { 0x03, "Host"},
582
  { 0x04, "Link Cable"},
583
  { 0x05, "PTP"},
584
  { 0x06, "Internal"},
585
  { 0, NULL}
586
};
587
588
static const value_string erf_clk_state[] = {
589
  { 0x00, "Invalid" },
590
  { 0x01, "Unsynchronized"},
591
  { 0x02, "Synchronized"},
592
  { 0, NULL}
593
};
594
595
static const value_string erf_clk_link_mode[] = {
596
  { 0x00, "Invalid"},
597
  { 0x01, "Not Connected"},
598
  { 0x02, "Master"},
599
  { 0x03, "Disabled Master"},
600
  { 0x04, "Slave"},
601
  { 0, NULL}
602
};
603
604
static const value_string erf_clk_port_proto[] = {
605
  { 0x00, "Invalid" },
606
  { 0x01, "None" },
607
  { 0x02, "1PPS" },
608
  { 0x03, "IRIG-B" },
609
  { 0x04, "Ethernet" },
610
  { 0, NULL }
611
};
612
613
static const value_string erf_tap_mode[] = {
614
  { 0x00, "Invalid" },
615
  { 0x01, "Off" },
616
  { 0x02, "Active" },
617
  { 0x03, "Monitor" },
618
  { 0x04, "Bypass" },
619
  { 0x05, "Blocking" },
620
  { 0, NULL }
621
};
622
623
static const value_string erf_tap_fail_mode[] = {
624
  { 0x00, "Invalid" },
625
  { 0x01, "Off" },
626
  { 0x02, "Open" },
627
  { 0x03, "Closed" },
628
  { 0, NULL }
629
};
630
631
static const value_string erf_dpi_state[] = {
632
  { 0x00, "Terminated"},
633
  { 0x01, "Inspecting"},
634
  { 0x02, "Monitoring"},
635
  { 0x03, "Classified"},
636
  { 0, NULL}
637
};
638
639
static const value_string erf_flow_state[] = {
640
  { 0x00, "Active"},
641
  { 0x01, "Terminated"},
642
  { 0x02, "Expired"},
643
  { 0, NULL}
644
};
645
646
/* Used as templates for ERF_META_TAG_tunneling_mode */
647
static const header_field_info erf_tunneling_modes[] = {
648
  { "IP-in-IP", "ip_in_ip", FT_BOOLEAN, 32, NULL, 0x1, NULL, HFILL },
649
  /* 0x02 is currently unused and reserved */
650
  { "VXLAN", "vxlan", FT_BOOLEAN, 32, NULL, 0x4, NULL, HFILL },
651
  { "GRE", "gre", FT_BOOLEAN, 32, NULL, 0x8, NULL, HFILL },
652
  { "GTP", "gtp", FT_BOOLEAN, 32, NULL, 0x10, NULL, HFILL },
653
  { "MPLS over VLAN", "mpls_vlan", FT_BOOLEAN, 32, NULL, 0x20, NULL, HFILL }
654
};
655
656
657
/* Used as templates for ERF_META_TAG_if_link_status */
658
static const header_field_info erf_link_status[] = {
659
  { "Link", "link", FT_BOOLEAN, 32, TFS(&tfs_up_down), 0x1, NULL, HFILL }
660
};
661
662
/* Used as templates for ERF_META_TAG_ptp_time_properties */
663
static const header_field_info erf_ptp_time_properties_flags[] = {
664
  { "Leap61", "leap61", FT_BOOLEAN, 32, NULL, 0x1, NULL, HFILL },
665
  { "Leap59", "leap59", FT_BOOLEAN, 32, NULL, 0x2, NULL, HFILL },
666
  { "Current UTC Offset Valid", "currentUtcOffsetValid", FT_BOOLEAN, 32, NULL, 0x4, NULL, HFILL },
667
  { "PTP Timescale", "ptpTimescale", FT_BOOLEAN, 32, NULL, 0x8, NULL, HFILL },
668
  { "Time Traceable", "timeTraceable", FT_BOOLEAN, 32, NULL, 0x10, NULL, HFILL },
669
  { "Frequency Traceable", "frequencyTraceable", FT_BOOLEAN, 32, NULL, 0x20, NULL, HFILL }
670
};
671
672
/* Used as templates for ERF_META_TAG_ptp_gm_clock_quality */
673
static const header_field_info erf_ptp_clock_quality[] = {
674
  { "Clock Class", "clockClass", FT_UINT32, BASE_DEC, NULL, 0xFF000000, NULL, HFILL },
675
  { "Clock Accuracy", "clockAccuracy", FT_UINT32, BASE_DEC | BASE_EXT_STRING, &ptp_v2_clockAccuracy_vals_ext, 0x00FF0000, NULL, HFILL },
676
  { "Offset Scaled Log Variance","offsetScaledLogVariance", FT_UINT32, BASE_DEC, NULL, 0x0000FFFF, NULL, HFILL },
677
};
678
679
/* Used as templates for ERF_META_TAG_parent_section */
680
static const header_field_info erf_parent_section[] = {
681
  { "Section Type", "section_type", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL },
682
  { "Section ID", "section_id", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }
683
};
684
685
/* Used as templates for ERF_META_TAG_stream_flags */
686
static const header_field_info erf_stream_flags[] = {
687
  { "Relative Snapping", "relative_snap", FT_BOOLEAN, 32, NULL, 0x1, NULL, HFILL },
688
  { "Entropy Snapping", "entropy_snap", FT_BOOLEAN, 32, NULL, 0x2, NULL, HFILL }
689
};
690
691
/* Used as templates for ERF_META_TAG_ext_hdrs_added/removed subtrees */
692
static const header_field_info erf_ext_hdr_items[] = {
693
  { "Extension Headers 0 to 31", "0_31", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL },
694
  { "Extension Headers 32 to 63", "32_63", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL },
695
  { "Extension Headers 64 to 95", "64_95", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL },
696
  { "Extension Headers 96 to 127", "96_127", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }
697
};
698
699
/* Used as templates for ERF_META_TAG_smart_trunc_default */
700
static const header_field_info erf_smart_trunc_default_flags[] = {
701
  { "Truncation Candidate", "trunc_candidate", FT_BOOLEAN, 32, &tfs_yes_no, 0x1, NULL, HFILL }
702
};
703
704
typedef struct {
705
  uint16_t code;
706
  header_field_info hfinfo;
707
} erf_meta_hf_template_t;
708
709
typedef struct {
710
  int ett_value;
711
  /*
712
   * XXX: Must be at least array_length(ehdr_type_vals). Should change to
713
   * dynamic (possibly using new proto tree API) if many more fields defined.
714
   * Non-trivial as bitmask functions take an array of pointers not values.
715
   * Either that or add a value-string-like automatic bitmask flags proto_item.
716
   *
717
   * Note that this struct is only added for tags that need it.
718
   */
719
  int hf_values[ERF_HF_VALUES_PER_TAG];
720
} erf_meta_tag_info_ex_t;
721
722
typedef struct {
723
  uint16_t code;
724
  uint16_t section;
725
  const erf_meta_hf_template_t* tag_template;
726
  const erf_meta_hf_template_t* section_template;
727
728
  int ett;
729
  int hf_value;
730
  erf_meta_tag_info_ex_t *extra;
731
  /* TODO: could add a type_value and callback here for greater flexibility */
732
} erf_meta_tag_info_t;
733
734
typedef struct {
735
  wmem_map_t* tag_table;
736
  wmem_array_t* hfri;
737
  wmem_array_t* ett;
738
  wmem_array_t* vs_list;
739
  wmem_array_t* vs_abbrev_list;
740
  erf_meta_tag_info_t* unknown_section_info;
741
} erf_meta_index_t;
742
743
typedef struct {
744
  wmem_map_t* source_map;
745
  wmem_map_t* host_anchor_map;
746
  uint64_t implicit_host_id;
747
} erf_state_t;
748
749
typedef struct {
750
  wmem_tree_t* meta_tree;
751
  wmem_list_t* meta_list;
752
} erf_source_info_t;
753
754
typedef struct {
755
  unsigned frame_num;
756
} erf_anchored_info_t;
757
758
typedef struct {
759
  wmem_tree_t* anchored_tree;
760
  wmem_list_t* anchored_list;
761
} erf_host_anchor_info_t;
762
763
typedef struct {
764
  uint64_t host_id;
765
  uint64_t anchor_id;
766
} erf_anchor_key_t;
767
768
0
#define ERF_SOURCE_KEY(host_id, source_id) (((uint64_t) host_id << 16) | source_id)
769
#define ERF_TAG_INFO_KEY(tag_info) (((uint32_t) (tag_info)->section << 16) | (tag_info)->code)
770
771
static erf_meta_index_t erf_meta_index;
772
static erf_state_t erf_state;
773
774
/*
775
 * XXX: These header_field_info are used as templates for dynamically building
776
 * per-section fields for each tag, as well as appropriate value_string arrays.
777
 * We abuse the abbrev field to store the short name of the tags.
778
 */
779
static const erf_meta_hf_template_t erf_meta_tags[] = {
780
  { ERF_META_TAG_padding,           { "Padding",                            "padding",           FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
781
  { ERF_META_TAG_comment,           { "Comment",                            "comment",           FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
782
  { ERF_META_TAG_gen_time,          { "Metadata Generation Time",           "gen_time",          FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, NULL, HFILL } },
783
  { ERF_META_TAG_parent_section,    { "Parent Section",                     "parent_section",    FT_BYTES,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
784
  { ERF_META_TAG_reset,             { "Metadata Reset",                     "reset",             FT_BYTES,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
785
  { ERF_META_TAG_event_time,        { "Event Time",                         "event_time",        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, NULL, HFILL } },
786
  { ERF_META_TAG_host_id,           { "Host ID",                            "host_id",           FT_UINT64,        BASE_HEX,          NULL, 0x0, NULL, HFILL } },
787
  { ERF_META_TAG_attribute,         { "Attribute",                          "attribute",         FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
788
  { ERF_META_TAG_fcs_len,           { "FCS Length (bits)",                  "fcs_len",           FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
789
  { ERF_META_TAG_mask_ipv4,         { "Subnet Mask (IPv4)",                 "mask_ipv4",         FT_IPv4,          BASE_NETMASK,      NULL, 0x0, NULL, HFILL } },
790
  { ERF_META_TAG_mask_cidr,         { "Subnet Mask (CIDR)",                 "mask_cidr",         FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
791
792
  { ERF_META_TAG_org_name,          { "Organisation",                       "org_name",          FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
793
  { ERF_META_TAG_name,              { "Name",                               "name",              FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
794
  { ERF_META_TAG_descr,             { "Description",                        "descr",             FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
795
  { ERF_META_TAG_config,            { "Configuration",                      "config",            FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
796
  { ERF_META_TAG_datapipe,          { "Datapipe Name",                      "datapipe",          FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
797
  { ERF_META_TAG_app_name,          { "Application Name",                   "app_name",          FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
798
  { ERF_META_TAG_os,                { "Operating System",                   "os",                FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
799
  { ERF_META_TAG_hostname,          { "Hostname",                           "hostname",          FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
800
  { ERF_META_TAG_user,              { "User",                               "user",              FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
801
  { ERF_META_TAG_model,             { "Model",                              "model",             FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
802
  { ERF_META_TAG_fw_version,        { "Firmware Version",                   "fw_version",        FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
803
  { ERF_META_TAG_serial_no,         { "Serial Number",                      "serial_no",         FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
804
  { ERF_META_TAG_ts_offset,         { "Timestamp Offset",                   "ts_offset",         FT_RELATIVE_TIME, BASE_NONE,         NULL, 0x0, NULL, HFILL } },
805
  { ERF_META_TAG_ts_clock_freq,     { "Timestamp Clock Frequency (Hz)",     "ts_clock_freq",     FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
806
  { ERF_META_TAG_tzone,             { "Timezone Offset",                    "tzone",             FT_INT32,         BASE_DEC,          NULL, 0x0, NULL, HFILL } },
807
  { ERF_META_TAG_tzone_name,        { "Timezone Name",                      "tzone_name",        FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
808
  { ERF_META_TAG_loc_lat,           { "Location Latitude",                  "loc_lat",           FT_INT32,         BASE_DEC,          NULL, 0x0, NULL, HFILL } },
809
  { ERF_META_TAG_loc_long,          { "Location Longitude",                 "loc_long",          FT_INT32,         BASE_DEC,          NULL, 0x0, NULL, HFILL } },
810
  { ERF_META_TAG_snaplen,           { "Snap Length",                        "snaplen",           FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
811
  { ERF_META_TAG_card_num,          { "Card Number",                        "card_num",          FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
812
  { ERF_META_TAG_module_num,        { "Module Number",                      "module_num",        FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
813
  { ERF_META_TAG_access_num,        { "Access Number",                      "access_num",        FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
814
  { ERF_META_TAG_stream_num,        { "Stream Number",                      "stream_num",        FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
815
  { ERF_META_TAG_loc_name,          { "Location Name",                      "loc_name",          FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
816
  { ERF_META_TAG_parent_file,       { "Parent Filename",                    "parent_file",       FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
817
  { ERF_META_TAG_filter,            { "Filter",                             "filter",            FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
818
  { ERF_META_TAG_flow_hash_mode,    { "Flow Hash Mode",                     "flow_hash_mode",    FT_UINT32,        BASE_DEC,          VALS(erf_hash_mode), 0x0, NULL, HFILL } },
819
  { ERF_META_TAG_tunneling_mode,    { "Tunneling Mode",                     "tunneling_mode",    FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
820
  { ERF_META_TAG_npb_format,        { "NPB Format",                         "npb_format",        FT_BYTES,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
821
  { ERF_META_TAG_mem,               { "Memory",                             "mem",               FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
822
  { ERF_META_TAG_datamine_id,       { "Datamine ID",                        "datamine_id",       FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
823
  { ERF_META_TAG_rotfile_id,        { "Rotfile ID",                         "rotfile_id",        FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
824
  { ERF_META_TAG_rotfile_name,      { "Rotfile Name",                       "rotfile_name",      FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
825
  { ERF_META_TAG_dev_name,          { "Device Name",                        "dev_name",          FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
826
  { ERF_META_TAG_dev_path,          { "Device Canonical Path",              "dev_path",          FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
827
  { ERF_META_TAG_loc_descr,         { "Location Description",               "loc_descr",         FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
828
  { ERF_META_TAG_app_version,       { "Application Version",                "app_version",       FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
829
  { ERF_META_TAG_cpu_affinity,      { "CPU Affinity Mask",                  "cpu_affinity",      FT_BYTES,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
830
  { ERF_META_TAG_cpu,               { "CPU Model",                          "cpu",               FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
831
  { ERF_META_TAG_cpu_phys_cores,    { "CPU Physical Cores",                 "cpu_phys_cores",    FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
832
  { ERF_META_TAG_cpu_numa_nodes,    { "CPU NUMA Nodes",                     "cpu_numa_nodes",    FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
833
  { ERF_META_TAG_dag_attribute,     { "DAG Attribute",                      "dag_attribute",     FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
834
  { ERF_META_TAG_dag_version,       { "DAG Software Version",               "dag_version",       FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
835
  { ERF_META_TAG_stream_flags,      { "Stream Flags",                       "stream_flags",      FT_UINT32,        BASE_HEX,          NULL, 0x0, NULL, HFILL } },
836
  { ERF_META_TAG_entropy_threshold, { "Entropy Threshold",                  "entropy_threshold", FT_FLOAT,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
837
  { ERF_META_TAG_smart_trunc_default, { "Smart Truncation Default",         "smart_trunc_default",FT_UINT32,       BASE_DEC,          NULL, 0x0, NULL, HFILL } },
838
  { ERF_META_TAG_ext_hdrs_added,    { "Extension Headers Added",            "ext_hdrs_added",    FT_BYTES,         BASE_NO_DISPLAY_VALUE, NULL, 0x0, NULL, HFILL } },
839
  { ERF_META_TAG_ext_hdrs_removed,  { "Extension Headers Removed",          "ext_hdrs_removed",  FT_BYTES,         BASE_NO_DISPLAY_VALUE, NULL, 0x0, NULL, HFILL } },
840
  { ERF_META_TAG_relative_snaplen,  { "Relative Snap Length",               "relative_snaplen",  FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
841
  { ERF_META_TAG_temperature,       { "Temperature",                        "temperature",       FT_FLOAT,         BASE_NONE|BASE_UNIT_STRING, UNS(&units_degree_celsius), 0x0, NULL, HFILL } },
842
  { ERF_META_TAG_power,             { "Power Consumption",                  "power",             FT_FLOAT,         BASE_NONE|BASE_UNIT_STRING, UNS(&units_watt), 0x0, NULL, HFILL } },
843
  { ERF_META_TAG_vendor,            { "Vendor",                             "vendor",            FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
844
  { ERF_META_TAG_cpu_threads,       { "CPU Threads",                        "cpu_threads",       FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
845
846
  { ERF_META_TAG_if_num,            { "Interface Number",                   "if_num",            FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
847
  { ERF_META_TAG_if_vc,             { "Interface Virtual Circuit",          "if_vc",             FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
848
  { ERF_META_TAG_if_speed,          { "Interface Line Rate",                "if_speed",          FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
849
  { ERF_META_TAG_if_ipv4,           { "Interface IPv4 address",             "if_ipv4",           FT_IPv4,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
850
  { ERF_META_TAG_if_ipv6,           { "Interface IPv6 address",             "if_ipv6",           FT_IPv6,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
851
  { ERF_META_TAG_if_mac,            { "Interface MAC address",              "if_mac",            FT_ETHER,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
852
  { ERF_META_TAG_if_eui,            { "Interface EUI-64 address",           "if_eui",            FT_EUI64,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
853
  { ERF_META_TAG_if_ib_gid,         { "Interface InfiniBand GID",           "if_ib_gid",         FT_IPv6,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
854
  { ERF_META_TAG_if_ib_lid,         { "Interface InfiniBand LID",           "if_ib_lid",         FT_UINT16,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
855
  { ERF_META_TAG_if_wwn,            { "Interface WWN",                      "if_wwn",            FT_BYTES,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
856
  { ERF_META_TAG_if_fc_id,          { "Interface FCID address",             "if_fc_id",          FT_BYTES,         SEP_DOT,           NULL, 0x0, NULL, HFILL } },
857
  { ERF_META_TAG_if_tx_speed,       { "Interface TX Line Rate",             "if_tx_speed",       FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
858
  { ERF_META_TAG_if_erf_type,       { "Interface ERF type",                 "if_erf_type",       FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
859
  { ERF_META_TAG_if_link_type,      { "Interface link type",                "if_link_type",      FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
860
  { ERF_META_TAG_if_sfp_type,       { "Interface Transceiver type",         "if_sfp_type",       FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
861
  { ERF_META_TAG_if_rx_power,       { "Interface RX Optical Power",         "if_rx_power",       FT_INT32,         BASE_DEC,          NULL, 0x0, NULL, HFILL } },
862
  { ERF_META_TAG_if_tx_power,       { "Interface TX Optical Power",         "if_tx_power",       FT_INT32,         BASE_DEC,          NULL, 0x0, NULL, HFILL } },
863
  { ERF_META_TAG_if_link_status,    { "Interface Link Status",              "if_link_status",    FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
864
  { ERF_META_TAG_if_phy_mode,       { "Interface Endace PHY Mode",          "if_phy_mode",       FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
865
  { ERF_META_TAG_if_port_type,      { "Interface Port Type",                "if_port_type",      FT_UINT32,        BASE_DEC,          VALS(erf_port_type), 0x0, NULL, HFILL } },
866
  { ERF_META_TAG_if_rx_latency,     { "Interface Uncorrected RX Latency",   "if_rx_latency",     FT_RELATIVE_TIME, BASE_NONE,         NULL, 0x0, NULL, HFILL } },
867
  { ERF_META_TAG_tap_mode,          { "Tap Mode",                           "tap_mode",          FT_UINT32,        BASE_DEC,          VALS(erf_tap_mode), 0x0, NULL, HFILL } },
868
  { ERF_META_TAG_tap_fail_mode,     { "Tap Failover Mode",                  "tap_fail_mode",     FT_UINT32,        BASE_DEC,          VALS(erf_tap_fail_mode), 0x0, NULL, HFILL } },
869
  { ERF_META_TAG_watchdog_expired,  { "Watchdog Expired",                   "watchdog_expired",  FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
870
  { ERF_META_TAG_watchdog_interval, { "Watchdog Interval (ms)",             "watchdog_interval", FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
871
872
  { ERF_META_TAG_src_ipv4,          { "Source IPv4 address",                "src_ipv4",          FT_IPv4,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
873
  { ERF_META_TAG_dest_ipv4,         { "Destination IPv4 address",           "dest_ipv4",         FT_IPv4,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
874
  { ERF_META_TAG_src_ipv6,          { "Source IPv6 address",                "src_ipv6",          FT_IPv6,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
875
  { ERF_META_TAG_dest_ipv6,         { "Destination IPv6 address",           "dest_ipv6",         FT_IPv6,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
876
  { ERF_META_TAG_src_mac,           { "Source MAC address",                 "src_mac",           FT_ETHER,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
877
  { ERF_META_TAG_dest_mac,          { "Destination MAC address",            "dest_mac",          FT_ETHER,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
878
  { ERF_META_TAG_src_eui,           { "Source EUI-64 address",              "src_eui",           FT_EUI64,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
879
  { ERF_META_TAG_dest_eui,          { "Destination EUI-64 address",         "dest_eui",          FT_EUI64,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
880
  { ERF_META_TAG_src_ib_gid,        { "Source InfiniBand GID address",      "src_ib_gid",        FT_IPv6,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
881
  { ERF_META_TAG_dest_ib_gid,       { "Destination InfiniBand GID address", "dest_ib_gid",       FT_IPv6,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
882
  { ERF_META_TAG_src_ib_lid,        { "Source InfiniBand LID address",      "src_ib_lid",        FT_UINT16,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
883
  { ERF_META_TAG_dest_ib_lid,       { "Destination InfiniBand LID address", "dest_ib_lid",       FT_UINT16,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
884
  { ERF_META_TAG_src_wwn,           { "Source WWN address",                 "src_wwn",           FT_BYTES,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
885
  { ERF_META_TAG_dest_wwn,          { "Destination WWN address",            "dest_wwn",          FT_BYTES,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
886
  { ERF_META_TAG_src_fc_id,         { "Source FCID address",                "src_fc_id",         FT_BYTES,         SEP_DOT,           NULL, 0x0, NULL, HFILL } },
887
  { ERF_META_TAG_dest_fc_id,        { "Destination FCID address",           "dest_fc_id",        FT_BYTES,         SEP_DOT,           NULL, 0x0, NULL, HFILL } },
888
  { ERF_META_TAG_src_port,          { "Source Port",                        "src_port",          FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
889
  { ERF_META_TAG_dest_port,         { "Destination Port",                   "dest_port",         FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
890
  { ERF_META_TAG_ip_proto,          { "IP Protocol",                        "ip_proto",          FT_UINT32,        BASE_DEC|BASE_EXT_STRING, &ipproto_val_ext, 0x0, NULL, HFILL } },
891
  { ERF_META_TAG_flow_hash,         { "Flow Hash",                          "flow_hash",         FT_UINT32,        BASE_HEX,          NULL, 0x0, NULL, HFILL } },
892
  { ERF_META_TAG_filter_match,      { "Filter Match",                       "filter_match",      FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
893
  { ERF_META_TAG_filter_match_name, { "Filter Match Name",                  "filter_match_name", FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
894
  { ERF_META_TAG_error_flags,       { "Error Flags",                        "error_flags",       FT_BYTES,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
895
  { ERF_META_TAG_initiator_pkts,    { "Initiator Packets",                  "initiator_pkts",    FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
896
  { ERF_META_TAG_responder_pkts,    { "Responder Packets",                  "responder_pkts",    FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
897
  { ERF_META_TAG_initiator_bytes,   { "Initiator Bytes",                    "initiator_bytes",   FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
898
  { ERF_META_TAG_responder_bytes,   { "Responder Bytes",                    "responder_bytes",   FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
899
  { ERF_META_TAG_initiator_min_entropy, { "Initiator Minimum Entropy",      "initiator_min_entropy", FT_FLOAT,     BASE_NONE,         NULL, 0x0, NULL, HFILL } },
900
  { ERF_META_TAG_responder_min_entropy, { "Responder Minimum Entropy",      "responder_min_entropy", FT_FLOAT,     BASE_NONE,         NULL, 0x0, NULL, HFILL } },
901
  { ERF_META_TAG_initiator_avg_entropy, { "Initiator Average Entropy",      "initiator_avg_entropy", FT_FLOAT,     BASE_NONE,         NULL, 0x0, NULL, HFILL } },
902
  { ERF_META_TAG_responder_avg_entropy, { "Responder Average Entropy",      "responder_avg_entropy", FT_FLOAT,     BASE_NONE,         NULL, 0x0, NULL, HFILL } },
903
  { ERF_META_TAG_initiator_max_entropy, { "Initiator Maximum Entropy",      "initiator_max_entropy", FT_FLOAT,     BASE_NONE,         NULL, 0x0, NULL, HFILL } },
904
  { ERF_META_TAG_responder_max_entropy, { "Responder Maximum Entropy",      "responder_max_entropy", FT_FLOAT,     BASE_NONE,         NULL, 0x0, NULL, HFILL } },
905
  { ERF_META_TAG_dpi_application,       { "DPI Application",                "dpi_application",   FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
906
  { ERF_META_TAG_dpi_confidence,        { "DPI Confidence",                 "dpi_confidence",    FT_STRING,        BASE_NONE,         NULL, 0x0, NULL, HFILL } },
907
  { ERF_META_TAG_dpi_state,             { "DPI State",                      "dpi_state",         FT_UINT32,        BASE_NONE,         VALS(erf_dpi_state), 0x0, NULL, HFILL } },
908
  { ERF_META_TAG_dpi_protocol_stack,    { "DPI Protocol Stack",             "dpi_protocol_stack", FT_STRING,       BASE_NONE,         NULL, 0x0, NULL, HFILL } },
909
  { ERF_META_TAG_flow_state,            { "Flow State",                     "flow_state",        FT_UINT32,        BASE_NONE,         VALS(erf_flow_state), 0x0, NULL, HFILL } },
910
  { ERF_META_TAG_vlan_id,           { "VLAN ID",                            "vlan_id",           FT_INT32,         BASE_DEC,          NULL, 0x0, NULL, HFILL } },
911
  { ERF_META_TAG_mpls_label,        { "MPLS Label",                         "mpls_label",        FT_INT32,         BASE_DEC,          NULL, 0x0, NULL, HFILL } },
912
  { ERF_META_TAG_vlan_pcp,          { "VLAN PCP",                           "vlan_pcp",          FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
913
  { ERF_META_TAG_mpls_tc,           { "MPLS_TC",                            "mpls_tc",           FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
914
  { ERF_META_TAG_dscp,              { "DSCP",                               "dscp",              FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
915
  { ERF_META_TAG_initiator_mpls_label, { "Initiator MPLS Label",            "initiator_mpls_label", FT_INT32,      BASE_DEC,          NULL, 0x0, NULL, HFILL } },
916
  { ERF_META_TAG_responder_mpls_label, { "Responder MPLS Label",            "responder_mpls_label", FT_INT32,      BASE_DEC,          NULL, 0x0, NULL, HFILL } },
917
  { ERF_META_TAG_initiator_mpls_tc, { "Initiator MPLS TC",                  "initiator_mpls_tc", FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
918
  { ERF_META_TAG_responder_mpls_tc, { "Responder MPLS TC",                  "responder_mpls_tc", FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
919
  { ERF_META_TAG_initiator_ipv4,    { "Initiator IPv4",                     "initiator_ipv4",    FT_IPv4,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
920
  { ERF_META_TAG_responder_ipv4,    { "Responder IPv4",                     "responder_ipv4",    FT_IPv4,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
921
  { ERF_META_TAG_initiator_ipv6,    { "Initiator IPv6",                     "initiator_ipv6",    FT_IPv6,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
922
  { ERF_META_TAG_responder_ipv6,    { "Responder IPv6",                     "responder_ipv6",    FT_IPv6,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
923
  { ERF_META_TAG_initiator_mac,     { "Initiator MAC Address",              "initiator_mac",     FT_ETHER,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
924
  { ERF_META_TAG_responder_mac,     { "Responder MAC Address",              "responder_mac",     FT_ETHER,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
925
  { ERF_META_TAG_initiator_port,    { "Initiator Port",                     "initiator_port",    FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
926
  { ERF_META_TAG_responder_port,    { "Responder Port",                     "responder_port",    FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
927
  { ERF_META_TAG_initiator_retx,    { "Initiator Retransmissions",          "initiator_retx",    FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
928
  { ERF_META_TAG_responder_retx,    { "Responder Retransmissions",          "responder_retx",    FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
929
  { ERF_META_TAG_initiator_zwin,    { "Initiator Zero Window Count",        "initiator_zwin",    FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
930
  { ERF_META_TAG_responder_zwin,    { "Responder Zero Window Count",        "responder_zwin",    FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
931
  { ERF_META_TAG_initiator_tcp_flags, { "Initiator TCP Flags",              "initiator_flags",   FT_BYTES,         BASE_NONE,          NULL, 0x0, NULL, HFILL } },
932
  { ERF_META_TAG_responder_tcp_flags, { "Responder TCP Flags",              "responder_flags",   FT_BYTES,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
933
  { ERF_META_TAG_tcp_irtt,          { "TCP Initial Round Trip Time",        "tcp_irtt",          FT_RELATIVE_TIME, BASE_NONE,         NULL, 0x0, NULL, HFILL } },
934
935
  { ERF_META_TAG_start_time,        { "Start Time",                         "start_time",        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, NULL, HFILL } },
936
  { ERF_META_TAG_end_time,          { "End Time",                           "end_time",          FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0, NULL, HFILL } },
937
  { ERF_META_TAG_stat_if_drop,      { "Interface Drop",                     "stat_if_drop",      FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
938
  { ERF_META_TAG_stat_frames,       { "Packets Received",                   "stat_frames",       FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
939
  { ERF_META_TAG_stat_bytes,        { "Bytes Received",                     "stat_bytes",        FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
940
  { ERF_META_TAG_stat_cap,          { "Packets Captured",                   "stat_cap",          FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
941
  { ERF_META_TAG_stat_cap_bytes,    { "Bytes Captured",                     "stat_cap_bytes",    FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
942
  { ERF_META_TAG_stat_os_drop,      { "OS Drop",                            "stat_os_drop",      FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
943
  { ERF_META_TAG_stat_ds_lctr,      { "Internal Error Drop",                "stat_ds_lctr",      FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
944
  { ERF_META_TAG_stat_filter_match, { "Filter Match",                       "stat_filter_match", FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
945
  { ERF_META_TAG_stat_filter_drop,  { "Filter Drop",                        "stat_filter_drop",  FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
946
  { ERF_META_TAG_stat_too_short,    { "Packets Too Short",                  "stat_too_short",    FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
947
  { ERF_META_TAG_stat_too_long,     { "Packets Too Long",                   "stat_too_long",     FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
948
  { ERF_META_TAG_stat_rx_error,     { "Packets RX Error",                   "stat_rx_error",     FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
949
  { ERF_META_TAG_stat_fcs_error,    { "Packets FCS Error",                  "stat_fcs_error",    FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
950
  { ERF_META_TAG_stat_aborted,      { "Packets Aborted",                    "stat_aborted",      FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
951
  { ERF_META_TAG_stat_proto_error,  { "Packets Protocol Error",             "stat_proto_error",  FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
952
  { ERF_META_TAG_stat_b1_error,     { "SDH B1 Errors",                      "stat_b1_error",     FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
953
  { ERF_META_TAG_stat_b2_error,     { "SDH B2 Errors",                      "stat_b2_error",     FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
954
  { ERF_META_TAG_stat_b3_error,     { "SDH B3 Errors",                      "stat_b3_error",     FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
955
  { ERF_META_TAG_stat_rei_error,    { "SDH REI Errors",                     "stat_rei_error",    FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
956
  { ERF_META_TAG_stat_drop,         { "Packets Dropped",                    "stat_drop",         FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
957
  { ERF_META_TAG_stat_buf_drop,     { "Buffer Drop",                        "stat_buf_drop",     FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
958
  { ERF_META_TAG_stream_drop,       { "Stream Drop",                        "stream_drop",       FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
959
  { ERF_META_TAG_stream_buf_drop,   { "Stream Buffer Drop",                 "stream_buf_drop",   FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
960
  { ERF_META_TAG_pkt_drop,          { "Packet Drop",                        "packet_drop",       FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
961
  { ERF_META_TAG_record_drop,       { "Record Drop",                        "record_drop",       FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
962
  { ERF_META_TAG_bandwidth,         { "Bandwidth",                          "bandwidth",         FT_UINT64,        BASE_DEC|BASE_UNIT_STRING, UNS(&units_bit_sec), 0x0, NULL, HFILL } },
963
  { ERF_META_TAG_duration,          { "Duration",                           "duration",          FT_RELATIVE_TIME, BASE_NONE,         NULL, 0x0, NULL, HFILL } },
964
  { ERF_META_TAG_top_index,         { "Top N Index",                        "top_index",         FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
965
  { ERF_META_TAG_concurrent_flows,  { "Concurrent Flows",                   "concurrent_flows",  FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
966
  { ERF_META_TAG_active_flows,      { "Active Flows",                       "active_flows",      FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
967
  { ERF_META_TAG_created_flows,     { "Created Flows",                      "created_flows",     FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
968
  { ERF_META_TAG_deleted_flows,     { "Deleted Flows",                      "deleted_flows",     FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
969
  { ERF_META_TAG_active_endpoints,  { "Active Endpoints",                   "active_endpoints",  FT_UINT32,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
970
  { ERF_META_TAG_tx_pkts,           { "Transmitted Packets",                "tx_packets",        FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
971
  { ERF_META_TAG_tx_bytes,          { "Transmitted Bytes",                  "tx_bytes",          FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
972
  { ERF_META_TAG_rx_bandwidth,      { "Receive Bandwidth",                  "rx_bandwidth",      FT_UINT64,        BASE_DEC|BASE_UNIT_STRING, UNS(&units_bit_sec), 0x0, NULL, HFILL } },
973
  { ERF_META_TAG_tx_bandwidth,      { "Transmit Bandwidth",                 "tx_bandwidth",      FT_UINT64,        BASE_DEC|BASE_UNIT_STRING, UNS(&units_bit_sec), 0x0, NULL, HFILL } },
974
  { ERF_META_TAG_records,           { "Records",                            "records",           FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
975
  { ERF_META_TAG_record_bytes,      { "Record Bytes",                       "record_bytes",      FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
976
  { ERF_META_TAG_pkt_drop_bytes,    { "Packet Drop Bytes",                  "packet_drop_bytes", FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
977
  { ERF_META_TAG_record_drop_bytes, { "Record Drop Bytes",                  "record_drop_bytes", FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
978
  { ERF_META_TAG_drop_bandwidth,    { "Drop Bandwidth",                     "drop_bandwidth",    FT_UINT64,        BASE_DEC|BASE_UNIT_STRING, UNS(&units_bit_sec), 0x0, NULL, HFILL } },
979
  { ERF_META_TAG_retx_pkts,         { "Retransmitted Packets",              "retx_packets",      FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
980
  { ERF_META_TAG_zwin_pkts,         { "Zero-Window Packets",                "zwin_packets",      FT_UINT64,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
981
982
  { ERF_META_TAG_ns_host_ipv4,      { "IPv4 Name",                          "ns_host_ipv4",      FT_IPv4,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
983
  { ERF_META_TAG_ns_host_ipv6,      { "IPv6 Name",                          "ns_host_ipv6",      FT_IPv6,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
984
  { ERF_META_TAG_ns_host_mac,       { "MAC Name",                           "ns_host_mac",       FT_ETHER,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
985
  { ERF_META_TAG_ns_host_eui,       { "EUI Name",                           "ns_host_eui",       FT_EUI64,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
986
  { ERF_META_TAG_ns_host_ib_gid,    { "InfiniBand GID Name",                "ns_host_ib_gid",    FT_IPv6,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
987
  { ERF_META_TAG_ns_host_ib_lid,    { "InfiniBand LID Name",                "ns_host_ib_lid",    FT_UINT16,        BASE_DEC,          NULL, 0x0, NULL, HFILL } },
988
  { ERF_META_TAG_ns_host_wwn,       { "WWN Name",                           "ns_host_wwn",       FT_BYTES,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
989
  { ERF_META_TAG_ns_host_fc_id,     { "FCID Name",                          "ns_host_fc_id",     FT_BYTES,         SEP_DOT,           NULL, 0x0, NULL, HFILL } },
990
  { ERF_META_TAG_ns_dns_ipv4,       { "Nameserver IPv4 address",            "ns_dns_ipv4",       FT_IPv4,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
991
  { ERF_META_TAG_ns_dns_ipv6,       { "Nameserver IPv6 address",            "ns_dns_ipv6",       FT_IPv6,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
992
993
  { ERF_META_TAG_exthdr,            { "ERF Extension Header",               "exthdr",            FT_BYTES,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
994
  { ERF_META_TAG_pcap_ng_block,     { "Pcapng Block",                       "pcap_ng_block",     FT_BYTES,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
995
  { ERF_META_TAG_asn1,              { "ASN.1",                              "asn1",              FT_BYTES,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
996
  { ERF_META_TAG_section_ref,       { "Section Reference",                  "section_ref",       FT_BYTES,         BASE_NONE,         NULL, 0x0, NULL, HFILL } },
997
998
  { ERF_META_TAG_clk_source,             { "Clock Source",                  "clk_source",             FT_UINT32,   BASE_DEC,          VALS(erf_clk_source), 0x0, NULL, HFILL } },
999
  { ERF_META_TAG_clk_state,              { "Clock State",                   "clk_state",              FT_UINT32,   BASE_DEC,          VALS(erf_clk_state), 0x0, NULL, HFILL } },
1000
  { ERF_META_TAG_clk_threshold,          { "Clock Threshold",               "clk_threshold",          FT_RELATIVE_TIME, BASE_NONE,    NULL, 0x0, NULL, HFILL } },
1001
  { ERF_META_TAG_clk_correction,         { "Clock Correction",              "clk_correction",         FT_RELATIVE_TIME, BASE_NONE,    NULL, 0x0, NULL, HFILL } },
1002
  { ERF_META_TAG_clk_failures,           { "Clock Failures",                "clk_failures",           FT_UINT32,   BASE_DEC,          NULL, 0x0, NULL, HFILL } },
1003
  { ERF_META_TAG_clk_resyncs,            { "Clock Resyncs",                 "clk_resyncs",            FT_UINT32,   BASE_DEC,          NULL, 0x0, NULL, HFILL } },
1004
  { ERF_META_TAG_clk_phase_error,        { "Clock Phase Error",             "clk_phase_error",        FT_RELATIVE_TIME, BASE_NONE,    NULL, 0x0, NULL, HFILL } },
1005
  { ERF_META_TAG_clk_input_pulses,       { "Clock Input Pulses",            "clk_input_pulses",       FT_UINT32,   BASE_DEC,          NULL, 0x0, NULL, HFILL } },
1006
  { ERF_META_TAG_clk_rejected_pulses,    { "Clock Rejected Pulses",         "clk_rejected_pulses",    FT_UINT32,   BASE_DEC,          NULL, 0x0, NULL, HFILL } },
1007
  { ERF_META_TAG_clk_phc_index,          { "Clock PHC Index",               "clk_phc_index",          FT_UINT32,   BASE_DEC,          NULL, 0x0, NULL, HFILL } },
1008
  { ERF_META_TAG_clk_phc_offset,         { "Clock PHC Offset",              "clk_phc_offset",         FT_RELATIVE_TIME, BASE_NONE,    NULL, 0x0, NULL, HFILL } },
1009
  { ERF_META_TAG_clk_timebase,           { "Clock Timebase",                "clk_timebase",           FT_STRING,   BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1010
  { ERF_META_TAG_clk_descr,              { "Clock Description",             "clk_descr",              FT_STRING,   BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1011
  { ERF_META_TAG_clk_out_source,         { "Clock Output Source",           "clk_out_source",         FT_UINT32,   BASE_DEC,          VALS(erf_clk_source), 0x0, NULL, HFILL } },
1012
  { ERF_META_TAG_clk_link_mode,          { "Clock Link Cable Mode",         "clk_link_mode",          FT_UINT32,   BASE_DEC,          VALS(erf_clk_link_mode), 0x0, NULL, HFILL } },
1013
1014
  /*
1015
   * PTP tags use the native PTPv2 format to preserve precision
1016
   * (except expanding integers to 32-bit).
1017
   */
1018
  { ERF_META_TAG_ptp_domain_num,         { "PTP Domain Number",             "ptp_domain_num",         FT_UINT32,   BASE_DEC,          NULL, 0x0, NULL, HFILL } },
1019
  { ERF_META_TAG_ptp_steps_removed,      { "PTP Steps Removed",             "ptp_steps_removed",      FT_UINT32,   BASE_DEC,          NULL, 0x0, NULL, HFILL } },
1020
  /* PTP TimeInterval scaled nanoseconds, using FT_RELATIVE_TIME so can compare with clk_threshold */
1021
  { ERF_META_TAG_ptp_offset_from_master, { "PTP Offset From Master",        "ptp_offset_from_master", FT_RELATIVE_TIME, BASE_NONE,    NULL, 0x0, NULL, HFILL } },
1022
  { ERF_META_TAG_ptp_mean_path_delay,    { "PTP Mean Path Delay",           "ptp_mean_path_delay",    FT_RELATIVE_TIME, BASE_NONE,    NULL, 0x0, NULL, HFILL } },
1023
  { ERF_META_TAG_ptp_parent_identity,    { "PTP Parent Clock Identity",     "ptp_parent_identity",    FT_EUI64,    BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1024
  { ERF_META_TAG_ptp_parent_port_num,    { "PTP Parent Port Number",        "ptp_parent_port_num",    FT_UINT32,   BASE_DEC,          NULL, 0x0, NULL, HFILL } },
1025
  { ERF_META_TAG_ptp_gm_identity,        { "PTP Grandmaster Identity",      "ptp_gm_identity",        FT_EUI64,    BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1026
  /* PTP ClockQuality combined field, see erf_ptp_clock_quality */
1027
  { ERF_META_TAG_ptp_gm_clock_quality,   { "PTP Grandmaster Clock Quality", "ptp_gm_clock_quality",   FT_UINT32,   BASE_HEX,          NULL, 0x0, NULL, HFILL } },
1028
  /* Integer seconds, using FT_RELATIVE_TIME so can compare with clk_phc_offset */
1029
  { ERF_META_TAG_ptp_current_utc_offset, { "PTP Current UTC Offset",        "ptp_current_utc_offset", FT_RELATIVE_TIME, BASE_NONE,    NULL, 0x0, NULL, HFILL } },
1030
  /* PTP TIME_PROPERTIES_DATA_SET flags, see erf_ptp_time_properties_flags */
1031
  { ERF_META_TAG_ptp_time_properties,    { "PTP Time Properties",           "ptp_time_properties",    FT_UINT32,   BASE_HEX,          NULL, 0x0, NULL, HFILL } },
1032
  { ERF_META_TAG_ptp_time_source,        { "PTP Time Source",               "ptp_time_source",        FT_UINT32,   BASE_DEC | BASE_EXT_STRING, &ptp_v2_timeSource_vals_ext, 0x0, NULL, HFILL } },
1033
  { ERF_META_TAG_ptp_clock_identity,     { "PTP Clock Identity",            "ptp_clock_identity",     FT_EUI64,    BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1034
  { ERF_META_TAG_ptp_port_num,           { "PTP Port Number",               "ptp_port_num",           FT_UINT32,   BASE_DEC,          NULL, 0x0, NULL, HFILL } },
1035
  { ERF_META_TAG_ptp_port_state,         { "PTP Port State",                "ptp_port_state",         FT_UINT32,   BASE_DEC | BASE_EXT_STRING, &ptp_v2_portState_vals_ext, 0x0, NULL, HFILL } },
1036
  { ERF_META_TAG_ptp_delay_mechanism,    { "PTP Delay Mechanism",           "ptp_delay_mechanism",    FT_UINT32,   BASE_DEC, VALS(ptp_v2_delayMechanism_vals), 0x0, NULL, HFILL } },
1037
1038
  { ERF_META_TAG_clk_port_proto,         { "Clock Input Port Protocol",     "clk_port_proto",         FT_UINT32,   BASE_DEC, VALS(erf_clk_port_proto), 0x0, NULL, HFILL } },
1039
1040
  { ERF_META_TAG_ntp_status,             { "NTP Status",                    "ntp_status",             FT_UINT32,   BASE_DEC,          NULL, 0x0, NULL, HFILL } },
1041
  { ERF_META_TAG_ntp_stratum,            { "NTP Stratum",                   "ntp_stratum",            FT_UINT32,   BASE_DEC,          NULL, 0x0, NULL, HFILL } },
1042
  { ERF_META_TAG_ntp_rootdelay,          { "NTP Root Delay",                "ntp_root_delay",         FT_INT32,    BASE_DEC,          NULL, 0x0, NULL, HFILL } },
1043
  { ERF_META_TAG_ntp_rootdisp,           { "NTP Root Dispersion",           "ntp_root_dispersion",    FT_UINT32,   BASE_DEC,          NULL, 0x0, NULL, HFILL } },
1044
  { ERF_META_TAG_ntp_offset,             { "NTP Offset",                    "ntp_offset",             FT_INT32,    BASE_DEC,          NULL, 0x0, NULL, HFILL } },
1045
  { ERF_META_TAG_ntp_frequency,          { "NTP Frequency",                 "ntp_frequency",          FT_INT32,    BASE_DEC|BASE_UNIT_STRING, UNS(&units_hz), 0x0, NULL, HFILL } },
1046
  { ERF_META_TAG_ntp_sys_jitter,         { "NTP System Jitter",             "ntp_sys_jitter",         FT_UINT32,   BASE_DEC,          NULL, 0x0, NULL, HFILL } },
1047
  { ERF_META_TAG_ntp_peer_remote,        { "NTP Peer Remote",               "ntp_peer_remote",        FT_STRING,   BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1048
  { ERF_META_TAG_ntp_peer_refid,         { "NTP Peer Refid",                "ntp_peer_refid",         FT_STRING,   BASE_NONE,         NULL, 0x0, NULL, HFILL } }
1049
};
1050
1051
/* Sections are also tags, but enumerate them separately to make logic simpler */
1052
static const erf_meta_hf_template_t erf_meta_sections[] = {
1053
  /*
1054
   * Some tags (such as generation time) can appear before the first section,
1055
   * we group these together into a fake section for consistency.
1056
   */
1057
  { ERF_META_SECTION_NONE,          { "No Section",                         "section_none",      FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1058
  { ERF_META_SECTION_UNKNOWN,       { "Unknown Section",                    "section_unknown",   FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1059
1060
  { ERF_META_SECTION_CAPTURE,       { "Capture Section",                    "section_capture",   FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1061
  { ERF_META_SECTION_HOST,          { "Host Section",                       "section_host",      FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1062
  { ERF_META_SECTION_MODULE,        { "Module Section",                     "section_module",    FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1063
  { ERF_META_SECTION_INTERFACE,     { "Interface Section",                  "section_interface", FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1064
  { ERF_META_SECTION_FLOW,          { "Flow Section",                       "section_flow",      FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1065
  { ERF_META_SECTION_STATS,         { "Statistics Section",                 "section_stats",     FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1066
  { ERF_META_SECTION_INFO,          { "Information Section",                "section_info",      FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1067
  { ERF_META_SECTION_CONTEXT,       { "Context Section",                    "section_context",   FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1068
  { ERF_META_SECTION_STREAM,        { "Stream Section",                     "section_stream",    FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1069
  { ERF_META_SECTION_TRANSFORM,     { "Transform Section",                  "section_transform", FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1070
  { ERF_META_SECTION_DNS,           { "DNS Section",                        "section_dns",       FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1071
  { ERF_META_SECTION_SOURCE,        { "Source Section",                     "section_source",    FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1072
  { ERF_META_SECTION_NETWORK,       { "Network Section",                    "section_network",   FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1073
  { ERF_META_SECTION_ENDPOINT,      { "Endpoint Section",                   "section_endpoint",  FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1074
  { ERF_META_SECTION_INPUT,         { "Input Section",                      "section_input",     FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } },
1075
  { ERF_META_SECTION_OUTPUT,        { "Output Section",                     "section_output",    FT_NONE,          BASE_NONE,         NULL, 0x0, NULL, HFILL } }
1076
};
1077
1078
0
static int erf_type_has_color(unsigned int type) {
1079
0
  switch (type & ERF_HDR_TYPE_MASK) {
1080
0
  case ERF_TYPE_COLOR_HDLC_POS:
1081
0
  case ERF_TYPE_COLOR_ETH:
1082
0
  case ERF_TYPE_COLOR_HASH_POS:
1083
0
  case ERF_TYPE_COLOR_HASH_ETH:
1084
0
  case ERF_TYPE_DSM_COLOR_HDLC_POS:
1085
0
  case ERF_TYPE_DSM_COLOR_ETH:
1086
0
  case ERF_TYPE_COLOR_MC_HDLC_POS:
1087
0
    return 1;
1088
0
  }
1089
0
  return 0;
1090
0
}
1091
1092
0
static erf_meta_tag_info_ex_t* erf_meta_tag_info_ex_new(wmem_allocator_t *allocator) {
1093
0
  size_t i = 0;
1094
0
  erf_meta_tag_info_ex_t *extra = wmem_new0(allocator, erf_meta_tag_info_ex_t);
1095
1096
0
  extra->ett_value = -1;
1097
0
  for (i = 0; i < array_length(extra->hf_values); i++) {
1098
0
    extra->hf_values[i] = -1;
1099
0
  }
1100
1101
0
  return extra;
1102
0
}
1103
1104
0
static erf_meta_tag_info_t* erf_meta_tag_info_new(wmem_allocator_t *allocator, const erf_meta_hf_template_t *section, const erf_meta_hf_template_t *tag) {
1105
0
  erf_meta_tag_info_t *tag_info = wmem_new0(allocator, erf_meta_tag_info_t);
1106
1107
0
  tag_info->code = tag->code;
1108
0
  tag_info->section = section->code;
1109
0
  tag_info->ett = -1;
1110
0
  tag_info->hf_value = -1;
1111
0
  tag_info->tag_template = tag;
1112
0
  tag_info->section_template = section;
1113
0
  tag_info->extra = NULL;
1114
1115
0
  return tag_info;
1116
0
}
1117
1118
static erf_meta_tag_info_t*
1119
init_section_fields(wmem_array_t *hfri_table, wmem_array_t *ett_table, const erf_meta_hf_template_t *section)
1120
0
{
1121
0
  erf_meta_tag_info_t *section_info;
1122
0
  int                 *ett_tmp; /* wmem_array_append needs actual memory to copy from */
1123
0
  hf_register_info     hfri_tmp[] = {
1124
0
    { NULL, { "Section ID", NULL, FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, /* Section ID */
1125
0
    { NULL, { "Section Length", NULL, FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},  /* Section Length */
1126
0
    { NULL, { "Reserved", NULL, FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }} /* Reserved extra bytes */
1127
0
  };
1128
1129
0
  section_info = erf_meta_tag_info_new(wmem_epan_scope(), section, section /*Needed for lookup commonality*/);
1130
0
  section_info->extra = erf_meta_tag_info_ex_new(wmem_epan_scope());
1131
1132
  /*Can't use the generic functions here because directly at section level*/
1133
0
  hfri_tmp[0].hfinfo.abbrev = wmem_strconcat(wmem_epan_scope(), "erf.meta.", section->hfinfo.abbrev, ".section_id", NULL);
1134
0
  hfri_tmp[0].p_id = &section_info->hf_value;
1135
0
  hfri_tmp[1].hfinfo.abbrev = wmem_strconcat(wmem_epan_scope(), "erf.meta.", section->hfinfo.abbrev, ".section_len", NULL);
1136
0
  hfri_tmp[1].p_id = &section_info->extra->hf_values[0];
1137
0
  hfri_tmp[2].hfinfo.abbrev = wmem_strconcat(wmem_epan_scope(), "erf.meta.", section->hfinfo.abbrev, ".section_hdr_rsvd", NULL);
1138
0
  hfri_tmp[2].p_id = &section_info->extra->hf_values[1];
1139
1140
  /* Add hf_register_info, ett entries */
1141
0
  wmem_array_append(hfri_table, hfri_tmp, array_length(hfri_tmp));
1142
0
  ett_tmp = &section_info->ett;
1143
0
  wmem_array_append(ett_table, &ett_tmp, 1);
1144
0
  ett_tmp = &section_info->extra->ett_value;
1145
0
  wmem_array_append(ett_table, &ett_tmp, 1);
1146
1147
0
  return section_info;
1148
0
}
1149
1150
static erf_meta_tag_info_t*
1151
init_tag_value_field(wmem_array_t *hfri_table, erf_meta_tag_info_t *tag_info)
1152
0
{
1153
0
  hf_register_info     hfri_tmp = { NULL, { NULL, NULL, FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}; /* Value, will be filled from template */
1154
1155
  /* Add value field */
1156
0
  hfri_tmp.p_id = &tag_info->hf_value;
1157
0
  hfri_tmp.hfinfo = tag_info->tag_template->hfinfo;
1158
0
  hfri_tmp.hfinfo.abbrev = wmem_strconcat(wmem_epan_scope(), "erf.meta.", tag_info->section_template->hfinfo.abbrev, ".", tag_info->tag_template->hfinfo.abbrev, NULL);
1159
0
  wmem_array_append_one(hfri_table, hfri_tmp);
1160
1161
0
  return tag_info;
1162
0
}
1163
1164
static erf_meta_tag_info_t*
1165
init_tag_value_subfields(wmem_array_t *hfri_table, erf_meta_tag_info_t *tag_info, const header_field_info *extra_fields, int extra_fields_len)
1166
0
{
1167
0
  int                  i = 0;
1168
0
  hf_register_info     hfri_tmp = { NULL, { NULL, NULL, FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}; /* Value, will be filled from template */
1169
1170
0
  if (extra_fields) {
1171
0
    tag_info->extra = erf_meta_tag_info_ex_new(wmem_epan_scope());
1172
0
    for (i = 0; i < extra_fields_len; i++) {
1173
      /* Add value subfield */
1174
0
      hfri_tmp.p_id = &tag_info->extra->hf_values[i];
1175
0
      hfri_tmp.hfinfo = extra_fields[i];
1176
0
      hfri_tmp.hfinfo.abbrev = wmem_strconcat(wmem_epan_scope(), "erf.meta.", tag_info->section_template->hfinfo.abbrev, ".", tag_info->tag_template->hfinfo.abbrev, ".", extra_fields[i].abbrev, NULL);
1177
0
      wmem_array_append_one(hfri_table, hfri_tmp);
1178
0
    }
1179
0
  }
1180
1181
0
  return tag_info;
1182
0
}
1183
1184
static erf_meta_tag_info_t*
1185
init_ext_hdrs_tag_value_subfields(wmem_array_t *hfri_table, erf_meta_tag_info_t *tag_info)
1186
0
{
1187
0
  size_t               i = 0;
1188
0
  size_t               num_known_ext_hdrs = array_length(ehdr_type_vals) -1 /*null terminated*/;
1189
0
  hf_register_info     hfri_tmp = { NULL, { NULL, NULL, FT_BOOLEAN, 32, NULL, 0x1, NULL, HFILL } }; /* Value, will be filled from template */
1190
1191
0
  DISSECTOR_ASSERT(array_length(ehdr_type_vals_short) > num_known_ext_hdrs);
1192
  /* XXX: this currently supports only up to 27 known extension headers */
1193
0
  DISSECTOR_ASSERT(ERF_HF_VALUES_PER_TAG > num_known_ext_hdrs - 4); /* -1 sentinel terminated */
1194
  /* Use the first 4 hf_values for 32-bit subtree */
1195
0
  init_tag_value_subfields(hfri_table, tag_info, erf_ext_hdr_items, array_length(erf_ext_hdr_items));
1196
0
  DISSECTOR_ASSERT(tag_info->extra);
1197
1198
  /*Fill in the rest of the remaining 27 entries with any known tag entries values */
1199
0
  for (i = 0; i < num_known_ext_hdrs; i++) {
1200
    /* Add value subfield */
1201
0
    hfri_tmp.p_id = &tag_info->extra->hf_values[4+i];
1202
0
    hfri_tmp.hfinfo.bitmask = (uint64_t)1 << ehdr_type_vals[i].value;
1203
0
    hfri_tmp.hfinfo.name = ehdr_type_vals[i].strptr;
1204
0
    hfri_tmp.hfinfo.abbrev = wmem_strconcat(wmem_epan_scope(),
1205
0
      "erf.meta.", tag_info->section_template->hfinfo.abbrev, ".", tag_info->tag_template->hfinfo.abbrev, ".", ehdr_type_vals_short[i].strptr, NULL);
1206
0
    wmem_array_append_one(hfri_table, hfri_tmp);
1207
0
  }
1208
1209
0
  return tag_info;
1210
0
}
1211
1212
static erf_meta_tag_info_t*
1213
init_ns_addr_tag_value_fields(wmem_array_t *hfri_table, erf_meta_tag_info_t *tag_info)
1214
0
{
1215
0
  header_field_info ns_addr_extra_fields[] = {
1216
0
    { NULL, NULL, FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }, /* Address value, will be filled from template */
1217
0
    { "Name", "name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }  /* Name value */
1218
0
  };
1219
1220
0
  tag_info->extra = erf_meta_tag_info_ex_new(wmem_epan_scope());
1221
1222
  /* Set address subfield type, etc. from template based on address type */
1223
0
  ns_addr_extra_fields[0] = tag_info->tag_template->hfinfo;
1224
0
  ns_addr_extra_fields[0].name = "Address";
1225
0
  ns_addr_extra_fields[0].abbrev = "addr";
1226
  /* Don't need a main value as we just use a text subtree */
1227
  /* Init subfields */
1228
0
  init_tag_value_subfields(hfri_table, tag_info, ns_addr_extra_fields, array_length(ns_addr_extra_fields));
1229
1230
0
  return tag_info;
1231
0
}
1232
1233
static erf_meta_tag_info_t*
1234
init_tag_fields(wmem_array_t *hfri_table, wmem_array_t *ett_table, const erf_meta_hf_template_t *section, const erf_meta_hf_template_t *tag)
1235
0
{
1236
0
  erf_meta_tag_info_t *tag_info;
1237
0
  int                 *ett_tmp; /* wmem_array_append needs actual memory to copy from */
1238
1239
0
  tag_info = erf_meta_tag_info_new(wmem_epan_scope(), section, tag);
1240
1241
  /*Tags with subfields (only)*/
1242
  /*XXX: Can't currently easily be described in the template because
1243
   * there is currently no dissect bitfield equivalent that supports arbitrary
1244
   * types/offsets*/
1245
0
  switch (tag->code) {
1246
  /*Special case: parent_section*/
1247
0
  case ERF_META_TAG_parent_section:
1248
    /*Don't need a main value*/
1249
    /*Init subfields*/
1250
0
    init_tag_value_subfields(hfri_table, tag_info, erf_parent_section, array_length(erf_parent_section));
1251
0
    break;
1252
1253
  /* Special case: name entry */
1254
0
  case ERF_META_TAG_ns_dns_ipv4:
1255
0
  case ERF_META_TAG_ns_dns_ipv6:
1256
0
  case ERF_META_TAG_ns_host_ipv4:
1257
0
  case ERF_META_TAG_ns_host_ipv6:
1258
0
  case ERF_META_TAG_ns_host_mac:
1259
0
  case ERF_META_TAG_ns_host_eui:
1260
0
  case ERF_META_TAG_ns_host_wwn:
1261
0
  case ERF_META_TAG_ns_host_ib_gid:
1262
0
  case ERF_META_TAG_ns_host_ib_lid:
1263
0
  case ERF_META_TAG_ns_host_fc_id:
1264
0
    init_ns_addr_tag_value_fields(hfri_table, tag_info);
1265
0
    break;
1266
1267
  /* Usual case: init single field template */
1268
0
  default:
1269
0
    init_tag_value_field(hfri_table, tag_info);
1270
0
    break;
1271
0
  }
1272
1273
  /*Tags that need additional subfields*/
1274
0
  switch (tag->code) {
1275
  /*Special case: bitfields*/
1276
  /*TODO: Maybe put extra_fields in template with dissect callback?*/
1277
0
  case ERF_META_TAG_tunneling_mode:
1278
0
    init_tag_value_subfields(hfri_table, tag_info, erf_tunneling_modes, array_length(erf_tunneling_modes));
1279
0
    break;
1280
0
  case ERF_META_TAG_if_link_status:
1281
0
    init_tag_value_subfields(hfri_table, tag_info, erf_link_status, array_length(erf_link_status));
1282
0
    break;
1283
0
  case ERF_META_TAG_ptp_time_properties:
1284
0
    init_tag_value_subfields(hfri_table, tag_info, erf_ptp_time_properties_flags, array_length(erf_ptp_time_properties_flags));
1285
0
    break;
1286
0
  case ERF_META_TAG_ptp_gm_clock_quality:
1287
0
    init_tag_value_subfields(hfri_table, tag_info, erf_ptp_clock_quality, array_length(erf_ptp_clock_quality));
1288
0
    break;
1289
0
    case ERF_META_TAG_stream_flags:
1290
0
    init_tag_value_subfields(hfri_table, tag_info, erf_stream_flags, array_length(erf_stream_flags));
1291
0
    break;
1292
0
  case ERF_META_TAG_smart_trunc_default:
1293
0
    init_tag_value_subfields(hfri_table, tag_info, erf_smart_trunc_default_flags, array_length(erf_smart_trunc_default_flags));
1294
0
    break;
1295
0
  case ERF_META_TAG_ext_hdrs_added:
1296
0
  case ERF_META_TAG_ext_hdrs_removed:
1297
0
    init_ext_hdrs_tag_value_subfields(hfri_table, tag_info);
1298
0
    break;
1299
0
  }
1300
1301
  /* Add ett entries */
1302
0
  ett_tmp = &tag_info->ett;
1303
0
  wmem_array_append_one(ett_table, ett_tmp);
1304
1305
0
  return tag_info;
1306
0
}
1307
1308
static void
1309
init_meta_tags(void)
1310
0
{
1311
0
  unsigned int                  i, j    = 0;
1312
0
  const erf_meta_hf_template_t *section = NULL;
1313
0
  const erf_meta_hf_template_t *tag     = NULL;
1314
0
  erf_meta_tag_info_t          *tag_info;
1315
0
  value_string                  vs_tmp  = {0, NULL};
1316
1317
0
  erf_meta_index.tag_table      = wmem_map_new(wmem_epan_scope(), g_direct_hash, g_direct_equal);
1318
0
  erf_meta_index.vs_list        = wmem_array_new(wmem_epan_scope(), sizeof(value_string));
1319
0
  erf_meta_index.vs_abbrev_list = wmem_array_new(wmem_epan_scope(), sizeof(value_string));
1320
0
  erf_meta_index.hfri           = wmem_array_new(wmem_epan_scope(), sizeof(hf_register_info));
1321
0
  erf_meta_index.ett            = wmem_array_new(wmem_epan_scope(), sizeof(int*));
1322
1323
  /* Generate tag fields */
1324
0
  for (j = 0; j < array_length(erf_meta_tags); j++) {
1325
0
    tag = &erf_meta_tags[j];
1326
1327
    /* Generate copy of the tag for each section */
1328
0
    for (i = 0; i < array_length(erf_meta_sections); i++) {
1329
0
      section = &erf_meta_sections[i];
1330
0
      tag_info = init_tag_fields(erf_meta_index.hfri, erf_meta_index.ett, section, tag);
1331
      /* Add to hash table */
1332
0
      wmem_map_insert(erf_meta_index.tag_table, GUINT_TO_POINTER(ERF_TAG_INFO_KEY(tag_info)), tag_info);
1333
0
    }
1334
1335
    /* Add value string entries */
1336
0
    vs_tmp.value = tag->code;
1337
0
    vs_tmp.strptr = tag->hfinfo.name;
1338
0
    wmem_array_append_one(erf_meta_index.vs_list, vs_tmp);
1339
0
    vs_tmp.value = tag->code;
1340
0
    vs_tmp.strptr = tag->hfinfo.abbrev;
1341
0
    wmem_array_append_one(erf_meta_index.vs_abbrev_list, vs_tmp);
1342
0
  }
1343
1344
  /* Generate section fields (skipping section_none and parts of section_unknown) */
1345
0
  for (i = 1; i < array_length(erf_meta_sections); i++) {
1346
0
    section = &erf_meta_sections[i];
1347
0
    tag_info = init_section_fields(erf_meta_index.hfri, erf_meta_index.ett, section);
1348
1349
0
    if (i != 1) { /* don't add value string for unknown section as it doesn't correspond to one section type code */
1350
      /* Add to hash table */
1351
0
      wmem_map_insert(erf_meta_index.tag_table, GUINT_TO_POINTER(ERF_TAG_INFO_KEY(tag_info)), tag_info);
1352
      /* Add value string entries */
1353
0
      vs_tmp.value = section->code;
1354
0
      vs_tmp.strptr = section->hfinfo.name;
1355
0
      wmem_array_append_one(erf_meta_index.vs_list, vs_tmp);
1356
0
      vs_tmp.value = section->code;
1357
0
      vs_tmp.strptr = section->hfinfo.abbrev;
1358
0
      wmem_array_append_one(erf_meta_index.vs_abbrev_list, vs_tmp);
1359
0
    } else {
1360
      /* Store section_unknown separately to simplify logic later */
1361
0
      erf_meta_index.unknown_section_info = tag_info;
1362
0
    }
1363
0
  }
1364
1365
  /* Terminate value string lists with {0, NULL} */
1366
0
  vs_tmp.value = 0;
1367
0
  vs_tmp.strptr = NULL;
1368
0
  wmem_array_append_one(erf_meta_index.vs_list, vs_tmp);
1369
0
  wmem_array_append_one(erf_meta_index.vs_abbrev_list, vs_tmp);
1370
  /* TODO: try value_string_ext, requires sorting first */
1371
0
}
1372
1373
0
static inline value_string *erf_to_value_string(wmem_array_t *array) {
1374
0
  return (value_string *)wmem_array_get_raw(array);
1375
0
}
1376
1377
0
static unsigned erf_anchor_key_hash(const void *key) {
1378
0
  const erf_anchor_key_t *anchor_key = (const erf_anchor_key_t*) key;
1379
1380
0
  return ((uint32_t)anchor_key->host_id ^ (uint32_t)anchor_key->anchor_id);
1381
1382
0
}
1383
1384
0
static gboolean erf_anchor_key_equal(const void *a, const void *b) {
1385
0
  const erf_anchor_key_t *anchor_key_a = (const erf_anchor_key_t*) a ;
1386
0
  const erf_anchor_key_t *anchor_key_b = (const erf_anchor_key_t*) b ;
1387
1388
0
  return (anchor_key_a->host_id) == (anchor_key_b->host_id) &&
1389
0
    (anchor_key_a->anchor_id & ERF_EXT_HDR_TYPE_ANCHOR_ID) == (anchor_key_b->anchor_id & ERF_EXT_HDR_TYPE_ANCHOR_ID);
1390
0
}
1391
1392
0
static void erf_host_anchor_info_insert(packet_info *pinfo, uint64_t host_id, uint64_t anchor_id, uint8_t flags _U_) {
1393
0
  erf_host_anchor_info_t *anchor_info;
1394
0
  erf_anchor_key_t key = {host_id, anchor_id};
1395
0
  erf_anchored_info_t *anchored_info;
1396
1397
0
  anchor_info = (erf_host_anchor_info_t*)wmem_map_lookup(erf_state.host_anchor_map, &key);
1398
1399
0
  if(!anchor_info) {
1400
0
    erf_anchor_key_t *key_ptr = wmem_new(wmem_file_scope(), erf_anchor_key_t);
1401
0
    *key_ptr = key;
1402
1403
0
    anchor_info = (erf_host_anchor_info_t*) wmem_new(wmem_file_scope(), erf_host_anchor_info_t);
1404
0
    anchor_info->anchored_tree = wmem_tree_new(wmem_file_scope());
1405
0
    anchor_info->anchored_list = wmem_list_new(wmem_file_scope());
1406
1407
0
    wmem_map_insert(erf_state.host_anchor_map, key_ptr, anchor_info);
1408
0
  }
1409
1410
  /* Information about this frame associated with the Anchor ID */
1411
0
  anchored_info = (erf_anchored_info_t*)wmem_tree_lookup32(anchor_info->anchored_tree, pinfo->num);
1412
0
  if(!anchored_info) {
1413
    /* anchored_info not found */
1414
0
    anchored_info = (erf_anchored_info_t*)wmem_new(wmem_file_scope(), erf_anchored_info_t);
1415
0
    anchored_info->frame_num = pinfo->num;
1416
1417
0
    wmem_list_append(anchor_info->anchored_list, anchored_info);
1418
0
    wmem_tree_insert32(anchor_info->anchored_tree, pinfo->num, anchored_info);
1419
0
  }
1420
0
  else {
1421
0
    return;
1422
0
  }
1423
0
}
1424
1425
1426
static int
1427
erf_source_append(uint64_t host_id, uint8_t source_id, uint32_t num)
1428
0
{
1429
0
  erf_source_info_t *source_info;
1430
0
  uint64_t           source_key = ERF_SOURCE_KEY(host_id, source_id);
1431
1432
0
  source_info = (erf_source_info_t*) wmem_map_lookup(erf_state.source_map, &source_key);
1433
1434
0
  if (!source_info) {
1435
0
    uint64_t *source_key_ptr = wmem_new(wmem_file_scope(), uint64_t);
1436
0
    *source_key_ptr = source_key;
1437
1438
0
    source_info = (erf_source_info_t*) wmem_new(wmem_file_scope(), erf_source_info_t);
1439
0
    source_info->meta_tree = wmem_tree_new(wmem_file_scope());
1440
0
    source_info->meta_list = wmem_list_new(wmem_file_scope());
1441
1442
0
    wmem_map_insert(erf_state.source_map, source_key_ptr, source_info);
1443
0
  }
1444
1445
  /* Add the frame to the list for that source */
1446
0
  wmem_list_append(source_info->meta_list, GUINT_TO_POINTER(num));
1447
  /*
1448
   * XXX: This assumes we are inserting fd_num in order, which we are as we use
1449
   * PINFO_FD_VISITED in caller.
1450
   */
1451
0
  wmem_tree_insert32(source_info->meta_tree, num, wmem_list_tail(source_info->meta_list));
1452
1453
0
  return 0;
1454
0
}
1455
1456
static uint32_t
1457
0
erf_source_find_closest(uint64_t host_id, uint8_t source_id, uint32_t fnum, uint32_t *fnum_next_ptr) {
1458
0
  wmem_list_frame_t  *list_frame      = NULL;
1459
0
  wmem_list_frame_t  *list_frame_prev = NULL;
1460
0
  erf_source_info_t  *source_info     = NULL;
1461
0
  uint64_t            source_key      = ERF_SOURCE_KEY(host_id, source_id);
1462
0
  uint32_t            fnum_prev       = UINT32_MAX;
1463
0
  uint32_t            fnum_next       = UINT32_MAX;
1464
1465
0
  source_info = (erf_source_info_t*) wmem_map_lookup(erf_state.source_map, &source_key);
1466
1467
0
  if (source_info) {
1468
0
    list_frame = (wmem_list_frame_t*) wmem_tree_lookup32_le(source_info->meta_tree, fnum);
1469
1470
0
    if (list_frame) {
1471
0
      fnum_prev = GPOINTER_TO_UINT(wmem_list_frame_data(list_frame));
1472
      /* If looking at a metadata record, get the real previous meta frame */
1473
0
      if (fnum_prev == fnum) {
1474
0
        list_frame_prev = wmem_list_frame_prev(list_frame);
1475
0
        fnum_prev = list_frame_prev ? GPOINTER_TO_UINT(wmem_list_frame_data(list_frame_prev)) : UINT32_MAX;
1476
0
      }
1477
1478
0
      list_frame = wmem_list_frame_next(list_frame);
1479
0
      fnum_next = list_frame ? GPOINTER_TO_UINT(wmem_list_frame_data(list_frame)) : UINT32_MAX;
1480
0
    } else {
1481
      /*
1482
       * XXX: Edge case: still need the first meta record to find the next one at the
1483
       * beginning of the file.
1484
       */
1485
0
      list_frame = wmem_list_head(source_info->meta_list);
1486
0
      fnum_next = list_frame ? GPOINTER_TO_UINT(wmem_list_frame_data(list_frame)) : UINT32_MAX;
1487
0
      fnum_prev = UINT32_MAX;
1488
0
    }
1489
0
  }
1490
1491
0
  if (fnum_next_ptr)
1492
0
    *fnum_next_ptr = fnum_next;
1493
1494
0
  return fnum_prev;
1495
0
}
1496
1497
/* Copy of atm_guess_traffic_type from atm.c in /wiretap */
1498
static void
1499
erf_atm_guess_lane_type(tvbuff_t *tvb, int offset, unsigned len,
1500
    struct atm_phdr *atm_info)
1501
0
{
1502
0
  if (len >= 2) {
1503
0
    if (tvb_get_ntohs(tvb, offset) == 0xFF00) {
1504
      /*
1505
       * Looks like LE Control traffic.
1506
       */
1507
0
      atm_info->subtype = TRAF_ST_LANE_LE_CTRL;
1508
0
    } else {
1509
      /*
1510
       * XXX - Ethernet, or Token Ring?
1511
       * Assume Ethernet for now; if we see earlier
1512
       * LANE traffic, we may be able to figure out
1513
       * the traffic type from that, but there may
1514
       * still be situations where the user has to
1515
       * tell us.
1516
       */
1517
0
      atm_info->subtype = TRAF_ST_LANE_802_3;
1518
0
    }
1519
0
  }
1520
0
}
1521
1522
static void
1523
erf_atm_guess_traffic_type(tvbuff_t *tvb, int offset, unsigned len,
1524
    struct atm_phdr *atm_info)
1525
0
{
1526
  /*
1527
   * Start out assuming nothing other than that it's AAL5.
1528
   */
1529
0
  atm_info->aal     = AAL_5;
1530
0
  atm_info->type    = TRAF_UNKNOWN;
1531
0
  atm_info->subtype = TRAF_ST_UNKNOWN;
1532
1533
0
  if (atm_info->vpi == 0) {
1534
    /*
1535
     * Traffic on some PVCs with a VPI of 0 and certain
1536
     * VCIs is of particular types.
1537
     */
1538
0
    switch (atm_info->vci) {
1539
1540
0
    case 5:
1541
      /*
1542
       * Signalling AAL.
1543
       */
1544
0
      atm_info->aal = AAL_SIGNALLING;
1545
0
      return;
1546
1547
0
    case 16:
1548
      /*
1549
       * ILMI.
1550
       */
1551
0
      atm_info->type = TRAF_ILMI;
1552
0
      return;
1553
0
    }
1554
0
  }
1555
1556
  /*
1557
   * OK, we can't tell what it is based on the VPI/VCI; try
1558
   * guessing based on the contents, if we have enough data
1559
   * to guess.
1560
   */
1561
1562
0
  if (len >= 3) {
1563
0
    uint8_t mtp3b;
1564
0
    if (tvb_get_ntoh24(tvb, offset) == 0xAAAA03) {
1565
      /*
1566
       * Looks like a SNAP header; assume it's LLC
1567
       * multiplexed RFC 1483 traffic.
1568
       */
1569
0
      atm_info->type = TRAF_LLCMX;
1570
0
    } else if ((atm_info->aal5t_len &&
1571
0
                atm_info->aal5t_len < 16) || len<16) {
1572
      /*
1573
       * As this cannot be a LANE Ethernet frame (less
1574
       * than 2 bytes of LANE header + 14 bytes of
1575
       * Ethernet header) we can try it as a SSCOP frame.
1576
       */
1577
0
      atm_info->aal = AAL_SIGNALLING;
1578
0
    } else if (((mtp3b = tvb_get_uint8(tvb, offset)) == 0x83) || (mtp3b == 0x81)) {
1579
      /*
1580
       * MTP3b headers often encapsulate
1581
       * a SCCP or MTN in the 3G network.
1582
       * This should cause 0x83 or 0x81
1583
       * in the first byte.
1584
       */
1585
0
      atm_info->aal = AAL_SIGNALLING;
1586
0
    } else {
1587
      /*
1588
       * Assume it's LANE.
1589
       */
1590
0
      atm_info->type = TRAF_LANE;
1591
0
      erf_atm_guess_lane_type(tvb, offset, len, atm_info);
1592
0
    }
1593
0
  } else {
1594
    /*
1595
     * Not only VCI 5 is used for signaling. It might be
1596
     * one of these VCIs.
1597
     */
1598
0
    atm_info->aal = AAL_SIGNALLING;
1599
0
  }
1600
0
}
1601
1602
static void
1603
dissect_classification_ex_header(tvbuff_t *tvb,  packet_info *pinfo, proto_tree *tree, int idx)
1604
0
{
1605
0
  proto_item *flags_item;
1606
0
  proto_tree *flags_tree;
1607
0
  uint64_t    hdr   = pinfo->pseudo_header->erf.ehdr_list[idx].ehdr;
1608
0
  uint32_t    value = ((uint32_t)(hdr >> 32)) & EHDR_CLASS_FLAGS_MASK;
1609
1610
0
  flags_item = proto_tree_add_uint(tree, hf_erf_ehdr_class_flags, tvb, 0, 0, value);
1611
0
  flags_tree = proto_item_add_subtree(flags_item, ett_erf_flags);
1612
1613
0
  proto_tree_add_uint(flags_tree, hf_erf_ehdr_class_flags_sh,   tvb, 0, 0, value);
1614
0
  proto_tree_add_uint(flags_tree, hf_erf_ehdr_class_flags_shm,  tvb, 0, 0, value);
1615
0
  proto_tree_add_uint(flags_tree, hf_erf_ehdr_class_flags_res1, tvb, 0, 0, value);
1616
0
  proto_tree_add_uint(flags_tree, hf_erf_ehdr_class_flags_user, tvb, 0, 0, value);
1617
0
  proto_tree_add_uint(flags_tree, hf_erf_ehdr_class_flags_res2, tvb, 0, 0, value);
1618
0
  proto_tree_add_uint(flags_tree, hf_erf_ehdr_class_flags_drop, tvb, 0, 0, value);
1619
0
  proto_tree_add_uint(flags_tree, hf_erf_ehdr_class_flags_str,  tvb, 0, 0, value);
1620
1621
0
  proto_tree_add_uint(tree, hf_erf_ehdr_class_seqnum, tvb, 0, 0, (uint32_t)hdr);
1622
0
}
1623
1624
static void
1625
dissect_intercept_ex_header(tvbuff_t *tvb,  packet_info *pinfo, proto_tree *tree, int idx)
1626
0
{
1627
0
  uint64_t    hdr = pinfo->pseudo_header->erf.ehdr_list[idx].ehdr;
1628
1629
0
  proto_tree_add_uint(tree, hf_erf_ehdr_int_res1, tvb, 0, 0, (uint8_t)((hdr >> 48) & 0xFF));
1630
0
  proto_tree_add_uint(tree, hf_erf_ehdr_int_id, tvb, 0, 0, (uint16_t)((hdr >> 32 ) & 0xFFFF));
1631
0
  proto_tree_add_uint(tree, hf_erf_ehdr_int_res2, tvb, 0, 0, (uint32_t)hdr);
1632
0
}
1633
1634
static void
1635
dissect_raw_link_ex_header(tvbuff_t *tvb,  packet_info *pinfo, proto_tree *tree, int idx)
1636
0
{
1637
0
  uint64_t    hdr = pinfo->pseudo_header->erf.ehdr_list[idx].ehdr;
1638
1639
0
  proto_tree_add_uint(tree, hf_erf_ehdr_raw_link_res ,    tvb, 0, 0, (uint32_t)((hdr >> 32) & 0xFFFFFF));
1640
0
  proto_tree_add_uint(tree, hf_erf_ehdr_raw_link_seqnum , tvb, 0, 0, (uint32_t)((hdr >> 16) & 0xffff));
1641
0
  proto_tree_add_uint(tree, hf_erf_ehdr_raw_link_rate,    tvb, 0, 0, (uint32_t)((hdr >> 8) & 0x00ff));
1642
0
  proto_tree_add_uint(tree, hf_erf_ehdr_raw_link_type,    tvb, 0, 0, (uint32_t)(hdr & 0x00ff));
1643
0
}
1644
1645
static void
1646
dissect_bfs_ex_header(tvbuff_t *tvb,  packet_info *pinfo, proto_tree *tree, int idx)
1647
0
{
1648
0
  uint64_t    hdr = pinfo->pseudo_header->erf.ehdr_list[idx].ehdr;
1649
1650
0
  proto_tree_add_uint(tree, hf_erf_ehdr_bfs_hash, tvb, 0, 0, (uint32_t)((hdr >> 48) & 0xFF));
1651
0
  proto_tree_add_uint(tree, hf_erf_ehdr_bfs_color, tvb, 0, 0, (uint32_t)((hdr >> 32) & 0xFFFF));
1652
0
  proto_tree_add_uint(tree, hf_erf_ehdr_bfs_raw_hash, tvb, 0, 0, (uint32_t)(hdr & 0xFFFFFFFF));
1653
0
}
1654
1655
static int
1656
channelised_fill_sdh_g707_format(sdh_g707_format_t* in_fmt, uint16_t bit_flds, uint8_t vc_size, uint8_t rate)
1657
0
{
1658
0
  int i = 0; /* i = 3 --> ITU-T letter #D - index of AUG-16
1659
              * i = 2 --> ITU-T letter #C - index of AUG-4,
1660
              * i = 1 --> ITU-T letter #B - index of AUG-1
1661
              * i = 0 --> ITU-T letter #A - index of AU3*/
1662
1663
0
  if ( (0 == vc_size) || (vc_size > DECHAN_MAX_VC_SIZE) || (rate > DECHAN_MAX_LINE_RATE) )
1664
0
  {
1665
    /* unknown / unused / invalid container size or invalid line rate */
1666
0
    in_fmt->m_vc_size = 0;
1667
0
    in_fmt->m_sdh_line_rate = 0;
1668
0
    memset(&(in_fmt->m_vc_index_array[0]), 0x00, DECHAN_MAX_AUG_INDEX);
1669
0
    return -1;
1670
0
  }
1671
1672
0
  in_fmt->m_vc_size = vc_size;
1673
0
  in_fmt->m_sdh_line_rate = rate;
1674
0
  memset(&(in_fmt->m_vc_index_array[0]), 0xff, DECHAN_MAX_AUG_INDEX);
1675
1676
  /* for STM64 traffic,from #D and so on .. */
1677
0
    for (i = (rate - 2); i >= 0; i--)
1678
0
  {
1679
0
    uint8_t aug_n_index = 0;
1680
1681
    /*if AUG-n is bigger than vc-size*/
1682
0
    if ( i >= (vc_size - 1))
1683
0
    {
1684
      /* check the value in bit flds */
1685
0
      aug_n_index = ((bit_flds >> (2 *i))& 0x3) +1;
1686
0
    }
1687
0
    else
1688
0
    {
1689
0
      aug_n_index = 0;
1690
0
    }
1691
0
    in_fmt->m_vc_index_array[i] = aug_n_index;
1692
0
  }
1693
0
  return 0;
1694
0
}
1695
1696
static void
1697
channelised_fill_vc_id_string(wmem_strbuf_t* out_string, sdh_g707_format_t* in_fmt)
1698
0
{
1699
0
  int      i;
1700
0
  bool is_printed  = false;
1701
1702
0
  static const char* g_vc_size_strings[] = {
1703
0
    "unknown",  /*0x0*/
1704
0
    "VC3",      /*0x1*/
1705
0
    "VC4",      /*0x2*/
1706
0
    "VC4-4c",   /*0x3*/
1707
0
    "VC4-16c",  /*0x4*/
1708
0
    "VC4-64c",  /*0x5*/};
1709
1710
0
  wmem_strbuf_truncate(out_string, 0);
1711
1712
0
  if ( (in_fmt->m_vc_size > DECHAN_MAX_VC_SIZE) || (in_fmt->m_sdh_line_rate > DECHAN_MAX_LINE_RATE) )
1713
0
  {
1714
0
    wmem_strbuf_append_printf(out_string, "Malformed");
1715
0
    return;
1716
0
  }
1717
1718
0
  wmem_strbuf_append_printf(out_string, "%s(",
1719
0
                            (in_fmt->m_vc_size < array_length(g_vc_size_strings)) ?
1720
0
                            g_vc_size_strings[in_fmt->m_vc_size] : g_vc_size_strings[0] );
1721
1722
0
  if (in_fmt->m_sdh_line_rate <= 0 )
1723
0
  {
1724
    /* line rate is not given */
1725
0
    for (i = (DECHAN_MAX_AUG_INDEX -1); i >= 0; i--)
1726
0
    {
1727
0
      if ((in_fmt->m_vc_index_array[i] > 0) || (is_printed) )
1728
0
      {
1729
0
        wmem_strbuf_append_printf(out_string, "%s%d",
1730
0
                                  ((is_printed)?", ":""),
1731
0
                                  in_fmt->m_vc_index_array[i]);
1732
0
        is_printed = true;
1733
0
      }
1734
0
    }
1735
1736
0
  }
1737
0
  else
1738
0
  {
1739
0
    for (i = in_fmt->m_sdh_line_rate - 2; i >= 0; i--)
1740
0
    {
1741
0
      wmem_strbuf_append_printf(out_string, "%s%d",
1742
0
                                ((is_printed)?", ":""),
1743
0
                                in_fmt->m_vc_index_array[i]);
1744
0
      is_printed = true;
1745
0
    }
1746
0
  }
1747
0
  if ( ! is_printed )
1748
0
  {
1749
    /* Not printed . possibly it's a ocXc packet with (0,0,0...) */
1750
0
    for ( i =0; i < in_fmt->m_vc_size - 2; i++)
1751
0
    {
1752
0
      wmem_strbuf_append_printf(out_string, "%s0",
1753
0
                                ((is_printed)?", ":""));
1754
0
      is_printed = true;
1755
0
    }
1756
0
  }
1757
0
  wmem_strbuf_append_c(out_string, ')');
1758
0
  return;
1759
0
}
1760
1761
static void
1762
dissect_channelised_ex_header(tvbuff_t *tvb,  packet_info *pinfo, proto_tree *tree, int idx)
1763
0
{
1764
0
  uint64_t           hdr              = pinfo->pseudo_header->erf.ehdr_list[idx].ehdr;
1765
0
  uint8_t            vc_id            = (uint8_t)((hdr >> 24) & 0xFF);
1766
0
  uint8_t            vc_size          = (uint8_t)((hdr >> 16) & 0xFF);
1767
0
  uint8_t            line_rate        = (uint8_t)((hdr >> 8) & 0xFF);
1768
0
  sdh_g707_format_t  g707_format;
1769
0
  wmem_strbuf_t     *vc_id_string = wmem_strbuf_create(pinfo->pool);
1770
1771
0
  channelised_fill_sdh_g707_format(&g707_format, vc_id, vc_size, line_rate);
1772
0
  channelised_fill_vc_id_string(vc_id_string, &g707_format);
1773
1774
0
  proto_tree_add_boolean(tree, hf_erf_ehdr_chan_morebits, tvb, 0, 0, (uint8_t)((hdr >> 63) & 0x1));
1775
0
  proto_tree_add_boolean(tree, hf_erf_ehdr_chan_morefrag, tvb, 0, 0, (uint8_t)((hdr >> 55) & 0x1));
1776
0
  proto_tree_add_uint(tree, hf_erf_ehdr_chan_seqnum, tvb, 0, 0, (uint16_t)((hdr >> 40) & 0x7FFF));
1777
0
  proto_tree_add_uint(tree, hf_erf_ehdr_chan_res, tvb, 0, 0, (uint8_t)((hdr >> 32) & 0xFF));
1778
0
  proto_tree_add_uint_format_value(tree, hf_erf_ehdr_chan_virt_container_id, tvb, 0, 0, vc_id,
1779
0
                                   "0x%.2x (g.707: %s)", vc_id, wmem_strbuf_get_str(vc_id_string));
1780
0
  proto_tree_add_uint(tree, hf_erf_ehdr_chan_assoc_virt_container_size, tvb, 0, 0, vc_size);
1781
0
  proto_tree_add_uint(tree, hf_erf_ehdr_chan_rate, tvb, 0, 0, line_rate);
1782
0
  proto_tree_add_uint(tree, hf_erf_ehdr_chan_type, tvb, 0, 0, (uint8_t)((hdr >> 0) & 0xFF));
1783
0
}
1784
1785
static void
1786
dissect_signature_ex_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int idx)
1787
0
{
1788
0
  uint64_t    hdr = pinfo->pseudo_header->erf.ehdr_list[idx].ehdr;
1789
1790
0
  proto_tree_add_uint(tree, hf_erf_ehdr_signature_payload_hash, tvb, 0, 0, (uint32_t)((hdr >> 32) & 0xFFFFFF));
1791
0
  proto_tree_add_uint(tree, hf_erf_ehdr_signature_color,        tvb, 0, 0, (uint8_t)((hdr >> 24) & 0xFF));
1792
0
  proto_tree_add_uint(tree, hf_erf_ehdr_signature_flow_hash,    tvb, 0, 0, (uint32_t)(hdr & 0xFFFFFF));
1793
0
}
1794
1795
static void
1796
dissect_host_id_ex_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int idx)
1797
0
{
1798
0
  uint64_t    hdr = pinfo->pseudo_header->erf.ehdr_list[idx].ehdr;
1799
1800
0
  proto_tree_add_uint(tree, hf_erf_ehdr_host_id_sourceid, tvb, 0, 0, (uint8_t)((hdr >> 48) & 0xFF));
1801
0
  proto_tree_add_uint64(tree, hf_erf_ehdr_host_id_hostid, tvb, 0, 0, (hdr & ERF_EHDR_HOST_ID_MASK));
1802
0
}
1803
1804
static void
1805
dissect_anchor_id_ex_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int idx)
1806
0
{
1807
0
  static int * const anchor_flags[] =
1808
0
  {
1809
0
    &hf_erf_ehdr_anchor_id_definition,
1810
0
    &hf_erf_ehdr_anchor_id_reserved,
1811
0
    NULL
1812
0
  };
1813
1814
0
  uint64_t    hdr = pinfo->pseudo_header->erf.ehdr_list[idx].ehdr;
1815
1816
0
  proto_tree_add_bitmask_value(tree, tvb, 0, hf_erf_ehdr_anchor_id_flags, ett_erf_anchor_flags, anchor_flags, (uint8_t)(hdr >> 48) & 0xff);
1817
0
  proto_tree_add_uint64(tree, hf_erf_ehdr_anchor_id_anchorid, tvb, 0, 0, (hdr & ERF_EHDR_ANCHOR_ID_MASK));
1818
0
}
1819
1820
1821
static void
1822
dissect_flow_id_ex_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int idx)
1823
0
{
1824
0
  uint64_t    hdr = pinfo->pseudo_header->erf.ehdr_list[idx].ehdr;
1825
0
  uint8_t     hash_type = (uint8_t)((hdr >> 40) & 0xFF);
1826
0
  proto_item *hash_type_item;
1827
0
  proto_tree *hash_type_tree;
1828
1829
0
  proto_tree_add_uint(tree, hf_erf_ehdr_flow_id_source_id,  tvb, 0, 0, (uint8_t)((hdr >> 48) & 0xFF));
1830
1831
0
  hash_type_item = proto_tree_add_uint_format_value(tree, hf_erf_ehdr_flow_id_hash_type, tvb, 0, 0, hash_type,
1832
0
                                                  "0x%02x (%s%s)",
1833
0
                                                  hash_type,
1834
0
                                                  (hash_type & ERF_EHDR_FLOW_ID_HASH_TYPE_INNER_MASK) ? "Inner " : "",
1835
0
                                                  val_to_str_const(
1836
0
                                                    (hash_type & ERF_EHDR_FLOW_ID_HASH_TYPE_TYPE_MASK),
1837
0
                                                    erf_hash_type,
1838
0
                                                    "Unknown Type"));
1839
1840
0
  hash_type_tree = proto_item_add_subtree(hash_type_item, ett_erf_hash_type);
1841
0
  proto_tree_add_uint(hash_type_tree, hf_erf_ehdr_flow_id_hash_type_type,  tvb, 0, 0, hash_type);
1842
0
  proto_tree_add_uint(hash_type_tree, hf_erf_ehdr_flow_id_hash_type_inner, tvb, 0, 0, hash_type);
1843
1844
0
  proto_tree_add_uint(tree, hf_erf_ehdr_flow_id_stack_type, tvb, 0, 0, (uint8_t)((hdr >> 32) & 0xFF));
1845
0
  proto_tree_add_uint(tree, hf_erf_ehdr_flow_id_flow_hash,  tvb, 0, 0, (uint32_t)(hdr & 0xFFFFFFFF));
1846
0
}
1847
1848
static float
1849
entropy_from_entropy_header_value(uint8_t entropy_hdr_value)
1850
0
{
1851
  /* mapping 1-255 to 0.0-8.0 */
1852
  /*  255 is 8.0 */
1853
  /* 1 represent any value less than 2/32 */
1854
  /* 0 represents not calculated */
1855
0
  return (float)((entropy_hdr_value == 0)?0.0f: (((float)entropy_hdr_value+1) / 32.0f));
1856
0
}
1857
1858
static void
1859
dissect_entropy_ex_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int idx)
1860
0
{
1861
0
  uint64_t    hdr = pinfo->pseudo_header->erf.ehdr_list[idx].ehdr;
1862
0
  uint8_t     entropy_hdr_value = (uint8_t)((hdr >> 48) & 0xFF);
1863
0
  float      entropy;
1864
0
  proto_item *pi;
1865
0
  proto_tree *entropy_value_tree;
1866
1867
0
  entropy = entropy_from_entropy_header_value(entropy_hdr_value);
1868
1869
0
  pi = proto_tree_add_float_format_value(tree, hf_erf_ehdr_entropy_entropy, tvb, 0, 0, entropy,
1870
0
    "%.2f %s", (double) entropy, entropy == 0.0f ? "(not calculated)":"bits");
1871
0
  entropy_value_tree = proto_item_add_subtree(pi, ett_erf_entropy_value);
1872
0
  proto_tree_add_uint(entropy_value_tree, hf_erf_ehdr_entropy_entropy_raw, tvb, 0, 0, entropy_hdr_value);
1873
1874
0
  proto_tree_add_uint64(tree, hf_erf_ehdr_entropy_reserved, tvb, 0, 0, (hdr & 0xFFFFFFFFFFFF));
1875
0
}
1876
1877
static uint64_t
1878
0
find_host_id(packet_info *pinfo, bool *has_anchor_definition) {
1879
0
  uint64_t    hdr;
1880
0
  uint8_t     type;
1881
0
  uint8_t     has_more = pinfo->pseudo_header->erf.phdr.type & 0x80;
1882
0
  int         i = 0;
1883
0
  uint64_t    host_id = ERF_META_HOST_ID_IMPLICIT;
1884
0
  bool        anchor_definition = false;
1885
1886
0
  while(has_more && (i < MAX_ERF_EHDR)) {
1887
0
    hdr = pinfo->pseudo_header->erf.ehdr_list[i].ehdr;
1888
0
    type = (uint8_t) (hdr >> 56);
1889
1890
0
    switch (type & 0x7f) {
1891
0
      case ERF_EXT_HDR_TYPE_HOST_ID:
1892
0
        if (host_id == ERF_META_HOST_ID_IMPLICIT)
1893
0
          host_id = hdr & ERF_EHDR_HOST_ID_MASK;
1894
0
        break;
1895
0
      case ERF_EXT_HDR_TYPE_ANCHOR_ID:
1896
0
        if ((hdr & ERF_EHDR_ANCHOR_ID_DEFINITION_MASK))
1897
0
          anchor_definition = true;
1898
0
        break;
1899
0
    }
1900
0
    has_more = type & 0x80;
1901
0
    i += 1;
1902
0
  }
1903
1904
0
  if (has_anchor_definition)
1905
0
    *has_anchor_definition = anchor_definition;
1906
1907
0
  return host_id;
1908
0
}
1909
1910
0
static void dissect_host_anchor_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint64_t host_id, uint64_t anchor_id, uint8_t anchor _U_) {
1911
1912
0
  erf_anchor_key_t key = {host_id, anchor_id};
1913
0
  erf_host_anchor_info_t *anchor_info;
1914
0
  erf_anchored_info_t *anchored_info;
1915
0
  wmem_list_frame_t *frame;
1916
0
  wmem_list_t *frame_list;
1917
0
  proto_item *pi = NULL;
1918
0
  proto_tree *subtree;
1919
1920
  /* TODO: top level linking to most recent frame like we have for Host ID? */
1921
0
  subtree = proto_tree_add_subtree_format(tree, tvb, 0, 0, ett_erf_anchor, &pi, "Host ID: 0x%012" PRIx64 ", Anchor ID: 0x%012" PRIx64, host_id & ERF_EHDR_HOST_ID_MASK, anchor_id & ERF_EHDR_ANCHOR_ID_MASK);
1922
0
  proto_item_set_generated(pi);
1923
1924
0
  pi = proto_tree_add_uint64(subtree, hf_erf_anchor_hostid, tvb, 0, 0, host_id & ERF_EHDR_HOST_ID_MASK);
1925
0
  proto_item_set_generated(pi);
1926
0
  pi = proto_tree_add_uint64(subtree, hf_erf_anchor_anchorid, tvb, 0, 0, anchor_id & ERF_EHDR_ANCHOR_ID_MASK);
1927
0
  proto_item_set_generated(pi);
1928
1929
0
  anchor_info = (erf_host_anchor_info_t*)wmem_map_lookup(erf_state.host_anchor_map, &key);
1930
1931
0
  if(!anchor_info) {
1932
0
    return;
1933
0
  }
1934
1935
0
  frame_list = anchor_info->anchored_list;
1936
1937
  /* Try to link frames */
1938
0
  frame = wmem_list_head(frame_list);
1939
0
  while(frame != NULL) {
1940
0
    anchored_info = (erf_anchored_info_t*)wmem_list_frame_data(frame);
1941
0
    if(pinfo->num != anchored_info->frame_num) {
1942
      /* Don't list the frame itself */
1943
0
      pi = proto_tree_add_uint(subtree, hf_erf_anchor_linked, tvb, 0, 0, anchored_info->frame_num);
1944
0
      proto_item_set_generated(pi);
1945
      /* XXX: Need to do this each time because pinfo is discarded. Filtering does not reset visited as it does not do a full redissect.
1946
      We also might not catch all frames in the first pass (e.g. comment after record). */
1947
0
      mark_frame_as_depended_upon(pinfo->fd, anchored_info->frame_num);
1948
0
    }
1949
0
    frame = wmem_list_frame_next(frame);
1950
0
  }
1951
0
}
1952
1953
static void
1954
dissect_host_id_source_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint64_t host_id, uint8_t source_id)
1955
0
{
1956
0
  proto_tree *hostid_tree;
1957
0
  proto_item *pi           = NULL;
1958
0
  uint32_t    fnum_current = UINT32_MAX;
1959
0
  uint32_t    fnum         = UINT32_MAX;
1960
0
  uint32_t    fnum_next    = UINT32_MAX;
1961
1962
0
  fnum = erf_source_find_closest(host_id, source_id, pinfo->num, &fnum_next);
1963
1964
0
  if (fnum != UINT32_MAX) {
1965
0
    fnum_current = fnum;
1966
0
  } else {
1967
    /* XXX: Possibly undesirable side effect: first metadata record links to next */
1968
0
    fnum_current = fnum_next;
1969
0
  }
1970
1971
0
  if (fnum_current != UINT32_MAX) {
1972
0
    pi = proto_tree_add_uint_format(tree, hf_erf_source_current, tvb, 0, 0, fnum_current,
1973
0
        "Host ID: 0x%012" PRIx64 ", Source ID: %u", host_id, source_id&0xFF);
1974
0
    hostid_tree = proto_item_add_subtree(pi, ett_erf_source);
1975
0
  } else {
1976
    /* If we have no frame number to link against, just add a static subtree */
1977
0
    hostid_tree = proto_tree_add_subtree_format(tree, tvb, 0, 0, ett_erf_source, &pi,
1978
0
        "Host ID: 0x%012" PRIx64 ", Source ID: %u", host_id, source_id&0xFF);
1979
0
  }
1980
0
  proto_item_set_generated(pi);
1981
1982
0
  pi = proto_tree_add_uint64(hostid_tree, hf_erf_hostid, tvb, 0, 0, host_id);
1983
0
  proto_item_set_generated(pi);
1984
0
  pi = proto_tree_add_uint(hostid_tree, hf_erf_sourceid, tvb, 0, 0, source_id);
1985
0
  proto_item_set_generated(pi);
1986
1987
0
  if (fnum_next != UINT32_MAX) {
1988
0
    pi = proto_tree_add_uint(hostid_tree, hf_erf_source_next, tvb, 0, 0, fnum_next);
1989
0
    proto_item_set_generated(pi);
1990
    /* XXX: Save the surrounding nearest periodic records when we do a filtered save so we keep native ERF metadata */
1991
0
    mark_frame_as_depended_upon(pinfo->fd, fnum_next);
1992
0
  }
1993
0
  if (fnum != UINT32_MAX) {
1994
0
    pi = proto_tree_add_uint(hostid_tree, hf_erf_source_prev, tvb, 0, 0, fnum);
1995
0
    proto_item_set_generated(pi);
1996
0
    mark_frame_as_depended_upon(pinfo->fd, fnum);
1997
0
  }
1998
0
}
1999
2000
static void
2001
dissect_unknown_ex_header(tvbuff_t *tvb,  packet_info *pinfo, proto_tree *tree, int idx)
2002
0
{
2003
0
  uint64_t    hdr = pinfo->pseudo_header->erf.ehdr_list[idx].ehdr;
2004
2005
0
  proto_tree_add_uint64(tree, hf_erf_ehdr_unk, tvb, 0, 0, hdr);
2006
0
}
2007
2008
static void
2009
dissect_mc_hdlc_header(tvbuff_t *tvb,  packet_info *pinfo, proto_tree *tree)
2010
0
{
2011
0
  proto_item *mc_hdlc_item;
2012
0
  proto_tree *mc_hdlc_tree;
2013
0
  uint32_t    mc_hdlc;
2014
0
  proto_item *pi;
2015
2016
  /* Multi Channel HDLC Header */
2017
0
  mc_hdlc_item = proto_tree_add_uint(tree, hf_erf_mc_hdlc, tvb, 0, 0, pinfo->pseudo_header->erf.subhdr.mc_hdr);
2018
0
  mc_hdlc_tree = proto_item_add_subtree(mc_hdlc_item, ett_erf_mc_hdlc);
2019
0
  mc_hdlc = pinfo->pseudo_header->erf.subhdr.mc_hdr;
2020
2021
0
  proto_tree_add_uint(mc_hdlc_tree, hf_erf_mc_hdlc_cn, tvb, 0, 0,  mc_hdlc);
2022
0
  proto_tree_add_uint(mc_hdlc_tree, hf_erf_mc_hdlc_res1, tvb, 0, 0,  mc_hdlc);
2023
0
  proto_tree_add_uint(mc_hdlc_tree, hf_erf_mc_hdlc_res2, tvb, 0, 0,  mc_hdlc);
2024
0
  pi=proto_tree_add_uint(mc_hdlc_tree, hf_erf_mc_hdlc_fcse, tvb, 0, 0,  mc_hdlc);
2025
0
  if (mc_hdlc & MC_HDLC_FCSE_MASK)
2026
0
    expert_add_info(pinfo, pi, &ei_erf_mc_hdlc_checksum_error);
2027
2028
0
  pi=proto_tree_add_uint(mc_hdlc_tree, hf_erf_mc_hdlc_sre,  tvb, 0, 0,  mc_hdlc);
2029
0
  if (mc_hdlc & MC_HDLC_SRE_MASK)
2030
0
    expert_add_info(pinfo, pi, &ei_erf_mc_hdlc_short_error);
2031
2032
0
  pi=proto_tree_add_uint(mc_hdlc_tree, hf_erf_mc_hdlc_lre,  tvb, 0, 0,  mc_hdlc);
2033
0
  if (mc_hdlc & MC_HDLC_LRE_MASK)
2034
0
    expert_add_info(pinfo, pi, &ei_erf_mc_hdlc_long_error);
2035
2036
0
  pi=proto_tree_add_uint(mc_hdlc_tree, hf_erf_mc_hdlc_afe,  tvb, 0, 0,  mc_hdlc);
2037
0
  if (mc_hdlc & MC_HDLC_AFE_MASK)
2038
0
    expert_add_info(pinfo, pi, &ei_erf_mc_hdlc_abort_error);
2039
2040
0
  pi=proto_tree_add_uint(mc_hdlc_tree, hf_erf_mc_hdlc_oe,   tvb, 0, 0,  mc_hdlc);
2041
0
  if (mc_hdlc & MC_HDLC_OE_MASK)
2042
0
    expert_add_info(pinfo, pi, &ei_erf_mc_hdlc_octet_error);
2043
2044
0
  pi=proto_tree_add_uint(mc_hdlc_tree, hf_erf_mc_hdlc_lbe,  tvb, 0, 0,  mc_hdlc);
2045
0
  if (mc_hdlc & MC_HDLC_LBE_MASK)
2046
0
    expert_add_info(pinfo, pi, &ei_erf_mc_hdlc_lost_byte_error);
2047
2048
0
  proto_tree_add_uint(mc_hdlc_tree, hf_erf_mc_hdlc_first, tvb, 0, 0,  mc_hdlc);
2049
0
  proto_tree_add_uint(mc_hdlc_tree, hf_erf_mc_hdlc_res3,  tvb, 0, 0,  mc_hdlc);
2050
0
}
2051
2052
static void
2053
dissect_mc_raw_header(tvbuff_t *tvb,  packet_info *pinfo, proto_tree *tree)
2054
0
{
2055
0
  proto_item *mc_raw_item;
2056
0
  proto_tree *mc_raw_tree;
2057
0
  uint32_t    mc_raw;
2058
2059
  /* Multi Channel RAW Header */
2060
0
  mc_raw_item = proto_tree_add_uint(tree, hf_erf_mc_raw, tvb, 0, 0, pinfo->pseudo_header->erf.subhdr.mc_hdr);
2061
0
  mc_raw_tree = proto_item_add_subtree(mc_raw_item, ett_erf_mc_raw);
2062
0
  mc_raw = pinfo->pseudo_header->erf.subhdr.mc_hdr;
2063
2064
0
  proto_tree_add_uint(mc_raw_tree, hf_erf_mc_raw_int,   tvb, 0, 0, mc_raw);
2065
0
  proto_tree_add_uint(mc_raw_tree, hf_erf_mc_raw_res1,  tvb, 0, 0, mc_raw);
2066
0
  proto_tree_add_uint(mc_raw_tree, hf_erf_mc_raw_sre,   tvb, 0, 0, mc_raw);
2067
0
  proto_tree_add_uint(mc_raw_tree, hf_erf_mc_raw_lre,   tvb, 0, 0, mc_raw);
2068
0
  proto_tree_add_uint(mc_raw_tree, hf_erf_mc_raw_res2,  tvb, 0, 0, mc_raw);
2069
0
  proto_tree_add_uint(mc_raw_tree, hf_erf_mc_raw_lbe,   tvb, 0, 0, mc_raw);
2070
0
  proto_tree_add_uint(mc_raw_tree, hf_erf_mc_raw_first, tvb, 0, 0, mc_raw);
2071
0
  proto_tree_add_uint(mc_raw_tree, hf_erf_mc_raw_res3,  tvb, 0, 0, mc_raw);
2072
0
}
2073
2074
static void
2075
dissect_mc_atm_header(tvbuff_t *tvb,  packet_info *pinfo, proto_tree *tree)
2076
0
{
2077
0
  proto_item *mc_atm_item;
2078
0
  proto_tree *mc_atm_tree;
2079
0
  uint32_t    mc_atm;
2080
2081
  /*"Multi Channel ATM Header"*/
2082
0
  mc_atm_item = proto_tree_add_uint(tree, hf_erf_mc_atm, tvb, 0, 0, pinfo->pseudo_header->erf.subhdr.mc_hdr);
2083
0
  mc_atm_tree = proto_item_add_subtree(mc_atm_item, ett_erf_mc_atm);
2084
0
  mc_atm = pinfo->pseudo_header->erf.subhdr.mc_hdr;
2085
2086
0
  proto_tree_add_uint(mc_atm_tree, hf_erf_mc_atm_cn,      tvb, 0, 0, mc_atm);
2087
0
  proto_tree_add_uint(mc_atm_tree, hf_erf_mc_atm_res1,    tvb, 0, 0, mc_atm);
2088
0
  proto_tree_add_uint(mc_atm_tree, hf_erf_mc_atm_mul,     tvb, 0, 0, mc_atm);
2089
2090
0
  proto_tree_add_uint(mc_atm_tree, hf_erf_mc_atm_port,    tvb, 0, 0, mc_atm);
2091
0
  proto_tree_add_uint(mc_atm_tree, hf_erf_mc_atm_res2,    tvb, 0, 0, mc_atm);
2092
2093
0
  proto_tree_add_uint(mc_atm_tree, hf_erf_mc_atm_lbe,     tvb, 0, 0, mc_atm);
2094
0
  proto_tree_add_uint(mc_atm_tree, hf_erf_mc_atm_hec,     tvb, 0, 0, mc_atm);
2095
0
  proto_tree_add_uint(mc_atm_tree, hf_erf_mc_atm_crc10,   tvb, 0, 0, mc_atm);
2096
0
  proto_tree_add_uint(mc_atm_tree, hf_erf_mc_atm_oamcell, tvb, 0, 0, mc_atm);
2097
0
  proto_tree_add_uint(mc_atm_tree, hf_erf_mc_atm_first,   tvb, 0, 0, mc_atm);
2098
0
  proto_tree_add_uint(mc_atm_tree, hf_erf_mc_atm_res3,    tvb, 0, 0, mc_atm);
2099
0
}
2100
2101
static void
2102
dissect_mc_rawlink_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2103
0
{
2104
0
  proto_item *mc_rawl_item;
2105
0
  proto_tree *mc_rawl_tree;
2106
0
  uint32_t    mc_rawl;
2107
2108
  /* Multi Channel RAW Link Header */
2109
0
  mc_rawl_item = proto_tree_add_uint(tree, hf_erf_mc_rawl, tvb, 0, 0, pinfo->pseudo_header->erf.subhdr.mc_hdr);
2110
0
  mc_rawl_tree = proto_item_add_subtree(mc_rawl_item, ett_erf_mc_rawlink);
2111
0
  mc_rawl = pinfo->pseudo_header->erf.subhdr.mc_hdr;
2112
2113
0
  proto_tree_add_uint(mc_rawl_tree, hf_erf_mc_rawl_cn,    tvb, 0, 0, mc_rawl);
2114
0
  proto_tree_add_uint(mc_rawl_tree, hf_erf_mc_rawl_res1,  tvb, 0, 0, mc_rawl);
2115
0
  proto_tree_add_uint(mc_rawl_tree, hf_erf_mc_rawl_lbe,   tvb, 0, 0, mc_rawl);
2116
0
  proto_tree_add_uint(mc_rawl_tree, hf_erf_mc_rawl_first, tvb, 0, 0, mc_rawl);
2117
0
  proto_tree_add_uint(mc_rawl_tree, hf_erf_mc_rawl_res2,  tvb, 0, 0, mc_rawl);
2118
0
}
2119
2120
static void
2121
dissect_mc_aal5_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2122
0
{
2123
0
  proto_item *mc_aal5_item;
2124
0
  proto_tree *mc_aal5_tree;
2125
0
  uint32_t    mc_aal5;
2126
2127
  /* Multi Channel AAL5 Header */
2128
0
  mc_aal5_item = proto_tree_add_uint(tree, hf_erf_mc_aal5, tvb, 0, 0, pinfo->pseudo_header->erf.subhdr.mc_hdr);
2129
0
  mc_aal5_tree = proto_item_add_subtree(mc_aal5_item, ett_erf_mc_aal5);
2130
0
  mc_aal5 = pinfo->pseudo_header->erf.subhdr.mc_hdr;
2131
2132
0
  proto_tree_add_uint(mc_aal5_tree, hf_erf_mc_aal5_cn,    tvb, 0, 0, mc_aal5);
2133
0
  proto_tree_add_uint(mc_aal5_tree, hf_erf_mc_aal5_res1,  tvb, 0, 0, mc_aal5);
2134
2135
0
  proto_tree_add_uint(mc_aal5_tree, hf_erf_mc_aal5_port,  tvb, 0, 0, mc_aal5);
2136
0
  proto_tree_add_uint(mc_aal5_tree, hf_erf_mc_aal5_crcck, tvb, 0, 0, mc_aal5);
2137
0
  proto_tree_add_uint(mc_aal5_tree, hf_erf_mc_aal5_crce,  tvb, 0, 0, mc_aal5);
2138
0
  proto_tree_add_uint(mc_aal5_tree, hf_erf_mc_aal5_lenck, tvb, 0, 0, mc_aal5);
2139
0
  proto_tree_add_uint(mc_aal5_tree, hf_erf_mc_aal5_lene,  tvb, 0, 0, mc_aal5);
2140
2141
0
  proto_tree_add_uint(mc_aal5_tree, hf_erf_mc_aal5_res2,  tvb, 0, 0, mc_aal5);
2142
0
  proto_tree_add_uint(mc_aal5_tree, hf_erf_mc_aal5_first, tvb, 0, 0, mc_aal5);
2143
0
  proto_tree_add_uint(mc_aal5_tree, hf_erf_mc_aal5_res3,  tvb, 0, 0, mc_aal5);
2144
0
}
2145
2146
static void
2147
dissect_mc_aal2_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2148
0
{
2149
0
  proto_item *mc_aal2_item;
2150
0
  proto_tree *mc_aal2_tree;
2151
0
  uint32_t    mc_aal2;
2152
2153
  /* Multi Channel AAL2 Header */
2154
0
  mc_aal2_item = proto_tree_add_uint(tree, hf_erf_mc_aal2, tvb, 0, 0, pinfo->pseudo_header->erf.subhdr.mc_hdr);
2155
0
  mc_aal2_tree = proto_item_add_subtree(mc_aal2_item, ett_erf_mc_aal2);
2156
0
  mc_aal2 = pinfo->pseudo_header->erf.subhdr.mc_hdr;
2157
2158
0
  proto_tree_add_uint(mc_aal2_tree, hf_erf_mc_aal2_cn,    tvb, 0, 0, mc_aal2);
2159
0
  proto_tree_add_uint(mc_aal2_tree, hf_erf_mc_aal2_res1,  tvb, 0, 0, mc_aal2);
2160
0
  proto_tree_add_uint(mc_aal2_tree, hf_erf_mc_aal2_res2,  tvb, 0, 0, mc_aal2);
2161
2162
0
  proto_tree_add_uint(mc_aal2_tree, hf_erf_mc_aal2_port,  tvb, 0, 0, mc_aal2);
2163
0
  proto_tree_add_uint(mc_aal2_tree, hf_erf_mc_aal2_res3,  tvb, 0, 0, mc_aal2);
2164
0
  proto_tree_add_uint(mc_aal2_tree, hf_erf_mc_aal2_first, tvb, 0, 0, mc_aal2);
2165
0
  proto_tree_add_uint(mc_aal2_tree, hf_erf_mc_aal2_maale, tvb, 0, 0, mc_aal2);
2166
0
  proto_tree_add_uint(mc_aal2_tree, hf_erf_mc_aal2_lene,  tvb, 0, 0, mc_aal2);
2167
2168
0
  proto_tree_add_uint(mc_aal2_tree, hf_erf_mc_aal2_cid,   tvb, 0, 0, mc_aal2);
2169
0
}
2170
2171
static void
2172
dissect_aal2_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2173
0
{
2174
0
  proto_item *aal2_item;
2175
0
  proto_tree *aal2_tree;
2176
0
  uint32_t    aal2;
2177
2178
  /* AAL2 Header */
2179
0
  aal2_item = proto_tree_add_uint(tree, hf_erf_aal2, tvb, 0, 0, pinfo->pseudo_header->erf.subhdr.mc_hdr);
2180
0
  aal2_tree = proto_item_add_subtree(aal2_item, ett_erf_aal2);
2181
0
  aal2 = pinfo->pseudo_header->erf.subhdr.aal2_hdr;
2182
2183
0
  proto_tree_add_uint(aal2_tree, hf_erf_aal2_cid,    tvb, 0, 0, aal2);
2184
2185
0
  proto_tree_add_uint(aal2_tree, hf_erf_aal2_maale,  tvb, 0, 0, aal2);
2186
2187
0
  proto_tree_add_uint(aal2_tree, hf_erf_aal2_maalei, tvb, 0, 0, aal2);
2188
0
  proto_tree_add_uint(aal2_tree, hf_erf_aal2_first,  tvb, 0, 0, aal2);
2189
0
  proto_tree_add_uint(aal2_tree, hf_erf_aal2_res1,   tvb, 0, 0, aal2);
2190
0
}
2191
2192
static void
2193
dissect_eth_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2194
0
{
2195
0
  proto_item          *eth_item;
2196
0
  proto_tree          *eth_tree;
2197
0
  uint8_t              eth_offset, eth_pad;
2198
2199
0
  eth_item = proto_tree_add_item(tree, hf_erf_eth, tvb, 0, 0, ENC_NA);
2200
2201
0
  eth_tree = proto_item_add_subtree(eth_item, ett_erf_eth);
2202
0
  eth_offset = pinfo->pseudo_header->erf.subhdr.eth_hdr.offset;
2203
0
  eth_pad = pinfo->pseudo_header->erf.subhdr.eth_hdr.pad;
2204
2205
0
  proto_tree_add_uint(eth_tree, hf_erf_eth_off, tvb, 0, 0, eth_offset);
2206
0
  proto_tree_add_uint(eth_tree, hf_erf_eth_pad, tvb, 0, 0, eth_pad);
2207
0
}
2208
2209
static void
2210
dissect_erf_pseudo_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2211
0
{
2212
0
  proto_item *pi;
2213
0
  proto_item *flags_item, *rectype_item;
2214
0
  proto_tree *flags_tree, *rectype_tree;
2215
0
  bool has_flags = false;
2216
2217
0
  if (hf_erf_ts <= 0) {
2218
0
    proto_registrar_get_byname("erf.ts");
2219
0
  }
2220
2221
0
  proto_tree_add_uint64(tree, hf_erf_ts, tvb, 0, 0, pinfo->pseudo_header->erf.phdr.ts);
2222
2223
0
  rectype_item = proto_tree_add_uint_format_value(tree, hf_erf_rectype, tvb, 0, 0, pinfo->pseudo_header->erf.phdr.type,
2224
0
                                                  "0x%02x (Type %d: %s)",
2225
0
                                                  pinfo->pseudo_header->erf.phdr.type,
2226
0
                                                  pinfo->pseudo_header->erf.phdr.type & ERF_HDR_TYPE_MASK,
2227
0
                                                  val_to_str_const(
2228
0
                                                    pinfo->pseudo_header->erf.phdr.type & ERF_HDR_TYPE_MASK,
2229
0
                                                    erf_type_vals,
2230
0
                                                    "Unknown Type"));
2231
2232
0
  rectype_tree = proto_item_add_subtree(rectype_item, ett_erf_rectype);
2233
0
  proto_tree_add_uint(rectype_tree, hf_erf_type, tvb, 0, 0, pinfo->pseudo_header->erf.phdr.type);
2234
0
  proto_tree_add_uint(rectype_tree, hf_erf_ehdr, tvb, 0, 0, pinfo->pseudo_header->erf.phdr.type);
2235
2236
0
  flags_item=proto_tree_add_uint(tree, hf_erf_flags, tvb, 0, 0, pinfo->pseudo_header->erf.phdr.flags);
2237
0
  flags_tree = proto_item_add_subtree(flags_item, ett_erf_flags);
2238
2239
0
  proto_tree_add_uint(flags_tree, hf_erf_flags_if_raw, tvb, 0, 0, pinfo->pseudo_header->erf.phdr.flags);
2240
2241
0
  proto_tree_add_uint(flags_tree, hf_erf_flags_vlen, tvb, 0, 0, pinfo->pseudo_header->erf.phdr.flags);
2242
0
  pi=proto_tree_add_uint(flags_tree, hf_erf_flags_trunc, tvb, 0, 0, pinfo->pseudo_header->erf.phdr.flags);
2243
0
  if (pinfo->pseudo_header->erf.phdr.flags & ERF_HDR_TRUNC_MASK) {
2244
0
    proto_item_append_text(flags_item, "(ERF Truncation Error");
2245
0
    expert_add_info(pinfo, pi, &ei_erf_truncation_error);
2246
0
    has_flags = true;
2247
0
  }
2248
2249
0
  pi=proto_tree_add_uint(flags_tree, hf_erf_flags_rxe, tvb, 0, 0, pinfo->pseudo_header->erf.phdr.flags);
2250
0
  if (pinfo->pseudo_header->erf.phdr.flags & ERF_HDR_RXE_MASK) {
2251
0
    proto_item_append_text(flags_item, "%sERF Rx Error", has_flags ? "; " : "(");
2252
0
    expert_add_info(pinfo, pi, &ei_erf_rx_error);
2253
0
    has_flags = true;
2254
0
  }
2255
2256
0
  pi=proto_tree_add_uint(flags_tree, hf_erf_flags_dse, tvb, 0, 0, pinfo->pseudo_header->erf.phdr.flags);
2257
0
  if (pinfo->pseudo_header->erf.phdr.flags & ERF_HDR_DSE_MASK) {
2258
0
    proto_item_append_text(flags_item, "%sERF DS Error", has_flags ? "; " : "(");
2259
0
    expert_add_info(pinfo, pi, &ei_erf_ds_error);
2260
0
    has_flags = true;
2261
0
  }
2262
0
  if (has_flags) {
2263
0
    proto_item_append_text(flags_item, ")");
2264
0
  }
2265
2266
0
  proto_tree_add_uint(flags_tree, hf_erf_flags_res, tvb, 0, 0, pinfo->pseudo_header->erf.phdr.flags);
2267
2268
0
  proto_tree_add_uint(tree, hf_erf_flags_cap, tvb, 0, 0, erf_interface_id_from_flags(pinfo->pseudo_header->erf.phdr.flags));
2269
2270
0
  proto_tree_add_uint(tree, hf_erf_rlen, tvb, 0, 0, pinfo->pseudo_header->erf.phdr.rlen);
2271
2272
0
  if (erf_type_has_color(pinfo->pseudo_header->erf.phdr.type)) {
2273
0
    proto_tree_add_uint(tree, hf_erf_color, tvb, 0, 0, pinfo->pseudo_header->erf.phdr.lctr);
2274
0
  } else {
2275
0
    pi=proto_tree_add_uint(tree, hf_erf_lctr, tvb, 0, 0, pinfo->pseudo_header->erf.phdr.lctr);
2276
0
    if (pinfo->pseudo_header->erf.phdr.lctr > 0)
2277
0
      expert_add_info(pinfo, pi, &ei_erf_packet_loss);
2278
0
  }
2279
2280
0
  proto_tree_add_uint(tree, hf_erf_wlen, tvb, 0, 0, pinfo->pseudo_header->erf.phdr.wlen);
2281
0
}
2282
2283
static void
2284
dissect_erf_pseudo_extension_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2285
0
{
2286
0
  proto_item *pi;
2287
0
  proto_item *ehdr_tree;
2288
0
  uint64_t    hdr;
2289
0
  uint8_t     type;
2290
0
  uint8_t     has_more = pinfo->pseudo_header->erf.phdr.type & 0x80;
2291
0
  int         i        = 0;
2292
0
  int         max      = array_length(pinfo->pseudo_header->erf.ehdr_list);
2293
2294
0
  uint64_t    host_id        = ERF_META_HOST_ID_IMPLICIT;
2295
0
  uint8_t     source_id      = 0;
2296
0
  bool        found_host_id  = false;
2297
0
  bool        has_anchor_definition = false;
2298
2299
  /*
2300
   * Get the first Host ID of the record (which may not be the first extension
2301
   * header).
2302
   */
2303
0
  host_id = find_host_id(pinfo, &has_anchor_definition);
2304
0
  if (host_id == ERF_META_HOST_ID_IMPLICIT) {
2305
    /*
2306
     * XXX: We are relying here on the Wireshark doing a second parse any
2307
     * time it does anything with tree items (including filtering) to associate
2308
     * the records before the first ERF_TYPE_META record. This does not work
2309
     * with TShark in one-pass mode, in which case the first few records get
2310
     * Host ID 0 (unset).
2311
     */
2312
0
    host_id = erf_state.implicit_host_id;
2313
0
    found_host_id = false;
2314
0
  } else {
2315
0
    found_host_id = true;
2316
0
  }
2317
2318
0
  while(has_more && (i < max)) {
2319
0
    hdr = pinfo->pseudo_header->erf.ehdr_list[i].ehdr;
2320
0
    type = (uint8_t) (hdr >> 56);
2321
2322
0
    pi = proto_tree_add_uint(tree, hf_erf_ehdr_t, tvb, 0, 0, (type & 0x7f));
2323
0
    ehdr_tree = proto_item_add_subtree(pi, ett_erf_pseudo_hdr);
2324
2325
0
    switch (type & 0x7f) {
2326
0
    case ERF_EXT_HDR_TYPE_CLASSIFICATION:
2327
0
      dissect_classification_ex_header(tvb, pinfo, ehdr_tree, i);
2328
0
      break;
2329
0
    case ERF_EXT_HDR_TYPE_INTERCEPTID:
2330
0
      dissect_intercept_ex_header(tvb, pinfo, ehdr_tree, i);
2331
0
      break;
2332
0
    case ERF_EXT_HDR_TYPE_RAW_LINK:
2333
0
      dissect_raw_link_ex_header(tvb, pinfo, ehdr_tree, i);
2334
0
      break;
2335
0
    case ERF_EXT_HDR_TYPE_BFS:
2336
0
      dissect_bfs_ex_header(tvb, pinfo, ehdr_tree, i);
2337
0
      break;
2338
0
    case ERF_EXT_HDR_TYPE_CHANNELISED:
2339
0
      dissect_channelised_ex_header(tvb, pinfo, ehdr_tree, i);
2340
0
      break;
2341
0
    case ERF_EXT_HDR_TYPE_SIGNATURE:
2342
0
      dissect_signature_ex_header(tvb, pinfo, ehdr_tree, i);
2343
0
      break;
2344
0
    case ERF_EXT_HDR_TYPE_FLOW_ID:
2345
0
      if (source_id == 0) {
2346
0
        source_id = (uint8_t)((hdr >> 48) & 0xFF);
2347
0
      }
2348
0
      dissect_flow_id_ex_header(tvb, pinfo, ehdr_tree, i);
2349
0
      break;
2350
0
    case ERF_EXT_HDR_TYPE_HOST_ID:
2351
0
      host_id = hdr & ERF_EHDR_HOST_ID_MASK;
2352
0
      source_id = (uint8_t)((hdr >> 48) & 0xFF);
2353
0
      dissect_host_id_ex_header(tvb, pinfo, ehdr_tree, i);
2354
2355
      /* Track and dissect combined Host ID and Source ID(s) */
2356
0
      if (!PINFO_FD_VISITED(pinfo)) {
2357
0
        if ((pinfo->pseudo_header->erf.phdr.type & 0x7f) == ERF_TYPE_META) {
2358
          /* Update the implicit Host ID when ERF_TYPE_META */
2359
          /* XXX: We currently assume there is only one in the whole file */
2360
0
          if (erf_state.implicit_host_id == 0 && source_id > 0) {
2361
0
            erf_state.implicit_host_id = host_id;
2362
0
          }
2363
2364
          /* Add to the sequence of ERF_TYPE_META records if periodic record */
2365
          /*
2366
           * Adding metadata from comment records makes for unhelpful linking
2367
           * and means we miss out on the correct frame when marking surrounding
2368
           * metadata as depended upon (e.g. could end up with a comment from
2369
           * another frame). We mark the anchor linked records separately.
2370
           */
2371
0
          if (!has_anchor_definition) {
2372
            /* XXX: this is a heuristic, technically we could have non-local sections
2373
              in the metadata even as an anchor definition record. */
2374
0
            erf_source_append(host_id, source_id, pinfo->num);
2375
0
          }
2376
0
        }
2377
0
      }
2378
0
      dissect_host_id_source_id(tvb, pinfo, tree, host_id, source_id);
2379
0
      break;
2380
0
    case ERF_EXT_HDR_TYPE_ANCHOR_ID:
2381
0
      dissect_anchor_id_ex_header(tvb, pinfo, ehdr_tree, i);
2382
0
      if (!PINFO_FD_VISITED(pinfo)) {
2383
0
        erf_host_anchor_info_insert(pinfo, host_id, hdr & ERF_EHDR_ANCHOR_ID_MASK, (uint8_t)(hdr >> 48));
2384
0
      }
2385
0
      dissect_host_anchor_id(tvb, pinfo, tree, host_id, hdr & ERF_EHDR_ANCHOR_ID_MASK, (uint8_t)(hdr >> 48));
2386
0
      break;
2387
0
    case ERF_EXT_HDR_TYPE_ENTROPY:
2388
0
      dissect_entropy_ex_header(tvb, pinfo, ehdr_tree, i);
2389
0
      break;
2390
0
    default:
2391
0
      dissect_unknown_ex_header(tvb, pinfo, ehdr_tree, i);
2392
0
      break;
2393
0
    }
2394
2395
0
    has_more = type & 0x80;
2396
0
    i += 1;
2397
0
  }
2398
0
  if (has_more) {
2399
0
    proto_tree_add_expert(tree, pinfo, &ei_erf_extension_headers_not_shown, tvb, 0, 0);
2400
0
  }
2401
2402
  /* If we have no explicit Host ID association, associate with the first Source ID (or 0) and implicit Host ID */
2403
  /* XXX: We are allowed to assume there is only one Source ID unless we have
2404
   * a Host ID extension header */
2405
0
  if (!found_host_id) {
2406
    /*
2407
     * TODO: Do we also want to track Host ID 0 Source ID 0 records?
2408
     * Don't for now to preserve feel of legacy files.
2409
     */
2410
0
    if (host_id != 0 || source_id != 0) {
2411
0
      if (!PINFO_FD_VISITED(pinfo)) {
2412
0
        if ((pinfo->pseudo_header->erf.phdr.type & 0x7f) == ERF_TYPE_META) {
2413
          /* Add to the sequence of ERF_TYPE_META records */
2414
0
          erf_source_append(host_id, source_id, pinfo->num);
2415
0
        }
2416
0
      }
2417
0
      dissect_host_id_source_id(tvb, pinfo, tree, host_id, source_id);
2418
0
    }
2419
0
  }
2420
0
}
2421
2422
0
uint64_t* erf_get_ehdr(packet_info *pinfo, uint8_t hdrtype, int* afterindex) {
2423
0
  uint8_t     type;
2424
0
  uint8_t     has_more;
2425
0
  int         max;
2426
0
  int         i        = afterindex ? *afterindex + 1 : 0; /*allow specifying instance to start after for use in loop*/
2427
2428
0
  if (!pinfo) /*XXX: how to determine if erf pseudo_header is valid?*/
2429
0
      return NULL;
2430
2431
0
  has_more = pinfo->pseudo_header->erf.phdr.type & 0x80;
2432
0
  max      = array_length(pinfo->pseudo_header->erf.ehdr_list);
2433
2434
2435
0
  while(has_more && (i < max)) {
2436
0
    type = (uint8_t) (pinfo->pseudo_header->erf.ehdr_list[i].ehdr >> 56);
2437
2438
0
    if ((type & 0x7f) == (hdrtype & 0x7f)) {
2439
0
         if (afterindex)
2440
0
             *afterindex = i;
2441
0
         return &pinfo->pseudo_header->erf.ehdr_list[i].ehdr;
2442
0
    }
2443
2444
0
    has_more = type & 0x80;
2445
0
    i += 1;
2446
0
  }
2447
2448
0
  return NULL;
2449
0
}
2450
2451
static void
2452
0
check_section_length(packet_info *pinfo, proto_item *sectionlen_pi, int offset, int sectionoffset, int sectionlen) {
2453
0
  if (sectionlen_pi) {
2454
0
    if (offset - sectionoffset == sectionlen) {
2455
0
      proto_item_append_text(sectionlen_pi, " [correct]");
2456
0
    } else if (sectionlen != 0) {
2457
0
      proto_item_append_text(sectionlen_pi, " [incorrect, should be %u]", offset - sectionoffset);
2458
0
      expert_add_info(pinfo, sectionlen_pi, &ei_erf_meta_section_len_error);
2459
0
    }
2460
0
  }
2461
0
}
2462
2463
static proto_item*
2464
dissect_meta_tag_bitfield(proto_item *section_tree, tvbuff_t *tvb, int offset, erf_meta_tag_info_t *tag_info, proto_item **out_tag_tree)
2465
0
{
2466
0
  proto_item *tag_pi        = NULL;
2467
0
  int* hf_flags[ERF_HF_VALUES_PER_TAG];
2468
0
  int i;
2469
2470
0
  DISSECTOR_ASSERT(tag_info->extra);
2471
2472
0
  for (i = 0; tag_info->extra->hf_values[i] != -1; i++) {
2473
0
    hf_flags[i] = &tag_info->extra->hf_values[i];
2474
0
  }
2475
0
  hf_flags[i] = NULL;
2476
2477
  /* use flags variant so we print integers without value_strings */
2478
0
  tag_pi = proto_tree_add_bitmask_with_flags(section_tree, tvb, offset + 4, tag_info->hf_value, tag_info->ett, hf_flags, ENC_BIG_ENDIAN, BMT_NO_FLAGS);
2479
0
  if (out_tag_tree) {
2480
0
    *out_tag_tree = proto_item_get_subtree(tag_pi);
2481
0
  }
2482
2483
0
  return tag_pi;
2484
0
}
2485
2486
static proto_item*
2487
dissect_meta_tag_ext_hdrs(proto_item *section_tree, packet_info* pinfo, tvbuff_t *tvb, int offset, int taglength, erf_meta_tag_info_t *tag_info, proto_item **out_tag_tree, expert_field **out_truncated_expert)
2488
0
{
2489
0
  proto_item *tag_pi        = NULL;
2490
0
  proto_tree *subtree       = NULL;
2491
0
  proto_item *subtree_pi    = NULL;
2492
0
  int i;
2493
0
  uint32_t ext_hdrs[4] = {0, 0, 0, 0};
2494
0
  int int_offset      = 0;
2495
0
  int int_avail       = MIN(taglength / 4, 4);
2496
0
  int bit_offset      = 0;
2497
0
  int ext_hdr_num     = 0;
2498
0
  bool first      = true;
2499
0
  bool all_set    = true;
2500
2501
0
  DISSECTOR_ASSERT(tag_info->extra);
2502
2503
0
  tag_pi = proto_tree_add_item(section_tree, tag_info->hf_value, tvb, offset + 4, taglength, ENC_BIG_ENDIAN);
2504
0
  *out_tag_tree = proto_item_add_subtree(tag_pi, tag_info->ett);
2505
2506
0
  for (int_offset = 0; int_offset < int_avail; int_offset++) {
2507
0
    ext_hdrs[int_offset] = tvb_get_uint32(tvb, offset + 4 + int_offset*4, ENC_BIG_ENDIAN);
2508
0
    if (ext_hdrs[int_offset] != UINT32_MAX)
2509
0
      all_set = false;
2510
0
  }
2511
2512
  /* Special case: all specified bits are 1 means all extension headers */
2513
0
  if (all_set)
2514
0
    proto_item_append_text(tag_pi, ": <All>");
2515
2516
  /* Add 4 subtrees, one for each uint32 representing 32 extension header numbers */
2517
0
  for (int_offset = 0; int_offset < int_avail; int_offset++) {
2518
    /* TODO: Put subtree hf values somewhere better than first 4 hf_values */
2519
0
    subtree_pi = proto_tree_add_item(*out_tag_tree, tag_info->extra->hf_values[int_offset], tvb, offset + 4 + int_offset*4, 4, ENC_BIG_ENDIAN);
2520
2521
    /* Add the individual bit dissections */
2522
    /* XXX: This currently assumes we only know up to the first 32 */
2523
0
    if (int_offset == 0) {
2524
0
      subtree = proto_item_add_subtree(subtree_pi, tag_info->ett);
2525
0
      for (i = 4; tag_info->extra->hf_values[i] != -1; i++) {
2526
0
        proto_tree_add_boolean(subtree, tag_info->extra->hf_values[i], tvb, offset + 4 + int_offset*4, 4, ext_hdrs[int_offset]);
2527
0
      }
2528
0
    }
2529
2530
    /* Add all set bits to the header, including the ones we don't understand */
2531
0
    for (bit_offset = 0; bit_offset < 32; bit_offset++) {
2532
0
      if (ext_hdrs[int_offset] & (1U << bit_offset)) {
2533
0
        char* str = val_to_str(pinfo->pool, ext_hdr_num, ehdr_type_vals, "%d");
2534
0
        proto_item_append_text(subtree_pi, ", %s", str);
2535
2536
        /* Also add to the top level */
2537
0
        if (!all_set)
2538
0
          proto_item_append_text(tag_pi, "%s %s", first ? ":" : ",", str);
2539
2540
0
        first = false;
2541
0
      }
2542
2543
0
      ext_hdr_num++;
2544
0
    }
2545
0
  }
2546
2547
0
  if (first)
2548
0
    proto_item_append_text(tag_pi, ": <None>");
2549
2550
  /* Check for truncated tag (i.e. last uint32 is partial) */
2551
0
  if (int_avail < 4 && taglength % 4 != 0) {
2552
0
    *out_truncated_expert = &ei_erf_meta_truncated_tag;
2553
0
  }
2554
2555
0
  return tag_pi;
2556
0
}
2557
2558
0
static void erf_ts_to_nstime(uint64_t timestamp, nstime_t* t, bool is_relative) {
2559
0
  uint64_t ts = timestamp;
2560
2561
  /* relative ERF timestamps are signed, convert as if unsigned then flip back */
2562
0
  if (is_relative) {
2563
0
    ts = (uint64_t) ABS((int64_t)timestamp);
2564
0
  }
2565
2566
2567
0
  t->secs = (long) (ts >> 32);
2568
0
  ts  = ((ts & 0xffffffff) * 1000 * 1000 * 1000);
2569
0
  ts += (ts & 0x80000000) << 1; /* rounding */
2570
0
  t->nsecs = ((int) (ts >> 32));
2571
0
  if (t->nsecs >= NS_PER_S) {
2572
0
    t->nsecs -= NS_PER_S;
2573
0
    t->secs += 1;
2574
0
  }
2575
2576
0
  if (is_relative && (int64_t)timestamp < 0) {
2577
    /*
2578
     * Set both signs to negative for consistency with other nstime code
2579
     * and so -0.123 works.
2580
     */
2581
0
    t->secs = -(t->secs);
2582
0
    t->nsecs = -(t->nsecs);
2583
0
  }
2584
0
}
2585
2586
/* TODO: Would be nice if default FT_RELATIVE_TIME formatter was prettier */
2587
0
static proto_item *dissect_relative_time(proto_tree *tree, const int hfindex, tvbuff_t *tvb, int offset, int length, nstime_t* t) {
2588
0
  proto_item *pi = NULL;
2589
2590
0
  DISSECTOR_ASSERT(t);
2591
2592
  /*Print in nanoseconds if <1ms for small values*/
2593
0
  if (t->secs == 0 && t->nsecs < 1000000 && t->nsecs > -1000000) {
2594
0
    pi = proto_tree_add_time_format_value(tree, hfindex, tvb, offset, length, t, "%d nanoseconds", t->nsecs);
2595
0
  } else {
2596
0
    pi = proto_tree_add_time(tree, hfindex, tvb, offset, length, t);
2597
0
  }
2598
2599
0
  return pi;
2600
0
}
2601
2602
0
static proto_item *dissect_ptp_timeinterval(proto_tree *tree, const int hfindex, tvbuff_t *tvb, int offset, int length, int64_t timeinterval) {
2603
0
  nstime_t t;
2604
0
  uint64_t ti, ti_ns;
2605
2606
0
  ti = (uint64_t) ABS(timeinterval);
2607
2608
0
  ti += (ti & 0x8000) << 1; /* rounding */
2609
0
  ti_ns = ti >> 16;
2610
0
  t.secs = (time_t) (ti_ns / NS_PER_S);
2611
0
  t.nsecs = (uint32_t)(ti_ns % NS_PER_S);
2612
0
  if (t.nsecs >= NS_PER_S) {
2613
0
    t.nsecs -= NS_PER_S;
2614
0
    t.secs += 1;
2615
0
  }
2616
2617
0
  if (timeinterval < 0) {
2618
    /*
2619
     * Set both signs to negative for consistency with other nstime code
2620
     * and so -0.123 works.
2621
     */
2622
0
    t.secs = -(t.secs);
2623
0
    t.nsecs = -(t.nsecs);
2624
0
  }
2625
2626
0
  return dissect_relative_time(tree, hfindex, tvb, offset, length, &t);
2627
0
}
2628
2629
static int
2630
0
meta_tag_expected_length(erf_meta_tag_info_t *tag_info) {
2631
0
  ftenum_t ftype = tag_info->tag_template->hfinfo.type;
2632
0
  int expected_length = 0;
2633
2634
0
  switch (ftype) {
2635
0
    case FT_ABSOLUTE_TIME:
2636
0
    case FT_RELATIVE_TIME:
2637
      /* Timestamps are in ERF timestamp except as below */
2638
0
      expected_length = 8;
2639
0
      break;
2640
2641
0
    default:
2642
0
      expected_length = ftype_wire_size(ftype); /* Returns 0 if unknown */
2643
0
      break;
2644
0
  }
2645
2646
  /* Special case overrides */
2647
0
  switch (tag_info->code) {
2648
0
    case ERF_META_TAG_ptp_current_utc_offset:
2649
      /*
2650
       * PTP tags are in native PTP format, but only current_utc_offset is
2651
       * a different length to the ERF timestamp.
2652
       */
2653
0
      expected_length = 4;
2654
0
      break;
2655
2656
0
    case ERF_META_TAG_if_wwn:
2657
0
    case ERF_META_TAG_src_wwn:
2658
0
    case ERF_META_TAG_dest_wwn:
2659
0
    case ERF_META_TAG_ns_host_wwn:
2660
      /* 16-byte WWNs */
2661
0
      expected_length = 16;
2662
0
      break;
2663
2664
0
    case ERF_META_TAG_ext_hdrs_added:
2665
0
    case ERF_META_TAG_ext_hdrs_removed:
2666
      /* 1 to 4 uint32 fields */
2667
0
      expected_length = 4;
2668
0
      break;
2669
0
  }
2670
2671
0
  return expected_length;
2672
0
}
2673
2674
static void
2675
0
dissect_meta_record_tags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
2676
0
  proto_item *pi            = NULL;
2677
0
  proto_item *tag_pi        = NULL;
2678
0
  proto_item *tag_tree;
2679
0
  proto_item *section_pi    = NULL;
2680
0
  proto_item *section_tree  = tree;
2681
0
  proto_item *sectionlen_pi = NULL;
2682
2683
0
  uint16_t               sectiontype  = ERF_META_SECTION_NONE;
2684
0
  uint16_t               tagtype      = 0;
2685
0
  uint16_t               taglength    = 0;
2686
0
  const char            *tagvalstring = NULL;
2687
0
  erf_meta_tag_info_t   *tag_info;
2688
0
  int                    expected_length = 0;
2689
0
  expert_field          *truncated_expert = NULL;
2690
0
  bool                   skip_truncated = false;
2691
2692
  /* Used for search entry and unknown tags */
2693
0
  erf_meta_hf_template_t tag_template_unknown = { 0, { "Unknown", "unknown",
2694
0
    FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } };
2695
0
  erf_meta_tag_info_t    tag_info_local       = { 0, 0, &tag_template_unknown, &tag_template_unknown,
2696
0
    ett_erf_meta_tag, hf_erf_meta_tag_unknown, NULL };
2697
2698
0
  int     offset        = 0;
2699
0
  int     sectionoffset = 0;
2700
0
  uint16_t sectionid     = 0;
2701
0
  uint16_t sectionlen    = 0;
2702
0
  int     remaining_len = 0;
2703
2704
0
  int captured_length = (int) tvb_captured_length(tvb);
2705
2706
  /* Set column heading title*/
2707
0
  col_set_str(pinfo->cinfo, COL_INFO, "Provenance Metadata");
2708
2709
  /* Go through the sections and their tags */
2710
  /* Not using tvb_captured_length because want to check for overrun */
2711
0
  while ((remaining_len = captured_length - offset) >= 4) {
2712
0
    tagtype = tvb_get_ntohs(tvb, offset);
2713
0
    taglength = tvb_get_ntohs(tvb, offset + 2);
2714
0
    tag_tree = NULL;
2715
0
    tag_pi = NULL;
2716
0
    truncated_expert = NULL;
2717
0
    skip_truncated = false;
2718
2719
0
    if (ERF_META_IS_SECTION(tagtype))
2720
0
      sectiontype = tagtype;
2721
2722
    /* Look up per-section tag hf */
2723
0
    tag_info_local.code = tagtype;
2724
0
    tag_info_local.section = sectiontype;
2725
0
    tag_info = (erf_meta_tag_info_t*) wmem_map_lookup(erf_meta_index.tag_table, GUINT_TO_POINTER(ERF_TAG_INFO_KEY(&tag_info_local)));
2726
2727
    /* Fall back to unknown tag */
2728
0
    if (tag_info == NULL)
2729
0
      tag_info = &tag_info_local;
2730
2731
    /* Get expected length (minimum length in the case of ns_host_*) */
2732
0
    expected_length = meta_tag_expected_length(tag_info);
2733
2734
0
    if (remaining_len < (int32_t)taglength + 4 || taglength < expected_length) {
2735
      /*
2736
       * Malformed tag, just dissect type and length. Top level tag
2737
       * dissection means can't add the subtree and type/length first.
2738
       *
2739
       * Allow too-long tags for now (and proto_tree generally generates
2740
       * a warning for these anyway).
2741
       */
2742
0
      skip_truncated = true;
2743
0
      truncated_expert = &ei_erf_meta_truncated_tag;
2744
0
    }
2745
2746
0
    if (taglength == 0) {
2747
      /*
2748
       * We highlight zero length differently as a special case to indicate
2749
       * a deliberately invalid tag.
2750
       */
2751
0
      if (!ERF_META_IS_SECTION(tagtype) && tagtype != ERF_META_TAG_padding) {
2752
0
        truncated_expert = &ei_erf_meta_zero_len_tag;
2753
        /* XXX: Still dissect normally too if string/unknown or section header */
2754
0
        if (expected_length != 0) {
2755
0
          skip_truncated = true;
2756
0
        }
2757
0
      }
2758
0
    }
2759
2760
    /* Dissect value, length and type */
2761
0
    if (ERF_META_IS_SECTION(tagtype)) { /* Section header tag */
2762
0
      if (section_pi) {
2763
        /* Update section item length of last section */
2764
0
        proto_item_set_len(section_pi, offset - sectionoffset);
2765
0
        if (sectionlen_pi) {
2766
0
          check_section_length(pinfo, sectionlen_pi, offset, sectionoffset, sectionlen);
2767
0
        }
2768
0
      }
2769
2770
0
      sectionoffset = offset;
2771
0
      if (tag_info->tag_template == &tag_template_unknown) {
2772
        /* Unknown section */
2773
0
        sectiontype = ERF_META_SECTION_UNKNOWN;
2774
0
        tag_info = erf_meta_index.unknown_section_info;
2775
0
      }
2776
0
      DISSECTOR_ASSERT(tag_info->extra);
2777
2778
0
      tagvalstring = val_to_str(pinfo->pool, tagtype, erf_to_value_string(erf_meta_index.vs_list), "Unknown Section (0x%x)");
2779
0
      col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "%s", tagvalstring);
2780
0
      section_tree = proto_tree_add_subtree(tree, tvb, offset, 0, tag_info->extra->ett_value, &section_pi, tagvalstring);
2781
0
      tag_tree = proto_tree_add_subtree_format(section_tree, tvb, offset, MIN(taglength + 4, remaining_len), tag_info->ett, &tag_pi, "Provenance %s Header", tagvalstring);
2782
2783
      /* XXX: Value may have been truncated (avoiding exception so get custom expertinfos) */
2784
0
      if (taglength >= 4 && !skip_truncated) {
2785
0
        sectionid = tvb_get_ntohs(tvb, offset + 4);
2786
0
        sectionlen = tvb_get_ntohs(tvb, offset + 6);
2787
2788
        /* Add section_id */
2789
0
        proto_tree_add_uint(tag_tree, tag_info->hf_value, tvb, offset + 4, 2, sectionid);
2790
0
        if (sectionid != 0) {
2791
0
          if(sectionid & 0x8000U) {
2792
            /* Local section */
2793
0
            proto_item_append_text(section_pi, " (Local) %u", sectionid & 0x7FFFU);
2794
0
          }
2795
0
          else {
2796
0
            proto_item_append_text(section_pi, " %u", sectionid);
2797
0
          }
2798
0
        }
2799
2800
        /* Add section_len */
2801
0
        sectionlen_pi = proto_tree_add_uint(tag_tree, tag_info->extra->hf_values[0], tvb, offset + 6, 2, sectionlen);
2802
2803
        /* Reserved extra section header information */
2804
0
        if (taglength > 4) {
2805
0
          proto_tree_add_item(tag_tree, tag_info->extra->hf_values[1], tvb, offset + 8, taglength - 4, ENC_NA);
2806
0
        }
2807
0
      } else if (taglength != 0) {
2808
        /* Section Header value is too short */
2809
0
        truncated_expert = &ei_erf_meta_truncated_tag;
2810
0
      }
2811
0
    } else if (!skip_truncated) { /* Not section header tag (and not truncated) */
2812
0
      enum ftenum tag_ft;
2813
0
      char        pi_label[ITEM_LABEL_LENGTH+1];
2814
0
      bool        dissected = true;
2815
0
      uint32_t    value32;
2816
0
      uint64_t    value64;
2817
0
      float       float_value;
2818
0
      char       *tmp = NULL;
2819
2820
0
      tag_ft = tag_info->tag_template->hfinfo.type;
2821
0
      pi_label[0] = '\0';
2822
2823
      /* Group tags before first section header into a fake section */
2824
0
      if (offset == 0) {
2825
0
        section_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_erf_meta, &section_pi, "No Section");
2826
0
      }
2827
2828
      /* Handle special cases */
2829
      /* TODO: might want to do this dynamically via tag_info callback */
2830
0
      switch (tagtype) {
2831
      /* TODO: use get_tcp_port in epan/addr_resolv.h etc */
2832
0
      case ERF_META_TAG_if_speed:
2833
0
      case ERF_META_TAG_if_tx_speed:
2834
0
        value64 = tvb_get_ntoh64(tvb, offset + 4);
2835
0
        tmp = format_size((int64_t)value64, FORMAT_SIZE_UNIT_BITS_S, FORMAT_SIZE_PREFIX_SI);
2836
0
        tag_pi = proto_tree_add_uint64_format_value(section_tree, tag_info->hf_value, tvb, offset + 4, taglength, value64, "%s (%" PRIu64 " bps)", tmp, value64);
2837
0
        g_free(tmp);
2838
0
        break;
2839
2840
0
      case ERF_META_TAG_if_rx_power:
2841
0
      case ERF_META_TAG_if_tx_power:
2842
0
        value32 = tvb_get_ntohl(tvb, offset + 4);
2843
0
        tag_pi = proto_tree_add_int_format_value(section_tree, tag_info->hf_value, tvb, offset + 4, taglength, (int32_t) value32, "%.2fdBm", (double)((int32_t) value32)/100.0);
2844
0
        break;
2845
2846
0
      case ERF_META_TAG_temperature:
2847
0
      case ERF_META_TAG_power:
2848
0
        value32 = tvb_get_ntohl(tvb, offset + 4);
2849
0
        float_value = (float)((int32_t) value32)/1000.0f;
2850
0
        tag_pi = proto_tree_add_float(section_tree, tag_info->hf_value, tvb, offset + 4, taglength, float_value);
2851
0
        break;
2852
2853
0
      case ERF_META_TAG_loc_lat:
2854
0
      case ERF_META_TAG_loc_long:
2855
0
        value32 = tvb_get_ntohl(tvb, offset + 4);
2856
0
        tag_pi = proto_tree_add_int_format_value(section_tree, tag_info->hf_value, tvb, offset + 4, taglength, (int32_t) value32, "%.2f", (double)((int32_t) value32)*1000000.0);
2857
0
        break;
2858
2859
0
      case ERF_META_TAG_mask_cidr:
2860
0
        value32 = tvb_get_ntohl(tvb, offset + 4);
2861
0
        tag_pi = proto_tree_add_uint_format_value(section_tree, tag_info->hf_value, tvb, offset + 4, taglength, value32, "/%u", value32);
2862
0
        break;
2863
2864
0
      case ERF_META_TAG_mem:
2865
0
        value64 = tvb_get_ntoh64(tvb, offset + 4);
2866
0
        tmp = format_size((int64_t)value64, FORMAT_SIZE_UNIT_BYTES, FORMAT_SIZE_PREFIX_IEC);
2867
0
        tag_pi = proto_tree_add_uint64_format_value(section_tree, tag_info->hf_value, tvb, offset + 4, taglength, value64, "%s (%" PRIu64" bytes)", tmp, value64);
2868
0
        g_free(tmp);
2869
0
        break;
2870
2871
0
      case ERF_META_TAG_parent_section:
2872
0
        DISSECTOR_ASSERT(tag_info->extra);
2873
0
        value32 = tvb_get_ntohs(tvb, offset + 4);
2874
        /*
2875
         * XXX: Formatting value manually because don't have erf_meta_vs_list
2876
         * populated at registration time.
2877
         */
2878
0
        tag_tree = proto_tree_add_subtree_format(section_tree, tvb, offset + 4, taglength, tag_info->ett, &tag_pi, "%s: %s %u", tag_info->tag_template->hfinfo.name,
2879
0
            val_to_str(pinfo->pool, value32, erf_to_value_string(erf_meta_index.vs_list), "Unknown Section (%u)"), tvb_get_ntohs(tvb, offset + 4 + 2));
2880
2881
0
        proto_tree_add_uint_format_value(tag_tree, tag_info->extra->hf_values[0], tvb, offset + 4, MIN(2, taglength), value32, "%s (%u)",
2882
0
            val_to_str_const(value32, erf_to_value_string(erf_meta_index.vs_abbrev_list), "Unknown"), value32);
2883
0
        proto_tree_add_item(tag_tree, tag_info->extra->hf_values[1], tvb, offset + 6, MIN(2, taglength - 2), ENC_BIG_ENDIAN);
2884
0
        break;
2885
2886
0
      case ERF_META_TAG_reset:
2887
0
        tag_pi = proto_tree_add_item(section_tree, tag_info->hf_value, tvb, offset + 4, taglength, ENC_NA);
2888
0
        expert_add_info(pinfo, tag_pi, &ei_erf_meta_reset);
2889
0
        break;
2890
2891
0
      case ERF_META_TAG_if_link_status:
2892
0
      case ERF_META_TAG_tunneling_mode:
2893
0
      case ERF_META_TAG_ptp_time_properties:
2894
0
      case ERF_META_TAG_ptp_gm_clock_quality:
2895
0
      case ERF_META_TAG_stream_flags:
2896
0
      case ERF_META_TAG_smart_trunc_default:
2897
0
        tag_pi = dissect_meta_tag_bitfield(section_tree, tvb, offset, tag_info, &tag_tree);
2898
0
        break;
2899
2900
2901
0
      case ERF_META_TAG_ns_dns_ipv4:
2902
0
      case ERF_META_TAG_ns_dns_ipv6:
2903
0
      case ERF_META_TAG_ns_host_ipv4:
2904
0
      case ERF_META_TAG_ns_host_ipv6:
2905
0
      case ERF_META_TAG_ns_host_mac:
2906
0
      case ERF_META_TAG_ns_host_eui:
2907
0
      case ERF_META_TAG_ns_host_wwn:
2908
0
      case ERF_META_TAG_ns_host_ib_gid:
2909
0
      case ERF_META_TAG_ns_host_ib_lid:
2910
0
      case ERF_META_TAG_ns_host_fc_id:
2911
0
      {
2912
0
        int addr_len = ftype_wire_size(tag_ft);
2913
2914
0
        DISSECTOR_ASSERT(tag_info->extra);
2915
2916
0
        tag_tree = proto_tree_add_subtree(section_tree, tvb, offset + 4, taglength, tag_info->ett, &tag_pi, tag_info->tag_template->hfinfo.name);
2917
        /* Address */
2918
0
        pi = proto_tree_add_item(tag_tree, tag_info->extra->hf_values[0], tvb, offset + 4, MIN(addr_len, taglength), ENC_BIG_ENDIAN);
2919
        /* Name */
2920
0
        proto_tree_add_item(tag_tree, tag_info->extra->hf_values[1], tvb, offset + 4 + addr_len, taglength - addr_len, ENC_UTF_8);
2921
0
        if (pi) {
2922
0
          proto_item_fill_label(PITEM_FINFO(pi), pi_label, NULL);
2923
          /* Set top level label e.g IPv4 Name: hostname Address: 1.2.3.4 */
2924
          /* TODO: Name is unescaped here but escaped in actual field */
2925
0
          proto_item_append_text(tag_pi, ": %s, %s",
2926
0
              tvb_get_stringzpad(pinfo->pool, tvb, offset + 4 + addr_len, taglength - addr_len, ENC_UTF_8), pi_label /* Includes ": " */);
2927
0
        }
2928
2929
0
        break;
2930
0
      }
2931
2932
0
      case ERF_META_TAG_ptp_offset_from_master:
2933
0
      case ERF_META_TAG_ptp_mean_path_delay:
2934
0
        value64 = tvb_get_ntoh64(tvb, offset + 4);
2935
0
        tag_pi = dissect_ptp_timeinterval(section_tree, tag_info->hf_value, tvb, offset + 4, taglength, (int64_t) value64);
2936
0
        break;
2937
2938
0
      case ERF_META_TAG_ptp_current_utc_offset:
2939
0
      {
2940
0
        nstime_t t;
2941
2942
0
        value32 = tvb_get_ntohl(tvb, offset + 4);
2943
        /* PTP value is signed */
2944
0
        t.secs = (int32_t) value32;
2945
0
        t.nsecs = 0;
2946
2947
0
        tag_pi = dissect_relative_time(section_tree, tag_info->hf_value, tvb, offset + 4, taglength, &t);
2948
0
        break;
2949
0
      }
2950
2951
0
      case ERF_META_TAG_entropy_threshold:
2952
0
      case ERF_META_TAG_initiator_min_entropy:
2953
0
      case ERF_META_TAG_responder_min_entropy:
2954
0
      case ERF_META_TAG_initiator_avg_entropy:
2955
0
      case ERF_META_TAG_responder_avg_entropy:
2956
0
      case ERF_META_TAG_initiator_max_entropy:
2957
0
      case ERF_META_TAG_responder_max_entropy:
2958
0
      {
2959
0
        float entropy;
2960
0
        value32 = tvb_get_ntohl(tvb, offset + 4);
2961
0
        entropy = entropy_from_entropy_header_value((uint8_t) value32);
2962
2963
0
        tag_pi = proto_tree_add_float_format_value(section_tree, tag_info->hf_value, tvb, 0, 0, entropy,
2964
0
          "%.2f %s", (double) entropy, entropy == 0.0f ? "(not calculated)":"bits");
2965
0
        break;
2966
0
      }
2967
2968
0
      case ERF_META_TAG_ext_hdrs_added:
2969
0
      case ERF_META_TAG_ext_hdrs_removed:
2970
0
        tag_pi = dissect_meta_tag_ext_hdrs(section_tree, pinfo, tvb, offset, taglength, tag_info, &tag_tree, &truncated_expert);
2971
0
        break;
2972
2973
0
      default:
2974
0
        dissected = false;
2975
0
        break;
2976
0
      }
2977
2978
      /* If not special case, dissect generically from template */
2979
0
      if (!dissected) {
2980
0
        if (FT_IS_INT(tag_ft) || FT_IS_UINT(tag_ft)) {
2981
0
          tag_pi = proto_tree_add_item(section_tree, tag_info->hf_value, tvb, offset + 4, taglength, ENC_BIG_ENDIAN);
2982
0
        } else if (FT_IS_STRING(tag_ft)) {
2983
0
          tag_pi = proto_tree_add_item(section_tree, tag_info->hf_value, tvb, offset + 4, taglength, ENC_UTF_8);
2984
0
        } else if (FT_IS_TIME(tag_ft)) {
2985
          /*
2986
           * ERF timestamps are conveniently the same as NTP/PTP timestamps but
2987
           * little endian.
2988
           */
2989
          /*
2990
           * FIXME: ENC_TIME_NTP | ENC_LITTLE_ENDIAN only swaps the
2991
           * upper and lower 32 bits. Is that a bug or by design? Should add
2992
           * a 'PTP" variant that doesn't round to microseconds and use that
2993
           * here. For now do by hand.
2994
           */
2995
0
          nstime_t t;
2996
0
          uint64_t ts;
2997
2998
0
          ts = tvb_get_letoh64(tvb, offset + 4);
2999
0
          erf_ts_to_nstime(ts, &t, tag_ft == FT_RELATIVE_TIME);
3000
3001
0
          tag_pi = dissect_relative_time(section_tree, tag_info->hf_value, tvb, offset + 4, taglength, &t);
3002
0
        } else {
3003
0
          tag_pi = proto_tree_add_item(section_tree, tag_info->hf_value, tvb, offset + 4, taglength, ENC_NA);
3004
0
        }
3005
0
      }
3006
0
    }
3007
3008
    /* Create subtree for tag if we haven't already */
3009
0
    if (!tag_tree) {
3010
      /* Make sure we actually put the subtree in the right place */
3011
0
      if (tag_pi || !tree) {
3012
0
        tag_tree = proto_item_add_subtree(tag_pi, tag_info->ett);
3013
0
      } else {
3014
        /* Truncated or error (avoiding exception so get custom expertinfos) */
3015
0
        tag_tree = proto_tree_add_subtree_format(section_tree, tvb, offset, MIN(taglength + 4, remaining_len), tag_info->ett, &tag_pi, "%s: [Invalid]", tag_info->tag_template->hfinfo.name);
3016
0
      }
3017
0
    }
3018
3019
    /* Add tag type field to subtree */
3020
    /*
3021
     * XXX: Formatting value manually because don't have erf_meta_vs_list
3022
     * populated at registration time.
3023
     */
3024
0
    proto_tree_add_uint_format_value(tag_tree, hf_erf_meta_tag_type, tvb, offset, 2, tagtype, "%s (%u)", val_to_str_const(tagtype, erf_to_value_string(erf_meta_index.vs_abbrev_list), "Unknown"), tagtype);
3025
0
    proto_tree_add_uint(tag_tree, hf_erf_meta_tag_len, tvb, offset + 2, 2, taglength);
3026
3027
    /* Add truncated expertinfo if needed */
3028
0
    if (truncated_expert) {
3029
0
      expert_add_info(pinfo, tag_pi, truncated_expert);
3030
0
    }
3031
3032
0
    offset += (((uint32_t)taglength + 4) + 0x3U) & ~0x3U;
3033
0
  }
3034
3035
0
  if (remaining_len != 0) {
3036
    /* Record itself is truncated */
3037
0
    expert_add_info(pinfo, proto_tree_get_parent(tree), &ei_erf_meta_truncated_record);
3038
    /* Continue to setting sectionlen error */
3039
0
  }
3040
3041
  /* Check final section length */
3042
0
  proto_item_set_len(section_pi, offset - sectionoffset);
3043
0
  check_section_length(pinfo, sectionlen_pi, offset, sectionoffset, sectionlen);
3044
0
}
3045
3046
static int
3047
dissect_erf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3048
0
{
3049
0
  uint8_t             flags;
3050
0
  uint8_t             erf_type;
3051
0
  uint32_t            atm_hdr  = 0;
3052
0
  proto_tree         *erf_tree;
3053
0
  proto_item         *erf_item;
3054
0
  erf_hdlc_type_vals  hdlc_type;
3055
0
  uint8_t             first_byte;
3056
0
  tvbuff_t           *new_tvb;
3057
0
  uint8_t             aal2_cid;
3058
0
  struct atm_phdr     atm_info;
3059
3060
0
  erf_type=pinfo->pseudo_header->erf.phdr.type & 0x7F;
3061
3062
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "ERF");
3063
3064
0
  col_add_str(pinfo->cinfo, COL_INFO,
3065
0
       val_to_str(pinfo->pool, erf_type, erf_type_vals, "Unknown type %u"));
3066
3067
0
  erf_item = proto_tree_add_item(tree, proto_erf, tvb, 0, -1, ENC_NA);
3068
0
  erf_tree = proto_item_add_subtree(erf_item, ett_erf);
3069
3070
0
  dissect_erf_pseudo_header(tvb, pinfo, erf_tree);
3071
0
  if (pinfo->pseudo_header->erf.phdr.type & 0x80) {
3072
0
    dissect_erf_pseudo_extension_header(tvb, pinfo, erf_tree);
3073
0
    }
3074
3075
0
  flags = pinfo->pseudo_header->erf.phdr.flags;
3076
  /*
3077
   * Set if frame is Received or Sent.
3078
   * XXX - this is really testing the low-order bit of the capture
3079
   * interface number, so interface 0 is assumed to be capturing
3080
   * in one direction on a bi-directional link, interface 1 is
3081
   * assumed to be capturing in the other direction on that link,
3082
   * and interfaces 2 and 3 are assumed to be capturing in two
3083
   * different directions on another link.  We don't distinguish
3084
   * between the two links.
3085
   */
3086
0
  pinfo->p2p_dir = ( (flags & 0x01) ? P2P_DIR_RECV : P2P_DIR_SENT);
3087
3088
0
  switch (erf_type) {
3089
3090
0
  case ERF_TYPE_RAW_LINK:
3091
0
    if(sdh_handle) {
3092
0
      call_dissector(sdh_handle, tvb, pinfo, tree);
3093
0
    }
3094
0
    else{
3095
0
      call_data_dissector(tvb, pinfo, tree);
3096
0
    }
3097
0
    break;
3098
3099
0
  case ERF_TYPE_ETH:
3100
0
  case ERF_TYPE_COLOR_ETH:
3101
0
  case ERF_TYPE_DSM_COLOR_ETH:
3102
0
  case ERF_TYPE_COLOR_HASH_ETH:
3103
0
    dissect_eth_header(tvb, pinfo, erf_tree);
3104
    /* fall through */
3105
0
  case ERF_TYPE_IPV4:
3106
0
  case ERF_TYPE_IPV6:
3107
0
  case ERF_TYPE_INFINIBAND:
3108
0
  case ERF_TYPE_INFINIBAND_LINK:
3109
0
  case ERF_TYPE_OPA_SNC:
3110
0
  case ERF_TYPE_OPA_9B:
3111
0
    if (!dissector_try_uint(erf_dissector_table, erf_type, tvb, pinfo, tree)) {
3112
0
      call_data_dissector(tvb, pinfo, tree);
3113
0
    }
3114
0
    break;
3115
3116
0
  case ERF_TYPE_LEGACY:
3117
0
  case ERF_TYPE_IP_COUNTER:
3118
0
  case ERF_TYPE_TCP_FLOW_COUNTER:
3119
    /* undefined */
3120
0
    break;
3121
3122
0
  case ERF_TYPE_PAD:
3123
    /* Nothing to do */
3124
0
    break;
3125
3126
0
  case ERF_TYPE_MC_RAW:
3127
0
    dissect_mc_raw_header(tvb, pinfo, erf_tree);
3128
0
    call_data_dissector(tvb, pinfo, tree);
3129
0
    break;
3130
3131
0
  case ERF_TYPE_MC_RAW_CHANNEL:
3132
0
    dissect_mc_rawlink_header(tvb, pinfo, erf_tree);
3133
0
    call_data_dissector(tvb, pinfo, tree);
3134
0
    break;
3135
3136
0
  case ERF_TYPE_MC_ATM:
3137
0
    dissect_mc_atm_header(tvb, pinfo, erf_tree);
3138
    /* continue with type ATM */
3139
    /* FALL THROUGH */
3140
3141
0
  case ERF_TYPE_ATM:
3142
0
    memset(&atm_info, 0, sizeof(atm_info));
3143
0
    atm_hdr = tvb_get_ntohl(tvb, 0);
3144
0
    atm_info.vpi = ((atm_hdr & 0x0ff00000) >> 20);
3145
0
    atm_info.vci = ((atm_hdr & 0x000ffff0) >>  4);
3146
0
    atm_info.channel = (flags & 0x03);
3147
3148
    /* Work around to have decoding working */
3149
0
    if (erf_rawcell_first) {
3150
0
      new_tvb = tvb_new_subset_remaining(tvb, ATM_HDR_LENGTH);
3151
      /* Treat this as a (short) ATM AAL5 PDU */
3152
0
      atm_info.aal = AAL_5;
3153
0
      switch (erf_aal5_type) {
3154
3155
0
      case ERF_AAL5_GUESS:
3156
0
        atm_info.type = TRAF_UNKNOWN;
3157
0
        atm_info.subtype = TRAF_ST_UNKNOWN;
3158
        /* Try to guess the type according to the first bytes */
3159
0
        erf_atm_guess_traffic_type(new_tvb, 0, tvb_captured_length(new_tvb), &atm_info);
3160
0
        break;
3161
3162
0
      case ERF_AAL5_LLC:
3163
0
        atm_info.type = TRAF_LLCMX;
3164
0
        atm_info.subtype = TRAF_ST_UNKNOWN;
3165
0
        break;
3166
3167
0
      case ERF_AAL5_UNSPEC:
3168
0
        atm_info.aal = AAL_5;
3169
0
        atm_info.type = TRAF_UNKNOWN;
3170
0
        atm_info.subtype = TRAF_ST_UNKNOWN;
3171
0
        break;
3172
0
      }
3173
3174
0
      call_dissector_with_data(atm_untruncated_handle, new_tvb, pinfo, tree,
3175
0
                               &atm_info);
3176
0
    } else {
3177
      /* Treat this as a raw cell */
3178
0
      atm_info.flags |= ATM_RAW_CELL;
3179
0
      atm_info.flags |= ATM_NO_HEC;
3180
0
      atm_info.aal = AAL_UNKNOWN;
3181
      /* can call atm_untruncated because we set ATM_RAW_CELL flag */
3182
0
      call_dissector_with_data(atm_untruncated_handle, tvb, pinfo, tree,
3183
0
                               &atm_info);
3184
0
    }
3185
0
    break;
3186
3187
0
  case ERF_TYPE_MC_AAL5:
3188
0
    dissect_mc_aal5_header(tvb, pinfo, erf_tree);
3189
    /* continue with type AAL5 */
3190
    /* FALL THROUGH */
3191
3192
0
  case ERF_TYPE_AAL5:
3193
0
    atm_hdr = tvb_get_ntohl(tvb, 0);
3194
0
    memset(&atm_info, 0, sizeof(atm_info));
3195
0
    atm_info.vpi = ((atm_hdr & 0x0ff00000) >> 20);
3196
0
    atm_info.vci = ((atm_hdr & 0x000ffff0) >>  4);
3197
0
    atm_info.channel = (flags & 0x03);
3198
3199
0
    new_tvb = tvb_new_subset_remaining(tvb, ATM_HDR_LENGTH);
3200
    /* Work around to have decoding working */
3201
0
    atm_info.aal = AAL_5;
3202
0
    switch (erf_aal5_type) {
3203
3204
0
    case ERF_AAL5_GUESS:
3205
0
      atm_info.type = TRAF_UNKNOWN;
3206
0
      atm_info.subtype = TRAF_ST_UNKNOWN;
3207
      /* Try to guess the type according to the first bytes */
3208
0
      erf_atm_guess_traffic_type(new_tvb, 0, tvb_captured_length(new_tvb), &atm_info);
3209
0
      break;
3210
3211
0
    case ERF_AAL5_LLC:
3212
0
      atm_info.type = TRAF_LLCMX;
3213
0
      atm_info.subtype = TRAF_ST_UNKNOWN;
3214
0
      break;
3215
3216
0
    case ERF_AAL5_UNSPEC:
3217
0
      atm_info.aal = AAL_5;
3218
0
      atm_info.type = TRAF_UNKNOWN;
3219
0
      atm_info.subtype = TRAF_ST_UNKNOWN;
3220
0
      break;
3221
0
    }
3222
3223
0
    call_dissector_with_data(atm_untruncated_handle, new_tvb, pinfo, tree,
3224
0
                             &atm_info);
3225
0
    break;
3226
3227
0
  case ERF_TYPE_MC_AAL2:
3228
0
    dissect_mc_aal2_header(tvb, pinfo, erf_tree);
3229
3230
    /*
3231
     * Most of the information is in the ATM header; fetch it.
3232
     */
3233
0
    atm_hdr = tvb_get_ntohl(tvb, 0);
3234
3235
    /*
3236
     * The channel identification number is in the MC header, so it's
3237
     * in the pseudo-header, not in the packet data.
3238
     */
3239
0
    aal2_cid = (pinfo->pseudo_header->erf.subhdr.mc_hdr & MC_AAL2_CID_MASK) >> MC_AAL2_CID_SHIFT;
3240
3241
    /* Zero out and fill in the ATM pseudo-header. */
3242
0
    memset(&atm_info, 0, sizeof(atm_info));
3243
0
    atm_info.aal = AAL_2;
3244
0
    atm_info.flags |= ATM_AAL2_NOPHDR;
3245
0
    atm_info.vpi = ((atm_hdr & 0x0ff00000) >> 20);
3246
0
    atm_info.vci = ((atm_hdr & 0x000ffff0) >>  4);
3247
0
    atm_info.channel = (flags & 0x03);
3248
0
    atm_info.aal2_cid = aal2_cid;
3249
0
    atm_info.type = TRAF_UNKNOWN;
3250
0
    atm_info.subtype = TRAF_ST_UNKNOWN;
3251
3252
    /* remove ATM cell header from tvb */
3253
0
    new_tvb = tvb_new_subset_remaining(tvb, ATM_HDR_LENGTH);
3254
0
    call_dissector_with_data(atm_untruncated_handle, new_tvb, pinfo, tree,
3255
0
                             &atm_info);
3256
0
    break;
3257
3258
0
  case ERF_TYPE_AAL2:
3259
0
    dissect_aal2_header(tvb, pinfo, erf_tree);
3260
3261
    /*
3262
     * Most of the information is in the ATM header; fetch it.
3263
     */
3264
0
    atm_hdr = tvb_get_ntohl(tvb, 0);
3265
3266
    /*
3267
     * The channel identification number is in the AAL2 header, so it's
3268
     * in the pseudo-header, not in the packet data.
3269
     */
3270
0
    aal2_cid = (pinfo->pseudo_header->erf.subhdr.aal2_hdr & AAL2_CID_MASK) >> AAL2_CID_SHIFT;
3271
3272
    /* Zero out and fill in the ATM pseudo-header. */
3273
0
    memset(&atm_info, 0, sizeof(atm_info));
3274
0
    atm_info.aal = AAL_2;
3275
0
    atm_info.flags |= ATM_AAL2_NOPHDR;
3276
0
    atm_info.vpi = ((atm_hdr & 0x0ff00000) >> 20);
3277
0
    atm_info.vci = ((atm_hdr & 0x000ffff0) >>  4);
3278
0
    atm_info.channel = (flags & 0x03);
3279
0
    atm_info.aal2_cid = aal2_cid;
3280
0
    atm_info.type = TRAF_UNKNOWN;
3281
0
    atm_info.subtype = TRAF_ST_UNKNOWN;
3282
3283
    /* remove ATM cell header from tvb */
3284
0
    new_tvb = tvb_new_subset_remaining(tvb, ATM_HDR_LENGTH);
3285
0
    call_dissector_with_data(atm_untruncated_handle, new_tvb, pinfo, tree,
3286
0
                             &atm_info);
3287
0
    break;
3288
3289
0
  case ERF_TYPE_MC_HDLC:
3290
0
    dissect_mc_hdlc_header(tvb, pinfo, erf_tree);
3291
    /* continue with type HDLC */
3292
    /* FALL THROUGH */
3293
3294
0
  case ERF_TYPE_HDLC_POS:
3295
0
  case ERF_TYPE_COLOR_HDLC_POS:
3296
0
  case ERF_TYPE_DSM_COLOR_HDLC_POS:
3297
0
  case ERF_TYPE_COLOR_MC_HDLC_POS:
3298
0
  case ERF_TYPE_COLOR_HASH_POS:
3299
0
    hdlc_type = (erf_hdlc_type_vals)erf_hdlc_type;
3300
3301
0
    if (hdlc_type == ERF_HDLC_GUESS) {
3302
      /* Try to guess the type. */
3303
0
      first_byte = tvb_get_uint8(tvb, 0);
3304
0
      if (first_byte == 0x0f || first_byte == 0x8f)
3305
0
        hdlc_type = ERF_HDLC_CHDLC;
3306
0
      else {
3307
        /* Anything to check for to recognize Frame Relay or MTP2?
3308
           Should we require PPP packets to begin with FF 03? */
3309
0
        hdlc_type = ERF_HDLC_PPP;
3310
0
      }
3311
0
    }
3312
    /* Clean the pseudo header (if used in subdissector) and call the
3313
       appropriate subdissector. */
3314
0
    switch (hdlc_type) {
3315
0
    case ERF_HDLC_CHDLC:
3316
0
      call_dissector(chdlc_handle, tvb, pinfo, tree);
3317
0
      break;
3318
0
    case ERF_HDLC_PPP:
3319
0
      call_dissector(ppp_handle, tvb, pinfo, tree);
3320
0
      break;
3321
0
    case ERF_HDLC_FRELAY:
3322
0
      memset(&pinfo->pseudo_header->dte_dce, 0, sizeof(pinfo->pseudo_header->dte_dce));
3323
0
      call_dissector(frelay_handle, tvb, pinfo, tree);
3324
0
      break;
3325
0
    case ERF_HDLC_MTP2:
3326
      /* not used, but .. */
3327
0
      memset(&pinfo->pseudo_header->mtp2, 0, sizeof(pinfo->pseudo_header->mtp2));
3328
0
      call_dissector(mtp2_handle, tvb, pinfo, tree);
3329
0
      break;
3330
0
    default:
3331
0
      break;
3332
0
    }
3333
0
    break;
3334
3335
0
  case ERF_TYPE_META:
3336
0
    dissect_meta_record_tags(tvb, pinfo, erf_tree);
3337
0
    break;
3338
3339
0
  default:
3340
0
    call_data_dissector(tvb, pinfo, tree);
3341
0
    break;
3342
0
  } /* erf type */
3343
0
  return tvb_captured_length(tvb);
3344
0
}
3345
3346
static void erf_init_dissection(void)
3347
16
{
3348
16
  erf_state.implicit_host_id = 0;
3349
16
  erf_state.source_map = wmem_map_new(wmem_file_scope(), wmem_int64_hash, g_int64_equal);
3350
16
  erf_state.host_anchor_map = wmem_map_new(wmem_file_scope(), erf_anchor_key_hash, erf_anchor_key_equal);
3351
  /* Old map is freed automatically */
3352
16
}
3353
3354
static void register_erf_fields(const char* unused _U_)
3355
0
{
3356
0
  static hf_register_info hf[] = {
3357
    /* ERF Header */
3358
0
    { &hf_erf_ts,
3359
0
      { "Timestamp", "erf.ts",
3360
0
        FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3361
0
    { &hf_erf_rectype,
3362
0
      { "Record type", "erf.types",
3363
0
        FT_UINT8, BASE_HEX,  NULL, 0x0, NULL, HFILL } },
3364
0
    { &hf_erf_type,
3365
0
      { "Type", "erf.types.type",
3366
0
        FT_UINT8, BASE_DEC,  VALS(erf_type_vals), ERF_HDR_TYPE_MASK, NULL, HFILL } },
3367
0
    { &hf_erf_ehdr,
3368
0
      { "Extension header present", "erf.types.ext_header",
3369
0
        FT_UINT8, BASE_DEC,  NULL, ERF_HDR_EHDR_MASK, NULL, HFILL } },
3370
0
    { &hf_erf_flags,
3371
0
      { "Flags", "erf.flags",
3372
0
        FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3373
0
    { &hf_erf_flags_cap,
3374
0
      { "Capture interface", "erf.flags.cap",
3375
0
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3376
0
    { &hf_erf_flags_if_raw,
3377
0
      { "Raw interface", "erf.flags.if_raw",
3378
0
        FT_UINT8, BASE_HEX, NULL, ERF_HDR_CAP_MASK, NULL, HFILL } },
3379
0
    { &hf_erf_flags_vlen,
3380
0
      { "Varying record length", "erf.flags.vlen",
3381
0
        FT_UINT8, BASE_DEC, NULL, ERF_HDR_VLEN_MASK, NULL, HFILL } },
3382
0
    { &hf_erf_flags_trunc,
3383
0
      { "Truncated", "erf.flags.trunc",
3384
0
        FT_UINT8, BASE_DEC, NULL, ERF_HDR_TRUNC_MASK, NULL, HFILL } },
3385
0
    { &hf_erf_flags_rxe,
3386
0
      { "RX error", "erf.flags.rxe",
3387
0
        FT_UINT8, BASE_DEC, NULL, ERF_HDR_RXE_MASK, NULL, HFILL } },
3388
0
    { &hf_erf_flags_dse,
3389
0
      { "DS error", "erf.flags.dse",
3390
0
        FT_UINT8, BASE_DEC, NULL, ERF_HDR_DSE_MASK, NULL, HFILL } },
3391
0
    { &hf_erf_flags_res,
3392
0
       { "Reserved", "erf.flags.res",
3393
0
         FT_UINT8, BASE_DEC, NULL, ERF_HDR_RES_MASK, NULL, HFILL } },
3394
0
     { &hf_erf_rlen,
3395
0
       { "Record length", "erf.rlen",
3396
0
         FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3397
0
     { &hf_erf_lctr,
3398
0
       { "Loss counter", "erf.lctr",
3399
0
         FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3400
0
     { &hf_erf_color,
3401
0
       { "Color", "erf.color",
3402
0
         FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3403
0
     { &hf_erf_wlen,
3404
0
       { "Wire length", "erf.wlen",
3405
0
         FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3406
0
    { &hf_erf_ehdr_t,
3407
0
      { "Extension Header", "erf.ehdr.types",
3408
0
        FT_UINT8, BASE_DEC, VALS(ehdr_type_vals), 0x0, NULL, HFILL } },
3409
3410
    /* Intercept ID Extension Header */
3411
0
    { &hf_erf_ehdr_int_res1,
3412
0
      { "Reserved", "erf.ehdr.int.res1",
3413
0
        FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3414
0
    { &hf_erf_ehdr_int_id,
3415
0
      { "Intercept ID", "erf.ehdr.int.intid",
3416
0
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3417
0
    { &hf_erf_ehdr_int_res2,
3418
0
      { "Reserved", "erf.ehdr.int.res2",
3419
0
        FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3420
3421
    /* Raw Link Extension Header */
3422
0
    { &hf_erf_ehdr_raw_link_res,
3423
0
      { "Reserved", "erf.ehdr.raw.res",
3424
0
        FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3425
0
    { &hf_erf_ehdr_raw_link_seqnum,
3426
0
      { "Sequence number", "erf.ehdr.raw.seqnum",
3427
0
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3428
0
    { &hf_erf_ehdr_raw_link_rate,
3429
0
      { "Rate", "erf.ehdr.raw.rate",
3430
0
        FT_UINT8, BASE_DEC, VALS(raw_link_rates), 0x0, NULL, HFILL } },
3431
0
    { &hf_erf_ehdr_raw_link_type,
3432
0
      { "Link Type", "erf.ehdr.raw.link_type",
3433
0
        FT_UINT8, BASE_DEC, VALS(raw_link_types), 0x0, NULL, HFILL } },
3434
3435
    /* Classification Extension Header */
3436
0
    { &hf_erf_ehdr_class_flags,
3437
0
      { "Flags", "erf.ehdr.class.flags",
3438
0
        FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3439
0
    { &hf_erf_ehdr_class_flags_sh,
3440
0
      { "Search hit", "erf.ehdr.class.flags.sh",
3441
0
        FT_UINT32, BASE_DEC, NULL, EHDR_CLASS_SH_MASK, NULL, HFILL } },
3442
0
    { &hf_erf_ehdr_class_flags_shm,
3443
0
      { "Multiple search hits", "erf.ehdr.class.flags.shm",
3444
0
        FT_UINT32, BASE_DEC, NULL, EHDR_CLASS_SHM_MASK, NULL, HFILL } },
3445
0
    { &hf_erf_ehdr_class_flags_res1,
3446
0
      { "Reserved", "erf.ehdr.class.flags.res1",
3447
0
        FT_UINT32, BASE_HEX, NULL, EHDR_CLASS_RES1_MASK, NULL, HFILL } },
3448
0
    { &hf_erf_ehdr_class_flags_user,
3449
0
      { "User classification", "erf.ehdr.class.flags.user",
3450
0
        FT_UINT32, BASE_DEC, NULL, EHDR_CLASS_USER_MASK, NULL, HFILL } },
3451
0
    { &hf_erf_ehdr_class_flags_res2,
3452
0
      { "Reserved", "erf.ehdr.class.flags.res2",
3453
0
        FT_UINT32, BASE_HEX, NULL, EHDR_CLASS_RES2_MASK, NULL, HFILL } },
3454
0
    { &hf_erf_ehdr_class_flags_drop,
3455
0
      { "Drop Steering Bit", "erf.ehdr.class.flags.drop",
3456
0
        FT_UINT32, BASE_DEC, NULL, EHDR_CLASS_DROP_MASK, NULL, HFILL } },
3457
0
    { &hf_erf_ehdr_class_flags_str,
3458
0
      { "Stream Steering Bits", "erf.ehdr.class.flags.str",
3459
0
        FT_UINT32, BASE_DEC, NULL, EHDR_CLASS_STER_MASK, NULL, HFILL } },
3460
0
    { &hf_erf_ehdr_class_seqnum,
3461
0
      { "Sequence number", "erf.ehdr.class.seqnum",
3462
0
        FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3463
3464
    /* BFS Extension Header */
3465
0
    { &hf_erf_ehdr_bfs_hash,
3466
0
      { "Hash", "erf.ehdr.bfs.hash",
3467
0
        FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3468
0
    { &hf_erf_ehdr_bfs_color,
3469
0
      { "Filter Color", "erf.ehdr.bfs.color",
3470
0
        FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL } },
3471
0
    { &hf_erf_ehdr_bfs_raw_hash,
3472
0
      { "Raw Hash", "erf.ehdr.bfs.rawhash",
3473
0
        FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
3474
3475
    /* Channelised Extension Header */
3476
0
    { &hf_erf_ehdr_chan_morebits,
3477
0
      { "More Bits", "erf.ehdr.chan.morebits",
3478
0
        FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL } },
3479
0
    { &hf_erf_ehdr_chan_morefrag,
3480
0
      { "More Fragments", "erf.ehdr.chan.morefrag",
3481
0
        FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL } },
3482
0
    { &hf_erf_ehdr_chan_seqnum,
3483
0
      { "Sequence Number", "erf.ehdr.chan.seqnum",
3484
0
        FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
3485
0
    { &hf_erf_ehdr_chan_res,
3486
0
      { "Reserved", "erf.ehdr.chan.res",
3487
0
        FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3488
0
    { &hf_erf_ehdr_chan_virt_container_id,
3489
0
      { "Virtual Container ID", "erf.ehdr.chan.vcid",
3490
0
        FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3491
0
    { &hf_erf_ehdr_chan_assoc_virt_container_size,
3492
0
      { "Associated Virtual Container Size", "erf.ehdr.chan.vcsize",
3493
0
        FT_UINT8, BASE_HEX, VALS(channelised_assoc_virt_container_size), 0, NULL, HFILL } },
3494
0
    { &hf_erf_ehdr_chan_rate,
3495
0
      { "Origin Line Type/Rate", "erf.ehdr.chan.rate",
3496
0
        FT_UINT8, BASE_HEX, VALS(channelised_rate), 0, NULL, HFILL } },
3497
0
    { &hf_erf_ehdr_chan_type,
3498
0
      { "Frame Part Type", "erf.ehdr.chan.type",
3499
0
        FT_UINT8, BASE_HEX, VALS(channelised_type), 0, NULL, HFILL } },
3500
3501
    /* Signature Extension Header */
3502
0
    { &hf_erf_ehdr_signature_payload_hash,
3503
0
      { "Payload Hash", "erf.ehdr.signature.payloadhash",
3504
0
        FT_UINT24, BASE_HEX, NULL, 0, NULL, HFILL } },
3505
0
    { &hf_erf_ehdr_signature_color,
3506
0
      { "Filter Color", "erf.ehdr.signature.color",
3507
0
        FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3508
0
    { &hf_erf_ehdr_signature_flow_hash,
3509
0
      { "Flow Hash", "erf.ehdr.signature.flowhash",
3510
0
        FT_UINT24, BASE_HEX, NULL, 0, NULL, HFILL } },
3511
3512
    /* Flow ID Extension Header */
3513
0
    { &hf_erf_ehdr_flow_id_source_id,
3514
0
      { "Source ID", "erf.ehdr.flowid.sourceid",
3515
0
        FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
3516
0
    { &hf_erf_ehdr_flow_id_hash_type,
3517
0
      { "Hash Type", "erf.ehdr.flowid.hashtype",
3518
0
        FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3519
0
    { &hf_erf_ehdr_flow_id_hash_type_type,
3520
0
      { "Type", "erf.ehdr.flowid.hashtype.type",
3521
0
        FT_UINT8, BASE_DEC, VALS(erf_hash_type), ERF_EHDR_FLOW_ID_HASH_TYPE_TYPE_MASK, NULL, HFILL } },
3522
0
    { &hf_erf_ehdr_flow_id_hash_type_inner,
3523
0
      { "Hash is for Tunnel Inner", "erf.ehdr.flowid.hashtype.inner",
3524
0
        FT_UINT8, BASE_DEC, NULL, ERF_EHDR_FLOW_ID_HASH_TYPE_INNER_MASK, NULL, HFILL } },
3525
0
    { &hf_erf_ehdr_flow_id_stack_type,
3526
0
      { "Stack Type", "erf.ehdr.flowid.stacktype",
3527
0
        FT_UINT8, BASE_HEX, VALS(erf_stack_type), 0, NULL, HFILL } },
3528
0
    { &hf_erf_ehdr_flow_id_flow_hash,
3529
0
      { "Flow Hash", "erf.ehdr.flowid.flowhash",
3530
0
        FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
3531
3532
    /* Host ID Extension Header */
3533
0
    { &hf_erf_ehdr_host_id_sourceid,
3534
0
      { "Source ID", "erf.ehdr.hostid.sourceid",
3535
0
        FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
3536
0
    { &hf_erf_ehdr_host_id_hostid,
3537
0
      { "Host ID", "erf.ehdr.hostid.hostid",
3538
0
        FT_UINT48, BASE_HEX, NULL, 0, NULL, HFILL } },
3539
3540
    /* Anchor ID Extension Header */
3541
0
    { &hf_erf_ehdr_anchor_id_flags,
3542
0
     { "Flags", "erf.ehdr.anchorid.flags",
3543
0
        FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL} },
3544
0
    { &hf_erf_ehdr_anchor_id_definition,
3545
0
     { "Anchor Definition", "erf.ehdr.anchorid.flags.definition",
3546
0
        FT_BOOLEAN, 8 /*bits in bitfield*/, NULL, 0x80, NULL, HFILL} },
3547
0
    { &hf_erf_ehdr_anchor_id_reserved,
3548
0
     { "Reserved", "erf.ehdr.anchorid.flags.rsvd",
3549
0
        FT_UINT8, BASE_HEX, NULL, 0x7f, NULL, HFILL} },
3550
0
    { &hf_erf_ehdr_anchor_id_anchorid,
3551
0
     { "Anchor ID", "erf.ehdr.anchorid.anchorid",
3552
0
        FT_UINT48, BASE_HEX, NULL, 0, NULL, HFILL} },
3553
3554
    /* Generated fields for navigating Host ID/Anchor ID */
3555
0
    { &hf_erf_anchor_linked,
3556
0
      {"Linked Frame", "erf.anchor.frame",
3557
0
        FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL} },
3558
0
    { &hf_erf_anchor_anchorid,
3559
0
      { "Anchor ID", "erf.anchor.anchorid",
3560
0
        FT_UINT48, BASE_HEX, NULL, 0, NULL, HFILL } },
3561
0
    { &hf_erf_anchor_hostid,
3562
0
      { "Host ID", "erf.anchor.hostid",
3563
0
        FT_UINT48, BASE_HEX, NULL, 0, NULL, HFILL } },
3564
3565
    /* Generated fields for navigating Host ID/Source ID */
3566
0
    { &hf_erf_sourceid,
3567
0
      { "Source ID", "erf.sourceid",
3568
0
        FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
3569
0
    { &hf_erf_hostid,
3570
0
      { "Host ID", "erf.hostid",
3571
0
        FT_UINT48, BASE_HEX, NULL, 0, NULL, HFILL } },
3572
0
    { &hf_erf_source_current,
3573
0
      { "Next Metadata in Source", "erf.source_meta_frame_current",
3574
0
        FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL } },
3575
0
    { &hf_erf_source_next,
3576
0
      { "Next Metadata in Source", "erf.source_meta_frame_next",
3577
0
        FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL } },
3578
0
    { &hf_erf_source_prev,
3579
0
      { "Previous Metadata in Source", "erf.source_meta_frame_prev",
3580
0
        FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL } },
3581
3582
    /* Entropy Extension Header */
3583
0
    { &hf_erf_ehdr_entropy_entropy,
3584
0
     { "Entropy", "erf.ehdr.entropy.entropy",
3585
0
        FT_FLOAT, BASE_NONE, NULL, 0, NULL, HFILL} },
3586
0
    { &hf_erf_ehdr_entropy_entropy_raw,
3587
0
     { "Raw Entropy", "erf.ehdr.entropy.entropy.raw",
3588
0
        FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL} },
3589
0
    { &hf_erf_ehdr_entropy_reserved,
3590
0
     { "Reserved", "erf.ehdr.entropy.rsvd",
3591
0
        FT_UINT48, BASE_HEX, NULL, 0, NULL, HFILL} },
3592
3593
    /* Unknown Extension Header */
3594
0
    { &hf_erf_ehdr_unk,
3595
0
      { "Data", "erf.ehdr.unknown.data",
3596
0
        FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3597
3598
    /* MC HDLC Header */
3599
0
    { &hf_erf_mc_hdlc,
3600
0
      { "Multi Channel HDLC Header", "erf.mchdlc",
3601
0
        FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3602
0
    { &hf_erf_mc_hdlc_cn,
3603
0
      { "Connection number", "erf.mchdlc.cn",
3604
0
        FT_UINT32, BASE_DEC, NULL, MC_HDLC_CN_MASK, NULL, HFILL } },
3605
0
    { &hf_erf_mc_hdlc_res1,
3606
0
      { "Reserved", "erf.mchdlc.res1",
3607
0
        FT_UINT32, BASE_HEX, NULL, MC_HDLC_RES1_MASK, NULL, HFILL } },
3608
0
    { &hf_erf_mc_hdlc_res2,
3609
0
      { "Reserved", "erf.mchdlc.res2",
3610
0
        FT_UINT32, BASE_HEX, NULL, MC_HDLC_RES2_MASK, NULL, HFILL } },
3611
0
    { &hf_erf_mc_hdlc_fcse,
3612
0
      { "FCS error", "erf.mchdlc.fcse",
3613
0
        FT_UINT32, BASE_DEC, NULL, MC_HDLC_FCSE_MASK, NULL, HFILL } },
3614
0
    { &hf_erf_mc_hdlc_sre,
3615
0
      { "Short record error", "erf.mchdlc.sre",
3616
0
        FT_UINT32, BASE_DEC, NULL, MC_HDLC_SRE_MASK, NULL, HFILL } },
3617
0
    { &hf_erf_mc_hdlc_lre,
3618
0
      { "Long record error", "erf.mchdlc.lre",
3619
0
        FT_UINT32, BASE_DEC, NULL, MC_HDLC_LRE_MASK, NULL, HFILL } },
3620
0
    { &hf_erf_mc_hdlc_afe,
3621
0
      { "Aborted frame error", "erf.mchdlc.afe",
3622
0
        FT_UINT32, BASE_DEC, NULL, MC_HDLC_AFE_MASK, NULL, HFILL } },
3623
0
    { &hf_erf_mc_hdlc_oe,
3624
0
      { "Octet error", "erf.mchdlc.oe",
3625
0
        FT_UINT32, BASE_DEC, NULL, MC_HDLC_OE_MASK, NULL, HFILL } },
3626
0
    { &hf_erf_mc_hdlc_lbe,
3627
0
      { "Lost byte error", "erf.mchdlc.lbe",
3628
0
        FT_UINT32, BASE_DEC, NULL, MC_HDLC_LBE_MASK, NULL, HFILL } },
3629
0
    { &hf_erf_mc_hdlc_first,
3630
0
      { "First record", "erf.mchdlc.first",
3631
0
        FT_UINT32, BASE_DEC, NULL, MC_HDLC_FIRST_MASK, NULL, HFILL } },
3632
0
    { &hf_erf_mc_hdlc_res3,
3633
0
      { "Reserved", "erf.mchdlc.res3",
3634
0
        FT_UINT32, BASE_HEX, NULL, MC_HDLC_RES3_MASK, NULL, HFILL } },
3635
3636
    /* MC RAW Header */
3637
0
    { &hf_erf_mc_raw,
3638
0
      { "Multi Channel RAW Header", "erf.mcraw",
3639
0
        FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3640
0
    { &hf_erf_mc_raw_int,
3641
0
      { "Physical interface", "erf.mcraw.int",
3642
0
        FT_UINT32, BASE_DEC, NULL, MC_RAW_INT_MASK, NULL, HFILL } },
3643
0
    { &hf_erf_mc_raw_res1,
3644
0
      { "Reserved", "erf.mcraw.res1",
3645
0
        FT_UINT32, BASE_HEX, NULL, MC_RAW_RES1_MASK, NULL, HFILL } },
3646
0
    { &hf_erf_mc_raw_sre,
3647
0
      { "Short record error", "erf.mcraw.sre",
3648
0
        FT_UINT32, BASE_DEC, NULL, MC_RAW_SRE_MASK, NULL, HFILL } },
3649
0
    { &hf_erf_mc_raw_lre,
3650
0
      { "Long record error", "erf.mcraw.lre",
3651
0
        FT_UINT32, BASE_DEC, NULL, MC_RAW_LRE_MASK, NULL, HFILL } },
3652
0
    { &hf_erf_mc_raw_res2,
3653
0
      { "Reserved", "erf.mcraw.res2",
3654
0
        FT_UINT32, BASE_HEX, NULL, MC_RAW_RES2_MASK, NULL, HFILL } },
3655
0
    { &hf_erf_mc_raw_lbe,
3656
0
      { "Lost byte error", "erf.mcraw.lbe",
3657
0
        FT_UINT32, BASE_DEC, NULL, MC_RAW_LBE_MASK, NULL, HFILL } },
3658
0
    { &hf_erf_mc_raw_first,
3659
0
      { "First record", "erf.mcraw.first",
3660
0
        FT_UINT32, BASE_DEC, NULL, MC_RAW_FIRST_MASK, NULL, HFILL } },
3661
0
    { &hf_erf_mc_raw_res3,
3662
0
      { "Reserved", "erf.mcraw.res3",
3663
0
        FT_UINT32, BASE_HEX, NULL, MC_RAW_RES3_MASK, NULL, HFILL } },
3664
3665
    /* MC ATM Header */
3666
0
    { &hf_erf_mc_atm,
3667
0
      { "Multi Channel ATM Header", "erf.mcatm",
3668
0
        FT_UINT32, BASE_HEX, NULL, 0x00, NULL, HFILL } },
3669
0
    { &hf_erf_mc_atm_cn,
3670
0
      { "Connection number", "erf.mcatm.cn",
3671
0
        FT_UINT32, BASE_DEC, NULL, MC_ATM_CN_MASK, NULL, HFILL } },
3672
0
    { &hf_erf_mc_atm_res1,
3673
0
      { "Reserved", "erf.mcatm.res1",
3674
0
        FT_UINT32, BASE_HEX, NULL, MC_ATM_RES1_MASK, NULL, HFILL } },
3675
0
    { &hf_erf_mc_atm_mul,
3676
0
      { "Multiplexed", "erf.mcatm.mul",
3677
0
        FT_UINT32, BASE_DEC, NULL, MC_ATM_MUL_MASK, NULL, HFILL } },
3678
0
    { &hf_erf_mc_atm_port,
3679
0
      { "Physical port", "erf.mcatm.port",
3680
0
        FT_UINT32, BASE_DEC, NULL, MC_ATM_PORT_MASK, NULL, HFILL } },
3681
0
    { &hf_erf_mc_atm_res2,
3682
0
      { "Reserved", "erf.mcatm.res2",
3683
0
        FT_UINT32, BASE_HEX, NULL, MC_ATM_RES2_MASK, NULL, HFILL } },
3684
0
    { &hf_erf_mc_atm_lbe,
3685
0
      { "Lost Byte Error", "erf.mcatm.lbe",
3686
0
        FT_UINT32, BASE_DEC, NULL, MC_ATM_LBE_MASK, NULL, HFILL } },
3687
0
    { &hf_erf_mc_atm_hec,
3688
0
      { "HEC corrected", "erf.mcatm.hec",
3689
0
        FT_UINT32, BASE_DEC, NULL, MC_ATM_HEC_MASK, NULL, HFILL } },
3690
0
    { &hf_erf_mc_atm_crc10,
3691
0
      { "OAM Cell CRC10 Error (not implemented)", "erf.mcatm.crc10",
3692
0
        FT_UINT32, BASE_DEC, NULL, MC_ATM_CRC10_MASK, NULL, HFILL } },
3693
0
    { &hf_erf_mc_atm_oamcell,
3694
0
      { "OAM Cell", "erf.mcatm.oamcell",
3695
0
        FT_UINT32, BASE_DEC, NULL, MC_ATM_OAMCELL_MASK, NULL, HFILL } },
3696
0
    { &hf_erf_mc_atm_first,
3697
0
      { "First record", "erf.mcatm.first",
3698
0
        FT_UINT32, BASE_DEC, NULL, MC_ATM_FIRST_MASK, NULL, HFILL } },
3699
0
    { &hf_erf_mc_atm_res3,
3700
0
      { "Reserved", "erf.mcatm.res3",
3701
0
        FT_UINT32, BASE_HEX, NULL, MC_ATM_RES3_MASK, NULL, HFILL } },
3702
3703
    /* MC RAW Link Header */
3704
0
    { &hf_erf_mc_rawl,
3705
0
      { "Multi Channel RAW Link Header", "erf.mcrawl",
3706
0
        FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3707
0
    { &hf_erf_mc_rawl_cn,
3708
0
      { "Connection number", "erf.mcrawl.cn",
3709
0
        FT_UINT32, BASE_DEC, NULL, MC_RAWL_CN_MASK, NULL, HFILL } },
3710
0
    { &hf_erf_mc_rawl_res1,
3711
0
      { "Reserved", "erf.mcrawl.res1",
3712
0
        FT_UINT32, BASE_HEX, NULL, MC_RAWL_RES2_MASK, NULL, HFILL } },
3713
0
    { &hf_erf_mc_rawl_lbe,
3714
0
      { "Lost byte error", "erf.mcrawl.lbe",
3715
0
        FT_UINT32, BASE_DEC, NULL, MC_RAWL_LBE_MASK, NULL, HFILL } },
3716
0
    { &hf_erf_mc_rawl_first,
3717
0
      { "First record", "erf.mcrawl.first",
3718
0
        FT_UINT32, BASE_DEC, NULL, MC_RAWL_FIRST_MASK, NULL, HFILL } },
3719
0
    { &hf_erf_mc_rawl_res2,
3720
0
      { "Reserved", "erf.mcrawl.res2",
3721
0
        FT_UINT32, BASE_HEX, NULL, MC_RAWL_RES2_MASK, NULL, HFILL } },
3722
3723
    /* MC AAL5 Header */
3724
0
    { &hf_erf_mc_aal5,
3725
0
      { "Multi Channel AAL5 Header", "erf.mcaal5",
3726
0
        FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3727
0
    { &hf_erf_mc_aal5_cn,
3728
0
      { "Connection number", "erf.mcaal5.cn",
3729
0
        FT_UINT32, BASE_DEC, NULL, MC_AAL5_CN_MASK, NULL, HFILL } },
3730
0
    { &hf_erf_mc_aal5_res1,
3731
0
      { "Reserved", "erf.mcaal5.res1",
3732
0
        FT_UINT32, BASE_HEX, NULL, MC_AAL5_RES1_MASK, NULL, HFILL } },
3733
0
    { &hf_erf_mc_aal5_port,
3734
0
      { "Physical port", "erf.mcaal5.port",
3735
0
        FT_UINT32, BASE_DEC, NULL, MC_AAL5_PORT_MASK, NULL, HFILL } },
3736
0
    { &hf_erf_mc_aal5_crcck,
3737
0
      { "CRC checked", "erf.mcaal5.crcck",
3738
0
        FT_UINT32, BASE_DEC, NULL, MC_AAL5_CRCCK_MASK, NULL, HFILL } },
3739
0
    { &hf_erf_mc_aal5_crce,
3740
0
      { "CRC error", "erf.mcaal5.crce",
3741
0
        FT_UINT32, BASE_DEC, NULL, MC_AAL5_CRCE_MASK, NULL, HFILL } },
3742
0
    { &hf_erf_mc_aal5_lenck,
3743
0
      { "Length checked", "erf.mcaal5.lenck",
3744
0
        FT_UINT32, BASE_DEC, NULL, MC_AAL5_LENCK_MASK, NULL, HFILL } },
3745
0
    { &hf_erf_mc_aal5_lene,
3746
0
      { "Length error", "erf.mcaal5.lene",
3747
0
        FT_UINT32, BASE_DEC, NULL, MC_AAL5_LENE_MASK, NULL, HFILL } },
3748
0
    { &hf_erf_mc_aal5_res2,
3749
0
      { "Reserved", "erf.mcaal5.res2",
3750
0
        FT_UINT32, BASE_HEX, NULL, MC_AAL5_RES2_MASK, NULL, HFILL } },
3751
0
    { &hf_erf_mc_aal5_first,
3752
0
      { "First record", "erf.mcaal5.first",
3753
0
        FT_UINT32, BASE_DEC, NULL, MC_AAL5_FIRST_MASK, NULL, HFILL } },
3754
0
    { &hf_erf_mc_aal5_res3,
3755
0
      { "Reserved", "erf.mcaal5.res3",
3756
0
        FT_UINT32, BASE_HEX, NULL, MC_AAL5_RES3_MASK, NULL, HFILL } },
3757
3758
    /* MC AAL2 Header */
3759
0
    { &hf_erf_mc_aal2,
3760
0
      { "Multi Channel AAL2 Header", "erf.mcaal2",
3761
0
        FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3762
0
    { &hf_erf_mc_aal2_cn,
3763
0
      { "Connection number", "erf.mcaal2.cn",
3764
0
        FT_UINT32, BASE_DEC, NULL, MC_AAL2_CN_MASK, NULL, HFILL } },
3765
0
    { &hf_erf_mc_aal2_res1,
3766
0
      { "Reserved for extra connection", "erf.mcaal2.res1",
3767
0
        FT_UINT32, BASE_HEX, NULL, MC_AAL2_RES1_MASK, NULL, HFILL } },
3768
0
    { &hf_erf_mc_aal2_res2,
3769
0
      { "Reserved for type", "erf.mcaal2.mul",
3770
0
        FT_UINT32, BASE_HEX, NULL, MC_AAL2_RES2_MASK, NULL, HFILL } },
3771
0
    { &hf_erf_mc_aal2_port,
3772
0
      { "Physical port", "erf.mcaal2.port",
3773
0
        FT_UINT32, BASE_DEC, NULL, MC_AAL2_PORT_MASK, NULL, HFILL } },
3774
0
    { &hf_erf_mc_aal2_res3,
3775
0
      { "Reserved", "erf.mcaal2.res2",
3776
0
        FT_UINT32, BASE_HEX, NULL, MC_AAL2_RES3_MASK, NULL, HFILL } },
3777
0
    { &hf_erf_mc_aal2_first,
3778
0
      { "First cell received", "erf.mcaal2.lbe",
3779
0
        FT_UINT32, BASE_DEC, NULL, MC_AAL2_FIRST_MASK, NULL, HFILL } },
3780
0
    { &hf_erf_mc_aal2_maale,
3781
0
      { "MAAL error", "erf.mcaal2.hec",
3782
0
        FT_UINT32, BASE_DEC, NULL, MC_AAL2_MAALE_MASK, NULL, HFILL } },
3783
0
    { &hf_erf_mc_aal2_lene,
3784
0
      { "Length error", "erf.mcaal2.crc10",
3785
0
        FT_UINT32, BASE_DEC, NULL, MC_AAL2_LENE_MASK, NULL, HFILL } },
3786
0
    { &hf_erf_mc_aal2_cid,
3787
0
      { "Channel Identification Number", "erf.mcaal2.cid",
3788
0
        FT_UINT32, BASE_DEC, NULL, MC_AAL2_CID_MASK, NULL, HFILL } },
3789
3790
    /* AAL2 Header */
3791
0
    { &hf_erf_aal2,
3792
0
      { "AAL2 Header", "erf.aal2",
3793
0
        FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3794
0
    { &hf_erf_aal2_cid,
3795
0
      { "Channel Identification Number", "erf.aal2.cid",
3796
0
        FT_UINT32, BASE_DEC, NULL, AAL2_CID_MASK, NULL, HFILL } },
3797
0
    { &hf_erf_aal2_maale,
3798
0
      { "MAAL error number", "erf.aal2.maale",
3799
0
        FT_UINT32, BASE_DEC, NULL, AAL2_MAALE_MASK, NULL, HFILL } },
3800
0
    { &hf_erf_aal2_maalei,
3801
0
      { "MAAL error", "erf.aal2.hec",
3802
0
        FT_UINT32, BASE_DEC, NULL, AAL2_MAALEI_MASK, NULL, HFILL } },
3803
0
    { &hf_erf_aal2_first,
3804
0
      { "First cell received", "erf.aal2.lbe",
3805
0
        FT_UINT32, BASE_DEC, NULL, AAL2_FIRST_MASK, NULL, HFILL } },
3806
0
    { &hf_erf_aal2_res1,
3807
0
      { "Reserved", "erf.aal2.res1",
3808
0
        FT_UINT32, BASE_HEX, NULL, AAL2_RES1_MASK, NULL, HFILL } },
3809
3810
    /* ETH Header */
3811
0
    { &hf_erf_eth,
3812
0
      { "Ethernet pad", "erf.eth",
3813
0
        FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL } },
3814
0
    { &hf_erf_eth_off,
3815
0
      { "Offset", "erf.eth.off",
3816
0
        FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3817
0
    { &hf_erf_eth_pad,
3818
0
      { "Padding", "erf.eth.pad",
3819
0
        FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL } },
3820
3821
    /* Provenance record unknown tags */
3822
0
    { &hf_erf_meta_tag_type,
3823
0
      { "Tag Type", "erf.meta.tag.type",
3824
0
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3825
0
    { &hf_erf_meta_tag_len,
3826
0
      { "Tag Length", "erf.meta.tag.len",
3827
0
        FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL } },
3828
0
    { &hf_erf_meta_tag_unknown,
3829
0
      { "Unknown Tag", "erf.meta.unknown",
3830
0
        FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } }
3831
0
  };
3832
3833
0
  static int *ett[] = {
3834
0
    &ett_erf,
3835
0
    &ett_erf_pseudo_hdr,
3836
0
    &ett_erf_rectype,
3837
0
    &ett_erf_hash_type,
3838
0
    &ett_erf_flags,
3839
0
    &ett_erf_mc_hdlc,
3840
0
    &ett_erf_mc_raw,
3841
0
    &ett_erf_mc_atm,
3842
0
    &ett_erf_mc_rawlink,
3843
0
    &ett_erf_mc_aal5,
3844
0
    &ett_erf_mc_aal2,
3845
0
    &ett_erf_aal2,
3846
0
    &ett_erf_eth,
3847
0
    &ett_erf_meta,
3848
0
    &ett_erf_meta_tag,
3849
0
    &ett_erf_source,
3850
0
    &ett_erf_anchor,
3851
0
    &ett_erf_anchor_flags,
3852
0
    &ett_erf_entropy_value
3853
0
  };
3854
3855
0
  static ei_register_info ei[] = {
3856
0
      { &ei_erf_mc_hdlc_checksum_error, { "erf.mchdlc.checksum.error", PI_CHECKSUM, PI_ERROR, "ERF MC HDLC FCS Error", EXPFILL }},
3857
0
      { &ei_erf_mc_hdlc_short_error, { "erf.mchdlc.short.error", PI_RECEIVE, PI_ERROR, "ERF MC HDLC Short Record Error, <5 bytes", EXPFILL }},
3858
0
      { &ei_erf_mc_hdlc_long_error, { "erf.mchdlc.long.error", PI_RECEIVE, PI_ERROR, "ERF MC HDLC Long Record Error, >2047 bytes", EXPFILL }},
3859
0
      { &ei_erf_mc_hdlc_abort_error, { "erf.mchdlc.abort.error", PI_RECEIVE, PI_ERROR, "ERF MC HDLC Aborted Frame Error", EXPFILL }},
3860
0
      { &ei_erf_mc_hdlc_octet_error, { "erf.mchdlc.octet.error", PI_RECEIVE, PI_ERROR, "ERF MC HDLC Octet Error, the closing flag was not octet aligned after bit unstuffing", EXPFILL }},
3861
0
      { &ei_erf_mc_hdlc_lost_byte_error, { "erf.mchdlc.lost_byte.error", PI_RECEIVE, PI_ERROR, "ERF MC HDLC Lost Byte Error", EXPFILL }},
3862
0
      { &ei_erf_rx_error, { "erf.rx.error", PI_INTERFACE, PI_ERROR, "ERF RX Error", EXPFILL }},
3863
0
      { &ei_erf_ds_error, { "erf.ds.error", PI_INTERFACE, PI_ERROR, "ERF DS Error", EXPFILL }},
3864
0
      { &ei_erf_truncation_error, { "erf.truncation.error", PI_INTERFACE, PI_ERROR, "ERF Truncation Error", EXPFILL }},
3865
0
      { &ei_erf_packet_loss, { "erf.packet_loss", PI_INTERFACE, PI_WARN, "Packet loss occurred between previous and current packet", EXPFILL }},
3866
0
      { &ei_erf_extension_headers_not_shown, { "erf.ehdr.more_not_shown", PI_INTERFACE, PI_WARN, "More extension headers were present, not shown", EXPFILL }},
3867
0
      { &ei_erf_meta_section_len_error, { "erf.meta.section_len.error", PI_PROTOCOL, PI_ERROR, "Provenance Section Length incorrect", EXPFILL }},
3868
0
      { &ei_erf_meta_truncated_record, { "erf.meta.truncated_record", PI_MALFORMED, PI_ERROR, "Provenance truncated record", EXPFILL }},
3869
0
      { &ei_erf_meta_truncated_tag, { "erf.meta.truncated_tag", PI_PROTOCOL, PI_ERROR, "Provenance truncated tag", EXPFILL }},
3870
0
      { &ei_erf_meta_zero_len_tag, { "erf.meta.zero_len_tag", PI_PROTOCOL, PI_NOTE, "Provenance zero length tag", EXPFILL }},
3871
0
      { &ei_erf_meta_reset, { "erf.meta.metadata_reset", PI_PROTOCOL, PI_WARN, "Provenance metadata reset", EXPFILL }}
3872
0
  };
3873
3874
0
  expert_module_t* expert_erf;
3875
3876
0
  init_meta_tags();
3877
3878
0
  proto_register_field_array(proto_erf, hf, array_length(hf));
3879
0
  proto_register_subtree_array(ett, array_length(ett));
3880
0
  expert_erf = expert_register_protocol(proto_erf);
3881
0
  expert_register_field_array(expert_erf, ei, array_length(ei));
3882
3883
  /* Register per-section Provenance fields */
3884
0
  proto_register_field_array(proto_erf, (hf_register_info*) wmem_array_get_raw(erf_meta_index.hfri), (int) wmem_array_get_count(erf_meta_index.hfri));
3885
0
  proto_register_subtree_array((int**) wmem_array_get_raw(erf_meta_index.ett), (int) wmem_array_get_count(erf_meta_index.ett));
3886
0
}
3887
3888
void
3889
proto_register_erf(void)
3890
16
{
3891
16
  static const enum_val_t erf_hdlc_options[] = {
3892
16
    { "chdlc",  "Cisco HDLC",       ERF_HDLC_CHDLC },
3893
16
    { "ppp",    "PPP serial",       ERF_HDLC_PPP },
3894
16
    { "frelay", "Frame Relay",      ERF_HDLC_FRELAY },
3895
16
    { "mtp2",   "SS7 MTP2",         ERF_HDLC_MTP2 },
3896
16
    { "guess",  "Attempt to guess", ERF_HDLC_GUESS },
3897
16
    { NULL, NULL, 0 }
3898
16
  };
3899
3900
16
  static const enum_val_t erf_aal5_options[] = {
3901
16
    { "guess", "Attempt to guess", ERF_AAL5_GUESS },
3902
16
    { "llc",   "LLC multiplexed",  ERF_AAL5_LLC },
3903
16
    { "unspec", "Unspecified", ERF_AAL5_UNSPEC },
3904
16
    { NULL, NULL, 0 }
3905
16
  };
3906
3907
16
  module_t *erf_module;
3908
16
  proto_erf = proto_register_protocol("Extensible Record Format", "ERF", "erf");
3909
3910
16
  erf_handle = register_dissector("erf", dissect_erf, proto_erf);
3911
3912
  /* Delay registration of ERF fields */
3913
16
  proto_register_prefix("erf", register_erf_fields);
3914
3915
16
  erf_module = prefs_register_protocol(proto_erf, NULL);
3916
3917
16
  prefs_register_enum_preference(erf_module, "hdlc_type", "ERF_HDLC Layer 2",
3918
16
                                 "Protocol encapsulated in HDLC records",
3919
16
                                 &erf_hdlc_type, erf_hdlc_options, false);
3920
3921
16
  prefs_register_bool_preference(erf_module, "rawcell_first",
3922
16
                                 "Raw ATM cells are first cell of AAL5 PDU",
3923
16
                                 "Whether raw ATM cells should be treated as "
3924
16
                                 "the first cell of an AAL5 PDU",
3925
16
                                 &erf_rawcell_first);
3926
3927
16
  prefs_register_enum_preference(erf_module, "aal5_type",
3928
16
                                 "ATM AAL5 packet type",
3929
16
                                 "Protocol encapsulated in ATM AAL5 packets",
3930
16
                                 &erf_aal5_type, erf_aal5_options, false);
3931
3932
  /*
3933
   * We just use eth_maybefcs now and respect the Ethernet preference.
3934
   * ERF records usually have FCS.
3935
   */
3936
16
  prefs_register_obsolete_preference(erf_module, "ethfcs");
3937
3938
16
  erf_dissector_table = register_dissector_table("erf.types.type", "ERF Type", proto_erf, FT_UINT8, BASE_DEC);
3939
3940
16
  register_init_routine(erf_init_dissection);
3941
  /* No extra cleanup needed */
3942
16
}
3943
3944
void
3945
proto_reg_handoff_erf(void)
3946
16
{
3947
16
  int file_type_subtype_erf;
3948
3949
16
  dissector_add_uint("wtap_encap", WTAP_ENCAP_ERF, erf_handle);
3950
  /* Also register dissector for Provenance non-packet records */
3951
16
  file_type_subtype_erf = wtap_name_to_file_type_subtype("erf");
3952
16
  if (file_type_subtype_erf != -1)
3953
16
    dissector_add_uint("wtap_fts_rec", file_type_subtype_erf, erf_handle);
3954
3955
  /* Get handles for serial line protocols */
3956
16
  chdlc_handle  = find_dissector_add_dependency("chdlc", proto_erf);
3957
16
  ppp_handle    = find_dissector_add_dependency("ppp_hdlc", proto_erf);
3958
16
  frelay_handle = find_dissector_add_dependency("fr", proto_erf);
3959
16
  mtp2_handle   = find_dissector_add_dependency("mtp2_with_crc", proto_erf);
3960
3961
  /* Get handle for ATM dissector */
3962
16
  atm_untruncated_handle = find_dissector_add_dependency("atm_untruncated", proto_erf);
3963
3964
16
  sdh_handle = find_dissector_add_dependency("sdh", proto_erf);
3965
16
}
3966
3967
/*
3968
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
3969
 *
3970
 * Local Variables:
3971
 * c-basic-offset: 2
3972
 * tab-width: 8
3973
 * indent-tabs-mode: nil
3974
 * End:
3975
 *
3976
 * ex: set shiftwidth=2 tabstop=8 expandtab:
3977
 * :indentSize=2:tabSize=8:noTabs=true:
3978
 */