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
12 #define WS_LOG_DOMAIN LOG_DOMAIN_EPAN
24 #include "timestamp.h"
26 #include "osi-utils.h"
29 #include "addr_resolv.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
;
54 * Has a tvbuff and a name.
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
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
;
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
{
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.
134 dissector_handle_t handle
;
135 GArray
*wanted_hfids
;
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)
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
{
163 protocol_t
*protocol
;
167 static GHashTable
*heur_dissector_lists
;
169 /* Name hashtables for fast detection of duplicate names */
170 static GHashTable
* heuristic_short_names
;
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
);
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
);
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
);
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
,
211 registered_dissectors
= g_hash_table_new_full(g_str_hash
, g_str_equal
,
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
);
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
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. */
274 call_routine(void *routine
, void *dummy _U_
)
276 void_func_t func
= (void_func_t
)routine
;
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.
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
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
318 tvb_set_reported_length(tvb
, specified_len
);
323 register_init_routine(void (*func
)(void))
325 init_routines
= g_slist_prepend(init_routines
, (void *)func
);
329 register_cleanup_routine(void (*func
)(void))
331 cleanup_routines
= g_slist_prepend(cleanup_routines
, (void *)func
);
334 /* register a new shutdown routine */
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. */
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 */
363 /* Initialize the expert infos */
364 expert_packet_init();
368 cleanup_dissection(void)
370 /* Cleanup protocol-specific variables. */
371 g_slist_foreach(cleanup_routines
, &call_routine
, NULL
);
373 /* Cleanup the stream-handling tables */
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
390 register_postseq_cleanup_routine(void_func_t func
)
392 postseq_cleanup_routines
= g_slist_prepend(postseq_cleanup_routines
,
396 /* Call all the registered "postseq_cleanup" routines. */
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.
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
);
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
);
422 remove_last_data_source(packet_info
*pinfo
)
426 last
= g_slist_last(pinfo
->data_src
);
427 pinfo
->data_src
= g_slist_delete_link(pinfo
->data_src
, last
);
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"));
440 get_data_source_tvb(const struct data_source
*src
)
446 * Find and return the tvb associated with the given data source name
449 get_data_source_tvb_by_name(packet_info
*pinfo
, const char *name
)
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
;
463 * Free up a frame's list of data sources.
466 free_data_sources(packet_info
*pinfo
)
468 if (pinfo
->data_src
) {
469 g_slist_free(pinfo
->data_src
);
470 pinfo
->data_src
= NULL
;
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
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
;
499 register_final_registration_routine(void (*func
)(void))
501 final_registration_routines
= g_slist_prepend(final_registration_routines
,
505 /* Call all the registered "final_registration" routines. */
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() */
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";
528 case REC_TYPE_FT_SPECIFIC_EVENT
:
529 record_type
= "Event";
532 case REC_TYPE_FT_SPECIFIC_REPORT
:
533 record_type
= "Report";
536 case REC_TYPE_SYSCALL
:
537 record_type
= "System Call";
540 case REC_TYPE_SYSTEMD_JOURNAL_EXPORT
:
541 record_type
= "Systemd Journal Entry";
544 case REC_TYPE_CUSTOM_BLOCK
:
545 switch (rec
->rec_header
.custom_block_header
.pen
) {
547 record_type
= "Black Box Log Block";
550 record_type
= "PCAPNG Custom Block";
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();
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.
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
;
590 case REC_TYPE_FT_SPECIFIC_EVENT
:
591 case REC_TYPE_FT_SPECIFIC_REPORT
:
592 edt
->pi
.pseudo_header
= NULL
;
595 case REC_TYPE_SYSCALL
:
596 edt
->pi
.pseudo_header
= NULL
;
599 case REC_TYPE_SYSTEMD_JOURNAL_EXPORT
:
600 edt
->pi
.pseudo_header
= NULL
;
603 case REC_TYPE_CUSTOM_BLOCK
:
604 switch (rec
->rec_header
.custom_block_header
.pen
) {
606 edt
->pi
.pseudo_header
= NULL
;
609 edt
->pi
.pseudo_header
= NULL
;
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
);
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
);
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" */
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
);
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]",
675 wtap_block_unref(rec
->block
);
681 /* Creates the top-most tvbuff and calls dissect_file() */
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
;
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
;
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
);
714 frame_delta_abs_time(edt
->session
, fd
, fd
->frame_ref_num
, &edt
->pi
.rel_ts
);
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
);
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
);
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]");
749 wtap_block_unref(rec
->block
);
755 /*********************** code added for sub-dissector lookup *********************/
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 */
769 enum dissector_e dissector_type
;
771 dissector_t dissector_type_simple
;
772 dissector_cb_t dissector_type_callback
;
774 void *dissector_data
;
775 protocol_t
*protocol
;
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
);
799 /* Increment layer number */
800 (*proto_layer_num_ptr
)++;
802 pinfo
->curr_proto_layer_num
= *proto_layer_num_ptr
;
806 remove_last_layer(packet_info
*pinfo
, bool reduce_count
)
808 int *proto_layer_num_ptr
;
809 wmem_list_frame_t
*frame
;
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
);
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
);
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
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
;
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
);
868 case DISSECTOR_TYPE_CALLBACK
:
869 len
= (handle
->dissector_func
.dissector_type_callback
)(tvb
, pinfo
, tree
, data
, handle
->dissector_data
);
873 ws_assert_not_reached();
875 pinfo
->current_proto
= saved_proto
;
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.
890 call_dissector_work_error(dissector_handle_t handle
, tvbuff_t
*tvb
,
891 packet_info
*pinfo_arg
, proto_tree
*tree
, void *);
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
;
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
;
905 if (handle
->protocol
!= NULL
&&
906 !proto_is_protocol_enabled(handle
->protocol
)) {
908 * The protocol isn't enabled.
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
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
);
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
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
;
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;
1001 address save_dl_src
;
1002 address save_dl_dst
;
1003 address save_net_src
;
1004 address save_net_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
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
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. */
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.
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
);
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;
1111 * An entry in the hash table portion of a dissector table.
1114 dissector_handle_t initial
;
1115 dissector_handle_t current
;
1118 /* Finds a dissector table by table name. */
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
);
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
) {
1146 * You can do a uint lookup in these tables.
1150 /* For now treat as uint */
1155 * But you can't do a uint lookup in any other types
1158 ws_assert_not_reached();
1164 return (dtbl_entry_t
*)g_hash_table_lookup(sub_dissectors
->hash_table
,
1165 GUINT_TO_POINTER(pattern
));
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
;
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
)));
1188 /* Add an entry to a uint dissector table. */
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",
1203 if (wireshark_abort_on_dissector_bug
)
1207 if (sub_dissectors
== NULL
) {
1208 fprintf(stderr
, "OOPS: dissector table \"%s\" doesn't exist\n",
1210 fprintf(stderr
, "Protocol being registered is \"%s\"\n",
1211 proto_get_protocol_long_name(handle
->protocol
));
1212 if (wireshark_abort_on_dissector_bug
)
1217 switch (sub_dissectors
->type
) {
1224 * You can do a uint lookup in these tables.
1230 * But you can't do a uint lookup in any other types
1233 ws_assert_not_reached();
1237 dissector_add_uint_sanity_check(name
, pattern
, handle
, sub_dissectors
);
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
;
1266 if (range
->nranges
== 0) {
1268 * Even an empty range would want a chance for
1269 * Decode As, if the dissector table supports
1272 sub_dissectors
= find_dissector_table(name
);
1273 if (sub_dissectors
->supports_decode_as
)
1274 dissector_add_for_decode_as(name
, handle
);
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
);
1287 dissector_add_range_preference(const char *name
, dissector_handle_t handle
, const char* range_str
)
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
);
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
) {
1336 max_value
= 0xFFFFFF;
1339 max_value
= 0xFFFFFFFF;
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
);
1354 void dissector_add_uint_with_preference(const char *name
, const uint32_t pattern
,
1355 dissector_handle_t handle
)
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
)
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 */
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
;
1390 ws_assert(sub_dissectors
);
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
)
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
);
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
);
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
);
1445 /* Remove the table entry */
1446 g_hash_table_remove(sub_dissectors
->hash_table
, guid_val
);
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.
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
);
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 */
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. */
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
;
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
));
1518 dtbl_entry
->current
= handle
;
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.
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. */
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
;
1547 ws_assert(sub_dissectors
);
1552 dtbl_entry
= find_uint_dtbl_entry(sub_dissectors
, pattern
);
1554 if (dtbl_entry
== NULL
)
1558 * Found - is there an initial value?
1560 if (dtbl_entry
->initial
!= NULL
) {
1561 dtbl_entry
->current
= dtbl_entry
->initial
;
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.
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
);
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
;
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.
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.
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.
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. */
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
;
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
;
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
)
1687 switch (sub_dissectors
->type
) {
1692 case FT_STRINGZTRUNC
:
1694 * You can do a string lookup in these tables.
1700 * But you can't do a string lookup in any other types
1703 ws_assert_not_reached();
1706 if (sub_dissectors
->param
== STRING_CASE_INSENSITIVE
) {
1707 key
= g_ascii_strdown(pattern
, -1);
1709 key
= g_strdup(pattern
);
1715 ret
= (dtbl_entry_t
*)g_hash_table_lookup(sub_dissectors
->hash_table
, key
);
1722 /* Add an entry to a string dissector table. */
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
;
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",
1737 if (wireshark_abort_on_dissector_bug
)
1741 if (sub_dissectors
== NULL
) {
1742 fprintf(stderr
, "OOPS: dissector table \"%s\" doesn't exist\n",
1744 fprintf(stderr
, "Protocol being registered is \"%s\"\n",
1745 proto_get_protocol_long_name(handle
->protocol
));
1746 if (wireshark_abort_on_dissector_bug
)
1751 switch (sub_dissectors
->type
) {
1756 case FT_STRINGZTRUNC
:
1758 * You can do a string lookup in these tables.
1764 * But you can't do a string lookup in any other types
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);
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 */
1800 /* If temporary dissectors are deleted, then the original dissector must */
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
;
1810 ws_assert(sub_dissectors
);
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. */
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
;
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
,
1851 dtbl_entry
->current
= handle
;
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.
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. */
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
;
1880 ws_assert(sub_dissectors
);
1885 dtbl_entry
= find_string_dtbl_entry(sub_dissectors
, pattern
);
1887 if (dtbl_entry
== NULL
)
1891 * Found - is there an initial value?
1893 if (dtbl_entry
->initial
!= NULL
) {
1894 dtbl_entry
->current
= dtbl_entry
->initial
;
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.
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
);
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
;
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.
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.
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. */
1983 dissector_get_string_handle(dissector_table_t sub_dissectors
,
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
;
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
;
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",
2025 if (wireshark_abort_on_dissector_bug
)
2029 if (sub_dissectors
== NULL
) {
2030 fprintf(stderr
, "OOPS: dissector table \"%s\" doesn't exist\n",
2032 fprintf(stderr
, "Protocol being registered is \"%s\"\n",
2033 proto_get_protocol_long_name(handle
->protocol
));
2034 if (wireshark_abort_on_dissector_bug
)
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
;
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",
2081 if (wireshark_abort_on_dissector_bug
)
2085 if (sub_dissectors
== NULL
) {
2086 fprintf(stderr
, "OOPS: dissector table \"%s\" doesn't exist\n",
2088 fprintf(stderr
, "Protocol being registered is \"%s\"\n",
2089 proto_get_protocol_long_name(handle
->protocol
));
2090 if (wireshark_abort_on_dissector_bug
)
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
;
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.
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.
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
;
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
2226 dissector_get_payload_handle(dissector_table_t
const dissector_table
)
2228 return dissector_get_uint_handle(dissector_table
, 0);
2232 dtbl_entry_get_handle (dtbl_entry_t
*dtbl_entry
)
2234 return dtbl_entry
->current
;
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
;
2245 if (a
->protocol
== NULL
)
2248 a_name
= proto_get_protocol_filter_name(proto_get_id(a
->protocol
));
2250 if (b
->protocol
== NULL
)
2253 b_name
= proto_get_protocol_filter_name(proto_get_id(b
->protocol
));
2255 ret
= strcmp(a_name
, b_name
);
2260 packet_all_tables_sort_handles(void)
2262 GHashTableIter iter
;
2263 g_hash_table_iter_init(&iter
, dissector_tables
);
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. */
2279 dissector_add_for_decode_as(const char *name
, dissector_handle_t handle
)
2281 dissector_table_t sub_dissectors
= find_dissector_table(name
);
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",
2291 fprintf(stderr
, "Protocol being registered is \"%s\"\n",
2292 proto_get_protocol_long_name(handle
->protocol
));
2293 if (wireshark_abort_on_dissector_bug
)
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",
2309 proto_get_protocol_short_name(handle
->protocol
),
2311 if (wireshark_abort_on_dissector_bug
)
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.
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
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)",
2362 name
, handle
->description
);
2363 if (wireshark_abort_on_dissector_bug
)
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
) {
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)",
2394 if (wireshark_abort_on_dissector_bug
)
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
);
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
);
2423 dtbl_entry_get_initial_handle (dtbl_entry_t
*dtbl_entry
)
2425 return dtbl_entry
->initial
;
2429 dissector_table_get_dissector_handles(dissector_table_t dissector_table
) {
2430 if (!dissector_table
)
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
;
2445 * A callback function to changed a dissector_handle if matched
2446 * This is used when iterating a dissector table
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
;
2471 dissector_table_get_type(dissector_table_t dissector_table
) {
2472 if (!dissector_table
) return FT_NONE
;
2473 return dissector_table
->type
;
2477 dissector_table_allow_decode_as(dissector_table_t dissector_table
)
2479 dissector_table
->supports_decode_as
= true;
2483 dissector_table_supports_decode_as(dissector_table_t dissector_table
)
2485 return dissector_table
->supports_decode_as
;
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
));
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 /**************************************************/
2507 /* Routines to walk dissector tables */
2509 /**************************************************/
2511 typedef struct dissector_foreach_info
{
2513 DATFunc caller_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.
2523 dissector_table_foreach_func (void *key
, void *value
, void *user_data
)
2525 dissector_foreach_info_t
*info
;
2526 dtbl_entry_t
*dtbl_entry
;
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
2539 * XXX - should the latter check be done?
2544 info
= (dissector_foreach_info_t
*)user_data
;
2545 info
->caller_func(info
->table_name
, info
->selector_type
, key
, value
,
2550 * Called for each entry in the table of all dissector tables.
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
;
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
);
2570 * Walk all dissector tables calling a user supplied function on each
2574 dissector_all_tables_foreach (DATFunc func
,
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
);
2587 * Walk one dissector table's hash table calling a user supplied function
2591 dissector_table_foreach (const char *table_name
,
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.
2610 dissector_table_foreach_handle(const char *table_name
,
2611 DATFunc_handle func
,
2614 dissector_table_t sub_dissectors
= find_dissector_table(table_name
);
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.
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
;
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.
2642 info
= (dissector_foreach_info_t
*)user_data
;
2643 info
->caller_func(info
->table_name
, info
->selector_type
, key
, value
,
2648 * Walk all dissector tables calling a user supplied function only on
2649 * any entry that has been changed from its original state.
2652 dissector_all_tables_foreach_changed (DATFunc func
,
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.
2668 dissector_table_foreach_changed (const char *table_name
,
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
{
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.
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.
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
2723 dissector_all_tables_foreach_table (DATFunc_table func
,
2725 GCompareFunc compare_key_func
)
2727 dissector_foreach_table_info_t info
;
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
);
2741 g_hash_table_foreach(dissector_tables
, dissector_all_tables_foreach_table_func
, &info
);
2746 register_dissector_table(const char *name
, const char *ui_name
, const int proto
, const ftenum_t type
,
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
);
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
,
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
,
2787 sub_dissectors
->hash_table
= g_hash_table_new_full(uuid_hash
,
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
,
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
,
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
;
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
;
2863 g_hash_table_insert(dissector_table_aliases
, (void *) alias_name
, (void *) name
);
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
);
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
;
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
;
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
);
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
);
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
;
2948 * Make sure the dissector table exists.
2950 if (sub_dissectors
== NULL
) {
2951 fprintf(stderr
, "OOPS: dissector table \"%s\" doesn't exist\n",
2953 proto_name
= proto_get_protocol_name(proto
);
2954 if (proto_name
!= NULL
) {
2955 fprintf(stderr
, "Protocol being registered is \"%s\"\n",
2958 if (wireshark_abort_on_dissector_bug
)
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",
2977 if (wireshark_abort_on_dissector_bug
)
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
));
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;
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
;
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
);
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
,
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
)
3059 const char *saved_curr_proto
;
3060 const char *saved_heur_list_name
;
3062 GSList
*prev_entry
= NULL
;
3063 uint16_t saved_can_desegment
;
3064 unsigned saved_layers_len
= 0;
3065 heur_dtbl_entry_t
*hdtbl_entry
;
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
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);
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.
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
);
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
);
3162 pinfo
->current_proto
= saved_curr_proto
;
3163 pinfo
->heur_list_name
= saved_heur_list_name
;
3164 pinfo
->can_desegment
= saved_can_desegment
;
3168 typedef struct heur_dissector_foreach_info
{
3170 DATFunc_heur caller_func
;
3172 const char *table_name
;
3173 } heur_dissector_foreach_info_t
;
3176 * Called for each entry in a heuristic dissector table.
3179 heur_dissector_table_foreach_func (void *data
, void *user_data
)
3181 heur_dissector_foreach_info_t
*info
;
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
,
3192 * Walk one heuristic dissector table's list calling a user supplied function
3196 heur_dissector_table_foreach (const char *table_name
,
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
{
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.
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.
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
3252 dissector_all_heur_tables_foreach_table (DATFunc_heur_table func
,
3254 GCompareFunc compare_key_func
)
3256 heur_dissector_foreach_table_info_t info
;
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
);
3270 g_hash_table_foreach(heur_dissector_lists
, dissector_all_heur_tables_foreach_table_func
, &info
);
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",
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
);
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
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
);
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
) {
3340 g_hash_table_remove(heur_dissector_lists
, name
);
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
3359 dissector_handle_get_protocol_long_name(const dissector_handle_t handle
)
3361 if (handle
== NULL
|| handle
->protocol
== 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
3370 dissector_handle_get_protocol_short_name(const dissector_handle_t handle
)
3372 if (handle
== NULL
|| handle
->protocol
== NULL
) {
3375 return proto_get_protocol_short_name(handle
->protocol
);
3378 /* For backwards source and binary compatibility */
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. */
3388 dissector_handle_get_description(const dissector_handle_t handle
)
3390 if (handle
== NULL
) {
3393 return handle
->description
;
3396 /* Get the index of the protocol for a dissector handle, if it has
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
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. */
3417 get_dissector_names(void)
3419 if (!registered_dissectors
) {
3423 return g_hash_table_get_keys(registered_dissectors
);
3426 /* Find a registered dissector by name. */
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
));
3445 /* Get a dissector name from handle. */
3447 dissector_handle_get_dissector_name(const dissector_handle_t handle
)
3449 if (handle
== NULL
) {
3452 return handle
->name
;
3456 dissector_handle_get_pref_suffix(const dissector_handle_t handle
)
3458 if (handle
== NULL
) {
3461 return handle
->pref_suffix
? handle
->pref_suffix
: "";
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.)
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
3507 if (handle
->protocol
!= NULL
)
3508 handle
->description
= proto_get_protocol_short_name(handle
->protocol
);
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
) {
3522 create_dissector_handle_with_name_and_description(dissector_t dissector
,
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
;
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. */
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
;
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. */
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
)
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
);
3596 /* Make sure the registration is unique */
3597 ws_error("dissector handle name \"%s\" is already registered", name
);
3603 /* Register a new dissector by name. */
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
);
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
);
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
);
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
);
3643 g_free(found_entry
->data
);
3644 sub_dissectors
->dissectors
= g_slist_delete_link(sub_dissectors
->dissectors
, found_entry
);
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. */
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
3678 call_dissector_only(dissector_handle_t handle
, tvbuff_t
*tvb
,
3679 packet_info
*pinfo
, proto_tree
*tree
, void *data
)
3683 DISSECTOR_ASSERT(handle
!= NULL
);
3684 ret
= call_dissector_work(handle
, tvb
, pinfo
, tree
, true, data
);
3688 /* Call a dissector through a handle and if this fails call the "data"
3692 call_dissector_with_data(dissector_handle_t handle
, tvbuff_t
*tvb
,
3693 packet_info
*pinfo
, proto_tree
*tree
, void *data
)
3697 ret
= call_dissector_only(handle
, tvb
, pinfo
, tree
, data
);
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
);
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
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
);
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
;
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
)
3808 depend_dissector_list_t sub_dissectors
;
3810 if ((parent
== NULL
) || (dependent
== NULL
))
3812 /* XXX - assert on parent? */
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
));
3833 bool deregister_depend_dissector(const char* parent
, const char* dependent
)
3835 depend_dissector_list_t sub_dissectors
= find_depend_dissector_list(parent
);
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
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.
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
;
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
;
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
) {
3898 printf("%s\t%u\t%s\n", table_name
, GPOINTER_TO_UINT(key
), decode_as
);
3902 printf("%s\t%s\t%s\n", table_name
, (char*)key
, decode_as
);
3906 printf("%s\t\t%s\n", table_name
, decode_as
);
3910 // We could output something here with the guid_key
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?
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
);
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
);
3946 ws_assert(sub_dissectors
);
3947 keys
= g_hash_table_get_keys(sub_dissectors
->hash_table
);
3949 switch (sub_dissectors
->type
) {
3954 keys
= g_list_sort(keys
, compare_ints
);
3959 case FT_UINT_STRING
:
3961 case FT_STRINGZTRUNC
:
3962 keys
= g_list_sort(keys
, (GCompareFunc
)strcmp
);
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.
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
);
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.
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
) {
4019 switch(table
->param
) {
4022 printf("\tBASE_NONE");
4026 printf("\tBASE_DEC");
4030 printf("\tBASE_HEX");
4034 printf("\tBASE_DEC_HEX");
4038 printf("\tBASE_HEX_DEC");
4042 printf("\t%d", table
->param
);
4050 if (table
->protocol
!= NULL
) {
4052 proto_get_protocol_short_name(table
->protocol
));
4054 printf("\t(no protocol)");
4055 printf("\tDecode As %ssupported",
4056 table
->supports_decode_as
? "" : "not ");
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.
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
) {
4078 proto_get_protocol_short_name(list
->protocol
));
4080 printf("\t(no protocol)");
4085 compare_dissector_key_name(const void *dissector_a
, const void *dissector_b
)
4087 return strcmp((const char*)dissector_a
, (const char*)dissector_b
);
4091 dissector_dump_dissector_tables(void)
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
);
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
);
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
{
4117 const char *description
;
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
);
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
);
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
;
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
);
4158 register_postdissector(dissector_handle_t handle
)
4162 if (!postdissectors
)
4163 postdissectors
= g_array_sized_new(false, false, (unsigned)sizeof(postdissector
), 1);
4166 p
.wanted_hfids
= NULL
;
4167 postdissectors
= g_array_append_val(postdissectors
, p
);
4171 set_postdissector_wanted_hfids(dissector_handle_t handle
, GArray
*wanted_hfids
)
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
;
4189 deregister_postdissector(dissector_handle_t handle
)
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
);
4207 have_postdissector(void)
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 */
4225 call_all_postdissectors(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
4229 for (i
= 0; i
< postdissectors
->len
; i
++) {
4230 call_dissector_only(POSTDISSECTORS(i
).handle
,
4231 tvb
, pinfo
, tree
, NULL
);
4236 postdissectors_want_hfids(void)
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
)))
4251 prime_epan_dissect_with_postdissector_wanted_hfids(epan_dissect_t
*edt
)
4255 if (postdissectors
== NULL
) {
4257 * No postdissector expressed an interest in any hfids.
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
);
4272 increment_dissection_depth(packet_info
*pinfo
) {
4273 pinfo
->dissection_depth
++;
4274 DISSECTOR_ASSERT(pinfo
->dissection_depth
< (int)prefs
.gui_max_tree_depth
);
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
4289 * indent-tabs-mode: t
4292 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
4293 * :indentSize=8:tabSize=8:noTabs=false: