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
23 #include "timestamp.h"
25 #include "osi-utils.h"
28 #include "addr_resolv.h"
30 #include "epan_dissect.h"
32 #include "wmem/wmem.h"
34 #include <epan/exceptions.h>
35 #include <epan/reassemble.h>
36 #include <epan/stream.h>
37 #include <epan/expert.h>
38 #include <epan/prefs.h>
39 #include <epan/range.h>
41 #include <wsutil/str_util.h>
42 #include <wsutil/ws_printf.h> /* ws_debug_printf */
44 static gint proto_malformed = -1;
45 static dissector_handle_t frame_handle = NULL;
46 static dissector_handle_t file_handle = NULL;
47 static dissector_handle_t data_handle = NULL;
51 * Has a tvbuff and a name.
61 * "hash_table" is a hash table, indexed by port number, supplying
62 * a "struct dtbl_entry"; it records what dissector is assigned to
63 * that uint or string value in that table.
65 * "dissector_handles" is a list of all dissectors that *could* be
66 * used in that table; not all of them are necessarily in the table,
67 * as they may be for protocols that don't have a fixed uint value,
68 * e.g. for TCP or UDP port number tables and protocols with no fixed
71 * "ui_name" is the name the dissector table has in the user interface.
73 * "type" is a field type giving the width of the uint value for that
74 * dissector table, if it's a uint dissector table.
76 * "param" is the base in which to display the uint value for that
77 * dissector table, if it's a uint dissector table, or if it's a string
78 * table, TRUE/FALSE to indicate case-insensitive or not.
80 * "protocol" is the protocol associated with the dissector table. Used
81 * for determining dependencies.
83 struct dissector_table {
84 GHashTable *hash_table;
85 GSList *dissector_handles;
91 gboolean supports_decode_as;
95 * Dissector tables. const char * -> dissector_table *
97 static GHashTable *dissector_tables = NULL;
100 * Dissector table aliases. const char * -> const char *
102 static GHashTable *dissector_table_aliases = NULL;
105 * List of registered dissectors.
107 static GHashTable *registered_dissectors = NULL;
110 * A dissector dependency list.
112 struct depend_dissector_list {
116 /* Maps char *dissector_name to depend_dissector_list_t */
117 static GHashTable *depend_dissector_lists = NULL;
119 /* Allow protocols to register a "cleanup" routine to be
120 * run after the initial sequential run through the packets.
121 * Note that the file can still be open after this; this is not
122 * the final cleanup. */
123 static GSList *postseq_cleanup_routines;
126 * Post-dissector information - handle for the dissector and a list
127 * of hfids for the fields the post-dissector wants.
130 dissector_handle_t handle;
131 GArray *wanted_hfids;
135 * Array of all postdissectors.
137 static GArray *postdissectors = NULL;
140 * i-th element of that array.
142 #define POSTDISSECTORS(i) g_array_index(postdissectors, postdissector, i)
145 destroy_depend_dissector_list(void *data)
147 depend_dissector_list_t dissector_list = (depend_dissector_list_t)data;
148 GSList **list = &(dissector_list->dissectors);
150 g_slist_free_full(*list, g_free);
151 g_slice_free(struct depend_dissector_list, dissector_list);
155 * A heuristics dissector list.
157 struct heur_dissector_list {
158 protocol_t *protocol;
162 static GHashTable *heur_dissector_lists = NULL;
164 /* Name hashtables for fast detection of duplicate names */
165 static GHashTable* heuristic_short_names = NULL;
168 destroy_heuristic_dissector_entry(gpointer data)
170 heur_dtbl_entry_t *hdtbl_entry = (heur_dtbl_entry_t *)data;
171 g_free(hdtbl_entry->list_name);
172 g_free(hdtbl_entry->short_name);
173 g_slice_free(heur_dtbl_entry_t, data);
177 destroy_heuristic_dissector_list(void *data)
179 heur_dissector_list_t dissector_list = (heur_dissector_list_t)data;
180 GSList **list = &(dissector_list->dissectors);
182 g_slist_free_full(*list, destroy_heuristic_dissector_entry);
183 g_slice_free(struct heur_dissector_list, dissector_list);
187 destroy_dissector_table(void *data)
189 struct dissector_table *table = (struct dissector_table *)data;
191 g_hash_table_destroy(table->hash_table);
192 g_slist_free(table->dissector_handles);
193 g_slice_free(struct dissector_table, data);
199 dissector_tables = g_hash_table_new_full(g_str_hash, g_str_equal,
200 NULL, destroy_dissector_table);
202 dissector_table_aliases = g_hash_table_new_full(g_str_hash, g_str_equal,
205 registered_dissectors = g_hash_table_new_full(g_str_hash, g_str_equal,
208 depend_dissector_lists = g_hash_table_new_full(g_str_hash, g_str_equal,
209 g_free, destroy_depend_dissector_list);
211 heur_dissector_lists = g_hash_table_new_full(g_str_hash, g_str_equal,
212 NULL, destroy_heuristic_dissector_list);
214 heuristic_short_names = g_hash_table_new(g_str_hash, g_str_equal);
218 packet_cache_proto_handles(void)
220 frame_handle = find_dissector("frame");
221 g_assert(frame_handle != NULL);
223 file_handle = find_dissector("file");
224 g_assert(file_handle != NULL);
226 data_handle = find_dissector("data");
227 g_assert(data_handle != NULL);
229 proto_malformed = proto_get_id_by_filter_name("_ws.malformed");
230 g_assert(proto_malformed != -1);
233 /* List of routines that are called before we make a pass through a capture file
234 * and dissect all its packets. See register_init_routine, register_cleanup_routine
235 * and register_shutdown_routine in packet.h */
236 static GSList *init_routines = NULL;
237 static GSList *cleanup_routines = NULL;
238 static GSList *shutdown_routines = NULL;
240 typedef void (*void_func_t)(void);
242 /* Initialize all data structures used for dissection. */
244 call_routine(gpointer routine, gpointer dummy _U_)
246 void_func_t func = (void_func_t)routine;
253 g_slist_free(init_routines);
254 g_slist_free(cleanup_routines);
255 g_slist_free(postseq_cleanup_routines);
256 g_hash_table_destroy(dissector_tables);
257 g_hash_table_destroy(dissector_table_aliases);
258 g_hash_table_destroy(registered_dissectors);
259 g_hash_table_destroy(depend_dissector_lists);
260 g_hash_table_destroy(heur_dissector_lists);
261 g_hash_table_destroy(heuristic_short_names);
262 g_slist_foreach(shutdown_routines, &call_routine, NULL);
263 g_slist_free(shutdown_routines);
264 if (postdissectors) {
265 for (guint i = 0; i < postdissectors->len; i++) {
266 if (POSTDISSECTORS(i).wanted_hfids) {
267 g_array_free(POSTDISSECTORS(i).wanted_hfids, TRUE);
270 g_array_free(postdissectors, TRUE);
275 * Given a tvbuff, and a length from a packet header, adjust the length
276 * of the tvbuff to reflect the specified length.
279 set_actual_length(tvbuff_t *tvb, const guint specified_len)
281 if (specified_len < tvb_reported_length(tvb)) {
282 /* Adjust the length of this tvbuff to include only the specified
285 The dissector above the one calling us (the dissector above is
286 probably us) may use that to determine how much of its packet
288 tvb_set_reported_length(tvb, specified_len);
293 register_init_routine(void (*func)(void))
295 init_routines = g_slist_prepend(init_routines, (gpointer)func);
299 register_cleanup_routine(void (*func)(void))
301 cleanup_routines = g_slist_prepend(cleanup_routines, (gpointer)func);
304 /* register a new shutdown routine */
306 register_shutdown_routine(void (*func)(void))
308 shutdown_routines = g_slist_prepend(shutdown_routines, (gpointer)func);
311 /* Initialize all data structures used for dissection. */
313 init_dissection(void)
316 * Reinitialize resolution information. Don't leak host entries from
317 * one file to another (e.g. embarassing-host-name.example.com from
318 * file1.pcapng into a name resolution block in file2.pcapng).
320 host_name_lookup_reset();
322 wmem_enter_file_scope();
324 /* Initialize the table of conversations. */
325 epan_conversation_init();
327 /* Initialize protocol-specific variables. */
328 g_slist_foreach(init_routines, &call_routine, NULL);
330 /* Initialize the stream-handling tables */
333 /* Initialize the expert infos */
334 expert_packet_init();
338 cleanup_dissection(void)
340 /* Cleanup protocol-specific variables. */
341 g_slist_foreach(cleanup_routines, &call_routine, NULL);
343 /* Cleanup the stream-handling tables */
346 /* Cleanup the expert infos */
347 expert_packet_cleanup();
349 wmem_leave_file_scope();
352 * Keep the name resolution info around until we start the next
353 * dissection. Lua scripts may potentially do name resolution at
354 * any time, even if we're not dissecting and have no capture
360 register_postseq_cleanup_routine(void_func_t func)
362 postseq_cleanup_routines = g_slist_prepend(postseq_cleanup_routines,
366 /* Call all the registered "postseq_cleanup" routines. */
368 postseq_cleanup_all_protocols(void)
370 g_slist_foreach(postseq_cleanup_routines,
371 &call_routine, NULL);
375 * Add a new data source to the list of data sources for a frame, given
376 * the tvbuff for the data source and its name.
379 add_new_data_source(packet_info *pinfo, tvbuff_t *tvb, const char *name)
381 struct data_source *src;
383 src = wmem_new(pinfo->pool, struct data_source);
385 src->name = wmem_strdup(pinfo->pool, name);
386 /* This could end up slow, but we should never have that many data
387 * sources so it probably doesn't matter */
388 pinfo->data_src = g_slist_append(pinfo->data_src, src);
392 remove_last_data_source(packet_info *pinfo)
396 last = g_slist_last(pinfo->data_src);
397 pinfo->data_src = g_slist_delete_link(pinfo->data_src, last);
401 get_data_source_name(const struct data_source *src)
403 guint length = tvb_captured_length(src->tvb);
405 return wmem_strdup_printf(NULL, "%s (%u byte%s)", src->name, length,
406 plurality(length, "", "s"));
410 get_data_source_tvb(const struct data_source *src)
416 * Find and return the tvb associated with the given data source name
419 get_data_source_tvb_by_name(packet_info *pinfo, const char *name)
422 for (source = pinfo->data_src; source; source = source->next) {
423 struct data_source *this_source = (struct data_source *)source;
424 if (this_source->name && strcmp(this_source->name, name) == 0) {
425 return this_source->tvb;
433 * Free up a frame's list of data sources.
436 free_data_sources(packet_info *pinfo)
438 if (pinfo->data_src) {
439 g_slist_free(pinfo->data_src);
440 pinfo->data_src = NULL;
445 mark_frame_as_depended_upon(packet_info *pinfo, guint32 frame_num)
447 /* Don't mark a frame as dependent on itself */
448 if (frame_num != pinfo->num) {
449 pinfo->dependent_frames = g_slist_prepend(pinfo->dependent_frames, GUINT_TO_POINTER(frame_num));
453 /* Allow dissectors to register a "final_registration" routine
454 * that is run like the proto_register_XXX() routine, but at the
455 * end of the epan_init() function; that is, *after* all other
456 * subsystems, like dfilters, have finished initializing. This is
457 * useful for dissector registration routines which need to compile
458 * display filters. dfilters can't initialize itself until all protocols
459 * have registered themselves. */
460 static GSList *final_registration_routines;
463 register_final_registration_routine(void (*func)(void))
465 final_registration_routines = g_slist_prepend(final_registration_routines,
469 /* Call all the registered "final_registration" routines. */
471 final_registration_all_protocols(void)
473 g_slist_foreach(final_registration_routines,
474 &call_routine, NULL);
478 /* Creates the top-most tvbuff and calls dissect_frame() */
480 dissect_record(epan_dissect_t *edt, int file_type_subtype,
481 wtap_rec *rec, tvbuff_t *tvb, frame_data *fd, column_info *cinfo)
483 const char *volatile record_type;
484 frame_data_t frame_dissector_data;
486 switch (rec->rec_type) {
488 case REC_TYPE_PACKET:
489 record_type = "Frame";
492 case REC_TYPE_FT_SPECIFIC_EVENT:
493 record_type = "Event";
496 case REC_TYPE_FT_SPECIFIC_REPORT:
497 record_type = "Report";
500 case REC_TYPE_SYSCALL:
501 record_type = "System Call";
506 * XXX - if we add record types that shouldn't be
507 * dissected and displayed, but that need to at
508 * least be processed somewhere, we need to somehow
509 * indicate that to our caller.
511 g_assert_not_reached();
516 col_init(cinfo, edt->session);
517 edt->pi.epan = edt->session;
518 /* edt->pi.pool created in epan_dissect_init() */
519 edt->pi.current_proto = "<Missing Protocol Name>";
520 edt->pi.cinfo = cinfo;
521 edt->pi.presence_flags = 0;
522 edt->pi.num = fd->num;
523 if (fd->flags.has_ts) {
524 edt->pi.presence_flags |= PINFO_HAS_TS;
525 edt->pi.abs_ts = fd->abs_ts;
527 switch (rec->rec_type) {
529 case REC_TYPE_PACKET:
530 edt->pi.pseudo_header = &rec->rec_header.packet_header.pseudo_header;
533 case REC_TYPE_FT_SPECIFIC_EVENT:
534 case REC_TYPE_FT_SPECIFIC_REPORT:
535 edt->pi.pseudo_header = NULL;
538 case REC_TYPE_SYSCALL:
539 edt->pi.pseudo_header = NULL;
545 clear_address(&edt->pi.dl_src);
546 clear_address(&edt->pi.dl_dst);
547 clear_address(&edt->pi.net_src);
548 clear_address(&edt->pi.net_dst);
549 clear_address(&edt->pi.src);
550 clear_address(&edt->pi.dst);
551 edt->pi.noreassembly_reason = "";
552 edt->pi.ptype = PT_NONE;
553 edt->pi.use_endpoint = FALSE;
554 edt->pi.conv_endpoint = NULL;
555 edt->pi.p2p_dir = P2P_DIR_UNKNOWN;
556 edt->pi.link_dir = LINK_DIR_UNKNOWN;
557 edt->pi.layers = wmem_list_new(edt->pi.pool);
560 frame_delta_abs_time(edt->session, fd, fd->frame_ref_num, &edt->pi.rel_ts);
562 /* pkt comment use first user, later from rec */
563 if (fd->flags.has_user_comment)
564 frame_dissector_data.pkt_comment = epan_get_user_comment(edt->session, fd);
565 else if (fd->flags.has_phdr_comment)
566 frame_dissector_data.pkt_comment = rec->opt_comment;
568 frame_dissector_data.pkt_comment = NULL;
569 frame_dissector_data.file_type_subtype = file_type_subtype;
570 frame_dissector_data.color_edt = edt; /* Used strictly for "coloring rules" */
573 /* Add this tvbuffer into the data_src list */
574 add_new_data_source(&edt->pi, edt->tvb, record_type);
576 /* Even though dissect_frame() catches all the exceptions a
577 * sub-dissector can throw, dissect_frame() itself may throw
578 * a ReportedBoundsError in bizarre cases. Thus, we catch the exception
579 * in this function. */
580 call_dissector_with_data(frame_handle, edt->tvb, &edt->pi, edt->tree, &frame_dissector_data);
583 g_assert_not_reached();
585 CATCH2(FragmentBoundsError, ReportedBoundsError) {
586 proto_tree_add_protocol_format(edt->tree, proto_malformed, edt->tvb, 0, 0,
587 "[Malformed %s: Packet Length]",
592 fd->flags.visited = 1;
595 /* Creates the top-most tvbuff and calls dissect_file() */
597 dissect_file(epan_dissect_t *edt, wtap_rec *rec,
598 tvbuff_t *tvb, frame_data *fd, column_info *cinfo)
600 file_data_t file_dissector_data;
603 col_init(cinfo, edt->session);
604 edt->pi.epan = edt->session;
605 /* edt->pi.pool created in epan_dissect_init() */
606 edt->pi.current_proto = "<Missing Filetype Name>";
607 edt->pi.cinfo = cinfo;
610 edt->pi.pseudo_header = NULL;
611 clear_address(&edt->pi.dl_src);
612 clear_address(&edt->pi.dl_dst);
613 clear_address(&edt->pi.net_src);
614 clear_address(&edt->pi.net_dst);
615 clear_address(&edt->pi.src);
616 clear_address(&edt->pi.dst);
617 edt->pi.noreassembly_reason = "";
618 edt->pi.ptype = PT_NONE;
619 edt->pi.use_endpoint = FALSE;
620 edt->pi.conv_endpoint = NULL;
621 edt->pi.p2p_dir = P2P_DIR_UNKNOWN;
622 edt->pi.link_dir = LINK_DIR_UNKNOWN;
623 edt->pi.layers = wmem_list_new(edt->pi.pool);
627 frame_delta_abs_time(edt->session, fd, fd->frame_ref_num, &edt->pi.rel_ts);
631 /* pkt comment use first user, later from rec */
632 if (fd->flags.has_user_comment)
633 file_dissector_data.pkt_comment = epan_get_user_comment(edt->session, fd);
634 else if (fd->flags.has_phdr_comment)
635 file_dissector_data.pkt_comment = rec->opt_comment;
637 file_dissector_data.pkt_comment = NULL;
638 file_dissector_data.color_edt = edt; /* Used strictly for "coloring rules" */
641 /* Add this tvbuffer into the data_src list */
642 add_new_data_source(&edt->pi, edt->tvb, "File");
644 /* Even though dissect_file() catches all the exceptions a
645 * sub-dissector can throw, dissect_frame() itself may throw
646 * a ReportedBoundsError in bizarre cases. Thus, we catch the exception
647 * in this function. */
648 call_dissector_with_data(file_handle, edt->tvb, &edt->pi, edt->tree, &file_dissector_data);
652 g_assert_not_reached();
654 CATCH3(FragmentBoundsError, ContainedBoundsError, ReportedBoundsError) {
655 proto_tree_add_protocol_format(edt->tree, proto_malformed, edt->tvb, 0, 0,
656 "[Malformed Record: Packet Length]");
660 fd->flags.visited = 1;
663 /*********************** code added for sub-dissector lookup *********************/
666 DISSECTOR_TYPE_SIMPLE,
667 DISSECTOR_TYPE_CALLBACK
671 * A dissector handle.
673 struct dissector_handle {
674 const char *name; /* dissector name */
675 enum dissector_e dissector_type;
676 void *dissector_func;
677 void *dissector_data;
678 protocol_t *protocol;
681 /* This function will return
682 * old style dissector :
683 * length of the payload or 1 of the payload is empty
685 * >0 this protocol was successfully dissected and this was this protocol.
686 * 0 this packet did not match this protocol.
688 * The only time this function will return 0 is if it is a new style dissector
689 * and if the dissector rejected the packet.
692 call_dissector_through_handle(dissector_handle_t handle, tvbuff_t *tvb,
693 packet_info *pinfo, proto_tree *tree, void *data)
695 const char *saved_proto;
698 saved_proto = pinfo->current_proto;
700 if ((handle->protocol != NULL) && (!proto_is_pino(handle->protocol))) {
701 pinfo->current_proto =
702 proto_get_protocol_short_name(handle->protocol);
705 if (handle->dissector_type == DISSECTOR_TYPE_SIMPLE) {
706 len = ((dissector_t)handle->dissector_func)(tvb, pinfo, tree, data);
708 else if (handle->dissector_type == DISSECTOR_TYPE_CALLBACK) {
709 len = ((dissector_cb_t)handle->dissector_func)(tvb, pinfo, tree, data, handle->dissector_data);
712 g_assert_not_reached();
714 pinfo->current_proto = saved_proto;
720 * Call a dissector through a handle.
721 * If the protocol for that handle isn't enabled, return 0 without
722 * calling the dissector.
723 * Otherwise, if the handle refers to a new-style dissector, call the
724 * dissector and return its return value, otherwise call it and return
725 * the length of the tvbuff pointed to by the argument.
729 call_dissector_work_error(dissector_handle_t handle, tvbuff_t *tvb,
730 packet_info *pinfo_arg, proto_tree *tree, void *);
733 call_dissector_work(dissector_handle_t handle, tvbuff_t *tvb, packet_info *pinfo_arg,
734 proto_tree *tree, gboolean add_proto_name, void *data)
736 packet_info *pinfo = pinfo_arg;
737 const char *saved_proto;
738 guint16 saved_can_desegment;
740 guint saved_layers_len = 0;
741 int saved_tree_count = tree ? tree->tree_data->count : 0;
743 if (handle->protocol != NULL &&
744 !proto_is_protocol_enabled(handle->protocol)) {
746 * The protocol isn't enabled.
751 saved_proto = pinfo->current_proto;
752 saved_can_desegment = pinfo->can_desegment;
753 saved_layers_len = wmem_list_count(pinfo->layers);
756 * can_desegment is set to 2 by anyone which offers the
757 * desegmentation api/service.
758 * Then everytime a subdissector is called it is decremented
760 * Thus only the subdissector immediately on top of whoever
761 * offers this service can use it.
762 * We save the current value of "can_desegment" for the
763 * benefit of TCP proxying dissectors such as SOCKS, so they
764 * can restore it and allow the dissectors they call to use
765 * the desegmentation service.
767 pinfo->saved_can_desegment = saved_can_desegment;
768 pinfo->can_desegment = saved_can_desegment-(saved_can_desegment>0);
769 if ((handle->protocol != NULL) && (!proto_is_pino(handle->protocol))) {
770 pinfo->current_proto =
771 proto_get_protocol_short_name(handle->protocol);
774 * Add the protocol name to the layers only if told to
775 * do so. Asn2wrs generated dissectors may be added
776 * multiple times otherwise.
778 /* XXX Should we check for a duplicate layer here? */
779 if (add_proto_name) {
780 pinfo->curr_layer_num++;
781 wmem_list_append(pinfo->layers, GINT_TO_POINTER(proto_get_id(handle->protocol)));
785 if (pinfo->flags.in_error_pkt) {
786 len = call_dissector_work_error(handle, tvb, pinfo, tree, data);
789 * Just call the subdissector.
791 len = call_dissector_through_handle(handle, tvb, pinfo, tree, data);
793 if (handle->protocol != NULL && !proto_is_pino(handle->protocol) && add_proto_name &&
794 (len == 0 || (tree && saved_tree_count == tree->tree_data->count))) {
796 * We've added a layer and either the dissector didn't
797 * accept the packet or we didn't add any items to the
800 while (wmem_list_count(pinfo->layers) > saved_layers_len) {
801 pinfo->curr_layer_num--;
802 wmem_list_remove_frame(pinfo->layers, wmem_list_tail(pinfo->layers));
805 pinfo->current_proto = saved_proto;
806 pinfo->can_desegment = saved_can_desegment;
812 call_dissector_work_error(dissector_handle_t handle, tvbuff_t *tvb,
813 packet_info *pinfo_arg, proto_tree *tree, void *data)
815 packet_info *pinfo = pinfo_arg;
816 const char *saved_proto;
817 guint16 saved_can_desegment;
818 volatile int len = 0;
819 gboolean save_writable;
822 address save_net_src;
823 address save_net_dst;
828 * This isn't a packet being transported inside
829 * the protocol whose dissector is calling us,
830 * it's a copy of a packet that caused an error
831 * in some protocol included in a packet that
832 * reports the error (e.g., an ICMP Unreachable
837 * Save the current state of the writability of
838 * the columns, and restore them after the
839 * dissector returns, so that the columns
840 * don't reflect the packet that got the error,
841 * they reflect the packet that reported the
844 saved_proto = pinfo->current_proto;
845 saved_can_desegment = pinfo->can_desegment;
847 save_writable = col_get_writable(pinfo->cinfo, -1);
848 col_set_writable(pinfo->cinfo, -1, FALSE);
849 copy_address_shallow(&save_dl_src, &pinfo->dl_src);
850 copy_address_shallow(&save_dl_dst, &pinfo->dl_dst);
851 copy_address_shallow(&save_net_src, &pinfo->net_src);
852 copy_address_shallow(&save_net_dst, &pinfo->net_dst);
853 copy_address_shallow(&save_src, &pinfo->src);
854 copy_address_shallow(&save_dst, &pinfo->dst);
856 /* Dissect the contained packet. */
858 len = call_dissector_through_handle(handle, tvb,pinfo, tree, data);
862 * Restore the column writability and addresses.
864 col_set_writable(pinfo->cinfo, -1, save_writable);
865 copy_address_shallow(&pinfo->dl_src, &save_dl_src);
866 copy_address_shallow(&pinfo->dl_dst, &save_dl_dst);
867 copy_address_shallow(&pinfo->net_src, &save_net_src);
868 copy_address_shallow(&pinfo->net_dst, &save_net_dst);
869 copy_address_shallow(&pinfo->src, &save_src);
870 copy_address_shallow(&pinfo->dst, &save_dst);
873 * Restore the current protocol, so any
874 * "Short Frame" indication reflects that
875 * protocol, not the protocol for the
876 * packet that got the error.
878 pinfo->current_proto = saved_proto;
881 * Restore the desegmentability state.
883 pinfo->can_desegment = saved_can_desegment;
886 * Rethrow the exception, so this will be
887 * reported as a short frame.
891 CATCH3(FragmentBoundsError, ContainedBoundsError, ReportedBoundsError) {
893 * "ret" wasn't set because an exception was thrown
894 * before "call_dissector_through_handle()" returned.
895 * As it called something, at least one dissector
896 * accepted the packet, and, as an exception was
897 * thrown, not only was all the tvbuff dissected,
898 * a dissector tried dissecting past the end of
899 * the data in some tvbuff, so we'll assume that
900 * the entire tvbuff was dissected.
902 len = tvb_captured_length(tvb);
906 col_set_writable(pinfo->cinfo, -1, save_writable);
907 copy_address_shallow(&pinfo->dl_src, &save_dl_src);
908 copy_address_shallow(&pinfo->dl_dst, &save_dl_dst);
909 copy_address_shallow(&pinfo->net_src, &save_net_src);
910 copy_address_shallow(&pinfo->net_dst, &save_net_dst);
911 copy_address_shallow(&pinfo->src, &save_src);
912 copy_address_shallow(&pinfo->dst, &save_dst);
913 pinfo->want_pdu_tracking = 0;
918 * An entry in the hash table portion of a dissector table.
921 dissector_handle_t initial;
922 dissector_handle_t current;
925 /* Finds a dissector table by table name. */
927 find_dissector_table(const char *name)
929 dissector_table_t dissector_table = (dissector_table_t) g_hash_table_lookup(dissector_tables, name);
930 if (! dissector_table) {
931 const char *new_name = (const char *) g_hash_table_lookup(dissector_table_aliases, name);
933 dissector_table = (dissector_table_t) g_hash_table_lookup(dissector_tables, new_name);
935 if (dissector_table) {
936 g_warning("%s is now %s", name, new_name);
939 return dissector_table;
942 /* Find an entry in a uint dissector table. */
943 static dtbl_entry_t *
944 find_uint_dtbl_entry(dissector_table_t sub_dissectors, const guint32 pattern)
946 switch (sub_dissectors->type) {
953 * You can do a uint lookup in these tables.
957 /* For now treat as uint */
962 * But you can't do a uint lookup in any other types
965 g_assert_not_reached();
971 return (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table,
972 GUINT_TO_POINTER(pattern));
977 dissector_add_uint_sanity_check(const char *name, guint32 pattern, dissector_handle_t handle, dissector_table_t sub_dissectors)
979 dtbl_entry_t *dtbl_entry;
982 g_warning("%s: %s registering using a pattern of 0",
983 name, proto_get_protocol_filter_name(proto_get_id(handle->protocol)));
986 dtbl_entry = g_hash_table_lookup(sub_dissectors->hash_table, GUINT_TO_POINTER(pattern));
987 if (dtbl_entry != NULL) {
988 g_warning("%s: %s registering using pattern %d already registered by %s",
989 name, proto_get_protocol_filter_name(proto_get_id(handle->protocol)),
990 pattern, proto_get_protocol_filter_name(proto_get_id(dtbl_entry->initial->protocol)));
995 /* Add an entry to a uint dissector table. */
997 dissector_add_uint(const char *name, const guint32 pattern, dissector_handle_t handle)
999 dissector_table_t sub_dissectors;
1000 dtbl_entry_t *dtbl_entry;
1002 sub_dissectors = find_dissector_table(name);
1005 * Make sure the handle and the dissector table exist.
1007 if (handle == NULL) {
1008 fprintf(stderr, "OOPS: handle to register \"%s\" to doesn't exist\n",
1010 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1014 if (sub_dissectors == NULL) {
1015 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
1017 fprintf(stderr, "Protocol being registered is \"%s\"\n",
1018 proto_get_protocol_long_name(handle->protocol));
1019 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1024 switch (sub_dissectors->type) {
1031 * You can do a uint lookup in these tables.
1037 * But you can't do a uint lookup in any other types
1040 g_assert_not_reached();
1044 dissector_add_uint_sanity_check(name, pattern, handle, sub_dissectors);
1047 dtbl_entry = (dtbl_entry_t *)g_malloc(sizeof (dtbl_entry_t));
1048 dtbl_entry->current = handle;
1049 dtbl_entry->initial = dtbl_entry->current;
1051 /* do the table insertion */
1052 g_hash_table_insert(sub_dissectors->hash_table,
1053 GUINT_TO_POINTER(pattern), (gpointer)dtbl_entry);
1056 * Now, if this table supports "Decode As", add this handle
1057 * to the list of handles that could be used for "Decode As"
1058 * with this table, because it *is* being used with this table.
1060 if (sub_dissectors->supports_decode_as)
1061 dissector_add_for_decode_as(name, handle);
1066 void dissector_add_uint_range(const char *name, range_t *range,
1067 dissector_handle_t handle)
1069 dissector_table_t sub_dissectors;
1073 if (range->nranges == 0) {
1075 * Even an empty range would want a chance for
1076 * Decode As, if the dissector table supports
1079 sub_dissectors = find_dissector_table(name);
1080 if (sub_dissectors->supports_decode_as)
1081 dissector_add_for_decode_as(name, handle);
1084 for (i = 0; i < range->nranges; i++) {
1085 for (j = range->ranges[i].low; j < range->ranges[i].high; j++)
1086 dissector_add_uint(name, j, handle);
1087 dissector_add_uint(name, range->ranges[i].high, handle);
1094 dissector_add_preference(const char *name, dissector_handle_t handle, guint init_value)
1098 gchar *description, *title;
1099 dissector_table_t pref_dissector_table = find_dissector_table(name);
1100 int proto_id = proto_get_id(handle->protocol);
1102 uint_var = wmem_new(wmem_epan_scope(), guint);
1103 *uint_var = init_value;
1105 /* If the dissector already has a preference module, use it */
1106 module = prefs_find_module(proto_get_protocol_filter_name(proto_id));
1109 /* Otherwise create a new one */
1110 module = prefs_register_protocol(proto_id, NULL);
1113 description = wmem_strdup_printf(wmem_epan_scope(), "Set the %s for %s (if other than the default of %u)",
1114 pref_dissector_table->ui_name, proto_get_protocol_short_name(handle->protocol), *uint_var);
1115 title = wmem_strdup_printf(wmem_epan_scope(), "%s %s", proto_get_protocol_short_name(handle->protocol),
1116 pref_dissector_table->ui_name);
1118 prefs_register_decode_as_preference(module, name, title, description, uint_var);
1121 void dissector_add_uint_with_preference(const char *name, const guint32 pattern,
1122 dissector_handle_t handle)
1124 dissector_add_preference(name, handle, pattern);
1125 dissector_add_uint(name, pattern, handle);
1128 void dissector_add_uint_range_with_preference(const char *name, const char* range_str,
1129 dissector_handle_t handle)
1133 gchar *description, *title;
1134 dissector_table_t pref_dissector_table = find_dissector_table(name);
1135 int proto_id = proto_get_id(handle->protocol);
1136 guint32 max_value = 0;
1138 /* If a dissector is added for Decode As only, it's dissector
1139 table value would default to 0.
1140 Set up a preference value with that information
1142 range = wmem_new0(wmem_epan_scope(), range_t*);
1144 /* If the dissector already has a preference module, use it */
1145 module = prefs_find_module(proto_get_protocol_filter_name(proto_id));
1146 if (module == NULL) {
1147 /* Otherwise create a new one */
1148 module = prefs_register_protocol(proto_id, NULL);
1150 /* Some preference callback functions use the proto_reg_handoff_
1151 routine to apply preferences, which could duplicate the
1152 registration of a preference. Check for that here */
1153 if (prefs_find_preference(module, name) == NULL) {
1154 description = wmem_strdup_printf(wmem_epan_scope(), "%s %s(s)",
1155 proto_get_protocol_short_name(handle->protocol), pref_dissector_table->ui_name);
1156 title = wmem_strdup_printf(wmem_epan_scope(), "%s(s)", pref_dissector_table->ui_name);
1158 /* Max value is based on datatype of dissector table */
1159 switch (pref_dissector_table->type) {
1168 max_value = 0xFFFFFF;
1171 max_value = 0xFFFFFFFF;
1175 g_error("The dissector table %s (%s) is not an integer type - are you using a buggy plugin?", name, pref_dissector_table->ui_name);
1176 g_assert_not_reached();
1179 range_convert_str(wmem_epan_scope(), range, range_str, max_value);
1180 prefs_register_decode_as_range_preference(module, name, title, description, range, max_value);
1183 dissector_add_uint_range(name, *range, handle);
1186 /* Delete the entry for a dissector in a uint dissector table
1187 with a particular pattern. */
1189 /* NOTE: this doesn't use the dissector call variable. It is included to */
1190 /* be consistant with the dissector_add_uint and more importantly to be used */
1191 /* if the technique of adding a temporary dissector is implemented. */
1192 /* If temporary dissectors are deleted, then the original dissector must */
1195 dissector_delete_uint(const char *name, const guint32 pattern,
1196 dissector_handle_t handle _U_)
1198 dissector_table_t sub_dissectors = find_dissector_table(name);
1199 dtbl_entry_t *dtbl_entry;
1202 g_assert(sub_dissectors);
1207 dtbl_entry = find_uint_dtbl_entry(sub_dissectors, pattern);
1209 if (dtbl_entry != NULL) {
1211 * Found - remove it.
1213 g_hash_table_remove(sub_dissectors->hash_table,
1214 GUINT_TO_POINTER(pattern));
1218 void dissector_delete_uint_range(const char *name, range_t *range,
1219 dissector_handle_t handle)
1224 for (i = 0; i < range->nranges; i++) {
1225 for (j = range->ranges[i].low; j < range->ranges[i].high; j++)
1226 dissector_delete_uint(name, j, handle);
1227 dissector_delete_uint(name, range->ranges[i].high, handle);
1233 dissector_delete_all_check (gpointer key _U_, gpointer value, gpointer user_data)
1235 dtbl_entry_t *dtbl_entry = (dtbl_entry_t *) value;
1236 dissector_handle_t handle = (dissector_handle_t) user_data;
1238 if (!dtbl_entry->current->protocol) {
1240 * Not all dissectors are registered with a protocol, so we need this
1241 * check when running from dissector_delete_from_all_tables.
1246 return (proto_get_id (dtbl_entry->current->protocol) == proto_get_id (handle->protocol));
1249 /* Delete all entries from a dissector table. */
1250 void dissector_delete_all(const char *name, dissector_handle_t handle)
1252 dissector_table_t sub_dissectors = find_dissector_table(name);
1253 g_assert (sub_dissectors);
1255 g_hash_table_foreach_remove (sub_dissectors->hash_table, dissector_delete_all_check, handle);
1259 dissector_delete_from_table(gpointer key _U_, gpointer value, gpointer user_data)
1261 dissector_table_t sub_dissectors = (dissector_table_t) value;
1262 g_assert (sub_dissectors);
1264 g_hash_table_foreach_remove(sub_dissectors->hash_table, dissector_delete_all_check, user_data);
1265 sub_dissectors->dissector_handles = g_slist_remove(sub_dissectors->dissector_handles, user_data);
1268 /* Delete handle from all tables and dissector_handles lists */
1270 dissector_delete_from_all_tables(dissector_handle_t handle)
1272 g_hash_table_foreach(dissector_tables, dissector_delete_from_table, handle);
1275 /* Change the entry for a dissector in a uint dissector table
1276 with a particular pattern to use a new dissector handle. */
1278 dissector_change_uint(const char *name, const guint32 pattern, dissector_handle_t handle)
1280 dissector_table_t sub_dissectors = find_dissector_table(name);
1281 dtbl_entry_t *dtbl_entry;
1284 g_assert(sub_dissectors);
1287 * See if the entry already exists. If so, reuse it.
1289 dtbl_entry = find_uint_dtbl_entry(sub_dissectors, pattern);
1290 if (dtbl_entry != NULL) {
1291 dtbl_entry->current = handle;
1296 * Don't create an entry if there is no dissector handle - I.E. the
1297 * user said not to decode something that wasn't being decoded
1298 * in the first place.
1303 dtbl_entry = (dtbl_entry_t *)g_malloc(sizeof (dtbl_entry_t));
1304 dtbl_entry->initial = NULL;
1305 dtbl_entry->current = handle;
1307 /* do the table insertion */
1308 g_hash_table_insert(sub_dissectors->hash_table,
1309 GUINT_TO_POINTER(pattern), (gpointer)dtbl_entry);
1312 /* Reset an entry in a uint dissector table to its initial value. */
1314 dissector_reset_uint(const char *name, const guint32 pattern)
1316 dissector_table_t sub_dissectors = find_dissector_table(name);
1317 dtbl_entry_t *dtbl_entry;
1320 g_assert(sub_dissectors);
1325 dtbl_entry = find_uint_dtbl_entry(sub_dissectors, pattern);
1327 if (dtbl_entry == NULL)
1331 * Found - is there an initial value?
1333 if (dtbl_entry->initial != NULL) {
1334 dtbl_entry->current = dtbl_entry->initial;
1336 g_hash_table_remove(sub_dissectors->hash_table,
1337 GUINT_TO_POINTER(pattern));
1341 /* Look for a given value in a given uint dissector table and, if found,
1342 call the dissector with the arguments supplied, and return the number
1343 of bytes consumed by the dissector, otherwise return 0. */
1346 dissector_try_uint_new(dissector_table_t sub_dissectors, const guint32 uint_val,
1347 tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1348 const gboolean add_proto_name, void *data)
1350 dtbl_entry_t *dtbl_entry;
1351 struct dissector_handle *handle;
1352 guint32 saved_match_uint;
1355 dtbl_entry = find_uint_dtbl_entry(sub_dissectors, uint_val);
1356 if (dtbl_entry == NULL) {
1358 * There's no entry in the table for our value.
1364 * Is there currently a dissector handle for this entry?
1366 handle = dtbl_entry->current;
1367 if (handle == NULL) {
1369 * No - pretend this dissector didn't exist,
1370 * so that other dissectors might have a chance
1371 * to dissect this packet.
1377 * Save the current value of "pinfo->match_uint",
1378 * set it to the uint_val that matched, call the
1379 * dissector, and restore "pinfo->match_uint".
1381 saved_match_uint = pinfo->match_uint;
1382 pinfo->match_uint = uint_val;
1383 len = call_dissector_work(handle, tvb, pinfo, tree, add_proto_name, data);
1384 pinfo->match_uint = saved_match_uint;
1387 * If a new-style dissector returned 0, it means that
1388 * it didn't think this tvbuff represented a packet for
1389 * its protocol, and didn't dissect anything.
1391 * Old-style dissectors can't reject the packet.
1393 * 0 is also returned if the protocol wasn't enabled.
1395 * If the packet was rejected, we return 0, so that
1396 * other dissectors might have a chance to dissect this
1397 * packet, otherwise we return the dissected length.
1403 dissector_try_uint(dissector_table_t sub_dissectors, const guint32 uint_val,
1404 tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1407 return dissector_try_uint_new(sub_dissectors, uint_val, tvb, pinfo, tree, TRUE, NULL);
1410 /* Look for a given value in a given uint dissector table and, if found,
1411 return the dissector handle for that value. */
1413 dissector_get_uint_handle(dissector_table_t const sub_dissectors, const guint32 uint_val)
1415 dtbl_entry_t *dtbl_entry;
1417 dtbl_entry = find_uint_dtbl_entry(sub_dissectors, uint_val);
1418 if (dtbl_entry != NULL)
1419 return dtbl_entry->current;
1425 dissector_get_default_uint_handle(const char *name, const guint32 uint_val)
1427 dissector_table_t sub_dissectors = find_dissector_table(name);
1429 if (sub_dissectors != NULL) {
1430 dtbl_entry_t *dtbl_entry = find_uint_dtbl_entry(sub_dissectors, uint_val);
1431 if (dtbl_entry != NULL)
1432 return dtbl_entry->initial;
1437 /* Find an entry in a string dissector table. */
1438 static dtbl_entry_t *
1439 find_string_dtbl_entry(dissector_table_t const sub_dissectors, const gchar *pattern)
1444 switch (sub_dissectors->type) {
1450 * You can do a string lookup in these tables.
1456 * But you can't do a string lookup in any other types
1459 g_assert_not_reached();
1462 if (sub_dissectors->param == TRUE) {
1463 key = g_ascii_strdown(pattern, -1);
1465 key = g_strdup(pattern);
1471 ret = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, key);
1478 /* Add an entry to a string dissector table. */
1480 dissector_add_string(const char *name, const gchar *pattern,
1481 dissector_handle_t handle)
1483 dissector_table_t sub_dissectors = find_dissector_table(name);
1484 dtbl_entry_t *dtbl_entry;
1488 * Make sure the handle and the dissector table exist.
1490 if (handle == NULL) {
1491 fprintf(stderr, "OOPS: handle to register \"%s\" to doesn't exist\n",
1493 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1497 if (sub_dissectors == NULL) {
1498 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
1500 fprintf(stderr, "Protocol being registered is \"%s\"\n",
1501 proto_get_protocol_long_name(handle->protocol));
1502 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1507 switch (sub_dissectors->type) {
1513 * You can do a string lookup in these tables.
1519 * But you can't do a string lookup in any other types
1522 g_assert_not_reached();
1525 dtbl_entry = (dtbl_entry_t *)g_malloc(sizeof (dtbl_entry_t));
1526 dtbl_entry->current = handle;
1527 dtbl_entry->initial = dtbl_entry->current;
1529 if (sub_dissectors->param == TRUE) {
1530 key = g_ascii_strdown(pattern, -1);
1532 key = g_strdup(pattern);
1535 /* do the table insertion */
1536 g_hash_table_insert(sub_dissectors->hash_table, (gpointer)key,
1537 (gpointer)dtbl_entry);
1540 * Now, if this table supports "Decode As", add this handle
1541 * to the list of handles that could be used for "Decode As"
1542 * with this table, because it *is* being used with this table.
1544 if (sub_dissectors->supports_decode_as)
1545 dissector_add_for_decode_as(name, handle);
1548 /* Delete the entry for a dissector in a string dissector table
1549 with a particular pattern. */
1551 /* NOTE: this doesn't use the dissector call variable. It is included to */
1552 /* be consistant with the dissector_add_string and more importantly to */
1553 /* be used if the technique of adding a temporary dissector is */
1555 /* If temporary dissectors are deleted, then the original dissector must */
1558 dissector_delete_string(const char *name, const gchar *pattern,
1559 dissector_handle_t handle _U_)
1561 dissector_table_t sub_dissectors = find_dissector_table(name);
1562 dtbl_entry_t *dtbl_entry;
1565 g_assert(sub_dissectors);
1570 dtbl_entry = find_string_dtbl_entry(sub_dissectors, pattern);
1572 if (dtbl_entry != NULL) {
1574 * Found - remove it.
1576 g_hash_table_remove(sub_dissectors->hash_table, pattern);
1580 /* Change the entry for a dissector in a string dissector table
1581 with a particular pattern to use a new dissector handle. */
1583 dissector_change_string(const char *name, const gchar *pattern,
1584 dissector_handle_t handle)
1586 dissector_table_t sub_dissectors = find_dissector_table(name);
1587 dtbl_entry_t *dtbl_entry;
1590 g_assert(sub_dissectors);
1593 * See if the entry already exists. If so, reuse it.
1595 dtbl_entry = find_string_dtbl_entry(sub_dissectors, pattern);
1596 if (dtbl_entry != NULL) {
1597 dtbl_entry->current = handle;
1602 * Don't create an entry if there is no dissector handle - I.E. the
1603 * user said not to decode something that wasn't being decoded
1604 * in the first place.
1609 dtbl_entry = (dtbl_entry_t *)g_malloc(sizeof (dtbl_entry_t));
1610 dtbl_entry->initial = NULL;
1611 dtbl_entry->current = handle;
1613 /* do the table insertion */
1614 g_hash_table_insert(sub_dissectors->hash_table, (gpointer)g_strdup(pattern),
1615 (gpointer)dtbl_entry);
1618 /* Reset an entry in a string sub-dissector table to its initial value. */
1620 dissector_reset_string(const char *name, const gchar *pattern)
1622 dissector_table_t sub_dissectors = find_dissector_table(name);
1623 dtbl_entry_t *dtbl_entry;
1626 g_assert(sub_dissectors);
1631 dtbl_entry = find_string_dtbl_entry(sub_dissectors, pattern);
1633 if (dtbl_entry == NULL)
1637 * Found - is there an initial value?
1639 if (dtbl_entry->initial != NULL) {
1640 dtbl_entry->current = dtbl_entry->initial;
1642 g_hash_table_remove(sub_dissectors->hash_table, pattern);
1646 /* Look for a given string in a given dissector table and, if found, call
1647 the dissector with the arguments supplied, and return length of dissected data,
1648 otherwise return 0. */
1650 dissector_try_string_new(dissector_table_t sub_dissectors, const gchar *string,
1651 tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const gboolean add_proto_name, void *data)
1653 dtbl_entry_t *dtbl_entry;
1654 struct dissector_handle *handle;
1656 const gchar *saved_match_string;
1658 /* XXX ASSERT instead ? */
1659 if (!string) return 0;
1660 dtbl_entry = find_string_dtbl_entry(sub_dissectors, string);
1661 if (dtbl_entry != NULL) {
1663 * Is there currently a dissector handle for this entry?
1665 handle = dtbl_entry->current;
1666 if (handle == NULL) {
1668 * No - pretend this dissector didn't exist,
1669 * so that other dissectors might have a chance
1670 * to dissect this packet.
1676 * Save the current value of "pinfo->match_string",
1677 * set it to the string that matched, call the
1678 * dissector, and restore "pinfo->match_string".
1680 saved_match_string = pinfo->match_string;
1681 pinfo->match_string = string;
1682 len = call_dissector_work(handle, tvb, pinfo, tree, add_proto_name, data);
1683 pinfo->match_string = saved_match_string;
1686 * If a new-style dissector returned 0, it means that
1687 * it didn't think this tvbuff represented a packet for
1688 * its protocol, and didn't dissect anything.
1690 * Old-style dissectors can't reject the packet.
1692 * 0 is also returned if the protocol wasn't enabled.
1694 * If the packet was rejected, we return 0, so that
1695 * other dissectors might have a chance to dissect this
1696 * packet, otherwise we return the dissected length.
1704 dissector_try_string(dissector_table_t sub_dissectors, const gchar *string,
1705 tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1707 return dissector_try_string_new(sub_dissectors, string, tvb, pinfo, tree, TRUE, data);
1710 /* Look for a given value in a given string dissector table and, if found,
1711 return the dissector handle for that value. */
1713 dissector_get_string_handle(dissector_table_t sub_dissectors,
1714 const gchar *string)
1716 dtbl_entry_t *dtbl_entry;
1718 /* XXX ASSERT instead ? */
1719 if (!string) return NULL;
1720 dtbl_entry = find_string_dtbl_entry(sub_dissectors, string);
1721 if (dtbl_entry != NULL)
1722 return dtbl_entry->current;
1728 dissector_get_default_string_handle(const char *name, const gchar *string)
1730 dissector_table_t sub_dissectors;
1732 /* XXX ASSERT instead ? */
1733 if (!string) return NULL;
1734 sub_dissectors = find_dissector_table(name);
1735 if (sub_dissectors != NULL) {
1736 dtbl_entry_t *dtbl_entry = find_string_dtbl_entry(sub_dissectors, string);
1737 if (dtbl_entry != NULL)
1738 return dtbl_entry->initial;
1743 /* Add an entry to a "custom" dissector table. */
1744 void dissector_add_custom_table_handle(const char *name, void *pattern, dissector_handle_t handle)
1746 dissector_table_t sub_dissectors = find_dissector_table(name);
1747 dtbl_entry_t *dtbl_entry;
1750 * Make sure the dissector table exists.
1752 if (sub_dissectors == NULL) {
1753 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
1755 fprintf(stderr, "Protocol being registered is \"%s\"\n",
1756 proto_get_protocol_long_name(handle->protocol));
1757 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1762 g_assert(sub_dissectors->type == FT_BYTES);
1764 dtbl_entry = (dtbl_entry_t *)g_malloc(sizeof (dtbl_entry_t));
1765 dtbl_entry->current = handle;
1766 dtbl_entry->initial = dtbl_entry->current;
1768 /* do the table insertion */
1769 g_hash_table_insert(sub_dissectors->hash_table, (gpointer)pattern,
1770 (gpointer)dtbl_entry);
1773 * Now, if this table supports "Decode As", add this handle
1774 * to the list of handles that could be used for "Decode As"
1775 * with this table, because it *is* being used with this table.
1777 if (sub_dissectors->supports_decode_as)
1778 dissector_add_for_decode_as(name, handle);
1781 dissector_handle_t dissector_get_custom_table_handle(dissector_table_t sub_dissectors, void *key)
1783 dtbl_entry_t *dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, key);
1785 if (dtbl_entry != NULL)
1786 return dtbl_entry->current;
1790 /* Add an entry to a guid dissector table. */
1791 void dissector_add_guid(const char *name, guid_key* guid_val, dissector_handle_t handle)
1793 dissector_table_t sub_dissectors;
1794 dtbl_entry_t *dtbl_entry;
1796 sub_dissectors = find_dissector_table(name);
1799 * Make sure the handle and the dissector table exist.
1801 if (handle == NULL) {
1802 fprintf(stderr, "OOPS: handle to register \"%s\" to doesn't exist\n",
1804 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1808 if (sub_dissectors == NULL) {
1809 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
1811 fprintf(stderr, "Protocol being registered is \"%s\"\n",
1812 proto_get_protocol_long_name(handle->protocol));
1813 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1818 if (sub_dissectors->type != FT_GUID) {
1819 g_assert_not_reached();
1822 dtbl_entry = (dtbl_entry_t *)g_malloc(sizeof (dtbl_entry_t));
1823 dtbl_entry->current = handle;
1824 dtbl_entry->initial = dtbl_entry->current;
1826 /* do the table insertion */
1827 g_hash_table_insert(sub_dissectors->hash_table,
1828 guid_val, (gpointer)dtbl_entry);
1831 * Now, if this table supports "Decode As", add this handle
1832 * to the list of handles that could be used for "Decode As"
1833 * with this table, because it *is* being used with this table.
1835 if (sub_dissectors->supports_decode_as)
1836 dissector_add_for_decode_as(name, handle);
1839 /* Look for a given value in a given guid dissector table and, if found,
1840 call the dissector with the arguments supplied, and return TRUE,
1841 otherwise return FALSE. */
1842 int dissector_try_guid_new(dissector_table_t sub_dissectors,
1843 guid_key* guid_val, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const gboolean add_proto_name, void *data)
1845 dtbl_entry_t *dtbl_entry;
1846 struct dissector_handle *handle;
1849 dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, guid_val);
1850 if (dtbl_entry != NULL) {
1852 * Is there currently a dissector handle for this entry?
1854 handle = dtbl_entry->current;
1855 if (handle == NULL) {
1857 * No - pretend this dissector didn't exist,
1858 * so that other dissectors might have a chance
1859 * to dissect this packet.
1865 * Save the current value of "pinfo->match_uint",
1866 * set it to the uint_val that matched, call the
1867 * dissector, and restore "pinfo->match_uint".
1869 len = call_dissector_work(handle, tvb, pinfo, tree, add_proto_name, data);
1872 * If a new-style dissector returned 0, it means that
1873 * it didn't think this tvbuff represented a packet for
1874 * its protocol, and didn't dissect anything.
1876 * Old-style dissectors can't reject the packet.
1878 * 0 is also returned if the protocol wasn't enabled.
1880 * If the packet was rejected, we return 0, so that
1881 * other dissectors might have a chance to dissect this
1882 * packet, otherwise we return the dissected length.
1889 int dissector_try_guid(dissector_table_t sub_dissectors,
1890 guid_key* guid_val, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1892 return dissector_try_guid_new(sub_dissectors, guid_val, tvb, pinfo, tree, TRUE, NULL);
1895 /** Look for a given value in a given guid dissector table and, if found,
1896 * return the current dissector handle for that value.
1898 * @param[in] sub_dissectors Dissector table to search.
1899 * @param[in] uint_val Value to match, e.g. the port number for the TCP dissector.
1900 * @return The matching dissector handle on success, NULL if no match is found.
1902 dissector_handle_t dissector_get_guid_handle(
1903 dissector_table_t const sub_dissectors, guid_key* guid_val)
1905 dtbl_entry_t *dtbl_entry;
1907 dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, guid_val);
1908 if (dtbl_entry != NULL)
1909 return dtbl_entry->current;
1914 /* Use the currently assigned payload dissector for the dissector table and,
1915 if any, call the dissector with the arguments supplied, and return the
1916 number of bytes consumed, otherwise return 0. */
1917 int dissector_try_payload(dissector_table_t sub_dissectors,
1918 tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1920 return dissector_try_uint(sub_dissectors, 0, tvb, pinfo, tree);
1923 /* Use the currently assigned payload dissector for the dissector table and,
1924 if any, call the dissector with the arguments supplied, and return the
1925 number of bytes consumed, otherwise return 0. */
1926 int dissector_try_payload_new(dissector_table_t sub_dissectors,
1927 tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const gboolean add_proto_name, void *data)
1929 return dissector_try_uint_new(sub_dissectors, 0, tvb, pinfo, tree, add_proto_name, data);
1932 /* Change the entry for a dissector in a payload (FT_NONE) dissector table
1933 with a particular pattern to use a new dissector handle. */
1934 void dissector_change_payload(const char *name, dissector_handle_t handle)
1936 dissector_change_uint(name, 0, handle);
1939 /* Reset payload (FT_NONE) dissector table to its initial value. */
1940 void dissector_reset_payload(const char *name)
1942 dissector_reset_uint(name, 0);
1946 dtbl_entry_get_handle (dtbl_entry_t *dtbl_entry)
1948 return dtbl_entry->current;
1952 dissector_compare_filter_name(gconstpointer dissector_a, gconstpointer dissector_b)
1954 const struct dissector_handle *a = (const struct dissector_handle *)dissector_a;
1955 const struct dissector_handle *b = (const struct dissector_handle *)dissector_b;
1956 const char *a_name, *b_name;
1959 if (a->protocol == NULL)
1962 a_name = proto_get_protocol_filter_name(proto_get_id(a->protocol));
1964 if (b->protocol == NULL)
1967 b_name = proto_get_protocol_filter_name(proto_get_id(b->protocol));
1969 ret = strcmp(a_name, b_name);
1973 /* Add a handle to the list of handles that *could* be used with this
1974 table. That list is used by the "Decode As"/"-d" code in the UI. */
1976 dissector_add_for_decode_as(const char *name, dissector_handle_t handle)
1978 dissector_table_t sub_dissectors = find_dissector_table(name);
1980 dissector_handle_t dup_handle;
1983 * Make sure the dissector table exists.
1985 if (sub_dissectors == NULL) {
1986 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
1988 fprintf(stderr, "Protocol being registered is \"%s\"\n",
1989 proto_get_protocol_long_name(handle->protocol));
1990 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1996 * Make sure it supports Decode As.
1998 if (!sub_dissectors->supports_decode_as) {
1999 const char *dissector_name;
2001 dissector_name = dissector_handle_get_dissector_name(handle);
2002 if (dissector_name == NULL)
2003 dissector_name = "(anonymous)";
2004 fprintf(stderr, "Registering dissector %s for protocol %s in dissector table %s, which doesn't support Decode As\n",
2006 proto_get_protocol_short_name(handle->protocol),
2008 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
2013 /* Add the dissector as a dependency
2014 (some dissector tables don't have protocol association, so there is
2015 the need for the NULL check */
2016 if (sub_dissectors->protocol != NULL)
2017 register_depend_dissector(proto_get_protocol_short_name(sub_dissectors->protocol), proto_get_protocol_short_name(handle->protocol));
2019 /* Is it already in this list? */
2020 entry = g_slist_find(sub_dissectors->dissector_handles, (gpointer)handle);
2021 if (entry != NULL) {
2023 * Yes - don't insert it again.
2028 /* Ensure the protocol is unique. This prevents confusion when
2029 using Decode As with duplicative entries.
2031 FT_STRING can at least show the string value in the dialog,
2032 so we don't do the check for them. */
2033 if (sub_dissectors->type != FT_STRING)
2035 for (entry = sub_dissectors->dissector_handles; entry != NULL; entry = g_slist_next(entry))
2037 dup_handle = (dissector_handle_t)entry->data;
2038 if (dup_handle->protocol == handle->protocol)
2040 const char *dissector_name, *dup_dissector_name;
2042 dissector_name = dissector_handle_get_dissector_name(handle);
2043 if (dissector_name == NULL)
2044 dissector_name = "(anonymous)";
2045 dup_dissector_name = dissector_handle_get_dissector_name(dup_handle);
2046 if (dup_dissector_name == NULL)
2047 dup_dissector_name = "(anonymous)";
2048 fprintf(stderr, "Duplicate dissectors %s and %s for protocol %s in dissector table %s\n",
2049 dissector_name, dup_dissector_name,
2050 proto_get_protocol_short_name(handle->protocol),
2052 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
2058 /* Add it to the list. */
2059 sub_dissectors->dissector_handles =
2060 g_slist_insert_sorted(sub_dissectors->dissector_handles, (gpointer)handle, (GCompareFunc)dissector_compare_filter_name);
2063 void dissector_add_for_decode_as_with_preference(const char *name,
2064 dissector_handle_t handle)
2066 /* If a dissector is added for Decode As only, it's dissector
2067 table value would default to 0.
2068 Set up a preference value with that information
2070 dissector_add_preference(name, handle, 0);
2072 dissector_add_for_decode_as(name, handle);
2076 dtbl_entry_get_initial_handle (dtbl_entry_t *dtbl_entry)
2078 return dtbl_entry->initial;
2082 dissector_table_get_dissector_handles(dissector_table_t dissector_table) {
2083 if (!dissector_table)
2086 return dissector_table->dissector_handles;
2090 * Data structure used as user data when iterating dissector handles
2092 typedef struct lookup_entry {
2093 const gchar* dissector_short_name;
2094 dissector_handle_t handle;
2098 * A callback function to changed a dissector_handle if matched
2099 * This is used when iterating a dissector table
2102 find_dissector_in_table(gpointer item, gpointer user_data)
2104 dissector_handle_t handle = (dissector_handle_t)item;
2105 lookup_entry_t * lookup = (lookup_entry_t *)user_data;
2106 const gchar *proto_short_name = dissector_handle_get_short_name(handle);
2107 if (proto_short_name && strcmp(lookup->dissector_short_name, proto_short_name) == 0) {
2108 lookup->handle = handle;
2112 dissector_handle_t dissector_table_get_dissector_handle(dissector_table_t dissector_table, const gchar* short_name)
2114 lookup_entry_t lookup;
2116 lookup.dissector_short_name = short_name;
2117 lookup.handle = NULL;
2119 g_slist_foreach(dissector_table->dissector_handles, find_dissector_in_table, &lookup);
2120 return lookup.handle;
2124 dissector_table_get_type(dissector_table_t dissector_table) {
2125 if (!dissector_table) return FT_NONE;
2126 return dissector_table->type;
2130 dissector_table_allow_decode_as(dissector_table_t dissector_table)
2132 dissector_table->supports_decode_as = TRUE;
2136 uuid_equal(gconstpointer k1, gconstpointer k2)
2138 const guid_key *key1 = (const guid_key *)k1;
2139 const guid_key *key2 = (const guid_key *)k2;
2140 return ((memcmp(&key1->guid, &key2->guid, sizeof (e_guid_t)) == 0)
2141 && (key1->ver == key2->ver));
2145 uuid_hash(gconstpointer k)
2147 const guid_key *key = (const guid_key *)k;
2148 /* This isn't perfect, but the Data1 part of these is almost always
2150 return key->guid.data1;
2153 /**************************************************/
2155 /* Routines to walk dissector tables */
2157 /**************************************************/
2159 typedef struct dissector_foreach_info {
2160 gpointer caller_data;
2161 DATFunc caller_func;
2163 const gchar *table_name;
2164 ftenum_t selector_type;
2165 } dissector_foreach_info_t;
2168 * Called for each entry in a dissector table.
2171 dissector_table_foreach_func (gpointer key, gpointer value, gpointer user_data)
2173 dissector_foreach_info_t *info;
2174 dtbl_entry_t *dtbl_entry;
2177 g_assert(user_data);
2179 dtbl_entry = (dtbl_entry_t *)value;
2180 if (dtbl_entry->current == NULL ||
2181 dtbl_entry->current->protocol == NULL) {
2183 * Either there is no dissector for this entry, or
2184 * the dissector doesn't have a protocol associated
2187 * XXX - should the latter check be done?
2192 info = (dissector_foreach_info_t *)user_data;
2193 info->caller_func(info->table_name, info->selector_type, key, value,
2198 * Called for each entry in the table of all dissector tables.
2201 dissector_all_tables_foreach_func (gpointer key, gpointer value, gpointer user_data)
2203 dissector_table_t sub_dissectors;
2204 dissector_foreach_info_t *info;
2207 g_assert(user_data);
2209 sub_dissectors = (dissector_table_t)value;
2210 info = (dissector_foreach_info_t *)user_data;
2211 info->table_name = (gchar*) key;
2212 info->selector_type = get_dissector_table_selector_type(info->table_name);
2213 g_hash_table_foreach(sub_dissectors->hash_table, info->next_func, info);
2217 * Walk all dissector tables calling a user supplied function on each
2221 dissector_all_tables_foreach (DATFunc func,
2224 dissector_foreach_info_t info;
2226 info.caller_data = user_data;
2227 info.caller_func = func;
2228 info.next_func = dissector_table_foreach_func;
2229 g_hash_table_foreach(dissector_tables, dissector_all_tables_foreach_func, &info);
2233 * Walk one dissector table's hash table calling a user supplied function
2237 dissector_table_foreach (const char *table_name,
2241 dissector_foreach_info_t info;
2242 dissector_table_t sub_dissectors = find_dissector_table(table_name);
2244 info.table_name = table_name;
2245 info.selector_type = sub_dissectors->type;
2246 info.caller_func = func;
2247 info.caller_data = user_data;
2248 g_hash_table_foreach(sub_dissectors->hash_table, dissector_table_foreach_func, &info);
2252 * Walk one dissector table's list of handles calling a user supplied
2253 * function on each entry.
2256 dissector_table_foreach_handle(const char *table_name,
2257 DATFunc_handle func,
2260 dissector_table_t sub_dissectors = find_dissector_table(table_name);
2263 for (tmp = sub_dissectors->dissector_handles; tmp != NULL;
2264 tmp = g_slist_next(tmp))
2265 func(table_name, tmp->data, user_data);
2269 * Called for each entry in a dissector table.
2272 dissector_table_foreach_changed_func (gpointer key, gpointer value, gpointer user_data)
2274 dtbl_entry_t *dtbl_entry;
2275 dissector_foreach_info_t *info;
2278 g_assert(user_data);
2280 dtbl_entry = (dtbl_entry_t *)value;
2281 if (dtbl_entry->initial == dtbl_entry->current) {
2283 * Entry hasn't changed - don't call the function.
2288 info = (dissector_foreach_info_t *)user_data;
2289 info->caller_func(info->table_name, info->selector_type, key, value,
2294 * Walk all dissector tables calling a user supplied function only on
2295 * any entry that has been changed from its original state.
2298 dissector_all_tables_foreach_changed (DATFunc func,
2301 dissector_foreach_info_t info;
2303 info.caller_data = user_data;
2304 info.caller_func = func;
2305 info.next_func = dissector_table_foreach_changed_func;
2306 g_hash_table_foreach(dissector_tables, dissector_all_tables_foreach_func, &info);
2310 * Walk one dissector table calling a user supplied function only on
2311 * any entry that has been changed from its original state.
2314 dissector_table_foreach_changed (const char *table_name,
2318 dissector_foreach_info_t info;
2319 dissector_table_t sub_dissectors = find_dissector_table(table_name);
2321 info.table_name = table_name;
2322 info.selector_type = sub_dissectors->type;
2323 info.caller_func = func;
2324 info.caller_data = user_data;
2325 g_hash_table_foreach(sub_dissectors->hash_table,
2326 dissector_table_foreach_changed_func, &info);
2329 typedef struct dissector_foreach_table_info {
2330 gpointer caller_data;
2331 DATFunc_table caller_func;
2332 } dissector_foreach_table_info_t;
2335 * Called for each entry in the table of all dissector tables.
2336 * This is used if we directly process the hash table.
2339 dissector_all_tables_foreach_table_func (gpointer key, gpointer value, gpointer user_data)
2341 dissector_table_t table;
2342 dissector_foreach_table_info_t *info;
2344 table = (dissector_table_t)value;
2345 info = (dissector_foreach_table_info_t *)user_data;
2346 (*info->caller_func)((gchar *)key, table->ui_name, info->caller_data);
2350 * Called for each key in the table of all dissector tables.
2351 * This is used if we get a list of table names, sort it, and process the list.
2354 dissector_all_tables_foreach_list_func (gpointer key, gpointer user_data)
2356 dissector_table_t table;
2357 dissector_foreach_table_info_t *info;
2359 table = (dissector_table_t)g_hash_table_lookup(dissector_tables, key);
2360 info = (dissector_foreach_table_info_t *)user_data;
2361 (*info->caller_func)((gchar*)key, table->ui_name, info->caller_data);
2365 * Walk all dissector tables calling a user supplied function on each
2369 dissector_all_tables_foreach_table (DATFunc_table func,
2371 GCompareFunc compare_key_func)
2373 dissector_foreach_table_info_t info;
2376 info.caller_data = user_data;
2377 info.caller_func = func;
2378 if (compare_key_func != NULL)
2380 list = g_hash_table_get_keys(dissector_tables);
2381 list = g_list_sort(list, compare_key_func);
2382 g_list_foreach(list, dissector_all_tables_foreach_list_func, &info);
2387 g_hash_table_foreach(dissector_tables, dissector_all_tables_foreach_table_func, &info);
2392 register_dissector_table(const char *name, const char *ui_name, const int proto, const ftenum_t type,
2395 dissector_table_t sub_dissectors;
2397 /* Make sure the registration is unique */
2398 if (g_hash_table_lookup(dissector_tables, name)) {
2399 g_error("The dissector table %s (%s) is already registered - are you using a buggy plugin?", name, ui_name);
2402 /* Create and register the dissector table for this name; returns */
2403 /* a pointer to the dissector table. */
2404 sub_dissectors = g_slice_new(struct dissector_table);
2412 * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
2413 * so we use "g_direct_hash()" and "g_direct_equal()".
2415 sub_dissectors->hash_func = g_direct_hash;
2416 sub_dissectors->hash_table = g_hash_table_new_full(g_direct_hash,
2425 sub_dissectors->hash_func = g_str_hash;
2426 sub_dissectors->hash_table = g_hash_table_new_full(g_str_hash,
2432 sub_dissectors->hash_table = g_hash_table_new_full(uuid_hash,
2439 /* Dissector tables with FT_NONE don't have values associated with
2440 dissectors so this will always be a hash table size of 1 just
2441 to store the single dtbl_entry_t */
2442 sub_dissectors->hash_func = g_direct_hash;
2443 sub_dissectors->hash_table = g_hash_table_new_full(g_direct_hash,
2450 g_error("The dissector table %s (%s) is registering an unsupported type - are you using a buggy plugin?", name, ui_name);
2451 g_assert_not_reached();
2453 sub_dissectors->dissector_handles = NULL;
2454 sub_dissectors->ui_name = ui_name;
2455 sub_dissectors->type = type;
2456 sub_dissectors->param = param;
2457 sub_dissectors->protocol = find_protocol_by_id(proto);
2458 sub_dissectors->supports_decode_as = FALSE;
2459 g_hash_table_insert(dissector_tables, (gpointer)name, (gpointer) sub_dissectors);
2460 return sub_dissectors;
2463 dissector_table_t register_custom_dissector_table(const char *name,
2464 const char *ui_name, const int proto, GHashFunc hash_func, GEqualFunc key_equal_func)
2466 dissector_table_t sub_dissectors;
2468 /* Make sure the registration is unique */
2469 if (g_hash_table_lookup(dissector_tables, name)) {
2470 g_error("The dissector table %s (%s) is already registered - are you using a buggy plugin?", name, ui_name);
2473 /* Create and register the dissector table for this name; returns */
2474 /* a pointer to the dissector table. */
2475 sub_dissectors = g_slice_new(struct dissector_table);
2476 sub_dissectors->hash_func = hash_func;
2477 sub_dissectors->hash_table = g_hash_table_new_full(hash_func,
2482 sub_dissectors->dissector_handles = NULL;
2483 sub_dissectors->ui_name = ui_name;
2484 sub_dissectors->type = FT_BYTES; /* Consider key a "blob" of data, no need to really create new type */
2485 sub_dissectors->param = BASE_NONE;
2486 sub_dissectors->protocol = find_protocol_by_id(proto);
2487 sub_dissectors->supports_decode_as = FALSE;
2488 g_hash_table_insert(dissector_tables, (gpointer)name, (gpointer) sub_dissectors);
2489 return sub_dissectors;
2493 register_dissector_table_alias(dissector_table_t dissector_table, const char *alias_name) {
2494 if (!dissector_table || !alias_name) return;
2496 const char *name = NULL;
2497 GList *list = g_hash_table_get_keys(dissector_tables);
2498 for (GList *cur = list; cur; cur = cur->next) {
2499 if (g_hash_table_lookup(dissector_tables, cur->data) == dissector_table) {
2500 name = (const char *) cur->data;
2507 g_hash_table_insert(dissector_table_aliases, (gpointer) alias_name, (gpointer) name);
2511 deregister_dissector_table(const char *name)
2513 dissector_table_t sub_dissectors = (dissector_table_t) g_hash_table_lookup(dissector_tables, name);
2514 if (!sub_dissectors) return;
2516 g_hash_table_remove(dissector_tables, name);
2518 GList *list = g_hash_table_get_keys(dissector_table_aliases);
2519 for (GList *cur = list; cur; cur = cur->next) {
2520 gpointer alias_name = cur->data;
2521 if (g_hash_table_lookup(dissector_table_aliases, alias_name) == name) {
2522 g_hash_table_remove(dissector_table_aliases, alias_name);
2529 get_dissector_table_ui_name(const char *name)
2531 dissector_table_t sub_dissectors = find_dissector_table(name);
2532 if (!sub_dissectors) return NULL;
2534 return sub_dissectors->ui_name;
2538 get_dissector_table_selector_type(const char *name)
2540 dissector_table_t sub_dissectors = find_dissector_table(name);
2541 if (!sub_dissectors) return FT_NONE;
2543 return sub_dissectors->type;
2547 get_dissector_table_param(const char *name)
2549 dissector_table_t sub_dissectors = find_dissector_table(name);
2550 if (!sub_dissectors) return 0;
2552 return sub_dissectors->param;
2555 /* Finds a heuristic dissector table by table name. */
2556 heur_dissector_list_t
2557 find_heur_dissector_list(const char *name)
2559 return (heur_dissector_list_t)g_hash_table_lookup(heur_dissector_lists, name);
2563 has_heur_dissector_list(const gchar *name) {
2564 return (find_heur_dissector_list(name) != NULL);
2567 heur_dtbl_entry_t* find_heur_dissector_by_unique_short_name(const char *short_name)
2569 return (heur_dtbl_entry_t*)g_hash_table_lookup(heuristic_short_names, short_name);
2573 heur_dissector_add(const char *name, heur_dissector_t dissector, const char *display_name, const char *short_name, const int proto, heuristic_enable_e enable)
2575 heur_dissector_list_t sub_dissectors = find_heur_dissector_list(name);
2576 const char *proto_name;
2577 heur_dtbl_entry_t *hdtbl_entry;
2582 * Make sure the dissector table exists.
2584 if (sub_dissectors == NULL) {
2585 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
2587 proto_name = proto_get_protocol_name(proto);
2588 if (proto_name != NULL) {
2589 fprintf(stderr, "Protocol being registered is \"%s\"\n",
2592 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
2597 /* Verify that sub-dissector is not already in the list */
2598 list_size = g_slist_length(sub_dissectors->dissectors);
2599 for (i = 0; i < list_size; i++)
2601 list_entry = g_slist_nth(sub_dissectors->dissectors, i);
2602 hdtbl_entry = (heur_dtbl_entry_t *)list_entry->data;
2603 if ((hdtbl_entry->dissector == dissector) &&
2604 (hdtbl_entry->protocol == find_protocol_by_id(proto)))
2606 proto_name = proto_get_protocol_name(proto);
2607 if (proto_name != NULL) {
2608 fprintf(stderr, "Protocol %s is already registered in \"%s\" table\n",
2611 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
2617 /* Ensure short_name is unique */
2618 if (g_hash_table_lookup(heuristic_short_names, short_name) != NULL) {
2619 g_error("Duplicate heuristic short_name \"%s\"!"
2620 " This might be caused by an inappropriate plugin or a development error.", short_name);
2623 hdtbl_entry = g_slice_new(heur_dtbl_entry_t);
2624 hdtbl_entry->dissector = dissector;
2625 hdtbl_entry->protocol = find_protocol_by_id(proto);
2626 hdtbl_entry->display_name = display_name;
2627 hdtbl_entry->short_name = g_strdup(short_name);
2628 hdtbl_entry->list_name = g_strdup(name);
2629 hdtbl_entry->enabled = (enable == HEURISTIC_ENABLE);
2631 /* do the table insertion */
2632 g_hash_table_insert(heuristic_short_names, (gpointer)hdtbl_entry->short_name, hdtbl_entry);
2634 sub_dissectors->dissectors = g_slist_prepend(sub_dissectors->dissectors,
2635 (gpointer)hdtbl_entry);
2637 /* XXX - could be optimized to pass hdtbl_entry directly */
2638 proto_add_heuristic_dissector(hdtbl_entry->protocol, hdtbl_entry->short_name);
2640 /* Add the dissector as a dependency
2641 (some heuristic tables don't have protocol association, so there is
2642 the need for the NULL check */
2643 if (sub_dissectors->protocol != NULL)
2644 register_depend_dissector(proto_get_protocol_short_name(sub_dissectors->protocol), proto_get_protocol_short_name(hdtbl_entry->protocol));
2650 find_matching_heur_dissector(gconstpointer a, gconstpointer b) {
2651 const heur_dtbl_entry_t *hdtbl_entry_a = (const heur_dtbl_entry_t *) a;
2652 const heur_dtbl_entry_t *hdtbl_entry_b = (const heur_dtbl_entry_t *) b;
2654 return (hdtbl_entry_a->dissector == hdtbl_entry_b->dissector) &&
2655 (hdtbl_entry_a->protocol == hdtbl_entry_b->protocol) ? 0 : 1;
2659 heur_dissector_delete(const char *name, heur_dissector_t dissector, const int proto) {
2660 heur_dissector_list_t sub_dissectors = find_heur_dissector_list(name);
2661 heur_dtbl_entry_t hdtbl_entry;
2662 GSList *found_entry;
2665 g_assert(sub_dissectors != NULL);
2667 hdtbl_entry.dissector = dissector;
2668 hdtbl_entry.protocol = find_protocol_by_id(proto);
2670 found_entry = g_slist_find_custom(sub_dissectors->dissectors,
2671 (gpointer) &hdtbl_entry, find_matching_heur_dissector);
2674 heur_dtbl_entry_t *found_hdtbl_entry = (heur_dtbl_entry_t *)(found_entry->data);
2675 g_free(found_hdtbl_entry->list_name);
2676 g_hash_table_remove(heuristic_short_names, found_hdtbl_entry->short_name);
2677 g_free(found_hdtbl_entry->short_name);
2678 g_slice_free(heur_dtbl_entry_t, found_entry->data);
2679 sub_dissectors->dissectors = g_slist_delete_link(sub_dissectors->dissectors,
2685 dissector_try_heuristic(heur_dissector_list_t sub_dissectors, tvbuff_t *tvb,
2686 packet_info *pinfo, proto_tree *tree, heur_dtbl_entry_t **heur_dtbl_entry, void *data)
2689 const char *saved_curr_proto;
2690 const char *saved_heur_list_name;
2692 guint16 saved_can_desegment;
2693 guint saved_layers_len = 0;
2694 heur_dtbl_entry_t *hdtbl_entry;
2697 int saved_tree_count = tree ? tree->tree_data->count : 0;
2699 /* can_desegment is set to 2 by anyone which offers this api/service.
2700 then everytime a subdissector is called it is decremented by one.
2701 thus only the subdissector immediately ontop of whoever offers this
2703 We save the current value of "can_desegment" for the
2704 benefit of TCP proxying dissectors such as SOCKS, so they
2705 can restore it and allow the dissectors they call to use
2706 the desegmentation service.
2708 saved_can_desegment = pinfo->can_desegment;
2709 pinfo->saved_can_desegment = saved_can_desegment;
2710 pinfo->can_desegment = saved_can_desegment-(saved_can_desegment>0);
2713 saved_curr_proto = pinfo->current_proto;
2714 saved_heur_list_name = pinfo->heur_list_name;
2716 saved_layers_len = wmem_list_count(pinfo->layers);
2717 *heur_dtbl_entry = NULL;
2719 for (entry = sub_dissectors->dissectors; entry != NULL;
2720 entry = g_slist_next(entry)) {
2721 /* XXX - why set this now and above? */
2722 pinfo->can_desegment = saved_can_desegment-(saved_can_desegment>0);
2723 hdtbl_entry = (heur_dtbl_entry_t *)entry->data;
2725 if (hdtbl_entry->protocol != NULL &&
2726 (!proto_is_protocol_enabled(hdtbl_entry->protocol)||(hdtbl_entry->enabled==FALSE))) {
2728 * No - don't try this dissector.
2733 if (hdtbl_entry->protocol != NULL) {
2734 proto_id = proto_get_id(hdtbl_entry->protocol);
2735 /* do NOT change this behavior - wslua uses the protocol short name set here in order
2736 to determine which Lua-based heurisitc dissector to call */
2737 pinfo->current_proto =
2738 proto_get_protocol_short_name(hdtbl_entry->protocol);
2741 * Add the protocol name to the layers; we'll remove it
2742 * if the dissector fails.
2744 pinfo->curr_layer_num++;
2745 wmem_list_append(pinfo->layers, GINT_TO_POINTER(proto_id));
2748 pinfo->heur_list_name = hdtbl_entry->list_name;
2750 len = (hdtbl_entry->dissector)(tvb, pinfo, tree, data);
2751 if (hdtbl_entry->protocol != NULL &&
2752 (len == 0 || (tree && saved_tree_count == tree->tree_data->count))) {
2754 * We added a protocol layer above. The dissector
2755 * didn't accept the packet or it didn't add any
2756 * items to the tree so remove it from the list.
2758 while (wmem_list_count(pinfo->layers) > saved_layers_len) {
2759 pinfo->curr_layer_num--;
2760 wmem_list_remove_frame(pinfo->layers, wmem_list_tail(pinfo->layers));
2764 *heur_dtbl_entry = hdtbl_entry;
2770 pinfo->current_proto = saved_curr_proto;
2771 pinfo->heur_list_name = saved_heur_list_name;
2772 pinfo->can_desegment = saved_can_desegment;
2776 typedef struct heur_dissector_foreach_info {
2777 gpointer caller_data;
2778 DATFunc_heur caller_func;
2780 const gchar *table_name;
2781 } heur_dissector_foreach_info_t;
2784 * Called for each entry in a heuristic dissector table.
2787 heur_dissector_table_foreach_func (gpointer data, gpointer user_data)
2789 heur_dissector_foreach_info_t *info;
2792 g_assert(user_data);
2794 info = (heur_dissector_foreach_info_t *)user_data;
2795 info->caller_func(info->table_name, (heur_dtbl_entry_t *)data,
2800 * Walk one heuristic dissector table's list calling a user supplied function
2804 heur_dissector_table_foreach (const char *table_name,
2808 heur_dissector_foreach_info_t info;
2809 heur_dissector_list_t sub_dissectors = find_heur_dissector_list(table_name);
2811 info.table_name = table_name;
2812 info.caller_func = func;
2813 info.caller_data = user_data;
2814 g_slist_foreach(sub_dissectors->dissectors,
2815 heur_dissector_table_foreach_func, &info);
2819 * Called for each entry in the table of all heuristic dissector tables.
2821 typedef struct heur_dissector_foreach_table_info {
2822 gpointer caller_data;
2823 DATFunc_heur_table caller_func;
2824 } heur_dissector_foreach_table_info_t;
2827 * Called for each entry in the table of all heuristic dissector tables.
2828 * This is used if we directly process the hash table.
2831 dissector_all_heur_tables_foreach_table_func (gpointer key, gpointer value, gpointer user_data)
2833 heur_dissector_foreach_table_info_t *info;
2835 info = (heur_dissector_foreach_table_info_t *)user_data;
2836 (*info->caller_func)((gchar *)key, (struct heur_dissector_list *)value, info->caller_data);
2840 * Called for each key in the table of all dissector tables.
2841 * This is used if we get a list of table names, sort it, and process the list.
2844 dissector_all_heur_tables_foreach_list_func (gpointer key, gpointer user_data)
2846 struct heur_dissector_list *list;
2847 heur_dissector_foreach_table_info_t *info;
2849 list = (struct heur_dissector_list *)g_hash_table_lookup(heur_dissector_lists, key);
2850 info = (heur_dissector_foreach_table_info_t *)user_data;
2851 (*info->caller_func)((gchar*)key, list, info->caller_data);
2855 * Walk all heuristic dissector tables calling a user supplied function on each
2859 dissector_all_heur_tables_foreach_table (DATFunc_heur_table func,
2861 GCompareFunc compare_key_func)
2863 heur_dissector_foreach_table_info_t info;
2866 info.caller_data = user_data;
2867 info.caller_func = func;
2868 if (compare_key_func != NULL)
2870 list = g_hash_table_get_keys(dissector_tables);
2871 list = g_list_sort(list, compare_key_func);
2872 g_list_foreach(list, dissector_all_heur_tables_foreach_list_func, &info);
2877 g_hash_table_foreach(heur_dissector_lists, dissector_all_heur_tables_foreach_table_func, &info);
2882 display_heur_dissector_table_entries(const char *table_name,
2883 heur_dtbl_entry_t *hdtbl_entry, gpointer user_data _U_)
2885 if (hdtbl_entry->protocol != NULL) {
2886 ws_debug_printf("%s\t%s\t%c\n",
2888 proto_get_protocol_filter_name(proto_get_id(hdtbl_entry->protocol)),
2889 (proto_is_protocol_enabled(hdtbl_entry->protocol) && hdtbl_entry->enabled) ? 'T' : 'F');
2894 dissector_dump_heur_decodes_display(const gchar *table_name, struct heur_dissector_list *listptr _U_, gpointer user_data _U_)
2896 heur_dissector_table_foreach(table_name, display_heur_dissector_table_entries, NULL);
2900 * For each heuristic dissector table, dump list of dissectors (filter_names) for that table
2903 dissector_dump_heur_decodes(void)
2905 dissector_all_heur_tables_foreach_table(dissector_dump_heur_decodes_display, NULL, NULL);
2909 heur_dissector_list_t
2910 register_heur_dissector_list(const char *name, const int proto)
2912 heur_dissector_list_t sub_dissectors;
2914 /* Make sure the registration is unique */
2915 if (g_hash_table_lookup(heur_dissector_lists, name) != NULL) {
2916 g_error("The heuristic dissector list %s is already registered - are you using a buggy plugin?", name);
2919 /* Create and register the dissector table for this name; returns */
2920 /* a pointer to the dissector table. */
2921 sub_dissectors = g_slice_new(struct heur_dissector_list);
2922 sub_dissectors->protocol = find_protocol_by_id(proto);
2923 sub_dissectors->dissectors = NULL; /* initially empty */
2924 g_hash_table_insert(heur_dissector_lists, (gpointer)name,
2925 (gpointer) sub_dissectors);
2926 return sub_dissectors;
2930 * Register dissectors by name; used if one dissector always calls a
2931 * particular dissector, or if it bases the decision of which dissector
2932 * to call on something other than a numerical value or on "try a bunch
2933 * of dissectors until one likes the packet".
2936 /* Get the long name of the protocol for a dissector handle, if it has
2939 dissector_handle_get_long_name(const dissector_handle_t handle)
2941 if (handle == NULL || handle->protocol == NULL) {
2944 return proto_get_protocol_long_name(handle->protocol);
2947 /* Get the short name of the protocol for a dissector handle, if it has
2950 dissector_handle_get_short_name(const dissector_handle_t handle)
2952 if (handle->protocol == NULL) {
2954 * No protocol (see, for example, the handle for
2955 * dissecting the set of protocols where the first
2956 * octet of the payload is an OSI network layer protocol
2961 return proto_get_protocol_short_name(handle->protocol);
2964 /* Get the index of the protocol for a dissector handle, if it has
2967 dissector_handle_get_protocol_index(const dissector_handle_t handle)
2969 if (handle->protocol == NULL) {
2971 * No protocol (see, for example, the handle for
2972 * dissecting the set of protocols where the first
2973 * octet of the payload is an OSI network layer protocol
2978 return proto_get_id(handle->protocol);
2981 /* Get a GList of all registered dissector names. The content of the list
2982 is owned by the hash table and should not be modified or freed.
2983 Use g_list_free() when done using the list. */
2985 get_dissector_names(void)
2987 return g_hash_table_get_keys(registered_dissectors);
2990 /* Find a registered dissector by name. */
2992 find_dissector(const char *name)
2994 return (dissector_handle_t)g_hash_table_lookup(registered_dissectors, name);
2997 /** Find a dissector by name and add parent protocol as a depedency*/
2998 dissector_handle_t find_dissector_add_dependency(const char *name, const int parent_proto)
3000 dissector_handle_t handle = (dissector_handle_t)g_hash_table_lookup(registered_dissectors, name);
3001 if ((handle != NULL) && (parent_proto > 0))
3003 register_depend_dissector(proto_get_protocol_short_name(find_protocol_by_id(parent_proto)), dissector_handle_get_short_name(handle));
3009 /* Get a dissector name from handle. */
3011 dissector_handle_get_dissector_name(const dissector_handle_t handle)
3013 if (handle == NULL) {
3016 return handle->name;
3019 static dissector_handle_t
3020 new_dissector_handle(enum dissector_e type, void *dissector, const int proto, const char *name, void *cb_data)
3022 struct dissector_handle *handle;
3024 handle = wmem_new(wmem_epan_scope(), struct dissector_handle);
3025 handle->name = name;
3026 handle->dissector_type = type;
3027 handle->dissector_func = dissector;
3028 handle->dissector_data = cb_data;
3029 handle->protocol = find_protocol_by_id(proto);
3033 /* Create an anonymous handle for a new dissector. */
3035 create_dissector_handle(dissector_t dissector, const int proto)
3037 return new_dissector_handle(DISSECTOR_TYPE_SIMPLE, dissector, proto, NULL, NULL);
3041 create_dissector_handle_with_name(dissector_t dissector,
3042 const int proto, const char* name)
3044 return new_dissector_handle(DISSECTOR_TYPE_SIMPLE, dissector, proto, name, NULL);
3047 /* Destroy an anonymous handle for a dissector. */
3049 destroy_dissector_handle(dissector_handle_t handle)
3051 if (handle == NULL) return;
3053 dissector_delete_from_all_tables(handle);
3054 deregister_postdissector(handle);
3055 wmem_free(wmem_epan_scope(), handle);
3058 static dissector_handle_t
3059 register_dissector_handle(const char *name, dissector_handle_t handle)
3061 /* Make sure the registration is unique */
3062 g_assert(g_hash_table_lookup(registered_dissectors, name) == NULL);
3064 g_hash_table_insert(registered_dissectors, (gpointer)name, handle);
3069 /* Register a new dissector by name. */
3071 register_dissector(const char *name, dissector_t dissector, const int proto)
3073 struct dissector_handle *handle;
3075 handle = new_dissector_handle(DISSECTOR_TYPE_SIMPLE, dissector, proto, name, NULL);
3077 return register_dissector_handle(name, handle);
3081 register_dissector_with_data(const char *name, dissector_cb_t dissector, const int proto, void *cb_data)
3083 struct dissector_handle *handle;
3085 handle = new_dissector_handle(DISSECTOR_TYPE_CALLBACK, dissector, proto, name, cb_data);
3087 return register_dissector_handle(name, handle);
3091 remove_depend_dissector_from_list(depend_dissector_list_t sub_dissectors, const char *dependent)
3093 GSList *found_entry;
3095 found_entry = g_slist_find_custom(sub_dissectors->dissectors,
3096 dependent, (GCompareFunc)strcmp);
3099 g_free(found_entry->data);
3100 sub_dissectors->dissectors = g_slist_delete_link(sub_dissectors->dissectors, found_entry);
3108 remove_depend_dissector_ghfunc(gpointer key _U_, gpointer value, gpointer user_data)
3110 depend_dissector_list_t sub_dissectors = (depend_dissector_list_t) value;
3111 const char *dependent = (const char *)user_data;
3113 remove_depend_dissector_from_list(sub_dissectors, dependent);
3116 /* Deregister a dissector by name. */
3118 deregister_dissector(const char *name)
3120 dissector_handle_t handle = find_dissector(name);
3121 if (handle == NULL) return;
3123 g_hash_table_remove(registered_dissectors, name);
3124 g_hash_table_remove(depend_dissector_lists, name);
3125 g_hash_table_foreach(depend_dissector_lists, remove_depend_dissector_ghfunc, (gpointer)name);
3126 g_hash_table_remove(heur_dissector_lists, name);
3128 destroy_dissector_handle(handle);
3131 /* Call a dissector through a handle but if the dissector rejected it
3135 call_dissector_only(dissector_handle_t handle, tvbuff_t *tvb,
3136 packet_info *pinfo, proto_tree *tree, void *data)
3140 g_assert(handle != NULL);
3141 ret = call_dissector_work(handle, tvb, pinfo, tree, TRUE, data);
3145 /* Call a dissector through a handle and if this fails call the "data"
3149 call_dissector_with_data(dissector_handle_t handle, tvbuff_t *tvb,
3150 packet_info *pinfo, proto_tree *tree, void *data)
3154 ret = call_dissector_only(handle, tvb, pinfo, tree, data);
3157 * The protocol was disabled, or the dissector rejected
3158 * it. Just dissect this packet as data.
3160 g_assert(data_handle->protocol != NULL);
3161 call_dissector_work(data_handle, tvb, pinfo, tree, TRUE, NULL);
3162 return tvb_captured_length(tvb);
3168 call_dissector(dissector_handle_t handle, tvbuff_t *tvb,
3169 packet_info *pinfo, proto_tree *tree)
3171 return call_dissector_with_data(handle, tvb, pinfo, tree, NULL);
3175 call_data_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3177 return call_dissector_work(data_handle, tvb, pinfo, tree, TRUE, NULL);
3181 * Call a heuristic dissector through a heur_dtbl_entry
3183 void call_heur_dissector_direct(heur_dtbl_entry_t *heur_dtbl_entry, tvbuff_t *tvb,
3184 packet_info *pinfo, proto_tree *tree, void *data)
3186 const char *saved_curr_proto;
3187 const char *saved_heur_list_name;
3188 guint16 saved_can_desegment;
3189 guint saved_layers_len = 0;
3191 g_assert(heur_dtbl_entry);
3193 /* can_desegment is set to 2 by anyone which offers this api/service.
3194 then everytime a subdissector is called it is decremented by one.
3195 thus only the subdissector immediately ontop of whoever offers this
3197 We save the current value of "can_desegment" for the
3198 benefit of TCP proxying dissectors such as SOCKS, so they
3199 can restore it and allow the dissectors they call to use
3200 the desegmentation service.
3202 saved_can_desegment = pinfo->can_desegment;
3203 pinfo->saved_can_desegment = saved_can_desegment;
3204 pinfo->can_desegment = saved_can_desegment-(saved_can_desegment>0);
3206 saved_curr_proto = pinfo->current_proto;
3207 saved_heur_list_name = pinfo->heur_list_name;
3209 saved_layers_len = wmem_list_count(pinfo->layers);
3211 if (!heur_dtbl_entry->enabled ||
3212 (heur_dtbl_entry->protocol != NULL && !proto_is_protocol_enabled(heur_dtbl_entry->protocol))) {
3213 g_assert(data_handle->protocol != NULL);
3214 call_dissector_work(data_handle, tvb, pinfo, tree, TRUE, NULL);
3218 if (heur_dtbl_entry->protocol != NULL) {
3219 /* do NOT change this behavior - wslua uses the protocol short name set here in order
3220 to determine which Lua-based heuristic dissector to call */
3221 pinfo->current_proto = proto_get_protocol_short_name(heur_dtbl_entry->protocol);
3222 pinfo->curr_layer_num++;
3223 wmem_list_append(pinfo->layers, GINT_TO_POINTER(proto_get_id(heur_dtbl_entry->protocol)));
3226 pinfo->heur_list_name = heur_dtbl_entry->list_name;
3228 /* call the dissector, in case of failure call data handle (might happen with exported PDUs) */
3229 if (!(*heur_dtbl_entry->dissector)(tvb, pinfo, tree, data)) {
3230 call_dissector_work(data_handle, tvb, pinfo, tree, TRUE, NULL);
3233 * We added a protocol layer above. The dissector
3234 * didn't accept the packet or it didn't add any
3235 * items to the tree so remove it from the list.
3237 while (wmem_list_count(pinfo->layers) > saved_layers_len) {
3238 pinfo->curr_layer_num--;
3239 wmem_list_remove_frame(pinfo->layers, wmem_list_tail(pinfo->layers));
3243 /* Restore info from caller */
3244 pinfo->can_desegment = saved_can_desegment;
3245 pinfo->current_proto = saved_curr_proto;
3246 pinfo->heur_list_name = saved_heur_list_name;
3251 find_matching_proto_name(gconstpointer arg1, gconstpointer arg2)
3253 const char *protocol_name = (const char*)arg1;
3254 const gchar *name = (const gchar *)arg2;
3256 return strcmp(protocol_name, name);
3259 gboolean register_depend_dissector(const char* parent, const char* dependent)
3262 depend_dissector_list_t sub_dissectors;
3264 if ((parent == NULL) || (dependent == NULL))
3266 /* XXX - assert on parent? */
3270 sub_dissectors = find_depend_dissector_list(parent);
3271 if (sub_dissectors == NULL) {
3272 /* parent protocol doesn't exist, create it */
3273 sub_dissectors = g_slice_new(struct depend_dissector_list);
3274 sub_dissectors->dissectors = NULL; /* initially empty */
3275 g_hash_table_insert(depend_dissector_lists, (gpointer)g_strdup(parent), (gpointer) sub_dissectors);
3278 /* Verify that sub-dissector is not already in the list */
3279 list_entry = g_slist_find_custom(sub_dissectors->dissectors, (gpointer)dependent, find_matching_proto_name);
3280 if (list_entry != NULL)
3281 return TRUE; /* Dependency already exists */
3283 sub_dissectors->dissectors = g_slist_prepend(sub_dissectors->dissectors, (gpointer)g_strdup(dependent));
3287 gboolean deregister_depend_dissector(const char* parent, const char* dependent)
3289 depend_dissector_list_t sub_dissectors = find_depend_dissector_list(parent);
3292 g_assert(sub_dissectors != NULL);
3294 return remove_depend_dissector_from_list(sub_dissectors, dependent);
3297 depend_dissector_list_t find_depend_dissector_list(const char* name)
3299 return (depend_dissector_list_t)g_hash_table_lookup(depend_dissector_lists, name);
3303 * Dumps the "layer type"/"decode as" associations to stdout, similar
3304 * to the proto_registrar_dump_*() routines.
3306 * There is one record per line. The fields are tab-delimited.
3308 * Field 1 = layer type, e.g. "tcp.port"
3309 * Field 2 = selector in decimal
3310 * Field 3 = "decode as" name, e.g. "http"
3315 dissector_dump_decodes_display(const gchar *table_name,
3316 ftenum_t selector_type _U_, gpointer key, gpointer value,
3317 gpointer user_data _U_)
3319 guint32 selector = GPOINTER_TO_UINT (key);
3320 dissector_table_t sub_dissectors = find_dissector_table(table_name);
3321 dtbl_entry_t *dtbl_entry;
3322 dissector_handle_t handle;
3324 const gchar *decode_as;
3326 g_assert(sub_dissectors);
3327 switch (sub_dissectors->type) {
3333 dtbl_entry = (dtbl_entry_t *)value;
3334 g_assert(dtbl_entry);
3336 handle = dtbl_entry->current;
3339 proto_id = dissector_handle_get_protocol_index(handle);
3341 if (proto_id != -1) {
3342 decode_as = proto_get_protocol_filter_name(proto_id);
3343 g_assert(decode_as != NULL);
3344 ws_debug_printf("%s\t%u\t%s\n", table_name, selector, decode_as);
3354 dissector_dump_decodes(void)
3356 dissector_all_tables_foreach(dissector_dump_decodes_display, NULL);
3360 * Dumps the "layer type"/"decode as" associations to stdout, similar
3361 * to the proto_registrar_dump_*() routines.
3363 * There is one record per line. The fields are tab-delimited.
3365 * Field 1 = layer type, e.g. "tcp.port"
3366 * Field 2 = selector in decimal
3367 * Field 3 = "decode as" name, e.g. "http"
3372 dissector_dump_dissector_tables_display (gpointer key, gpointer user_data _U_)
3374 const char *table_name = (const char *)key;
3375 dissector_table_t table;
3377 table = (dissector_table_t)g_hash_table_lookup(dissector_tables, key);
3378 ws_debug_printf("%s\t%s\t%s", table_name, table->ui_name, ftype_name(table->type));
3379 switch (table->type) {
3385 switch(table->param) {
3388 ws_debug_printf("\tBASE_NONE");
3392 ws_debug_printf("\tBASE_DEC");
3396 ws_debug_printf("\tBASE_HEX");
3400 ws_debug_printf("\tBASE_DEC_HEX");
3404 ws_debug_printf("\tBASE_HEX_DEC");
3408 ws_debug_printf("\t%d", table->param);
3416 if (table->protocol != NULL) {
3417 ws_debug_printf("\t%s",
3418 proto_get_protocol_short_name(table->protocol));
3420 ws_debug_printf("\t(no protocol)");
3421 ws_debug_printf("\tDecode As %ssupported",
3422 table->supports_decode_as ? "" : "not ");
3423 ws_debug_printf("\n");
3427 compare_dissector_key_name(gconstpointer dissector_a, gconstpointer dissector_b)
3429 return strcmp((const char*)dissector_a, (const char*)dissector_b);
3433 dissector_dump_dissector_tables(void)
3437 list = g_hash_table_get_keys(dissector_tables);
3438 list = g_list_sort(list, compare_dissector_key_name);
3439 g_list_foreach(list, dissector_dump_dissector_tables_display, NULL);
3444 register_postdissector(dissector_handle_t handle)
3448 if (!postdissectors)
3449 postdissectors = g_array_sized_new(FALSE, FALSE, (guint)sizeof(postdissector), 1);
3452 p.wanted_hfids = NULL;
3453 postdissectors = g_array_append_val(postdissectors, p);
3457 set_postdissector_wanted_hfids(dissector_handle_t handle, GArray *wanted_hfids)
3461 if (!postdissectors) return;
3463 for (i = 0; i < postdissectors->len; i++) {
3464 if (POSTDISSECTORS(i).handle == handle) {
3465 if (POSTDISSECTORS(i).wanted_hfids) {
3466 g_array_free(POSTDISSECTORS(i).wanted_hfids, TRUE);
3468 POSTDISSECTORS(i).wanted_hfids = wanted_hfids;
3475 deregister_postdissector(dissector_handle_t handle)
3479 if (!postdissectors) return;
3481 for (i = 0; i < postdissectors->len; i++) {
3482 if (POSTDISSECTORS(i).handle == handle) {
3483 if (POSTDISSECTORS(i).wanted_hfids) {
3484 g_array_free(POSTDISSECTORS(i).wanted_hfids, TRUE);
3486 postdissectors = g_array_remove_index_fast(postdissectors, i);
3493 have_postdissector(void)
3496 dissector_handle_t handle;
3498 for (i = 0; i < postdissectors->len; i++) {
3499 handle = POSTDISSECTORS(i).handle;
3501 if (handle->protocol != NULL
3502 && proto_is_protocol_enabled(handle->protocol)) {
3503 /* We have at least one enabled postdissector */
3511 call_all_postdissectors(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3515 for (i = 0; i < postdissectors->len; i++) {
3516 call_dissector_only(POSTDISSECTORS(i).handle,
3517 tvb, pinfo, tree, NULL);
3522 postdissectors_want_hfids(void)
3526 for (i = 0; i < postdissectors->len; i++) {
3527 if (POSTDISSECTORS(i).wanted_hfids != NULL &&
3528 POSTDISSECTORS(i).wanted_hfids->len != 0)
3535 prime_epan_dissect_with_postdissector_wanted_hfids(epan_dissect_t *edt)
3539 if (postdissectors == NULL) {
3541 * No postdissector expressed an interest in any hfids.
3545 for (i = 0; i < postdissectors->len; i++) {
3546 if (POSTDISSECTORS(i).wanted_hfids != NULL &&
3547 POSTDISSECTORS(i).wanted_hfids->len != 0)
3548 epan_dissect_prime_with_hfid_array(edt,
3549 POSTDISSECTORS(i).wanted_hfids);
3554 * Editor modelines - http://www.wireshark.org/tools/modelines.html
3559 * indent-tabs-mode: t
3562 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3563 * :indentSize=8:tabSize=8:noTabs=false: