Coverage Report

Created: 2025-02-15 06:25

/src/wireshark/epan/epan.c
Line
Count
Source (jump to first uncovered line)
1
/* epan.c
2
 *
3
 * Wireshark Protocol Analyzer Library
4
 *
5
 * Copyright (c) 2001 by Gerald Combs <gerald@wireshark.org>
6
 *
7
 * SPDX-License-Identifier: GPL-2.0-or-later
8
 */
9
10
#include "config.h"
11
#include "epan.h"
12
13
#include <stdarg.h>
14
#include <stdio.h>
15
#include <stdlib.h>
16
17
#include <gcrypt.h>
18
19
#ifdef HAVE_LIBGNUTLS
20
#include <gnutls/gnutls.h>
21
#endif /* HAVE_LIBGNUTLS */
22
23
#include <glib.h>
24
25
#include <wsutil/report_message.h>
26
27
#include <epan/exceptions.h>
28
29
#include "epan/frame_data.h"
30
31
#include "dfilter/dfilter.h"
32
#include "dfilter/dfilter-translator.h"
33
#include "epan_dissect.h"
34
35
#include <wsutil/nstime.h>
36
#include <wsutil/wslog.h>
37
#include <wsutil/ws_assert.h>
38
#include <wsutil/version_info.h>
39
40
#include "conversation.h"
41
#include "except.h"
42
#include "packet.h"
43
#include "prefs.h"
44
#include "column-info.h"
45
#include "tap.h"
46
#include "addr_resolv.h"
47
#include "oids.h"
48
#include <epan/wmem_scopes.h>
49
#include "expert.h"
50
#include "print.h"
51
#include "capture_dissectors.h"
52
#include "exported_pdu.h"
53
#include "export_object.h"
54
#include "stat_tap_ui.h"
55
#include "follow.h"
56
#include "disabled_protos.h"
57
#include "decode_as.h"
58
#include "conversation_filter.h"
59
#include "conversation_table.h"
60
#include "reassemble.h"
61
#include "srt_table.h"
62
#include "stats_tree.h"
63
#include "secrets.h"
64
#include "funnel.h"
65
#include "wscbor.h"
66
#include <dtd.h>
67
68
#ifdef HAVE_PLUGINS
69
#include <wsutil/plugins.h>
70
#endif
71
72
#ifdef HAVE_LUA
73
#include <lua.h>
74
#include <wslua/wslua.h>
75
#endif
76
77
#ifdef HAVE_LIBSMI
78
#include <smi.h>
79
#endif
80
81
#include <ares.h>
82
83
#ifdef HAVE_LZ4
84
#include <lz4.h>
85
#endif
86
87
#ifdef HAVE_ZSTD
88
#include <zstd.h>
89
#endif
90
91
#ifdef HAVE_NGHTTP2
92
#include <nghttp2/nghttp2.h>
93
#endif
94
95
#ifdef HAVE_NGHTTP3
96
#include <nghttp3/nghttp3.h>
97
#endif
98
99
#ifdef HAVE_BROTLI
100
#include <brotli/decode.h>
101
#endif
102
103
#ifdef HAVE_LIBXML2
104
#include <libxml/xmlversion.h>
105
#include <libxml/parser.h>
106
#endif
107
108
#ifndef _WIN32
109
#include <signal.h>
110
#endif
111
112
static GSList *epan_plugin_register_all_procotols;
113
static GSList *epan_plugin_register_all_handoffs;
114
115
static wmem_allocator_t *pinfo_pool_cache;
116
117
/* Global variables holding the content of the corresponding environment variable
118
 * to save fetching it repeatedly.
119
 */
120
bool wireshark_abort_on_dissector_bug;
121
bool wireshark_abort_on_too_many_items;
122
123
void
124
ws_dissector_bug(const char *format, ...)
125
0
{
126
0
  va_list     ap;
127
128
0
  va_start(ap, format);
129
0
  vfprintf(stderr, format, ap);
130
0
  va_end(ap);
131
132
0
  if (wireshark_abort_on_dissector_bug)
133
0
    abort();
134
0
}
135
136
#ifdef HAVE_PLUGINS
137
/* Used for bookkeeping, includes all libwireshark plugin types (dissector, tap, epan). */
138
static plugins_t *libwireshark_plugins;
139
#endif
140
141
/* "epan_plugins" are a specific type of libwireshark plugin (the name isn't the best for clarity). */
142
static GSList *epan_plugins;
143
144
const char*
145
0
epan_get_version(void) {
146
0
  return VERSION;
147
0
}
148
149
void
150
epan_get_version_number(int *major, int *minor, int *micro)
151
0
{
152
0
  if (major)
153
0
    *major = VERSION_MAJOR;
154
0
  if (minor)
155
0
    *minor = VERSION_MINOR;
156
0
  if (micro)
157
0
    *micro = VERSION_MICRO;
158
0
}
159
160
#if defined(_WIN32) && GCRYPT_VERSION_NUMBER < 0x010b00
161
// Libgcrypt prints all log messages to stderr by default. This is noisier
162
// than we would like on Windows. In particular slow_gatherer tends to print
163
//     "NOTE: you should run 'diskperf -y' to enable the disk statistics"
164
// which we don't care about.
165
// gcry_set_log_handler was deprecated in libgcrypt 1.11.0, and also that
166
// particular log message was quieted when not supported (and hence not useful)
167
// https://github.com/gpg/libgcrypt/commit/35abf4d2eb582b78873aa324f6d02976788ffbbc
168
static void
169
quiet_gcrypt_logger (void *dummy _U_, int level, const char *format, va_list args)
170
{
171
  enum ws_log_level log_level;
172
173
  switch (level) {
174
  case GCRY_LOG_CONT: // Continuation. Ignore for now.
175
  case GCRY_LOG_DEBUG:
176
  case GCRY_LOG_INFO:
177
    return;
178
  case GCRY_LOG_WARN:
179
  case GCRY_LOG_BUG:
180
    log_level = LOG_LEVEL_WARNING;
181
    break;
182
  case GCRY_LOG_ERROR:
183
    log_level = LOG_LEVEL_ERROR;
184
    break;
185
  case GCRY_LOG_FATAL:
186
    log_level = LOG_LEVEL_CRITICAL;
187
    break;
188
  default:
189
    return;
190
  }
191
  ws_logv(LOG_DOMAIN_EPAN, log_level, format, args);
192
}
193
#endif // _WIN32
194
195
static void
196
epan_plugin_init(void *data, void *user_data _U_)
197
0
{
198
0
  ((epan_plugin *)data)->init();
199
0
}
200
201
static void
202
epan_plugin_post_init(void *data, void *user_data _U_)
203
0
{
204
0
  ((epan_plugin *)data)->post_init();
205
0
}
206
207
static void
208
epan_plugin_dissect_init(void *data, void *user_data)
209
0
{
210
0
  ((epan_plugin *)data)->dissect_init((epan_dissect_t *)user_data);
211
0
}
212
213
static void
214
epan_plugin_dissect_cleanup(void *data, void *user_data)
215
0
{
216
0
  ((epan_plugin *)data)->dissect_cleanup((epan_dissect_t *)user_data);
217
0
}
218
219
static void
220
epan_plugin_cleanup(void *data, void *user_data _U_)
221
0
{
222
0
  ((epan_plugin *)data)->cleanup();
223
0
}
224
225
#ifdef HAVE_PLUGINS
226
void epan_register_plugin(const epan_plugin *plug)
227
{
228
  epan_plugins = g_slist_prepend(epan_plugins, (epan_plugin *)plug);
229
  if (plug->register_all_protocols)
230
    epan_plugin_register_all_procotols = g_slist_prepend(epan_plugin_register_all_procotols, plug->register_all_protocols);
231
  if (plug->register_all_handoffs)
232
    epan_plugin_register_all_handoffs = g_slist_prepend(epan_plugin_register_all_handoffs, plug->register_all_handoffs);
233
}
234
#else /* HAVE_PLUGINS */
235
void epan_register_plugin(const epan_plugin *plug _U_)
236
0
{
237
0
  ws_warning("epan_register_plugin: built without support for binary plugins");
238
0
}
239
#endif /* HAVE_PLUGINS */
240
241
int epan_plugins_supported(void)
242
0
{
243
#ifdef HAVE_PLUGINS
244
  return plugins_supported() ? 0 : 1;
245
#else
246
0
  return -1;
247
0
#endif
248
0
}
249
250
static void epan_plugin_register_all_tap_listeners(void *data, void *user_data _U_)
251
0
{
252
0
  epan_plugin *plug = (epan_plugin *)data;
253
0
  if (plug->register_all_tap_listeners)
254
0
    plug->register_all_tap_listeners();
255
0
}
256
257
bool
258
epan_init(register_cb cb, void *client_data, bool load_plugins)
259
14
{
260
14
  volatile bool status = true;
261
262
  /* Get the value of some environment variables and set corresponding globals for performance reasons*/
263
  /* If the WIRESHARK_ABORT_ON_DISSECTOR_BUG environment variable is set,
264
   * it will call abort(), instead, to make it easier to get a stack trace.
265
  */
266
14
  if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL) {
267
0
    wireshark_abort_on_dissector_bug = true;
268
14
  } else {
269
14
    wireshark_abort_on_dissector_bug = false;
270
14
  }
271
272
14
  if (getenv("WIRESHARK_ABORT_ON_TOO_MANY_ITEMS") != NULL) {
273
0
    wireshark_abort_on_too_many_items = true;
274
14
  } else {
275
14
    wireshark_abort_on_too_many_items = false;
276
14
  }
277
278
  /*
279
   * proto_init -> register_all_protocols -> g_async_queue_new which
280
   * requires threads to be initialized. This happens automatically with
281
   * GLib 2.32, before that g_thread_init must be called. But only since
282
   * GLib 2.24, multiple invocations are allowed. Check for an earlier
283
   * invocation just in case.
284
   */
285
  /* initialize memory allocation subsystem */
286
14
  wmem_init_scopes();
287
288
  /* initialize the GUID to name mapping table */
289
14
  guids_init();
290
291
  /* initialize name resolution (addr_resolv.c) */
292
14
  addr_resolv_init();
293
294
14
  except_init();
295
296
14
  dfilter_translator_init();
297
298
14
  if (load_plugins) {
299
#ifdef HAVE_PLUGINS
300
    libwireshark_plugins = plugins_init(WS_PLUGIN_EPAN);
301
#endif
302
0
  }
303
304
  /* initialize libgcrypt (beware, it won't be thread-safe) */
305
#if GCRYPT_VERSION_NUMBER >= 0x010a00
306
  /* Ensure FIPS mode is disabled; it makes it impossible to decrypt
307
   * non-NIST approved algorithms. We're decrypting, not promising
308
   * security. This overrides any file or environment variables that
309
   * would normally turn on FIPS mode, and has to be done prior to
310
   * gcry_check_version().
311
   */
312
  gcry_control (GCRYCTL_NO_FIPS_MODE);
313
#endif
314
14
  gcry_check_version(NULL);
315
#if defined(_WIN32) && GCRYPT_VERSION_NUMBER < 0x010b00
316
  gcry_set_log_handler (quiet_gcrypt_logger, NULL);
317
#endif
318
14
  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
319
14
  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
320
#ifdef HAVE_LIBGNUTLS
321
  gnutls_global_init();
322
#if GNUTLS_VERSION_NUMBER >= 0x030602
323
  if (gnutls_fips140_mode_enabled()) {
324
    gnutls_fips140_set_mode(GNUTLS_FIPS140_LAX, 0);
325
  }
326
#endif
327
#endif
328
#ifdef HAVE_LIBXML2
329
  xmlInitParser();
330
  LIBXML_TEST_VERSION;
331
#endif
332
333
14
#ifndef _WIN32
334
  // We might receive a SIGPIPE due to maxmind_db.
335
14
  signal(SIGPIPE, SIG_IGN);
336
14
#endif
337
338
14
  TRY {
339
14
    export_pdu_init();
340
14
    tap_init();
341
14
    prefs_init();
342
14
    expert_init();
343
14
    packet_init();
344
14
    secrets_init();
345
14
    conversation_init();
346
14
    capture_dissector_init();
347
14
    reassembly_tables_init();
348
14
    conversation_filters_init();
349
14
    g_slist_foreach(epan_plugins, epan_plugin_init, NULL);
350
14
    proto_init(epan_plugin_register_all_procotols, epan_plugin_register_all_handoffs, cb, client_data);
351
14
    g_slist_foreach(epan_plugins, epan_plugin_register_all_tap_listeners, NULL);
352
14
    packet_cache_proto_handles();
353
14
    dfilter_init();
354
14
    wscbor_init();
355
14
    final_registration_all_protocols();
356
14
    print_cache_field_handles();
357
14
    expert_packet_init();
358
#ifdef HAVE_LUA
359
    wslua_init(cb, client_data);
360
#endif
361
14
    g_slist_foreach(epan_plugins, epan_plugin_post_init, NULL);
362
14
  }
363
14
  CATCH(DissectorError) {
364
    /*
365
     * This is probably a dissector, or something it calls,
366
     * calling REPORT_DISSECTOR_ERROR() in a registration
367
     * routine or something else outside the normal dissection
368
     * code path.
369
     */
370
0
    const char *exception_message = GET_MESSAGE;
371
0
    static const char dissector_error_nomsg[] =
372
0
        "Dissector writer didn't bother saying what the error was";
373
374
0
    report_failure("Dissector bug: %s",
375
0
             exception_message == NULL ?
376
0
         dissector_error_nomsg : exception_message);
377
0
    if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
378
0
      abort();
379
0
    status = false;
380
0
  }
381
14
  ENDTRY;
382
14
  return status;
383
14
}
384
385
/*
386
 * Load all settings, from the current profile, that affect libwireshark.
387
 */
388
e_prefs *
389
epan_load_settings(void)
390
14
{
391
14
  e_prefs *prefs_p;
392
393
  /* load the decode as entries of the current profile */
394
14
  load_decode_as_entries();
395
396
14
  prefs_p = read_prefs();
397
398
  /*
399
   * Read the files that enable and disable protocols and heuristic
400
   * dissectors.
401
   */
402
14
  read_enabled_and_disabled_lists();
403
404
14
  return prefs_p;
405
14
}
406
407
void
408
epan_cleanup(void)
409
0
{
410
0
  g_slist_foreach(epan_plugins, epan_plugin_cleanup, NULL);
411
0
  g_slist_free(epan_plugins);
412
0
  epan_plugins = NULL;
413
0
  g_slist_free(epan_plugin_register_all_procotols);
414
0
  epan_plugin_register_all_procotols = NULL;
415
0
  g_slist_free(epan_plugin_register_all_handoffs);
416
0
  epan_plugin_register_all_handoffs = NULL;
417
418
0
  dfilter_cleanup();
419
0
  decode_clear_all();
420
0
  decode_cleanup();
421
422
#ifdef HAVE_LUA
423
  /*
424
   * Must deregister Proto objects in Lua before destroying dissector
425
   * tables in packet_cleanup(). Doing so will also deregister and free
426
   * preferences, this must happen before prefs_cleanup(). That will
427
   * update the list of deregistered fields which must be followed by
428
   * proto_cleanup() to complete deallocation.
429
   */
430
  wslua_early_cleanup();
431
#endif
432
433
  /*
434
   * Note: packet_cleanup() will call registered shutdown routines which
435
   * may be used to deregister dynamically registered protocol fields,
436
   * and prefs_cleanup() will call uat_clear() which also may be used to
437
   * deregister dynamically registered protocol fields. This must be done
438
   * before proto_cleanup() to avoid inconsistency and memory leaks.
439
   */
440
0
  packet_cleanup();
441
0
  prefs_cleanup();
442
0
  proto_cleanup();
443
444
0
  secrets_cleanup();
445
0
  conversation_filters_cleanup();
446
0
  reassembly_table_cleanup();
447
0
  tap_cleanup();
448
0
  expert_cleanup();
449
0
  capture_dissector_cleanup();
450
0
  export_pdu_cleanup();
451
0
  cleanup_enabled_and_disabled_lists();
452
0
  stats_tree_cleanup();
453
0
  funnel_cleanup();
454
0
  dtd_location(NULL);
455
#ifdef HAVE_LUA
456
  wslua_cleanup();
457
#endif
458
#ifdef HAVE_LIBGNUTLS
459
  gnutls_global_deinit();
460
#endif
461
#ifdef HAVE_LIBXML2
462
  xmlCleanupParser();
463
#endif
464
0
  except_deinit();
465
0
  addr_resolv_cleanup();
466
467
0
  dfilter_translator_cleanup();
468
469
0
  if (pinfo_pool_cache != NULL) {
470
0
    wmem_destroy_allocator(pinfo_pool_cache);
471
0
    pinfo_pool_cache = NULL;
472
0
  }
473
474
0
  wmem_cleanup_scopes();
475
476
#ifdef HAVE_PLUGINS
477
  plugins_cleanup(libwireshark_plugins);
478
  libwireshark_plugins = NULL;
479
#endif
480
0
}
481
482
struct epan_session {
483
  struct packet_provider_data *prov;  /* packet provider data for this session */
484
  struct packet_provider_funcs funcs; /* functions using that data */
485
};
486
487
epan_t *
488
epan_new(struct packet_provider_data *prov,
489
    const struct packet_provider_funcs *funcs)
490
14
{
491
14
  epan_t *session = g_slice_new0(epan_t);
492
493
14
  session->prov = prov;
494
14
  session->funcs = *funcs;
495
496
  /* XXX, it should take session as param */
497
14
  init_dissection();
498
499
14
  return session;
500
14
}
501
502
wtap_block_t
503
epan_get_modified_block(const epan_t *session, const frame_data *fd)
504
0
{
505
0
  if (session->funcs.get_modified_block)
506
0
    return session->funcs.get_modified_block(session->prov, fd);
507
508
0
  return NULL;
509
0
}
510
511
const char *
512
epan_get_interface_name(const epan_t *session, uint32_t interface_id, unsigned section_number)
513
0
{
514
0
  if (session->funcs.get_interface_name)
515
0
    return session->funcs.get_interface_name(session->prov, interface_id, section_number);
516
517
0
  return NULL;
518
0
}
519
520
const char *
521
epan_get_interface_description(const epan_t *session, uint32_t interface_id, unsigned section_number)
522
0
{
523
0
  if (session->funcs.get_interface_description)
524
0
    return session->funcs.get_interface_description(session->prov, interface_id, section_number);
525
526
0
  return NULL;
527
0
}
528
529
const nstime_t *
530
epan_get_frame_ts(const epan_t *session, uint32_t frame_num)
531
167k
{
532
167k
  const nstime_t *abs_ts = NULL;
533
534
167k
  if (session && session->funcs.get_frame_ts)
535
167k
    abs_ts = session->funcs.get_frame_ts(session->prov, frame_num);
536
537
167k
  if (!abs_ts) {
538
    /* This can happen if frame_num doesn't have a ts */
539
0
    ws_debug("!!! couldn't get frame ts for %u !!!\n", frame_num);
540
0
  }
541
542
167k
  return abs_ts;
543
167k
}
544
545
void
546
epan_free(epan_t *session)
547
0
{
548
0
  if (session) {
549
    /* XXX, it should take session as param */
550
0
    cleanup_dissection();
551
552
0
    g_slice_free(epan_t, session);
553
0
  }
554
0
}
555
556
void
557
epan_conversation_init(void)
558
14
{
559
14
  conversation_epan_reset();
560
14
}
561
562
/* Overrides proto_tree_visible i epan_dissect_init to make all fields visible.
563
 * This is > 0 if a Lua script wanted to see all fields all the time.
564
 * This is ref-counted, so clearing it won't override other taps/scripts wanting it.
565
 */
566
static int always_visible_refcount;
567
568
void
569
epan_set_always_visible(bool force)
570
0
{
571
0
  if (force)
572
0
    always_visible_refcount++;
573
0
  else if (always_visible_refcount > 0)
574
0
    always_visible_refcount--;
575
0
}
576
577
void
578
epan_dissect_init(epan_dissect_t *edt, epan_t *session, const bool create_proto_tree, const bool proto_tree_visible)
579
14
{
580
14
  ws_assert(edt);
581
582
14
  edt->session = session;
583
584
14
  memset(&edt->pi, 0, sizeof(edt->pi));
585
14
  if (pinfo_pool_cache != NULL) {
586
0
    edt->pi.pool = pinfo_pool_cache;
587
0
    pinfo_pool_cache = NULL;
588
0
  }
589
14
  else {
590
14
    edt->pi.pool = wmem_allocator_new(WMEM_ALLOCATOR_BLOCK_FAST);
591
14
  }
592
593
14
  if (create_proto_tree) {
594
14
    edt->tree = proto_tree_create_root(&edt->pi);
595
14
    proto_tree_set_visible(edt->tree, (always_visible_refcount > 0) ? true : proto_tree_visible);
596
14
  }
597
0
  else {
598
0
    edt->tree = NULL;
599
0
  }
600
601
14
  edt->tvb = NULL;
602
603
14
  g_slist_foreach(epan_plugins, epan_plugin_dissect_init, edt);
604
14
}
605
606
void
607
epan_dissect_reset(epan_dissect_t *edt)
608
103k
{
609
  /* We have to preserve the pool pointer across the memzeroing */
610
103k
  wmem_allocator_t *tmp;
611
612
103k
  ws_assert(edt);
613
614
103k
  wtap_block_unref(edt->pi.rec->block);
615
616
103k
  g_slist_free(edt->pi.proto_data);
617
618
  /* Free the data sources list. */
619
103k
  free_data_sources(&edt->pi);
620
621
103k
  if (edt->tvb) {
622
    /* Free all tvb's chained from this tvb */
623
103k
    tvb_free_chain(edt->tvb);
624
103k
    edt->tvb = NULL;
625
103k
  }
626
627
103k
  if (edt->tree)
628
103k
    proto_tree_reset(edt->tree);
629
630
103k
  tmp = edt->pi.pool;
631
103k
  wmem_free_all(tmp);
632
633
103k
  memset(&edt->pi, 0, sizeof(edt->pi));
634
103k
  edt->pi.pool = tmp;
635
103k
}
636
637
epan_dissect_t*
638
epan_dissect_new(epan_t *session, const bool create_proto_tree, const bool proto_tree_visible)
639
14
{
640
14
  epan_dissect_t *edt;
641
642
14
  edt = g_new0(epan_dissect_t, 1);
643
644
14
  epan_dissect_init(edt, session, create_proto_tree, proto_tree_visible);
645
14
  return edt;
646
14
}
647
648
void
649
epan_dissect_fake_protocols(epan_dissect_t *edt, const bool fake_protocols)
650
0
{
651
0
  if (edt)
652
0
    proto_tree_set_fake_protocols(edt->tree, fake_protocols);
653
0
}
654
655
void
656
epan_dissect_run(epan_dissect_t *edt, int file_type_subtype,
657
  wtap_rec *rec, frame_data *fd, column_info *cinfo)
658
103k
{
659
#ifdef HAVE_LUA
660
  wslua_prime_dfilter(edt); /* done before entering wmem scope */
661
#endif
662
103k
  wmem_enter_packet_scope();
663
103k
  dissect_record(edt, file_type_subtype, rec, fd, cinfo);
664
665
  /* free all memory allocated */
666
103k
  wmem_leave_packet_scope();
667
103k
  wtap_block_unref(rec->block);
668
103k
  rec->block = NULL;
669
103k
}
670
671
void
672
epan_dissect_run_with_taps(epan_dissect_t *edt, int file_type_subtype,
673
  wtap_rec *rec, frame_data *fd, column_info *cinfo)
674
0
{
675
0
  wmem_enter_packet_scope();
676
0
  tap_queue_init(edt);
677
0
  dissect_record(edt, file_type_subtype, rec, fd, cinfo);
678
0
  tap_push_tapped_queue(edt);
679
680
  /* free all memory allocated */
681
0
  wmem_leave_packet_scope();
682
0
  wtap_block_unref(rec->block);
683
0
  rec->block = NULL;
684
0
}
685
686
void
687
epan_dissect_file_run(epan_dissect_t *edt, wtap_rec *rec,
688
  frame_data *fd, column_info *cinfo)
689
0
{
690
#ifdef HAVE_LUA
691
  wslua_prime_dfilter(edt); /* done before entering wmem scope */
692
#endif
693
0
  wmem_enter_packet_scope();
694
0
  dissect_file(edt, rec, fd, cinfo);
695
696
  /* free all memory allocated */
697
0
  wmem_leave_packet_scope();
698
0
  wtap_block_unref(rec->block);
699
0
  rec->block = NULL;
700
0
}
701
702
void
703
epan_dissect_file_run_with_taps(epan_dissect_t *edt, wtap_rec *rec,
704
  frame_data *fd, column_info *cinfo)
705
0
{
706
0
  wmem_enter_packet_scope();
707
0
  tap_queue_init(edt);
708
0
  dissect_file(edt, rec, fd, cinfo);
709
0
  tap_push_tapped_queue(edt);
710
711
  /* free all memory allocated */
712
0
  wmem_leave_packet_scope();
713
0
  wtap_block_unref(rec->block);
714
0
  rec->block = NULL;
715
0
}
716
717
void
718
epan_dissect_cleanup(epan_dissect_t* edt)
719
0
{
720
0
  ws_assert(edt);
721
722
0
  g_slist_foreach(epan_plugins, epan_plugin_dissect_cleanup, edt);
723
724
0
  g_slist_free(edt->pi.proto_data);
725
726
  /* Free the data sources list. */
727
0
  free_data_sources(&edt->pi);
728
729
0
  if (edt->tvb) {
730
    /* Free all tvb's chained from this tvb */
731
0
    tvb_free_chain(edt->tvb);
732
0
  }
733
734
0
  if (edt->tree) {
735
0
    proto_tree_free(edt->tree);
736
0
  }
737
738
0
  if (pinfo_pool_cache == NULL) {
739
0
    wmem_free_all(edt->pi.pool);
740
0
    pinfo_pool_cache = edt->pi.pool;
741
0
  }
742
0
  else {
743
0
    wmem_destroy_allocator(edt->pi.pool);
744
0
  }
745
0
}
746
747
void
748
epan_dissect_free(epan_dissect_t* edt)
749
0
{
750
0
  epan_dissect_cleanup(edt);
751
0
  g_free(edt);
752
0
}
753
754
void
755
epan_dissect_prime_with_dfilter(epan_dissect_t *edt, const dfilter_t* dfcode)
756
0
{
757
0
  dfilter_prime_proto_tree(dfcode, edt->tree);
758
0
}
759
760
void
761
epan_dissect_prime_with_dfilter_print(epan_dissect_t *edt, const dfilter_t* dfcode)
762
0
{
763
0
  dfilter_prime_proto_tree_print(dfcode, edt->tree);
764
0
}
765
766
void
767
epan_dissect_prime_with_hfid(epan_dissect_t *edt, int hfid)
768
0
{
769
0
  proto_tree_prime_with_hfid(edt->tree, hfid);
770
0
}
771
772
void
773
epan_dissect_prime_with_hfid_array(epan_dissect_t *edt, GArray *hfids)
774
0
{
775
0
  unsigned i;
776
777
0
  for (i = 0; i < hfids->len; i++) {
778
0
    proto_tree_prime_with_hfid(edt->tree,
779
0
        g_array_index(hfids, int, i));
780
0
  }
781
0
}
782
783
/* ----------------------- */
784
const char *
785
epan_custom_set(epan_dissect_t *edt, GSList *field_ids,
786
           int occurrence,
787
           bool display_details,
788
           char *result,
789
           char *expr, const int size )
790
0
{
791
0
  return proto_custom_set(edt->tree, field_ids, occurrence, display_details, result, expr, size);
792
0
}
793
794
void
795
epan_dissect_fill_in_columns(epan_dissect_t *edt, const bool fill_col_exprs, const bool fill_fd_colums)
796
0
{
797
0
  col_custom_set_edt(edt, edt->pi.cinfo);
798
0
  col_fill_in(&edt->pi, fill_col_exprs, fill_fd_colums);
799
0
}
800
801
bool
802
epan_dissect_packet_contains_field(epan_dissect_t* edt,
803
           const char *field_name)
804
0
{
805
0
  GPtrArray* array;
806
0
  int field_id;
807
0
  bool contains_field;
808
809
0
  if (!edt || !edt->tree)
810
0
    return false;
811
0
  field_id = proto_get_id_by_filter_name(field_name);
812
0
  if (field_id < 0)
813
0
    return false;
814
0
  array = proto_find_finfo(edt->tree, field_id);
815
0
  contains_field = (array->len > 0) ? true : false;
816
0
  g_ptr_array_free(array, true);
817
0
  return contains_field;
818
0
}
819
820
/*
821
 * Get compile-time information for libraries used by libwireshark.
822
 */
823
void
824
epan_gather_compile_info(feature_list l)
825
14
{
826
14
  gather_zlib_compile_info(l);
827
14
  gather_zlib_ng_compile_info(l);
828
14
  gather_pcre2_compile_info(l);
829
830
  /* Lua */
831
#ifdef HAVE_LUA
832
#ifdef HAVE_LUA_UNICODE
833
  with_feature(l, "%s", LUA_RELEASE" (UfW patched)");
834
#else /* HAVE_LUA_UNICODE */
835
  with_feature(l, "%s", LUA_RELEASE);
836
#endif /* HAVE_LUA_UNICODE */
837
#else /* HAVE_LUA */
838
14
  without_feature(l, "Lua");
839
14
#endif /* HAVE_LUA */
840
841
  /* GnuTLS */
842
#ifdef HAVE_LIBGNUTLS
843
#ifdef HAVE_GNUTLS_PKCS11
844
  with_feature(l, "GnuTLS %s and PKCS#11", LIBGNUTLS_VERSION);
845
#else
846
  with_feature(l, "GnuTLS %s", LIBGNUTLS_VERSION);
847
#endif /* HAVE_GNUTLS_PKCS11 */
848
#else
849
14
  without_feature(l, "GnuTLS");
850
14
#endif /* HAVE_LIBGNUTLS */
851
852
  /* Gcrypt */
853
14
  with_feature(l, "Gcrypt %s", GCRYPT_VERSION);
854
855
  /* Kerberos */
856
#if defined(HAVE_MIT_KERBEROS)
857
  with_feature(l, "Kerberos (MIT)");
858
#elif defined(HAVE_HEIMDAL_KERBEROS)
859
  with_feature(l, "Kerberos (Heimdal)");
860
#else
861
14
  without_feature(l, "Kerberos");
862
14
#endif /* HAVE_KERBEROS */
863
864
  /* MaxMindDB */
865
#ifdef HAVE_MAXMINDDB
866
  with_feature(l, "MaxMind %s", MAXMINDDB_VERSION);
867
#else
868
14
  without_feature(l, "MaxMind");
869
14
#endif /* HAVE_MAXMINDDB */
870
871
  /* nghttp2 */
872
#ifdef HAVE_NGHTTP2
873
  with_feature(l, "nghttp2 %s", NGHTTP2_VERSION);
874
#else
875
14
  without_feature(l, "nghttp2");
876
14
#endif /* HAVE_NGHTTP2 */
877
878
  /* nghttp3 */
879
#ifdef HAVE_NGHTTP3
880
  with_feature(l, "nghttp3 %s", NGHTTP3_VERSION);
881
#else
882
14
  without_feature(l, "nghttp3");
883
14
#endif /* HAVE_NGHTTP3 */
884
885
  /* brotli */
886
#ifdef HAVE_BROTLI
887
  with_feature(l, "brotli");
888
#else
889
14
  without_feature(l, "brotli");
890
14
#endif /* HAVE_BROTLI */
891
892
  /* LZ4 */
893
#ifdef HAVE_LZ4
894
  with_feature(l, "LZ4 %s", LZ4_VERSION_STRING);
895
#else
896
14
  without_feature(l, "LZ4");
897
14
#endif /* HAVE_LZ4 */
898
899
  /* Zstandard */
900
#ifdef HAVE_ZSTD
901
  with_feature(l, "Zstandard %s", ZSTD_VERSION_STRING);
902
#else
903
14
  without_feature(l, "Zstandard");
904
14
#endif /* HAVE_ZSTD */
905
906
  /* Snappy */
907
#ifdef HAVE_SNAPPY
908
  /*
909
   * snappy-stubs-public.h defines SNAPPY_MAJOR, SNAPPY_MINOR,
910
   * and SNAPPY_PATCHLEVEL, but it's a C++-only header.
911
   */
912
  with_feature(l, "Snappy %s", SNAPPY_VERSION);
913
#else
914
14
  without_feature(l, "Snappy");
915
14
#endif /* HAVE_SNAPPY */
916
917
  /* libxml2 */
918
#ifdef HAVE_LIBXML2
919
  with_feature(l, "libxml2 %s", LIBXML_DOTTED_VERSION);
920
#else
921
14
  without_feature(l, "libxml2");
922
14
#endif /* HAVE_LIBXML2 */
923
924
  /* libsmi */
925
#ifdef HAVE_LIBSMI
926
  with_feature(l, "libsmi %s", SMI_VERSION_STRING);
927
#else
928
14
  without_feature(l, "libsmi");
929
14
#endif /* HAVE_LIBSMI */
930
14
}
931
932
/*
933
 * Get runtime information for libraries used by libwireshark.
934
 */
935
void
936
epan_gather_runtime_info(feature_list l)
937
14
{
938
14
  gather_zlib_runtime_info(l);
939
14
  gather_pcre2_runtime_info(l);
940
941
  /* c-ares */
942
14
  with_feature(l, "c-ares %s", ares_version(NULL));
943
944
  /* GnuTLS */
945
#ifdef HAVE_LIBGNUTLS
946
  with_feature(l, "GnuTLS %s", gnutls_check_version(NULL));
947
#endif /* HAVE_LIBGNUTLS */
948
949
  /* Gcrypt */
950
14
  with_feature(l, "Gcrypt %s", gcry_check_version(NULL));
951
952
  /* nghttp2 */
953
#if NGHTTP2_VERSION_AGE >= 1
954
  nghttp2_info *nghttp2_ptr = nghttp2_version(0);
955
  with_feature(l, "nghttp2 %s",  nghttp2_ptr->version_str);
956
#endif /* NGHTTP2_VERSION_AGE */
957
958
  /* nghttp3 */
959
#if NGHTTP3_VERSION_AGE >= 1
960
  const nghttp3_info *nghttp3_ptr = nghttp3_version(0);
961
  with_feature(l, "nghttp3 %s", nghttp3_ptr->version_str);
962
#endif /* NGHTTP3_VERSION_AGE */
963
964
  /* brotli */
965
#ifdef HAVE_BROTLI
966
  with_feature(l, "brotli %d.%d.%d", BrotliDecoderVersion() >> 24,
967
    (BrotliDecoderVersion() >> 12) & 0xFFF, BrotliDecoderVersion() & 0xFFF);
968
#endif
969
970
  /* LZ4 */
971
#ifdef HAVE_LZ4
972
  with_feature(l, "LZ4 %s", LZ4_versionString());
973
#endif /* HAVE_LZ4 */
974
975
  /* Zstandard */
976
#if ZSTD_VERSION_NUMBER >= 10300
977
  with_feature(l, "Zstandard %s", ZSTD_versionString());
978
#endif /* ZSTD_VERSION_NUMBER */
979
980
  /* libsmi */
981
#ifdef HAVE_SMI_VERSION_STRING
982
  with_feature(l, "libsmi %s", smi_version_string);
983
#endif /* HAVE_SMI_VERSION_STRING */
984
14
}
985
986
/*
987
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
988
 *
989
 * Local variables:
990
 * c-basic-offset: 8
991
 * tab-width: 8
992
 * indent-tabs-mode: t
993
 * End:
994
 *
995
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
996
 * :indentSize=8:tabSize=8:noTabs=false:
997
 */