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
, const uint8_t *data
, 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
, 1, &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" */
658 * XXX - currently, the length arguments in
659 * tvbuff structure are signed, but the captured
660 * and reported length values are unsigned; this means
661 * that length values > 2^31 - 1 will appear as
664 * Captured length values that large will already
665 * have been filtered out by the Wiretap modules
666 * (the file will be reported as corrupted), to
667 * avoid trying to allocate large chunks of data.
669 * Reported length values will not have been
670 * filtered out, and should not be filtered out,
671 * as those lengths are not necessarily invalid.
673 * For now, we clip the reported length at INT_MAX
675 * (XXX, is this still a problem?) There was an exception when we call
676 * tvb_new_real_data() now there's not.
678 edt
->tvb
= tvb_new_real_data(data
, fd
->cap_len
,
679 fd
->pkt_len
> INT_MAX
? INT_MAX
: fd
->pkt_len
);
680 /* Add this tvbuffer into the data_src list */
681 add_new_data_source(&edt
->pi
, edt
->tvb
, record_type
);
683 /* Even though dissect_frame() catches all the exceptions a
684 * sub-dissector can throw, dissect_frame() itself may throw
685 * a ReportedBoundsError in bizarre cases. Thus, we catch the exception
686 * in this function. */
687 call_dissector_with_data(frame_handle
, edt
->tvb
, &edt
->pi
, edt
->tree
, &frame_dissector_data
);
690 ws_assert_not_reached();
692 CATCH2(FragmentBoundsError
, ReportedBoundsError
) {
693 proto_tree_add_protocol_format(edt
->tree
, proto_malformed
, edt
->tvb
, 0, 0,
694 "[Malformed %s: Packet Length]",
698 wtap_block_unref(rec
->block
);
704 /* Creates the top-most tvbuff and calls dissect_file() */
706 dissect_file(epan_dissect_t
*edt
, wtap_rec
*rec
,
707 const uint8_t *data
, frame_data
*fd
, column_info
*cinfo
)
709 file_data_t file_dissector_data
;
712 col_init(cinfo
, edt
->session
);
713 edt
->pi
.epan
= edt
->session
;
714 /* edt->pi.pool created in epan_dissect_init() */
715 edt
->pi
.current_proto
= "<Missing Filetype Name>";
716 edt
->pi
.cinfo
= cinfo
;
719 edt
->pi
.pseudo_header
= NULL
;
720 clear_address(&edt
->pi
.dl_src
);
721 clear_address(&edt
->pi
.dl_dst
);
722 clear_address(&edt
->pi
.net_src
);
723 clear_address(&edt
->pi
.net_dst
);
724 clear_address(&edt
->pi
.src
);
725 clear_address(&edt
->pi
.dst
);
726 edt
->pi
.noreassembly_reason
= "";
727 edt
->pi
.ptype
= PT_NONE
;
728 edt
->pi
.use_conv_addr_port_endpoints
= false;
729 edt
->pi
.conv_addr_port_endpoints
= NULL
;
730 edt
->pi
.conv_elements
= NULL
;
731 edt
->pi
.p2p_dir
= P2P_DIR_UNKNOWN
;
732 edt
->pi
.link_dir
= LINK_DIR_UNKNOWN
;
733 edt
->pi
.layers
= wmem_list_new(edt
->pi
.pool
);
736 frame_delta_abs_time(edt
->session
, fd
, 1, &edt
->pi
.rel_ts
);
740 * If the block has been modified, use the modified block,
741 * otherwise use the block from the file.
743 if (fd
->has_modified_block
) {
744 file_dissector_data
.pkt_block
= epan_get_modified_block(edt
->session
, fd
);
747 file_dissector_data
.pkt_block
= rec
->block
;
749 file_dissector_data
.color_edt
= edt
; /* Used strictly for "coloring rules" */
751 edt
->tvb
= tvb_new_real_data(data
, fd
->cap_len
,
752 fd
->pkt_len
> INT_MAX
? INT_MAX
: fd
->pkt_len
);
753 /* Add this tvbuffer into the data_src list */
754 add_new_data_source(&edt
->pi
, edt
->tvb
, "File");
756 /* Even though dissect_file() catches all the exceptions a
757 * sub-dissector can throw, dissect_frame() itself may throw
758 * a ReportedBoundsError in bizarre cases. Thus, we catch the exception
759 * in this function. */
760 call_dissector_with_data(file_handle
, edt
->tvb
, &edt
->pi
, edt
->tree
, &file_dissector_data
);
764 ws_assert_not_reached();
766 CATCH3(FragmentBoundsError
, ContainedBoundsError
, ReportedBoundsError
) {
767 proto_tree_add_protocol_format(edt
->tree
, proto_malformed
, edt
->tvb
, 0, 0,
768 "[Malformed Record: Packet Length]");
771 wtap_block_unref(rec
->block
);
777 /*********************** code added for sub-dissector lookup *********************/
780 DISSECTOR_TYPE_SIMPLE
,
781 DISSECTOR_TYPE_CALLBACK
785 * A dissector handle.
787 struct dissector_handle
{
788 const char *name
; /* dissector name */
789 const char *description
; /* dissector description */
791 enum dissector_e dissector_type
;
793 dissector_t dissector_type_simple
;
794 dissector_cb_t dissector_type_callback
;
796 void *dissector_data
;
797 protocol_t
*protocol
;
801 add_layer(packet_info
*pinfo
, int proto_id
)
803 int *proto_layer_num_ptr
;
805 pinfo
->curr_layer_num
++;
806 wmem_list_append(pinfo
->layers
, GINT_TO_POINTER(proto_id
));
808 /* Increment layer number for this proto id. */
809 if (pinfo
->proto_layers
== NULL
) {
810 pinfo
->proto_layers
= wmem_map_new(pinfo
->pool
, g_direct_hash
, g_direct_equal
);
813 proto_layer_num_ptr
= wmem_map_lookup(pinfo
->proto_layers
, GINT_TO_POINTER(proto_id
));
814 if (proto_layer_num_ptr
== NULL
) {
815 /* Insert new layer */
816 proto_layer_num_ptr
= wmem_new(pinfo
->pool
, int);
817 *proto_layer_num_ptr
= 1;
818 wmem_map_insert(pinfo
->proto_layers
, GINT_TO_POINTER(proto_id
), proto_layer_num_ptr
);
821 /* Increment layer number */
822 (*proto_layer_num_ptr
)++;
824 pinfo
->curr_proto_layer_num
= *proto_layer_num_ptr
;
828 remove_last_layer(packet_info
*pinfo
, bool reduce_count
)
830 int *proto_layer_num_ptr
;
831 wmem_list_frame_t
*frame
;
835 pinfo
->curr_layer_num
--;
838 frame
= wmem_list_tail(pinfo
->layers
);
839 proto_id
= GPOINTER_TO_INT(wmem_list_frame_data(frame
));
840 wmem_list_remove_frame(pinfo
->layers
, frame
);
843 /* Reduce count for removed protocol layer. */
844 proto_layer_num_ptr
= wmem_map_lookup(pinfo
->proto_layers
, GINT_TO_POINTER(proto_id
));
845 if (proto_layer_num_ptr
&& *proto_layer_num_ptr
> 0) {
846 (*proto_layer_num_ptr
)--;
850 /* Restore count for new last (protocol) layer. */
851 frame
= wmem_list_tail(pinfo
->layers
);
853 proto_id
= GPOINTER_TO_INT(wmem_list_frame_data(frame
));
854 proto_layer_num_ptr
= wmem_map_lookup(pinfo
->proto_layers
, GINT_TO_POINTER(proto_id
));
855 ws_assert(proto_layer_num_ptr
);
856 pinfo
->curr_proto_layer_num
= *proto_layer_num_ptr
;
861 /* This function will return
862 * >0 this protocol was successfully dissected and this was this protocol.
863 * 0 this packet did not match this protocol.
865 * XXX - if the dissector only dissects metadata passed through the data
866 * pointer, and dissects none of the packet data, that's indistinguishable
867 * from "packet did not match this protocol". See issues #12366 and
871 call_dissector_through_handle(dissector_handle_t handle
, tvbuff_t
*tvb
,
872 packet_info
*pinfo
, proto_tree
*tree
, void *data
)
874 const char *saved_proto
;
877 saved_proto
= pinfo
->current_proto
;
879 if ((handle
->protocol
!= NULL
) && (!proto_is_pino(handle
->protocol
))) {
880 pinfo
->current_proto
=
881 proto_get_protocol_short_name(handle
->protocol
);
884 switch (handle
->dissector_type
) {
886 case DISSECTOR_TYPE_SIMPLE
:
887 len
= (handle
->dissector_func
.dissector_type_simple
)(tvb
, pinfo
, tree
, data
);
890 case DISSECTOR_TYPE_CALLBACK
:
891 len
= (handle
->dissector_func
.dissector_type_callback
)(tvb
, pinfo
, tree
, data
, handle
->dissector_data
);
895 ws_assert_not_reached();
897 pinfo
->current_proto
= saved_proto
;
903 * Call a dissector through a handle.
904 * If the protocol for that handle isn't enabled, return 0 without
905 * calling the dissector.
906 * Otherwise, if the handle refers to a new-style dissector, call the
907 * dissector and return its return value, otherwise call it and return
908 * the length of the tvbuff pointed to by the argument.
912 call_dissector_work_error(dissector_handle_t handle
, tvbuff_t
*tvb
,
913 packet_info
*pinfo_arg
, proto_tree
*tree
, void *);
916 call_dissector_work(dissector_handle_t handle
, tvbuff_t
*tvb
, packet_info
*pinfo
,
917 proto_tree
*tree
, bool add_proto_name
, void *data
)
919 const char *saved_proto
;
920 uint16_t saved_can_desegment
;
922 unsigned saved_layers_len
= 0;
923 unsigned saved_tree_count
= tree
? tree
->tree_data
->count
: 0;
924 unsigned saved_desegment_len
= pinfo
->desegment_len
;
927 if (handle
->protocol
!= NULL
&&
928 !proto_is_protocol_enabled(handle
->protocol
)) {
930 * The protocol isn't enabled.
935 saved_proto
= pinfo
->current_proto
;
936 saved_can_desegment
= pinfo
->can_desegment
;
937 saved_layers_len
= wmem_list_count(pinfo
->layers
);
938 DISSECTOR_ASSERT(saved_layers_len
< prefs
.gui_max_tree_depth
);
941 * can_desegment is set to 2 by anyone which offers the
942 * desegmentation api/service.
943 * Then every time a subdissector is called it is decremented
945 * Thus only the subdissector immediately on top of whoever
946 * offers this service can use it.
947 * We save the current value of "can_desegment" for the
948 * benefit of TCP proxying dissectors such as SOCKS, so they
949 * can restore it and allow the dissectors they call to use
950 * the desegmentation service.
952 pinfo
->saved_can_desegment
= saved_can_desegment
;
953 pinfo
->can_desegment
= saved_can_desegment
-(saved_can_desegment
>0);
954 if ((handle
->protocol
!= NULL
) && (!proto_is_pino(handle
->protocol
))) {
955 pinfo
->current_proto
=
956 proto_get_protocol_short_name(handle
->protocol
);
959 * Add the protocol name to the layers only if told to
960 * do so. Asn2wrs generated dissectors may be added
961 * multiple times otherwise.
963 /* XXX Should we check for a duplicate layer here? */
964 if (add_proto_name
) {
965 add_layer(pinfo
, proto_get_id(handle
->protocol
));
969 if (pinfo
->flags
.in_error_pkt
) {
970 len
= call_dissector_work_error(handle
, tvb
, pinfo
, tree
, data
);
973 * Just call the subdissector.
975 len
= call_dissector_through_handle(handle
, tvb
, pinfo
, tree
, data
);
977 consumed_none
= len
== 0 || (pinfo
->desegment_len
!= saved_desegment_len
&& pinfo
->desegment_offset
== 0);
978 /* If len == 0, then the dissector didn't accept the packet.
979 * In the latter case, the dissector accepted the packet, but didn't
980 * consume any bytes because they all belong in a later segment.
981 * In the latter case, we probably won't call a dissector here again
982 * on the next pass, so removing the layer keeps any *further* layers
983 * past this one the same on subsequent passes.
985 * XXX: DISSECTOR_ASSERT that the tree count didn't change? If the
986 * dissector didn't consume any bytes but added items to the tree,
987 * that's improper behavior and needs a rethink. We could also move the
988 * test that the packet didn't change desegment_offset and desegment_len
989 * while rejecting the packet from packet-tcp.c decode_tcp_ports to here.
991 if (handle
->protocol
!= NULL
&& !proto_is_pino(handle
->protocol
) && add_proto_name
&&
992 (consumed_none
|| (tree
&& saved_tree_count
== tree
->tree_data
->count
))) {
994 * We've added a layer and either the dissector didn't
995 * consume any data or we didn't add any items to the
998 while (wmem_list_count(pinfo
->layers
) > saved_layers_len
) {
1000 * Only reduce the layer number if the dissector didn't
1001 * consume any data. Since tree can be NULL on
1002 * the first pass, we cannot check it or it will
1003 * break dissectors that rely on a stable value.
1005 remove_last_layer(pinfo
, consumed_none
);
1008 pinfo
->current_proto
= saved_proto
;
1009 pinfo
->can_desegment
= saved_can_desegment
;
1015 call_dissector_work_error(dissector_handle_t handle
, tvbuff_t
*tvb
,
1016 packet_info
*pinfo_arg
, proto_tree
*tree
, void *data
)
1018 packet_info
*pinfo
= pinfo_arg
;
1019 const char *saved_proto
;
1020 uint16_t saved_can_desegment
;
1021 volatile int len
= 0;
1023 address save_dl_src
;
1024 address save_dl_dst
;
1025 address save_net_src
;
1026 address save_net_dst
;
1029 uint32_t save_ptype
;
1030 uint32_t save_srcport
;
1031 uint32_t save_destport
;
1034 * This isn't a packet being transported inside
1035 * the protocol whose dissector is calling us,
1036 * it's a copy of a packet that caused an error
1037 * in some protocol included in a packet that
1038 * reports the error (e.g., an ICMP Unreachable
1043 * Save the current state of the writability of
1044 * the columns, and restore them after the
1045 * dissector returns, so that the columns
1046 * don't reflect the packet that got the error,
1047 * they reflect the packet that reported the
1050 saved_proto
= pinfo
->current_proto
;
1051 saved_can_desegment
= pinfo
->can_desegment
;
1053 save_writable
= col_get_writable(pinfo
->cinfo
, -1);
1054 col_set_writable(pinfo
->cinfo
, -1, false);
1055 copy_address_shallow(&save_dl_src
, &pinfo
->dl_src
);
1056 copy_address_shallow(&save_dl_dst
, &pinfo
->dl_dst
);
1057 copy_address_shallow(&save_net_src
, &pinfo
->net_src
);
1058 copy_address_shallow(&save_net_dst
, &pinfo
->net_dst
);
1059 copy_address_shallow(&save_src
, &pinfo
->src
);
1060 copy_address_shallow(&save_dst
, &pinfo
->dst
);
1061 save_ptype
= pinfo
->ptype
;
1062 save_srcport
= pinfo
->srcport
;
1063 save_destport
= pinfo
->destport
;
1065 /* Dissect the contained packet. */
1067 len
= call_dissector_through_handle(handle
, tvb
,pinfo
, tree
, data
);
1069 CATCH(BoundsError
) {
1071 * Restore the column writability and addresses and ports.
1073 col_set_writable(pinfo
->cinfo
, -1, save_writable
);
1074 copy_address_shallow(&pinfo
->dl_src
, &save_dl_src
);
1075 copy_address_shallow(&pinfo
->dl_dst
, &save_dl_dst
);
1076 copy_address_shallow(&pinfo
->net_src
, &save_net_src
);
1077 copy_address_shallow(&pinfo
->net_dst
, &save_net_dst
);
1078 copy_address_shallow(&pinfo
->src
, &save_src
);
1079 copy_address_shallow(&pinfo
->dst
, &save_dst
);
1080 pinfo
->ptype
= save_ptype
;
1081 pinfo
->srcport
= save_srcport
;
1082 pinfo
->destport
= save_destport
;
1085 * Restore the current protocol, so any
1086 * "Short Frame" indication reflects that
1087 * protocol, not the protocol for the
1088 * packet that got the error.
1090 pinfo
->current_proto
= saved_proto
;
1093 * Restore the desegmentability state.
1095 pinfo
->can_desegment
= saved_can_desegment
;
1098 * Rethrow the exception, so this will be
1099 * reported as a short frame.
1103 CATCH3(FragmentBoundsError
, ContainedBoundsError
, ReportedBoundsError
) {
1105 * "ret" wasn't set because an exception was thrown
1106 * before "call_dissector_through_handle()" returned.
1107 * As it called something, at least one dissector
1108 * accepted the packet, and, as an exception was
1109 * thrown, not only was all the tvbuff dissected,
1110 * a dissector tried dissecting past the end of
1111 * the data in some tvbuff, so we'll assume that
1112 * the entire tvbuff was dissected.
1114 len
= tvb_captured_length(tvb
);
1118 col_set_writable(pinfo
->cinfo
, -1, save_writable
);
1119 copy_address_shallow(&pinfo
->dl_src
, &save_dl_src
);
1120 copy_address_shallow(&pinfo
->dl_dst
, &save_dl_dst
);
1121 copy_address_shallow(&pinfo
->net_src
, &save_net_src
);
1122 copy_address_shallow(&pinfo
->net_dst
, &save_net_dst
);
1123 copy_address_shallow(&pinfo
->src
, &save_src
);
1124 copy_address_shallow(&pinfo
->dst
, &save_dst
);
1125 pinfo
->ptype
= save_ptype
;
1126 pinfo
->srcport
= save_srcport
;
1127 pinfo
->destport
= save_destport
;
1128 pinfo
->want_pdu_tracking
= 0;
1133 * An entry in the hash table portion of a dissector table.
1136 dissector_handle_t initial
;
1137 dissector_handle_t current
;
1140 /* Finds a dissector table by table name. */
1142 find_dissector_table(const char *name
)
1144 dissector_table_t dissector_table
= (dissector_table_t
) g_hash_table_lookup(dissector_tables
, name
);
1145 if (! dissector_table
) {
1146 const char *new_name
= (const char *) g_hash_table_lookup(dissector_table_aliases
, name
);
1148 dissector_table
= (dissector_table_t
) g_hash_table_lookup(dissector_tables
, new_name
);
1150 if (dissector_table
) {
1151 ws_warning("%s is now %s", name
, new_name
);
1154 return dissector_table
;
1157 /* Find an entry in a uint dissector table. */
1158 static dtbl_entry_t
*
1159 find_uint_dtbl_entry(dissector_table_t sub_dissectors
, const uint32_t pattern
)
1161 switch (sub_dissectors
->type
) {
1168 * You can do a uint lookup in these tables.
1172 /* For now treat as uint */
1177 * But you can't do a uint lookup in any other types
1180 ws_assert_not_reached();
1186 return (dtbl_entry_t
*)g_hash_table_lookup(sub_dissectors
->hash_table
,
1187 GUINT_TO_POINTER(pattern
));
1192 dissector_add_uint_sanity_check(const char *name
, uint32_t pattern
, dissector_handle_t handle
, dissector_table_t sub_dissectors
)
1194 dtbl_entry_t
*dtbl_entry
;
1197 ws_warning("%s: %s registering using a pattern of 0",
1198 name
, proto_get_protocol_filter_name(proto_get_id(handle
->protocol
)));
1201 dtbl_entry
= g_hash_table_lookup(sub_dissectors
->hash_table
, GUINT_TO_POINTER(pattern
));
1202 if (dtbl_entry
!= NULL
) {
1203 ws_warning("%s: %s registering using pattern %d already registered by %s",
1204 name
, proto_get_protocol_filter_name(proto_get_id(handle
->protocol
)),
1205 pattern
, proto_get_protocol_filter_name(proto_get_id(dtbl_entry
->initial
->protocol
)));
1210 /* Add an entry to a uint dissector table. */
1212 dissector_add_uint(const char *name
, const uint32_t pattern
, dissector_handle_t handle
)
1214 dissector_table_t sub_dissectors
;
1215 dtbl_entry_t
*dtbl_entry
;
1217 sub_dissectors
= find_dissector_table(name
);
1220 * Make sure the handle and the dissector table exist.
1222 if (handle
== NULL
) {
1223 fprintf(stderr
, "OOPS: handle to register \"%s\" to doesn't exist\n",
1225 if (wireshark_abort_on_dissector_bug
)
1229 if (sub_dissectors
== NULL
) {
1230 fprintf(stderr
, "OOPS: dissector table \"%s\" doesn't exist\n",
1232 fprintf(stderr
, "Protocol being registered is \"%s\"\n",
1233 proto_get_protocol_long_name(handle
->protocol
));
1234 if (wireshark_abort_on_dissector_bug
)
1239 switch (sub_dissectors
->type
) {
1246 * You can do a uint lookup in these tables.
1252 * But you can't do a uint lookup in any other types
1255 ws_assert_not_reached();
1259 dissector_add_uint_sanity_check(name
, pattern
, handle
, sub_dissectors
);
1262 dtbl_entry
= g_new(dtbl_entry_t
, 1);
1263 dtbl_entry
->current
= handle
;
1264 dtbl_entry
->initial
= dtbl_entry
->current
;
1266 /* do the table insertion */
1267 g_hash_table_insert(sub_dissectors
->hash_table
,
1268 GUINT_TO_POINTER(pattern
), (void *)dtbl_entry
);
1271 * Now, if this table supports "Decode As", add this handle
1272 * to the list of handles that could be used for "Decode As"
1273 * with this table, because it *is* being used with this table.
1275 if (sub_dissectors
->supports_decode_as
)
1276 dissector_add_for_decode_as(name
, handle
);
1281 void dissector_add_uint_range(const char *name
, range_t
*range
,
1282 dissector_handle_t handle
)
1284 dissector_table_t sub_dissectors
;
1288 if (range
->nranges
== 0) {
1290 * Even an empty range would want a chance for
1291 * Decode As, if the dissector table supports
1294 sub_dissectors
= find_dissector_table(name
);
1295 if (sub_dissectors
->supports_decode_as
)
1296 dissector_add_for_decode_as(name
, handle
);
1299 for (i
= 0; i
< range
->nranges
; i
++) {
1300 for (j
= range
->ranges
[i
].low
; j
< range
->ranges
[i
].high
; j
++)
1301 dissector_add_uint(name
, j
, handle
);
1302 dissector_add_uint(name
, range
->ranges
[i
].high
, handle
);
1309 dissector_add_range_preference(const char *name
, dissector_handle_t handle
, const char* range_str
)
1313 char *description
, *title
;
1314 dissector_table_t pref_dissector_table
= find_dissector_table(name
);
1315 int proto_id
= proto_get_id(handle
->protocol
);
1316 uint32_t max_value
= 0;
1318 /* If a dissector is added for Decode As only, it's dissector
1319 table value would default to 0.
1320 Set up a preference value with that information
1322 range
= wmem_new0(wmem_epan_scope(), range_t
*);
1324 /* If the dissector's protocol already has a preference module, use it */
1325 const char* module_name
= proto_get_protocol_filter_name(proto_id
);
1326 module
= prefs_find_module(module_name
);
1327 if (module
== NULL
) {
1328 /* Otherwise create a new one */
1329 module
= prefs_register_protocol(proto_id
, NULL
);
1332 const char *fullname
= wmem_strdup_printf(wmem_epan_scope(), "%s%s", name
, dissector_handle_get_pref_suffix(handle
));
1334 /* Some preference callback functions use the proto_reg_handoff_
1335 routine to apply preferences, which could duplicate the
1336 registration of a preference. Check for that here */
1337 if (prefs_find_preference(module
, fullname
) == NULL
) {
1338 const char *handle_desc
= dissector_handle_get_description(handle
);
1339 if (g_strcmp0(range_str
, "") > 0) {
1340 description
= wmem_strdup_printf(wmem_epan_scope(), "%s %s(s) (default: %s)",
1341 handle_desc
, pref_dissector_table
->ui_name
, range_str
);
1343 description
= wmem_strdup_printf(wmem_epan_scope(), "%s %s(s)",
1344 handle_desc
, pref_dissector_table
->ui_name
);
1346 title
= wmem_strdup_printf(wmem_epan_scope(), "%s %s(s)", handle_desc
, pref_dissector_table
->ui_name
);
1348 /* Max value is based on datatype of dissector table */
1349 switch (pref_dissector_table
->type
) {
1358 max_value
= 0xFFFFFF;
1361 max_value
= 0xFFFFFFFF;
1365 ws_error("The dissector table %s (%s) is not an integer type - are you using a buggy plugin?", name
, pref_dissector_table
->ui_name
);
1366 ws_assert_not_reached();
1369 range_convert_str(wmem_epan_scope(), range
, range_str
, max_value
);
1370 prefs_register_decode_as_range_preference(module
, fullname
, title
, description
, range
, max_value
, name
, handle_desc
);
1376 void dissector_add_uint_with_preference(const char *name
, const uint32_t pattern
,
1377 dissector_handle_t handle
)
1381 range_str
= wmem_strdup_printf(NULL
, "%d", pattern
);
1382 dissector_add_range_preference(name
, handle
, range_str
);
1383 wmem_free(NULL
, range_str
);
1384 dissector_add_uint(name
, pattern
, handle
);
1387 void dissector_add_uint_range_with_preference(const char *name
, const char* range_str
,
1388 dissector_handle_t handle
)
1392 range
= dissector_add_range_preference(name
, handle
, range_str
);
1393 dissector_add_uint_range(name
, range
, handle
);
1396 /* Delete the entry for a dissector in a uint dissector table
1397 with a particular pattern. */
1399 /* NOTE: this doesn't use the dissector call variable. It is included to */
1400 /* be consistent with the dissector_add_uint and more importantly to be used */
1401 /* if the technique of adding a temporary dissector is implemented. */
1402 /* If temporary dissectors are deleted, then the original dissector must */
1405 dissector_delete_uint(const char *name
, const uint32_t pattern
,
1406 dissector_handle_t handle _U_
)
1408 dissector_table_t sub_dissectors
= find_dissector_table(name
);
1409 dtbl_entry_t
*dtbl_entry
;
1412 ws_assert(sub_dissectors
);
1417 dtbl_entry
= find_uint_dtbl_entry(sub_dissectors
, pattern
);
1419 if (dtbl_entry
!= NULL
) {
1421 * Found - remove it.
1423 g_hash_table_remove(sub_dissectors
->hash_table
,
1424 GUINT_TO_POINTER(pattern
));
1428 void dissector_delete_uint_range(const char *name
, range_t
*range
,
1429 dissector_handle_t handle
)
1434 for (i
= 0; i
< range
->nranges
; i
++) {
1435 for (j
= range
->ranges
[i
].low
; j
< range
->ranges
[i
].high
; j
++)
1436 dissector_delete_uint(name
, j
, handle
);
1437 dissector_delete_uint(name
, range
->ranges
[i
].high
, handle
);
1442 /* Remove an entry from a guid dissector table. */
1443 void dissector_delete_guid(const char *name
, guid_key
* guid_val
, dissector_handle_t handle
)
1445 dissector_table_t sub_dissectors
;
1446 dtbl_entry_t
*dtbl_entry
;
1448 sub_dissectors
= find_dissector_table(name
);
1451 ws_assert(sub_dissectors
);
1453 /* Find the table entry */
1454 dtbl_entry
= (dtbl_entry_t
*)g_hash_table_lookup(sub_dissectors
->hash_table
, guid_val
);
1456 if (dtbl_entry
== NULL
) {
1457 fprintf(stderr
, "OOPS: guid not found in dissector table \"%s\"\n", name
);
1461 /* Make sure the handles match */
1462 if (dtbl_entry
->current
!= handle
) {
1463 fprintf(stderr
, "OOPS: handle does not match for guid in dissector table \"%s\"\n", name
);
1467 /* Remove the table entry */
1468 g_hash_table_remove(sub_dissectors
->hash_table
, guid_val
);
1473 dissector_delete_all_check (void *key _U_
, void *value
, void *user_data
)
1475 dtbl_entry_t
*dtbl_entry
= (dtbl_entry_t
*) value
;
1476 dissector_handle_t handle
= (dissector_handle_t
) user_data
;
1478 if (!dtbl_entry
->current
->protocol
) {
1480 * Not all dissectors are registered with a protocol, so we need this
1481 * check when running from dissector_delete_from_all_tables.
1486 return (proto_get_id (dtbl_entry
->current
->protocol
) == proto_get_id (handle
->protocol
));
1489 /* Delete all entries from a dissector table. */
1490 void dissector_delete_all(const char *name
, dissector_handle_t handle
)
1492 dissector_table_t sub_dissectors
= find_dissector_table(name
);
1493 ws_assert (sub_dissectors
);
1495 g_hash_table_foreach_remove (sub_dissectors
->hash_table
, dissector_delete_all_check
, handle
);
1499 dissector_delete_from_table(gpointer key _U_
, gpointer value
, gpointer user_data
)
1501 dissector_table_t sub_dissectors
= (dissector_table_t
) value
;
1502 ws_assert (sub_dissectors
);
1504 g_hash_table_foreach_remove(sub_dissectors
->hash_table
, dissector_delete_all_check
, user_data
);
1505 sub_dissectors
->dissector_handles
= g_slist_remove(sub_dissectors
->dissector_handles
, user_data
);
1508 /* Delete handle from all tables and dissector_handles lists */
1510 dissector_delete_from_all_tables(dissector_handle_t handle
)
1512 g_hash_table_foreach(dissector_tables
, dissector_delete_from_table
, handle
);
1515 /* Change the entry for a dissector in a uint dissector table
1516 with a particular pattern to use a new dissector handle. */
1518 dissector_change_uint(const char *name
, const uint32_t pattern
, dissector_handle_t handle
)
1520 dissector_table_t sub_dissectors
= find_dissector_table(name
);
1521 dtbl_entry_t
*dtbl_entry
;
1524 ws_assert(sub_dissectors
);
1527 * See if the entry already exists. If so, reuse it.
1529 dtbl_entry
= find_uint_dtbl_entry(sub_dissectors
, pattern
);
1530 if (dtbl_entry
!= NULL
) {
1532 * If there's no initial value, and the user said not
1533 * to decode it, just remove the entry to save memory.
1535 if (handle
== NULL
&& dtbl_entry
->initial
== NULL
) {
1536 g_hash_table_remove(sub_dissectors
->hash_table
,
1537 GUINT_TO_POINTER(pattern
));
1540 dtbl_entry
->current
= handle
;
1545 * Don't create an entry if there is no dissector handle - I.E. the
1546 * user said not to decode something that wasn't being decoded
1547 * in the first place.
1552 dtbl_entry
= g_new(dtbl_entry_t
, 1);
1553 dtbl_entry
->initial
= NULL
;
1554 dtbl_entry
->current
= handle
;
1556 /* do the table insertion */
1557 g_hash_table_insert(sub_dissectors
->hash_table
,
1558 GUINT_TO_POINTER(pattern
), (void *)dtbl_entry
);
1561 /* Reset an entry in a uint dissector table to its initial value. */
1563 dissector_reset_uint(const char *name
, const uint32_t pattern
)
1565 dissector_table_t sub_dissectors
= find_dissector_table(name
);
1566 dtbl_entry_t
*dtbl_entry
;
1569 ws_assert(sub_dissectors
);
1574 dtbl_entry
= find_uint_dtbl_entry(sub_dissectors
, pattern
);
1576 if (dtbl_entry
== NULL
)
1580 * Found - is there an initial value?
1582 if (dtbl_entry
->initial
!= NULL
) {
1583 dtbl_entry
->current
= dtbl_entry
->initial
;
1585 g_hash_table_remove(sub_dissectors
->hash_table
,
1586 GUINT_TO_POINTER(pattern
));
1590 /* Return true if an entry in a uint dissector table is found and has been
1591 * changed (i.e. dissector_change_uint() has been called, such as from
1592 * Decode As, prefs registered via dissector_add_uint_[range_]with_preference),
1593 * etc.), otherwise return false.
1596 dissector_is_uint_changed(dissector_table_t
const sub_dissectors
, const uint32_t uint_val
)
1598 if (sub_dissectors
!= NULL
) {
1599 dtbl_entry_t
*dtbl_entry
= find_uint_dtbl_entry(sub_dissectors
, uint_val
);
1600 if (dtbl_entry
!= NULL
)
1601 return (dtbl_entry
->current
!= dtbl_entry
->initial
);
1606 /* Look for a given value in a given uint dissector table and, if found,
1607 call the dissector with the arguments supplied, and return the number
1608 of bytes consumed by the dissector, otherwise return 0. */
1611 dissector_try_uint_with_data(dissector_table_t sub_dissectors
, const uint32_t uint_val
,
1612 tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1613 const bool add_proto_name
, void *data
)
1615 dtbl_entry_t
*dtbl_entry
;
1616 struct dissector_handle
*handle
;
1617 uint32_t saved_match_uint
;
1620 dtbl_entry
= find_uint_dtbl_entry(sub_dissectors
, uint_val
);
1621 if (dtbl_entry
== NULL
) {
1623 * There's no entry in the table for our value.
1629 * Is there currently a dissector handle for this entry?
1631 handle
= dtbl_entry
->current
;
1632 if (handle
== NULL
) {
1634 * No - pretend this dissector didn't exist,
1635 * so that other dissectors might have a chance
1636 * to dissect this packet.
1642 * Save the current value of "pinfo->match_uint",
1643 * set it to the uint_val that matched, call the
1644 * dissector, and restore "pinfo->match_uint".
1646 saved_match_uint
= pinfo
->match_uint
;
1647 pinfo
->match_uint
= uint_val
;
1648 len
= call_dissector_work(handle
, tvb
, pinfo
, tree
, add_proto_name
, data
);
1649 pinfo
->match_uint
= saved_match_uint
;
1652 * If a new-style dissector returned 0, it means that
1653 * it didn't think this tvbuff represented a packet for
1654 * its protocol, and didn't dissect anything.
1656 * Old-style dissectors can't reject the packet.
1658 * 0 is also returned if the protocol wasn't enabled.
1660 * If the packet was rejected, we return 0, so that
1661 * other dissectors might have a chance to dissect this
1662 * packet, otherwise we return the dissected length.
1668 dissector_try_uint(dissector_table_t sub_dissectors
, const uint32_t uint_val
,
1669 tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
1672 return dissector_try_uint_with_data(sub_dissectors
, uint_val
, tvb
, pinfo
, tree
, true, NULL
);
1675 /* Look for a given value in a given uint dissector table and, if found,
1676 return the dissector handle for that value. */
1678 dissector_get_uint_handle(dissector_table_t
const sub_dissectors
, const uint32_t uint_val
)
1680 dtbl_entry_t
*dtbl_entry
;
1682 dtbl_entry
= find_uint_dtbl_entry(sub_dissectors
, uint_val
);
1683 if (dtbl_entry
!= NULL
)
1684 return dtbl_entry
->current
;
1690 dissector_get_default_uint_handle(const char *name
, const uint32_t uint_val
)
1692 dissector_table_t sub_dissectors
= find_dissector_table(name
);
1694 if (sub_dissectors
!= NULL
) {
1695 dtbl_entry_t
*dtbl_entry
= find_uint_dtbl_entry(sub_dissectors
, uint_val
);
1696 if (dtbl_entry
!= NULL
)
1697 return dtbl_entry
->initial
;
1702 /* Find an entry in a string dissector table. */
1703 static dtbl_entry_t
*
1704 find_string_dtbl_entry(dissector_table_t
const sub_dissectors
, const char *pattern
)
1709 switch (sub_dissectors
->type
) {
1714 case FT_STRINGZTRUNC
:
1716 * You can do a string lookup in these tables.
1722 * But you can't do a string lookup in any other types
1725 ws_assert_not_reached();
1728 if (sub_dissectors
->param
== STRING_CASE_INSENSITIVE
) {
1729 key
= g_ascii_strdown(pattern
, -1);
1731 key
= g_strdup(pattern
);
1737 ret
= (dtbl_entry_t
*)g_hash_table_lookup(sub_dissectors
->hash_table
, key
);
1744 /* Add an entry to a string dissector table. */
1746 dissector_add_string(const char *name
, const char *pattern
,
1747 dissector_handle_t handle
)
1749 dissector_table_t sub_dissectors
= find_dissector_table(name
);
1750 dtbl_entry_t
*dtbl_entry
;
1754 * Make sure the handle and the dissector table exist.
1756 if (handle
== NULL
) {
1757 fprintf(stderr
, "OOPS: handle to register \"%s\" to doesn't exist\n",
1759 if (wireshark_abort_on_dissector_bug
)
1763 if (sub_dissectors
== NULL
) {
1764 fprintf(stderr
, "OOPS: dissector table \"%s\" doesn't exist\n",
1766 fprintf(stderr
, "Protocol being registered is \"%s\"\n",
1767 proto_get_protocol_long_name(handle
->protocol
));
1768 if (wireshark_abort_on_dissector_bug
)
1773 switch (sub_dissectors
->type
) {
1778 case FT_STRINGZTRUNC
:
1780 * You can do a string lookup in these tables.
1786 * But you can't do a string lookup in any other types
1789 ws_assert_not_reached();
1792 dtbl_entry
= g_new(dtbl_entry_t
, 1);
1793 dtbl_entry
->current
= handle
;
1794 dtbl_entry
->initial
= dtbl_entry
->current
;
1796 if (sub_dissectors
->param
== STRING_CASE_INSENSITIVE
) {
1797 key
= g_ascii_strdown(pattern
, -1);
1799 key
= g_strdup(pattern
);
1802 /* do the table insertion */
1803 g_hash_table_insert(sub_dissectors
->hash_table
, (void *)key
,
1804 (void *)dtbl_entry
);
1807 * Now, if this table supports "Decode As", add this handle
1808 * to the list of handles that could be used for "Decode As"
1809 * with this table, because it *is* being used with this table.
1811 if (sub_dissectors
->supports_decode_as
)
1812 dissector_add_for_decode_as(name
, handle
);
1815 /* Delete the entry for a dissector in a string dissector table
1816 with a particular pattern. */
1818 /* NOTE: this doesn't use the dissector call variable. It is included to */
1819 /* be consistent with the dissector_add_string and more importantly to */
1820 /* be used if the technique of adding a temporary dissector is */
1822 /* If temporary dissectors are deleted, then the original dissector must */
1825 dissector_delete_string(const char *name
, const char *pattern
,
1826 dissector_handle_t handle _U_
)
1828 dissector_table_t sub_dissectors
= find_dissector_table(name
);
1829 dtbl_entry_t
*dtbl_entry
;
1832 ws_assert(sub_dissectors
);
1837 dtbl_entry
= find_string_dtbl_entry(sub_dissectors
, pattern
);
1839 if (dtbl_entry
!= NULL
) {
1841 * Found - remove it.
1843 g_hash_table_remove(sub_dissectors
->hash_table
, pattern
);
1847 /* Change the entry for a dissector in a string dissector table
1848 with a particular pattern to use a new dissector handle. */
1850 dissector_change_string(const char *name
, const char *pattern
,
1851 dissector_handle_t handle
)
1853 dissector_table_t sub_dissectors
= find_dissector_table(name
);
1854 dtbl_entry_t
*dtbl_entry
;
1857 ws_assert(sub_dissectors
);
1860 * See if the entry already exists. If so, reuse it.
1862 dtbl_entry
= find_string_dtbl_entry(sub_dissectors
, pattern
);
1863 if (dtbl_entry
!= NULL
) {
1865 * If there's no initial value, and the user said not
1866 * to decode it, just remove the entry to save memory.
1868 if (handle
== NULL
&& dtbl_entry
->initial
== NULL
) {
1869 g_hash_table_remove(sub_dissectors
->hash_table
,
1873 dtbl_entry
->current
= handle
;
1878 * Don't create an entry if there is no dissector handle - I.E. the
1879 * user said not to decode something that wasn't being decoded
1880 * in the first place.
1885 dtbl_entry
= g_new(dtbl_entry_t
, 1);
1886 dtbl_entry
->initial
= NULL
;
1887 dtbl_entry
->current
= handle
;
1889 /* do the table insertion */
1890 g_hash_table_insert(sub_dissectors
->hash_table
, (void *)g_strdup(pattern
),
1891 (void *)dtbl_entry
);
1894 /* Reset an entry in a string sub-dissector table to its initial value. */
1896 dissector_reset_string(const char *name
, const char *pattern
)
1898 dissector_table_t sub_dissectors
= find_dissector_table(name
);
1899 dtbl_entry_t
*dtbl_entry
;
1902 ws_assert(sub_dissectors
);
1907 dtbl_entry
= find_string_dtbl_entry(sub_dissectors
, pattern
);
1909 if (dtbl_entry
== NULL
)
1913 * Found - is there an initial value?
1915 if (dtbl_entry
->initial
!= NULL
) {
1916 dtbl_entry
->current
= dtbl_entry
->initial
;
1918 g_hash_table_remove(sub_dissectors
->hash_table
, pattern
);
1922 /* Return true if an entry in a uint dissector table is found and has been
1923 * changed (i.e. dissector_change_uint() has been called, such as from
1924 * Decode As, prefs registered via dissector_add_uint_[range_]with_preference),
1925 * etc.), otherwise return false.
1928 dissector_is_string_changed(dissector_table_t
const sub_dissectors
, const char *string
)
1930 if (sub_dissectors
!= NULL
) {
1931 dtbl_entry_t
*dtbl_entry
= find_string_dtbl_entry(sub_dissectors
, string
);
1932 if (dtbl_entry
!= NULL
)
1933 return (dtbl_entry
->current
!= dtbl_entry
->initial
);
1938 /* Look for a given string in a given dissector table and, if found, call
1939 the dissector with the arguments supplied, and return length of dissected data,
1940 otherwise return 0. */
1942 dissector_try_string_with_data(dissector_table_t sub_dissectors
, const char *string
,
1943 tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, const bool add_proto_name
, void *data
)
1945 dtbl_entry_t
*dtbl_entry
;
1946 struct dissector_handle
*handle
;
1948 const char *saved_match_string
;
1950 /* XXX ASSERT instead ? */
1951 if (!string
) return 0;
1952 dtbl_entry
= find_string_dtbl_entry(sub_dissectors
, string
);
1953 if (dtbl_entry
!= NULL
) {
1955 * Is there currently a dissector handle for this entry?
1957 handle
= dtbl_entry
->current
;
1958 if (handle
== NULL
) {
1960 * No - pretend this dissector didn't exist,
1961 * so that other dissectors might have a chance
1962 * to dissect this packet.
1968 * Save the current value of "pinfo->match_string",
1969 * set it to the string that matched, call the
1970 * dissector, and restore "pinfo->match_string".
1972 saved_match_string
= pinfo
->match_string
;
1973 pinfo
->match_string
= string
;
1974 len
= call_dissector_work(handle
, tvb
, pinfo
, tree
, add_proto_name
, data
);
1975 pinfo
->match_string
= saved_match_string
;
1978 * If a new-style dissector returned 0, it means that
1979 * it didn't think this tvbuff represented a packet for
1980 * its protocol, and didn't dissect anything.
1982 * Old-style dissectors can't reject the packet.
1984 * 0 is also returned if the protocol wasn't enabled.
1986 * If the packet was rejected, we return 0, so that
1987 * other dissectors might have a chance to dissect this
1988 * packet, otherwise we return the dissected length.
1995 /* Look for a given value in a given string dissector table and, if found,
1996 return the dissector handle for that value. */
1998 dissector_get_string_handle(dissector_table_t sub_dissectors
,
2001 dtbl_entry_t
*dtbl_entry
;
2003 /* XXX ASSERT instead ? */
2004 if (!string
) return NULL
;
2005 dtbl_entry
= find_string_dtbl_entry(sub_dissectors
, string
);
2006 if (dtbl_entry
!= NULL
)
2007 return dtbl_entry
->current
;
2013 dissector_get_default_string_handle(const char *name
, const char *string
)
2015 dissector_table_t sub_dissectors
;
2017 /* XXX ASSERT instead ? */
2018 if (!string
) return NULL
;
2019 sub_dissectors
= find_dissector_table(name
);
2020 if (sub_dissectors
!= NULL
) {
2021 dtbl_entry_t
*dtbl_entry
= find_string_dtbl_entry(sub_dissectors
, string
);
2022 if (dtbl_entry
!= NULL
)
2023 return dtbl_entry
->initial
;
2028 /* Add an entry to a "custom" dissector table. */
2029 void dissector_add_custom_table_handle(const char *name
, void *pattern
, dissector_handle_t handle
)
2031 dissector_table_t sub_dissectors
= find_dissector_table(name
);
2032 dtbl_entry_t
*dtbl_entry
;
2035 * Make sure the handle and the dissector table exist.
2037 if (handle
== NULL
) {
2038 fprintf(stderr
, "OOPS: handle to register \"%s\" to doesn't exist\n",
2040 if (wireshark_abort_on_dissector_bug
)
2044 if (sub_dissectors
== NULL
) {
2045 fprintf(stderr
, "OOPS: dissector table \"%s\" doesn't exist\n",
2047 fprintf(stderr
, "Protocol being registered is \"%s\"\n",
2048 proto_get_protocol_long_name(handle
->protocol
));
2049 if (wireshark_abort_on_dissector_bug
)
2054 ws_assert(sub_dissectors
->type
== FT_BYTES
);
2056 dtbl_entry
= g_new(dtbl_entry_t
, 1);
2057 dtbl_entry
->current
= handle
;
2058 dtbl_entry
->initial
= dtbl_entry
->current
;
2060 /* do the table insertion */
2061 g_hash_table_insert(sub_dissectors
->hash_table
, (void *)pattern
,
2062 (void *)dtbl_entry
);
2065 * Now, if this table supports "Decode As", add this handle
2066 * to the list of handles that could be used for "Decode As"
2067 * with this table, because it *is* being used with this table.
2069 if (sub_dissectors
->supports_decode_as
)
2070 dissector_add_for_decode_as(name
, handle
);
2073 dissector_handle_t
dissector_get_custom_table_handle(dissector_table_t sub_dissectors
, void *key
)
2075 dtbl_entry_t
*dtbl_entry
= (dtbl_entry_t
*)g_hash_table_lookup(sub_dissectors
->hash_table
, key
);
2077 if (dtbl_entry
!= NULL
)
2078 return dtbl_entry
->current
;
2082 /* Add an entry to a guid dissector table. */
2083 void dissector_add_guid(const char *name
, guid_key
* guid_val
, dissector_handle_t handle
)
2085 dissector_table_t sub_dissectors
;
2086 dtbl_entry_t
*dtbl_entry
;
2088 sub_dissectors
= find_dissector_table(name
);
2091 * Make sure the handle and the dissector table exist.
2093 if (handle
== NULL
) {
2094 fprintf(stderr
, "OOPS: handle to register \"%s\" to doesn't exist\n",
2096 if (wireshark_abort_on_dissector_bug
)
2100 if (sub_dissectors
== NULL
) {
2101 fprintf(stderr
, "OOPS: dissector table \"%s\" doesn't exist\n",
2103 fprintf(stderr
, "Protocol being registered is \"%s\"\n",
2104 proto_get_protocol_long_name(handle
->protocol
));
2105 if (wireshark_abort_on_dissector_bug
)
2110 if (sub_dissectors
->type
!= FT_GUID
) {
2111 ws_assert_not_reached();
2114 dtbl_entry
= g_new(dtbl_entry_t
, 1);
2115 dtbl_entry
->current
= handle
;
2116 dtbl_entry
->initial
= dtbl_entry
->current
;
2118 /* do the table insertion */
2119 g_hash_table_insert(sub_dissectors
->hash_table
,
2120 guid_val
, (void *)dtbl_entry
);
2123 * Now, if this table supports "Decode As", add this handle
2124 * to the list of handles that could be used for "Decode As"
2125 * with this table, because it *is* being used with this table.
2127 if (sub_dissectors
->supports_decode_as
)
2128 dissector_add_for_decode_as(name
, handle
);
2131 /* Look for a given value in a given guid dissector table and, if found,
2132 call the dissector with the arguments supplied, and return true,
2133 otherwise return false. */
2134 int dissector_try_guid_with_data(dissector_table_t sub_dissectors
,
2135 guid_key
* guid_val
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, const bool add_proto_name
, void *data
)
2137 dtbl_entry_t
*dtbl_entry
;
2138 struct dissector_handle
*handle
;
2141 dtbl_entry
= (dtbl_entry_t
*)g_hash_table_lookup(sub_dissectors
->hash_table
, guid_val
);
2142 if (dtbl_entry
!= NULL
) {
2144 * Is there currently a dissector handle for this entry?
2146 handle
= dtbl_entry
->current
;
2147 if (handle
== NULL
) {
2149 * No - pretend this dissector didn't exist,
2150 * so that other dissectors might have a chance
2151 * to dissect this packet.
2157 * Save the current value of "pinfo->match_uint",
2158 * set it to the uint_val that matched, call the
2159 * dissector, and restore "pinfo->match_uint".
2161 len
= call_dissector_work(handle
, tvb
, pinfo
, tree
, add_proto_name
, data
);
2164 * If a new-style dissector returned 0, it means that
2165 * it didn't think this tvbuff represented a packet for
2166 * its protocol, and didn't dissect anything.
2168 * Old-style dissectors can't reject the packet.
2170 * 0 is also returned if the protocol wasn't enabled.
2172 * If the packet was rejected, we return 0, so that
2173 * other dissectors might have a chance to dissect this
2174 * packet, otherwise we return the dissected length.
2181 /** Look for a given value in a given guid dissector table and, if found,
2182 * return the current dissector handle for that value.
2184 * @param[in] sub_dissectors Dissector table to search.
2185 * @param[in] guid_val Value to match.
2186 * @return The matching dissector handle on success, NULL if no match is found.
2188 dissector_handle_t
dissector_get_guid_handle(
2189 dissector_table_t
const sub_dissectors
, guid_key
* guid_val
)
2191 dtbl_entry_t
*dtbl_entry
;
2193 dtbl_entry
= (dtbl_entry_t
*)g_hash_table_lookup(sub_dissectors
->hash_table
, guid_val
);
2194 if (dtbl_entry
!= NULL
)
2195 return dtbl_entry
->current
;
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_with_data(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_with_data(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: