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