Coverage Report

Created: 2026-01-02 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-frame.c
Line
Count
Source
1
/* packet-frame.c
2
 *
3
 * Top-most dissector. Decides dissector based on Wiretap Encapsulation Type.
4
 *
5
 * Wireshark - Network traffic analyzer
6
 * By Gerald Combs <gerald@wireshark.org>
7
 * Copyright 2000 Gerald Combs
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 */
11
12
#include "config.h"
13
14
#ifdef _MSC_VER
15
#include <windows.h>
16
#endif
17
18
#include <epan/packet.h>
19
#include <epan/capture_dissectors.h>
20
#include <epan/epan.h>
21
#include <epan/exceptions.h>
22
#include <epan/show_exception.h>
23
#include <epan/prefs.h>
24
#include <epan/to_str.h>
25
#include <epan/sequence_analysis.h>
26
#include <epan/tap.h>
27
#include <epan/proto_data.h>
28
#include <epan/expert.h>
29
#include <epan/tfs.h>
30
#include <wsutil/wsgcrypt.h>
31
#include <wsutil/str_util.h>
32
#include <wsutil/wslog.h>
33
#include <wsutil/ws_assert.h>
34
#include <epan/addr_resolv.h>
35
#include <epan/wmem_scopes.h>
36
#include <epan/column-info.h>
37
38
#include "packet-frame.h"
39
40
#include <epan/color_filters.h>
41
42
void proto_register_frame(void);
43
void event_register_frame(void);
44
void proto_reg_handoff_frame(void);
45
void event_reg_handoff_frame(void);
46
47
static int proto_frame;
48
static int proto_pkt_comment;
49
static int proto_syscall;
50
static int proto_darwin;
51
52
static int hf_frame_arrival_time_local;
53
static int hf_frame_arrival_time_utc;
54
static int hf_frame_arrival_time_epoch;
55
static int hf_frame_shift_offset;
56
static int hf_frame_time_delta;
57
static int hf_frame_time_delta_displayed;
58
static int hf_frame_time_relative;
59
static int hf_frame_time_relative_cap;
60
static int hf_frame_time_reference;
61
static int hf_frame_number;
62
static int hf_frame_len;
63
static int hf_frame_capture_len;
64
static int hf_frame_p2p_dir;
65
static int hf_frame_file_off;
66
static int hf_frame_md5_hash;
67
static int hf_frame_marked;
68
static int hf_frame_ignored;
69
static int hf_frame_link_number;
70
static int hf_frame_packet_id;
71
static int hf_frame_hash;
72
static int hf_frame_hash_bytes;
73
static int hf_frame_verdict;
74
static int hf_frame_verdict_hardware;
75
static int hf_frame_verdict_tc;
76
static int hf_frame_verdict_xdp;
77
static int hf_frame_verdict_unknown;
78
static int hf_frame_drop_count;
79
static int hf_frame_protocols;
80
static int hf_frame_color_filter_name;
81
static int hf_frame_color_filter_text;
82
static int hf_frame_section_number;
83
static int hf_frame_interface_id;
84
static int hf_frame_interface_name;
85
static int hf_frame_interface_description;
86
static int hf_frame_interface_queue;
87
static int hf_frame_pack_flags;
88
static int hf_frame_pack_direction;
89
static int hf_frame_pack_reception_type;
90
static int hf_frame_pack_fcs_length;
91
static int hf_frame_pack_reserved;
92
static int hf_frame_pack_crc_error;
93
static int hf_frame_pack_wrong_packet_too_long_error;
94
static int hf_frame_pack_wrong_packet_too_short_error;
95
static int hf_frame_pack_wrong_inter_frame_gap_error;
96
static int hf_frame_pack_unaligned_frame_error;
97
static int hf_frame_pack_start_frame_delimiter_error;
98
static int hf_frame_pack_preamble_error;
99
static int hf_frame_pack_symbol_error;
100
static int hf_frame_wtap_encap;
101
static int hf_frame_cb_pen;
102
static int hf_frame_cb_copy_allowed;
103
static int hf_frame_comment;
104
static int hf_frame_encoding;
105
106
static int ett_frame;
107
static int ett_ifname;
108
static int ett_flags;
109
static int ett_comments;
110
static int ett_hash;
111
static int ett_verdict;
112
113
static expert_field ei_comments_text;
114
static expert_field ei_arrive_time_out_of_range;
115
static expert_field ei_incomplete;
116
static expert_field ei_len_lt_caplen;
117
118
static int frame_tap;
119
120
static dissector_handle_t docsis_handle;
121
static dissector_handle_t sysdig_handle;
122
static dissector_handle_t systemd_journal_handle;
123
static dissector_handle_t darwin_handle;
124
125
/* Preferences */
126
static bool show_file_off;
127
static bool force_docsis_encap;
128
static bool generate_md5_hash;
129
static bool generate_bits_field = true;
130
static bool disable_packet_size_limited_in_summary;
131
static unsigned max_comment_lines   = 30;
132
133
static const value_string p2p_dirs[] = {
134
  { P2P_DIR_UNKNOWN, "Unknown" },
135
  { P2P_DIR_SENT,    "Sent" },
136
  { P2P_DIR_RECV,    "Received" },
137
  { 0, NULL }
138
};
139
140
static const value_string packet_word_directions[] = {
141
  { PACK_FLAGS_DIRECTION_UNKNOWN,  "Unknown" },
142
  { PACK_FLAGS_DIRECTION_INBOUND,  "Inbound" },
143
  { PACK_FLAGS_DIRECTION_OUTBOUND, "Outbound" },
144
  { 0, NULL }
145
};
146
147
static const value_string packet_word_reception_types[] = {
148
  { PACK_FLAGS_RECEPTION_TYPE_UNSPECIFIED, "Not specified" },
149
  { PACK_FLAGS_RECEPTION_TYPE_UNICAST,     "Unicast" },
150
  { PACK_FLAGS_RECEPTION_TYPE_MULTICAST,   "Multicast" },
151
  { PACK_FLAGS_RECEPTION_TYPE_BROADCAST,   "Broadcast" },
152
  { PACK_FLAGS_RECEPTION_TYPE_PROMISCUOUS, "Promiscuous" },
153
  { 0, NULL }
154
};
155
156
static const value_string packet_char_enc_types[] = {
157
  { PACKET_CHAR_ENC_CHAR_ASCII, "ASCII" },
158
  { PACKET_CHAR_ENC_CHAR_EBCDIC, "EBCDIC" },
159
  { 0, NULL }
160
};
161
162
static const val64_string verdict_ebpf_tc_types[] = {
163
  { -1, "TC_ACT_UNSPEC"},
164
  { 0, "TC_ACT_OK"},
165
  { 1, "TC_ACT_RECLASSIFY"},
166
  { 2, "TC_ACT_SHOT"},
167
  { 3, "TC_ACT_PIPE"},
168
  { 4, "TC_ACT_STOLEN"},
169
  { 5, "TC_ACT_QUEUED"},
170
  { 6, "TC_ACT_REPEAT"},
171
  { 7, "TC_ACT_REDIRECT"},
172
  { 8, "TC_ACT_TRAP"},
173
  { 0, NULL }
174
};
175
176
static const val64_string verdict_ebpf_xdp_types[] = {
177
  { 0, "XDP_ABORTED"},
178
  { 1, "XDP_DROP"},
179
  { 2, "XDP_PASS"},
180
  { 3, "XDP_TX"},
181
  { 4, "XDP_REDIRECT"},
182
  { 0, NULL }
183
};
184
185
static dissector_table_t wtap_encap_dissector_table;
186
static dissector_table_t wtap_fts_rec_dissector_table;
187
static dissector_table_t block_pen_dissector_table;
188
static dissector_table_t binary_option_pen_dissector_table;
189
static dissector_table_t packet_block_option_dissector_table;
190
191
/* The number of tree items required to add an exception to the tree */
192
113k
#define EXCEPTION_TREE_ITEMS 10
193
194
/* OPT_EPB_VERDICT sub-types */
195
0
#define OPT_VERDICT_TYPE_HW  0
196
0
#define OPT_VERDICT_TYPE_TC  1
197
0
#define OPT_VERDICT_TYPE_XDP 2
198
199
/* OPT_EPB_HASH sub-types */
200
0
#define OPT_HASH_2COMP    0
201
0
#define OPT_HASH_XOR    1
202
0
#define OPT_HASH_CRC32    2
203
0
#define OPT_HASH_MD5      3
204
0
#define OPT_HASH_SHA1     4
205
0
#define OPT_HASH_TOEPLITZ 5
206
207
/* Structure for passing as userdata to wtap_block_foreach_option */
208
typedef struct fr_foreach_s {
209
  proto_item *item;
210
  proto_tree *tree;
211
  tvbuff_t *tvb;
212
  packet_info *pinfo;
213
  unsigned n_changes;
214
} fr_foreach_t;
215
216
static const char *
217
get_verdict_type_string(uint8_t type)
218
0
{
219
0
  switch(type) {
220
0
  case OPT_VERDICT_TYPE_HW:
221
0
    return "Hardware";
222
0
  case OPT_VERDICT_TYPE_TC:
223
0
    return "eBPF_TC";
224
0
  case OPT_VERDICT_TYPE_XDP:
225
0
    return "eBPF_XDP";
226
0
  }
227
0
  return "Unknown";
228
0
}
229
230
static const char *
231
get_hash_type_string(uint8_t type)
232
0
{
233
0
  switch(type) {
234
0
  case OPT_HASH_2COMP:
235
0
    return "2's Complement";
236
0
  case OPT_HASH_XOR:
237
0
    return "XOR";
238
0
  case OPT_HASH_CRC32:
239
0
    return "CRC32";
240
0
  case OPT_HASH_MD5:
241
0
    return "MD5";
242
0
  case OPT_HASH_SHA1:
243
0
    return "SHA1";
244
0
  case OPT_HASH_TOEPLITZ:
245
0
    return "Toeplitz";
246
0
  default:
247
0
    return "Unknown";
248
0
  }
249
0
}
250
251
static void
252
ensure_tree_item(proto_tree *tree, unsigned count)
253
254k
{
254
  /*
255
   * Ensure that no exception is thrown in proto.c when adding the
256
   * next tree item. Even if the maximum number of items is
257
   * reached, we know for sure that no infinite loop will occur.
258
   */
259
254k
  if (tree && PTREE_DATA(tree)->count > count)
260
254k
    PTREE_DATA(tree)->count -= count;
261
254k
}
262
263
/****************************************************************************/
264
/* whenever a frame packet is seen by the tap listener */
265
/* Add a new frame into the graph */
266
static tap_packet_status
267
frame_seq_analysis_packet( void *ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *dummy _U_, tap_flags_t flags _U_)
268
0
{
269
0
  seq_analysis_info_t *sainfo = (seq_analysis_info_t *) ptr;
270
0
  seq_analysis_item_t *sai = sequence_analysis_create_sai_with_addresses(pinfo, sainfo);
271
272
0
  if (!sai)
273
0
    return TAP_PACKET_DONT_REDRAW;
274
275
0
  sai->frame_number = pinfo->num;
276
277
0
  sequence_analysis_use_color_filter(pinfo, sai);
278
279
0
  sai->port_src=pinfo->srcport;
280
0
  sai->port_dst=pinfo->destport;
281
282
0
  sequence_analysis_use_col_info_as_label_comment(pinfo, sai);
283
284
0
  sai->line_style = 1;
285
0
  sai->conv_num = 0;
286
0
  sai->display = true;
287
288
0
  g_queue_push_tail(sainfo->items, sai);
289
290
0
  return TAP_PACKET_REDRAW;
291
0
}
292
293
/*
294
 * Routine used to register frame end routine.  The routine should only
295
 * be registered when the dissector is used in the frame, not in the
296
 * proto_register_XXX function.
297
 */
298
void
299
register_frame_end_routine(packet_info *pinfo, void (*func)(void))
300
3.90k
{
301
3.90k
  pinfo->frame_end_routines = g_slist_append(pinfo->frame_end_routines, (void *)func);
302
3.90k
}
303
304
typedef void (*void_func_t)(void);
305
306
static void
307
call_frame_end_routine(void *routine)
308
3.90k
{
309
3.90k
  void_func_t func = (void_func_t)routine;
310
3.90k
  (*func)();
311
3.90k
}
312
313
static bool
314
frame_add_comment(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t *option, void *user_data)
315
0
{
316
0
  fr_foreach_t *fr_user_data = (fr_foreach_t *)user_data;
317
0
  proto_item *comment_item;
318
0
  proto_item *hidden_item;
319
0
  proto_tree *comments_tree;
320
0
  char *newline;             /* location of next newline in comment */
321
0
  char *ch;                  /* utility pointer */
322
0
  unsigned i;                    /* track number of lines */
323
324
0
  if (option_id == OPT_COMMENT) {
325
0
    ch = option->stringval;
326
0
    newline = strchr(ch, '\n');
327
0
    if (newline == NULL) {
328
      /* Single-line comment, no special treatment needed */
329
0
      comment_item = proto_tree_add_string_format(fr_user_data->tree,
330
0
          hf_frame_comment,
331
0
          fr_user_data->tvb, 0, 0,
332
0
          ch,
333
0
          "%s", ch);
334
0
    }
335
0
    else {
336
      /* Multi-line comment. Temporarily change the first
337
       * newline to a null so we only show the first line
338
       */
339
0
      *newline = '\0';
340
0
      comment_item = proto_tree_add_string_format(fr_user_data->tree,
341
0
          hf_frame_comment,
342
0
          fr_user_data->tvb, 0, 0,
343
0
          ch,
344
0
          "%s [...]", ch);
345
0
      comments_tree = proto_item_add_subtree(comment_item, ett_comments);
346
0
      for (i = 0; i < max_comment_lines; i++) {
347
        /* Add each line as a separate item under
348
         * the comment tree
349
         */
350
0
        proto_tree_add_string_format(comments_tree, hf_frame_comment,
351
0
          fr_user_data->tvb, 0, 0,
352
0
          ch,
353
0
          "%s", ch);
354
0
        if (newline == NULL) {
355
          /* This was set in the previous loop
356
           * iteration; it means we've added the
357
           * final line
358
           */
359
0
          break;
360
0
        }
361
0
        else {
362
          /* Put back the newline we removed */
363
0
          *newline = '\n';
364
0
          ch = newline + 1;
365
0
          if (*ch == '\0') {
366
0
            break;
367
0
          }
368
          /* Find next newline to repeat the process
369
           * in the next iteration
370
           */
371
0
          newline = strchr(ch, '\n');
372
0
          if (newline != NULL) {
373
0
            *newline = '\0';
374
0
          }
375
0
        }
376
0
      }
377
0
      if (i == max_comment_lines) {
378
        /* Put back a newline if we still have one dangling */
379
0
        if (newline != NULL) {
380
0
          *newline = '\n';
381
0
        }
382
        /* Add truncation notice */
383
0
        proto_tree_add_string_format(comments_tree, hf_frame_comment,
384
0
          fr_user_data->tvb, 0, 0,
385
0
          "",
386
0
          "[comment truncated at %d line%s]",
387
0
          max_comment_lines,
388
0
          plurality(max_comment_lines, "", "s"));
389
0
      }
390
      /* Add the original comment unchanged as a hidden
391
       * item, so searches still work like before
392
       */
393
0
      hidden_item = proto_tree_add_string(comments_tree,
394
0
          hf_frame_comment,
395
0
          fr_user_data->tvb, 0, 0,
396
0
          option->stringval);
397
0
      proto_item_set_hidden(hidden_item);
398
399
0
      comment_item = comments_tree;
400
0
    }
401
0
    hidden_item = expert_add_info_format(fr_user_data->pinfo, comment_item, &ei_comments_text,
402
0
        "%s",  option->stringval);
403
0
    proto_item_set_hidden(hidden_item);
404
0
  }
405
0
  fr_user_data->n_changes++;
406
0
  return true;
407
0
}
408
409
static bool
410
frame_add_hash(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t *option, void *user_data)
411
0
{
412
0
  fr_foreach_t *fr_user_data = (fr_foreach_t *)user_data;
413
414
0
  if (option_id == OPT_PKT_HASH) {
415
0
    packet_hash_opt_t *hash = &option->packet_hash;
416
0
    const char *format
417
0
      = fr_user_data->n_changes ? ", %s (%u)" : "%s (%u)";
418
419
0
    proto_item_append_text(fr_user_data->item, format,
420
0
               get_hash_type_string(hash->type),
421
0
               hash->type);
422
423
0
    proto_tree_add_bytes_with_length(fr_user_data->tree,
424
0
             hf_frame_hash_bytes,
425
0
             fr_user_data->tvb, 0, 0,
426
0
             hash->hash_bytes->data,
427
0
             hash->hash_bytes->len);
428
0
  }
429
0
  fr_user_data->n_changes++;
430
0
  return true;
431
0
}
432
433
static bool
434
frame_add_verdict(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t *option, void *user_data)
435
0
{
436
0
  fr_foreach_t *fr_user_data = (fr_foreach_t *)user_data;
437
438
0
  if (option_id == OPT_PKT_VERDICT) {
439
0
    packet_verdict_opt_t *verdict = &option->packet_verdictval;
440
0
    char *format = fr_user_data->n_changes ? ", %s (%u)" : "%s (%u)";
441
442
0
    proto_item_append_text(fr_user_data->item, format,
443
0
               get_verdict_type_string(verdict->type),
444
0
               verdict->type);
445
446
0
    switch(verdict->type) {
447
0
      case OPT_VERDICT_TYPE_TC:
448
0
        proto_tree_add_int64(fr_user_data->tree,
449
0
                 hf_frame_verdict_tc,
450
0
                 fr_user_data->tvb, 0, 0,
451
0
                 verdict->data.verdict_linux_ebpf_tc);
452
0
        break;
453
0
      case OPT_VERDICT_TYPE_XDP:
454
0
        proto_tree_add_int64(fr_user_data->tree,
455
0
                 hf_frame_verdict_xdp,
456
0
                 fr_user_data->tvb, 0, 0,
457
0
                 verdict->data.verdict_linux_ebpf_xdp);
458
0
        break;
459
0
      case OPT_VERDICT_TYPE_HW:
460
0
        proto_tree_add_bytes_with_length(fr_user_data->tree,
461
0
                 hf_frame_verdict_hardware,
462
0
                 fr_user_data->tvb, 0, 0,
463
0
                 verdict->data.verdict_bytes->data,
464
0
                 verdict->data.verdict_bytes->len);
465
0
        break;
466
0
      default:
467
0
        proto_tree_add_bytes_with_length(fr_user_data->tree,
468
0
                 hf_frame_verdict_unknown,
469
0
                 fr_user_data->tvb, 0, 0,
470
0
                 verdict->data.verdict_bytes->data,
471
0
                 verdict->data.verdict_bytes->len);
472
0
        break;
473
0
    }
474
0
  }
475
0
  fr_user_data->n_changes++;
476
0
  return true;
477
0
}
478
479
struct custom_binary_opt_cb_data {
480
  tvbuff_t *tvb;
481
  packet_info *pinfo;
482
  proto_tree *tree;
483
  struct custom_binary_opt_data data;
484
};
485
486
static bool
487
handle_packet_option(wtap_block_t block _U_, unsigned option_id,
488
    wtap_opttype_e option_type _U_, wtap_optval_t *optval, void *user_data)
489
0
{
490
0
  struct custom_binary_opt_cb_data *cb_data = (struct custom_binary_opt_cb_data *)user_data;
491
492
0
  switch (option_id) {
493
494
0
  case OPT_CUSTOM_STR_COPY:
495
0
  case OPT_CUSTOM_STR_NO_COPY:
496
    /* Display it */
497
0
    break;
498
499
0
  case OPT_CUSTOM_BIN_COPY:
500
0
  case OPT_CUSTOM_BIN_NO_COPY:
501
    /* Process it */
502
0
    cb_data->data.optval = optval;
503
0
    dissector_try_uint_with_data(binary_option_pen_dissector_table,
504
0
        optval->custom_binaryval.pen, cb_data->tvb,
505
0
        cb_data->pinfo, cb_data->tree, false, &cb_data->data);
506
0
    break;
507
508
0
  default:
509
0
    dissector_try_uint_with_data(packet_block_option_dissector_table,
510
0
      option_id, cb_data->tvb,
511
0
      cb_data->pinfo, cb_data->tree, false, optval);
512
0
    break;
513
0
  }
514
515
0
  return true;
516
0
}
517
518
static int
519
dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
520
192k
{
521
192k
  proto_item  *volatile ti = NULL;
522
192k
  unsigned     cap_len = 0, frame_len = 0;
523
192k
  nstime_t     rel_ts;
524
192k
  uint32_t     pack_flags;
525
192k
  uint32_t     interface_queue;
526
192k
  uint64_t     drop_count;
527
192k
  uint64_t     packetid;
528
192k
  proto_tree  *volatile tree;
529
192k
  proto_tree  *comments_tree;
530
192k
  proto_tree  *volatile fh_tree = NULL;
531
192k
  proto_item  *item;
532
192k
  const char *cap_plurality, *frame_plurality;
533
192k
  frame_data_t *fr_data = (frame_data_t*)data;
534
192k
  const color_filter_t *color_filter;
535
192k
  dissector_handle_t dissector_handle;
536
192k
  fr_foreach_t fr_user_data;
537
538
192k
  tree=parent_tree;
539
540
192k
  DISSECTOR_ASSERT(fr_data);
541
542
  /*
543
   * Set the protocol to the record type name.
544
   */
545
192k
  pinfo->current_proto = pinfo->rec->rec_type_name;
546
192k
  col_set_str(pinfo->cinfo, COL_PROTOCOL, pinfo->rec->rec_type_name);
547
548
192k
  if (wtap_block_count_option(fr_data->pkt_block, OPT_COMMENT) > 0) {
549
0
    item = proto_tree_add_item(tree, proto_pkt_comment, tvb, 0, 0, ENC_NA);
550
0
    comments_tree = proto_item_add_subtree(item, ett_comments);
551
0
    fr_user_data.item = item;
552
0
    fr_user_data.tree = comments_tree;
553
0
    fr_user_data.pinfo = pinfo;
554
0
    fr_user_data.tvb = tvb;
555
0
    fr_user_data.n_changes = 0;
556
0
    wtap_block_foreach_option(fr_data->pkt_block, frame_add_comment, (void *)&fr_user_data);
557
0
  }
558
559
192k
  cap_len = tvb_captured_length(tvb);
560
192k
  frame_len = tvb_reported_length(tvb);
561
562
  /* If FRAME is not referenced from any filters we don't need to
563
     worry about generating any tree items.
564
565
     We do, however, have to worry about generating expert infos,
566
     as those have to show up if, for example, the user requests
567
     the expert info dialog.
568
569
     Therefore, the dissection code has to be careful about
570
     what stuff it does only if do_frame_dissection is true.
571
572
     XXX - all these tricks to optimize dissection if only some
573
     information is required are fragile.  Something better that
574
     handles this automatically would be useful. */
575
192k
  bool do_frame_dissection = proto_field_is_referenced(tree, proto_frame);
576
192k
  cap_plurality = plurality(cap_len, "", "s");
577
192k
  frame_plurality = plurality(frame_len, "", "s");
578
579
  /* Put in frame header information. */
580
192k
  if (do_frame_dissection) {
581
140k
    ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, tvb_captured_length(tvb),
582
140k
        "Frame %u: %s", pinfo->num, pinfo->rec->rec_type_name);
583
140k
  } else {
584
51.6k
    ti = NULL;
585
51.6k
  }
586
192k
  switch (pinfo->rec->rec_type) {
587
588
192k
  case REC_TYPE_PACKET:
589
192k
    if (do_frame_dissection) {
590
140k
      proto_item_append_text(ti, ", %u byte%s on wire",
591
140k
          frame_len, frame_plurality);
592
140k
      if (generate_bits_field)
593
140k
        proto_item_append_text(ti, " (%u bits)", frame_len * 8);
594
140k
      proto_item_append_text(ti, ", %u byte%s captured",
595
140k
          cap_len, cap_plurality);
596
140k
      if (generate_bits_field) {
597
140k
        proto_item_append_text(ti, " (%u bits)",
598
140k
            cap_len * 8);
599
140k
      }
600
140k
      if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID) {
601
0
        const char *interface_name = epan_get_interface_name(pinfo->epan,
602
0
            pinfo->rec->rec_header.packet_header.interface_id,
603
0
            pinfo->rec->presence_flags & WTAP_HAS_SECTION_NUMBER ? pinfo->rec->section_number : 0);
604
0
        if (interface_name != NULL) {
605
0
          proto_item_append_text(ti, " on interface %s, id %u",
606
0
              interface_name, pinfo->rec->rec_header.packet_header.interface_id);
607
0
        } else {
608
0
          proto_item_append_text(ti, " on unnamed interface, id %u",
609
0
              pinfo->rec->rec_header.packet_header.interface_id);
610
0
        }
611
0
      }
612
140k
    }
613
192k
    if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_uint32_option_value(fr_data->pkt_block, OPT_PKT_FLAGS, &pack_flags)) {
614
0
      switch (PACK_FLAGS_DIRECTION(pack_flags)) {
615
616
0
      case PACK_FLAGS_DIRECTION_UNKNOWN:
617
0
      default:
618
0
        pinfo->p2p_dir = P2P_DIR_UNKNOWN;
619
0
        break;
620
621
0
      case PACK_FLAGS_DIRECTION_INBOUND:
622
0
        pinfo->p2p_dir = P2P_DIR_RECV;
623
0
        if (do_frame_dissection)
624
0
          proto_item_append_text(ti, " (inbound)");
625
0
        break;
626
627
0
      case PACK_FLAGS_DIRECTION_OUTBOUND:
628
0
        pinfo->p2p_dir = P2P_DIR_SENT;
629
0
        if (do_frame_dissection)
630
0
          proto_item_append_text(ti, " (outbound)");
631
0
        break;
632
0
      }
633
0
    }
634
635
    /*
636
     * If the pseudo-header *and* the packet record both
637
     * have direction information, the pseudo-header
638
     * overrides the packet record.
639
     */
640
192k
    if (pinfo->pseudo_header != NULL) {
641
192k
      switch (pinfo->rec->rec_header.packet_header.pkt_encap) {
642
643
0
      case WTAP_ENCAP_WFLEET_HDLC:
644
0
      case WTAP_ENCAP_CHDLC_WITH_PHDR:
645
0
      case WTAP_ENCAP_PPP_WITH_PHDR:
646
0
      case WTAP_ENCAP_SDLC:
647
0
      case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR:
648
0
        pinfo->p2p_dir = pinfo->pseudo_header->p2p.sent ?
649
0
            P2P_DIR_SENT : P2P_DIR_RECV;
650
0
        break;
651
652
0
      case WTAP_ENCAP_BLUETOOTH_HCI:
653
0
        pinfo->p2p_dir = pinfo->pseudo_header->bthci.sent ?
654
0
          P2P_DIR_SENT : P2P_DIR_RECV;
655
0
        break;
656
657
0
      case WTAP_ENCAP_LAPB:
658
0
      case WTAP_ENCAP_FRELAY_WITH_PHDR:
659
0
        pinfo->p2p_dir =
660
0
            (pinfo->pseudo_header->dte_dce.flags & FROM_DCE) ?
661
0
            P2P_DIR_RECV : P2P_DIR_SENT;
662
0
        break;
663
664
0
      case WTAP_ENCAP_ISDN:
665
0
      case WTAP_ENCAP_V5_EF:
666
0
      case WTAP_ENCAP_DPNSS:
667
0
      case WTAP_ENCAP_BACNET_MS_TP_WITH_PHDR:
668
0
        pinfo->p2p_dir = pinfo->pseudo_header->isdn.uton ?
669
0
            P2P_DIR_SENT : P2P_DIR_RECV;
670
0
        break;
671
672
0
      case WTAP_ENCAP_LINUX_LAPD:
673
0
        pinfo->p2p_dir = (pinfo->pseudo_header->lapd.pkttype == 3 ||
674
0
          pinfo->pseudo_header->lapd.pkttype == 4) ?
675
0
          P2P_DIR_SENT : P2P_DIR_RECV;
676
0
        break;
677
678
0
      case WTAP_ENCAP_MTP2_WITH_PHDR:
679
0
        pinfo->p2p_dir = pinfo->pseudo_header->mtp2.sent ?
680
0
            P2P_DIR_SENT : P2P_DIR_RECV;
681
0
        pinfo->link_number  = pinfo->pseudo_header->mtp2.link_number;
682
0
        break;
683
684
0
      case WTAP_ENCAP_GSM_UM:
685
0
        pinfo->p2p_dir = pinfo->pseudo_header->gsm_um.uplink ?
686
0
            P2P_DIR_SENT : P2P_DIR_RECV;
687
0
        break;
688
192k
      }
689
192k
    }
690
192k
    break;
691
692
192k
  case REC_TYPE_FT_SPECIFIC_EVENT:
693
0
    break;
694
695
0
  case REC_TYPE_FT_SPECIFIC_REPORT:
696
0
    break;
697
698
0
  case REC_TYPE_SYSCALL:
699
0
    if (do_frame_dissection) {
700
      /*
701
       * This gives us a top-of-tree "syscall" protocol
702
       * with "frame" fields underneath. Should we create
703
       * corresponding syscall.time, .time_epoch, etc
704
       * fields and use them instead or would frame.*
705
       * be preferred?
706
       *
707
       * XXX - is this length value relevant?
708
       */
709
0
      proto_item_append_text(ti, ", %u byte%s",
710
0
          frame_len, frame_plurality);
711
0
    }
712
0
    break;
713
714
0
  case REC_TYPE_SYSTEMD_JOURNAL_EXPORT:
715
0
    if (do_frame_dissection) {
716
      /*
717
       * XXX - we need to rethink what's handled by
718
       * packet-record.c, what's handled by packet-frame.c.
719
       * and what's handled by the syscall and systemd
720
       * journal dissectors (and maybe even the packet
721
       * dissector).
722
       *
723
       * XXX - is this length value relevant?
724
       */
725
0
      proto_item_append_text(ti, ", %u byte%s",
726
0
          frame_len, frame_plurality);
727
0
    }
728
0
    break;
729
730
0
  case REC_TYPE_CUSTOM_BLOCK:
731
0
    if (do_frame_dissection) {
732
0
      proto_item_append_text(ti, ", %u byte%s",
733
0
          frame_len, frame_plurality);
734
0
      proto_item_append_text(ti, ", copying%s allowed",
735
0
                             pinfo->rec->rec_header.custom_block_header.copy_allowed ? "" : " not");
736
0
    }
737
0
    break;
738
739
0
  default:
740
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
741
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "Record type %u",
742
0
        pinfo->rec->rec_type);
743
0
    call_data_dissector(tvb, pinfo, parent_tree);
744
0
    return tvb_captured_length(tvb);
745
192k
  }
746
747
192k
  if (do_frame_dissection) {
748
140k
    fh_tree = proto_item_add_subtree(ti, ett_frame);
749
140k
  } else {
750
51.6k
    fh_tree = NULL;
751
51.6k
  }
752
753
192k
  if (pinfo->rec->presence_flags & WTAP_HAS_SECTION_NUMBER &&
754
0
      do_frame_dissection &&
755
0
      (proto_field_is_referenced(tree, hf_frame_section_number))) {
756
    /* Show it as 1-origin */
757
0
    proto_tree_add_uint(fh_tree, hf_frame_section_number, tvb,
758
0
            0, 0, pinfo->rec->section_number + 1);
759
0
  }
760
761
192k
  if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID &&
762
0
      do_frame_dissection &&
763
0
      ((proto_field_is_referenced(tree, hf_frame_interface_id) || proto_field_is_referenced(tree, hf_frame_interface_name) || proto_field_is_referenced(tree, hf_frame_interface_description)))) {
764
0
    unsigned section_number = pinfo->rec->presence_flags & WTAP_HAS_SECTION_NUMBER ? pinfo->rec->section_number : 0;
765
0
    const char *interface_name = epan_get_interface_name(pinfo->epan, pinfo->rec->rec_header.packet_header.interface_id, section_number);
766
0
    const char *interface_description = epan_get_interface_description(pinfo->epan, pinfo->rec->rec_header.packet_header.interface_id, section_number);
767
0
    proto_tree *if_tree;
768
0
    proto_item *if_item;
769
770
0
    if (interface_name) {
771
0
      if_item = proto_tree_add_uint_format_value(fh_tree, hf_frame_interface_id, tvb, 0, 0,
772
0
                   pinfo->rec->rec_header.packet_header.interface_id, "%u (%s)",
773
0
                   pinfo->rec->rec_header.packet_header.interface_id, interface_name);
774
0
      if_tree = proto_item_add_subtree(if_item, ett_ifname);
775
0
      proto_tree_add_string(if_tree, hf_frame_interface_name, tvb, 0, 0, interface_name);
776
0
    } else {
777
0
      if_item = proto_tree_add_uint(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->rec->rec_header.packet_header.interface_id);
778
0
    }
779
780
0
    if (interface_description) {
781
0
      if_tree = proto_item_add_subtree(if_item, ett_ifname);
782
0
      proto_tree_add_string(if_tree, hf_frame_interface_description, tvb, 0, 0, interface_description);
783
0
    }
784
0
  }
785
786
192k
  if (pinfo->rec->rec_type == REC_TYPE_PACKET) {
787
192k
    if (do_frame_dissection) {
788
140k
      if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_uint32_option_value(fr_data->pkt_block, OPT_PKT_QUEUE, &interface_queue)) {
789
0
        proto_tree_add_uint(fh_tree, hf_frame_interface_queue, tvb, 0, 0, interface_queue);
790
0
      }
791
792
140k
      if (wtap_block_count_option(fr_data->pkt_block, OPT_PKT_HASH) > 0) {
793
0
        proto_tree *hash_tree;
794
0
        proto_item *hash_item;
795
796
0
        hash_item = proto_tree_add_string(fh_tree, hf_frame_hash, tvb, 0, 0, "");
797
0
        hash_tree = proto_item_add_subtree(hash_item, ett_hash);
798
0
        fr_user_data.item = hash_item;
799
0
        fr_user_data.tree = hash_tree;
800
0
        fr_user_data.pinfo = pinfo;
801
0
        fr_user_data.tvb = tvb;
802
0
        fr_user_data.n_changes = 0;
803
0
        wtap_block_foreach_option(fr_data->pkt_block, frame_add_hash, (void *)&fr_user_data);
804
0
      }
805
806
140k
      if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_uint32_option_value(fr_data->pkt_block, OPT_PKT_FLAGS, &pack_flags)) {
807
0
        proto_tree *flags_tree;
808
0
        proto_item *flags_item;
809
0
        static int * const flags[] = {
810
0
          &hf_frame_pack_direction,
811
0
          &hf_frame_pack_reception_type,
812
0
          &hf_frame_pack_fcs_length,
813
0
          &hf_frame_pack_reserved,
814
0
          &hf_frame_pack_crc_error,
815
0
          &hf_frame_pack_wrong_packet_too_long_error,
816
0
          &hf_frame_pack_wrong_packet_too_short_error,
817
0
          &hf_frame_pack_wrong_inter_frame_gap_error,
818
0
          &hf_frame_pack_unaligned_frame_error,
819
0
          &hf_frame_pack_start_frame_delimiter_error,
820
0
          &hf_frame_pack_preamble_error,
821
0
          &hf_frame_pack_symbol_error,
822
0
          NULL
823
0
        };
824
825
0
        flags_item = proto_tree_add_uint(fh_tree, hf_frame_pack_flags, tvb, 0, 0, pack_flags);
826
0
        flags_tree = proto_item_add_subtree(flags_item, ett_flags);
827
0
        proto_tree_add_bitmask_list_value(flags_tree, tvb, 0, 0, flags, pack_flags);
828
0
      }
829
830
140k
      if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_uint64_option_value(fr_data->pkt_block, OPT_PKT_PACKETID, &packetid)) {
831
0
        proto_tree_add_uint64(fh_tree, hf_frame_packet_id, tvb, 0, 0, packetid);
832
0
      }
833
834
140k
      if (wtap_block_count_option(fr_data->pkt_block, OPT_PKT_VERDICT) > 0) {
835
0
        proto_tree *verdict_tree;
836
0
        proto_item *verdict_item;
837
838
0
        verdict_item = proto_tree_add_string(fh_tree, hf_frame_verdict, tvb, 0, 0, "");
839
0
        verdict_tree = proto_item_add_subtree(verdict_item, ett_verdict);
840
0
        fr_user_data.item = verdict_item;
841
0
        fr_user_data.tree = verdict_tree;
842
0
        fr_user_data.pinfo = pinfo;
843
0
        fr_user_data.tvb = tvb;
844
0
        fr_user_data.n_changes = 0;
845
0
        wtap_block_foreach_option(pinfo->rec->block, frame_add_verdict, (void *)&fr_user_data);
846
0
      }
847
848
140k
      proto_tree_add_int(fh_tree, hf_frame_wtap_encap, tvb, 0, 0, pinfo->rec->rec_header.packet_header.pkt_encap);
849
140k
    }
850
192k
  }
851
852
192k
  if (pinfo->presence_flags & PINFO_HAS_TS) {
853
192k
    if (do_frame_dissection) {
854
140k
      proto_tree_add_time(fh_tree, hf_frame_arrival_time_local, tvb, 0, 0, &pinfo->abs_ts);
855
140k
      proto_tree_add_time(fh_tree, hf_frame_arrival_time_utc, tvb, 0, 0, &pinfo->abs_ts);
856
140k
      proto_tree_add_time(fh_tree, hf_frame_arrival_time_epoch, tvb, 0, 0, &pinfo->abs_ts);
857
140k
    }
858
192k
    if (pinfo->abs_ts.nsecs < 0 || pinfo->abs_ts.nsecs >= 1000000000) {
859
0
      expert_add_info_format(pinfo, ti, &ei_arrive_time_out_of_range,
860
0
                "Arrival Time: Fractional second %09ld is invalid,"
861
0
                " the valid range is 0-999999999",
862
0
                (long) pinfo->abs_ts.nsecs);
863
0
    }
864
192k
    if (do_frame_dissection) {
865
140k
      item = proto_tree_add_time(fh_tree, hf_frame_shift_offset, tvb,
866
140k
              0, 0, &(pinfo->fd->shift_offset));
867
140k
      proto_item_set_generated(item);
868
869
140k
      if (proto_field_is_referenced(tree, hf_frame_time_delta)) {
870
140k
        nstime_t     del_cap_ts;
871
872
140k
        if (frame_delta_time_prev_captured(pinfo->epan, pinfo->fd, &del_cap_ts)) {
873
140k
          item = proto_tree_add_time(fh_tree, hf_frame_time_delta, tvb,
874
140k
                   0, 0, &(del_cap_ts));
875
140k
          proto_item_set_generated(item);
876
140k
        }
877
140k
      }
878
879
140k
      if (proto_field_is_referenced(tree, hf_frame_time_delta_displayed)) {
880
140k
        nstime_t del_dis_ts;
881
882
140k
        if (frame_delta_time_prev_displayed(pinfo->epan, pinfo->fd, &del_dis_ts)) {
883
0
          item = proto_tree_add_time(fh_tree, hf_frame_time_delta_displayed, tvb,
884
0
                   0, 0, &(del_dis_ts));
885
0
          proto_item_set_generated(item);
886
0
        }
887
140k
      }
888
889
140k
      if (frame_rel_time(pinfo->epan, pinfo->fd, &rel_ts)) {
890
140k
        item = proto_tree_add_time(fh_tree, hf_frame_time_relative, tvb,
891
140k
                 0, 0, &(rel_ts));
892
140k
        proto_item_set_generated(item);
893
140k
      }
894
895
140k
      if (frame_rel_start_time(pinfo->epan, pinfo->fd, &rel_ts)) {
896
0
        item = proto_tree_add_time(fh_tree, hf_frame_time_relative_cap, tvb,
897
0
                 0, 0, &(rel_ts));
898
0
        proto_item_set_generated(item);
899
0
      }
900
901
140k
      if (pinfo->fd->ref_time) {
902
0
        ti = proto_tree_add_item(fh_tree, hf_frame_time_reference, tvb, 0, 0, ENC_NA);
903
0
        proto_item_set_generated(ti);
904
0
      }
905
140k
    }
906
192k
  }
907
908
192k
  if (do_frame_dissection) {
909
140k
    proto_tree_add_uint(fh_tree, hf_frame_number, tvb,
910
140k
            0, 0, pinfo->num);
911
912
140k
    item = proto_tree_add_uint_format_value(fh_tree, hf_frame_len, tvb,
913
140k
              0, 0, frame_len, "%u byte%s (%u bits)",
914
140k
              frame_len, frame_plurality, frame_len * 8);
915
140k
  } else {
916
51.6k
    item = NULL;
917
51.6k
  }
918
192k
  if (frame_len < cap_len) {
919
    /*
920
     * A reported length less than a captured length
921
     * is bogus, as you cannot capture more data
922
     * than there is in a packet.
923
     */
924
0
    expert_add_info(pinfo, item, &ei_len_lt_caplen);
925
0
  }
926
927
192k
  if (do_frame_dissection) {
928
140k
    proto_tree_add_uint_format_value(fh_tree, hf_frame_capture_len, tvb,
929
140k
             0, 0, cap_len, "%u byte%s (%u bits)",
930
140k
             cap_len, cap_plurality, cap_len * 8);
931
932
140k
    if (pinfo->rec->rec_type == REC_TYPE_PACKET) {
933
140k
      if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_uint64_option_value(fr_data->pkt_block, OPT_PKT_DROPCOUNT, &drop_count)) {
934
0
        proto_tree_add_uint64(fh_tree, hf_frame_drop_count, tvb, 0, 0, drop_count);
935
0
      }
936
140k
    }
937
938
140k
    if (generate_md5_hash) {
939
0
      const uint8_t *cp;
940
0
      uint8_t       digest[HASH_MD5_LENGTH];
941
0
      const char   *digest_string;
942
943
0
      cp = tvb_get_ptr(tvb, 0, cap_len);
944
945
0
      gcry_md_hash_buffer(GCRY_MD_MD5, digest, cp, cap_len);
946
0
      digest_string = bytes_to_str_punct(pinfo->pool, digest, HASH_MD5_LENGTH, '\0');
947
0
      ti = proto_tree_add_string(fh_tree, hf_frame_md5_hash, tvb, 0, 0, digest_string);
948
0
      proto_item_set_generated(ti);
949
0
    }
950
951
140k
    ti = proto_tree_add_boolean(fh_tree, hf_frame_marked, tvb, 0, 0, pinfo->fd->marked);
952
140k
    proto_item_set_generated(ti);
953
954
140k
    ti = proto_tree_add_boolean(fh_tree, hf_frame_ignored, tvb, 0, 0, pinfo->fd->ignored);
955
140k
    proto_item_set_generated(ti);
956
140k
  }
957
958
192k
  if (pinfo->rec->rec_type == REC_TYPE_PACKET) {
959
192k
    if (do_frame_dissection) {
960
      /* Check for existences of P2P pseudo header */
961
140k
      if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) {
962
0
        proto_tree_add_int(fh_tree, hf_frame_p2p_dir, tvb,
963
0
               0, 0, pinfo->p2p_dir);
964
0
      }
965
966
      /* Check for existences of MTP2 link number */
967
140k
      if ((pinfo->pseudo_header != NULL) &&
968
140k
          (pinfo->rec->rec_header.packet_header.pkt_encap == WTAP_ENCAP_MTP2_WITH_PHDR)) {
969
0
        proto_tree_add_uint(fh_tree, hf_frame_link_number, tvb,
970
0
                0, 0, pinfo->link_number);
971
0
      }
972
140k
    }
973
974
    /*
975
     * Process custom options.
976
     */
977
192k
    struct custom_binary_opt_cb_data cb_data;
978
979
192k
    cb_data.pinfo = pinfo;
980
192k
    cb_data.tvb = tvb;
981
192k
    cb_data.tree = fh_tree;
982
192k
    cb_data.data.optval = NULL;
983
192k
    wtap_block_foreach_option(fr_data->pkt_block,
984
192k
        handle_packet_option, &cb_data);
985
192k
  }
986
987
  /* If there is Darwin data, call the dissector */
988
192k
  if (p_get_proto_data(wmem_file_scope(), pinfo, proto_darwin, 0) != NULL) {
989
0
    call_dissector(darwin_handle, tvb, pinfo, fh_tree);
990
0
  }
991
992
192k
  if (do_frame_dissection) {
993
140k
    if (show_file_off) {
994
0
      proto_tree_add_int64_format_value(fh_tree, hf_frame_file_off, tvb,
995
0
                0, 0, pinfo->fd->file_off,
996
0
                "%" PRId64 " (0x%" PRIx64 ")",
997
0
                pinfo->fd->file_off, pinfo->fd->file_off);
998
0
    }
999
140k
  }
1000
1001
192k
  if (pinfo->fd->ignored) {
1002
    /* Ignored package, stop handling here */
1003
0
    col_set_str(pinfo->cinfo, COL_INFO, "<Ignored>");
1004
0
    proto_tree_add_boolean_format(tree, hf_frame_ignored, tvb, 0, 0, true, "This frame is marked as ignored");
1005
0
    return tvb_captured_length(tvb);
1006
0
  }
1007
1008
192k
  if (frame_len < cap_len) {
1009
    /*
1010
     * Fix the reported length; a reported length less than
1011
     * a captured length is bogus, as you cannot capture
1012
     * more data than there is in a packet.
1013
     */
1014
0
    tvb_fix_reported_length(tvb);
1015
0
  }
1016
1017
  /* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */
1018
192k
  TRY {
1019
#ifdef _MSC_VER
1020
    /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions
1021
       like memory access violations.
1022
       (a running debugger will be called before the except part below) */
1023
    /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
1024
       stack in an inconsistent state thus causing a crash at some point in the
1025
       handling of the exception.
1026
       See: https://lists.wireshark.org/archives/wireshark-dev/200704/msg00243.html
1027
    */
1028
    __try {
1029
#endif
1030
192k
      switch (pinfo->rec->rec_type) {
1031
1032
192k
      case REC_TYPE_PACKET:
1033
192k
        if ((force_docsis_encap) && (docsis_handle)) {
1034
0
          dissector_handle = docsis_handle;
1035
192k
        } else {
1036
          /*
1037
           * XXX - we don't use dissector_try_uint_with_data()
1038
           * because we don't want to have to
1039
           * treat a zero return from the dissector
1040
           * as meaning "packet not accepted,
1041
           * because that doesn't work for
1042
           * packets where libwiretap strips
1043
           * off the metadata header and puts
1044
           * it into the pseudo-header, leaving
1045
           * zero bytes worth of payload.  See
1046
           * bug 15630.
1047
           *
1048
           * If the dissector for the packet's
1049
           * purported link-layer header type
1050
           * rejects the packet, that's a sign
1051
           * of a bug somewhere, so making it
1052
           * impossible for those dissectors
1053
           * to reject packets isn't a problem.
1054
           */
1055
192k
          dissector_handle =
1056
192k
              dissector_get_uint_handle(wtap_encap_dissector_table,
1057
192k
                  pinfo->rec->rec_header.packet_header.pkt_encap);
1058
192k
        }
1059
192k
        if (dissector_handle != NULL) {
1060
0
          uint32_t save_match_uint = pinfo->match_uint;
1061
1062
0
          pinfo->match_uint =
1063
0
              pinfo->rec->rec_header.packet_header.pkt_encap;
1064
0
          call_dissector_only(dissector_handle,
1065
0
              tvb, pinfo, parent_tree,
1066
0
              (void *)pinfo->pseudo_header);
1067
0
          pinfo->match_uint = save_match_uint;
1068
192k
        } else {
1069
192k
          col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
1070
192k
          col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %d",
1071
192k
                 pinfo->rec->rec_header.packet_header.pkt_encap);
1072
192k
          call_data_dissector(tvb, pinfo, parent_tree);
1073
192k
        }
1074
192k
        break;
1075
1076
0
      case REC_TYPE_FT_SPECIFIC_EVENT:
1077
0
      case REC_TYPE_FT_SPECIFIC_REPORT:
1078
0
        {
1079
0
          int file_type_subtype;
1080
1081
0
          file_type_subtype = fr_data->file_type_subtype;
1082
1083
0
          if (!dissector_try_uint(wtap_fts_rec_dissector_table, file_type_subtype,
1084
0
              tvb, pinfo, parent_tree)) {
1085
0
            col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
1086
0
            col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP FT ST = %d",
1087
0
                   file_type_subtype);
1088
0
            call_data_dissector(tvb, pinfo, parent_tree);
1089
0
          }
1090
0
        }
1091
0
        break;
1092
1093
0
      case REC_TYPE_SYSCALL:
1094
        /* Sysdig is the only type we currently handle. */
1095
0
        if (sysdig_handle) {
1096
0
          call_dissector_with_data(sysdig_handle,
1097
0
              tvb, pinfo, parent_tree,
1098
0
              (void *)pinfo->pseudo_header);
1099
0
        }
1100
0
        break;
1101
1102
0
      case REC_TYPE_SYSTEMD_JOURNAL_EXPORT:
1103
0
        if (systemd_journal_handle) {
1104
0
          call_dissector_with_data(systemd_journal_handle,
1105
0
              tvb, pinfo, parent_tree,
1106
0
              (void *)pinfo->pseudo_header);
1107
0
        }
1108
0
        break;
1109
1110
0
      case REC_TYPE_CUSTOM_BLOCK:
1111
0
        if (!dissector_try_uint(block_pen_dissector_table,
1112
0
            pinfo->rec->rec_header.custom_block_header.pen,
1113
0
            tvb, pinfo, parent_tree)) {
1114
0
          col_set_str(pinfo->cinfo, COL_PROTOCOL, "PCAPNG");
1115
0
          proto_tree_add_uint_format_value(fh_tree, hf_frame_cb_pen, tvb, 0, 0,
1116
0
                                           pinfo->rec->rec_header.custom_block_header.pen,
1117
0
                                           "%s (%u)",
1118
0
                                           enterprises_lookup(pinfo->rec->rec_header.custom_block_header.pen, "Unknown"),
1119
0
                                           pinfo->rec->rec_header.custom_block_header.pen);
1120
0
          proto_tree_add_boolean(fh_tree, hf_frame_cb_copy_allowed, tvb, 0, 0, pinfo->rec->rec_header.custom_block_header.copy_allowed);
1121
0
          col_add_fstr(pinfo->cinfo, COL_INFO, "Custom Block: PEN = %s (%d), will%s be copied",
1122
0
                       enterprises_lookup(pinfo->rec->rec_header.custom_block_header.pen, "Unknown"),
1123
0
                       pinfo->rec->rec_header.custom_block_header.pen,
1124
0
                       pinfo->rec->rec_header.custom_block_header.copy_allowed ? "" : " not");
1125
0
          call_data_dissector(tvb, pinfo, parent_tree);
1126
0
        }
1127
0
        break;
1128
192k
      }
1129
#ifdef _MSC_VER
1130
    } __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
1131
      ensure_tree_item(parent_tree, EXCEPTION_TREE_ITEMS);
1132
      switch (GetExceptionCode()) {
1133
      case(STATUS_ACCESS_VIOLATION):
1134
        show_exception(tvb, pinfo, parent_tree, DissectorError,
1135
                 "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
1136
        break;
1137
      case(STATUS_INTEGER_DIVIDE_BY_ZERO):
1138
        show_exception(tvb, pinfo, parent_tree, DissectorError,
1139
                 "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
1140
        break;
1141
      case(STATUS_STACK_OVERFLOW):
1142
        show_exception(tvb, pinfo, parent_tree, DissectorError,
1143
                 "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
1144
        /* XXX - this will have probably corrupted the stack,
1145
           which makes problems later in the exception code */
1146
        break;
1147
        /* XXX - add other hardware exception codes as required */
1148
      default:
1149
        show_exception(tvb, pinfo, parent_tree, DissectorError,
1150
                 ws_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
1151
      }
1152
    }
1153
#endif
1154
192k
  }
1155
192k
  CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
1156
0
    ensure_tree_item(parent_tree, EXCEPTION_TREE_ITEMS);
1157
0
    show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
1158
0
  }
1159
192k
  ENDTRY;
1160
1161
192k
  if (proto_field_is_referenced(tree, hf_frame_protocols)) {
1162
140k
    wmem_strbuf_t *val = wmem_strbuf_new_sized(pinfo->pool, 128);
1163
140k
    wmem_list_frame_t *frame;
1164
    /* skip the first entry, it's always the "frame" protocol */
1165
140k
    frame = wmem_list_frame_next(wmem_list_head(pinfo->layers));
1166
140k
    if (frame) {
1167
140k
      wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
1168
140k
      frame = wmem_list_frame_next(frame);
1169
140k
    }
1170
140k
    while (frame) {
1171
0
      wmem_strbuf_append_c(val, ':');
1172
0
      wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
1173
0
      frame = wmem_list_frame_next(frame);
1174
0
    }
1175
140k
    ensure_tree_item(fh_tree, 1);
1176
140k
    ti = proto_tree_add_string(fh_tree, hf_frame_protocols, tvb, 0, 0, wmem_strbuf_get_str(val));
1177
140k
    proto_item_set_generated(ti);
1178
140k
  }
1179
1180
192k
  proto_tree_add_uint(fh_tree, hf_frame_encoding, tvb, 0, 0, pinfo->fd->encoding);
1181
1182
  /* Add the columns as fields. We have to do this here, so that
1183
   * they're available for postdissectors that want all the fields.
1184
   *
1185
   * Note the coloring rule names are set after this, which means
1186
   * that you can set a coloring rule based on the value of a column,
1187
   * like _ws.col.protocol or _ws.col.info.
1188
   * OTOH, if we created _ws.col.custom, and a custom column used
1189
   * frame.coloring_rule.name, filtering with it wouldn't work -
1190
   * but you can filter on that field directly, so that doesn't matter.
1191
   */
1192
192k
  col_dissect(tvb, pinfo, parent_tree);
1193
1194
  /*  Call postdissectors if we have any (while trying to avoid another
1195
   *  TRY/CATCH)
1196
   */
1197
192k
  if (have_postdissector()) {
1198
192k
    TRY {
1199
#ifdef _MSC_VER
1200
      /* Win32: Visual-C Structured Exception Handling (SEH)
1201
         to trap hardware exceptions like memory access violations */
1202
      /* (a running debugger will be called before the except part below) */
1203
      /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
1204
         stack in an inconsistent state thus causing a crash at some point in the
1205
         handling of the exception.
1206
         See: https://lists.wireshark.org/archives/wireshark-dev/200704/msg00243.html
1207
      */
1208
      __try {
1209
#endif
1210
192k
        call_all_postdissectors(tvb, pinfo, parent_tree);
1211
#ifdef _MSC_VER
1212
      } __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
1213
        ensure_tree_item(parent_tree, EXCEPTION_TREE_ITEMS);
1214
        switch (GetExceptionCode()) {
1215
        case(STATUS_ACCESS_VIOLATION):
1216
          show_exception(tvb, pinfo, parent_tree, DissectorError,
1217
                   "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
1218
          break;
1219
        case(STATUS_INTEGER_DIVIDE_BY_ZERO):
1220
          show_exception(tvb, pinfo, parent_tree, DissectorError,
1221
                   "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
1222
          break;
1223
        case(STATUS_STACK_OVERFLOW):
1224
          show_exception(tvb, pinfo, parent_tree, DissectorError,
1225
                   "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
1226
          /* XXX - this will have probably corrupted the stack,
1227
             which makes problems later in the exception code */
1228
          break;
1229
          /* XXX - add other hardware exception codes as required */
1230
        default:
1231
          show_exception(tvb, pinfo, parent_tree, DissectorError,
1232
                   ws_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
1233
        }
1234
      }
1235
#endif
1236
192k
    }
1237
192k
    CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
1238
113k
      ensure_tree_item(parent_tree, EXCEPTION_TREE_ITEMS);
1239
113k
      show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
1240
113k
    }
1241
192k
    ENDTRY;
1242
192k
  }
1243
1244
  /* Attempt to (re-)calculate color filters (if any). */
1245
192k
  if (pinfo->fd->need_colorize) {
1246
0
    color_filter = color_filters_colorize_packet(fr_data->color_edt);
1247
0
    pinfo->fd->color_filter = color_filter;
1248
0
    pinfo->fd->need_colorize = 0;
1249
192k
  } else {
1250
192k
    color_filter = pinfo->fd->color_filter;
1251
192k
  }
1252
192k
  if (color_filter) {
1253
0
    ensure_tree_item(fh_tree, 1);
1254
0
    item = proto_tree_add_string(fh_tree, hf_frame_color_filter_name, tvb,
1255
0
               0, 0, color_filter->filter_name);
1256
0
    proto_item_set_generated(item);
1257
0
    ensure_tree_item(fh_tree, 1);
1258
0
    item = proto_tree_add_string(fh_tree, hf_frame_color_filter_text, tvb,
1259
0
               0, 0, color_filter->filter_text);
1260
0
    proto_item_set_generated(item);
1261
0
  }
1262
1263
192k
  tap_queue_packet(frame_tap, pinfo, NULL);
1264
1265
1266
192k
  if (pinfo->frame_end_routines) {
1267
2.27k
    g_slist_free_full(pinfo->frame_end_routines, &call_frame_end_routine);
1268
2.27k
    pinfo->frame_end_routines = NULL;
1269
2.27k
  }
1270
1271
192k
  if (prefs.enable_incomplete_dissectors_check && tree && tree->tree_data->visible) {
1272
0
    char* decoded;
1273
0
    unsigned length;
1274
0
    unsigned i;
1275
0
    unsigned byte;
1276
0
    unsigned bit;
1277
1278
0
    length = tvb_captured_length(tvb);
1279
0
    decoded = proto_find_undecoded_data(tree, length);
1280
1281
0
    for (i = 0; i < length; i++) {
1282
0
      byte = i / 8;
1283
0
      bit = i % 8;
1284
0
      if (!(decoded[byte] & (1 << bit))) {
1285
0
        field_info* fi = proto_find_field_from_offset(tree, i, tvb);
1286
0
        if (fi && fi->hfinfo->id != proto_frame) {
1287
0
          if (prefs.incomplete_dissectors_check_debug)
1288
0
            ws_log(LOG_DOMAIN_CAPTURE, LOG_LEVEL_WARNING,
1289
0
              "Dissector %s incomplete in frame %u: undecoded byte number %u "
1290
0
              "(0x%.4X+%u)",
1291
0
              fi->hfinfo->abbrev,
1292
0
              pinfo->num, i, i - i % 16, i % 16);
1293
0
          ensure_tree_item(tree, 1);
1294
0
          proto_tree_add_expert_format(tree, pinfo, &ei_incomplete, tvb, i, 1, "Undecoded byte number: %u (0x%.4X+%u)", i, i - i % 16, i % 16);
1295
0
        }
1296
0
      }
1297
0
    }
1298
0
  }
1299
1300
192k
  return tvb_captured_length(tvb);
1301
192k
}
1302
1303
static void common_register_frame(bool use_packets)
1304
14
{
1305
14
  static hf_register_info hf[] = {
1306
14
    { &hf_frame_arrival_time_local,
1307
14
      { "Arrival Time", "frame.time",
1308
14
        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
1309
14
        "Absolute time when this frame was captured, in local time", HFILL }},
1310
1311
14
    { &hf_frame_arrival_time_utc,
1312
14
      { "UTC Arrival Time", "frame.time_utc",
1313
14
        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
1314
14
        "Absolute time when this frame was captured, in Coordinated Universal Time (UTC)", HFILL }},
1315
1316
14
    { &hf_frame_arrival_time_epoch,
1317
14
      { "Epoch Arrival Time", "frame.time_epoch",
1318
14
        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UNIX, NULL, 0x0,
1319
14
        "Absolute time when this frame was captured, in Epoch time (also known as Unix time)", HFILL }},
1320
1321
14
    { &hf_frame_shift_offset,
1322
14
      { "Time shift for this packet", "frame.offset_shift",
1323
14
        FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1324
14
        "Time shift applied to this packet", HFILL }},
1325
1326
14
    { &hf_frame_time_delta,
1327
14
      { "Time delta from previous captured frame", "frame.time_delta",
1328
14
        FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1329
14
        NULL, HFILL }},
1330
1331
14
    { &hf_frame_time_delta_displayed,
1332
14
      { "Time delta from previous displayed frame", "frame.time_delta_displayed",
1333
14
        FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1334
14
        NULL, HFILL }},
1335
1336
14
    { &hf_frame_time_relative,
1337
14
      { "Time since reference or first frame", "frame.time_relative",
1338
14
        FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1339
14
        "Time relative to time reference or first frame", HFILL }},
1340
1341
14
    { &hf_frame_time_relative_cap,
1342
14
      { "Time since start of capturing", "frame.time_relative_capture_start",
1343
14
        FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1344
14
        "Time relative to the capture start", HFILL }},
1345
1346
14
    { &hf_frame_time_reference,
1347
14
      { "This is a Time Reference frame", "frame.ref_time",
1348
14
        FT_NONE, BASE_NONE, NULL, 0x0,
1349
14
        "This frame is a Time Reference frame", HFILL }},
1350
1351
14
    { &hf_frame_number,
1352
14
      { "Frame Number", "frame.number",
1353
14
        FT_UINT32, BASE_DEC, NULL, 0x0,
1354
14
        NULL, HFILL }},
1355
1356
14
    { &hf_frame_len,
1357
14
      { "Frame Length", "frame.len",
1358
14
        FT_UINT32, BASE_DEC, NULL, 0x0,
1359
14
        "Frame length on the wire", HFILL }},
1360
1361
14
    { &hf_frame_capture_len,
1362
14
      { "Capture Length", "frame.cap_len",
1363
14
        FT_UINT32, BASE_DEC, NULL, 0x0,
1364
14
        "Frame length stored into the capture file", HFILL }},
1365
1366
14
    { &hf_frame_md5_hash,
1367
14
      { "Frame MD5 Hash", "frame.md5_hash",
1368
14
        FT_STRING, BASE_NONE, NULL, 0x0,
1369
14
        NULL, HFILL }},
1370
1371
14
    { &hf_frame_p2p_dir,
1372
14
      { "Point-to-Point Direction", "frame.p2p_dir",
1373
14
        FT_INT8, BASE_DEC, VALS(p2p_dirs), 0x0,
1374
14
        NULL, HFILL }},
1375
1376
14
    { &hf_frame_link_number,
1377
14
      { "Link Number", "frame.link_nr",
1378
14
        FT_UINT16, BASE_DEC, NULL, 0x0,
1379
14
        NULL, HFILL }},
1380
1381
14
    { &hf_frame_file_off,
1382
14
      { "File Offset", "frame.file_off",
1383
14
        FT_INT64, BASE_DEC, NULL, 0x0,
1384
14
        NULL, HFILL }},
1385
1386
14
    { &hf_frame_marked,
1387
14
      { "Frame is marked", "frame.marked",
1388
14
        FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1389
14
        "Frame is marked in the GUI", HFILL }},
1390
1391
14
    { &hf_frame_ignored,
1392
14
      { "Frame is ignored", "frame.ignored",
1393
14
        FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1394
14
        "Frame is ignored by the dissectors", HFILL }},
1395
1396
14
    { &hf_frame_protocols,
1397
14
      { "Protocols in frame", "frame.protocols",
1398
14
        FT_STRING, BASE_NONE, NULL, 0x0,
1399
14
        "Protocols carried by this frame", HFILL }},
1400
1401
14
    { &hf_frame_color_filter_name,
1402
14
      { "Coloring Rule Name", "frame.coloring_rule.name",
1403
14
        FT_STRING, BASE_NONE, NULL, 0x0,
1404
14
        "The frame matched the coloring rule with this name", HFILL }},
1405
1406
14
    { &hf_frame_color_filter_text,
1407
14
      { "Coloring Rule String", "frame.coloring_rule.string",
1408
14
        FT_STRING, BASE_NONE, NULL, 0x0,
1409
14
        "The frame matched this coloring rule string", HFILL }},
1410
1411
14
    { &hf_frame_section_number,
1412
14
      { "Section number", "frame.section_number",
1413
14
        FT_UINT32, BASE_DEC, NULL, 0x0,
1414
14
        "The number of the file section this frame is in", HFILL }},
1415
1416
14
    { &hf_frame_interface_id,
1417
14
      { "Interface id", "frame.interface_id",
1418
14
        FT_UINT32, BASE_DEC, NULL, 0x0,
1419
14
        NULL, HFILL }},
1420
1421
14
    { &hf_frame_interface_name,
1422
14
      { "Interface name", "frame.interface_name",
1423
14
        FT_STRING, BASE_NONE, NULL, 0x0,
1424
14
        "The friendly name for this interface", HFILL }},
1425
1426
14
    { &hf_frame_interface_description,
1427
14
      { "Interface description", "frame.interface_description",
1428
14
        FT_STRING, BASE_NONE, NULL, 0x0,
1429
14
        "The description for this interface", HFILL }},
1430
1431
14
    { &hf_frame_interface_queue,
1432
14
      { "Interface queue", "frame.interface_queue",
1433
14
        FT_UINT32, BASE_DEC, NULL, 0x0,
1434
14
        NULL, HFILL }},
1435
1436
14
    { &hf_frame_pack_flags,
1437
14
      { "Packet flags", "frame.packet_flags",
1438
14
        FT_UINT32, BASE_HEX, NULL, 0x0,
1439
14
        NULL, HFILL }},
1440
1441
14
    { &hf_frame_pack_direction,
1442
14
      { "Direction", "frame.packet_flags_direction",
1443
14
        FT_UINT32, BASE_HEX, VALS(packet_word_directions), PACK_FLAGS_DIRECTION_MASK,
1444
14
        NULL, HFILL }},
1445
1446
14
    { &hf_frame_pack_reception_type,
1447
14
      { "Reception type", "frame.packet_flags_reception_type",
1448
14
        FT_UINT32, BASE_DEC, VALS(packet_word_reception_types), PACK_FLAGS_RECEPTION_TYPE_MASK,
1449
14
        NULL, HFILL }},
1450
1451
14
    { &hf_frame_pack_fcs_length,
1452
14
      { "FCS length", "frame.packet_flags_fcs_length",
1453
14
        FT_UINT32, BASE_DEC, NULL, PACK_FLAGS_FCS_LENGTH_MASK,
1454
14
        NULL, HFILL }},
1455
1456
14
    { &hf_frame_pack_reserved,
1457
14
      { "Reserved", "frame.packet_flags_reserved",
1458
14
        FT_UINT32, BASE_DEC, NULL, PACK_FLAGS_RESERVED_MASK,
1459
14
        NULL, HFILL }},
1460
1461
14
    { &hf_frame_pack_crc_error,
1462
14
      { "CRC error", "frame.packet_flags_crc_error",
1463
14
        FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_CRC_ERROR,
1464
14
        NULL, HFILL }},
1465
1466
14
    { &hf_frame_pack_wrong_packet_too_long_error,
1467
14
      { "Packet too long error", "frame.packet_flags_packet_too_error",
1468
14
        FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_PACKET_TOO_LONG,
1469
14
        NULL, HFILL }},
1470
1471
14
    { &hf_frame_pack_wrong_packet_too_short_error,
1472
14
      { "Packet too short error", "frame.packet_flags_packet_too_short_error",
1473
14
        FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_PACKET_TOO_SHORT,
1474
14
        NULL, HFILL }},
1475
1476
14
    { &hf_frame_pack_wrong_inter_frame_gap_error,
1477
14
      { "Wrong interframe gap error", "frame.packet_flags_wrong_inter_frame_gap_error",
1478
14
        FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_WRONG_INTER_FRAME_GAP,
1479
14
        NULL, HFILL }},
1480
1481
14
    { &hf_frame_pack_unaligned_frame_error,
1482
14
      { "Unaligned frame error", "frame.packet_flags_unaligned_frame_error",
1483
14
        FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_UNALIGNED_FRAME,
1484
14
        NULL, HFILL }},
1485
1486
14
    { &hf_frame_pack_start_frame_delimiter_error,
1487
14
      { "Start frame delimiter error", "frame.packet_flags_start_frame_delimiter_error",
1488
14
        FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_START_FRAME_DELIMITER_ERROR,
1489
14
        NULL, HFILL }},
1490
1491
14
    { &hf_frame_pack_preamble_error,
1492
14
      { "Preamble error", "frame.packet_flags_preamble_error",
1493
14
        FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_PREAMBLE_ERROR,
1494
14
        NULL, HFILL }},
1495
1496
14
    { &hf_frame_pack_symbol_error,
1497
14
      { "Symbol error", "frame.packet_flags_symbol_error",
1498
14
        FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_SYMBOL_ERROR,
1499
14
        NULL, HFILL }},
1500
1501
14
    { &hf_frame_comment,
1502
14
      { "Comment", "frame.comment",
1503
14
        FT_STRING, BASE_NONE, NULL, 0x0,
1504
14
        NULL, HFILL }},
1505
1506
14
    { &hf_frame_packet_id,
1507
14
      { "Packet id", "frame.packet_id",
1508
14
        FT_UINT64, BASE_DEC, NULL, 0x0,
1509
14
        NULL, HFILL }},
1510
1511
14
    { &hf_frame_hash,
1512
14
      { "Hash Algorithm", "frame.hash",
1513
14
        FT_STRING, BASE_NONE, NULL, 0x0,
1514
14
        NULL, HFILL }},
1515
1516
14
    { &hf_frame_hash_bytes,
1517
14
      { "Hash Value", "frame.hash.value",
1518
14
        FT_BYTES, SEP_SPACE, NULL, 0x0,
1519
14
        NULL, HFILL }},
1520
1521
14
    { &hf_frame_verdict,
1522
14
      { "Verdict", "frame.verdict",
1523
14
        FT_STRING, BASE_NONE, NULL, 0x0,
1524
14
        NULL, HFILL }},
1525
1526
14
    { &hf_frame_verdict_hardware,
1527
14
      { "Hardware", "frame.verdict.hw",
1528
14
        FT_BYTES, SEP_SPACE, NULL, 0x0,
1529
14
        NULL, HFILL }},
1530
1531
14
    { &hf_frame_verdict_tc,
1532
14
      { "eBPF TC", "frame.verdict.ebpf_tc",
1533
14
        FT_INT64, BASE_DEC|BASE_VAL64_STRING,
1534
14
        VALS64(verdict_ebpf_tc_types), 0x0,
1535
14
        NULL, HFILL }},
1536
1537
14
    { &hf_frame_verdict_xdp,
1538
14
      { "eBPF XDP", "frame.verdict.ebpf_xdp",
1539
14
        FT_INT64, BASE_DEC|BASE_VAL64_STRING,
1540
14
        VALS64(verdict_ebpf_xdp_types), 0x0,
1541
14
        NULL, HFILL }},
1542
1543
14
    { &hf_frame_verdict_unknown,
1544
14
      { "Unknown", "frame.verdict.unknown",
1545
14
        FT_BYTES, SEP_SPACE, NULL, 0x0,
1546
14
        NULL, HFILL }},
1547
1548
14
    { &hf_frame_drop_count,
1549
14
      { "Drop Count", "frame.drop_count",
1550
14
        FT_UINT64, BASE_DEC, NULL, 0x0,
1551
14
        "Number of frames lost between this frame and the preceding one on the same interface", HFILL }},
1552
1553
14
    { &hf_frame_cb_pen,
1554
14
      { "Private Enterprise Number", "frame.cb_pen",
1555
14
        FT_UINT32, BASE_DEC, NULL, 0x0,
1556
14
        "IANA assigned private enterprise number (PEN)", HFILL }},
1557
1558
14
    { &hf_frame_cb_copy_allowed,
1559
14
      { "Copying", "frame.cb_copy",
1560
14
        FT_BOOLEAN, BASE_NONE, TFS(&tfs_allowed_not_allowed), 0x0,
1561
14
        "Whether the custom block will be written or not", HFILL }},
1562
1563
14
    { &hf_frame_encoding,
1564
14
      { "Character encoding", "frame.encoding",
1565
14
        FT_UINT32, BASE_DEC, VALS(packet_char_enc_types), 0x0,
1566
14
        "Character encoding (ASCII, EBCDIC...)", HFILL }},
1567
1568
14
  };
1569
1570
14
  static hf_register_info hf_encap =
1571
14
    { &hf_frame_wtap_encap,
1572
14
      { "Encapsulation type", "frame.encap_type",
1573
14
        FT_INT16, BASE_DEC, NULL, 0x0,
1574
14
        NULL, HFILL }};
1575
1576
14
  static int *ett[] = {
1577
14
    &ett_frame,
1578
14
    &ett_ifname,
1579
14
    &ett_flags,
1580
14
    &ett_comments,
1581
14
    &ett_hash,
1582
14
    &ett_verdict,
1583
14
  };
1584
1585
14
  static ei_register_info ei[] = {
1586
14
    { &ei_comments_text, { "frame.comment.expert", PI_COMMENTS_GROUP, PI_COMMENT, "Formatted comment", EXPFILL }},
1587
14
    { &ei_arrive_time_out_of_range, { "frame.time_invalid", PI_SEQUENCE, PI_NOTE, "Arrival Time: Fractional second out of range (0-999999999)", EXPFILL }},
1588
14
    { &ei_incomplete, { "frame.incomplete", PI_UNDECODED, PI_NOTE, "Incomplete dissector", EXPFILL }},
1589
14
    { &ei_len_lt_caplen, { "frame.len_lt_caplen", PI_MALFORMED, PI_ERROR, "Frame length is less than captured length", EXPFILL }}
1590
14
  };
1591
1592
14
  module_t *frame_module;
1593
14
  expert_module_t* expert_frame;
1594
1595
14
  if (hf_encap.hfinfo.strings == NULL) {
1596
14
    int encap_count = wtap_get_num_encap_types();
1597
14
    value_string *arr;
1598
14
    int i;
1599
1600
14
    hf_encap.hfinfo.strings = arr = wmem_alloc_array(wmem_epan_scope(), value_string, encap_count+1);
1601
1602
3.19k
    for (i = 0; i < encap_count; i++) {
1603
3.17k
      arr[i].value = i;
1604
3.17k
      arr[i].strptr = wtap_encap_description(i);
1605
3.17k
    }
1606
14
    arr[encap_count].value = 0;
1607
14
    arr[encap_count].strptr = NULL;
1608
14
  }
1609
1610
14
  proto_frame = proto_register_protocol("Frame", "Frame", "frame"); /* name, short name, abbreviation */
1611
14
  if (use_packets) {
1612
14
    proto_pkt_comment = proto_register_protocol_in_name_only("Packet comments", "Pkt_Comment", "pkt_comment", proto_frame, FT_PROTOCOL);
1613
14
    proto_register_alias(proto_pkt_comment, "evt_comment");
1614
14
  } else {
1615
0
    proto_pkt_comment = proto_register_protocol_in_name_only("Event comments", "Evt_Comment", "evt_comment", proto_frame, FT_PROTOCOL);
1616
0
    proto_register_alias(proto_pkt_comment, "pkt_comment");
1617
0
  }
1618
14
  proto_syscall = proto_register_protocol("System Call", "Syscall", "syscall");
1619
1620
14
  proto_register_field_array(proto_frame, hf, array_length(hf));
1621
14
  proto_register_field_array(proto_frame, &hf_encap, 1);
1622
14
  proto_register_subtree_array(ett, array_length(ett));
1623
14
  expert_frame = expert_register_protocol(proto_frame);
1624
14
  expert_register_field_array(expert_frame, ei, array_length(ei));
1625
14
  register_dissector("frame",dissect_frame,proto_frame);
1626
1627
14
  wtap_encap_dissector_table = register_dissector_table("wtap_encap",
1628
14
      "Wiretap encapsulation type", proto_frame, FT_UINT32, BASE_DEC);
1629
14
  wtap_fts_rec_dissector_table = register_dissector_table("wtap_fts_rec",
1630
14
      "Wiretap file type for file-type-specific records", proto_frame, FT_UINT32, BASE_DEC);
1631
14
  block_pen_dissector_table = register_dissector_table("pcapng_custom_block",
1632
14
      "PcapNG custom block PEN", proto_frame, FT_UINT32, BASE_DEC);
1633
14
  binary_option_pen_dissector_table = register_dissector_table("pcapng_custom_binary_option",
1634
14
      "PcapNG custom binary option PEN", proto_frame, FT_UINT32, BASE_DEC);
1635
14
  packet_block_option_dissector_table = register_dissector_table("pcapng_packet_block_option",
1636
14
      "PcapNG packet block option", proto_frame, FT_UINT32, BASE_DEC);
1637
14
  register_capture_dissector_table("wtap_encap", "Wiretap encapsulation type");
1638
1639
  /* You can't disable dissection of "Frame", as that would be
1640
     tantamount to not doing any dissection whatsoever. */
1641
14
  proto_set_cant_toggle(proto_frame);
1642
1643
14
  register_seq_analysis("any", "All Flows", proto_frame, NULL, TL_REQUIRES_COLUMNS, frame_seq_analysis_packet);
1644
1645
  /* Our preferences */
1646
14
  frame_module = prefs_register_protocol(proto_frame, NULL);
1647
14
  prefs_register_bool_preference(frame_module, "show_file_off",
1648
14
      "Show File Offset", "Show offset of frame in capture file", &show_file_off);
1649
14
  prefs_register_bool_preference(frame_module, "force_docsis_encap",
1650
14
      "Treat all frames as DOCSIS frames", "Treat all frames as DOCSIS Frames", &force_docsis_encap);
1651
14
  prefs_register_bool_preference(frame_module, "generate_md5_hash",
1652
14
      "Generate an MD5 hash of each frame",
1653
14
      "Whether or not MD5 hashes should be generated for each frame, useful for finding duplicate frames.",
1654
14
      &generate_md5_hash);
1655
14
  prefs_register_obsolete_preference(frame_module, "generate_epoch_time");
1656
14
  prefs_register_bool_preference(frame_module, "generate_bits_field",
1657
14
      "Show the number of bits in the frame",
1658
14
      "Whether or not the number of bits in the frame should be shown.",
1659
14
      &generate_bits_field);
1660
14
  prefs_register_bool_preference(frame_module, "disable_packet_size_limited_in_summary",
1661
14
      "Disable 'packet size limited during capture' message in summary",
1662
14
      "Whether or not 'packet size limited during capture' message in shown in Info column.",
1663
14
      &disable_packet_size_limited_in_summary);
1664
14
  prefs_register_uint_preference(frame_module, "max_comment_lines",
1665
14
      "Maximum number of lines to display for one packet comment",
1666
14
      "Show at most this many lines of a multi-line packet comment"
1667
14
      " (applied separately to each comment)",
1668
14
      10, &max_comment_lines);
1669
1670
14
  frame_tap=register_tap("frame");
1671
14
}
1672
1673
void
1674
proto_register_frame(void)
1675
14
{
1676
14
  common_register_frame(true);
1677
14
}
1678
1679
void
1680
event_register_frame(void)
1681
0
{
1682
0
  common_register_frame(false);
1683
0
}
1684
1685
void
1686
proto_reg_handoff_frame(void)
1687
14
{
1688
14
  docsis_handle = find_dissector_add_dependency("docsis", proto_frame);
1689
14
  darwin_handle = find_dissector_add_dependency("darwin", proto_frame);
1690
1691
14
  proto_darwin = proto_registrar_get_id_byname("darwin");
1692
14
}
1693
1694
void
1695
event_reg_handoff_frame(void)
1696
0
{
1697
0
  sysdig_handle = find_dissector_add_dependency("sysdig", proto_frame);
1698
0
  systemd_journal_handle = find_dissector_add_dependency("systemd_journal", proto_frame);
1699
0
}
1700
1701
/*
1702
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1703
 *
1704
 * Local variables:
1705
 * c-basic-offset: 8
1706
 * tab-width: 8
1707
 * indent-tabs-mode: t
1708
 * End:
1709
 *
1710
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1711
 * :indentSize=8:tabSize=8:noTabs=false:
1712
 */