dcerpc-netlogon: improve NetrLogonGetCapabilities dissection
[wireshark-sm.git] / epan / packet.c
blob08e61e435e37b1c46975c8abcd6327618ab8ef33
1 /* packet.c
2 * Routines for packet disassembly
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
11 #include "config.h"
12 #define WS_LOG_DOMAIN LOG_DOMAIN_EPAN
14 #include <glib.h>
16 #include <stdio.h>
17 #include <stdlib.h>
19 #include <stdarg.h>
20 #include <string.h>
21 #include <time.h>
23 #include "packet.h"
24 #include "timestamp.h"
26 #include "osi-utils.h"
27 #include "to_str.h"
29 #include "addr_resolv.h"
30 #include "tvbuff.h"
31 #include "epan_dissect.h"
33 #include <epan/wmem_scopes.h>
35 #include <epan/column-info.h>
36 #include <epan/exceptions.h>
37 #include <epan/reassemble.h>
38 #include <epan/stream.h>
39 #include <epan/expert.h>
40 #include <epan/prefs.h>
41 #include <epan/range.h>
43 #include <wsutil/str_util.h>
44 #include <wsutil/wslog.h>
45 #include <wsutil/ws_assert.h>
47 static int proto_malformed;
48 static dissector_handle_t frame_handle;
49 static dissector_handle_t file_handle;
50 static dissector_handle_t data_handle;
52 /**
53 * A data source.
54 * Has a tvbuff and a name.
56 struct data_source {
57 tvbuff_t *tvb;
58 char *name;
62 * A dissector table.
64 * "hash_table" is a hash table, indexed by port number, supplying
65 * a "struct dtbl_entry"; it records what dissector is assigned to
66 * that uint or string value in that table.
68 * "dissector_handles" is a list of all dissectors that *could* be
69 * used in that table; not all of them are necessarily in the table,
70 * as they may be for protocols that don't have a fixed uint value,
71 * e.g. for TCP or UDP port number tables and protocols with no fixed
72 * port number.
74 * "ui_name" is the name the dissector table has in the user interface.
76 * "type" is a field type giving the width of the uint value for that
77 * dissector table, if it's a uint dissector table.
79 * "param" is the base in which to display the uint value for that
80 * dissector table, if it's a uint dissector table, or if it's a string
81 * table, true/false to indicate case-insensitive or not.
83 * "protocol" is the protocol associated with the dissector table. Used
84 * for determining dependencies.
86 struct dissector_table {
87 GHashTable *hash_table;
88 GSList *dissector_handles;
89 const char *ui_name;
90 ftenum_t type;
91 int param;
92 protocol_t *protocol;
93 GHashFunc hash_func;
94 bool supports_decode_as;
98 * Dissector tables. const char * -> dissector_table *
100 static GHashTable *dissector_tables;
101 static bool all_tables_handles_sorted = false;
104 * Dissector table aliases. const char * -> const char *
106 static GHashTable *dissector_table_aliases;
109 * List of registered dissectors.
111 static GHashTable *registered_dissectors;
114 * A dissector dependency list.
116 struct depend_dissector_list {
117 GSList *dissectors;
120 /* Maps char *dissector_name to depend_dissector_list_t */
121 static GHashTable *depend_dissector_lists;
123 /* Allow protocols to register a "cleanup" routine to be
124 * run after the initial sequential run through the packets.
125 * Note that the file can still be open after this; this is not
126 * the final cleanup. */
127 static GSList *postseq_cleanup_routines;
130 * Post-dissector information - handle for the dissector and a list
131 * of hfids for the fields the post-dissector wants.
133 typedef struct {
134 dissector_handle_t handle;
135 GArray *wanted_hfids;
136 } postdissector;
139 * Array of all postdissectors.
141 static GArray *postdissectors;
144 * i-th element of that array.
146 #define POSTDISSECTORS(i) g_array_index(postdissectors, postdissector, i)
148 static void
149 destroy_depend_dissector_list(void *data)
151 depend_dissector_list_t dissector_list = (depend_dissector_list_t)data;
152 GSList **list = &(dissector_list->dissectors);
154 g_slist_free_full(*list, g_free);
155 g_slice_free(struct depend_dissector_list, dissector_list);
159 * A heuristics dissector list.
161 struct heur_dissector_list {
162 const char *ui_name;
163 protocol_t *protocol;
164 GSList *dissectors;
167 static GHashTable *heur_dissector_lists;
169 /* Name hashtables for fast detection of duplicate names */
170 static GHashTable* heuristic_short_names;
172 static void
173 destroy_heuristic_dissector_entry(void *data)
175 heur_dtbl_entry_t *hdtbl_entry = (heur_dtbl_entry_t *)data;
176 g_free(hdtbl_entry->list_name);
177 g_free(hdtbl_entry->short_name);
178 g_slice_free(heur_dtbl_entry_t, data);
181 static void
182 destroy_heuristic_dissector_list(void *data)
184 heur_dissector_list_t dissector_list = (heur_dissector_list_t)data;
185 GSList **list = &(dissector_list->dissectors);
187 g_slist_free_full(*list, destroy_heuristic_dissector_entry);
188 g_slice_free(struct heur_dissector_list, dissector_list);
191 static void
192 destroy_dissector_table(void *data)
194 struct dissector_table *table = (struct dissector_table *)data;
196 g_hash_table_destroy(table->hash_table);
197 g_slist_free(table->dissector_handles);
198 g_slice_free(struct dissector_table, data);
201 void
202 packet_init(void)
204 dissector_tables = g_hash_table_new_full(g_str_hash, g_str_equal,
205 NULL, destroy_dissector_table);
206 all_tables_handles_sorted = false;
208 dissector_table_aliases = g_hash_table_new_full(g_str_hash, g_str_equal,
209 NULL, NULL);
211 registered_dissectors = g_hash_table_new_full(g_str_hash, g_str_equal,
212 NULL, NULL);
214 depend_dissector_lists = g_hash_table_new_full(g_str_hash, g_str_equal,
215 g_free, destroy_depend_dissector_list);
217 heur_dissector_lists = g_hash_table_new_full(g_str_hash, g_str_equal,
218 NULL, destroy_heuristic_dissector_list);
220 heuristic_short_names = g_hash_table_new(g_str_hash, g_str_equal);
223 void
224 packet_cache_proto_handles(void)
226 frame_handle = find_dissector("frame");
227 ws_assert(frame_handle != NULL);
229 file_handle = find_dissector("file");
230 ws_assert(file_handle != NULL);
232 data_handle = find_dissector("data");
233 ws_assert(data_handle != NULL);
235 proto_malformed = proto_get_id_by_filter_name("_ws.malformed");
236 ws_assert(proto_malformed != -1);
239 /* List of routines that are called before we make a pass through a capture file
240 * and dissect all its packets. See register_init_routine, register_cleanup_routine
241 * and register_shutdown_routine in packet.h */
243 * List of "init" routines, which are called before we make a pass through
244 * a capture file and dissect all its packets (e.g., when we read in a
245 * new capture file, or run a "filter packets" or "colorize packets"
246 * pass over the current capture file or when the preferences are changed).
248 * See register_init_routine().
250 static GSList *init_routines;
253 * List of "cleanup" routines, which are called after closing a capture
254 * file (or when preferences are changed; in that case these routines
255 * are called before the init routines are executed). They can be used
256 * to release resources that are allocated in an "init" routine.
258 * See register_cleanup_routine().
260 static GSList *cleanup_routines;
263 * List of "shutdown" routines, which are called once, just before
264 * program exit.
266 * See register_shutdown_routine().
268 static GSList *shutdown_routines;
270 typedef void (*void_func_t)(void);
272 /* Initialize all data structures used for dissection. */
273 static void
274 call_routine(void *routine, void *dummy _U_)
276 void_func_t func = (void_func_t)routine;
277 (*func)();
280 void
281 packet_cleanup(void)
283 g_slist_free(init_routines);
284 g_slist_free(cleanup_routines);
285 g_slist_free(postseq_cleanup_routines);
286 g_hash_table_destroy(dissector_tables);
287 g_hash_table_destroy(dissector_table_aliases);
288 g_hash_table_destroy(registered_dissectors);
289 g_hash_table_destroy(depend_dissector_lists);
290 g_hash_table_destroy(heur_dissector_lists);
291 g_hash_table_destroy(heuristic_short_names);
292 g_slist_foreach(shutdown_routines, &call_routine, NULL);
293 g_slist_free(shutdown_routines);
294 if (postdissectors) {
295 for (unsigned i = 0; i < postdissectors->len; i++) {
296 if (POSTDISSECTORS(i).wanted_hfids) {
297 g_array_free(POSTDISSECTORS(i).wanted_hfids, true);
300 g_array_free(postdissectors, true);
305 * Given a tvbuff, and a length from a packet header, adjust the length
306 * of the tvbuff to reflect the specified length.
308 void
309 set_actual_length(tvbuff_t *tvb, const unsigned specified_len)
311 if (specified_len < tvb_reported_length(tvb)) {
312 /* Adjust the length of this tvbuff to include only the specified
313 payload length.
315 The dissector above the one calling us (the dissector above is
316 probably us) may use that to determine how much of its packet
317 was padding. */
318 tvb_set_reported_length(tvb, specified_len);
322 void
323 register_init_routine(void (*func)(void))
325 init_routines = g_slist_prepend(init_routines, (void *)func);
328 void
329 register_cleanup_routine(void (*func)(void))
331 cleanup_routines = g_slist_prepend(cleanup_routines, (void *)func);
334 /* register a new shutdown routine */
335 void
336 register_shutdown_routine(void (*func)(void))
338 shutdown_routines = g_slist_prepend(shutdown_routines, (void *)func);
341 /* Initialize all data structures used for dissection. */
342 void
343 init_dissection(void)
346 * Reinitialize resolution information. Don't leak host entries from
347 * one file to another (e.g. embarrassing-host-name.example.com from
348 * file1.pcapng into a name resolution block in file2.pcapng).
350 host_name_lookup_reset();
352 wmem_enter_file_scope();
354 /* Initialize the table of conversations. */
355 epan_conversation_init();
357 /* Initialize protocol-specific variables. */
358 g_slist_foreach(init_routines, &call_routine, NULL);
360 /* Initialize the stream-handling tables */
361 stream_init();
363 /* Initialize the expert infos */
364 expert_packet_init();
367 void
368 cleanup_dissection(void)
370 /* Cleanup protocol-specific variables. */
371 g_slist_foreach(cleanup_routines, &call_routine, NULL);
373 /* Cleanup the stream-handling tables */
374 stream_cleanup();
376 /* Cleanup the expert infos */
377 expert_packet_cleanup();
379 wmem_leave_file_scope();
382 * Keep the name resolution info around until we start the next
383 * dissection. Lua scripts may potentially do name resolution at
384 * any time, even if we're not dissecting and have no capture
385 * file open.
389 void
390 register_postseq_cleanup_routine(void_func_t func)
392 postseq_cleanup_routines = g_slist_prepend(postseq_cleanup_routines,
393 (void *)func);
396 /* Call all the registered "postseq_cleanup" routines. */
397 void
398 postseq_cleanup_all_protocols(void)
400 g_slist_foreach(postseq_cleanup_routines,
401 &call_routine, NULL);
405 * Add a new data source to the list of data sources for a frame, given
406 * the tvbuff for the data source and its name.
408 void
409 add_new_data_source(packet_info *pinfo, tvbuff_t *tvb, const char *name)
411 struct data_source *src;
413 src = wmem_new(pinfo->pool, struct data_source);
414 src->tvb = tvb;
415 src->name = wmem_strdup(pinfo->pool, name);
416 /* This could end up slow, but we should never have that many data
417 * sources so it probably doesn't matter */
418 pinfo->data_src = g_slist_append(pinfo->data_src, src);
421 void
422 remove_last_data_source(packet_info *pinfo)
424 GSList *last;
426 last = g_slist_last(pinfo->data_src);
427 pinfo->data_src = g_slist_delete_link(pinfo->data_src, last);
430 char*
431 get_data_source_name(const struct data_source *src)
433 unsigned length = tvb_captured_length(src->tvb);
435 return wmem_strdup_printf(NULL, "%s (%u byte%s)", src->name, length,
436 plurality(length, "", "s"));
439 tvbuff_t *
440 get_data_source_tvb(const struct data_source *src)
442 return src->tvb;
446 * Find and return the tvb associated with the given data source name
448 tvbuff_t *
449 get_data_source_tvb_by_name(packet_info *pinfo, const char *name)
451 GSList *source;
452 for (source = pinfo->data_src; source; source = source->next) {
453 struct data_source *this_source = (struct data_source *)source->data;
454 if (this_source->name && strcmp(this_source->name, name) == 0) {
455 return this_source->tvb;
458 return NULL;
463 * Free up a frame's list of data sources.
465 void
466 free_data_sources(packet_info *pinfo)
468 if (pinfo->data_src) {
469 g_slist_free(pinfo->data_src);
470 pinfo->data_src = NULL;
474 void
475 mark_frame_as_depended_upon(frame_data *fd, uint32_t frame_num)
477 /* Don't mark a frame as dependent on itself */
478 if (frame_num != fd->num) {
479 /* ws_assert(frame_num < fd->num) - we assume in several other
480 * places in the code that frames don't depend on future
481 * frames. */
482 if (fd->dependent_frames == NULL) {
483 fd->dependent_frames = g_hash_table_new(g_direct_hash, g_direct_equal);
485 g_hash_table_add(fd->dependent_frames, GUINT_TO_POINTER(frame_num));
489 /* Allow dissectors to register a "final_registration" routine
490 * that is run like the proto_register_XXX() routine, but at the
491 * end of the epan_init() function; that is, *after* all other
492 * subsystems, like dfilters, have finished initializing. This is
493 * useful for dissector registration routines which need to compile
494 * display filters. dfilters can't initialize itself until all protocols
495 * have registered themselves. */
496 static GSList *final_registration_routines;
498 void
499 register_final_registration_routine(void (*func)(void))
501 final_registration_routines = g_slist_prepend(final_registration_routines,
502 (void *)func);
505 /* Call all the registered "final_registration" routines. */
506 void
507 final_registration_all_protocols(void)
509 g_slist_foreach(final_registration_routines,
510 &call_routine, NULL);
514 /* Creates the top-most tvbuff and calls dissect_frame() */
515 void
516 dissect_record(epan_dissect_t *edt, int file_type_subtype,
517 wtap_rec *rec, tvbuff_t *tvb, frame_data *fd, column_info *cinfo)
519 const char *volatile record_type;
520 frame_data_t frame_dissector_data;
522 switch (rec->rec_type) {
524 case REC_TYPE_PACKET:
525 record_type = "Frame";
526 break;
528 case REC_TYPE_FT_SPECIFIC_EVENT:
529 record_type = "Event";
530 break;
532 case REC_TYPE_FT_SPECIFIC_REPORT:
533 record_type = "Report";
534 break;
536 case REC_TYPE_SYSCALL:
537 record_type = "System Call";
538 break;
540 case REC_TYPE_SYSTEMD_JOURNAL_EXPORT:
541 record_type = "Systemd Journal Entry";
542 break;
544 case REC_TYPE_CUSTOM_BLOCK:
545 switch (rec->rec_header.custom_block_header.pen) {
546 case PEN_NFLX:
547 record_type = "Black Box Log Block";
548 break;
549 default:
550 record_type = "PCAPNG Custom Block";
551 break;
553 break;
555 default:
557 * XXX - if we add record types that shouldn't be
558 * dissected and displayed, but that need to at
559 * least be processed somewhere, we need to somehow
560 * indicate that to our caller.
562 ws_assert_not_reached();
563 break;
566 if (cinfo != NULL)
567 col_init(cinfo, edt->session);
568 edt->pi.epan = edt->session;
569 /* edt->pi.pool created in epan_dissect_init() */
570 edt->pi.current_proto = "<Missing Protocol Name>";
571 edt->pi.cinfo = cinfo;
572 edt->pi.presence_flags = 0;
573 edt->pi.num = fd->num;
575 * XXX - this doesn't check the wtap_rec because, for
576 * some capture files, time stamps are supplied only
577 * when reading sequentially, so we keep the time stamp
578 * in the frame_data structure.
580 if (fd->has_ts) {
581 edt->pi.presence_flags |= PINFO_HAS_TS;
582 edt->pi.abs_ts = fd->abs_ts;
584 switch (rec->rec_type) {
586 case REC_TYPE_PACKET:
587 edt->pi.pseudo_header = &rec->rec_header.packet_header.pseudo_header;
588 break;
590 case REC_TYPE_FT_SPECIFIC_EVENT:
591 case REC_TYPE_FT_SPECIFIC_REPORT:
592 edt->pi.pseudo_header = NULL;
593 break;
595 case REC_TYPE_SYSCALL:
596 edt->pi.pseudo_header = NULL;
597 break;
599 case REC_TYPE_SYSTEMD_JOURNAL_EXPORT:
600 edt->pi.pseudo_header = NULL;
601 break;
603 case REC_TYPE_CUSTOM_BLOCK:
604 switch (rec->rec_header.custom_block_header.pen) {
605 case PEN_NFLX:
606 edt->pi.pseudo_header = NULL;
607 break;
608 default:
609 edt->pi.pseudo_header = NULL;
610 break;
612 break;
616 edt->pi.fd = fd;
617 edt->pi.rec = rec;
618 clear_address(&edt->pi.dl_src);
619 clear_address(&edt->pi.dl_dst);
620 clear_address(&edt->pi.net_src);
621 clear_address(&edt->pi.net_dst);
622 clear_address(&edt->pi.src);
623 clear_address(&edt->pi.dst);
624 edt->pi.noreassembly_reason = "";
625 edt->pi.ptype = PT_NONE;
626 edt->pi.use_conv_addr_port_endpoints = false;
627 edt->pi.conv_addr_port_endpoints = NULL;
628 edt->pi.conv_elements = NULL;
629 edt->pi.p2p_dir = P2P_DIR_UNKNOWN;
630 edt->pi.link_dir = LINK_DIR_UNKNOWN;
631 edt->pi.src_win_scale = -1; /* unknown Rcv.Wind.Shift */
632 edt->pi.dst_win_scale = -1; /* unknown Rcv.Wind.Shift */
633 edt->pi.layers = wmem_list_new(edt->pi.pool);
634 edt->tvb = tvb;
636 frame_delta_abs_time(edt->session, fd, fd->frame_ref_num, &edt->pi.rel_ts);
638 if (rec->ts_rel_cap_valid) {
639 nstime_copy(&edt->pi.rel_cap_ts, &rec->ts_rel_cap);
640 edt->pi.rel_cap_ts_present = true;
644 * If the block has been modified, use the modified block,
645 * otherwise use the block from the file.
647 if (fd->has_modified_block) {
648 frame_dissector_data.pkt_block = epan_get_modified_block(edt->session, fd);
650 else {
651 frame_dissector_data.pkt_block = rec->block;
653 frame_dissector_data.file_type_subtype = file_type_subtype;
654 frame_dissector_data.color_edt = edt; /* Used strictly for "coloring rules" */
656 TRY {
657 /* Add this tvbuffer into the data_src list */
658 add_new_data_source(&edt->pi, edt->tvb, record_type);
660 /* Even though dissect_frame() catches all the exceptions a
661 * sub-dissector can throw, dissect_frame() itself may throw
662 * a ReportedBoundsError in bizarre cases. Thus, we catch the exception
663 * in this function. */
664 call_dissector_with_data(frame_handle, edt->tvb, &edt->pi, edt->tree, &frame_dissector_data);
666 CATCH(BoundsError) {
667 ws_assert_not_reached();
669 CATCH2(FragmentBoundsError, ReportedBoundsError) {
670 proto_tree_add_protocol_format(edt->tree, proto_malformed, edt->tvb, 0, 0,
671 "[Malformed %s: Packet Length]",
672 record_type);
674 ENDTRY;
675 wtap_block_unref(rec->block);
676 rec->block = NULL;
678 fd->visited = 1;
681 /* Creates the top-most tvbuff and calls dissect_file() */
682 void
683 dissect_file(epan_dissect_t *edt, wtap_rec *rec,
684 tvbuff_t *tvb, frame_data *fd, column_info *cinfo)
686 file_data_t file_dissector_data;
688 if (cinfo != NULL)
689 col_init(cinfo, edt->session);
690 edt->pi.epan = edt->session;
691 /* edt->pi.pool created in epan_dissect_init() */
692 edt->pi.current_proto = "<Missing Filetype Name>";
693 edt->pi.cinfo = cinfo;
694 edt->pi.fd = fd;
695 edt->pi.rec = rec;
696 edt->pi.pseudo_header = NULL;
697 clear_address(&edt->pi.dl_src);
698 clear_address(&edt->pi.dl_dst);
699 clear_address(&edt->pi.net_src);
700 clear_address(&edt->pi.net_dst);
701 clear_address(&edt->pi.src);
702 clear_address(&edt->pi.dst);
703 edt->pi.noreassembly_reason = "";
704 edt->pi.ptype = PT_NONE;
705 edt->pi.use_conv_addr_port_endpoints = false;
706 edt->pi.conv_addr_port_endpoints = NULL;
707 edt->pi.conv_elements = NULL;
708 edt->pi.p2p_dir = P2P_DIR_UNKNOWN;
709 edt->pi.link_dir = LINK_DIR_UNKNOWN;
710 edt->pi.layers = wmem_list_new(edt->pi.pool);
711 edt->tvb = tvb;
714 frame_delta_abs_time(edt->session, fd, fd->frame_ref_num, &edt->pi.rel_ts);
717 TRY {
719 * If the block has been modified, use the modified block,
720 * otherwise use the block from the file.
722 if (fd->has_modified_block) {
723 file_dissector_data.pkt_block = epan_get_modified_block(edt->session, fd);
725 else {
726 file_dissector_data.pkt_block = rec->block;
728 file_dissector_data.color_edt = edt; /* Used strictly for "coloring rules" */
731 /* Add this tvbuffer into the data_src list */
732 add_new_data_source(&edt->pi, edt->tvb, "File");
734 /* Even though dissect_file() catches all the exceptions a
735 * sub-dissector can throw, dissect_frame() itself may throw
736 * a ReportedBoundsError in bizarre cases. Thus, we catch the exception
737 * in this function. */
738 call_dissector_with_data(file_handle, edt->tvb, &edt->pi, edt->tree, &file_dissector_data);
741 CATCH(BoundsError) {
742 ws_assert_not_reached();
744 CATCH3(FragmentBoundsError, ContainedBoundsError, ReportedBoundsError) {
745 proto_tree_add_protocol_format(edt->tree, proto_malformed, edt->tvb, 0, 0,
746 "[Malformed Record: Packet Length]");
748 ENDTRY;
749 wtap_block_unref(rec->block);
750 rec->block = NULL;
752 fd->visited = 1;
755 /*********************** code added for sub-dissector lookup *********************/
757 enum dissector_e {
758 DISSECTOR_TYPE_SIMPLE,
759 DISSECTOR_TYPE_CALLBACK
763 * A dissector handle.
765 struct dissector_handle {
766 const char *name; /* dissector name */
767 const char *description; /* dissector description */
768 char *pref_suffix;
769 enum dissector_e dissector_type;
770 union {
771 dissector_t dissector_type_simple;
772 dissector_cb_t dissector_type_callback;
773 } dissector_func;
774 void *dissector_data;
775 protocol_t *protocol;
778 static void
779 add_layer(packet_info *pinfo, int proto_id)
781 int *proto_layer_num_ptr;
783 pinfo->curr_layer_num++;
784 wmem_list_append(pinfo->layers, GINT_TO_POINTER(proto_id));
786 /* Increment layer number for this proto id. */
787 if (pinfo->proto_layers == NULL) {
788 pinfo->proto_layers = wmem_map_new(pinfo->pool, g_direct_hash, g_direct_equal);
791 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id));
792 if (proto_layer_num_ptr == NULL) {
793 /* Insert new layer */
794 proto_layer_num_ptr = wmem_new(pinfo->pool, int);
795 *proto_layer_num_ptr = 1;
796 wmem_map_insert(pinfo->proto_layers, GINT_TO_POINTER(proto_id), proto_layer_num_ptr);
798 else {
799 /* Increment layer number */
800 (*proto_layer_num_ptr)++;
802 pinfo->curr_proto_layer_num = *proto_layer_num_ptr;
805 static void
806 remove_last_layer(packet_info *pinfo, bool reduce_count)
808 int *proto_layer_num_ptr;
809 wmem_list_frame_t *frame;
810 int proto_id;
812 if (reduce_count) {
813 pinfo->curr_layer_num--;
816 frame = wmem_list_tail(pinfo->layers);
817 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(frame));
818 wmem_list_remove_frame(pinfo->layers, frame);
820 if (reduce_count) {
821 /* Reduce count for removed protocol layer. */
822 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id));
823 if (proto_layer_num_ptr && *proto_layer_num_ptr > 0) {
824 (*proto_layer_num_ptr)--;
828 /* Restore count for new last (protocol) layer. */
829 frame = wmem_list_tail(pinfo->layers);
830 if (frame) {
831 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(frame));
832 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id));
833 ws_assert(proto_layer_num_ptr);
834 pinfo->curr_proto_layer_num = *proto_layer_num_ptr;
839 /* This function will return
840 * >0 this protocol was successfully dissected and this was this protocol.
841 * 0 this packet did not match this protocol.
843 * XXX - if the dissector only dissects metadata passed through the data
844 * pointer, and dissects none of the packet data, that's indistinguishable
845 * from "packet did not match this protocol". See issues #12366 and
846 * #12368.
848 static int
849 call_dissector_through_handle(dissector_handle_t handle, tvbuff_t *tvb,
850 packet_info *pinfo, proto_tree *tree, void *data)
852 const char *saved_proto;
853 int len;
855 saved_proto = pinfo->current_proto;
857 if ((handle->protocol != NULL) && (!proto_is_pino(handle->protocol))) {
858 pinfo->current_proto =
859 proto_get_protocol_short_name(handle->protocol);
862 switch (handle->dissector_type) {
864 case DISSECTOR_TYPE_SIMPLE:
865 len = (handle->dissector_func.dissector_type_simple)(tvb, pinfo, tree, data);
866 break;
868 case DISSECTOR_TYPE_CALLBACK:
869 len = (handle->dissector_func.dissector_type_callback)(tvb, pinfo, tree, data, handle->dissector_data);
870 break;
872 default:
873 ws_assert_not_reached();
875 pinfo->current_proto = saved_proto;
877 return len;
881 * Call a dissector through a handle.
882 * If the protocol for that handle isn't enabled, return 0 without
883 * calling the dissector.
884 * Otherwise, if the handle refers to a new-style dissector, call the
885 * dissector and return its return value, otherwise call it and return
886 * the length of the tvbuff pointed to by the argument.
889 static int
890 call_dissector_work_error(dissector_handle_t handle, tvbuff_t *tvb,
891 packet_info *pinfo_arg, proto_tree *tree, void *);
893 static int
894 call_dissector_work(dissector_handle_t handle, tvbuff_t *tvb, packet_info *pinfo,
895 proto_tree *tree, bool add_proto_name, void *data)
897 const char *saved_proto;
898 uint16_t saved_can_desegment;
899 int len;
900 unsigned saved_layers_len = 0;
901 unsigned saved_tree_count = tree ? tree->tree_data->count : 0;
902 unsigned saved_desegment_len = pinfo->desegment_len;
903 bool consumed_none;
905 if (handle->protocol != NULL &&
906 !proto_is_protocol_enabled(handle->protocol)) {
908 * The protocol isn't enabled.
910 return 0;
913 saved_proto = pinfo->current_proto;
914 saved_can_desegment = pinfo->can_desegment;
915 saved_layers_len = wmem_list_count(pinfo->layers);
916 DISSECTOR_ASSERT(saved_layers_len < prefs.gui_max_tree_depth);
919 * can_desegment is set to 2 by anyone which offers the
920 * desegmentation api/service.
921 * Then every time a subdissector is called it is decremented
922 * by one.
923 * Thus only the subdissector immediately on top of whoever
924 * offers this service can use it.
925 * We save the current value of "can_desegment" for the
926 * benefit of TCP proxying dissectors such as SOCKS, so they
927 * can restore it and allow the dissectors they call to use
928 * the desegmentation service.
930 pinfo->saved_can_desegment = saved_can_desegment;
931 pinfo->can_desegment = saved_can_desegment-(saved_can_desegment>0);
932 if ((handle->protocol != NULL) && (!proto_is_pino(handle->protocol))) {
933 pinfo->current_proto =
934 proto_get_protocol_short_name(handle->protocol);
937 * Add the protocol name to the layers only if told to
938 * do so. Asn2wrs generated dissectors may be added
939 * multiple times otherwise.
941 /* XXX Should we check for a duplicate layer here? */
942 if (add_proto_name) {
943 add_layer(pinfo, proto_get_id(handle->protocol));
947 if (pinfo->flags.in_error_pkt) {
948 len = call_dissector_work_error(handle, tvb, pinfo, tree, data);
949 } else {
951 * Just call the subdissector.
953 len = call_dissector_through_handle(handle, tvb, pinfo, tree, data);
955 consumed_none = len == 0 || (pinfo->desegment_len != saved_desegment_len && pinfo->desegment_offset == 0);
956 /* If len == 0, then the dissector didn't accept the packet.
957 * In the latter case, the dissector accepted the packet, but didn't
958 * consume any bytes because they all belong in a later segment.
959 * In the latter case, we probably won't call a dissector here again
960 * on the next pass, so removing the layer keeps any *further* layers
961 * past this one the same on subsequent passes.
963 * XXX: DISSECTOR_ASSERT that the tree count didn't change? If the
964 * dissector didn't consume any bytes but added items to the tree,
965 * that's improper behavior and needs a rethink. We could also move the
966 * test that the packet didn't change desegment_offset and desegment_len
967 * while rejecting the packet from packet-tcp.c decode_tcp_ports to here.
969 if (handle->protocol != NULL && !proto_is_pino(handle->protocol) && add_proto_name &&
970 (consumed_none || (tree && saved_tree_count == tree->tree_data->count))) {
972 * We've added a layer and either the dissector didn't
973 * consume any data or we didn't add any items to the
974 * tree. Remove it.
976 while (wmem_list_count(pinfo->layers) > saved_layers_len) {
978 * Only reduce the layer number if the dissector didn't
979 * consume any data. Since tree can be NULL on
980 * the first pass, we cannot check it or it will
981 * break dissectors that rely on a stable value.
983 remove_last_layer(pinfo, consumed_none);
986 pinfo->current_proto = saved_proto;
987 pinfo->can_desegment = saved_can_desegment;
988 return len;
992 static int
993 call_dissector_work_error(dissector_handle_t handle, tvbuff_t *tvb,
994 packet_info *pinfo_arg, proto_tree *tree, void *data)
996 packet_info *pinfo = pinfo_arg;
997 const char *saved_proto;
998 uint16_t saved_can_desegment;
999 volatile int len = 0;
1000 bool save_writable;
1001 address save_dl_src;
1002 address save_dl_dst;
1003 address save_net_src;
1004 address save_net_dst;
1005 address save_src;
1006 address save_dst;
1007 uint32_t save_ptype;
1008 uint32_t save_srcport;
1009 uint32_t save_destport;
1012 * This isn't a packet being transported inside
1013 * the protocol whose dissector is calling us,
1014 * it's a copy of a packet that caused an error
1015 * in some protocol included in a packet that
1016 * reports the error (e.g., an ICMP Unreachable
1017 * packet).
1021 * Save the current state of the writability of
1022 * the columns, and restore them after the
1023 * dissector returns, so that the columns
1024 * don't reflect the packet that got the error,
1025 * they reflect the packet that reported the
1026 * error.
1028 saved_proto = pinfo->current_proto;
1029 saved_can_desegment = pinfo->can_desegment;
1031 save_writable = col_get_writable(pinfo->cinfo, -1);
1032 col_set_writable(pinfo->cinfo, -1, false);
1033 copy_address_shallow(&save_dl_src, &pinfo->dl_src);
1034 copy_address_shallow(&save_dl_dst, &pinfo->dl_dst);
1035 copy_address_shallow(&save_net_src, &pinfo->net_src);
1036 copy_address_shallow(&save_net_dst, &pinfo->net_dst);
1037 copy_address_shallow(&save_src, &pinfo->src);
1038 copy_address_shallow(&save_dst, &pinfo->dst);
1039 save_ptype = pinfo->ptype;
1040 save_srcport = pinfo->srcport;
1041 save_destport = pinfo->destport;
1043 /* Dissect the contained packet. */
1044 TRY {
1045 len = call_dissector_through_handle(handle, tvb,pinfo, tree, data);
1047 CATCH(BoundsError) {
1049 * Restore the column writability and addresses and ports.
1051 col_set_writable(pinfo->cinfo, -1, save_writable);
1052 copy_address_shallow(&pinfo->dl_src, &save_dl_src);
1053 copy_address_shallow(&pinfo->dl_dst, &save_dl_dst);
1054 copy_address_shallow(&pinfo->net_src, &save_net_src);
1055 copy_address_shallow(&pinfo->net_dst, &save_net_dst);
1056 copy_address_shallow(&pinfo->src, &save_src);
1057 copy_address_shallow(&pinfo->dst, &save_dst);
1058 pinfo->ptype = save_ptype;
1059 pinfo->srcport = save_srcport;
1060 pinfo->destport = save_destport;
1063 * Restore the current protocol, so any
1064 * "Short Frame" indication reflects that
1065 * protocol, not the protocol for the
1066 * packet that got the error.
1068 pinfo->current_proto = saved_proto;
1071 * Restore the desegmentability state.
1073 pinfo->can_desegment = saved_can_desegment;
1076 * Rethrow the exception, so this will be
1077 * reported as a short frame.
1079 RETHROW;
1081 CATCH3(FragmentBoundsError, ContainedBoundsError, ReportedBoundsError) {
1083 * "ret" wasn't set because an exception was thrown
1084 * before "call_dissector_through_handle()" returned.
1085 * As it called something, at least one dissector
1086 * accepted the packet, and, as an exception was
1087 * thrown, not only was all the tvbuff dissected,
1088 * a dissector tried dissecting past the end of
1089 * the data in some tvbuff, so we'll assume that
1090 * the entire tvbuff was dissected.
1092 len = tvb_captured_length(tvb);
1094 ENDTRY;
1096 col_set_writable(pinfo->cinfo, -1, save_writable);
1097 copy_address_shallow(&pinfo->dl_src, &save_dl_src);
1098 copy_address_shallow(&pinfo->dl_dst, &save_dl_dst);
1099 copy_address_shallow(&pinfo->net_src, &save_net_src);
1100 copy_address_shallow(&pinfo->net_dst, &save_net_dst);
1101 copy_address_shallow(&pinfo->src, &save_src);
1102 copy_address_shallow(&pinfo->dst, &save_dst);
1103 pinfo->ptype = save_ptype;
1104 pinfo->srcport = save_srcport;
1105 pinfo->destport = save_destport;
1106 pinfo->want_pdu_tracking = 0;
1107 return len;
1111 * An entry in the hash table portion of a dissector table.
1113 struct dtbl_entry {
1114 dissector_handle_t initial;
1115 dissector_handle_t current;
1118 /* Finds a dissector table by table name. */
1119 dissector_table_t
1120 find_dissector_table(const char *name)
1122 dissector_table_t dissector_table = (dissector_table_t) g_hash_table_lookup(dissector_tables, name);
1123 if (! dissector_table) {
1124 const char *new_name = (const char *) g_hash_table_lookup(dissector_table_aliases, name);
1125 if (new_name) {
1126 dissector_table = (dissector_table_t) g_hash_table_lookup(dissector_tables, new_name);
1128 if (dissector_table) {
1129 ws_warning("%s is now %s", name, new_name);
1132 return dissector_table;
1135 /* Find an entry in a uint dissector table. */
1136 static dtbl_entry_t *
1137 find_uint_dtbl_entry(dissector_table_t sub_dissectors, const uint32_t pattern)
1139 switch (sub_dissectors->type) {
1141 case FT_UINT8:
1142 case FT_UINT16:
1143 case FT_UINT24:
1144 case FT_UINT32:
1146 * You can do a uint lookup in these tables.
1148 break;
1149 case FT_NONE:
1150 /* For now treat as uint */
1151 break;
1153 default:
1155 * But you can't do a uint lookup in any other types
1156 * of tables.
1158 ws_assert_not_reached();
1162 * Find the entry.
1164 return (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table,
1165 GUINT_TO_POINTER(pattern));
1168 #if 0
1169 static void
1170 dissector_add_uint_sanity_check(const char *name, uint32_t pattern, dissector_handle_t handle, dissector_table_t sub_dissectors)
1172 dtbl_entry_t *dtbl_entry;
1174 if (pattern == 0) {
1175 ws_warning("%s: %s registering using a pattern of 0",
1176 name, proto_get_protocol_filter_name(proto_get_id(handle->protocol)));
1179 dtbl_entry = g_hash_table_lookup(sub_dissectors->hash_table, GUINT_TO_POINTER(pattern));
1180 if (dtbl_entry != NULL) {
1181 ws_warning("%s: %s registering using pattern %d already registered by %s",
1182 name, proto_get_protocol_filter_name(proto_get_id(handle->protocol)),
1183 pattern, proto_get_protocol_filter_name(proto_get_id(dtbl_entry->initial->protocol)));
1186 #endif
1188 /* Add an entry to a uint dissector table. */
1189 void
1190 dissector_add_uint(const char *name, const uint32_t pattern, dissector_handle_t handle)
1192 dissector_table_t sub_dissectors;
1193 dtbl_entry_t *dtbl_entry;
1195 sub_dissectors = find_dissector_table(name);
1198 * Make sure the handle and the dissector table exist.
1200 if (handle == NULL) {
1201 fprintf(stderr, "OOPS: handle to register \"%s\" to doesn't exist\n",
1202 name);
1203 if (wireshark_abort_on_dissector_bug)
1204 abort();
1205 return;
1207 if (sub_dissectors == NULL) {
1208 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
1209 name);
1210 fprintf(stderr, "Protocol being registered is \"%s\"\n",
1211 proto_get_protocol_long_name(handle->protocol));
1212 if (wireshark_abort_on_dissector_bug)
1213 abort();
1214 return;
1217 switch (sub_dissectors->type) {
1219 case FT_UINT8:
1220 case FT_UINT16:
1221 case FT_UINT24:
1222 case FT_UINT32:
1224 * You can do a uint lookup in these tables.
1226 break;
1228 default:
1230 * But you can't do a uint lookup in any other types
1231 * of tables.
1233 ws_assert_not_reached();
1236 #if 0
1237 dissector_add_uint_sanity_check(name, pattern, handle, sub_dissectors);
1238 #endif
1240 dtbl_entry = g_new(dtbl_entry_t, 1);
1241 dtbl_entry->current = handle;
1242 dtbl_entry->initial = dtbl_entry->current;
1244 /* do the table insertion */
1245 g_hash_table_insert(sub_dissectors->hash_table,
1246 GUINT_TO_POINTER(pattern), (void *)dtbl_entry);
1249 * Now, if this table supports "Decode As", add this handle
1250 * to the list of handles that could be used for "Decode As"
1251 * with this table, because it *is* being used with this table.
1253 if (sub_dissectors->supports_decode_as)
1254 dissector_add_for_decode_as(name, handle);
1259 void dissector_add_uint_range(const char *name, range_t *range,
1260 dissector_handle_t handle)
1262 dissector_table_t sub_dissectors;
1263 uint32_t i, j;
1265 if (range) {
1266 if (range->nranges == 0) {
1268 * Even an empty range would want a chance for
1269 * Decode As, if the dissector table supports
1270 * it.
1272 sub_dissectors = find_dissector_table(name);
1273 if (sub_dissectors->supports_decode_as)
1274 dissector_add_for_decode_as(name, handle);
1276 else {
1277 for (i = 0; i < range->nranges; i++) {
1278 for (j = range->ranges[i].low; j < range->ranges[i].high; j++)
1279 dissector_add_uint(name, j, handle);
1280 dissector_add_uint(name, range->ranges[i].high, handle);
1286 static range_t*
1287 dissector_add_range_preference(const char *name, dissector_handle_t handle, const char* range_str)
1289 range_t** range;
1290 module_t *module;
1291 char *description, *title;
1292 dissector_table_t pref_dissector_table = find_dissector_table(name);
1293 int proto_id = proto_get_id(handle->protocol);
1294 uint32_t max_value = 0;
1296 /* If a dissector is added for Decode As only, it's dissector
1297 table value would default to 0.
1298 Set up a preference value with that information
1300 range = wmem_new0(wmem_epan_scope(), range_t*);
1302 /* If the dissector's protocol already has a preference module, use it */
1303 const char* module_name = proto_get_protocol_filter_name(proto_id);
1304 module = prefs_find_module(module_name);
1305 if (module == NULL) {
1306 /* Otherwise create a new one */
1307 module = prefs_register_protocol(proto_id, NULL);
1310 const char *fullname = wmem_strdup_printf(wmem_epan_scope(), "%s%s", name, dissector_handle_get_pref_suffix(handle));
1312 /* Some preference callback functions use the proto_reg_handoff_
1313 routine to apply preferences, which could duplicate the
1314 registration of a preference. Check for that here */
1315 if (prefs_find_preference(module, fullname) == NULL) {
1316 const char *handle_desc = dissector_handle_get_description(handle);
1317 if (g_strcmp0(range_str, "") > 0) {
1318 description = wmem_strdup_printf(wmem_epan_scope(), "%s %s(s) (default: %s)",
1319 handle_desc, pref_dissector_table->ui_name, range_str);
1320 } else {
1321 description = wmem_strdup_printf(wmem_epan_scope(), "%s %s(s)",
1322 handle_desc, pref_dissector_table->ui_name);
1324 title = wmem_strdup_printf(wmem_epan_scope(), "%s %s(s)", handle_desc, pref_dissector_table->ui_name);
1326 /* Max value is based on datatype of dissector table */
1327 switch (pref_dissector_table->type) {
1329 case FT_UINT8:
1330 max_value = 0xFF;
1331 break;
1332 case FT_UINT16:
1333 max_value = 0xFFFF;
1334 break;
1335 case FT_UINT24:
1336 max_value = 0xFFFFFF;
1337 break;
1338 case FT_UINT32:
1339 max_value = 0xFFFFFFFF;
1340 break;
1342 default:
1343 ws_error("The dissector table %s (%s) is not an integer type - are you using a buggy plugin?", name, pref_dissector_table->ui_name);
1344 ws_assert_not_reached();
1347 range_convert_str(wmem_epan_scope(), range, range_str, max_value);
1348 prefs_register_decode_as_range_preference(module, fullname, title, description, range, max_value, name, handle_desc);
1351 return *range;
1354 void dissector_add_uint_with_preference(const char *name, const uint32_t pattern,
1355 dissector_handle_t handle)
1357 char* range_str;
1359 range_str = wmem_strdup_printf(NULL, "%d", pattern);
1360 dissector_add_range_preference(name, handle, range_str);
1361 wmem_free(NULL, range_str);
1362 dissector_add_uint(name, pattern, handle);
1365 void dissector_add_uint_range_with_preference(const char *name, const char* range_str,
1366 dissector_handle_t handle)
1368 range_t* range;
1370 range = dissector_add_range_preference(name, handle, range_str);
1371 dissector_add_uint_range(name, range, handle);
1374 /* Delete the entry for a dissector in a uint dissector table
1375 with a particular pattern. */
1377 /* NOTE: this doesn't use the dissector call variable. It is included to */
1378 /* be consistent with the dissector_add_uint and more importantly to be used */
1379 /* if the technique of adding a temporary dissector is implemented. */
1380 /* If temporary dissectors are deleted, then the original dissector must */
1381 /* be available. */
1382 void
1383 dissector_delete_uint(const char *name, const uint32_t pattern,
1384 dissector_handle_t handle _U_)
1386 dissector_table_t sub_dissectors = find_dissector_table(name);
1387 dtbl_entry_t *dtbl_entry;
1389 /* sanity check */
1390 ws_assert(sub_dissectors);
1393 * Find the entry.
1395 dtbl_entry = find_uint_dtbl_entry(sub_dissectors, pattern);
1397 if (dtbl_entry != NULL) {
1399 * Found - remove it.
1401 g_hash_table_remove(sub_dissectors->hash_table,
1402 GUINT_TO_POINTER(pattern));
1406 void dissector_delete_uint_range(const char *name, range_t *range,
1407 dissector_handle_t handle)
1409 uint32_t i, j;
1411 if (range) {
1412 for (i = 0; i < range->nranges; i++) {
1413 for (j = range->ranges[i].low; j < range->ranges[i].high; j++)
1414 dissector_delete_uint(name, j, handle);
1415 dissector_delete_uint(name, range->ranges[i].high, handle);
1420 /* Remove an entry from a guid dissector table. */
1421 void dissector_delete_guid(const char *name, guid_key* guid_val, dissector_handle_t handle)
1423 dissector_table_t sub_dissectors;
1424 dtbl_entry_t *dtbl_entry;
1426 sub_dissectors = find_dissector_table(name);
1428 /* sanity check */
1429 ws_assert(sub_dissectors);
1431 /* Find the table entry */
1432 dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, guid_val);
1434 if (dtbl_entry == NULL) {
1435 fprintf(stderr, "OOPS: guid not found in dissector table \"%s\"\n", name);
1436 return;
1439 /* Make sure the handles match */
1440 if (dtbl_entry->current != handle) {
1441 fprintf(stderr, "OOPS: handle does not match for guid in dissector table \"%s\"\n", name);
1442 return;
1445 /* Remove the table entry */
1446 g_hash_table_remove(sub_dissectors->hash_table, guid_val);
1450 static gboolean
1451 dissector_delete_all_check (void *key _U_, void *value, void *user_data)
1453 dtbl_entry_t *dtbl_entry = (dtbl_entry_t *) value;
1454 dissector_handle_t handle = (dissector_handle_t) user_data;
1456 if (!dtbl_entry->current->protocol) {
1458 * Not all dissectors are registered with a protocol, so we need this
1459 * check when running from dissector_delete_from_all_tables.
1461 return FALSE;
1464 return (proto_get_id (dtbl_entry->current->protocol) == proto_get_id (handle->protocol));
1467 /* Delete all entries from a dissector table. */
1468 void dissector_delete_all(const char *name, dissector_handle_t handle)
1470 dissector_table_t sub_dissectors = find_dissector_table(name);
1471 ws_assert (sub_dissectors);
1473 g_hash_table_foreach_remove (sub_dissectors->hash_table, dissector_delete_all_check, handle);
1476 static void
1477 dissector_delete_from_table(gpointer key _U_, gpointer value, gpointer user_data)
1479 dissector_table_t sub_dissectors = (dissector_table_t) value;
1480 ws_assert (sub_dissectors);
1482 g_hash_table_foreach_remove(sub_dissectors->hash_table, dissector_delete_all_check, user_data);
1483 sub_dissectors->dissector_handles = g_slist_remove(sub_dissectors->dissector_handles, user_data);
1486 /* Delete handle from all tables and dissector_handles lists */
1487 static void
1488 dissector_delete_from_all_tables(dissector_handle_t handle)
1490 g_hash_table_foreach(dissector_tables, dissector_delete_from_table, handle);
1493 /* Change the entry for a dissector in a uint dissector table
1494 with a particular pattern to use a new dissector handle. */
1495 void
1496 dissector_change_uint(const char *name, const uint32_t pattern, dissector_handle_t handle)
1498 dissector_table_t sub_dissectors = find_dissector_table(name);
1499 dtbl_entry_t *dtbl_entry;
1501 /* sanity check */
1502 ws_assert(sub_dissectors);
1505 * See if the entry already exists. If so, reuse it.
1507 dtbl_entry = find_uint_dtbl_entry(sub_dissectors, pattern);
1508 if (dtbl_entry != NULL) {
1510 * If there's no initial value, and the user said not
1511 * to decode it, just remove the entry to save memory.
1513 if (handle == NULL && dtbl_entry->initial == NULL) {
1514 g_hash_table_remove(sub_dissectors->hash_table,
1515 GUINT_TO_POINTER(pattern));
1516 return;
1518 dtbl_entry->current = handle;
1519 return;
1523 * Don't create an entry if there is no dissector handle - I.E. the
1524 * user said not to decode something that wasn't being decoded
1525 * in the first place.
1527 if (handle == NULL)
1528 return;
1530 dtbl_entry = g_new(dtbl_entry_t, 1);
1531 dtbl_entry->initial = NULL;
1532 dtbl_entry->current = handle;
1534 /* do the table insertion */
1535 g_hash_table_insert(sub_dissectors->hash_table,
1536 GUINT_TO_POINTER(pattern), (void *)dtbl_entry);
1539 /* Reset an entry in a uint dissector table to its initial value. */
1540 void
1541 dissector_reset_uint(const char *name, const uint32_t pattern)
1543 dissector_table_t sub_dissectors = find_dissector_table(name);
1544 dtbl_entry_t *dtbl_entry;
1546 /* sanity check */
1547 ws_assert(sub_dissectors);
1550 * Find the entry.
1552 dtbl_entry = find_uint_dtbl_entry(sub_dissectors, pattern);
1554 if (dtbl_entry == NULL)
1555 return;
1558 * Found - is there an initial value?
1560 if (dtbl_entry->initial != NULL) {
1561 dtbl_entry->current = dtbl_entry->initial;
1562 } else {
1563 g_hash_table_remove(sub_dissectors->hash_table,
1564 GUINT_TO_POINTER(pattern));
1568 /* Return true if an entry in a uint dissector table is found and has been
1569 * changed (i.e. dissector_change_uint() has been called, such as from
1570 * Decode As, prefs registered via dissector_add_uint_[range_]with_preference),
1571 * etc.), otherwise return false.
1573 bool
1574 dissector_is_uint_changed(dissector_table_t const sub_dissectors, const uint32_t uint_val)
1576 if (sub_dissectors != NULL) {
1577 dtbl_entry_t *dtbl_entry = find_uint_dtbl_entry(sub_dissectors, uint_val);
1578 if (dtbl_entry != NULL)
1579 return (dtbl_entry->current != dtbl_entry->initial);
1581 return false;
1584 /* Look for a given value in a given uint dissector table and, if found,
1585 call the dissector with the arguments supplied, and return the number
1586 of bytes consumed by the dissector, otherwise return 0. */
1589 dissector_try_uint_new(dissector_table_t sub_dissectors, const uint32_t uint_val,
1590 tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1591 const bool add_proto_name, void *data)
1593 dtbl_entry_t *dtbl_entry;
1594 struct dissector_handle *handle;
1595 uint32_t saved_match_uint;
1596 int len;
1598 dtbl_entry = find_uint_dtbl_entry(sub_dissectors, uint_val);
1599 if (dtbl_entry == NULL) {
1601 * There's no entry in the table for our value.
1603 return 0;
1607 * Is there currently a dissector handle for this entry?
1609 handle = dtbl_entry->current;
1610 if (handle == NULL) {
1612 * No - pretend this dissector didn't exist,
1613 * so that other dissectors might have a chance
1614 * to dissect this packet.
1616 return 0;
1620 * Save the current value of "pinfo->match_uint",
1621 * set it to the uint_val that matched, call the
1622 * dissector, and restore "pinfo->match_uint".
1624 saved_match_uint = pinfo->match_uint;
1625 pinfo->match_uint = uint_val;
1626 len = call_dissector_work(handle, tvb, pinfo, tree, add_proto_name, data);
1627 pinfo->match_uint = saved_match_uint;
1630 * If a new-style dissector returned 0, it means that
1631 * it didn't think this tvbuff represented a packet for
1632 * its protocol, and didn't dissect anything.
1634 * Old-style dissectors can't reject the packet.
1636 * 0 is also returned if the protocol wasn't enabled.
1638 * If the packet was rejected, we return 0, so that
1639 * other dissectors might have a chance to dissect this
1640 * packet, otherwise we return the dissected length.
1642 return len;
1646 dissector_try_uint(dissector_table_t sub_dissectors, const uint32_t uint_val,
1647 tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1650 return dissector_try_uint_new(sub_dissectors, uint_val, tvb, pinfo, tree, true, NULL);
1653 /* Look for a given value in a given uint dissector table and, if found,
1654 return the dissector handle for that value. */
1655 dissector_handle_t
1656 dissector_get_uint_handle(dissector_table_t const sub_dissectors, const uint32_t uint_val)
1658 dtbl_entry_t *dtbl_entry;
1660 dtbl_entry = find_uint_dtbl_entry(sub_dissectors, uint_val);
1661 if (dtbl_entry != NULL)
1662 return dtbl_entry->current;
1663 else
1664 return NULL;
1667 dissector_handle_t
1668 dissector_get_default_uint_handle(const char *name, const uint32_t uint_val)
1670 dissector_table_t sub_dissectors = find_dissector_table(name);
1672 if (sub_dissectors != NULL) {
1673 dtbl_entry_t *dtbl_entry = find_uint_dtbl_entry(sub_dissectors, uint_val);
1674 if (dtbl_entry != NULL)
1675 return dtbl_entry->initial;
1677 return NULL;
1680 /* Find an entry in a string dissector table. */
1681 static dtbl_entry_t *
1682 find_string_dtbl_entry(dissector_table_t const sub_dissectors, const char *pattern)
1684 dtbl_entry_t *ret;
1685 char *key;
1687 switch (sub_dissectors->type) {
1689 case FT_STRING:
1690 case FT_STRINGZ:
1691 case FT_STRINGZPAD:
1692 case FT_STRINGZTRUNC:
1694 * You can do a string lookup in these tables.
1696 break;
1698 default:
1700 * But you can't do a string lookup in any other types
1701 * of tables.
1703 ws_assert_not_reached();
1706 if (sub_dissectors->param == STRING_CASE_INSENSITIVE) {
1707 key = g_ascii_strdown(pattern, -1);
1708 } else {
1709 key = g_strdup(pattern);
1713 * Find the entry.
1715 ret = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, key);
1717 g_free(key);
1719 return ret;
1722 /* Add an entry to a string dissector table. */
1723 void
1724 dissector_add_string(const char *name, const char *pattern,
1725 dissector_handle_t handle)
1727 dissector_table_t sub_dissectors = find_dissector_table(name);
1728 dtbl_entry_t *dtbl_entry;
1729 char *key;
1732 * Make sure the handle and the dissector table exist.
1734 if (handle == NULL) {
1735 fprintf(stderr, "OOPS: handle to register \"%s\" to doesn't exist\n",
1736 name);
1737 if (wireshark_abort_on_dissector_bug)
1738 abort();
1739 return;
1741 if (sub_dissectors == NULL) {
1742 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
1743 name);
1744 fprintf(stderr, "Protocol being registered is \"%s\"\n",
1745 proto_get_protocol_long_name(handle->protocol));
1746 if (wireshark_abort_on_dissector_bug)
1747 abort();
1748 return;
1751 switch (sub_dissectors->type) {
1753 case FT_STRING:
1754 case FT_STRINGZ:
1755 case FT_STRINGZPAD:
1756 case FT_STRINGZTRUNC:
1758 * You can do a string lookup in these tables.
1760 break;
1762 default:
1764 * But you can't do a string lookup in any other types
1765 * of tables.
1767 ws_assert_not_reached();
1770 dtbl_entry = g_new(dtbl_entry_t, 1);
1771 dtbl_entry->current = handle;
1772 dtbl_entry->initial = dtbl_entry->current;
1774 if (sub_dissectors->param == STRING_CASE_INSENSITIVE) {
1775 key = g_ascii_strdown(pattern, -1);
1776 } else {
1777 key = g_strdup(pattern);
1780 /* do the table insertion */
1781 g_hash_table_insert(sub_dissectors->hash_table, (void *)key,
1782 (void *)dtbl_entry);
1785 * Now, if this table supports "Decode As", add this handle
1786 * to the list of handles that could be used for "Decode As"
1787 * with this table, because it *is* being used with this table.
1789 if (sub_dissectors->supports_decode_as)
1790 dissector_add_for_decode_as(name, handle);
1793 /* Delete the entry for a dissector in a string dissector table
1794 with a particular pattern. */
1796 /* NOTE: this doesn't use the dissector call variable. It is included to */
1797 /* be consistent with the dissector_add_string and more importantly to */
1798 /* be used if the technique of adding a temporary dissector is */
1799 /* implemented. */
1800 /* If temporary dissectors are deleted, then the original dissector must */
1801 /* be available. */
1802 void
1803 dissector_delete_string(const char *name, const char *pattern,
1804 dissector_handle_t handle _U_)
1806 dissector_table_t sub_dissectors = find_dissector_table(name);
1807 dtbl_entry_t *dtbl_entry;
1809 /* sanity check */
1810 ws_assert(sub_dissectors);
1813 * Find the entry.
1815 dtbl_entry = find_string_dtbl_entry(sub_dissectors, pattern);
1817 if (dtbl_entry != NULL) {
1819 * Found - remove it.
1821 g_hash_table_remove(sub_dissectors->hash_table, pattern);
1825 /* Change the entry for a dissector in a string dissector table
1826 with a particular pattern to use a new dissector handle. */
1827 void
1828 dissector_change_string(const char *name, const char *pattern,
1829 dissector_handle_t handle)
1831 dissector_table_t sub_dissectors = find_dissector_table(name);
1832 dtbl_entry_t *dtbl_entry;
1834 /* sanity check */
1835 ws_assert(sub_dissectors);
1838 * See if the entry already exists. If so, reuse it.
1840 dtbl_entry = find_string_dtbl_entry(sub_dissectors, pattern);
1841 if (dtbl_entry != NULL) {
1843 * If there's no initial value, and the user said not
1844 * to decode it, just remove the entry to save memory.
1846 if (handle == NULL && dtbl_entry->initial == NULL) {
1847 g_hash_table_remove(sub_dissectors->hash_table,
1848 pattern);
1849 return;
1851 dtbl_entry->current = handle;
1852 return;
1856 * Don't create an entry if there is no dissector handle - I.E. the
1857 * user said not to decode something that wasn't being decoded
1858 * in the first place.
1860 if (handle == NULL)
1861 return;
1863 dtbl_entry = g_new(dtbl_entry_t, 1);
1864 dtbl_entry->initial = NULL;
1865 dtbl_entry->current = handle;
1867 /* do the table insertion */
1868 g_hash_table_insert(sub_dissectors->hash_table, (void *)g_strdup(pattern),
1869 (void *)dtbl_entry);
1872 /* Reset an entry in a string sub-dissector table to its initial value. */
1873 void
1874 dissector_reset_string(const char *name, const char *pattern)
1876 dissector_table_t sub_dissectors = find_dissector_table(name);
1877 dtbl_entry_t *dtbl_entry;
1879 /* sanity check */
1880 ws_assert(sub_dissectors);
1883 * Find the entry.
1885 dtbl_entry = find_string_dtbl_entry(sub_dissectors, pattern);
1887 if (dtbl_entry == NULL)
1888 return;
1891 * Found - is there an initial value?
1893 if (dtbl_entry->initial != NULL) {
1894 dtbl_entry->current = dtbl_entry->initial;
1895 } else {
1896 g_hash_table_remove(sub_dissectors->hash_table, pattern);
1900 /* Return true if an entry in a uint dissector table is found and has been
1901 * changed (i.e. dissector_change_uint() has been called, such as from
1902 * Decode As, prefs registered via dissector_add_uint_[range_]with_preference),
1903 * etc.), otherwise return false.
1905 bool
1906 dissector_is_string_changed(dissector_table_t const sub_dissectors, const char *string)
1908 if (sub_dissectors != NULL) {
1909 dtbl_entry_t *dtbl_entry = find_string_dtbl_entry(sub_dissectors, string);
1910 if (dtbl_entry != NULL)
1911 return (dtbl_entry->current != dtbl_entry->initial);
1913 return false;
1916 /* Look for a given string in a given dissector table and, if found, call
1917 the dissector with the arguments supplied, and return length of dissected data,
1918 otherwise return 0. */
1920 dissector_try_string_new(dissector_table_t sub_dissectors, const char *string,
1921 tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const bool add_proto_name, void *data)
1923 dtbl_entry_t *dtbl_entry;
1924 struct dissector_handle *handle;
1925 int len;
1926 const char *saved_match_string;
1928 /* XXX ASSERT instead ? */
1929 if (!string) return 0;
1930 dtbl_entry = find_string_dtbl_entry(sub_dissectors, string);
1931 if (dtbl_entry != NULL) {
1933 * Is there currently a dissector handle for this entry?
1935 handle = dtbl_entry->current;
1936 if (handle == NULL) {
1938 * No - pretend this dissector didn't exist,
1939 * so that other dissectors might have a chance
1940 * to dissect this packet.
1942 return 0;
1946 * Save the current value of "pinfo->match_string",
1947 * set it to the string that matched, call the
1948 * dissector, and restore "pinfo->match_string".
1950 saved_match_string = pinfo->match_string;
1951 pinfo->match_string = string;
1952 len = call_dissector_work(handle, tvb, pinfo, tree, add_proto_name, data);
1953 pinfo->match_string = saved_match_string;
1956 * If a new-style dissector returned 0, it means that
1957 * it didn't think this tvbuff represented a packet for
1958 * its protocol, and didn't dissect anything.
1960 * Old-style dissectors can't reject the packet.
1962 * 0 is also returned if the protocol wasn't enabled.
1964 * If the packet was rejected, we return 0, so that
1965 * other dissectors might have a chance to dissect this
1966 * packet, otherwise we return the dissected length.
1968 return len;
1970 return 0;
1974 dissector_try_string(dissector_table_t sub_dissectors, const char *string,
1975 tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1977 return dissector_try_string_new(sub_dissectors, string, tvb, pinfo, tree, true, data);
1980 /* Look for a given value in a given string dissector table and, if found,
1981 return the dissector handle for that value. */
1982 dissector_handle_t
1983 dissector_get_string_handle(dissector_table_t sub_dissectors,
1984 const char *string)
1986 dtbl_entry_t *dtbl_entry;
1988 /* XXX ASSERT instead ? */
1989 if (!string) return NULL;
1990 dtbl_entry = find_string_dtbl_entry(sub_dissectors, string);
1991 if (dtbl_entry != NULL)
1992 return dtbl_entry->current;
1993 else
1994 return NULL;
1997 dissector_handle_t
1998 dissector_get_default_string_handle(const char *name, const char *string)
2000 dissector_table_t sub_dissectors;
2002 /* XXX ASSERT instead ? */
2003 if (!string) return NULL;
2004 sub_dissectors = find_dissector_table(name);
2005 if (sub_dissectors != NULL) {
2006 dtbl_entry_t *dtbl_entry = find_string_dtbl_entry(sub_dissectors, string);
2007 if (dtbl_entry != NULL)
2008 return dtbl_entry->initial;
2010 return NULL;
2013 /* Add an entry to a "custom" dissector table. */
2014 void dissector_add_custom_table_handle(const char *name, void *pattern, dissector_handle_t handle)
2016 dissector_table_t sub_dissectors = find_dissector_table(name);
2017 dtbl_entry_t *dtbl_entry;
2020 * Make sure the handle and the dissector table exist.
2022 if (handle == NULL) {
2023 fprintf(stderr, "OOPS: handle to register \"%s\" to doesn't exist\n",
2024 name);
2025 if (wireshark_abort_on_dissector_bug)
2026 abort();
2027 return;
2029 if (sub_dissectors == NULL) {
2030 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
2031 name);
2032 fprintf(stderr, "Protocol being registered is \"%s\"\n",
2033 proto_get_protocol_long_name(handle->protocol));
2034 if (wireshark_abort_on_dissector_bug)
2035 abort();
2036 return;
2039 ws_assert(sub_dissectors->type == FT_BYTES);
2041 dtbl_entry = g_new(dtbl_entry_t, 1);
2042 dtbl_entry->current = handle;
2043 dtbl_entry->initial = dtbl_entry->current;
2045 /* do the table insertion */
2046 g_hash_table_insert(sub_dissectors->hash_table, (void *)pattern,
2047 (void *)dtbl_entry);
2050 * Now, if this table supports "Decode As", add this handle
2051 * to the list of handles that could be used for "Decode As"
2052 * with this table, because it *is* being used with this table.
2054 if (sub_dissectors->supports_decode_as)
2055 dissector_add_for_decode_as(name, handle);
2058 dissector_handle_t dissector_get_custom_table_handle(dissector_table_t sub_dissectors, void *key)
2060 dtbl_entry_t *dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, key);
2062 if (dtbl_entry != NULL)
2063 return dtbl_entry->current;
2065 return NULL;
2067 /* Add an entry to a guid dissector table. */
2068 void dissector_add_guid(const char *name, guid_key* guid_val, dissector_handle_t handle)
2070 dissector_table_t sub_dissectors;
2071 dtbl_entry_t *dtbl_entry;
2073 sub_dissectors = find_dissector_table(name);
2076 * Make sure the handle and the dissector table exist.
2078 if (handle == NULL) {
2079 fprintf(stderr, "OOPS: handle to register \"%s\" to doesn't exist\n",
2080 name);
2081 if (wireshark_abort_on_dissector_bug)
2082 abort();
2083 return;
2085 if (sub_dissectors == NULL) {
2086 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
2087 name);
2088 fprintf(stderr, "Protocol being registered is \"%s\"\n",
2089 proto_get_protocol_long_name(handle->protocol));
2090 if (wireshark_abort_on_dissector_bug)
2091 abort();
2092 return;
2095 if (sub_dissectors->type != FT_GUID) {
2096 ws_assert_not_reached();
2099 dtbl_entry = g_new(dtbl_entry_t, 1);
2100 dtbl_entry->current = handle;
2101 dtbl_entry->initial = dtbl_entry->current;
2103 /* do the table insertion */
2104 g_hash_table_insert(sub_dissectors->hash_table,
2105 guid_val, (void *)dtbl_entry);
2108 * Now, if this table supports "Decode As", add this handle
2109 * to the list of handles that could be used for "Decode As"
2110 * with this table, because it *is* being used with this table.
2112 if (sub_dissectors->supports_decode_as)
2113 dissector_add_for_decode_as(name, handle);
2116 /* Look for a given value in a given guid dissector table and, if found,
2117 call the dissector with the arguments supplied, and return true,
2118 otherwise return false. */
2119 int dissector_try_guid_new(dissector_table_t sub_dissectors,
2120 guid_key* guid_val, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const bool add_proto_name, void *data)
2122 dtbl_entry_t *dtbl_entry;
2123 struct dissector_handle *handle;
2124 int len;
2126 dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, guid_val);
2127 if (dtbl_entry != NULL) {
2129 * Is there currently a dissector handle for this entry?
2131 handle = dtbl_entry->current;
2132 if (handle == NULL) {
2134 * No - pretend this dissector didn't exist,
2135 * so that other dissectors might have a chance
2136 * to dissect this packet.
2138 return 0;
2142 * Save the current value of "pinfo->match_uint",
2143 * set it to the uint_val that matched, call the
2144 * dissector, and restore "pinfo->match_uint".
2146 len = call_dissector_work(handle, tvb, pinfo, tree, add_proto_name, data);
2149 * If a new-style dissector returned 0, it means that
2150 * it didn't think this tvbuff represented a packet for
2151 * its protocol, and didn't dissect anything.
2153 * Old-style dissectors can't reject the packet.
2155 * 0 is also returned if the protocol wasn't enabled.
2157 * If the packet was rejected, we return 0, so that
2158 * other dissectors might have a chance to dissect this
2159 * packet, otherwise we return the dissected length.
2161 return len;
2163 return 0;
2166 int dissector_try_guid(dissector_table_t sub_dissectors,
2167 guid_key* guid_val, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2169 return dissector_try_guid_new(sub_dissectors, guid_val, tvb, pinfo, tree, true, NULL);
2172 /** Look for a given value in a given guid dissector table and, if found,
2173 * return the current dissector handle for that value.
2175 * @param[in] sub_dissectors Dissector table to search.
2176 * @param[in] guid_val Value to match.
2177 * @return The matching dissector handle on success, NULL if no match is found.
2179 dissector_handle_t dissector_get_guid_handle(
2180 dissector_table_t const sub_dissectors, guid_key* guid_val)
2182 dtbl_entry_t *dtbl_entry;
2184 dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, guid_val);
2185 if (dtbl_entry != NULL)
2186 return dtbl_entry->current;
2187 else
2188 return NULL;
2191 /* Use the currently assigned payload dissector for the dissector table and,
2192 if any, call the dissector with the arguments supplied, and return the
2193 number of bytes consumed, otherwise return 0. */
2194 int dissector_try_payload(dissector_table_t sub_dissectors,
2195 tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2197 return dissector_try_uint(sub_dissectors, 0, tvb, pinfo, tree);
2200 /* Use the currently assigned payload dissector for the dissector table and,
2201 if any, call the dissector with the arguments supplied, and return the
2202 number of bytes consumed, otherwise return 0. */
2203 int dissector_try_payload_new(dissector_table_t sub_dissectors,
2204 tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const bool add_proto_name, void *data)
2206 return dissector_try_uint_new(sub_dissectors, 0, tvb, pinfo, tree, add_proto_name, data);
2209 /* Change the entry for a dissector in a payload (FT_NONE) dissector table
2210 with a particular pattern to use a new dissector handle. */
2211 void dissector_change_payload(const char *name, dissector_handle_t handle)
2213 dissector_change_uint(name, 0, handle);
2216 /* Reset payload (FT_NONE) dissector table to its initial value. */
2217 void dissector_reset_payload(const char *name)
2219 dissector_reset_uint(name, 0);
2222 /* Given a payload dissector table (type FT_NONE), return the handle of
2223 the dissector that is currently active, i.e. that was selected via
2224 Decode As. */
2225 dissector_handle_t
2226 dissector_get_payload_handle(dissector_table_t const dissector_table)
2228 return dissector_get_uint_handle(dissector_table, 0);
2231 dissector_handle_t
2232 dtbl_entry_get_handle (dtbl_entry_t *dtbl_entry)
2234 return dtbl_entry->current;
2237 static int
2238 dissector_compare_filter_name(const void *dissector_a, const void *dissector_b)
2240 const struct dissector_handle *a = (const struct dissector_handle *)dissector_a;
2241 const struct dissector_handle *b = (const struct dissector_handle *)dissector_b;
2242 const char *a_name, *b_name;
2243 int ret;
2245 if (a->protocol == NULL)
2246 a_name = "";
2247 else
2248 a_name = proto_get_protocol_filter_name(proto_get_id(a->protocol));
2250 if (b->protocol == NULL)
2251 b_name = "";
2252 else
2253 b_name = proto_get_protocol_filter_name(proto_get_id(b->protocol));
2255 ret = strcmp(a_name, b_name);
2256 return ret;
2259 void
2260 packet_all_tables_sort_handles(void)
2262 GHashTableIter iter;
2263 g_hash_table_iter_init(&iter, dissector_tables);
2264 void *key, *value;
2265 dissector_table_t table;
2266 while (g_hash_table_iter_next(&iter, &key, &value)) {
2267 table = (dissector_table_t)value;
2268 table->dissector_handles = g_slist_sort(table->dissector_handles, (GCompareFunc)dissector_compare_filter_name);
2270 /* Any handles added to a table after this (e.g., by a Lua dissector,
2271 * by reloading Lua dissectors, by a UAT or other preference) will
2272 * be added using g_slist_insert_sorted. */
2273 all_tables_handles_sorted = true;
2276 /* Add a handle to the list of handles that *could* be used with this
2277 table. That list is used by the "Decode As"/"-d" code in the UI. */
2278 void
2279 dissector_add_for_decode_as(const char *name, dissector_handle_t handle)
2281 dissector_table_t sub_dissectors = find_dissector_table(name);
2282 GSList *entry;
2283 dissector_handle_t dup_handle;
2286 * Make sure the dissector table exists.
2288 if (sub_dissectors == NULL) {
2289 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
2290 name);
2291 fprintf(stderr, "Protocol being registered is \"%s\"\n",
2292 proto_get_protocol_long_name(handle->protocol));
2293 if (wireshark_abort_on_dissector_bug)
2294 abort();
2295 return;
2299 * Make sure it supports Decode As.
2301 if (!sub_dissectors->supports_decode_as) {
2302 const char *dissector_name;
2304 dissector_name = dissector_handle_get_dissector_name(handle);
2305 if (dissector_name == NULL)
2306 dissector_name = "(anonymous)";
2307 fprintf(stderr, "Registering dissector %s for protocol %s in dissector table %s, which doesn't support Decode As\n",
2308 dissector_name,
2309 proto_get_protocol_short_name(handle->protocol),
2310 name);
2311 if (wireshark_abort_on_dissector_bug)
2312 abort();
2313 return;
2316 /* Add the dissector as a dependency
2317 (some dissector tables don't have protocol association, so there is
2318 the need for the NULL check */
2319 if (sub_dissectors->protocol != NULL)
2320 register_depend_dissector(proto_get_protocol_short_name(sub_dissectors->protocol), proto_get_protocol_short_name(handle->protocol));
2322 /* Is it already in this list? */
2323 entry = g_slist_find(sub_dissectors->dissector_handles, (void *)handle);
2324 if (entry != NULL) {
2326 * Yes - don't insert it again.
2328 return;
2331 /* Ensure the dissector's description is unique. This prevents
2332 confusion when using Decode As; duplicate descriptions would
2333 make it impossible to distinguish between the dissectors
2334 with the same descriptions.
2336 FT_STRING can at least show the string value in the dialog,
2337 so we don't do the check for them. XXX - It can show the
2338 string value the dissector is being set to if there's a custom
2339 populate function (like BER uses) but the GUI model still uses
2340 the description.
2343 const char *dissector_name;
2344 dissector_name = dissector_handle_get_dissector_name(handle);
2346 if (sub_dissectors->type != FT_STRING)
2348 for (entry = sub_dissectors->dissector_handles; entry != NULL; entry = g_slist_next(entry))
2350 dup_handle = (dissector_handle_t)entry->data;
2351 if (dup_handle->description != NULL &&
2352 strcmp(dup_handle->description, handle->description) == 0)
2354 const char *dup_dissector_name;
2356 dup_dissector_name = dissector_handle_get_dissector_name(dup_handle);
2357 if (dup_dissector_name == NULL)
2358 dup_dissector_name = "(anonymous)";
2359 fprintf(stderr, "Dissectors %s and %s in dissector table %s have the same description %s\n",
2360 dissector_name ? dissector_name : "(anonymous)",
2361 dup_dissector_name,
2362 name, handle->description);
2363 if (wireshark_abort_on_dissector_bug)
2364 abort();
2369 /* We support adding automatic Decode As preferences on 32-bit
2370 * integer tables. Make sure that the preference we would generate has
2371 * a unique name. That means that for a given table's entries, each
2372 * dissector handle for the same protocol must have a unique pref suffix.
2374 if (FT_IS_UINT32(sub_dissectors->type)) {
2375 const char* pref_suffix = dissector_handle_get_pref_suffix(handle);
2376 for (entry = sub_dissectors->dissector_handles; entry != NULL; entry = g_slist_next(entry))
2378 dup_handle = (dissector_handle_t)entry->data;
2379 if (handle->protocol != dup_handle->protocol) {
2380 continue;
2382 if (g_strcmp0(pref_suffix, dissector_handle_get_pref_suffix(dup_handle)) == 0)
2384 const char *dup_dissector_name;
2385 dup_dissector_name = dissector_handle_get_dissector_name(dup_handle);
2386 if (dup_dissector_name == NULL) {
2387 dup_dissector_name = "(anonymous)";
2388 fprintf(stderr, "Dissector for %s is anonymous", proto_get_protocol_short_name(dup_handle->protocol));
2390 fprintf(stderr, "Dissectors %s and %s in dissector table %s would have the same Decode As preference\n",
2391 dissector_name ? dissector_name : "(anonymous)",
2392 dup_dissector_name,
2393 name);
2394 if (wireshark_abort_on_dissector_bug)
2395 abort();
2400 /* Add it to the list. */
2401 if (all_tables_handles_sorted) {
2402 sub_dissectors->dissector_handles =
2403 g_slist_insert_sorted(sub_dissectors->dissector_handles, (void *)handle, (GCompareFunc)dissector_compare_filter_name);
2404 } else {
2405 sub_dissectors->dissector_handles =
2406 g_slist_prepend(sub_dissectors->dissector_handles, (void *)handle);
2410 void dissector_add_for_decode_as_with_preference(const char *name,
2411 dissector_handle_t handle)
2413 /* If a dissector is added for Decode As only, it's dissector
2414 table value would default to 0.
2415 Set up a preference value with that information
2417 dissector_add_range_preference(name, handle, "");
2419 dissector_add_for_decode_as(name, handle);
2422 dissector_handle_t
2423 dtbl_entry_get_initial_handle (dtbl_entry_t *dtbl_entry)
2425 return dtbl_entry->initial;
2428 GSList *
2429 dissector_table_get_dissector_handles(dissector_table_t dissector_table) {
2430 if (!dissector_table)
2431 return NULL;
2433 return dissector_table->dissector_handles;
2437 * Data structure used as user data when iterating dissector handles
2439 typedef struct lookup_entry {
2440 const char* dissector_description;
2441 dissector_handle_t handle;
2442 } lookup_entry_t;
2445 * A callback function to changed a dissector_handle if matched
2446 * This is used when iterating a dissector table
2448 static void
2449 find_dissector_in_table(void *item, void *user_data)
2451 dissector_handle_t handle = (dissector_handle_t)item;
2452 lookup_entry_t * lookup = (lookup_entry_t *)user_data;
2453 const char *description = dissector_handle_get_description(handle);
2454 if (description && strcmp(lookup->dissector_description, description) == 0) {
2455 lookup->handle = handle;
2459 dissector_handle_t dissector_table_get_dissector_handle(dissector_table_t dissector_table, const char* description)
2461 lookup_entry_t lookup;
2463 lookup.dissector_description = description;
2464 lookup.handle = NULL;
2466 g_slist_foreach(dissector_table->dissector_handles, find_dissector_in_table, &lookup);
2467 return lookup.handle;
2470 ftenum_t
2471 dissector_table_get_type(dissector_table_t dissector_table) {
2472 if (!dissector_table) return FT_NONE;
2473 return dissector_table->type;
2476 void
2477 dissector_table_allow_decode_as(dissector_table_t dissector_table)
2479 dissector_table->supports_decode_as = true;
2482 bool
2483 dissector_table_supports_decode_as(dissector_table_t dissector_table)
2485 return dissector_table->supports_decode_as;
2488 static int
2489 uuid_equal(const void *k1, const void *k2)
2491 const guid_key *key1 = (const guid_key *)k1;
2492 const guid_key *key2 = (const guid_key *)k2;
2493 return ((memcmp(&key1->guid, &key2->guid, sizeof (e_guid_t)) == 0)
2494 && (key1->ver == key2->ver));
2497 static unsigned
2498 uuid_hash(const void *k)
2500 const guid_key *key = (const guid_key *)k;
2501 /* This isn't perfect, but the Data1 part of these is almost always unique. */
2502 return key->guid.data1;
2505 /**************************************************/
2506 /* */
2507 /* Routines to walk dissector tables */
2508 /* */
2509 /**************************************************/
2511 typedef struct dissector_foreach_info {
2512 void * caller_data;
2513 DATFunc caller_func;
2514 GHFunc next_func;
2515 const char *table_name;
2516 ftenum_t selector_type;
2517 } dissector_foreach_info_t;
2520 * Called for each entry in a dissector table.
2522 static void
2523 dissector_table_foreach_func (void *key, void *value, void *user_data)
2525 dissector_foreach_info_t *info;
2526 dtbl_entry_t *dtbl_entry;
2528 ws_assert(value);
2529 ws_assert(user_data);
2531 dtbl_entry = (dtbl_entry_t *)value;
2532 if (dtbl_entry->current == NULL ||
2533 dtbl_entry->current->protocol == NULL) {
2535 * Either there is no dissector for this entry, or
2536 * the dissector doesn't have a protocol associated
2537 * with it.
2539 * XXX - should the latter check be done?
2541 return;
2544 info = (dissector_foreach_info_t *)user_data;
2545 info->caller_func(info->table_name, info->selector_type, key, value,
2546 info->caller_data);
2550 * Called for each entry in the table of all dissector tables.
2552 static void
2553 dissector_all_tables_foreach_func (void *key, void *value, void *user_data)
2555 dissector_table_t sub_dissectors;
2556 dissector_foreach_info_t *info;
2558 ws_assert(value);
2559 ws_assert(user_data);
2561 sub_dissectors = (dissector_table_t)value;
2562 info = (dissector_foreach_info_t *)user_data;
2563 info->table_name = (char*) key;
2564 info->selector_type = get_dissector_table_selector_type(info->table_name);
2565 g_hash_table_foreach(sub_dissectors->hash_table, info->next_func, info);
2568 #if 0
2570 * Walk all dissector tables calling a user supplied function on each
2571 * entry.
2573 static void
2574 dissector_all_tables_foreach (DATFunc func,
2575 void *user_data)
2577 dissector_foreach_info_t info;
2579 info.caller_data = user_data;
2580 info.caller_func = func;
2581 info.next_func = dissector_table_foreach_func;
2582 g_hash_table_foreach(dissector_tables, dissector_all_tables_foreach_func, &info);
2584 #endif
2587 * Walk one dissector table's hash table calling a user supplied function
2588 * on each entry.
2590 void
2591 dissector_table_foreach (const char *table_name,
2592 DATFunc func,
2593 void * user_data)
2595 dissector_foreach_info_t info;
2596 dissector_table_t sub_dissectors = find_dissector_table(table_name);
2598 info.table_name = table_name;
2599 info.selector_type = sub_dissectors->type;
2600 info.caller_func = func;
2601 info.caller_data = user_data;
2602 g_hash_table_foreach(sub_dissectors->hash_table, dissector_table_foreach_func, &info);
2606 * Walk one dissector table's list of handles calling a user supplied
2607 * function on each entry.
2609 void
2610 dissector_table_foreach_handle(const char *table_name,
2611 DATFunc_handle func,
2612 void * user_data)
2614 dissector_table_t sub_dissectors = find_dissector_table(table_name);
2615 GSList *tmp;
2617 for (tmp = sub_dissectors->dissector_handles; tmp != NULL;
2618 tmp = g_slist_next(tmp))
2619 func(table_name, tmp->data, user_data);
2623 * Called for each entry in a dissector table.
2625 static void
2626 dissector_table_foreach_changed_func (void *key, void *value, void *user_data)
2628 dtbl_entry_t *dtbl_entry;
2629 dissector_foreach_info_t *info;
2631 ws_assert(value);
2632 ws_assert(user_data);
2634 dtbl_entry = (dtbl_entry_t *)value;
2635 if (dtbl_entry->initial == dtbl_entry->current) {
2637 * Entry hasn't changed - don't call the function.
2639 return;
2642 info = (dissector_foreach_info_t *)user_data;
2643 info->caller_func(info->table_name, info->selector_type, key, value,
2644 info->caller_data);
2648 * Walk all dissector tables calling a user supplied function only on
2649 * any entry that has been changed from its original state.
2651 void
2652 dissector_all_tables_foreach_changed (DATFunc func,
2653 void *user_data)
2655 dissector_foreach_info_t info;
2657 info.caller_data = user_data;
2658 info.caller_func = func;
2659 info.next_func = dissector_table_foreach_changed_func;
2660 g_hash_table_foreach(dissector_tables, dissector_all_tables_foreach_func, &info);
2664 * Walk one dissector table calling a user supplied function only on
2665 * any entry that has been changed from its original state.
2667 void
2668 dissector_table_foreach_changed (const char *table_name,
2669 DATFunc func,
2670 void * user_data)
2672 dissector_foreach_info_t info;
2673 dissector_table_t sub_dissectors = find_dissector_table(table_name);
2675 info.table_name = table_name;
2676 info.selector_type = sub_dissectors->type;
2677 info.caller_func = func;
2678 info.caller_data = user_data;
2679 g_hash_table_foreach(sub_dissectors->hash_table,
2680 dissector_table_foreach_changed_func, &info);
2683 typedef struct dissector_foreach_table_info {
2684 void * caller_data;
2685 DATFunc_table caller_func;
2686 } dissector_foreach_table_info_t;
2689 * Called for each entry in the table of all dissector tables.
2690 * This is used if we directly process the hash table.
2692 static void
2693 dissector_all_tables_foreach_table_func (void *key, void *value, void *user_data)
2695 dissector_table_t table;
2696 dissector_foreach_table_info_t *info;
2698 table = (dissector_table_t)value;
2699 info = (dissector_foreach_table_info_t *)user_data;
2700 (*info->caller_func)((char *)key, table->ui_name, info->caller_data);
2704 * Called for each key in the table of all dissector tables.
2705 * This is used if we get a list of table names, sort it, and process the list.
2707 static void
2708 dissector_all_tables_foreach_list_func (void *key, void *user_data)
2710 dissector_table_t table;
2711 dissector_foreach_table_info_t *info;
2713 table = (dissector_table_t)g_hash_table_lookup(dissector_tables, key);
2714 info = (dissector_foreach_table_info_t *)user_data;
2715 (*info->caller_func)((char*)key, table->ui_name, info->caller_data);
2719 * Walk all dissector tables calling a user supplied function on each
2720 * table.
2722 void
2723 dissector_all_tables_foreach_table (DATFunc_table func,
2724 void * user_data,
2725 GCompareFunc compare_key_func)
2727 dissector_foreach_table_info_t info;
2728 GList *list;
2730 info.caller_data = user_data;
2731 info.caller_func = func;
2732 if (compare_key_func != NULL)
2734 list = g_hash_table_get_keys(dissector_tables);
2735 list = g_list_sort(list, compare_key_func);
2736 g_list_foreach(list, dissector_all_tables_foreach_list_func, &info);
2737 g_list_free(list);
2739 else
2741 g_hash_table_foreach(dissector_tables, dissector_all_tables_foreach_table_func, &info);
2745 dissector_table_t
2746 register_dissector_table(const char *name, const char *ui_name, const int proto, const ftenum_t type,
2747 const int param)
2749 dissector_table_t sub_dissectors;
2751 /* Make sure the registration is unique */
2752 if (g_hash_table_lookup(dissector_tables, name)) {
2753 ws_error("The dissector table %s (%s) is already registered - are you using a buggy plugin?", name, ui_name);
2756 /* Create and register the dissector table for this name; returns */
2757 /* a pointer to the dissector table. */
2758 sub_dissectors = g_slice_new(struct dissector_table);
2759 switch (type) {
2761 case FT_UINT8:
2762 case FT_UINT16:
2763 case FT_UINT24:
2764 case FT_UINT32:
2766 * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
2767 * so we use "g_direct_hash()" and "g_direct_equal()".
2769 sub_dissectors->hash_func = g_direct_hash;
2770 sub_dissectors->hash_table = g_hash_table_new_full(g_direct_hash,
2771 g_direct_equal,
2772 NULL,
2773 &g_free);
2774 break;
2776 case FT_STRING:
2777 case FT_STRINGZ:
2778 case FT_STRINGZPAD:
2779 case FT_STRINGZTRUNC:
2780 sub_dissectors->hash_func = g_str_hash;
2781 sub_dissectors->hash_table = g_hash_table_new_full(g_str_hash,
2782 g_str_equal,
2783 &g_free,
2784 &g_free);
2785 break;
2786 case FT_GUID:
2787 sub_dissectors->hash_table = g_hash_table_new_full(uuid_hash,
2788 uuid_equal,
2789 NULL,
2790 &g_free);
2791 break;
2793 case FT_NONE:
2794 /* Dissector tables with FT_NONE don't have values associated with
2795 dissectors so this will always be a hash table size of 1 just
2796 to store the single dtbl_entry_t */
2797 sub_dissectors->hash_func = g_direct_hash;
2798 sub_dissectors->hash_table = g_hash_table_new_full(g_direct_hash,
2799 g_direct_equal,
2800 NULL,
2801 &g_free);
2802 break;
2804 default:
2805 ws_error("The dissector table %s (%s) is registering an unsupported type - are you using a buggy plugin?", name, ui_name);
2806 ws_assert_not_reached();
2808 sub_dissectors->dissector_handles = NULL;
2809 sub_dissectors->ui_name = ui_name;
2810 sub_dissectors->type = type;
2811 sub_dissectors->param = param;
2812 sub_dissectors->protocol = (proto == -1) ? NULL : find_protocol_by_id(proto);
2813 sub_dissectors->supports_decode_as = false;
2814 g_hash_table_insert(dissector_tables, (void *)name, (void *) sub_dissectors);
2815 return sub_dissectors;
2818 dissector_table_t register_custom_dissector_table(const char *name,
2819 const char *ui_name, const int proto, GHashFunc hash_func, GEqualFunc key_equal_func,
2820 GDestroyNotify key_destroy_func)
2822 dissector_table_t sub_dissectors;
2824 /* Make sure the registration is unique */
2825 if (g_hash_table_lookup(dissector_tables, name)) {
2826 ws_error("The dissector table %s (%s) is already registered - are you using a buggy plugin?", name, ui_name);
2829 /* Create and register the dissector table for this name; returns */
2830 /* a pointer to the dissector table. */
2831 sub_dissectors = g_slice_new(struct dissector_table);
2832 sub_dissectors->hash_func = hash_func;
2833 sub_dissectors->hash_table = g_hash_table_new_full(hash_func,
2834 key_equal_func,
2835 key_destroy_func,
2836 &g_free);
2838 sub_dissectors->dissector_handles = NULL;
2839 sub_dissectors->ui_name = ui_name;
2840 sub_dissectors->type = FT_BYTES; /* Consider key a "blob" of data, no need to really create new type */
2841 sub_dissectors->param = BASE_NONE;
2842 sub_dissectors->protocol = (proto == -1) ? NULL : find_protocol_by_id(proto);
2843 sub_dissectors->supports_decode_as = false;
2844 g_hash_table_insert(dissector_tables, (void *)name, (void *) sub_dissectors);
2845 return sub_dissectors;
2848 void
2849 register_dissector_table_alias(dissector_table_t dissector_table, const char *alias_name) {
2850 if (!dissector_table || !alias_name) return;
2852 const char *name = NULL;
2853 GList *list = g_hash_table_get_keys(dissector_tables);
2854 for (GList *cur = list; cur; cur = cur->next) {
2855 if (g_hash_table_lookup(dissector_tables, cur->data) == dissector_table) {
2856 name = (const char *) cur->data;
2857 break;
2860 g_list_free(list);
2861 if (!name) return;
2863 g_hash_table_insert(dissector_table_aliases, (void *) alias_name, (void *) name);
2866 void
2867 deregister_dissector_table(const char *name)
2869 dissector_table_t sub_dissectors = (dissector_table_t) g_hash_table_lookup(dissector_tables, name);
2870 if (!sub_dissectors) return;
2872 g_hash_table_remove(dissector_tables, name);
2874 GList *list = g_hash_table_get_keys(dissector_table_aliases);
2875 for (GList *cur = list; cur; cur = cur->next) {
2876 void *alias_name = cur->data;
2877 if (g_hash_table_lookup(dissector_table_aliases, alias_name) == name) {
2878 g_hash_table_remove(dissector_table_aliases, alias_name);
2881 g_list_free(list);
2884 const char *
2885 get_dissector_table_ui_name(const char *name)
2887 dissector_table_t sub_dissectors = find_dissector_table(name);
2888 if (!sub_dissectors) return NULL;
2890 return sub_dissectors->ui_name;
2893 ftenum_t
2894 get_dissector_table_selector_type(const char *name)
2896 dissector_table_t sub_dissectors = find_dissector_table(name);
2897 if (!sub_dissectors) return FT_NONE;
2899 return sub_dissectors->type;
2903 get_dissector_table_param(const char *name)
2905 dissector_table_t sub_dissectors = find_dissector_table(name);
2906 if (!sub_dissectors) return 0;
2908 return sub_dissectors->param;
2911 static void
2912 check_valid_heur_name_or_fail(const char *heur_name)
2914 if (proto_check_field_name_lower(heur_name)) {
2915 ws_error("Heuristic Protocol internal name \"%s\" has one or more invalid characters."
2916 " Allowed are lowercase, digits, '-', '_' and non-repeating '.'."
2917 " This might be caused by an inappropriate plugin or a development error.", heur_name);
2921 /* Finds a heuristic dissector table by table name. */
2922 heur_dissector_list_t
2923 find_heur_dissector_list(const char *name)
2925 return (heur_dissector_list_t)g_hash_table_lookup(heur_dissector_lists, name);
2928 bool
2929 has_heur_dissector_list(const char *name) {
2930 return (find_heur_dissector_list(name) != NULL);
2933 heur_dtbl_entry_t* find_heur_dissector_by_unique_short_name(const char *short_name)
2935 return (heur_dtbl_entry_t*)g_hash_table_lookup(heuristic_short_names, short_name);
2938 void
2939 heur_dissector_add(const char *name, heur_dissector_t dissector, const char *display_name, const char *internal_name, const int proto, heuristic_enable_e enable)
2941 heur_dissector_list_t sub_dissectors = find_heur_dissector_list(name);
2942 const char *proto_name;
2943 heur_dtbl_entry_t *hdtbl_entry;
2944 unsigned i, list_size;
2945 GSList *list_entry;
2948 * Make sure the dissector table exists.
2950 if (sub_dissectors == NULL) {
2951 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
2952 name);
2953 proto_name = proto_get_protocol_name(proto);
2954 if (proto_name != NULL) {
2955 fprintf(stderr, "Protocol being registered is \"%s\"\n",
2956 proto_name);
2958 if (wireshark_abort_on_dissector_bug)
2959 abort();
2960 return;
2963 /* Verify that sub-dissector is not already in the list */
2964 list_size = g_slist_length(sub_dissectors->dissectors);
2965 for (i = 0; i < list_size; i++)
2967 list_entry = g_slist_nth(sub_dissectors->dissectors, i);
2968 hdtbl_entry = (heur_dtbl_entry_t *)list_entry->data;
2969 if ((hdtbl_entry->dissector == dissector) &&
2970 (hdtbl_entry->protocol == find_protocol_by_id(proto)))
2972 proto_name = proto_get_protocol_name(proto);
2973 if (proto_name != NULL) {
2974 fprintf(stderr, "Protocol %s is already registered in \"%s\" table\n",
2975 proto_name, name);
2977 if (wireshark_abort_on_dissector_bug)
2978 abort();
2979 return;
2983 /* Make sure short_name is "parsing friendly" since it should only be used internally */
2984 check_valid_heur_name_or_fail(internal_name);
2986 /* Ensure short_name is unique */
2987 if (g_hash_table_lookup(heuristic_short_names, internal_name) != NULL) {
2988 ws_error("Duplicate heuristic short_name \"%s\"!"
2989 " This might be caused by an inappropriate plugin or a development error.", internal_name);
2992 hdtbl_entry = g_slice_new(heur_dtbl_entry_t);
2993 hdtbl_entry->dissector = dissector;
2994 hdtbl_entry->protocol = find_protocol_by_id(proto);
2995 hdtbl_entry->display_name = display_name;
2996 hdtbl_entry->short_name = g_strdup(internal_name);
2997 hdtbl_entry->list_name = g_strdup(name);
2998 hdtbl_entry->enabled = (enable == HEURISTIC_ENABLE);
2999 hdtbl_entry->enabled_by_default = (enable == HEURISTIC_ENABLE);
3001 /* do the table insertion */
3002 g_hash_table_insert(heuristic_short_names, (void *)hdtbl_entry->short_name, hdtbl_entry);
3004 sub_dissectors->dissectors = g_slist_prepend(sub_dissectors->dissectors,
3005 (void *)hdtbl_entry);
3007 /* XXX - could be optimized to pass hdtbl_entry directly */
3008 proto_add_heuristic_dissector(hdtbl_entry->protocol, hdtbl_entry->short_name);
3010 /* Add the dissector as a dependency
3011 (some heuristic tables don't have protocol association, so there is
3012 the need for the NULL check */
3013 if (sub_dissectors->protocol != NULL)
3014 register_depend_dissector(proto_get_protocol_short_name(sub_dissectors->protocol), proto_get_protocol_short_name(hdtbl_entry->protocol));
3019 static int
3020 find_matching_heur_dissector(const void *a, const void *b) {
3021 const heur_dtbl_entry_t *hdtbl_entry_a = (const heur_dtbl_entry_t *) a;
3022 const heur_dtbl_entry_t *hdtbl_entry_b = (const heur_dtbl_entry_t *) b;
3024 return (hdtbl_entry_a->dissector == hdtbl_entry_b->dissector) &&
3025 (hdtbl_entry_a->protocol == hdtbl_entry_b->protocol) ? 0 : 1;
3028 void
3029 heur_dissector_delete(const char *name, heur_dissector_t dissector, const int proto) {
3030 heur_dissector_list_t sub_dissectors = find_heur_dissector_list(name);
3031 heur_dtbl_entry_t hdtbl_entry;
3032 GSList *found_entry;
3034 /* sanity check */
3035 ws_assert(sub_dissectors != NULL);
3037 hdtbl_entry.dissector = dissector;
3038 hdtbl_entry.protocol = find_protocol_by_id(proto);
3040 found_entry = g_slist_find_custom(sub_dissectors->dissectors,
3041 (void *) &hdtbl_entry, find_matching_heur_dissector);
3043 if (found_entry) {
3044 heur_dtbl_entry_t *found_hdtbl_entry = (heur_dtbl_entry_t *)(found_entry->data);
3045 proto_add_deregistered_data(found_hdtbl_entry->list_name);
3046 g_hash_table_remove(heuristic_short_names, found_hdtbl_entry->short_name);
3047 proto_add_deregistered_data(found_hdtbl_entry->short_name);
3048 proto_add_deregistered_slice(sizeof(heur_dtbl_entry_t), found_hdtbl_entry);
3049 sub_dissectors->dissectors = g_slist_delete_link(sub_dissectors->dissectors,
3050 found_entry);
3054 bool
3055 dissector_try_heuristic(heur_dissector_list_t sub_dissectors, tvbuff_t *tvb,
3056 packet_info *pinfo, proto_tree *tree, heur_dtbl_entry_t **heur_dtbl_entry, void *data)
3058 bool status;
3059 const char *saved_curr_proto;
3060 const char *saved_heur_list_name;
3061 GSList *entry;
3062 GSList *prev_entry = NULL;
3063 uint16_t saved_can_desegment;
3064 unsigned saved_layers_len = 0;
3065 heur_dtbl_entry_t *hdtbl_entry;
3066 int proto_id;
3067 int len;
3068 bool consumed_none;
3069 unsigned saved_desegment_len;
3070 unsigned saved_tree_count = tree ? tree->tree_data->count : 0;
3072 /* can_desegment is set to 2 by anyone which offers this api/service.
3073 then every time a subdissector is called it is decremented by one.
3074 thus only the subdissector immediately ontop of whoever offers this
3075 service can use it.
3076 We save the current value of "can_desegment" for the
3077 benefit of TCP proxying dissectors such as SOCKS, so they
3078 can restore it and allow the dissectors they call to use
3079 the desegmentation service.
3081 saved_can_desegment = pinfo->can_desegment;
3082 pinfo->saved_can_desegment = saved_can_desegment;
3083 pinfo->can_desegment = saved_can_desegment-(saved_can_desegment>0);
3085 status = false;
3086 saved_curr_proto = pinfo->current_proto;
3087 saved_heur_list_name = pinfo->heur_list_name;
3089 saved_layers_len = wmem_list_count(pinfo->layers);
3090 *heur_dtbl_entry = NULL;
3092 DISSECTOR_ASSERT(saved_layers_len < prefs.gui_max_tree_depth);
3094 for (entry = sub_dissectors->dissectors; entry != NULL;
3095 entry = g_slist_next(entry)) {
3096 /* XXX - why set this now and above? */
3097 pinfo->can_desegment = saved_can_desegment-(saved_can_desegment>0);
3098 hdtbl_entry = (heur_dtbl_entry_t *)entry->data;
3100 if (hdtbl_entry->protocol != NULL &&
3101 (!proto_is_protocol_enabled(hdtbl_entry->protocol)||(hdtbl_entry->enabled==false))) {
3103 * No - don't try this dissector.
3105 continue;
3108 if (hdtbl_entry->protocol != NULL) {
3109 proto_id = proto_get_id(hdtbl_entry->protocol);
3110 /* do NOT change this behavior - wslua uses the protocol short name set here in order
3111 to determine which Lua-based heurisitc dissector to call */
3112 pinfo->current_proto =
3113 proto_get_protocol_short_name(hdtbl_entry->protocol);
3116 * Add the protocol name to the layers; we'll remove it
3117 * if the dissector fails.
3119 add_layer(pinfo, proto_id);
3122 pinfo->heur_list_name = hdtbl_entry->list_name;
3124 saved_desegment_len = pinfo->desegment_len;
3125 len = (hdtbl_entry->dissector)(tvb, pinfo, tree, data);
3126 consumed_none = len == 0 || (pinfo->desegment_len != saved_desegment_len && pinfo->desegment_offset == 0);
3127 if (hdtbl_entry->protocol != NULL &&
3128 (consumed_none || (tree && saved_tree_count == tree->tree_data->count))) {
3130 * We added a protocol layer above. The dissector
3131 * didn't consume any data or it didn't add any
3132 * items to the tree so remove it from the list.
3134 while (wmem_list_count(pinfo->layers) > saved_layers_len) {
3136 * Only reduce the layer number if the dissector
3137 * didn't consume data. Since tree can be NULL on
3138 * the first pass, we cannot check it or it will
3139 * break dissectors that rely on a stable value.
3141 remove_last_layer(pinfo, consumed_none);
3144 if (len) {
3145 if (ws_log_msg_is_active(WS_LOG_DOMAIN, LOG_LEVEL_DEBUG)) {
3146 ws_debug("Frame: %d | Layers: %s | Dissector: %s\n", pinfo->num, proto_list_layers(pinfo), hdtbl_entry->short_name);
3149 *heur_dtbl_entry = hdtbl_entry;
3151 /* Bubble the matched entry to the top for faster search next time. */
3152 if (prev_entry != NULL) {
3153 sub_dissectors->dissectors = g_slist_remove_link(sub_dissectors->dissectors, entry);
3154 sub_dissectors->dissectors = g_slist_concat(entry, sub_dissectors->dissectors);
3156 status = true;
3157 break;
3159 prev_entry = entry;
3162 pinfo->current_proto = saved_curr_proto;
3163 pinfo->heur_list_name = saved_heur_list_name;
3164 pinfo->can_desegment = saved_can_desegment;
3165 return status;
3168 typedef struct heur_dissector_foreach_info {
3169 void * caller_data;
3170 DATFunc_heur caller_func;
3171 GHFunc next_func;
3172 const char *table_name;
3173 } heur_dissector_foreach_info_t;
3176 * Called for each entry in a heuristic dissector table.
3178 static void
3179 heur_dissector_table_foreach_func (void *data, void *user_data)
3181 heur_dissector_foreach_info_t *info;
3183 ws_assert(data);
3184 ws_assert(user_data);
3186 info = (heur_dissector_foreach_info_t *)user_data;
3187 info->caller_func(info->table_name, (heur_dtbl_entry_t *)data,
3188 info->caller_data);
3192 * Walk one heuristic dissector table's list calling a user supplied function
3193 * on each entry.
3195 void
3196 heur_dissector_table_foreach (const char *table_name,
3197 DATFunc_heur func,
3198 void * user_data)
3200 heur_dissector_foreach_info_t info;
3201 heur_dissector_list_t sub_dissectors = find_heur_dissector_list(table_name);
3202 DISSECTOR_ASSERT(sub_dissectors != NULL);
3204 info.table_name = table_name;
3205 info.caller_func = func;
3206 info.caller_data = user_data;
3207 g_slist_foreach(sub_dissectors->dissectors,
3208 heur_dissector_table_foreach_func, &info);
3212 * Called for each entry in the table of all heuristic dissector tables.
3214 typedef struct heur_dissector_foreach_table_info {
3215 void * caller_data;
3216 DATFunc_heur_table caller_func;
3217 } heur_dissector_foreach_table_info_t;
3220 * Called for each entry in the table of all heuristic dissector tables.
3221 * This is used if we directly process the hash table.
3223 static void
3224 dissector_all_heur_tables_foreach_table_func (void *key, void *value, void *user_data)
3226 heur_dissector_foreach_table_info_t *info;
3228 info = (heur_dissector_foreach_table_info_t *)user_data;
3229 (*info->caller_func)((char *)key, (struct heur_dissector_list *)value, info->caller_data);
3233 * Called for each key in the table of all dissector tables.
3234 * This is used if we get a list of table names, sort it, and process the list.
3236 static void
3237 dissector_all_heur_tables_foreach_list_func (void *key, void *user_data)
3239 struct heur_dissector_list *list;
3240 heur_dissector_foreach_table_info_t *info;
3242 list = (struct heur_dissector_list *)g_hash_table_lookup(heur_dissector_lists, key);
3243 info = (heur_dissector_foreach_table_info_t *)user_data;
3244 (*info->caller_func)((char*)key, list, info->caller_data);
3248 * Walk all heuristic dissector tables calling a user supplied function on each
3249 * table.
3251 void
3252 dissector_all_heur_tables_foreach_table (DATFunc_heur_table func,
3253 void * user_data,
3254 GCompareFunc compare_key_func)
3256 heur_dissector_foreach_table_info_t info;
3257 GList *list;
3259 info.caller_data = user_data;
3260 info.caller_func = func;
3261 if (compare_key_func != NULL)
3263 list = g_hash_table_get_keys(dissector_tables);
3264 list = g_list_sort(list, compare_key_func);
3265 g_list_foreach(list, dissector_all_heur_tables_foreach_list_func, &info);
3266 g_list_free(list);
3268 else
3270 g_hash_table_foreach(heur_dissector_lists, dissector_all_heur_tables_foreach_table_func, &info);
3274 static void
3275 display_heur_dissector_table_entries(const char *table_name,
3276 heur_dtbl_entry_t *hdtbl_entry, void *user_data _U_)
3278 if (hdtbl_entry->protocol != NULL) {
3279 printf("%s\t%s\t%c\t%c\t%s\t%s\n",
3280 table_name,
3281 proto_get_protocol_filter_name(proto_get_id(hdtbl_entry->protocol)),
3282 (proto_is_protocol_enabled(hdtbl_entry->protocol) && hdtbl_entry->enabled) ? 'T' : 'F',
3283 (proto_is_protocol_enabled_by_default(hdtbl_entry->protocol) && hdtbl_entry->enabled_by_default) ? 'T' : 'F',
3284 hdtbl_entry->short_name,
3285 hdtbl_entry->display_name);
3289 static void
3290 dissector_dump_heur_decodes_display(const char *table_name, struct heur_dissector_list *listptr _U_, void *user_data _U_)
3292 heur_dissector_table_foreach(table_name, display_heur_dissector_table_entries, NULL);
3296 * For each heuristic dissector table, dump list of dissectors (filter_names) for that table
3298 void
3299 dissector_dump_heur_decodes(void)
3301 dissector_all_heur_tables_foreach_table(dissector_dump_heur_decodes_display, NULL, NULL);
3305 heur_dissector_list_t
3306 register_heur_dissector_list_with_description(const char *name, const char *ui_name, const int proto)
3308 heur_dissector_list_t sub_dissectors;
3310 /* Make sure the registration is unique */
3311 if (g_hash_table_lookup(heur_dissector_lists, name) != NULL) {
3312 ws_error("The heuristic dissector list %s is already registered - are you using a buggy plugin?", name);
3315 /* Create and register the dissector table for this name; returns */
3316 /* a pointer to the dissector table. */
3317 sub_dissectors = g_slice_new(struct heur_dissector_list);
3318 sub_dissectors->protocol = (proto == -1) ? NULL : find_protocol_by_id(proto);
3319 sub_dissectors->ui_name = ui_name;
3320 sub_dissectors->dissectors = NULL; /* initially empty */
3321 g_hash_table_insert(heur_dissector_lists, (void *)name,
3322 (void *) sub_dissectors);
3323 return sub_dissectors;
3326 heur_dissector_list_t
3327 register_heur_dissector_list(const char *name, const int proto)
3329 return register_heur_dissector_list_with_description(name, NULL, proto);
3332 void
3333 deregister_heur_dissector_list(const char *name)
3335 heur_dissector_list_t sub_dissectors = find_heur_dissector_list(name);
3336 if (sub_dissectors == NULL) {
3337 return;
3340 g_hash_table_remove(heur_dissector_lists, name);
3343 const char *
3344 heur_dissector_list_get_description(heur_dissector_list_t list)
3346 return list ? list->ui_name : NULL;
3350 * Register dissectors by name; used if one dissector always calls a
3351 * particular dissector, or if it bases the decision of which dissector
3352 * to call on something other than a numerical value or on "try a bunch
3353 * of dissectors until one likes the packet".
3356 /* Get the long name of the protocol for a dissector handle, if it has
3357 a protocol. */
3358 const char *
3359 dissector_handle_get_protocol_long_name(const dissector_handle_t handle)
3361 if (handle == NULL || handle->protocol == NULL) {
3362 return NULL;
3364 return proto_get_protocol_long_name(handle->protocol);
3367 /* Get the short name of the protocol for a dissector handle, if it has
3368 a protocol. */
3369 const char *
3370 dissector_handle_get_protocol_short_name(const dissector_handle_t handle)
3372 if (handle == NULL || handle->protocol == NULL) {
3373 return NULL;
3375 return proto_get_protocol_short_name(handle->protocol);
3378 /* For backwards source and binary compatibility */
3379 const char *
3380 dissector_handle_get_short_name(const dissector_handle_t handle)
3382 return dissector_handle_get_protocol_short_name(handle);
3385 /* Get the description for what the dissector in the dissector handle
3386 dissects, if it has one. */
3387 const char *
3388 dissector_handle_get_description(const dissector_handle_t handle)
3390 if (handle == NULL) {
3391 return NULL;
3393 return handle->description;
3396 /* Get the index of the protocol for a dissector handle, if it has
3397 a protocol. */
3399 dissector_handle_get_protocol_index(const dissector_handle_t handle)
3401 if (handle->protocol == NULL) {
3403 * No protocol (see, for example, the handle for
3404 * dissecting the set of protocols where the first
3405 * octet of the payload is an OSI network layer protocol
3406 * ID).
3408 return -1;
3410 return proto_get_id(handle->protocol);
3413 /* Get a GList of all registered dissector names. The content of the list
3414 is owned by the hash table and should not be modified or freed.
3415 Use g_list_free() when done using the list. */
3416 GList*
3417 get_dissector_names(void)
3419 if (!registered_dissectors) {
3420 return NULL;
3423 return g_hash_table_get_keys(registered_dissectors);
3426 /* Find a registered dissector by name. */
3427 dissector_handle_t
3428 find_dissector(const char *name)
3430 return (dissector_handle_t)g_hash_table_lookup(registered_dissectors, name);
3433 /** Find a dissector by name and add parent protocol as a dependency*/
3434 dissector_handle_t find_dissector_add_dependency(const char *name, const int parent_proto)
3436 dissector_handle_t handle = (dissector_handle_t)g_hash_table_lookup(registered_dissectors, name);
3437 if ((handle != NULL) && (parent_proto > 0))
3439 register_depend_dissector(proto_get_protocol_short_name(find_protocol_by_id(parent_proto)), dissector_handle_get_protocol_short_name(handle));
3442 return handle;
3445 /* Get a dissector name from handle. */
3446 const char *
3447 dissector_handle_get_dissector_name(const dissector_handle_t handle)
3449 if (handle == NULL) {
3450 return NULL;
3452 return handle->name;
3455 const char *
3456 dissector_handle_get_pref_suffix(const dissector_handle_t handle)
3458 if (handle == NULL) {
3459 return "";
3461 return handle->pref_suffix ? handle->pref_suffix : "";
3464 static void
3465 check_valid_dissector_name_or_fail(const char *name)
3467 if (proto_check_field_name(name)) {
3468 ws_error("Dissector name \"%s\" has one or more invalid characters."
3469 " Allowed are letters, digits, '-', '_' and non-repeating '.'."
3470 " This might be caused by an inappropriate plugin or a development error.", name);
3474 static dissector_handle_t
3475 new_dissector_handle(const int proto, const char *name, const char *description)
3477 struct dissector_handle *handle;
3479 /* Make sure name is "parsing friendly" - descriptions should be
3480 * used for complicated phrases. NULL for anonymous unregistered
3481 * dissectors is allowed; we check for that in various places.
3483 * (It might be safer to have a default name used for anonymous
3484 * dissectors rather than NULL checks scattered in the code.)
3486 if (name) {
3487 check_valid_dissector_name_or_fail(name);
3490 handle = wmem_new(wmem_epan_scope(), struct dissector_handle);
3491 handle->name = name;
3492 handle->description = description;
3493 handle->protocol = find_protocol_by_id(proto);
3494 handle->pref_suffix = NULL;
3496 if (handle->description == NULL) {
3498 * No description for what this dissector dissects
3499 * was supplied; use the short name for the protocol,
3500 * if we have the protocol.
3502 * (We may have no protocol; see, for example, the handle
3503 * for dissecting the set of protocols where the first
3504 * octet of the payload is an OSI network layer protocol
3505 * ID.)
3507 if (handle->protocol != NULL)
3508 handle->description = proto_get_protocol_short_name(handle->protocol);
3509 } else {
3510 if (name && g_strcmp0(name, proto_get_protocol_filter_name(proto)) != 0) {
3511 handle->pref_suffix = ascii_strdown_inplace(wmem_strdup_printf(wmem_epan_scope(), ".%s", name));
3512 char *pos = handle->pref_suffix;
3513 while ((pos = strchr(pos, '-')) != NULL) {
3514 *pos++ = '_';
3518 return handle;
3521 dissector_handle_t
3522 create_dissector_handle_with_name_and_description(dissector_t dissector,
3523 const int proto,
3524 const char* name,
3525 const char* description)
3527 dissector_handle_t handle;
3529 handle = new_dissector_handle(proto, name, description);
3530 handle->dissector_type = DISSECTOR_TYPE_SIMPLE;
3531 handle->dissector_func.dissector_type_simple = dissector;
3532 handle->dissector_data = NULL;
3533 return handle;
3536 dissector_handle_t
3537 create_dissector_handle_with_name(dissector_t dissector,
3538 const int proto, const char* name)
3540 return create_dissector_handle_with_name_and_description(dissector, proto, name, NULL);
3543 /* Create an anonymous handle for a new dissector. */
3544 dissector_handle_t
3545 create_dissector_handle(dissector_t dissector, const int proto)
3547 return create_dissector_handle_with_name_and_description(dissector, proto, NULL, NULL);
3550 static dissector_handle_t
3551 create_dissector_handle_with_name_and_data(dissector_cb_t dissector, const int proto, const char *name, void* cb_data)
3553 dissector_handle_t handle;
3555 handle = new_dissector_handle(proto, name, NULL);
3556 handle->dissector_type = DISSECTOR_TYPE_CALLBACK;
3557 handle->dissector_func.dissector_type_callback = dissector;
3558 handle->dissector_data = cb_data;
3559 return handle;
3562 dissector_handle_t
3563 create_dissector_handle_with_data(dissector_cb_t dissector, const int proto, void* cb_data)
3565 return create_dissector_handle_with_name_and_data(dissector, proto, NULL, cb_data);
3568 /* Destroy an anonymous handle for a dissector. */
3569 static void
3570 destroy_dissector_handle(dissector_handle_t handle)
3572 if (handle == NULL) return;
3574 dissector_delete_from_all_tables(handle);
3575 deregister_postdissector(handle);
3576 if (handle->pref_suffix) {
3577 wmem_free(wmem_epan_scope(), handle->pref_suffix);
3579 wmem_free(wmem_epan_scope(), handle);
3582 static dissector_handle_t
3583 register_dissector_handle(const char *name, dissector_handle_t handle)
3585 bool new_entry;
3587 /* A registered dissector should have a name. */
3588 if (name == NULL || name[0] == '\0') {
3589 ws_error("A registered dissector name cannot be NULL or the empty string."
3590 " Anonymous dissector handles can be created with create_dissector_handle()."
3591 " This might be caused by an inappropriate plugin or a development error.");
3594 new_entry = g_hash_table_insert(registered_dissectors, (void *)name, handle);
3595 if (!new_entry) {
3596 /* Make sure the registration is unique */
3597 ws_error("dissector handle name \"%s\" is already registered", name);
3600 return handle;
3603 /* Register a new dissector by name. */
3604 dissector_handle_t
3605 register_dissector(const char *name, dissector_t dissector, const int proto)
3607 dissector_handle_t handle;
3609 handle = create_dissector_handle_with_name(dissector, proto, name);
3611 return register_dissector_handle(name, handle);
3614 dissector_handle_t
3615 register_dissector_with_description(const char *name, const char *description, dissector_t dissector, const int proto)
3617 dissector_handle_t handle;
3619 handle = create_dissector_handle_with_name_and_description(dissector, proto, name, description);
3621 return register_dissector_handle(name, handle);
3624 dissector_handle_t
3625 register_dissector_with_data(const char *name, dissector_cb_t dissector, const int proto, void *cb_data)
3627 dissector_handle_t handle;
3629 handle = create_dissector_handle_with_name_and_data(dissector, proto, name, cb_data);
3631 return register_dissector_handle(name, handle);
3634 static bool
3635 remove_depend_dissector_from_list(depend_dissector_list_t sub_dissectors, const char *dependent)
3637 GSList *found_entry;
3639 found_entry = g_slist_find_custom(sub_dissectors->dissectors,
3640 dependent, (GCompareFunc)strcmp);
3642 if (found_entry) {
3643 g_free(found_entry->data);
3644 sub_dissectors->dissectors = g_slist_delete_link(sub_dissectors->dissectors, found_entry);
3645 return true;
3648 return false;
3651 static void
3652 remove_depend_dissector_ghfunc(void *key _U_, void *value, void *user_data)
3654 depend_dissector_list_t sub_dissectors = (depend_dissector_list_t) value;
3655 const char *dependent = (const char *)user_data;
3657 remove_depend_dissector_from_list(sub_dissectors, dependent);
3660 /* Deregister a dissector by name. */
3661 void
3662 deregister_dissector(const char *name)
3664 dissector_handle_t handle = find_dissector(name);
3665 if (handle == NULL) return;
3667 g_hash_table_remove(registered_dissectors, name);
3668 g_hash_table_remove(depend_dissector_lists, name);
3669 g_hash_table_foreach(depend_dissector_lists, remove_depend_dissector_ghfunc, (void *)name);
3671 destroy_dissector_handle(handle);
3674 /* Call a dissector through a handle but if the dissector rejected it
3675 * return 0.
3678 call_dissector_only(dissector_handle_t handle, tvbuff_t *tvb,
3679 packet_info *pinfo, proto_tree *tree, void *data)
3681 int ret;
3683 DISSECTOR_ASSERT(handle != NULL);
3684 ret = call_dissector_work(handle, tvb, pinfo, tree, true, data);
3685 return ret;
3688 /* Call a dissector through a handle and if this fails call the "data"
3689 * dissector.
3692 call_dissector_with_data(dissector_handle_t handle, tvbuff_t *tvb,
3693 packet_info *pinfo, proto_tree *tree, void *data)
3695 int ret;
3697 ret = call_dissector_only(handle, tvb, pinfo, tree, data);
3698 if (ret == 0) {
3700 * The protocol was disabled, or the dissector rejected
3701 * it. Just dissect this packet as data.
3703 DISSECTOR_ASSERT(data_handle->protocol != NULL);
3704 call_dissector_work(data_handle, tvb, pinfo, tree, true, NULL);
3705 return tvb_captured_length(tvb);
3707 return ret;
3711 call_dissector(dissector_handle_t handle, tvbuff_t *tvb,
3712 packet_info *pinfo, proto_tree *tree)
3714 return call_dissector_with_data(handle, tvb, pinfo, tree, NULL);
3718 call_data_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3720 return call_dissector_work(data_handle, tvb, pinfo, tree, true, NULL);
3724 * Call a heuristic dissector through a heur_dtbl_entry
3726 void call_heur_dissector_direct(heur_dtbl_entry_t *heur_dtbl_entry, tvbuff_t *tvb,
3727 packet_info *pinfo, proto_tree *tree, void *data)
3729 const char *saved_curr_proto;
3730 const char *saved_heur_list_name;
3731 uint16_t saved_can_desegment;
3732 unsigned saved_layers_len = 0;
3734 DISSECTOR_ASSERT(heur_dtbl_entry);
3736 /* can_desegment is set to 2 by anyone which offers this api/service.
3737 then every time a subdissector is called it is decremented by one.
3738 thus only the subdissector immediately ontop of whoever offers this
3739 service can use it.
3740 We save the current value of "can_desegment" for the
3741 benefit of TCP proxying dissectors such as SOCKS, so they
3742 can restore it and allow the dissectors they call to use
3743 the desegmentation service.
3745 saved_can_desegment = pinfo->can_desegment;
3746 pinfo->saved_can_desegment = saved_can_desegment;
3747 pinfo->can_desegment = saved_can_desegment-(saved_can_desegment>0);
3749 saved_curr_proto = pinfo->current_proto;
3750 saved_heur_list_name = pinfo->heur_list_name;
3752 saved_layers_len = wmem_list_count(pinfo->layers);
3754 if (!heur_dtbl_entry->enabled ||
3755 (heur_dtbl_entry->protocol != NULL && !proto_is_protocol_enabled(heur_dtbl_entry->protocol))) {
3756 DISSECTOR_ASSERT(data_handle->protocol != NULL);
3757 call_dissector_work(data_handle, tvb, pinfo, tree, true, NULL);
3758 return;
3761 if (heur_dtbl_entry->protocol != NULL) {
3762 /* do NOT change this behavior - wslua uses the protocol short name set here in order
3763 to determine which Lua-based heuristic dissector to call */
3764 pinfo->current_proto = proto_get_protocol_short_name(heur_dtbl_entry->protocol);
3765 add_layer(pinfo, proto_get_id(heur_dtbl_entry->protocol));
3768 pinfo->heur_list_name = heur_dtbl_entry->list_name;
3770 /* call the dissector, in case of failure call data handle (might happen with exported PDUs) */
3771 if (!(*heur_dtbl_entry->dissector)(tvb, pinfo, tree, data)) {
3773 * We added a protocol layer above. The dissector
3774 * didn't accept the packet or it didn't add any
3775 * items to the tree so remove it from the list.
3777 while (wmem_list_count(pinfo->layers) > saved_layers_len) {
3778 remove_last_layer(pinfo, true);
3781 call_dissector_work(data_handle, tvb, pinfo, tree, true, NULL);
3784 /* XXX: Remove layers if it was accepted but didn't actually consume
3785 * data due to desegmentation? (Currently the only callers of this
3786 * are UDP and exported PDUs, so not yet necessary.)
3789 /* Restore info from caller */
3790 pinfo->can_desegment = saved_can_desegment;
3791 pinfo->current_proto = saved_curr_proto;
3792 pinfo->heur_list_name = saved_heur_list_name;
3796 static int
3797 find_matching_proto_name(const void *arg1, const void *arg2)
3799 const char *protocol_name = (const char*)arg1;
3800 const char *name = (const char *)arg2;
3802 return strcmp(protocol_name, name);
3805 bool register_depend_dissector(const char* parent, const char* dependent)
3807 GSList *list_entry;
3808 depend_dissector_list_t sub_dissectors;
3810 if ((parent == NULL) || (dependent == NULL))
3812 /* XXX - assert on parent? */
3813 return false;
3816 sub_dissectors = find_depend_dissector_list(parent);
3817 if (sub_dissectors == NULL) {
3818 /* parent protocol doesn't exist, create it */
3819 sub_dissectors = g_slice_new(struct depend_dissector_list);
3820 sub_dissectors->dissectors = NULL; /* initially empty */
3821 g_hash_table_insert(depend_dissector_lists, (void *)g_strdup(parent), (void *) sub_dissectors);
3824 /* Verify that sub-dissector is not already in the list */
3825 list_entry = g_slist_find_custom(sub_dissectors->dissectors, (void *)dependent, find_matching_proto_name);
3826 if (list_entry != NULL)
3827 return true; /* Dependency already exists */
3829 sub_dissectors->dissectors = g_slist_prepend(sub_dissectors->dissectors, (void *)g_strdup(dependent));
3830 return true;
3833 bool deregister_depend_dissector(const char* parent, const char* dependent)
3835 depend_dissector_list_t sub_dissectors = find_depend_dissector_list(parent);
3837 /* sanity check */
3838 ws_assert(sub_dissectors != NULL);
3840 return remove_depend_dissector_from_list(sub_dissectors, dependent);
3843 depend_dissector_list_t find_depend_dissector_list(const char* name)
3845 return (depend_dissector_list_t)g_hash_table_lookup(depend_dissector_lists, name);
3849 * Dumps the "layer type"/"decode as" associations to stdout, similar
3850 * to the proto_registrar_dump_*() routines.
3852 * There is one record per line. The fields are tab-delimited.
3854 * Field 1 = layer type, e.g. "tcp.port"
3855 * Field 2 = selector - decimal for integer tables, strings for string tables,
3856 * blank for payload tables. Custom and GUID tables aren't shown.
3857 * (XXX - Should integer tables respect the table base, e.g. use hex?)
3858 * Field 3 = "decode as" name, e.g. "http"
3860 * XXX - View -> Internals -> Dissector Tables in the GUI includes the UI name,
3861 * and separates tables by category. We could add fields for the the UI name
3862 * and category.
3864 * The GUI doesn't display FT_NONE (it should) nor FT_GUID tables, but does
3865 * FT_BYTES (Custom) tables with the handle description name as key.
3866 * That may or may not be helpful.
3870 static void
3871 dissector_dump_decodes_display(const char *table_name,
3872 ftenum_t selector_type _U_, void *key, void *value)
3874 dissector_table_t sub_dissectors = find_dissector_table(table_name);
3875 dtbl_entry_t *dtbl_entry;
3876 dissector_handle_t handle;
3877 int proto_id;
3878 const char *decode_as;
3880 ws_assert(sub_dissectors);
3882 dtbl_entry = (dtbl_entry_t *)value;
3883 ws_assert(dtbl_entry);
3885 handle = dtbl_entry->current;
3886 ws_assert(handle);
3888 proto_id = dissector_handle_get_protocol_index(handle);
3890 if (proto_id != -1) {
3891 decode_as = proto_get_protocol_filter_name(proto_id);
3892 ws_assert(decode_as != NULL);
3893 switch (sub_dissectors->type) {
3894 case FT_UINT8:
3895 case FT_UINT16:
3896 case FT_UINT24:
3897 case FT_UINT32:
3898 printf("%s\t%u\t%s\n", table_name, GPOINTER_TO_UINT(key), decode_as);
3899 break;
3901 case FT_STRING:
3902 printf("%s\t%s\t%s\n", table_name, (char*)key, decode_as);
3903 break;
3905 case FT_NONE:
3906 printf("%s\t\t%s\n", table_name, decode_as);
3907 break;
3909 case FT_GUID:
3910 // We could output something here with the guid_key
3911 break;
3913 case FT_BYTES:
3914 // View->Internals->Dissector Tables uses the description,
3915 // but that doesn't tell anything about how the table is
3916 // configured. (This isn't a list of all possible handles.)
3917 // Is it useful to output?
3918 break;
3920 default:
3921 break;
3926 static int compare_ints(const void *a, const void *b)
3928 uint32_t inta, intb;
3930 inta = GPOINTER_TO_UINT(a);
3931 intb = GPOINTER_TO_UINT(b);
3933 if (inta < intb)
3934 return -1;
3935 if (inta > intb)
3936 return 1;
3937 return 0;
3940 static void
3941 dissector_dump_table_decodes(const char *table_name, const char *ui_name _U_, void *user_data _U_)
3943 dissector_table_t sub_dissectors = find_dissector_table(table_name);
3944 GList *keys;
3946 ws_assert(sub_dissectors);
3947 keys = g_hash_table_get_keys(sub_dissectors->hash_table);
3949 switch (sub_dissectors->type) {
3950 case FT_UINT8:
3951 case FT_UINT16:
3952 case FT_UINT24:
3953 case FT_UINT32:
3954 keys = g_list_sort(keys, compare_ints);
3955 break;
3957 case FT_STRING:
3958 case FT_STRINGZ:
3959 case FT_UINT_STRING:
3960 case FT_STRINGZPAD:
3961 case FT_STRINGZTRUNC:
3962 keys = g_list_sort(keys, (GCompareFunc)strcmp);
3963 break;
3965 /* FT_NONE we don't need to sort. We could do something for
3966 * FT_GUID and FT_BYTES (Custom) if we were to output them,
3967 * possibly with g_list_sort_with_data.
3969 default:
3970 break;
3973 for (GList *entry = g_list_first(keys); entry; entry = entry->next) {
3974 void *key = entry->data;
3975 void *value = g_hash_table_lookup(sub_dissectors->hash_table, key);
3976 dissector_dump_decodes_display(table_name, sub_dissectors->type, key, value);
3979 g_list_free(keys);
3982 void
3983 dissector_dump_decodes(void)
3985 dissector_all_tables_foreach_table(dissector_dump_table_decodes, NULL, (GCompareFunc)strcmp);
3989 * Dumps information about dissector tables to stdout.
3991 * There is one record per line. The fields are tab-delimited.
3993 * Field 1 = dissector table name, e.g. "tcp.port"
3994 * Field 2 = name used for the dissector table in the GUI
3995 * Field 3 = type (textual representation of the ftenum type)
3996 * Field 4 = base for display (for integer types)
3997 * Field 5 = protocol name
3998 * Field 6 = "decode as" support
4000 * This does not dump the *individual entries* in the dissector tables,
4001 * i.e. it doesn't show what dissector handles what particular value
4002 * of the key in the dissector table.
4005 static void
4006 dissector_dump_dissector_tables_display (void *key, void *user_data _U_)
4008 const char *table_name = (const char *)key;
4009 dissector_table_t table;
4011 table = (dissector_table_t)g_hash_table_lookup(dissector_tables, key);
4012 printf("%s\t%s\t%s", table_name, table->ui_name, ftype_name(table->type));
4013 switch (table->type) {
4015 case FT_UINT8:
4016 case FT_UINT16:
4017 case FT_UINT24:
4018 case FT_UINT32:
4019 switch(table->param) {
4021 case BASE_NONE:
4022 printf("\tBASE_NONE");
4023 break;
4025 case BASE_DEC:
4026 printf("\tBASE_DEC");
4027 break;
4029 case BASE_HEX:
4030 printf("\tBASE_HEX");
4031 break;
4033 case BASE_DEC_HEX:
4034 printf("\tBASE_DEC_HEX");
4035 break;
4037 case BASE_HEX_DEC:
4038 printf("\tBASE_HEX_DEC");
4039 break;
4041 default:
4042 printf("\t%d", table->param);
4043 break;
4045 break;
4047 default:
4048 break;
4050 if (table->protocol != NULL) {
4051 printf("\t%s",
4052 proto_get_protocol_short_name(table->protocol));
4053 } else
4054 printf("\t(no protocol)");
4055 printf("\tDecode As %ssupported",
4056 table->supports_decode_as ? "" : "not ");
4057 printf("\n");
4060 /** The output format of this function is meant to parallel
4061 * that of dissector_dump_dissector_tables_display().
4062 * Field 3 is shown as "heuristic".
4063 * Field 4 is omitted, as it is for FT_STRING dissector tables above.
4064 * Field 6 is omitted since "Decode As" doesn't apply.
4067 static void
4068 dissector_dump_heur_dissector_tables_display (void *key, void *user_data _U_)
4070 const char *list_name = (const char *)key;
4071 heur_dissector_list_t list;
4073 list = (heur_dissector_list_t)g_hash_table_lookup(heur_dissector_lists, key);
4074 printf("%s\t%s\theuristic", list_name, list->ui_name ? list->ui_name : list_name);
4076 if (list->protocol != NULL) {
4077 printf("\t%s",
4078 proto_get_protocol_short_name(list->protocol));
4079 } else
4080 printf("\t(no protocol)");
4081 printf("\n");
4084 static int
4085 compare_dissector_key_name(const void *dissector_a, const void *dissector_b)
4087 return strcmp((const char*)dissector_a, (const char*)dissector_b);
4090 void
4091 dissector_dump_dissector_tables(void)
4093 GList *list;
4095 list = g_hash_table_get_keys(dissector_tables);
4096 list = g_list_sort(list, compare_dissector_key_name);
4097 g_list_foreach(list, dissector_dump_dissector_tables_display, NULL);
4098 g_list_free(list);
4100 list = g_hash_table_get_keys(heur_dissector_lists);
4101 list = g_list_sort(list, compare_dissector_key_name);
4102 g_list_foreach(list, dissector_dump_heur_dissector_tables_display, NULL);
4103 g_list_free(list);
4107 * Dumps the entries in the table of registered dissectors.
4109 * There is one record per line. The fields are tab-delimited.
4111 * Field 1 = dissector name
4112 * Field 2 = dissector description
4115 struct dissector_info {
4116 const char *name;
4117 const char *description;
4120 static int
4121 compare_dissector_info_names(const void *arg1, const void *arg2)
4123 const struct dissector_info *info1 = (const struct dissector_info *) arg1;
4124 const struct dissector_info *info2 = (const struct dissector_info *) arg2;
4126 return strcmp(info1->name, info2->name);
4129 void
4130 dissector_dump_dissectors(void)
4132 GHashTableIter iter;
4133 struct dissector_info *dissectors_info;
4134 unsigned num_protocols;
4135 gpointer key, value;
4136 unsigned proto_index;
4138 g_hash_table_iter_init(&iter, registered_dissectors);
4139 num_protocols = g_hash_table_size(registered_dissectors);
4140 dissectors_info = g_new(struct dissector_info, num_protocols);
4141 proto_index = 0;
4142 while (g_hash_table_iter_next(&iter, &key, &value)) {
4143 dissectors_info[proto_index].name = (const char *)key;
4144 dissectors_info[proto_index].description =
4145 ((dissector_handle_t) value)->description;
4146 proto_index++;
4148 qsort(dissectors_info, num_protocols, sizeof(struct dissector_info),
4149 compare_dissector_info_names);
4150 for (proto_index = 0; proto_index < num_protocols; proto_index++) {
4151 printf("%s\t%s\n", dissectors_info[proto_index].name,
4152 dissectors_info[proto_index].description);
4154 g_free(dissectors_info);
4157 void
4158 register_postdissector(dissector_handle_t handle)
4160 postdissector p;
4162 if (!postdissectors)
4163 postdissectors = g_array_sized_new(false, false, (unsigned)sizeof(postdissector), 1);
4165 p.handle = handle;
4166 p.wanted_hfids = NULL;
4167 postdissectors = g_array_append_val(postdissectors, p);
4170 void
4171 set_postdissector_wanted_hfids(dissector_handle_t handle, GArray *wanted_hfids)
4173 unsigned i;
4175 if (!postdissectors) return;
4177 for (i = 0; i < postdissectors->len; i++) {
4178 if (POSTDISSECTORS(i).handle == handle) {
4179 if (POSTDISSECTORS(i).wanted_hfids) {
4180 g_array_free(POSTDISSECTORS(i).wanted_hfids, true);
4182 POSTDISSECTORS(i).wanted_hfids = wanted_hfids;
4183 break;
4188 void
4189 deregister_postdissector(dissector_handle_t handle)
4191 unsigned i;
4193 if (!postdissectors) return;
4195 for (i = 0; i < postdissectors->len; i++) {
4196 if (POSTDISSECTORS(i).handle == handle) {
4197 if (POSTDISSECTORS(i).wanted_hfids) {
4198 g_array_free(POSTDISSECTORS(i).wanted_hfids, true);
4200 postdissectors = g_array_remove_index_fast(postdissectors, i);
4201 break;
4206 bool
4207 have_postdissector(void)
4209 unsigned i;
4210 dissector_handle_t handle;
4212 for (i = 0; i < postdissectors->len; i++) {
4213 handle = POSTDISSECTORS(i).handle;
4215 if (handle->protocol != NULL
4216 && proto_is_protocol_enabled(handle->protocol)) {
4217 /* We have at least one enabled postdissector */
4218 return true;
4221 return false;
4224 void
4225 call_all_postdissectors(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4227 unsigned i;
4229 for (i = 0; i < postdissectors->len; i++) {
4230 call_dissector_only(POSTDISSECTORS(i).handle,
4231 tvb, pinfo, tree, NULL);
4235 bool
4236 postdissectors_want_hfids(void)
4238 unsigned i;
4240 for (i = 0; i < postdissectors->len; i++) {
4241 if (POSTDISSECTORS(i).wanted_hfids != NULL &&
4242 POSTDISSECTORS(i).wanted_hfids->len != 0 &&
4243 (POSTDISSECTORS(i).handle->protocol == NULL ||
4244 proto_is_protocol_enabled(POSTDISSECTORS(i).handle->protocol)))
4245 return true;
4247 return false;
4250 void
4251 prime_epan_dissect_with_postdissector_wanted_hfids(epan_dissect_t *edt)
4253 unsigned i;
4255 if (postdissectors == NULL) {
4257 * No postdissector expressed an interest in any hfids.
4259 return;
4261 for (i = 0; i < postdissectors->len; i++) {
4262 if (POSTDISSECTORS(i).wanted_hfids != NULL &&
4263 POSTDISSECTORS(i).wanted_hfids->len != 0 &&
4264 (POSTDISSECTORS(i).handle->protocol == NULL ||
4265 proto_is_protocol_enabled(POSTDISSECTORS(i).handle->protocol)))
4266 epan_dissect_prime_with_hfid_array(edt,
4267 POSTDISSECTORS(i).wanted_hfids);
4271 void
4272 increment_dissection_depth(packet_info *pinfo) {
4273 pinfo->dissection_depth++;
4274 DISSECTOR_ASSERT(pinfo->dissection_depth < (int)prefs.gui_max_tree_depth);
4277 void
4278 decrement_dissection_depth(packet_info *pinfo) {
4279 pinfo->dissection_depth--;
4280 DISSECTOR_ASSERT(pinfo->dissection_depth >= 0);
4284 * Editor modelines - https://www.wireshark.org/tools/modelines.html
4286 * Local variables:
4287 * c-basic-offset: 8
4288 * tab-width: 8
4289 * indent-tabs-mode: t
4290 * End:
4292 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
4293 * :indentSize=8:tabSize=8:noTabs=false: