Coverage Report

Created: 2026-11-12 07:01

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
#include <string.h>
15
16
#ifdef _MSC_VER
17
#include <windows.h>
18
#endif
19
20
#include <epan/packet.h>
21
#include <epan/capture_dissectors.h>
22
#include <epan/epan.h>
23
#include <epan/exceptions.h>
24
#include <epan/show_exception.h>
25
#include <epan/prefs.h>
26
#include <epan/to_str.h>
27
#include <epan/sequence_analysis.h>
28
#include <epan/tap.h>
29
#include <epan/proto_data.h>
30
#include <epan/expert.h>
31
#include <epan/tfs.h>
32
#include <wsutil/wsgcrypt.h>
33
#include <wsutil/str_util.h>
34
#include <wsutil/wslog.h>
35
#include <wsutil/ws_assert.h>
36
#include <epan/addr_resolv.h>
37
#include <epan/wmem_scopes.h>
38
#include <epan/column-info.h>
39
#include <epan/conversation_filter.h>
40
#include <wsutil/pint.h>
41
42
#include "packet-frame.h"
43
44
#include <epan/color_filters.h>
45
#include <epan/tag_rules.h>
46
47
void proto_register_frame(void);
48
void event_register_frame(void);
49
void proto_reg_handoff_frame(void);
50
void event_reg_handoff_frame(void);
51
52
static int proto_frame;
53
static int proto_pkt_comment;
54
static int proto_syscall;
55
static int proto_darwin;
56
57
static int hf_frame_arrival_time_local;
58
static int hf_frame_arrival_time_utc;
59
static int hf_frame_arrival_time_epoch;
60
static int hf_frame_shift_offset;
61
static int hf_frame_time_delta;
62
static int hf_frame_time_delta_displayed;
63
static int hf_frame_time_relative;
64
static int hf_frame_time_relative_cap;
65
static int hf_frame_time_reference;
66
static int hf_frame_number;
67
static int hf_frame_len;
68
static int hf_frame_capture_len;
69
static int hf_frame_p2p_dir;
70
static int hf_frame_file_off;
71
static int hf_frame_md5_hash;
72
static int hf_frame_marked;
73
static int hf_frame_ignored;
74
static int hf_frame_link_number;
75
static int hf_frame_packet_id;
76
static int hf_frame_process;
77
static int hf_frame_process_pid;
78
static int hf_frame_process_tid;
79
static int hf_frame_process_name;
80
static int hf_frame_process_path;
81
static int hf_frame_process_cmdline;
82
static int hf_frame_process_ppid;
83
static int hf_frame_process_uid;
84
static int hf_frame_process_user;
85
static int hf_frame_process_uuid;
86
static int hf_frame_process_start_time;
87
static int hf_frame_hash;
88
static int hf_frame_hash_bytes;
89
static int hf_frame_verdict;
90
static int hf_frame_verdict_hardware;
91
static int hf_frame_verdict_tc;
92
static int hf_frame_verdict_xdp;
93
static int hf_frame_verdict_unknown;
94
static int hf_frame_drop_count;
95
static int hf_frame_protocols;
96
static int hf_frame_color_filter_count;
97
static int hf_frame_color_filter_name;
98
static int hf_frame_color_filter_text;
99
static int hf_frame_color_filter_disabled;
100
static int hf_frame_section_number;
101
static int hf_frame_interface_id;
102
static int hf_frame_interface_name;
103
static int hf_frame_interface_description;
104
static int hf_frame_interface_queue;
105
static int hf_frame_pack_flags;
106
static int hf_frame_pack_direction;
107
static int hf_frame_pack_reception_type;
108
static int hf_frame_pack_fcs_length;
109
static int hf_frame_pack_reserved;
110
static int hf_frame_pack_crc_error;
111
static int hf_frame_pack_wrong_packet_too_long_error;
112
static int hf_frame_pack_wrong_packet_too_short_error;
113
static int hf_frame_pack_wrong_inter_frame_gap_error;
114
static int hf_frame_pack_unaligned_frame_error;
115
static int hf_frame_pack_start_frame_delimiter_error;
116
static int hf_frame_pack_preamble_error;
117
static int hf_frame_pack_symbol_error;
118
static int hf_frame_wtap_encap;
119
static int hf_frame_cb_pen;
120
static int hf_frame_cb_copy_allowed;
121
static int hf_frame_comment;
122
static int hf_frame_tags;
123
static int hf_frame_tag;
124
static int hf_frame_encoding;
125
static int hf_frame_cust_opt;
126
static int hf_frame_cust_opt_pen;
127
static int hf_frame_cust_opt_copy_allowed;
128
static int hf_frame_cust_opt_string;
129
static int hf_frame_cust_opt_data;
130
131
static int ett_frame;
132
static int ett_ifname;
133
static int ett_flags;
134
static int ett_comments;
135
static int ett_hash;
136
static int ett_verdict;
137
static int ett_process;
138
static int ett_frame_tags;
139
static int ett_frame_color_filters;
140
static int ett_frame_color_filter;
141
142
static expert_field ei_comments_text;
143
static expert_field ei_arrive_time_out_of_range;
144
static expert_field ei_incomplete;
145
static expert_field ei_len_lt_caplen;
146
147
static int frame_tap;
148
149
static dissector_handle_t docsis_handle;
150
static dissector_handle_t sysdig_handle;
151
static dissector_handle_t systemd_journal_handle;
152
static dissector_handle_t darwin_handle;
153
154
/* Preferences */
155
static bool show_file_off;
156
static bool force_docsis_encap;
157
static bool generate_md5_hash;
158
static bool generate_bits_field = true;
159
static bool disable_packet_size_limited_in_summary;
160
static unsigned max_comment_lines   = 30;
161
162
static const value_string p2p_dirs[] = {
163
  { P2P_DIR_UNKNOWN, "Unknown" },
164
  { P2P_DIR_SENT,    "Sent" },
165
  { P2P_DIR_RECV,    "Received" },
166
  { 0, NULL }
167
};
168
169
static const value_string packet_word_directions[] = {
170
  { PACK_FLAGS_DIRECTION_UNKNOWN,  "Unknown" },
171
  { PACK_FLAGS_DIRECTION_INBOUND,  "Inbound" },
172
  { PACK_FLAGS_DIRECTION_OUTBOUND, "Outbound" },
173
  { 0, NULL }
174
};
175
176
static const value_string packet_word_reception_types[] = {
177
  { PACK_FLAGS_RECEPTION_TYPE_UNSPECIFIED, "Not specified" },
178
  { PACK_FLAGS_RECEPTION_TYPE_UNICAST,     "Unicast" },
179
  { PACK_FLAGS_RECEPTION_TYPE_MULTICAST,   "Multicast" },
180
  { PACK_FLAGS_RECEPTION_TYPE_BROADCAST,   "Broadcast" },
181
  { PACK_FLAGS_RECEPTION_TYPE_PROMISCUOUS, "Promiscuous" },
182
  { 0, NULL }
183
};
184
185
static const value_string packet_char_enc_types[] = {
186
  { PACKET_CHAR_ENC_CHAR_ASCII, "ASCII" },
187
  { PACKET_CHAR_ENC_CHAR_EBCDIC, "EBCDIC" },
188
  { 0, NULL }
189
};
190
191
static const val64_string verdict_ebpf_tc_types[] = {
192
  { -1, "TC_ACT_UNSPEC"},
193
  { 0, "TC_ACT_OK"},
194
  { 1, "TC_ACT_RECLASSIFY"},
195
  { 2, "TC_ACT_SHOT"},
196
  { 3, "TC_ACT_PIPE"},
197
  { 4, "TC_ACT_STOLEN"},
198
  { 5, "TC_ACT_QUEUED"},
199
  { 6, "TC_ACT_REPEAT"},
200
  { 7, "TC_ACT_REDIRECT"},
201
  { 8, "TC_ACT_TRAP"},
202
  { 0, NULL }
203
};
204
205
static const val64_string verdict_ebpf_xdp_types[] = {
206
  { 0, "XDP_ABORTED"},
207
  { 1, "XDP_DROP"},
208
  { 2, "XDP_PASS"},
209
  { 3, "XDP_TX"},
210
  { 4, "XDP_REDIRECT"},
211
  { 0, NULL }
212
};
213
214
static dissector_table_t wtap_encap_dissector_table;
215
static dissector_table_t wtap_fts_rec_dissector_table;
216
static dissector_table_t block_pen_dissector_table;
217
static dissector_table_t binary_option_pen_dissector_table;
218
static dissector_table_t string_option_pen_dissector_table;
219
static dissector_table_t packet_block_option_dissector_table;
220
221
/* The number of tree items required to add an exception to the tree */
222
79.2k
#define EXCEPTION_TREE_ITEMS 10
223
224
/* OPT_EPB_VERDICT sub-types */
225
0
#define OPT_VERDICT_TYPE_HW  0
226
0
#define OPT_VERDICT_TYPE_TC  1
227
0
#define OPT_VERDICT_TYPE_XDP 2
228
229
/* OPT_EPB_HASH sub-types */
230
0
#define OPT_HASH_2COMP    0
231
0
#define OPT_HASH_XOR    1
232
0
#define OPT_HASH_CRC32    2
233
0
#define OPT_HASH_MD5      3
234
0
#define OPT_HASH_SHA1     4
235
0
#define OPT_HASH_TOEPLITZ 5
236
237
/* Structure for passing as userdata to wtap_block_foreach_option */
238
typedef struct fr_foreach_s {
239
  proto_item *item;
240
  proto_tree *tree;
241
  tvbuff_t *tvb;
242
  packet_info *pinfo;
243
  unsigned n_changes;
244
} fr_foreach_t;
245
246
static const char *
247
get_verdict_type_string(uint8_t type)
248
0
{
249
0
  switch(type) {
250
0
  case OPT_VERDICT_TYPE_HW:
251
0
    return "Hardware";
252
0
  case OPT_VERDICT_TYPE_TC:
253
0
    return "eBPF_TC";
254
0
  case OPT_VERDICT_TYPE_XDP:
255
0
    return "eBPF_XDP";
256
0
  }
257
0
  return "Unknown";
258
0
}
259
260
static const char *
261
get_hash_type_string(uint8_t type)
262
0
{
263
0
  switch(type) {
264
0
  case OPT_HASH_2COMP:
265
0
    return "2's Complement";
266
0
  case OPT_HASH_XOR:
267
0
    return "XOR";
268
0
  case OPT_HASH_CRC32:
269
0
    return "CRC32";
270
0
  case OPT_HASH_MD5:
271
0
    return "MD5";
272
0
  case OPT_HASH_SHA1:
273
0
    return "SHA1";
274
0
  case OPT_HASH_TOEPLITZ:
275
0
    return "Toeplitz";
276
0
  default:
277
0
    return "Unknown";
278
0
  }
279
0
}
280
281
static void
282
ensure_tree_item(proto_tree *tree, unsigned count)
283
135k
{
284
  /*
285
   * Ensure that no exception is thrown in proto.c when adding the
286
   * next tree item. Even if the maximum number of items is
287
   * reached, we know for sure that no infinite loop will occur.
288
   */
289
135k
  if (tree && PTREE_DATA(tree)->count > count)
290
134k
    PTREE_DATA(tree)->count -= count;
291
135k
}
292
293
/****************************************************************************/
294
/* whenever a frame packet is seen by the tap listener */
295
/* Add a new frame into the graph */
296
static tap_packet_status
297
frame_seq_analysis_packet( void *ptr, packet_info *pinfo, epan_dissect_t *edt _U_, const void *dummy _U_, tap_flags_t flags _U_)
298
0
{
299
0
  seq_analysis_info_t *sainfo = (seq_analysis_info_t *) ptr;
300
0
  seq_analysis_item_t *sai = sequence_analysis_create_sai_with_addresses(pinfo, sainfo);
301
302
0
  if (!sai)
303
0
    return TAP_PACKET_DONT_REDRAW;
304
305
0
  sai->frame_number = pinfo->num;
306
307
0
  sequence_analysis_use_color_filter(pinfo, sai);
308
309
0
  sai->port_src=pinfo->srcport;
310
0
  sai->port_dst=pinfo->destport;
311
312
0
  sequence_analysis_use_col_info_as_label_comment(pinfo, sai);
313
314
0
  sai->line_style = 1;
315
0
  sai->conv_num = 0;
316
0
  sai->display = true;
317
318
0
  g_queue_push_tail(sainfo->items, sai);
319
320
0
  return TAP_PACKET_REDRAW;
321
0
}
322
323
/*
324
 * Routine used to register frame end routine.  The routine should only
325
 * be registered when the dissector is used in the frame, not in the
326
 * proto_register_XXX function.
327
 */
328
void
329
register_frame_end_routine(packet_info *pinfo, void (*func)(void))
330
879
{
331
879
  pinfo->frame_end_routines = g_slist_append(pinfo->frame_end_routines, (void *)func);
332
879
}
333
334
typedef void (*void_func_t)(void);
335
336
static void
337
call_frame_end_routine(void *routine)
338
879
{
339
879
  void_func_t func = (void_func_t)routine;
340
879
  (*func)();
341
879
}
342
343
static bool
344
frame_add_comment(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t *option, void *user_data)
345
0
{
346
0
  fr_foreach_t *fr_user_data = (fr_foreach_t *)user_data;
347
0
  proto_item *comment_item;
348
0
  proto_item *hidden_item;
349
0
  proto_tree *comments_tree;
350
0
  char *newline;             /* location of next newline in comment */
351
0
  char *ch;                  /* utility pointer */
352
0
  unsigned i;                    /* track number of lines */
353
354
0
  if (option_id == OPT_COMMENT) {
355
0
    ch = option->stringval;
356
0
    newline = strchr(ch, '\n');
357
0
    if (newline == NULL) {
358
      /* Single-line comment, no special treatment needed */
359
0
      comment_item = proto_tree_add_string_format(fr_user_data->tree,
360
0
          hf_frame_comment,
361
0
          fr_user_data->tvb, 0, 0,
362
0
          ch,
363
0
          "%s", ch);
364
0
    }
365
0
    else {
366
      /* Multi-line comment. Temporarily change the first
367
       * newline to a null so we only show the first line
368
       */
369
0
      *newline = '\0';
370
0
      comment_item = proto_tree_add_string_format(fr_user_data->tree,
371
0
          hf_frame_comment,
372
0
          fr_user_data->tvb, 0, 0,
373
0
          ch,
374
0
          "%s [...]", ch);
375
0
      comments_tree = proto_item_add_subtree(comment_item, ett_comments);
376
0
      for (i = 0; i < max_comment_lines; i++) {
377
        /* Add each line as a separate item under
378
         * the comment tree
379
         */
380
0
        proto_tree_add_string_format(comments_tree, hf_frame_comment,
381
0
          fr_user_data->tvb, 0, 0,
382
0
          ch,
383
0
          "%s", ch);
384
0
        if (newline == NULL) {
385
          /* This was set in the previous loop
386
           * iteration; it means we've added the
387
           * final line
388
           */
389
0
          break;
390
0
        }
391
0
        else {
392
          /* Put back the newline we removed */
393
0
          *newline = '\n';
394
0
          ch = newline + 1;
395
0
          if (*ch == '\0') {
396
0
            break;
397
0
          }
398
          /* Find next newline to repeat the process
399
           * in the next iteration
400
           */
401
0
          newline = strchr(ch, '\n');
402
0
          if (newline != NULL) {
403
0
            *newline = '\0';
404
0
          }
405
0
        }
406
0
      }
407
0
      if (i == max_comment_lines) {
408
        /* Put back a newline if we still have one dangling */
409
0
        if (newline != NULL) {
410
0
          *newline = '\n';
411
0
        }
412
        /* Add truncation notice */
413
0
        proto_tree_add_string_format(comments_tree, hf_frame_comment,
414
0
          fr_user_data->tvb, 0, 0,
415
0
          "",
416
0
          "[comment truncated at %d line%s]",
417
0
          max_comment_lines,
418
0
          plurality(max_comment_lines, "", "s"));
419
0
      }
420
      /* Add the original comment unchanged as a hidden
421
       * item, so searches still work like before
422
       */
423
0
      hidden_item = proto_tree_add_string(comments_tree,
424
0
          hf_frame_comment,
425
0
          fr_user_data->tvb, 0, 0,
426
0
          option->stringval);
427
0
      proto_item_set_hidden(hidden_item);
428
429
0
      comment_item = comments_tree;
430
0
    }
431
0
    hidden_item = expert_add_info_format(fr_user_data->pinfo, comment_item, &ei_comments_text,
432
0
        "%s",  option->stringval);
433
0
    proto_item_set_hidden(hidden_item);
434
0
  }
435
0
  fr_user_data->n_changes++;
436
0
  return true;
437
0
}
438
439
static bool
440
frame_add_hash(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t *option, void *user_data)
441
0
{
442
0
  fr_foreach_t *fr_user_data = (fr_foreach_t *)user_data;
443
444
0
  if (option_id == OPT_PKT_HASH) {
445
0
    packet_hash_opt_t *hash = &option->packet_hash;
446
0
    const char *format
447
0
      = fr_user_data->n_changes ? ", %s (%u)" : "%s (%u)";
448
449
0
    proto_item_append_text(fr_user_data->item, format,
450
0
               get_hash_type_string(hash->type),
451
0
               hash->type);
452
453
0
    proto_tree_add_bytes_with_length(fr_user_data->tree,
454
0
             hf_frame_hash_bytes,
455
0
             fr_user_data->tvb, 0, 0,
456
0
             hash->hash_bytes->data,
457
0
             hash->hash_bytes->len);
458
0
  }
459
0
  fr_user_data->n_changes++;
460
0
  return true;
461
0
}
462
463
static bool
464
frame_add_verdict(wtap_block_t block _U_, unsigned option_id, wtap_opttype_e option_type _U_, wtap_optval_t *option, void *user_data)
465
0
{
466
0
  fr_foreach_t *fr_user_data = (fr_foreach_t *)user_data;
467
468
0
  if (option_id == OPT_PKT_VERDICT) {
469
0
    packet_verdict_opt_t *verdict = &option->packet_verdictval;
470
0
    char *format = fr_user_data->n_changes ? ", %s (%u)" : "%s (%u)";
471
472
0
    proto_item_append_text(fr_user_data->item, format,
473
0
               get_verdict_type_string(verdict->type),
474
0
               verdict->type);
475
476
0
    switch(verdict->type) {
477
0
      case OPT_VERDICT_TYPE_TC:
478
0
        proto_tree_add_int64(fr_user_data->tree,
479
0
                 hf_frame_verdict_tc,
480
0
                 fr_user_data->tvb, 0, 0,
481
0
                 verdict->data.verdict_linux_ebpf_tc);
482
0
        break;
483
0
      case OPT_VERDICT_TYPE_XDP:
484
0
        proto_tree_add_int64(fr_user_data->tree,
485
0
                 hf_frame_verdict_xdp,
486
0
                 fr_user_data->tvb, 0, 0,
487
0
                 verdict->data.verdict_linux_ebpf_xdp);
488
0
        break;
489
0
      case OPT_VERDICT_TYPE_HW:
490
0
        proto_tree_add_bytes_with_length(fr_user_data->tree,
491
0
                 hf_frame_verdict_hardware,
492
0
                 fr_user_data->tvb, 0, 0,
493
0
                 verdict->data.verdict_bytes->data,
494
0
                 verdict->data.verdict_bytes->len);
495
0
        break;
496
0
      default:
497
0
        proto_tree_add_bytes_with_length(fr_user_data->tree,
498
0
                 hf_frame_verdict_unknown,
499
0
                 fr_user_data->tvb, 0, 0,
500
0
                 verdict->data.verdict_bytes->data,
501
0
                 verdict->data.verdict_bytes->len);
502
0
        break;
503
0
    }
504
0
  }
505
0
  fr_user_data->n_changes++;
506
0
  return true;
507
0
}
508
509
struct custom_binary_opt_cb_data {
510
  tvbuff_t *tvb;
511
  packet_info *pinfo;
512
  proto_tree *tree;
513
  struct custom_binary_opt_data data;
514
};
515
516
static bool
517
handle_packet_option(wtap_block_t block _U_, unsigned option_id,
518
    wtap_opttype_e option_type _U_, wtap_optval_t *optval, void *user_data)
519
0
{
520
0
  struct custom_binary_opt_cb_data *cb_data = (struct custom_binary_opt_cb_data *)user_data;
521
0
  proto_item *ti;
522
0
  proto_tree *opt_tree;
523
524
0
  switch (option_id) {
525
526
0
  case OPT_CUSTOM_STR_COPY:
527
0
  case OPT_CUSTOM_STR_NO_COPY:
528
    /* Display it */
529
0
    cb_data->data.optval = optval;
530
0
    if (!dissector_try_uint_with_data(string_option_pen_dissector_table,
531
0
        optval->custom_stringval.pen, cb_data->tvb,
532
0
        cb_data->pinfo, cb_data->tree, false, &cb_data->data)) {
533
0
      ti = proto_tree_add_item(cb_data->tree, hf_frame_cust_opt, cb_data->tvb, 0, tvb_reported_length(cb_data->tvb), ENC_NA);
534
0
      opt_tree = proto_item_add_subtree(ti, ett_verdict);
535
0
      proto_tree_add_uint(opt_tree, hf_frame_cust_opt_pen, cb_data->tvb, 0, 0,
536
0
               optval->custom_stringval.pen);
537
0
      proto_tree_add_boolean(opt_tree, hf_frame_cust_opt_copy_allowed, cb_data->tvb, 0, 0, option_id == OPT_CUSTOM_STR_COPY);
538
0
      proto_tree_add_string(opt_tree, hf_frame_cust_opt_string, cb_data->tvb, 0, 0, optval->custom_stringval.string);
539
0
    }
540
0
    break;
541
542
0
  case OPT_CUSTOM_BIN_COPY:
543
0
  case OPT_CUSTOM_BIN_NO_COPY:
544
    /* Process it */
545
0
    cb_data->data.optval = optval;
546
0
    if (!dissector_try_uint_with_data(binary_option_pen_dissector_table,
547
0
        optval->custom_binaryval.pen, cb_data->tvb,
548
0
        cb_data->pinfo, cb_data->tree, false, &cb_data->data)) {
549
550
0
      ti = proto_tree_add_item(cb_data->tree, hf_frame_cust_opt, cb_data->tvb, 0, tvb_reported_length(cb_data->tvb), ENC_NA);
551
0
      opt_tree = proto_item_add_subtree(ti, ett_verdict);
552
0
      proto_tree_add_uint(opt_tree, hf_frame_cust_opt_pen, cb_data->tvb, 0, 0,
553
0
               optval->custom_binaryval.pen);
554
0
      proto_tree_add_boolean(opt_tree, hf_frame_cust_opt_copy_allowed, cb_data->tvb, 0, 0, option_id == OPT_CUSTOM_BIN_COPY);
555
0
      proto_tree_add_bytes_with_length(opt_tree, hf_frame_cust_opt_data, cb_data->tvb, 0, 0, optval->custom_binaryval.data.custom_data, (unsigned)optval->custom_binaryval.data.custom_data_len);
556
557
0
    }
558
0
    break;
559
560
0
  default:
561
0
    dissector_try_uint_with_data(packet_block_option_dissector_table,
562
0
      option_id, cb_data->tvb,
563
0
      cb_data->pinfo, cb_data->tree, false, optval);
564
0
    break;
565
0
  }
566
567
0
  return true;
568
0
}
569
570
/* Conversation (temporary) coloring rules are never listed. With "details"
571
 * every other matching rule is listed; otherwise the rule that colors the
572
 * frame and the disabled matches, which exist only while
573
 * gui.coloring_rules_include_disabled is set. */
574
static bool
575
color_filter_entry_shown(const color_filter_t *colorf,
576
                         const color_filter_t *primary, bool details)
577
0
{
578
0
  if (color_filter_is_tmp(colorf))
579
0
    return false;
580
0
  return details || colorf == primary || !colorf->enabled;
581
0
}
582
583
/* A single listed rule keeps the flat items directly under the Frame item. */
584
static void
585
add_color_filter_flat(proto_tree *tree, tvbuff_t *tvb, const color_filter_t *colorf)
586
0
{
587
0
  proto_item *item;
588
589
0
  ensure_tree_item(tree, 1);
590
0
  item = proto_tree_add_string(tree, hf_frame_color_filter_name, tvb,
591
0
                               0, 0, colorf->filter_name);
592
0
  proto_item_set_generated(item);
593
594
0
  ensure_tree_item(tree, 1);
595
0
  item = proto_tree_add_string(tree, hf_frame_color_filter_text, tvb,
596
0
                               0, 0, colorf->filter_text);
597
0
  proto_item_set_generated(item);
598
599
0
  if (!colorf->enabled) {
600
0
    ensure_tree_item(tree, 1);
601
0
    item = proto_tree_add_boolean(tree, hf_frame_color_filter_disabled, tvb,
602
0
                                  0, 0, true);
603
0
    proto_item_set_generated(item);
604
0
  }
605
0
}
606
607
/* One of several listed rules: the name item shows only the rule name and
608
 * holds the filter string and, for a disabled rule, the disabled flag. */
609
static void
610
add_color_filter_nested(proto_tree *tree, tvbuff_t *tvb, const color_filter_t *colorf)
611
0
{
612
0
  proto_item *item;
613
0
  proto_tree *rule_tree;
614
615
0
  ensure_tree_item(tree, 1);
616
0
  item = proto_tree_add_string_format(tree, hf_frame_color_filter_name, tvb,
617
0
                                      0, 0, colorf->filter_name, "%s",
618
0
                                      colorf->filter_name);
619
0
  proto_item_set_generated(item);
620
0
  rule_tree = proto_item_add_subtree(item, ett_frame_color_filter);
621
622
0
  ensure_tree_item(rule_tree, 1);
623
0
  item = proto_tree_add_string_format(rule_tree, hf_frame_color_filter_text, tvb,
624
0
                                      0, 0, colorf->filter_text,
625
0
                                      "Filter String: %s", colorf->filter_text);
626
0
  proto_item_set_generated(item);
627
628
0
  if (!colorf->enabled) {
629
0
    ensure_tree_item(rule_tree, 1);
630
0
    item = proto_tree_add_boolean_format(rule_tree, hf_frame_color_filter_disabled,
631
0
                                         tvb, 0, 0, true, "Disabled: %s",
632
0
                                         tfs_get_true_false(true));
633
0
    proto_item_set_generated(item);
634
0
  }
635
0
}
636
637
/* Key of the per-packet data holding the process ID, for the conversation filter. */
638
0
#define FRAME_PROCESS_ID_KEY 1
639
640
/*
641
 * Add the process and thread IDs from one pcapng epb_processid_threadid
642
 * option, and what the file's process information says about the
643
 * process.  wiretap stores the option as a 64-bit value with the process
644
 * ID in the upper 32 bits and the thread ID in the lower 32 bits; an ID
645
 * of 0 means that it is not available.
646
 *
647
 * The tree may be NULL; if this is the packet's first process, its ID is
648
 * remembered for the conversation filter, and its user name is set for
649
 * the user name column, regardless.
650
 */
651
static void
652
frame_add_process(proto_tree *fh_tree, tvbuff_t *tvb, packet_info *pinfo, uint64_t procid_threadid, bool first)
653
0
{
654
0
  uint32_t pid, tid, process_info_id, ppid, uid;
655
0
  unsigned section_number;
656
0
  bool have_info = false;
657
0
  const char *name = NULL, *path, *user;
658
0
  const uint8_t *cmdline, *uuid;
659
0
  size_t cmdline_size, uuid_size;
660
0
  nstime_t start_time;
661
0
  proto_item *process_item, *item;
662
0
  proto_tree *process_tree;
663
664
0
  pid = (uint32_t)(procid_threadid >> 32);
665
0
  tid = (uint32_t)procid_threadid;
666
0
  section_number = pinfo->rec->presence_flags & WTAP_HAS_SECTION_NUMBER ? pinfo->rec->section_number : 0;
667
668
0
  if (pid != 0) {
669
0
    if (first)
670
0
      p_add_proto_data(pinfo->pool, pinfo, proto_frame, FRAME_PROCESS_ID_KEY, GUINT_TO_POINTER(pid));
671
672
    /*
673
     * Look the process up, using the time stamp of the packet
674
     * to tell apart processes that reused the ID.
675
     */
676
0
    have_info = epan_find_process_info(pinfo->epan, pid, section_number,
677
0
        (pinfo->presence_flags & PINFO_HAS_TS) ? &pinfo->abs_ts : NULL,
678
0
        pinfo->fd->file_off, &process_info_id);
679
0
    if (have_info) {
680
0
      name = epan_get_process_name(pinfo->epan, process_info_id, section_number);
681
0
      if (first)
682
0
        pinfo->user_name = epan_get_process_user_name(pinfo->epan, process_info_id, section_number);
683
0
    }
684
0
    col_append_sep_fstr(pinfo->cinfo, COL_PROCESS_ID, ",", "%u", pid);
685
0
    if (name != NULL)
686
0
      col_append_sep_str(pinfo->cinfo, COL_PROCESS_NAME, ",", name);
687
0
  }
688
689
0
  if (fh_tree == NULL)
690
0
    return;
691
692
0
  if (name != NULL) {
693
0
    process_item = proto_tree_add_none_format(fh_tree, hf_frame_process, tvb, 0, 0,
694
0
        "Process information: PID %u (%s), TID %u", pid, name, tid);
695
0
  } else {
696
0
    process_item = proto_tree_add_none_format(fh_tree, hf_frame_process, tvb, 0, 0,
697
0
        "Process information: PID %u, TID %u", pid, tid);
698
0
  }
699
0
  process_tree = proto_item_add_subtree(process_item, ett_process);
700
0
  item = proto_tree_add_uint(process_tree, hf_frame_process_pid, tvb, 0, 0, pid);
701
0
  if (pid == 0)
702
0
    proto_item_append_text(item, " (not available)");
703
0
  item = proto_tree_add_uint(process_tree, hf_frame_process_tid, tvb, 0, 0, tid);
704
0
  if (tid == 0)
705
0
    proto_item_append_text(item, " (not available)");
706
707
0
  if (!have_info)
708
0
    return;
709
710
0
  if (name != NULL) {
711
0
    item = proto_tree_add_string(process_tree, hf_frame_process_name, tvb, 0, 0, name);
712
0
    proto_item_set_generated(item);
713
0
  }
714
0
  path = epan_get_process_path(pinfo->epan, process_info_id, section_number);
715
0
  if (path != NULL) {
716
0
    item = proto_tree_add_string(process_tree, hf_frame_process_path, tvb, 0, 0, path);
717
0
    proto_item_set_generated(item);
718
0
  }
719
0
  cmdline = epan_get_process_cmdline(pinfo->epan, process_info_id, section_number, &cmdline_size);
720
0
  if (cmdline != NULL) {
721
    /* The arguments are separated by NULs; show them separated by spaces. */
722
0
    char *cmdline_str = (char *)wmem_alloc(pinfo->pool, cmdline_size + 1);
723
0
    size_t i;
724
725
0
    for (i = 0; i < cmdline_size; i++)
726
0
      cmdline_str[i] = cmdline[i] == '\0' ? ' ' : cmdline[i];
727
0
    cmdline_str[cmdline_size] = '\0';
728
0
    item = proto_tree_add_string(process_tree, hf_frame_process_cmdline, tvb, 0, 0, cmdline_str);
729
0
    proto_item_set_generated(item);
730
0
  }
731
0
  if (epan_get_process_parent_id(pinfo->epan, process_info_id, section_number, &ppid)) {
732
0
    item = proto_tree_add_uint(process_tree, hf_frame_process_ppid, tvb, 0, 0, ppid);
733
0
    proto_item_set_generated(item);
734
0
  }
735
0
  if (epan_get_process_user_id(pinfo->epan, process_info_id, section_number, &uid)) {
736
0
    item = proto_tree_add_uint(process_tree, hf_frame_process_uid, tvb, 0, 0, uid);
737
0
    proto_item_set_generated(item);
738
0
  }
739
0
  user = epan_get_process_user_name(pinfo->epan, process_info_id, section_number);
740
0
  if (user != NULL) {
741
0
    item = proto_tree_add_string(process_tree, hf_frame_process_user, tvb, 0, 0, user);
742
0
    proto_item_set_generated(item);
743
0
  }
744
0
  uuid = epan_get_process_uuid(pinfo->epan, process_info_id, section_number, &uuid_size);
745
0
  if (uuid != NULL && uuid_size == 16) {
746
0
    e_guid_t guid;
747
748
0
    guid.data1 = pntohu32(uuid);
749
0
    guid.data2 = pntohu16(uuid + 4);
750
0
    guid.data3 = pntohu16(uuid + 6);
751
0
    memcpy(guid.data4, uuid + 8, sizeof guid.data4);
752
0
    item = proto_tree_add_guid(process_tree, hf_frame_process_uuid, tvb, 0, 0, &guid);
753
0
    proto_item_set_generated(item);
754
0
  }
755
0
  if (epan_get_process_start_time(pinfo->epan, process_info_id, section_number, &start_time)) {
756
0
    item = proto_tree_add_time(process_tree, hf_frame_process_start_time, tvb, 0, 0, &start_time);
757
0
    proto_item_set_generated(item);
758
0
  }
759
0
}
760
761
/*
762
 * Add the processes the packet belongs to.  A packet can have several
763
 * epb_processid_threadid options, one for each process that could have
764
 * sent or received it, e.g. every process that has the socket open, or
765
 * the sender and the receivers of a multicast datagram on the capturing
766
 * host.
767
 */
768
static void
769
frame_add_process_info(proto_tree *fh_tree, tvbuff_t *tvb, packet_info *pinfo, wtap_block_t pkt_block)
770
124k
{
771
124k
  unsigned count = wtap_block_count_option(pkt_block, OPT_PKT_PROCIDTHRDID);
772
773
124k
  for (unsigned n = 0; n < count; n++) {
774
0
    uint64_t procid_threadid;
775
776
0
    if (wtap_block_get_nth_uint64_option_value(pkt_block, OPT_PKT_PROCIDTHRDID, n, &procid_threadid) != WTAP_OPTTYPE_SUCCESS)
777
0
      break;
778
0
    frame_add_process(fh_tree, tvb, pinfo, procid_threadid, n == 0);
779
0
  }
780
124k
}
781
782
static bool
783
frame_process_filter_valid(packet_info *pinfo, void *user_data _U_)
784
0
{
785
0
  return p_get_proto_data(pinfo->pool, pinfo, proto_frame, FRAME_PROCESS_ID_KEY) != NULL;
786
0
}
787
788
static char *
789
frame_process_build_filter(packet_info *pinfo, void *user_data _U_)
790
0
{
791
0
  return ws_strdup_printf("frame.process.pid == %u",
792
0
      GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_frame, FRAME_PROCESS_ID_KEY)));
793
0
}
794
795
static int
796
dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
797
124k
{
798
124k
  proto_item  *volatile ti = NULL;
799
124k
  unsigned     cap_len = 0, frame_len = 0;
800
124k
  nstime_t     rel_ts;
801
124k
  uint32_t     pack_flags;
802
124k
  uint32_t     interface_queue;
803
124k
  uint64_t     drop_count;
804
124k
  uint64_t     packetid;
805
124k
  proto_tree  *volatile tree;
806
124k
  proto_tree  *comments_tree;
807
124k
  proto_tree  *volatile fh_tree = NULL;
808
124k
  proto_item  *item;
809
124k
  const char *cap_plurality, *frame_plurality;
810
124k
  frame_data_t *fr_data = (frame_data_t*)data;
811
124k
  const color_filter_t *color_filter;
812
124k
  dissector_handle_t dissector_handle;
813
124k
  fr_foreach_t fr_user_data;
814
815
124k
  tree=parent_tree;
816
817
124k
  if (!fr_data) {
818
0
    return 0;
819
0
  }
820
821
  /*
822
   * Set the protocol to the record type name.
823
   */
824
124k
  pinfo->current_proto = pinfo->rec->rec_type_name;
825
124k
  col_set_str(pinfo->cinfo, COL_PROTOCOL, pinfo->rec->rec_type_name);
826
827
124k
  if (wtap_block_count_option(fr_data->pkt_block, OPT_COMMENT) > 0) {
828
0
    TRY {
829
#ifdef _MSC_VER
830
      /* Win32: Visual-C Structured Exception Handling (SEH)
831
         to trap hardware exceptions like memory access violations */
832
      /* (a running debugger will be called before the except part below) */
833
      /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
834
         stack in an inconsistent state thus causing a crash at some point in the
835
         handling of the exception.
836
         See: https://lists.wireshark.org/archives/wireshark-dev/200704/msg00243.html
837
      */
838
      __try {
839
#endif
840
0
        item = proto_tree_add_item(tree, proto_pkt_comment, tvb, 0, 0, ENC_NA);
841
0
        comments_tree = proto_item_add_subtree(item, ett_comments);
842
0
        fr_user_data.item = item;
843
0
        fr_user_data.tree = comments_tree;
844
0
        fr_user_data.pinfo = pinfo;
845
0
        fr_user_data.tvb = tvb;
846
0
        fr_user_data.n_changes = 0;
847
0
        wtap_block_foreach_option(fr_data->pkt_block, frame_add_comment, (void *)&fr_user_data);
848
#ifdef _MSC_VER
849
      } __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
850
        ensure_tree_item(parent_tree, EXCEPTION_TREE_ITEMS);
851
        switch (GetExceptionCode()) {
852
        case(STATUS_ACCESS_VIOLATION):
853
          show_exception(tvb, pinfo, parent_tree, DissectorError,
854
                   "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
855
          break;
856
        case(STATUS_INTEGER_DIVIDE_BY_ZERO):
857
          show_exception(tvb, pinfo, parent_tree, DissectorError,
858
                   "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
859
          break;
860
        case(STATUS_STACK_OVERFLOW):
861
          show_exception(tvb, pinfo, parent_tree, DissectorError,
862
                   "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
863
          /* XXX - this will have probably corrupted the stack,
864
             which makes problems later in the exception code */
865
          break;
866
          /* XXX - add other hardware exception codes as required */
867
        default:
868
          show_exception(tvb, pinfo, parent_tree, DissectorError,
869
                   ws_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
870
        }
871
      }
872
#endif
873
0
    }
874
0
    CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
875
0
      ensure_tree_item(parent_tree, EXCEPTION_TREE_ITEMS);
876
0
      show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
877
0
    }
878
0
    ENDTRY;
879
0
  }
880
881
124k
  cap_len = tvb_captured_length(tvb);
882
124k
  frame_len = tvb_reported_length(tvb);
883
884
  /* If FRAME is not referenced from any filters we don't need to
885
     worry about generating any tree items.
886
887
     We do, however, have to worry about generating expert infos,
888
     as those have to show up if, for example, the user requests
889
     the expert info dialog.
890
891
     Therefore, the dissection code has to be careful about
892
     what stuff it does only if do_frame_dissection is true.
893
894
     XXX - all these tricks to optimize dissection if only some
895
     information is required are fragile.  Something better that
896
     handles this automatically would be useful. */
897
124k
  bool do_frame_dissection = proto_field_is_referenced(tree, proto_frame);
898
124k
  cap_plurality = plurality(cap_len, "", "s");
899
124k
  frame_plurality = plurality(frame_len, "", "s");
900
901
  /* Put in frame header information. */
902
124k
  if (do_frame_dissection) {
903
55.8k
    ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, tvb_captured_length(tvb),
904
55.8k
        "Frame %u: %s", pinfo->num, pinfo->rec->rec_type_name);
905
69.0k
  } else {
906
69.0k
    ti = NULL;
907
69.0k
  }
908
124k
  switch (pinfo->rec->rec_type) {
909
910
124k
  case REC_TYPE_PACKET:
911
124k
    if (do_frame_dissection) {
912
55.8k
      proto_item_append_text(ti, ", %u byte%s on wire",
913
55.8k
          frame_len, frame_plurality);
914
55.8k
      if (generate_bits_field)
915
55.8k
        proto_item_append_text(ti, " (%u bits)", frame_len * 8);
916
55.8k
      proto_item_append_text(ti, ", %u byte%s captured",
917
55.8k
          cap_len, cap_plurality);
918
55.8k
      if (generate_bits_field) {
919
55.8k
        proto_item_append_text(ti, " (%u bits)",
920
55.8k
            cap_len * 8);
921
55.8k
      }
922
55.8k
      if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID) {
923
0
        const char *interface_name = epan_get_interface_name(pinfo->epan,
924
0
            pinfo->rec->rec_header.packet_header.interface_id,
925
0
            pinfo->rec->presence_flags & WTAP_HAS_SECTION_NUMBER ? pinfo->rec->section_number : 0);
926
0
        if (interface_name != NULL) {
927
0
          proto_item_append_text(ti, " on interface %s, id %u",
928
0
              interface_name, pinfo->rec->rec_header.packet_header.interface_id);
929
0
        } else {
930
0
          proto_item_append_text(ti, " on unnamed interface, id %u",
931
0
              pinfo->rec->rec_header.packet_header.interface_id);
932
0
        }
933
0
      }
934
55.8k
    }
935
124k
    if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_uint32_option_value(fr_data->pkt_block, OPT_PKT_FLAGS, &pack_flags)) {
936
0
      switch (PACK_FLAGS_DIRECTION(pack_flags)) {
937
938
0
      case PACK_FLAGS_DIRECTION_UNKNOWN:
939
0
      default:
940
0
        pinfo->p2p_dir = P2P_DIR_UNKNOWN;
941
0
        break;
942
943
0
      case PACK_FLAGS_DIRECTION_INBOUND:
944
0
        pinfo->p2p_dir = P2P_DIR_RECV;
945
0
        if (do_frame_dissection)
946
0
          proto_item_append_text(ti, " (inbound)");
947
0
        break;
948
949
0
      case PACK_FLAGS_DIRECTION_OUTBOUND:
950
0
        pinfo->p2p_dir = P2P_DIR_SENT;
951
0
        if (do_frame_dissection)
952
0
          proto_item_append_text(ti, " (outbound)");
953
0
        break;
954
0
      }
955
0
    }
956
957
    /*
958
     * If the pseudo-header *and* the packet record both
959
     * have direction information, the pseudo-header
960
     * overrides the packet record.
961
     */
962
124k
    if (pinfo->pseudo_header != NULL) {
963
124k
      switch (pinfo->rec->rec_header.packet_header.pkt_encap) {
964
965
0
      case WTAP_ENCAP_WFLEET_HDLC:
966
0
      case WTAP_ENCAP_CHDLC_WITH_PHDR:
967
0
      case WTAP_ENCAP_PPP_WITH_PHDR:
968
0
      case WTAP_ENCAP_SDLC:
969
0
      case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR:
970
0
        pinfo->p2p_dir = pinfo->pseudo_header->p2p.sent ?
971
0
            P2P_DIR_SENT : P2P_DIR_RECV;
972
0
        break;
973
974
0
      case WTAP_ENCAP_BLUETOOTH_HCI:
975
0
        pinfo->p2p_dir = pinfo->pseudo_header->bthci.sent ?
976
0
          P2P_DIR_SENT : P2P_DIR_RECV;
977
0
        break;
978
979
0
      case WTAP_ENCAP_LAPB:
980
0
      case WTAP_ENCAP_FRELAY_WITH_PHDR:
981
0
        pinfo->p2p_dir =
982
0
            (pinfo->pseudo_header->dte_dce.flags & FROM_DCE) ?
983
0
            P2P_DIR_RECV : P2P_DIR_SENT;
984
0
        break;
985
986
0
      case WTAP_ENCAP_ISDN:
987
0
      case WTAP_ENCAP_V5_EF:
988
0
      case WTAP_ENCAP_DPNSS:
989
0
      case WTAP_ENCAP_BACNET_MS_TP_WITH_PHDR:
990
0
        pinfo->p2p_dir = pinfo->pseudo_header->isdn.uton ?
991
0
            P2P_DIR_SENT : P2P_DIR_RECV;
992
0
        break;
993
994
0
      case WTAP_ENCAP_LINUX_LAPD:
995
0
        pinfo->p2p_dir = (pinfo->pseudo_header->lapd.pkttype == 3 ||
996
0
          pinfo->pseudo_header->lapd.pkttype == 4) ?
997
0
          P2P_DIR_SENT : P2P_DIR_RECV;
998
0
        break;
999
1000
0
      case WTAP_ENCAP_MTP2_WITH_PHDR:
1001
0
        pinfo->p2p_dir = pinfo->pseudo_header->mtp2.sent ?
1002
0
            P2P_DIR_SENT : P2P_DIR_RECV;
1003
0
        pinfo->link_number  = pinfo->pseudo_header->mtp2.link_number;
1004
0
        break;
1005
1006
0
      case WTAP_ENCAP_GSM_UM:
1007
0
        pinfo->p2p_dir = pinfo->pseudo_header->gsm_um.uplink ?
1008
0
            P2P_DIR_SENT : P2P_DIR_RECV;
1009
0
        break;
1010
124k
      }
1011
124k
    }
1012
124k
    break;
1013
1014
124k
  case REC_TYPE_FT_SPECIFIC_EVENT:
1015
0
    break;
1016
1017
0
  case REC_TYPE_FT_SPECIFIC_REPORT:
1018
0
    break;
1019
1020
0
  case REC_TYPE_SYSCALL:
1021
0
    if (do_frame_dissection) {
1022
      /*
1023
       * This gives us a top-of-tree "syscall" protocol
1024
       * with "frame" fields underneath. Should we create
1025
       * corresponding syscall.time, .time_epoch, etc
1026
       * fields and use them instead or would frame.*
1027
       * be preferred?
1028
       *
1029
       * XXX - is this length value relevant?
1030
       */
1031
0
      proto_item_append_text(ti, ", %u byte%s",
1032
0
          frame_len, frame_plurality);
1033
0
    }
1034
0
    break;
1035
1036
0
  case REC_TYPE_SYSTEMD_JOURNAL_EXPORT:
1037
0
    if (do_frame_dissection) {
1038
      /*
1039
       * XXX - we need to rethink what's handled by
1040
       * packet-record.c, what's handled by packet-frame.c.
1041
       * and what's handled by the syscall and systemd
1042
       * journal dissectors (and maybe even the packet
1043
       * dissector).
1044
       *
1045
       * XXX - is this length value relevant?
1046
       */
1047
0
      proto_item_append_text(ti, ", %u byte%s",
1048
0
          frame_len, frame_plurality);
1049
0
    }
1050
0
    break;
1051
1052
0
  case REC_TYPE_CUSTOM_BLOCK:
1053
0
    if (do_frame_dissection) {
1054
0
      proto_item_append_text(ti, ", %u byte%s",
1055
0
          frame_len, frame_plurality);
1056
0
      proto_item_append_text(ti, ", copying%s allowed",
1057
0
                             pinfo->rec->rec_header.custom_block_header.copy_allowed ? "" : " not");
1058
0
    }
1059
0
    break;
1060
1061
0
  default:
1062
0
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
1063
0
    col_add_fstr(pinfo->cinfo, COL_INFO, "Record type %u",
1064
0
        pinfo->rec->rec_type);
1065
0
    call_data_dissector(tvb, pinfo, parent_tree);
1066
0
    return tvb_captured_length(tvb);
1067
124k
  }
1068
1069
124k
  if (do_frame_dissection) {
1070
55.8k
    fh_tree = proto_item_add_subtree(ti, ett_frame);
1071
69.0k
  } else {
1072
69.0k
    fh_tree = NULL;
1073
69.0k
  }
1074
1075
124k
  if (pinfo->rec->presence_flags & WTAP_HAS_SECTION_NUMBER &&
1076
0
      do_frame_dissection &&
1077
0
      (proto_field_is_referenced(tree, hf_frame_section_number))) {
1078
    /* Show it as 1-origin */
1079
0
    proto_tree_add_uint(fh_tree, hf_frame_section_number, tvb,
1080
0
            0, 0, pinfo->rec->section_number + 1);
1081
0
  }
1082
1083
124k
  if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID &&
1084
0
      do_frame_dissection &&
1085
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)))) {
1086
0
    unsigned section_number = pinfo->rec->presence_flags & WTAP_HAS_SECTION_NUMBER ? pinfo->rec->section_number : 0;
1087
0
    const char *interface_name = epan_get_interface_name(pinfo->epan, pinfo->rec->rec_header.packet_header.interface_id, section_number);
1088
0
    const char *interface_description = epan_get_interface_description(pinfo->epan, pinfo->rec->rec_header.packet_header.interface_id, section_number);
1089
0
    proto_tree *if_tree;
1090
0
    proto_item *if_item;
1091
1092
0
    if (interface_name) {
1093
0
      if_item = proto_tree_add_uint_format_value(fh_tree, hf_frame_interface_id, tvb, 0, 0,
1094
0
                   pinfo->rec->rec_header.packet_header.interface_id, "%u (%s)",
1095
0
                   pinfo->rec->rec_header.packet_header.interface_id, interface_name);
1096
0
      if_tree = proto_item_add_subtree(if_item, ett_ifname);
1097
0
      proto_tree_add_string(if_tree, hf_frame_interface_name, tvb, 0, 0, interface_name);
1098
0
    } else {
1099
0
      if_item = proto_tree_add_uint(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->rec->rec_header.packet_header.interface_id);
1100
0
    }
1101
1102
0
    if (interface_description) {
1103
0
      if_tree = proto_item_add_subtree(if_item, ett_ifname);
1104
0
      proto_tree_add_string(if_tree, hf_frame_interface_description, tvb, 0, 0, interface_description);
1105
0
    }
1106
0
  }
1107
1108
124k
  if (pinfo->rec->rec_type == REC_TYPE_PACKET) {
1109
124k
    if (do_frame_dissection) {
1110
55.8k
      if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_uint32_option_value(fr_data->pkt_block, OPT_PKT_QUEUE, &interface_queue)) {
1111
0
        proto_tree_add_uint(fh_tree, hf_frame_interface_queue, tvb, 0, 0, interface_queue);
1112
0
      }
1113
1114
55.8k
      if (wtap_block_count_option(fr_data->pkt_block, OPT_PKT_HASH) > 0) {
1115
0
        proto_tree *hash_tree;
1116
0
        proto_item *hash_item;
1117
1118
0
        hash_item = proto_tree_add_string(fh_tree, hf_frame_hash, tvb, 0, 0, "");
1119
0
        hash_tree = proto_item_add_subtree(hash_item, ett_hash);
1120
0
        fr_user_data.item = hash_item;
1121
0
        fr_user_data.tree = hash_tree;
1122
0
        fr_user_data.pinfo = pinfo;
1123
0
        fr_user_data.tvb = tvb;
1124
0
        fr_user_data.n_changes = 0;
1125
0
        wtap_block_foreach_option(fr_data->pkt_block, frame_add_hash, (void *)&fr_user_data);
1126
0
      }
1127
1128
55.8k
      if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_uint32_option_value(fr_data->pkt_block, OPT_PKT_FLAGS, &pack_flags)) {
1129
0
        proto_tree *flags_tree;
1130
0
        proto_item *flags_item;
1131
0
        static int * const flags[] = {
1132
0
          &hf_frame_pack_direction,
1133
0
          &hf_frame_pack_reception_type,
1134
0
          &hf_frame_pack_fcs_length,
1135
0
          &hf_frame_pack_reserved,
1136
0
          &hf_frame_pack_crc_error,
1137
0
          &hf_frame_pack_wrong_packet_too_long_error,
1138
0
          &hf_frame_pack_wrong_packet_too_short_error,
1139
0
          &hf_frame_pack_wrong_inter_frame_gap_error,
1140
0
          &hf_frame_pack_unaligned_frame_error,
1141
0
          &hf_frame_pack_start_frame_delimiter_error,
1142
0
          &hf_frame_pack_preamble_error,
1143
0
          &hf_frame_pack_symbol_error,
1144
0
          NULL
1145
0
        };
1146
1147
0
        flags_item = proto_tree_add_uint(fh_tree, hf_frame_pack_flags, tvb, 0, 0, pack_flags);
1148
0
        flags_tree = proto_item_add_subtree(flags_item, ett_flags);
1149
0
        proto_tree_add_bitmask_list_value(flags_tree, tvb, 0, 0, flags, pack_flags);
1150
0
      }
1151
1152
55.8k
      if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_uint64_option_value(fr_data->pkt_block, OPT_PKT_PACKETID, &packetid)) {
1153
0
        proto_tree_add_uint64(fh_tree, hf_frame_packet_id, tvb, 0, 0, packetid);
1154
0
      }
1155
1156
55.8k
      if (wtap_block_count_option(fr_data->pkt_block, OPT_PKT_VERDICT) > 0) {
1157
0
        proto_tree *verdict_tree;
1158
0
        proto_item *verdict_item;
1159
1160
0
        verdict_item = proto_tree_add_string(fh_tree, hf_frame_verdict, tvb, 0, 0, "");
1161
0
        verdict_tree = proto_item_add_subtree(verdict_item, ett_verdict);
1162
0
        fr_user_data.item = verdict_item;
1163
0
        fr_user_data.tree = verdict_tree;
1164
0
        fr_user_data.pinfo = pinfo;
1165
0
        fr_user_data.tvb = tvb;
1166
0
        fr_user_data.n_changes = 0;
1167
0
        wtap_block_foreach_option(fr_data->pkt_block, frame_add_verdict, (void *)&fr_user_data);
1168
0
      }
1169
1170
55.8k
      proto_tree_add_int(fh_tree, hf_frame_wtap_encap, tvb, 0, 0, pinfo->rec->rec_header.packet_header.pkt_encap);
1171
55.8k
    }
1172
1173
    /*
1174
     * Done whether or not we're building the frame tree, as it
1175
     * also supplies the user name column and the conversation
1176
     * filter.
1177
     */
1178
124k
    frame_add_process_info(fh_tree, tvb, pinfo, fr_data->pkt_block);
1179
124k
  }
1180
1181
124k
  if (pinfo->presence_flags & PINFO_HAS_TS) {
1182
124k
    if (do_frame_dissection) {
1183
55.8k
      proto_tree_add_time(fh_tree, hf_frame_arrival_time_local, tvb, 0, 0, &pinfo->abs_ts);
1184
55.8k
      proto_tree_add_time(fh_tree, hf_frame_arrival_time_utc, tvb, 0, 0, &pinfo->abs_ts);
1185
55.8k
      proto_tree_add_time(fh_tree, hf_frame_arrival_time_epoch, tvb, 0, 0, &pinfo->abs_ts);
1186
55.8k
    }
1187
124k
    if (pinfo->abs_ts.nsecs < 0 || pinfo->abs_ts.nsecs >= 1000000000) {
1188
0
      expert_add_info_format(pinfo, ti, &ei_arrive_time_out_of_range,
1189
0
                "Arrival Time: Fractional second %09ld is invalid,"
1190
0
                " the valid range is 0-999999999",
1191
0
                (long) pinfo->abs_ts.nsecs);
1192
0
    }
1193
124k
    if (do_frame_dissection) {
1194
55.8k
      item = proto_tree_add_time(fh_tree, hf_frame_shift_offset, tvb,
1195
55.8k
              0, 0, &(pinfo->fd->shift_offset));
1196
55.8k
      proto_item_set_generated(item);
1197
1198
55.8k
      if (proto_field_is_referenced(tree, hf_frame_time_delta)) {
1199
55.8k
        nstime_t     del_cap_ts;
1200
1201
55.8k
        if (frame_delta_time_prev_captured(pinfo->epan, pinfo->fd, &del_cap_ts)) {
1202
55.8k
          item = proto_tree_add_time(fh_tree, hf_frame_time_delta, tvb,
1203
55.8k
                   0, 0, &(del_cap_ts));
1204
55.8k
          proto_item_set_generated(item);
1205
55.8k
        }
1206
55.8k
      }
1207
1208
55.8k
      if (proto_field_is_referenced(tree, hf_frame_time_delta_displayed)) {
1209
55.8k
        nstime_t del_dis_ts;
1210
1211
55.8k
        if (frame_delta_time_prev_displayed(pinfo->epan, pinfo->fd, &del_dis_ts)) {
1212
0
          item = proto_tree_add_time(fh_tree, hf_frame_time_delta_displayed, tvb,
1213
0
                   0, 0, &(del_dis_ts));
1214
0
          proto_item_set_generated(item);
1215
0
        }
1216
55.8k
      }
1217
1218
55.8k
      if (frame_rel_time(pinfo->epan, pinfo->fd, &rel_ts)) {
1219
55.8k
        item = proto_tree_add_time(fh_tree, hf_frame_time_relative, tvb,
1220
55.8k
                 0, 0, &(rel_ts));
1221
55.8k
        proto_item_set_generated(item);
1222
55.8k
      }
1223
1224
55.8k
      if (frame_rel_start_time(pinfo->epan, pinfo->fd, &rel_ts)) {
1225
0
        item = proto_tree_add_time(fh_tree, hf_frame_time_relative_cap, tvb,
1226
0
                 0, 0, &(rel_ts));
1227
0
        proto_item_set_generated(item);
1228
0
      }
1229
1230
55.8k
      if (pinfo->fd->ref_time) {
1231
0
        ti = proto_tree_add_item(fh_tree, hf_frame_time_reference, tvb, 0, 0, ENC_NA);
1232
0
        proto_item_set_generated(ti);
1233
0
      }
1234
55.8k
    }
1235
124k
  }
1236
1237
124k
  if (do_frame_dissection) {
1238
55.8k
    proto_tree_add_uint(fh_tree, hf_frame_number, tvb,
1239
55.8k
            0, 0, pinfo->num);
1240
1241
55.8k
    item = proto_tree_add_uint_format_value(fh_tree, hf_frame_len, tvb,
1242
55.8k
              0, 0, frame_len, "%u byte%s (%u bits)",
1243
55.8k
              frame_len, frame_plurality, frame_len * 8);
1244
69.0k
  } else {
1245
69.0k
    item = NULL;
1246
69.0k
  }
1247
124k
  if (frame_len < cap_len) {
1248
    /*
1249
     * A reported length less than a captured length
1250
     * is bogus, as you cannot capture more data
1251
     * than there is in a packet.
1252
     */
1253
0
    expert_add_info(pinfo, item, &ei_len_lt_caplen);
1254
0
  }
1255
1256
124k
  if (do_frame_dissection) {
1257
55.8k
    proto_tree_add_uint_format_value(fh_tree, hf_frame_capture_len, tvb,
1258
55.8k
             0, 0, cap_len, "%u byte%s (%u bits)",
1259
55.8k
             cap_len, cap_plurality, cap_len * 8);
1260
1261
55.8k
    if (pinfo->rec->rec_type == REC_TYPE_PACKET) {
1262
55.8k
      if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_uint64_option_value(fr_data->pkt_block, OPT_PKT_DROPCOUNT, &drop_count)) {
1263
0
        proto_tree_add_uint64(fh_tree, hf_frame_drop_count, tvb, 0, 0, drop_count);
1264
0
      }
1265
55.8k
    }
1266
1267
55.8k
    if (generate_md5_hash) {
1268
0
      const uint8_t *cp;
1269
0
      uint8_t       digest[HASH_MD5_LENGTH];
1270
0
      const char   *digest_string;
1271
1272
0
      cp = tvb_get_ptr(tvb, 0, cap_len);
1273
1274
0
      gcry_md_hash_buffer(GCRY_MD_MD5, digest, cp, cap_len);
1275
0
      digest_string = bytes_to_str_punct(pinfo->pool, digest, HASH_MD5_LENGTH, '\0');
1276
0
      ti = proto_tree_add_string(fh_tree, hf_frame_md5_hash, tvb, 0, 0, digest_string);
1277
0
      proto_item_set_generated(ti);
1278
0
    }
1279
1280
55.8k
    ti = proto_tree_add_boolean(fh_tree, hf_frame_marked, tvb, 0, 0, pinfo->fd->marked);
1281
55.8k
    proto_item_set_generated(ti);
1282
1283
55.8k
    ti = proto_tree_add_boolean(fh_tree, hf_frame_ignored, tvb, 0, 0, pinfo->fd->ignored);
1284
55.8k
    proto_item_set_generated(ti);
1285
55.8k
  }
1286
1287
124k
  if (pinfo->rec->rec_type == REC_TYPE_PACKET) {
1288
124k
    if (do_frame_dissection) {
1289
      /* Check for existence of P2P pseudo header */
1290
55.8k
      if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) {
1291
0
        proto_tree_add_int(fh_tree, hf_frame_p2p_dir, tvb,
1292
0
               0, 0, pinfo->p2p_dir);
1293
0
      }
1294
1295
      /* Check for existence of MTP2 link number */
1296
55.8k
      if ((pinfo->pseudo_header != NULL) &&
1297
55.8k
          (pinfo->rec->rec_header.packet_header.pkt_encap == WTAP_ENCAP_MTP2_WITH_PHDR)) {
1298
0
        proto_tree_add_uint(fh_tree, hf_frame_link_number, tvb,
1299
0
                0, 0, pinfo->link_number);
1300
0
      }
1301
55.8k
    }
1302
124k
  }
1303
1304
  /*
1305
   * Process custom options.
1306
   */
1307
124k
  struct custom_binary_opt_cb_data cb_data;
1308
1309
124k
  cb_data.pinfo = pinfo;
1310
124k
  cb_data.tvb = tvb;
1311
124k
  cb_data.tree = fh_tree;
1312
124k
  cb_data.data.optval = NULL;
1313
124k
  wtap_block_foreach_option(fr_data->pkt_block,
1314
124k
      handle_packet_option, &cb_data);
1315
1316
  /* If there is Darwin data, call the dissector */
1317
124k
  if (p_get_proto_data(wmem_file_scope(), pinfo, proto_darwin, 0) != NULL) {
1318
0
    call_dissector(darwin_handle, tvb, pinfo, fh_tree);
1319
0
  }
1320
1321
124k
  if (do_frame_dissection) {
1322
55.8k
    if (show_file_off) {
1323
0
      proto_tree_add_int64_format_value(fh_tree, hf_frame_file_off, tvb,
1324
0
                0, 0, pinfo->fd->file_off,
1325
0
                "%" PRId64 " (0x%" PRIx64 ")",
1326
0
                pinfo->fd->file_off, pinfo->fd->file_off);
1327
0
    }
1328
55.8k
  }
1329
1330
124k
  if (pinfo->fd->ignored) {
1331
    /* Ignored package, stop handling here */
1332
0
    col_set_str(pinfo->cinfo, COL_INFO, "<Ignored>");
1333
0
    proto_tree_add_boolean_format(tree, hf_frame_ignored, tvb, 0, 0, true, "This frame is marked as ignored");
1334
0
    return tvb_captured_length(tvb);
1335
0
  }
1336
1337
124k
  if (frame_len < cap_len) {
1338
    /*
1339
     * Fix the reported length; a reported length less than
1340
     * a captured length is bogus, as you cannot capture
1341
     * more data than there is in a packet.
1342
     */
1343
0
    tvb_fix_reported_length(tvb);
1344
0
  }
1345
1346
  /* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */
1347
124k
  TRY {
1348
#ifdef _MSC_VER
1349
    /* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions
1350
       like memory access violations.
1351
       (a running debugger will be called before the except part below) */
1352
    /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
1353
       stack in an inconsistent state thus causing a crash at some point in the
1354
       handling of the exception.
1355
       See: https://lists.wireshark.org/archives/wireshark-dev/200704/msg00243.html
1356
    */
1357
    __try {
1358
#endif
1359
124k
      switch (pinfo->rec->rec_type) {
1360
1361
124k
      case REC_TYPE_PACKET:
1362
124k
        if ((force_docsis_encap) && (docsis_handle)) {
1363
0
          dissector_handle = docsis_handle;
1364
124k
        } else {
1365
          /*
1366
           * XXX - we don't use dissector_try_uint_with_data()
1367
           * because we don't want to have to
1368
           * treat a zero return from the dissector
1369
           * as meaning "packet not accepted,
1370
           * because that doesn't work for
1371
           * packets where libwiretap strips
1372
           * off the metadata header and puts
1373
           * it into the pseudo-header, leaving
1374
           * zero bytes worth of payload.  See
1375
           * bug 15630.
1376
           *
1377
           * If the dissector for the packet's
1378
           * purported link-layer header type
1379
           * rejects the packet, that's a sign
1380
           * of a bug somewhere, so making it
1381
           * impossible for those dissectors
1382
           * to reject packets isn't a problem.
1383
           */
1384
124k
          dissector_handle =
1385
124k
              dissector_get_uint_handle(wtap_encap_dissector_table,
1386
124k
                  pinfo->rec->rec_header.packet_header.pkt_encap);
1387
124k
        }
1388
124k
        if (dissector_handle != NULL) {
1389
0
          uint32_t save_match_uint = pinfo->match_uint;
1390
1391
0
          pinfo->match_uint =
1392
0
              pinfo->rec->rec_header.packet_header.pkt_encap;
1393
0
          call_dissector_only(dissector_handle,
1394
0
              tvb, pinfo, parent_tree,
1395
0
              (void *)pinfo->pseudo_header);
1396
0
          pinfo->match_uint = save_match_uint;
1397
124k
        } else {
1398
124k
          col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
1399
124k
          col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %d",
1400
124k
                 pinfo->rec->rec_header.packet_header.pkt_encap);
1401
124k
          call_data_dissector(tvb, pinfo, parent_tree);
1402
124k
        }
1403
124k
        break;
1404
1405
0
      case REC_TYPE_FT_SPECIFIC_EVENT:
1406
0
      case REC_TYPE_FT_SPECIFIC_REPORT:
1407
0
        {
1408
0
          int file_type_subtype;
1409
1410
0
          file_type_subtype = fr_data->file_type_subtype;
1411
1412
0
          if (!dissector_try_uint(wtap_fts_rec_dissector_table, file_type_subtype,
1413
0
              tvb, pinfo, parent_tree)) {
1414
0
            col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
1415
0
            col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP FT ST = %d",
1416
0
                   file_type_subtype);
1417
0
            call_data_dissector(tvb, pinfo, parent_tree);
1418
0
          }
1419
0
        }
1420
0
        break;
1421
1422
0
      case REC_TYPE_SYSCALL:
1423
        /* Sysdig is the only type we currently handle. */
1424
0
        if (sysdig_handle) {
1425
0
          call_dissector_with_data(sysdig_handle,
1426
0
              tvb, pinfo, parent_tree,
1427
0
              (void *)pinfo->pseudo_header);
1428
0
        }
1429
0
        break;
1430
1431
0
      case REC_TYPE_SYSTEMD_JOURNAL_EXPORT:
1432
0
        if (systemd_journal_handle) {
1433
0
          call_dissector_with_data(systemd_journal_handle,
1434
0
              tvb, pinfo, parent_tree,
1435
0
              (void *)pinfo->pseudo_header);
1436
0
        }
1437
0
        break;
1438
1439
0
      case REC_TYPE_CUSTOM_BLOCK:
1440
0
        if (!dissector_try_uint(block_pen_dissector_table,
1441
0
            pinfo->rec->rec_header.custom_block_header.pen,
1442
0
            tvb, pinfo, parent_tree)) {
1443
0
          col_set_str(pinfo->cinfo, COL_PROTOCOL, "PCAPNG");
1444
0
          proto_tree_add_uint(fh_tree, hf_frame_cb_pen, tvb, 0, 0,
1445
0
                              pinfo->rec->rec_header.custom_block_header.pen);
1446
0
          proto_tree_add_boolean(fh_tree, hf_frame_cb_copy_allowed, tvb, 0, 0, pinfo->rec->rec_header.custom_block_header.copy_allowed);
1447
0
          col_add_fstr(pinfo->cinfo, COL_INFO, "Custom Block: PEN = %s (%d), will%s be copied",
1448
0
                       enterprises_lookup(pinfo->rec->rec_header.custom_block_header.pen, "Unknown"),
1449
0
                       pinfo->rec->rec_header.custom_block_header.pen,
1450
0
                       pinfo->rec->rec_header.custom_block_header.copy_allowed ? "" : " not");
1451
0
          call_data_dissector(tvb, pinfo, parent_tree);
1452
0
        }
1453
0
        break;
1454
124k
      }
1455
#ifdef _MSC_VER
1456
    } __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
1457
      ensure_tree_item(parent_tree, EXCEPTION_TREE_ITEMS);
1458
      switch (GetExceptionCode()) {
1459
      case(STATUS_ACCESS_VIOLATION):
1460
        show_exception(tvb, pinfo, parent_tree, DissectorError,
1461
                 "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
1462
        break;
1463
      case(STATUS_INTEGER_DIVIDE_BY_ZERO):
1464
        show_exception(tvb, pinfo, parent_tree, DissectorError,
1465
                 "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
1466
        break;
1467
      case(STATUS_STACK_OVERFLOW):
1468
        show_exception(tvb, pinfo, parent_tree, DissectorError,
1469
                 "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
1470
        /* XXX - this will have probably corrupted the stack,
1471
           which makes problems later in the exception code */
1472
        break;
1473
        /* XXX - add other hardware exception codes as required */
1474
      default:
1475
        show_exception(tvb, pinfo, parent_tree, DissectorError,
1476
                 ws_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
1477
      }
1478
    }
1479
#endif
1480
124k
  }
1481
124k
  CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
1482
0
    ensure_tree_item(parent_tree, EXCEPTION_TREE_ITEMS);
1483
0
    show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
1484
0
  }
1485
124k
  ENDTRY;
1486
1487
124k
  if (proto_field_is_referenced(tree, hf_frame_protocols)) {
1488
55.8k
    wmem_strbuf_t *val = wmem_strbuf_new_sized(pinfo->pool, 128);
1489
55.8k
    wmem_list_frame_t *frame;
1490
    /* skip the first entry, it's always the "frame" protocol */
1491
55.8k
    frame = wmem_list_frame_next(wmem_list_head(pinfo->layers));
1492
55.8k
    if (frame) {
1493
55.8k
      wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
1494
55.8k
      frame = wmem_list_frame_next(frame);
1495
55.8k
    }
1496
55.8k
    while (frame) {
1497
0
      wmem_strbuf_append_c(val, ':');
1498
0
      wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
1499
0
      frame = wmem_list_frame_next(frame);
1500
0
    }
1501
55.8k
    ensure_tree_item(fh_tree, 1);
1502
55.8k
    ti = proto_tree_add_string(fh_tree, hf_frame_protocols, tvb, 0, 0, wmem_strbuf_get_str(val));
1503
55.8k
    proto_item_set_generated(ti);
1504
55.8k
  }
1505
1506
124k
  proto_tree_add_uint(fh_tree, hf_frame_encoding, tvb, 0, 0, pinfo->fd->encoding);
1507
1508
  /* Add the columns as fields. We have to do this here, so that
1509
   * they're available for postdissectors that want all the fields.
1510
   *
1511
   * Note the coloring rule names are set after this, which means
1512
   * that you can set a coloring rule based on the value of a column,
1513
   * like _ws.col.protocol or _ws.col.info.
1514
   * OTOH, if we created _ws.col.custom, and a custom column used
1515
   * frame.coloring_rule.name, filtering with it wouldn't work -
1516
   * but you can filter on that field directly, so that doesn't matter.
1517
   */
1518
124k
  col_dissect(tvb, pinfo, parent_tree);
1519
1520
  /*  Call postdissectors if we have any (while trying to avoid another
1521
   *  TRY/CATCH)
1522
   */
1523
124k
  if (have_postdissector()) {
1524
124k
    TRY {
1525
#ifdef _MSC_VER
1526
      /* Win32: Visual-C Structured Exception Handling (SEH)
1527
         to trap hardware exceptions like memory access violations */
1528
      /* (a running debugger will be called before the except part below) */
1529
      /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
1530
         stack in an inconsistent state thus causing a crash at some point in the
1531
         handling of the exception.
1532
         See: https://lists.wireshark.org/archives/wireshark-dev/200704/msg00243.html
1533
      */
1534
      __try {
1535
#endif
1536
124k
        call_all_postdissectors(tvb, pinfo, parent_tree);
1537
#ifdef _MSC_VER
1538
      } __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
1539
        ensure_tree_item(parent_tree, EXCEPTION_TREE_ITEMS);
1540
        switch (GetExceptionCode()) {
1541
        case(STATUS_ACCESS_VIOLATION):
1542
          show_exception(tvb, pinfo, parent_tree, DissectorError,
1543
                   "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
1544
          break;
1545
        case(STATUS_INTEGER_DIVIDE_BY_ZERO):
1546
          show_exception(tvb, pinfo, parent_tree, DissectorError,
1547
                   "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
1548
          break;
1549
        case(STATUS_STACK_OVERFLOW):
1550
          show_exception(tvb, pinfo, parent_tree, DissectorError,
1551
                   "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
1552
          /* XXX - this will have probably corrupted the stack,
1553
             which makes problems later in the exception code */
1554
          break;
1555
          /* XXX - add other hardware exception codes as required */
1556
        default:
1557
          show_exception(tvb, pinfo, parent_tree, DissectorError,
1558
                   ws_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
1559
        }
1560
      }
1561
#endif
1562
124k
    }
1563
124k
    CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
1564
79.2k
      ensure_tree_item(parent_tree, EXCEPTION_TREE_ITEMS);
1565
79.2k
      show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
1566
79.2k
    }
1567
124k
    ENDTRY;
1568
124k
  }
1569
1570
  /* Attempt to (re-)calculate color filters (if any). */
1571
124k
  if (pinfo->fd->need_colorize) {
1572
0
    wmem_list_t *matches = NULL;
1573
1574
    /* Get ALL matching color filters (not just first).
1575
     * Store matches in proto_data so the display code below can show
1576
     * multiple matching rules in the frame tree. This enables multi-color
1577
     * support in TShark when --color flag is used. */
1578
0
    color_filter = color_filters_colorize_packet_all(fr_data->color_edt, wmem_file_scope(), &matches,
1579
0
                                                     prefs.gui_coloring_rules_include_disabled);
1580
0
    pinfo->fd->color_filter = color_filter;
1581
0
    pinfo->fd->need_colorize = 0;
1582
1583
    /* Always clear any previously stored match list, then store the new
1584
     * one (if any).  Clearing unconditionally ensures stale matches do
1585
     * not linger when a rule change causes the packet to stop matching. */
1586
0
    wmem_list_t *old_matches = (wmem_list_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_frame, 0);
1587
0
    if (old_matches) {
1588
0
      wmem_destroy_list(old_matches);
1589
0
      p_remove_proto_data(wmem_file_scope(), pinfo, proto_frame, 0);
1590
0
    }
1591
0
    if (matches) {
1592
0
      p_add_proto_data(wmem_file_scope(), pinfo, proto_frame, 0, matches);
1593
0
    }
1594
124k
  } else {
1595
124k
    color_filter = pinfo->fd->color_filter;
1596
124k
  }
1597
1598
124k
  if (fh_tree) {
1599
55.8k
    bool details = prefs.gui_packet_list_multi_color_details;
1600
55.8k
    bool include = prefs.gui_coloring_rules_include_disabled;
1601
55.8k
    bool list = details || include;
1602
    /* Retrieve all matching rules stored during colorization above. */
1603
55.8k
    wmem_list_t *matches = (wmem_list_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_frame, 0);
1604
    /* If proto_data was cleared (e.g., after rescan_packets() without color
1605
     * priming), re-run colorization now. The full protocol tree has been
1606
     * built by the sub-dissectors above, so dfilter evaluation works
1607
     * without priming. With disabled rules included, a frame can match
1608
     * only disabled rules and then has no primary rule. */
1609
55.8k
    if (!matches && list && (color_filter != NULL || include)) {
1610
0
      color_filters_colorize_packet_all(fr_data->color_edt, wmem_file_scope(), &matches, include);
1611
0
      if (matches) {
1612
0
        p_add_proto_data(wmem_file_scope(), pinfo, proto_frame, 0, matches);
1613
0
      }
1614
0
    }
1615
1616
    /* Count first: one listed rule keeps the flat items, several get a
1617
     * "Coloring Rules" item with one subtree per rule. */
1618
55.8k
    const color_filter_t *first_shown = NULL;
1619
55.8k
    unsigned shown = 0;
1620
55.8k
    if (matches && list) {
1621
0
      for (wmem_list_frame_t *lf = wmem_list_head(matches); lf != NULL; lf = wmem_list_frame_next(lf)) {
1622
0
        const color_filter_t *colorf = (const color_filter_t *)wmem_list_frame_data(lf);
1623
0
        if (color_filter_entry_shown(colorf, color_filter, details)) {
1624
0
          if (shown == 0)
1625
0
            first_shown = colorf;
1626
0
          shown++;
1627
0
        }
1628
0
      }
1629
55.8k
    } else if (color_filter != NULL && color_filter_entry_shown(color_filter, color_filter, details)) {
1630
0
      first_shown = color_filter;
1631
0
      shown = 1;
1632
0
    }
1633
1634
55.8k
    if (shown == 1) {
1635
0
      add_color_filter_flat(fh_tree, tvb, first_shown);
1636
55.8k
    } else if (shown > 1) {
1637
0
      ensure_tree_item(fh_tree, 1);
1638
0
      proto_item *rules_item = proto_tree_add_uint(fh_tree, hf_frame_color_filter_count,
1639
0
                                                   tvb, 0, 0, shown);
1640
0
      proto_item_set_generated(rules_item);
1641
0
      proto_tree *rules_tree = proto_item_add_subtree(rules_item, ett_frame_color_filters);
1642
0
      for (wmem_list_frame_t *lf = wmem_list_head(matches); lf != NULL; lf = wmem_list_frame_next(lf)) {
1643
0
        const color_filter_t *colorf = (const color_filter_t *)wmem_list_frame_data(lf);
1644
0
        if (color_filter_entry_shown(colorf, color_filter, details)) {
1645
0
          add_color_filter_nested(rules_tree, tvb, colorf);
1646
0
        }
1647
0
      }
1648
0
    }
1649
55.8k
  }
1650
1651
  /* Add a "Tags" item (frame.tags, present only when at least one tagging
1652
   * rule matched, so it can be filtered/columned without expanding it) with
1653
   * a subtree holding one frame.tag item (rule name) per matching rule. */
1654
124k
  if (fh_tree) {
1655
55.8k
    const GSList *tag_names = (const GSList *)p_get_proto_data(wmem_file_scope(), pinfo, proto_frame, 1);
1656
1657
55.8k
    if (tag_names) {
1658
0
      proto_item *tags_item = proto_tree_add_boolean(fh_tree, hf_frame_tags, tvb, 0, 0, true);
1659
0
      proto_item_set_generated(tags_item);
1660
1661
0
      if (proto_field_is_referenced(fh_tree, hf_frame_tag)) {
1662
0
        proto_tree *tags_tree = proto_item_add_subtree(tags_item, ett_frame_tags);
1663
0
        for (const GSList *t = tag_names; t; t = g_slist_next(t)) {
1664
0
          proto_item *tag_item = proto_tree_add_string(tags_tree, hf_frame_tag, tvb, 0, 0,
1665
0
                                                       (const char *)t->data);
1666
0
          proto_item_set_generated(tag_item);
1667
0
        }
1668
0
      }
1669
0
    }
1670
55.8k
  }
1671
1672
124k
  tap_queue_packet(frame_tap, pinfo, NULL);
1673
1674
1675
124k
  if (pinfo->frame_end_routines) {
1676
489
    g_slist_free_full(pinfo->frame_end_routines, &call_frame_end_routine);
1677
489
    pinfo->frame_end_routines = NULL;
1678
489
  }
1679
1680
124k
  if (prefs.enable_incomplete_dissectors_check && tree && tree->tree_data->visible) {
1681
0
    char* decoded;
1682
0
    unsigned length;
1683
0
    unsigned i;
1684
0
    unsigned byte;
1685
0
    unsigned bit;
1686
1687
0
    length = tvb_captured_length(tvb);
1688
0
    decoded = proto_find_undecoded_data(tree, length);
1689
1690
0
    for (i = 0; i < length; i++) {
1691
0
      byte = i / 8;
1692
0
      bit = i % 8;
1693
0
      if (!(decoded[byte] & (1 << bit))) {
1694
0
        field_info* fi = proto_find_field_from_offset(tree, i, tvb);
1695
0
        if (fi && fi->hfinfo->id != proto_frame) {
1696
0
          if (prefs.incomplete_dissectors_check_debug)
1697
0
            ws_log(LOG_DOMAIN_CAPTURE, LOG_LEVEL_WARNING,
1698
0
              "Dissector %s incomplete in frame %u: undecoded byte number %u "
1699
0
              "(0x%.4X+%u)",
1700
0
              fi->hfinfo->abbrev,
1701
0
              pinfo->num, i, i - i % 16, i % 16);
1702
0
          ensure_tree_item(tree, 1);
1703
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);
1704
0
        }
1705
0
      }
1706
0
    }
1707
0
  }
1708
1709
124k
  return tvb_captured_length(tvb);
1710
124k
}
1711
1712
static void common_register_frame(bool use_packets)
1713
16
{
1714
16
  static hf_register_info hf[] = {
1715
16
    { &hf_frame_arrival_time_local,
1716
16
      { "Arrival Time", "frame.time",
1717
16
        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
1718
16
        "Absolute time when this frame was captured, in local time", HFILL }},
1719
1720
16
    { &hf_frame_arrival_time_utc,
1721
16
      { "UTC Arrival Time", "frame.time_utc",
1722
16
        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0x0,
1723
16
        "Absolute time when this frame was captured, in Coordinated Universal Time (UTC)", HFILL }},
1724
1725
16
    { &hf_frame_arrival_time_epoch,
1726
16
      { "Epoch Arrival Time", "frame.time_epoch",
1727
16
        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UNIX, NULL, 0x0,
1728
16
        "Absolute time when this frame was captured, in Epoch time (also known as Unix time)", HFILL }},
1729
1730
16
    { &hf_frame_shift_offset,
1731
16
      { "Time shift for this packet", "frame.offset_shift",
1732
16
        FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1733
16
        "Time shift applied to this packet", HFILL }},
1734
1735
16
    { &hf_frame_time_delta,
1736
16
      { "Time delta from previous captured frame", "frame.time_delta",
1737
16
        FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1738
16
        NULL, HFILL }},
1739
1740
16
    { &hf_frame_time_delta_displayed,
1741
16
      { "Time delta from previous displayed frame", "frame.time_delta_displayed",
1742
16
        FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1743
16
        NULL, HFILL }},
1744
1745
16
    { &hf_frame_time_relative,
1746
16
      { "Time since reference or first frame", "frame.time_relative",
1747
16
        FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1748
16
        "Time relative to time reference or first frame", HFILL }},
1749
1750
16
    { &hf_frame_time_relative_cap,
1751
16
      { "Time since start of capturing", "frame.time_relative_capture_start",
1752
16
        FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1753
16
        "Time relative to the capture start", HFILL }},
1754
1755
16
    { &hf_frame_time_reference,
1756
16
      { "This is a Time Reference frame", "frame.ref_time",
1757
16
        FT_NONE, BASE_NONE, NULL, 0x0,
1758
16
        "This frame is a Time Reference frame", HFILL }},
1759
1760
16
    { &hf_frame_number,
1761
16
      { "Frame Number", "frame.number",
1762
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1763
16
        NULL, HFILL }},
1764
1765
16
    { &hf_frame_len,
1766
16
      { "Frame Length", "frame.len",
1767
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1768
16
        "Frame length on the wire", HFILL }},
1769
1770
16
    { &hf_frame_capture_len,
1771
16
      { "Capture Length", "frame.cap_len",
1772
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1773
16
        "Frame length stored into the capture file", HFILL }},
1774
1775
16
    { &hf_frame_md5_hash,
1776
16
      { "Frame MD5 Hash", "frame.md5_hash",
1777
16
        FT_STRING, BASE_NONE, NULL, 0x0,
1778
16
        NULL, HFILL }},
1779
1780
16
    { &hf_frame_p2p_dir,
1781
16
      { "Point-to-Point Direction", "frame.p2p_dir",
1782
16
        FT_INT8, BASE_DEC, VALS(p2p_dirs), 0x0,
1783
16
        NULL, HFILL }},
1784
1785
16
    { &hf_frame_link_number,
1786
16
      { "Link Number", "frame.link_nr",
1787
16
        FT_UINT16, BASE_DEC, NULL, 0x0,
1788
16
        NULL, HFILL }},
1789
1790
16
    { &hf_frame_file_off,
1791
16
      { "File Offset", "frame.file_off",
1792
16
        FT_INT64, BASE_DEC, NULL, 0x0,
1793
16
        NULL, HFILL }},
1794
1795
16
    { &hf_frame_marked,
1796
16
      { "Frame is marked", "frame.marked",
1797
16
        FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1798
16
        "Frame is marked in the GUI", HFILL }},
1799
1800
16
    { &hf_frame_ignored,
1801
16
      { "Frame is ignored", "frame.ignored",
1802
16
        FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1803
16
        "Frame is ignored by the dissectors", HFILL }},
1804
1805
16
    { &hf_frame_protocols,
1806
16
      { "Protocols in frame", "frame.protocols",
1807
16
        FT_STRING, BASE_NONE, NULL, 0x0,
1808
16
        "Protocols carried by this frame", HFILL }},
1809
1810
16
    { &hf_frame_color_filter_count,
1811
16
      { "Coloring Rules", "frame.coloring_rule.count",
1812
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1813
16
        "Number of coloring rules listed for this frame", HFILL }},
1814
1815
16
    { &hf_frame_color_filter_name,
1816
16
      { "Coloring Rule Name", "frame.coloring_rule.name",
1817
16
        FT_STRING, BASE_NONE, NULL, 0x0,
1818
16
        "The frame matched the coloring rule with this name", HFILL }},
1819
1820
16
    { &hf_frame_color_filter_text,
1821
16
      { "Coloring Rule String", "frame.coloring_rule.string",
1822
16
        FT_STRING, BASE_NONE, NULL, 0x0,
1823
16
        "The frame matched this coloring rule string", HFILL }},
1824
1825
16
    { &hf_frame_color_filter_disabled,
1826
16
      { "Coloring Rule Disabled", "frame.coloring_rule.disabled",
1827
16
        FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1828
16
        "The frame matched this coloring rule, but the rule is disabled and does not color frames", HFILL }},
1829
1830
16
    { &hf_frame_section_number,
1831
16
      { "Section number", "frame.section_number",
1832
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1833
16
        "The number of the file section this frame is in", HFILL }},
1834
1835
16
    { &hf_frame_interface_id,
1836
16
      { "Interface id", "frame.interface_id",
1837
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1838
16
        NULL, HFILL }},
1839
1840
16
    { &hf_frame_interface_name,
1841
16
      { "Interface name", "frame.interface_name",
1842
16
        FT_STRING, BASE_NONE, NULL, 0x0,
1843
16
        "The friendly name for this interface", HFILL }},
1844
1845
16
    { &hf_frame_interface_description,
1846
16
      { "Interface description", "frame.interface_description",
1847
16
        FT_STRING, BASE_NONE, NULL, 0x0,
1848
16
        "The description for this interface", HFILL }},
1849
1850
16
    { &hf_frame_interface_queue,
1851
16
      { "Interface queue", "frame.interface_queue",
1852
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1853
16
        NULL, HFILL }},
1854
1855
16
    { &hf_frame_pack_flags,
1856
16
      { "Packet flags", "frame.packet_flags",
1857
16
        FT_UINT32, BASE_HEX, NULL, 0x0,
1858
16
        NULL, HFILL }},
1859
1860
16
    { &hf_frame_pack_direction,
1861
16
      { "Direction", "frame.packet_flags_direction",
1862
16
        FT_UINT32, BASE_HEX, VALS(packet_word_directions), PACK_FLAGS_DIRECTION_MASK,
1863
16
        NULL, HFILL }},
1864
1865
16
    { &hf_frame_pack_reception_type,
1866
16
      { "Reception type", "frame.packet_flags_reception_type",
1867
16
        FT_UINT32, BASE_DEC, VALS(packet_word_reception_types), PACK_FLAGS_RECEPTION_TYPE_MASK,
1868
16
        NULL, HFILL }},
1869
1870
16
    { &hf_frame_pack_fcs_length,
1871
16
      { "FCS length", "frame.packet_flags_fcs_length",
1872
16
        FT_UINT32, BASE_DEC, NULL, PACK_FLAGS_FCS_LENGTH_MASK,
1873
16
        NULL, HFILL }},
1874
1875
16
    { &hf_frame_pack_reserved,
1876
16
      { "Reserved", "frame.packet_flags_reserved",
1877
16
        FT_UINT32, BASE_DEC, NULL, PACK_FLAGS_RESERVED_MASK,
1878
16
        NULL, HFILL }},
1879
1880
16
    { &hf_frame_pack_crc_error,
1881
16
      { "CRC error", "frame.packet_flags_crc_error",
1882
16
        FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_CRC_ERROR,
1883
16
        NULL, HFILL }},
1884
1885
16
    { &hf_frame_pack_wrong_packet_too_long_error,
1886
16
      { "Packet too long error", "frame.packet_flags_packet_too_error",
1887
16
        FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_PACKET_TOO_LONG,
1888
16
        NULL, HFILL }},
1889
1890
16
    { &hf_frame_pack_wrong_packet_too_short_error,
1891
16
      { "Packet too short error", "frame.packet_flags_packet_too_short_error",
1892
16
        FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_PACKET_TOO_SHORT,
1893
16
        NULL, HFILL }},
1894
1895
16
    { &hf_frame_pack_wrong_inter_frame_gap_error,
1896
16
      { "Wrong interframe gap error", "frame.packet_flags_wrong_inter_frame_gap_error",
1897
16
        FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_WRONG_INTER_FRAME_GAP,
1898
16
        NULL, HFILL }},
1899
1900
16
    { &hf_frame_pack_unaligned_frame_error,
1901
16
      { "Unaligned frame error", "frame.packet_flags_unaligned_frame_error",
1902
16
        FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_UNALIGNED_FRAME,
1903
16
        NULL, HFILL }},
1904
1905
16
    { &hf_frame_pack_start_frame_delimiter_error,
1906
16
      { "Start frame delimiter error", "frame.packet_flags_start_frame_delimiter_error",
1907
16
        FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_START_FRAME_DELIMITER_ERROR,
1908
16
        NULL, HFILL }},
1909
1910
16
    { &hf_frame_pack_preamble_error,
1911
16
      { "Preamble error", "frame.packet_flags_preamble_error",
1912
16
        FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_PREAMBLE_ERROR,
1913
16
        NULL, HFILL }},
1914
1915
16
    { &hf_frame_pack_symbol_error,
1916
16
      { "Symbol error", "frame.packet_flags_symbol_error",
1917
16
        FT_BOOLEAN, 32, TFS(&tfs_set_notset), PACK_FLAGS_SYMBOL_ERROR,
1918
16
        NULL, HFILL }},
1919
1920
16
    { &hf_frame_comment,
1921
16
      { "Comment", "frame.comment",
1922
16
        FT_STRING, BASE_NONE, NULL, 0x0,
1923
16
        NULL, HFILL }},
1924
1925
16
    { &hf_frame_tags,
1926
16
      { "Tags", "frame.tags",
1927
16
        FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1928
16
        "At least one tagging rule matched this frame", HFILL }},
1929
1930
16
    { &hf_frame_tag,
1931
16
      { "Tag", "frame.tag",
1932
16
        FT_STRING, BASE_NONE, NULL, 0x0,
1933
16
        "Name of a matching tagging rule", HFILL }},
1934
1935
16
    { &hf_frame_packet_id,
1936
16
      { "Packet id", "frame.packet_id",
1937
16
        FT_UINT64, BASE_DEC, NULL, 0x0,
1938
16
        NULL, HFILL }},
1939
1940
16
    { &hf_frame_process,
1941
16
      { "Process information", "frame.process",
1942
16
        FT_NONE, BASE_NONE, NULL, 0x0,
1943
16
        "Process associated with the packet, from the pcapng epb_processid_threadid option and the process information in the file", HFILL }},
1944
1945
16
    { &hf_frame_process_pid,
1946
16
      { "Process ID", "frame.process.pid",
1947
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1948
16
        "Identifier of the process associated with the packet; 0 if not available", HFILL }},
1949
1950
16
    { &hf_frame_process_tid,
1951
16
      { "Thread ID", "frame.process.tid",
1952
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1953
16
        "Identifier of the thread associated with the packet; 0 if not available", HFILL }},
1954
1955
16
    { &hf_frame_process_name,
1956
16
      { "Process name", "frame.process.name",
1957
16
        FT_STRING, BASE_NONE, NULL, 0x0,
1958
16
        "Short name of the process, typically that of its executable", HFILL }},
1959
1960
16
    { &hf_frame_process_path,
1961
16
      { "Executable path", "frame.process.path",
1962
16
        FT_STRING, BASE_NONE, NULL, 0x0,
1963
16
        "Full path of the executable image of the process", HFILL }},
1964
1965
16
    { &hf_frame_process_cmdline,
1966
16
      { "Command line", "frame.process.cmdline",
1967
16
        FT_STRING, BASE_NONE, NULL, 0x0,
1968
16
        "Command line of the process, its arguments separated by spaces", HFILL }},
1969
1970
16
    { &hf_frame_process_ppid,
1971
16
      { "Parent process ID", "frame.process.ppid",
1972
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1973
16
        "Identifier of the parent of the process", HFILL }},
1974
1975
16
    { &hf_frame_process_uid,
1976
16
      { "User ID", "frame.process.uid",
1977
16
        FT_UINT32, BASE_DEC, NULL, 0x0,
1978
16
        "Numeric identifier of the user account the process runs as", HFILL }},
1979
1980
16
    { &hf_frame_process_user,
1981
16
      { "User name", "frame.process.user",
1982
16
        FT_STRING, BASE_NONE, NULL, 0x0,
1983
16
        "Name of the user account the process runs as", HFILL }},
1984
1985
16
    { &hf_frame_process_uuid,
1986
16
      { "Executable UUID", "frame.process.uuid",
1987
16
        FT_GUID, BASE_NONE, NULL, 0x0,
1988
16
        "UUID of the executable image of the process", HFILL }},
1989
1990
16
    { &hf_frame_process_start_time,
1991
16
      { "Start time", "frame.process.start_time",
1992
16
        FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
1993
16
        "Time at which the process started", HFILL }},
1994
1995
16
    { &hf_frame_hash,
1996
16
      { "Hash Algorithm", "frame.hash",
1997
16
        FT_STRING, BASE_NONE, NULL, 0x0,
1998
16
        NULL, HFILL }},
1999
2000
16
    { &hf_frame_hash_bytes,
2001
16
      { "Hash Value", "frame.hash.value",
2002
16
        FT_BYTES, SEP_SPACE, NULL, 0x0,
2003
16
        NULL, HFILL }},
2004
2005
16
    { &hf_frame_verdict,
2006
16
      { "Verdict", "frame.verdict",
2007
16
        FT_STRING, BASE_NONE, NULL, 0x0,
2008
16
        NULL, HFILL }},
2009
2010
16
    { &hf_frame_verdict_hardware,
2011
16
      { "Hardware", "frame.verdict.hw",
2012
16
        FT_BYTES, SEP_SPACE, NULL, 0x0,
2013
16
        NULL, HFILL }},
2014
2015
16
    { &hf_frame_verdict_tc,
2016
16
      { "eBPF TC", "frame.verdict.ebpf_tc",
2017
16
        FT_INT64, BASE_DEC|BASE_VAL64_STRING,
2018
16
        VALS64(verdict_ebpf_tc_types), 0x0,
2019
16
        NULL, HFILL }},
2020
2021
16
    { &hf_frame_verdict_xdp,
2022
16
      { "eBPF XDP", "frame.verdict.ebpf_xdp",
2023
16
        FT_INT64, BASE_DEC|BASE_VAL64_STRING,
2024
16
        VALS64(verdict_ebpf_xdp_types), 0x0,
2025
16
        NULL, HFILL }},
2026
2027
16
    { &hf_frame_verdict_unknown,
2028
16
      { "Unknown", "frame.verdict.unknown",
2029
16
        FT_BYTES, SEP_SPACE, NULL, 0x0,
2030
16
        NULL, HFILL }},
2031
2032
16
    { &hf_frame_drop_count,
2033
16
      { "Drop Count", "frame.drop_count",
2034
16
        FT_UINT64, BASE_DEC, NULL, 0x0,
2035
16
        "Number of frames lost between this frame and the preceding one on the same interface", HFILL }},
2036
2037
16
    { &hf_frame_cb_pen,
2038
16
      { "Private Enterprise Number", "frame.cb_pen",
2039
16
        FT_UINT32, BASE_ENTERPRISES, STRINGS_ENTERPRISES, 0x0,
2040
16
        "IANA assigned private enterprise number (PEN)", HFILL }},
2041
2042
16
    { &hf_frame_cb_copy_allowed,
2043
16
      { "Copying", "frame.cb_copy",
2044
16
        FT_BOOLEAN, BASE_NONE, TFS(&tfs_allowed_not_allowed), 0x0,
2045
16
        "Whether the custom block will be written or not", HFILL }},
2046
2047
16
    { &hf_frame_encoding,
2048
16
      { "Character encoding", "frame.encoding",
2049
16
        FT_UINT32, BASE_DEC, VALS(packet_char_enc_types), 0x0,
2050
16
        "Character encoding (ASCII, EBCDIC...)", HFILL }},
2051
2052
16
    { &hf_frame_cust_opt,
2053
16
      { "Custom Option", "frame.custom_opt",
2054
16
        FT_NONE, BASE_NONE, NULL, 0x0,
2055
16
        NULL, HFILL }},
2056
2057
16
    { &hf_frame_cust_opt_pen,
2058
16
      { "Private Enterprise Number", "frame.custom_opt.pen",
2059
16
        FT_UINT32, BASE_ENTERPRISES, STRINGS_ENTERPRISES, 0x0,
2060
16
        "IANA assigned private enterprise number (PEN)", HFILL }},
2061
2062
16
    { &hf_frame_cust_opt_copy_allowed,
2063
16
      { "Copying", "frame.custom_opt.copy",
2064
16
        FT_BOOLEAN, BASE_NONE, TFS(&tfs_allowed_not_allowed), 0x0,
2065
16
        "Whether the custom option will be written or not", HFILL }},
2066
2067
16
    { &hf_frame_cust_opt_string,
2068
16
      { "String data", "frame.custom_opt.string",
2069
16
        FT_STRING, BASE_NONE, NULL, 0x0,
2070
16
        NULL, HFILL }},
2071
2072
16
    { &hf_frame_cust_opt_data,
2073
16
      { "Binary data", "frame.custom_opt.binary",
2074
16
        FT_BYTES, BASE_NONE, NULL, 0x0,
2075
16
        NULL, HFILL }},
2076
16
  };
2077
2078
16
  static hf_register_info hf_encap =
2079
16
    { &hf_frame_wtap_encap,
2080
16
      { "Encapsulation type", "frame.encap_type",
2081
16
        FT_INT16, BASE_DEC, NULL, 0x0,
2082
16
        NULL, HFILL }};
2083
2084
16
  static int *ett[] = {
2085
16
    &ett_frame,
2086
16
    &ett_ifname,
2087
16
    &ett_flags,
2088
16
    &ett_comments,
2089
16
    &ett_hash,
2090
16
    &ett_verdict,
2091
16
    &ett_process,
2092
16
    &ett_frame_tags,
2093
16
    &ett_frame_color_filters,
2094
16
    &ett_frame_color_filter,
2095
16
  };
2096
2097
16
  static ei_register_info ei[] = {
2098
16
    { &ei_comments_text, { "frame.comment.expert", PI_COMMENTS_GROUP, PI_COMMENT, "Formatted comment", EXPFILL }},
2099
16
    { &ei_arrive_time_out_of_range, { "frame.time_invalid", PI_SEQUENCE, PI_NOTE, "Arrival Time: Fractional second out of range (0-999999999)", EXPFILL }},
2100
16
    { &ei_incomplete, { "frame.incomplete", PI_UNDECODED, PI_NOTE, "Incomplete dissector", EXPFILL }},
2101
16
    { &ei_len_lt_caplen, { "frame.len_lt_caplen", PI_MALFORMED, PI_ERROR, "Frame length is less than captured length", EXPFILL }}
2102
16
  };
2103
2104
16
  module_t *frame_module;
2105
16
  expert_module_t* expert_frame;
2106
2107
16
  if (hf_encap.hfinfo.strings == NULL) {
2108
16
    int encap_count = wtap_get_num_encap_types();
2109
16
    value_string *arr;
2110
16
    int i;
2111
2112
16
    hf_encap.hfinfo.strings = arr = wmem_alloc_array(wmem_epan_scope(), value_string, encap_count+1);
2113
2114
3.72k
    for (i = 0; i < encap_count; i++) {
2115
3.71k
      arr[i].value = i;
2116
3.71k
      arr[i].strptr = wtap_encap_description(i);
2117
3.71k
    }
2118
16
    arr[encap_count].value = 0;
2119
16
    arr[encap_count].strptr = NULL;
2120
16
  }
2121
2122
16
  proto_frame = proto_register_protocol("Frame", "Frame", "frame"); /* name, short name, abbreviation */
2123
16
  if (use_packets) {
2124
16
    proto_pkt_comment = proto_register_protocol_in_name_only("Packet comments", "Pkt_Comment", "pkt_comment", proto_frame, FT_PROTOCOL);
2125
16
    proto_register_alias(proto_pkt_comment, "evt_comment");
2126
16
  } else {
2127
0
    proto_pkt_comment = proto_register_protocol_in_name_only("Event comments", "Evt_Comment", "evt_comment", proto_frame, FT_PROTOCOL);
2128
0
    proto_register_alias(proto_pkt_comment, "pkt_comment");
2129
0
  }
2130
16
  proto_syscall = proto_register_protocol("System Call", "Syscall", "syscall");
2131
2132
16
  proto_register_field_array(proto_frame, hf, array_length(hf));
2133
16
  proto_register_field_array(proto_frame, &hf_encap, 1);
2134
16
  proto_register_subtree_array(ett, array_length(ett));
2135
16
  expert_frame = expert_register_protocol(proto_frame);
2136
16
  expert_register_field_array(expert_frame, ei, array_length(ei));
2137
16
  register_dissector("frame",dissect_frame,proto_frame);
2138
2139
16
  wtap_encap_dissector_table = register_dissector_table("wtap_encap",
2140
16
      "Wiretap encapsulation type", proto_frame, FT_UINT32, BASE_DEC);
2141
16
  wtap_fts_rec_dissector_table = register_dissector_table("wtap_fts_rec",
2142
16
      "Wiretap file type for file-type-specific records", proto_frame, FT_UINT32, BASE_DEC);
2143
16
  block_pen_dissector_table = register_dissector_table("pcapng_custom_block",
2144
16
      "PcapNG custom block PEN", proto_frame, FT_UINT32, BASE_DEC);
2145
16
  binary_option_pen_dissector_table = register_dissector_table("pcapng_custom_binary_option",
2146
16
      "PcapNG custom binary option PEN", proto_frame, FT_UINT32, BASE_DEC);
2147
16
  string_option_pen_dissector_table = register_dissector_table("pcapng_custom_string_option",
2148
16
      "PcapNG custom string option PEN", proto_frame, FT_UINT32, BASE_DEC);
2149
16
  packet_block_option_dissector_table = register_dissector_table("pcapng_packet_block_option",
2150
16
      "PcapNG packet block option", proto_frame, FT_UINT32, BASE_DEC);
2151
16
  register_capture_dissector_table("wtap_encap", "Wiretap encapsulation type");
2152
2153
  /* You can't disable dissection of "Frame", as that would be
2154
     tantamount to not doing any dissection whatsoever. */
2155
16
  proto_set_cant_toggle(proto_frame);
2156
2157
16
  register_seq_analysis("any", "All Flows", proto_frame, NULL, TL_REQUIRES_COLUMNS, frame_seq_analysis_packet);
2158
2159
16
  if (use_packets) {
2160
16
    register_conversation_filter("process", "Process",
2161
16
        frame_process_filter_valid, frame_process_build_filter, NULL);
2162
16
  }
2163
2164
  /* Our preferences */
2165
16
  frame_module = prefs_register_protocol(proto_frame, NULL);
2166
16
  prefs_register_bool_preference(frame_module, "show_file_off",
2167
16
      "Show File Offset", "Show offset of frame in capture file", &show_file_off);
2168
16
  prefs_register_bool_preference(frame_module, "force_docsis_encap",
2169
16
      "Treat all frames as DOCSIS frames", "Treat all frames as DOCSIS Frames", &force_docsis_encap);
2170
16
  prefs_register_bool_preference(frame_module, "generate_md5_hash",
2171
16
      "Generate an MD5 hash of each frame",
2172
16
      "Whether or not MD5 hashes should be generated for each frame, useful for finding duplicate frames.",
2173
16
      &generate_md5_hash);
2174
16
  prefs_register_obsolete_preference(frame_module, "generate_epoch_time");
2175
16
  prefs_register_bool_preference(frame_module, "generate_bits_field",
2176
16
      "Show the number of bits in the frame",
2177
16
      "Whether or not the number of bits in the frame should be shown.",
2178
16
      &generate_bits_field);
2179
16
  prefs_register_bool_preference(frame_module, "disable_packet_size_limited_in_summary",
2180
16
      "Disable 'packet size limited during capture' message in summary",
2181
16
      "Whether or not 'packet size limited during capture' message in shown in Info column.",
2182
16
      &disable_packet_size_limited_in_summary);
2183
16
  prefs_register_uint_preference(frame_module, "max_comment_lines",
2184
16
      "Maximum number of lines to display for one packet comment",
2185
16
      "Show at most this many lines of a multi-line packet comment"
2186
16
      " (applied separately to each comment)",
2187
16
      10, &max_comment_lines);
2188
2189
16
  frame_tap=register_tap("frame");
2190
16
}
2191
2192
void
2193
proto_register_frame(void)
2194
16
{
2195
16
  common_register_frame(true);
2196
16
}
2197
2198
void
2199
event_register_frame(void)
2200
0
{
2201
0
  common_register_frame(false);
2202
0
}
2203
2204
void
2205
proto_reg_handoff_frame(void)
2206
16
{
2207
16
  docsis_handle = find_dissector_add_dependency("docsis", proto_frame);
2208
16
  darwin_handle = find_dissector_add_dependency("darwin", proto_frame);
2209
2210
16
  proto_darwin = proto_registrar_get_id_byname("darwin");
2211
16
}
2212
2213
void
2214
event_reg_handoff_frame(void)
2215
0
{
2216
0
  sysdig_handle = find_dissector_add_dependency("sysdig", proto_frame);
2217
0
  systemd_journal_handle = find_dissector_add_dependency("systemd_journal", proto_frame);
2218
0
}
2219
2220
/*
2221
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2222
 *
2223
 * Local variables:
2224
 * c-basic-offset: 8
2225
 * tab-width: 8
2226
 * indent-tabs-mode: t
2227
 * End:
2228
 *
2229
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2230
 * :indentSize=8:tabSize=8:noTabs=false:
2231
 */