TODO SMB2 NegotiateContext....
[metze/wireshark/wip.git] / epan / packet.c
1 /* packet.c
2  * Routines for packet disassembly
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10
11 #include "config.h"
12
13 #include <glib.h>
14
15 #include <stdio.h>
16 #include <stdlib.h>
17
18 #include <stdarg.h>
19 #include <string.h>
20 #include <time.h>
21
22 #include "packet.h"
23 #include "timestamp.h"
24
25 #include "osi-utils.h"
26 #include "to_str.h"
27
28 #include "addr_resolv.h"
29 #include "tvbuff.h"
30 #include "epan_dissect.h"
31
32 #include "wmem/wmem.h"
33
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>
40
41 #include <wsutil/str_util.h>
42 #include <wsutil/ws_printf.h> /* ws_debug_printf */
43
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;
48
49 /**
50  * A data source.
51  * Has a tvbuff and a name.
52  */
53 struct data_source {
54         tvbuff_t *tvb;
55         char *name;
56 };
57
58 /*
59  * A dissector table.
60  *
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.
64  *
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
69  * port number.
70  *
71  * "ui_name" is the name the dissector table has in the user interface.
72  *
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.
75  *
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.
79  *
80  * "protocol" is the protocol associated with the dissector table. Used
81  * for determining dependencies.
82  */
83 struct dissector_table {
84         GHashTable      *hash_table;
85         GSList          *dissector_handles;
86         const char      *ui_name;
87         ftenum_t        type;
88         int             param;
89         protocol_t      *protocol;
90         GHashFunc       hash_func;
91         gboolean        supports_decode_as;
92 };
93
94 /*
95  * Dissector tables. const char * -> dissector_table *
96  */
97 static GHashTable *dissector_tables = NULL;
98
99 /*
100  * Dissector table aliases. const char * -> const char *
101  */
102 static GHashTable *dissector_table_aliases = NULL;
103
104 /*
105  * List of registered dissectors.
106  */
107 static GHashTable *registered_dissectors = NULL;
108
109 /*
110  * A dissector dependency list.
111  */
112 struct depend_dissector_list {
113         GSList          *dissectors;
114 };
115
116 /* Maps char *dissector_name to depend_dissector_list_t */
117 static GHashTable *depend_dissector_lists = NULL;
118
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;
124
125 /*
126  * Post-dissector information - handle for the dissector and a list
127  * of hfids for the fields the post-dissector wants.
128  */
129 typedef struct {
130         dissector_handle_t handle;
131         GArray *wanted_hfids;
132 } postdissector;
133
134 /*
135  * Array of all postdissectors.
136  */
137 static GArray *postdissectors = NULL;
138
139 /*
140  * i-th element of that array.
141  */
142 #define POSTDISSECTORS(i)       g_array_index(postdissectors, postdissector, i)
143
144 static void
145 destroy_depend_dissector_list(void *data)
146 {
147         depend_dissector_list_t dissector_list = (depend_dissector_list_t)data;
148         GSList **list = &(dissector_list->dissectors);
149
150         g_slist_free_full(*list, g_free);
151         g_slice_free(struct depend_dissector_list, dissector_list);
152 }
153
154 /*
155  * A heuristics dissector list.
156  */
157 struct heur_dissector_list {
158         protocol_t      *protocol;
159         GSList          *dissectors;
160 };
161
162 static GHashTable *heur_dissector_lists = NULL;
163
164 /* Name hashtables for fast detection of duplicate names */
165 static GHashTable* heuristic_short_names  = NULL;
166
167 static void
168 destroy_heuristic_dissector_entry(gpointer data)
169 {
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);
174 }
175
176 static void
177 destroy_heuristic_dissector_list(void *data)
178 {
179         heur_dissector_list_t dissector_list = (heur_dissector_list_t)data;
180         GSList **list = &(dissector_list->dissectors);
181
182         g_slist_free_full(*list, destroy_heuristic_dissector_entry);
183         g_slice_free(struct heur_dissector_list, dissector_list);
184 }
185
186 static void
187 destroy_dissector_table(void *data)
188 {
189         struct dissector_table *table = (struct dissector_table *)data;
190
191         g_hash_table_destroy(table->hash_table);
192         g_slist_free(table->dissector_handles);
193         g_slice_free(struct dissector_table, data);
194 }
195
196 void
197 packet_init(void)
198 {
199         dissector_tables = g_hash_table_new_full(g_str_hash, g_str_equal,
200                         NULL, destroy_dissector_table);
201
202         dissector_table_aliases = g_hash_table_new_full(g_str_hash, g_str_equal,
203                         NULL, NULL);
204
205         registered_dissectors = g_hash_table_new_full(g_str_hash, g_str_equal,
206                         NULL, NULL);
207
208         depend_dissector_lists = g_hash_table_new_full(g_str_hash, g_str_equal,
209                         g_free, destroy_depend_dissector_list);
210
211         heur_dissector_lists = g_hash_table_new_full(g_str_hash, g_str_equal,
212                         NULL, destroy_heuristic_dissector_list);
213
214         heuristic_short_names  = g_hash_table_new(g_str_hash, g_str_equal);
215 }
216
217 void
218 packet_cache_proto_handles(void)
219 {
220         frame_handle = find_dissector("frame");
221         g_assert(frame_handle != NULL);
222
223         file_handle = find_dissector("file");
224         g_assert(file_handle != NULL);
225
226         data_handle = find_dissector("data");
227         g_assert(data_handle != NULL);
228
229         proto_malformed = proto_get_id_by_filter_name("_ws.malformed");
230         g_assert(proto_malformed != -1);
231 }
232
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;
239
240 typedef void (*void_func_t)(void);
241
242 /* Initialize all data structures used for dissection. */
243 static void
244 call_routine(gpointer routine, gpointer dummy _U_)
245 {
246         void_func_t func = (void_func_t)routine;
247         (*func)();
248 }
249
250 void
251 packet_cleanup(void)
252 {
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);
268                         }
269                 }
270                 g_array_free(postdissectors, TRUE);
271         }
272 }
273
274 /*
275  * Given a tvbuff, and a length from a packet header, adjust the length
276  * of the tvbuff to reflect the specified length.
277  */
278 void
279 set_actual_length(tvbuff_t *tvb, const guint specified_len)
280 {
281         if (specified_len < tvb_reported_length(tvb)) {
282                 /* Adjust the length of this tvbuff to include only the specified
283                    payload length.
284
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
287                    was padding. */
288                 tvb_set_reported_length(tvb, specified_len);
289         }
290 }
291
292 void
293 register_init_routine(void (*func)(void))
294 {
295         init_routines = g_slist_prepend(init_routines, (gpointer)func);
296 }
297
298 void
299 register_cleanup_routine(void (*func)(void))
300 {
301         cleanup_routines = g_slist_prepend(cleanup_routines, (gpointer)func);
302 }
303
304 /* register a new shutdown routine */
305 void
306 register_shutdown_routine(void (*func)(void))
307 {
308         shutdown_routines = g_slist_prepend(shutdown_routines, (gpointer)func);
309 }
310
311 /* Initialize all data structures used for dissection. */
312 void
313 init_dissection(void)
314 {
315         /*
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).
319          */
320         host_name_lookup_reset();
321
322         wmem_enter_file_scope();
323
324         /* Initialize the table of conversations. */
325         epan_conversation_init();
326
327         /* Initialize protocol-specific variables. */
328         g_slist_foreach(init_routines, &call_routine, NULL);
329
330         /* Initialize the stream-handling tables */
331         stream_init();
332
333         /* Initialize the expert infos */
334         expert_packet_init();
335 }
336
337 void
338 cleanup_dissection(void)
339 {
340         /* Cleanup protocol-specific variables. */
341         g_slist_foreach(cleanup_routines, &call_routine, NULL);
342
343         /* Cleanup the stream-handling tables */
344         stream_cleanup();
345
346         /* Cleanup the expert infos */
347         expert_packet_cleanup();
348
349         wmem_leave_file_scope();
350
351         /*
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
355          * file open.
356          */
357 }
358
359 void
360 register_postseq_cleanup_routine(void_func_t func)
361 {
362         postseq_cleanup_routines = g_slist_prepend(postseq_cleanup_routines,
363                         (gpointer)func);
364 }
365
366 /* Call all the registered "postseq_cleanup" routines. */
367 void
368 postseq_cleanup_all_protocols(void)
369 {
370         g_slist_foreach(postseq_cleanup_routines,
371                         &call_routine, NULL);
372 }
373
374 /*
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.
377  */
378 void
379 add_new_data_source(packet_info *pinfo, tvbuff_t *tvb, const char *name)
380 {
381         struct data_source *src;
382
383         src = wmem_new(pinfo->pool, struct data_source);
384         src->tvb = tvb;
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);
389 }
390
391 void
392 remove_last_data_source(packet_info *pinfo)
393 {
394         GSList *last;
395
396         last = g_slist_last(pinfo->data_src);
397         pinfo->data_src = g_slist_delete_link(pinfo->data_src, last);
398 }
399
400 char*
401 get_data_source_name(const struct data_source *src)
402 {
403         guint length = tvb_captured_length(src->tvb);
404
405         return wmem_strdup_printf(NULL, "%s (%u byte%s)", src->name, length,
406                                 plurality(length, "", "s"));
407 }
408
409 tvbuff_t *
410 get_data_source_tvb(const struct data_source *src)
411 {
412         return src->tvb;
413 }
414
415 /*
416  * Find and return the tvb associated with the given data source name
417  */
418 tvbuff_t *
419 get_data_source_tvb_by_name(packet_info *pinfo, const char *name)
420 {
421         GSList *source;
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;
426                 }
427         }
428         return NULL;
429 }
430
431
432 /*
433  * Free up a frame's list of data sources.
434  */
435 void
436 free_data_sources(packet_info *pinfo)
437 {
438         if (pinfo->data_src) {
439                 g_slist_free(pinfo->data_src);
440                 pinfo->data_src = NULL;
441         }
442 }
443
444 void
445 mark_frame_as_depended_upon(packet_info *pinfo, guint32 frame_num)
446 {
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));
450         }
451 }
452
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;
461
462 void
463 register_final_registration_routine(void (*func)(void))
464 {
465         final_registration_routines = g_slist_prepend(final_registration_routines,
466                         (gpointer)func);
467 }
468
469 /* Call all the registered "final_registration" routines. */
470 void
471 final_registration_all_protocols(void)
472 {
473         g_slist_foreach(final_registration_routines,
474                         &call_routine, NULL);
475 }
476
477
478 /* Creates the top-most tvbuff and calls dissect_frame() */
479 void
480 dissect_record(epan_dissect_t *edt, int file_type_subtype,
481     wtap_rec *rec, tvbuff_t *tvb, frame_data *fd, column_info *cinfo)
482 {
483         const char *volatile record_type;
484         frame_data_t frame_dissector_data;
485
486         switch (rec->rec_type) {
487
488         case REC_TYPE_PACKET:
489                 record_type = "Frame";
490                 break;
491
492         case REC_TYPE_FT_SPECIFIC_EVENT:
493                 record_type = "Event";
494                 break;
495
496         case REC_TYPE_FT_SPECIFIC_REPORT:
497                 record_type = "Report";
498                 break;
499
500         case REC_TYPE_SYSCALL:
501                 record_type = "System Call";
502                 break;
503
504         default:
505                 /*
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.
510                  */
511                 g_assert_not_reached();
512                 break;
513         }
514
515         if (cinfo != NULL)
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;
526         }
527         switch (rec->rec_type) {
528
529         case REC_TYPE_PACKET:
530                 edt->pi.pseudo_header = &rec->rec_header.packet_header.pseudo_header;
531                 break;
532
533         case REC_TYPE_FT_SPECIFIC_EVENT:
534         case REC_TYPE_FT_SPECIFIC_REPORT:
535                 edt->pi.pseudo_header = NULL;
536                 break;
537
538         case REC_TYPE_SYSCALL:
539                 edt->pi.pseudo_header = NULL;
540                 break;
541         }
542
543         edt->pi.fd            = fd;
544         edt->pi.rec           = rec;
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);
558         edt->tvb = tvb;
559
560         frame_delta_abs_time(edt->session, fd, fd->frame_ref_num, &edt->pi.rel_ts);
561
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;
567         else
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" */
571
572         TRY {
573                 /* Add this tvbuffer into the data_src list */
574                 add_new_data_source(&edt->pi, edt->tvb, record_type);
575
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);
581         }
582         CATCH(BoundsError) {
583                 g_assert_not_reached();
584         }
585         CATCH2(FragmentBoundsError, ReportedBoundsError) {
586                 proto_tree_add_protocol_format(edt->tree, proto_malformed, edt->tvb, 0, 0,
587                                                "[Malformed %s: Packet Length]",
588                                                record_type);
589         }
590         ENDTRY;
591
592         fd->flags.visited = 1;
593 }
594
595 /* Creates the top-most tvbuff and calls dissect_file() */
596 void
597 dissect_file(epan_dissect_t *edt, wtap_rec *rec,
598                tvbuff_t *tvb, frame_data *fd, column_info *cinfo)
599 {
600         file_data_t file_dissector_data;
601
602         if (cinfo != NULL)
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;
608         edt->pi.fd    = fd;
609         edt->pi.rec   = rec;
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);
624         edt->tvb = tvb;
625
626
627         frame_delta_abs_time(edt->session, fd, fd->frame_ref_num, &edt->pi.rel_ts);
628
629
630         TRY {
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;
636                 else
637                         file_dissector_data.pkt_comment = NULL;
638                 file_dissector_data.color_edt = edt; /* Used strictly for "coloring rules" */
639
640
641                 /* Add this tvbuffer into the data_src list */
642                 add_new_data_source(&edt->pi, edt->tvb, "File");
643
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);
649
650         }
651         CATCH(BoundsError) {
652                 g_assert_not_reached();
653         }
654         CATCH3(FragmentBoundsError, ContainedBoundsError, ReportedBoundsError) {
655                 proto_tree_add_protocol_format(edt->tree, proto_malformed, edt->tvb, 0, 0,
656                                                "[Malformed Record: Packet Length]");
657         }
658         ENDTRY;
659
660         fd->flags.visited = 1;
661 }
662
663 /*********************** code added for sub-dissector lookup *********************/
664
665 enum dissector_e {
666         DISSECTOR_TYPE_SIMPLE,
667         DISSECTOR_TYPE_CALLBACK
668 };
669
670 /*
671  * A dissector handle.
672  */
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;
679 };
680
681 /* This function will return
682  * old style dissector :
683  *   length of the payload or 1 of the payload is empty
684  * new dissector :
685  *   >0  this protocol was successfully dissected and this was this protocol.
686  *   0   this packet did not match this protocol.
687  *
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.
690  */
691 static int
692 call_dissector_through_handle(dissector_handle_t handle, tvbuff_t *tvb,
693                               packet_info *pinfo, proto_tree *tree, void *data)
694 {
695         const char *saved_proto;
696         int         len;
697
698         saved_proto = pinfo->current_proto;
699
700         if ((handle->protocol != NULL) && (!proto_is_pino(handle->protocol))) {
701                 pinfo->current_proto =
702                         proto_get_protocol_short_name(handle->protocol);
703         }
704
705         if (handle->dissector_type == DISSECTOR_TYPE_SIMPLE) {
706                 len = ((dissector_t)handle->dissector_func)(tvb, pinfo, tree, data);
707         }
708         else if (handle->dissector_type == DISSECTOR_TYPE_CALLBACK) {
709                 len = ((dissector_cb_t)handle->dissector_func)(tvb, pinfo, tree, data, handle->dissector_data);
710         }
711         else {
712                 g_assert_not_reached();
713         }
714         pinfo->current_proto = saved_proto;
715
716         return len;
717 }
718
719 /*
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.
726  */
727
728 static int
729 call_dissector_work_error(dissector_handle_t handle, tvbuff_t *tvb,
730                           packet_info *pinfo_arg, proto_tree *tree, void *);
731
732 static int
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)
735 {
736         packet_info *pinfo = pinfo_arg;
737         const char  *saved_proto;
738         guint16      saved_can_desegment;
739         int          len;
740         guint        saved_layers_len = 0;
741         int          saved_tree_count = tree ? tree->tree_data->count : 0;
742
743         if (handle->protocol != NULL &&
744             !proto_is_protocol_enabled(handle->protocol)) {
745                 /*
746                  * The protocol isn't enabled.
747                  */
748                 return 0;
749         }
750
751         saved_proto = pinfo->current_proto;
752         saved_can_desegment = pinfo->can_desegment;
753         saved_layers_len = wmem_list_count(pinfo->layers);
754
755         /*
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
759          * by one.
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.
766          */
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);
772
773                 /*
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.
777                  */
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)));
782                 }
783         }
784
785         if (pinfo->flags.in_error_pkt) {
786                 len = call_dissector_work_error(handle, tvb, pinfo, tree, data);
787         } else {
788                 /*
789                  * Just call the subdissector.
790                  */
791                 len = call_dissector_through_handle(handle, tvb, pinfo, tree, data);
792         }
793         if (handle->protocol != NULL && !proto_is_pino(handle->protocol) && add_proto_name &&
794                 (len == 0 || (tree && saved_tree_count == tree->tree_data->count))) {
795                 /*
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
798                  * tree. Remove it.
799                  */
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));
803                 }
804         }
805         pinfo->current_proto = saved_proto;
806         pinfo->can_desegment = saved_can_desegment;
807         return len;
808 }
809
810
811 static int
812 call_dissector_work_error(dissector_handle_t handle, tvbuff_t *tvb,
813                           packet_info *pinfo_arg, proto_tree *tree, void *data)
814 {
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;
820         address       save_dl_src;
821         address       save_dl_dst;
822         address       save_net_src;
823         address       save_net_dst;
824         address       save_src;
825         address       save_dst;
826
827         /*
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
833         * packet).
834         */
835
836         /*
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
842         * error.
843         */
844         saved_proto = pinfo->current_proto;
845         saved_can_desegment = pinfo->can_desegment;
846
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);
855
856         /* Dissect the contained packet. */
857         TRY {
858                 len = call_dissector_through_handle(handle, tvb,pinfo, tree, data);
859         }
860         CATCH(BoundsError) {
861                 /*
862                 * Restore the column writability and addresses.
863                 */
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);
871
872                 /*
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.
877                 */
878                 pinfo->current_proto = saved_proto;
879
880                 /*
881                 * Restore the desegmentability state.
882                 */
883                 pinfo->can_desegment = saved_can_desegment;
884
885                 /*
886                 * Rethrow the exception, so this will be
887                 * reported as a short frame.
888                 */
889                 RETHROW;
890         }
891         CATCH3(FragmentBoundsError, ContainedBoundsError, ReportedBoundsError) {
892                 /*
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.
901                 */
902                 len = tvb_captured_length(tvb);
903         }
904         ENDTRY;
905
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;
914         return len;
915 }
916
917 /*
918  * An entry in the hash table portion of a dissector table.
919  */
920 struct dtbl_entry {
921         dissector_handle_t initial;
922         dissector_handle_t current;
923 };
924
925 /* Finds a dissector table by table name. */
926 dissector_table_t
927 find_dissector_table(const char *name)
928 {
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);
932                 if (new_name) {
933                         dissector_table = (dissector_table_t) g_hash_table_lookup(dissector_tables, new_name);
934                 }
935                 if (dissector_table) {
936                         g_warning("%s is now %s", name, new_name);
937                 }
938         }
939         return dissector_table;
940 }
941
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)
945 {
946         switch (sub_dissectors->type) {
947
948         case FT_UINT8:
949         case FT_UINT16:
950         case FT_UINT24:
951         case FT_UINT32:
952                 /*
953                  * You can do a uint lookup in these tables.
954                  */
955                 break;
956         case FT_NONE:
957                 /* For now treat as uint */
958                 break;
959
960         default:
961                 /*
962                  * But you can't do a uint lookup in any other types
963                  * of tables.
964                  */
965                 g_assert_not_reached();
966         }
967
968         /*
969          * Find the entry.
970          */
971         return (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table,
972                                    GUINT_TO_POINTER(pattern));
973 }
974
975 #if 0
976 static void
977 dissector_add_uint_sanity_check(const char *name, guint32 pattern, dissector_handle_t handle, dissector_table_t sub_dissectors)
978 {
979         dtbl_entry_t *dtbl_entry;
980
981         if (pattern == 0) {
982                 g_warning("%s: %s registering using a pattern of 0",
983                           name, proto_get_protocol_filter_name(proto_get_id(handle->protocol)));
984         }
985
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)));
991         }
992 }
993 #endif
994
995 /* Add an entry to a uint dissector table. */
996 void
997 dissector_add_uint(const char *name, const guint32 pattern, dissector_handle_t handle)
998 {
999         dissector_table_t  sub_dissectors;
1000         dtbl_entry_t      *dtbl_entry;
1001
1002         sub_dissectors = find_dissector_table(name);
1003
1004         /*
1005          * Make sure the handle and the dissector table exist.
1006          */
1007         if (handle == NULL) {
1008                 fprintf(stderr, "OOPS: handle to register \"%s\" to doesn't exist\n",
1009                     name);
1010                 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1011                         abort();
1012                 return;
1013         }
1014         if (sub_dissectors == NULL) {
1015                 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
1016                     name);
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)
1020                         abort();
1021                 return;
1022         }
1023
1024         switch (sub_dissectors->type) {
1025
1026         case FT_UINT8:
1027         case FT_UINT16:
1028         case FT_UINT24:
1029         case FT_UINT32:
1030                 /*
1031                  * You can do a uint lookup in these tables.
1032                  */
1033                 break;
1034
1035         default:
1036                 /*
1037                  * But you can't do a uint lookup in any other types
1038                  * of tables.
1039                  */
1040                 g_assert_not_reached();
1041         }
1042
1043 #if 0
1044         dissector_add_uint_sanity_check(name, pattern, handle, sub_dissectors);
1045 #endif
1046
1047         dtbl_entry = (dtbl_entry_t *)g_malloc(sizeof (dtbl_entry_t));
1048         dtbl_entry->current = handle;
1049         dtbl_entry->initial = dtbl_entry->current;
1050
1051         /* do the table insertion */
1052         g_hash_table_insert(sub_dissectors->hash_table,
1053                              GUINT_TO_POINTER(pattern), (gpointer)dtbl_entry);
1054
1055         /*
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.
1059          */
1060         if (sub_dissectors->supports_decode_as)
1061                 dissector_add_for_decode_as(name, handle);
1062 }
1063
1064
1065
1066 void dissector_add_uint_range(const char *name, range_t *range,
1067                               dissector_handle_t handle)
1068 {
1069         dissector_table_t  sub_dissectors;
1070         guint32 i, j;
1071
1072         if (range) {
1073                 if (range->nranges == 0) {
1074                         /*
1075                          * Even an empty range would want a chance for
1076                          * Decode As, if the dissector table supports
1077                          * it.
1078                          */
1079                         sub_dissectors = find_dissector_table(name);
1080                         if (sub_dissectors->supports_decode_as)
1081                                 dissector_add_for_decode_as(name, handle);
1082                 }
1083                 else {
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);
1088                         }
1089                 }
1090         }
1091 }
1092
1093 static void
1094 dissector_add_preference(const char *name, dissector_handle_t handle, guint init_value)
1095 {
1096         guint* uint_var;
1097         module_t *module;
1098         gchar *description, *title;
1099         dissector_table_t  pref_dissector_table = find_dissector_table(name);
1100         int proto_id = proto_get_id(handle->protocol);
1101
1102         uint_var = wmem_new(wmem_epan_scope(), guint);
1103         *uint_var = init_value;
1104
1105         /* If the dissector already has a preference module, use it */
1106         module = prefs_find_module(proto_get_protocol_filter_name(proto_id));
1107         if (module == NULL)
1108         {
1109                 /* Otherwise create a new one */
1110                 module = prefs_register_protocol(proto_id, NULL);
1111         }
1112
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);
1117
1118         prefs_register_decode_as_preference(module, name, title, description, uint_var);
1119 }
1120
1121 void dissector_add_uint_with_preference(const char *name, const guint32 pattern,
1122     dissector_handle_t handle)
1123 {
1124         dissector_add_preference(name, handle, pattern);
1125         dissector_add_uint(name, pattern, handle);
1126 }
1127
1128 void dissector_add_uint_range_with_preference(const char *name, const char* range_str,
1129     dissector_handle_t handle)
1130 {
1131         range_t** range;
1132         module_t *module;
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;
1137
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
1141          */
1142         range = wmem_new0(wmem_epan_scope(), range_t*);
1143
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);
1149         }
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);
1157
1158                 /* Max value is based on datatype of dissector table */
1159                 switch (pref_dissector_table->type) {
1160
1161                 case FT_UINT8:
1162                         max_value = 0xFF;
1163                         break;
1164                 case FT_UINT16:
1165                         max_value = 0xFFFF;
1166                         break;
1167                 case FT_UINT24:
1168                         max_value = 0xFFFFFF;
1169                         break;
1170                 case FT_UINT32:
1171                         max_value = 0xFFFFFFFF;
1172                         break;
1173
1174                 default:
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();
1177                 }
1178
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);
1181         }
1182
1183         dissector_add_uint_range(name, *range, handle);
1184 }
1185
1186 /* Delete the entry for a dissector in a uint dissector table
1187    with a particular pattern. */
1188
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 */
1193 /*      be available. */
1194 void
1195 dissector_delete_uint(const char *name, const guint32 pattern,
1196         dissector_handle_t handle _U_)
1197 {
1198         dissector_table_t sub_dissectors = find_dissector_table(name);
1199         dtbl_entry_t *dtbl_entry;
1200
1201         /* sanity check */
1202         g_assert(sub_dissectors);
1203
1204         /*
1205          * Find the entry.
1206          */
1207         dtbl_entry = find_uint_dtbl_entry(sub_dissectors, pattern);
1208
1209         if (dtbl_entry != NULL) {
1210                 /*
1211                  * Found - remove it.
1212                  */
1213                 g_hash_table_remove(sub_dissectors->hash_table,
1214                                     GUINT_TO_POINTER(pattern));
1215         }
1216 }
1217
1218 void dissector_delete_uint_range(const char *name, range_t *range,
1219                                  dissector_handle_t handle)
1220 {
1221         guint32 i, j;
1222
1223         if (range) {
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);
1228                 }
1229         }
1230 }
1231
1232 static gboolean
1233 dissector_delete_all_check (gpointer key _U_, gpointer value, gpointer user_data)
1234 {
1235         dtbl_entry_t *dtbl_entry = (dtbl_entry_t *) value;
1236         dissector_handle_t handle = (dissector_handle_t) user_data;
1237
1238         if (!dtbl_entry->current->protocol) {
1239                 /*
1240                  * Not all dissectors are registered with a protocol, so we need this
1241                  * check when running from dissector_delete_from_all_tables.
1242                  */
1243                 return FALSE;
1244         }
1245
1246         return (proto_get_id (dtbl_entry->current->protocol) == proto_get_id (handle->protocol));
1247 }
1248
1249 /* Delete all entries from a dissector table. */
1250 void dissector_delete_all(const char *name, dissector_handle_t handle)
1251 {
1252         dissector_table_t sub_dissectors = find_dissector_table(name);
1253         g_assert (sub_dissectors);
1254
1255         g_hash_table_foreach_remove (sub_dissectors->hash_table, dissector_delete_all_check, handle);
1256 }
1257
1258 static void
1259 dissector_delete_from_table(gpointer key _U_, gpointer value, gpointer user_data)
1260 {
1261         dissector_table_t sub_dissectors = (dissector_table_t) value;
1262         g_assert (sub_dissectors);
1263
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);
1266 }
1267
1268 /* Delete handle from all tables and dissector_handles lists */
1269 static void
1270 dissector_delete_from_all_tables(dissector_handle_t handle)
1271 {
1272         g_hash_table_foreach(dissector_tables, dissector_delete_from_table, handle);
1273 }
1274
1275 /* Change the entry for a dissector in a uint dissector table
1276    with a particular pattern to use a new dissector handle. */
1277 void
1278 dissector_change_uint(const char *name, const guint32 pattern, dissector_handle_t handle)
1279 {
1280         dissector_table_t sub_dissectors = find_dissector_table(name);
1281         dtbl_entry_t *dtbl_entry;
1282
1283         /* sanity check */
1284         g_assert(sub_dissectors);
1285
1286         /*
1287          * See if the entry already exists. If so, reuse it.
1288          */
1289         dtbl_entry = find_uint_dtbl_entry(sub_dissectors, pattern);
1290         if (dtbl_entry != NULL) {
1291                 dtbl_entry->current = handle;
1292                 return;
1293         }
1294
1295         /*
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.
1299          */
1300         if (handle == NULL)
1301                 return;
1302
1303         dtbl_entry = (dtbl_entry_t *)g_malloc(sizeof (dtbl_entry_t));
1304         dtbl_entry->initial = NULL;
1305         dtbl_entry->current = handle;
1306
1307         /* do the table insertion */
1308         g_hash_table_insert(sub_dissectors->hash_table,
1309                              GUINT_TO_POINTER(pattern), (gpointer)dtbl_entry);
1310 }
1311
1312 /* Reset an entry in a uint dissector table to its initial value. */
1313 void
1314 dissector_reset_uint(const char *name, const guint32 pattern)
1315 {
1316         dissector_table_t  sub_dissectors = find_dissector_table(name);
1317         dtbl_entry_t      *dtbl_entry;
1318
1319         /* sanity check */
1320         g_assert(sub_dissectors);
1321
1322         /*
1323          * Find the entry.
1324          */
1325         dtbl_entry = find_uint_dtbl_entry(sub_dissectors, pattern);
1326
1327         if (dtbl_entry == NULL)
1328                 return;
1329
1330         /*
1331          * Found - is there an initial value?
1332          */
1333         if (dtbl_entry->initial != NULL) {
1334                 dtbl_entry->current = dtbl_entry->initial;
1335         } else {
1336                 g_hash_table_remove(sub_dissectors->hash_table,
1337                                     GUINT_TO_POINTER(pattern));
1338         }
1339 }
1340
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. */
1344
1345 int
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)
1349 {
1350         dtbl_entry_t            *dtbl_entry;
1351         struct dissector_handle *handle;
1352         guint32                  saved_match_uint;
1353         int len;
1354
1355         dtbl_entry = find_uint_dtbl_entry(sub_dissectors, uint_val);
1356         if (dtbl_entry == NULL) {
1357                 /*
1358                  * There's no entry in the table for our value.
1359                  */
1360                 return 0;
1361         }
1362
1363         /*
1364          * Is there currently a dissector handle for this entry?
1365          */
1366         handle = dtbl_entry->current;
1367         if (handle == NULL) {
1368                 /*
1369                  * No - pretend this dissector didn't exist,
1370                  * so that other dissectors might have a chance
1371                  * to dissect this packet.
1372                  */
1373                 return 0;
1374         }
1375
1376         /*
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".
1380          */
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;
1385
1386         /*
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.
1390          *
1391          * Old-style dissectors can't reject the packet.
1392          *
1393          * 0 is also returned if the protocol wasn't enabled.
1394          *
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.
1398          */
1399         return len;
1400 }
1401
1402 int
1403 dissector_try_uint(dissector_table_t sub_dissectors, const guint32 uint_val,
1404                    tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1405 {
1406
1407         return dissector_try_uint_new(sub_dissectors, uint_val, tvb, pinfo, tree, TRUE, NULL);
1408 }
1409
1410 /* Look for a given value in a given uint dissector table and, if found,
1411    return the dissector handle for that value. */
1412 dissector_handle_t
1413 dissector_get_uint_handle(dissector_table_t const sub_dissectors, const guint32 uint_val)
1414 {
1415         dtbl_entry_t *dtbl_entry;
1416
1417         dtbl_entry = find_uint_dtbl_entry(sub_dissectors, uint_val);
1418         if (dtbl_entry != NULL)
1419                 return dtbl_entry->current;
1420         else
1421                 return NULL;
1422 }
1423
1424 dissector_handle_t
1425 dissector_get_default_uint_handle(const char *name, const guint32 uint_val)
1426 {
1427         dissector_table_t sub_dissectors = find_dissector_table(name);
1428
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;
1433         }
1434         return NULL;
1435 }
1436
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)
1440 {
1441         dtbl_entry_t *ret;
1442         char *key;
1443
1444         switch (sub_dissectors->type) {
1445
1446         case FT_STRING:
1447         case FT_STRINGZ:
1448         case FT_STRINGZPAD:
1449                 /*
1450                  * You can do a string lookup in these tables.
1451                  */
1452                 break;
1453
1454         default:
1455                 /*
1456                  * But you can't do a string lookup in any other types
1457                  * of tables.
1458                  */
1459                 g_assert_not_reached();
1460         }
1461
1462         if (sub_dissectors->param == TRUE) {
1463                 key = g_ascii_strdown(pattern, -1);
1464         } else {
1465                 key = g_strdup(pattern);
1466         }
1467
1468         /*
1469          * Find the entry.
1470          */
1471         ret = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, key);
1472
1473         g_free(key);
1474
1475         return ret;
1476 }
1477
1478 /* Add an entry to a string dissector table. */
1479 void
1480 dissector_add_string(const char *name, const gchar *pattern,
1481                      dissector_handle_t handle)
1482 {
1483         dissector_table_t  sub_dissectors = find_dissector_table(name);
1484         dtbl_entry_t      *dtbl_entry;
1485         char *key;
1486
1487         /*
1488          * Make sure the handle and the dissector table exist.
1489          */
1490         if (handle == NULL) {
1491                 fprintf(stderr, "OOPS: handle to register \"%s\" to doesn't exist\n",
1492                     name);
1493                 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1494                         abort();
1495                 return;
1496         }
1497         if (sub_dissectors == NULL) {
1498                 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
1499                     name);
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)
1503                         abort();
1504                 return;
1505         }
1506
1507         switch (sub_dissectors->type) {
1508
1509         case FT_STRING:
1510         case FT_STRINGZ:
1511         case FT_STRINGZPAD:
1512                 /*
1513                  * You can do a string lookup in these tables.
1514                  */
1515                 break;
1516
1517         default:
1518                 /*
1519                  * But you can't do a string lookup in any other types
1520                  * of tables.
1521                  */
1522                 g_assert_not_reached();
1523         }
1524
1525         dtbl_entry = (dtbl_entry_t *)g_malloc(sizeof (dtbl_entry_t));
1526         dtbl_entry->current = handle;
1527         dtbl_entry->initial = dtbl_entry->current;
1528
1529         if (sub_dissectors->param == TRUE) {
1530                 key = g_ascii_strdown(pattern, -1);
1531         } else {
1532                 key = g_strdup(pattern);
1533         }
1534
1535         /* do the table insertion */
1536         g_hash_table_insert(sub_dissectors->hash_table, (gpointer)key,
1537                              (gpointer)dtbl_entry);
1538
1539         /*
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.
1543          */
1544         if (sub_dissectors->supports_decode_as)
1545                 dissector_add_for_decode_as(name, handle);
1546 }
1547
1548 /* Delete the entry for a dissector in a string dissector table
1549    with a particular pattern. */
1550
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 */
1554 /*      implemented.  */
1555 /*      If temporary dissectors are deleted, then the original dissector must */
1556 /*      be available. */
1557 void
1558 dissector_delete_string(const char *name, const gchar *pattern,
1559         dissector_handle_t handle _U_)
1560 {
1561         dissector_table_t  sub_dissectors = find_dissector_table(name);
1562         dtbl_entry_t      *dtbl_entry;
1563
1564         /* sanity check */
1565         g_assert(sub_dissectors);
1566
1567         /*
1568          * Find the entry.
1569          */
1570         dtbl_entry = find_string_dtbl_entry(sub_dissectors, pattern);
1571
1572         if (dtbl_entry != NULL) {
1573                 /*
1574                  * Found - remove it.
1575                  */
1576                 g_hash_table_remove(sub_dissectors->hash_table, pattern);
1577         }
1578 }
1579
1580 /* Change the entry for a dissector in a string dissector table
1581    with a particular pattern to use a new dissector handle. */
1582 void
1583 dissector_change_string(const char *name, const gchar *pattern,
1584                         dissector_handle_t handle)
1585 {
1586         dissector_table_t  sub_dissectors = find_dissector_table(name);
1587         dtbl_entry_t      *dtbl_entry;
1588
1589         /* sanity check */
1590         g_assert(sub_dissectors);
1591
1592         /*
1593          * See if the entry already exists. If so, reuse it.
1594          */
1595         dtbl_entry = find_string_dtbl_entry(sub_dissectors, pattern);
1596         if (dtbl_entry != NULL) {
1597                 dtbl_entry->current = handle;
1598                 return;
1599         }
1600
1601         /*
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.
1605          */
1606         if (handle == NULL)
1607                 return;
1608
1609         dtbl_entry = (dtbl_entry_t *)g_malloc(sizeof (dtbl_entry_t));
1610         dtbl_entry->initial = NULL;
1611         dtbl_entry->current = handle;
1612
1613         /* do the table insertion */
1614         g_hash_table_insert(sub_dissectors->hash_table, (gpointer)g_strdup(pattern),
1615                              (gpointer)dtbl_entry);
1616 }
1617
1618 /* Reset an entry in a string sub-dissector table to its initial value. */
1619 void
1620 dissector_reset_string(const char *name, const gchar *pattern)
1621 {
1622         dissector_table_t  sub_dissectors = find_dissector_table(name);
1623         dtbl_entry_t      *dtbl_entry;
1624
1625         /* sanity check */
1626         g_assert(sub_dissectors);
1627
1628         /*
1629          * Find the entry.
1630          */
1631         dtbl_entry = find_string_dtbl_entry(sub_dissectors, pattern);
1632
1633         if (dtbl_entry == NULL)
1634                 return;
1635
1636         /*
1637          * Found - is there an initial value?
1638          */
1639         if (dtbl_entry->initial != NULL) {
1640                 dtbl_entry->current = dtbl_entry->initial;
1641         } else {
1642                 g_hash_table_remove(sub_dissectors->hash_table, pattern);
1643         }
1644 }
1645
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. */
1649 int
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)
1652 {
1653         dtbl_entry_t            *dtbl_entry;
1654         struct dissector_handle *handle;
1655         int                      len;
1656         const gchar             *saved_match_string;
1657
1658         /* XXX ASSERT instead ? */
1659         if (!string) return 0;
1660         dtbl_entry = find_string_dtbl_entry(sub_dissectors, string);
1661         if (dtbl_entry != NULL) {
1662                 /*
1663                  * Is there currently a dissector handle for this entry?
1664                  */
1665                 handle = dtbl_entry->current;
1666                 if (handle == NULL) {
1667                         /*
1668                          * No - pretend this dissector didn't exist,
1669                          * so that other dissectors might have a chance
1670                          * to dissect this packet.
1671                          */
1672                         return 0;
1673                 }
1674
1675                 /*
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".
1679                  */
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;
1684
1685                 /*
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.
1689                  *
1690                  * Old-style dissectors can't reject the packet.
1691                  *
1692                  * 0 is also returned if the protocol wasn't enabled.
1693                  *
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.
1697                  */
1698                 return len;
1699         }
1700         return 0;
1701 }
1702
1703 int
1704 dissector_try_string(dissector_table_t sub_dissectors, const gchar *string,
1705                      tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1706 {
1707         return dissector_try_string_new(sub_dissectors, string, tvb, pinfo, tree, TRUE, data);
1708 }
1709
1710 /* Look for a given value in a given string dissector table and, if found,
1711    return the dissector handle for that value. */
1712 dissector_handle_t
1713 dissector_get_string_handle(dissector_table_t sub_dissectors,
1714                             const gchar *string)
1715 {
1716         dtbl_entry_t *dtbl_entry;
1717
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;
1723         else
1724                 return NULL;
1725 }
1726
1727 dissector_handle_t
1728 dissector_get_default_string_handle(const char *name, const gchar *string)
1729 {
1730         dissector_table_t sub_dissectors;
1731
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;
1739         }
1740         return NULL;
1741 }
1742
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)
1745 {
1746         dissector_table_t  sub_dissectors = find_dissector_table(name);
1747         dtbl_entry_t      *dtbl_entry;
1748
1749         /*
1750          * Make sure the dissector table exists.
1751          */
1752         if (sub_dissectors == NULL) {
1753                 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
1754                     name);
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)
1758                         abort();
1759                 return;
1760         }
1761
1762         g_assert(sub_dissectors->type == FT_BYTES);
1763
1764         dtbl_entry = (dtbl_entry_t *)g_malloc(sizeof (dtbl_entry_t));
1765         dtbl_entry->current = handle;
1766         dtbl_entry->initial = dtbl_entry->current;
1767
1768         /* do the table insertion */
1769         g_hash_table_insert(sub_dissectors->hash_table, (gpointer)pattern,
1770                              (gpointer)dtbl_entry);
1771
1772         /*
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.
1776          */
1777         if (sub_dissectors->supports_decode_as)
1778                 dissector_add_for_decode_as(name, handle);
1779 }
1780
1781 dissector_handle_t dissector_get_custom_table_handle(dissector_table_t sub_dissectors, void *key)
1782 {
1783         dtbl_entry_t *dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, key);
1784
1785         if (dtbl_entry != NULL)
1786                 return dtbl_entry->current;
1787
1788         return NULL;
1789 }
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)
1792 {
1793         dissector_table_t  sub_dissectors;
1794         dtbl_entry_t      *dtbl_entry;
1795
1796         sub_dissectors = find_dissector_table(name);
1797
1798         /*
1799          * Make sure the handle and the dissector table exist.
1800          */
1801         if (handle == NULL) {
1802                 fprintf(stderr, "OOPS: handle to register \"%s\" to doesn't exist\n",
1803                     name);
1804                 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
1805                         abort();
1806                 return;
1807         }
1808         if (sub_dissectors == NULL) {
1809                 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
1810                     name);
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)
1814                         abort();
1815                 return;
1816         }
1817
1818         if (sub_dissectors->type != FT_GUID) {
1819                 g_assert_not_reached();
1820         }
1821
1822         dtbl_entry = (dtbl_entry_t *)g_malloc(sizeof (dtbl_entry_t));
1823         dtbl_entry->current = handle;
1824         dtbl_entry->initial = dtbl_entry->current;
1825
1826         /* do the table insertion */
1827         g_hash_table_insert(sub_dissectors->hash_table,
1828                              guid_val, (gpointer)dtbl_entry);
1829
1830         /*
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.
1834          */
1835         if (sub_dissectors->supports_decode_as)
1836                 dissector_add_for_decode_as(name, handle);
1837 }
1838
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)
1844 {
1845         dtbl_entry_t            *dtbl_entry;
1846         struct dissector_handle *handle;
1847         int len;
1848
1849         dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, guid_val);
1850         if (dtbl_entry != NULL) {
1851                 /*
1852                  * Is there currently a dissector handle for this entry?
1853                  */
1854                 handle = dtbl_entry->current;
1855                 if (handle == NULL) {
1856                         /*
1857                          * No - pretend this dissector didn't exist,
1858                          * so that other dissectors might have a chance
1859                          * to dissect this packet.
1860                          */
1861                         return 0;
1862                 }
1863
1864                 /*
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".
1868                  */
1869                 len = call_dissector_work(handle, tvb, pinfo, tree, add_proto_name, data);
1870
1871                 /*
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.
1875                  *
1876                  * Old-style dissectors can't reject the packet.
1877                  *
1878                  * 0 is also returned if the protocol wasn't enabled.
1879                  *
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.
1883                  */
1884                 return len;
1885         }
1886         return 0;
1887 }
1888
1889 int dissector_try_guid(dissector_table_t sub_dissectors,
1890     guid_key* guid_val, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1891 {
1892     return dissector_try_guid_new(sub_dissectors, guid_val, tvb, pinfo, tree, TRUE, NULL);
1893 }
1894
1895 /** Look for a given value in a given guid dissector table and, if found,
1896  * return the current dissector handle for that value.
1897  *
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.
1901  */
1902 dissector_handle_t dissector_get_guid_handle(
1903     dissector_table_t const sub_dissectors, guid_key* guid_val)
1904 {
1905         dtbl_entry_t *dtbl_entry;
1906
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;
1910         else
1911                 return NULL;
1912 }
1913
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)
1919 {
1920         return dissector_try_uint(sub_dissectors, 0, tvb, pinfo, tree);
1921 }
1922
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)
1928 {
1929         return dissector_try_uint_new(sub_dissectors, 0, tvb, pinfo, tree, add_proto_name, data);
1930 }
1931
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)
1935 {
1936         dissector_change_uint(name, 0, handle);
1937 }
1938
1939 /* Reset payload (FT_NONE) dissector table to its initial value. */
1940 void dissector_reset_payload(const char *name)
1941 {
1942         dissector_reset_uint(name, 0);
1943 }
1944
1945 dissector_handle_t
1946 dtbl_entry_get_handle (dtbl_entry_t *dtbl_entry)
1947 {
1948         return dtbl_entry->current;
1949 }
1950
1951 static gint
1952 dissector_compare_filter_name(gconstpointer dissector_a, gconstpointer dissector_b)
1953 {
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;
1957         gint ret;
1958
1959         if (a->protocol == NULL)
1960                 a_name = "";
1961         else
1962                 a_name = proto_get_protocol_filter_name(proto_get_id(a->protocol));
1963
1964         if (b->protocol == NULL)
1965                 b_name = "";
1966         else
1967                 b_name = proto_get_protocol_filter_name(proto_get_id(b->protocol));
1968
1969         ret = strcmp(a_name, b_name);
1970         return ret;
1971 }
1972
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. */
1975 void
1976 dissector_add_for_decode_as(const char *name, dissector_handle_t handle)
1977 {
1978         dissector_table_t  sub_dissectors = find_dissector_table(name);
1979         GSList            *entry;
1980         dissector_handle_t dup_handle;
1981
1982         /*
1983          * Make sure the dissector table exists.
1984          */
1985         if (sub_dissectors == NULL) {
1986                 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
1987                     name);
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)
1991                         abort();
1992                 return;
1993         }
1994
1995         /*
1996          * Make sure it supports Decode As.
1997          */
1998         if (!sub_dissectors->supports_decode_as) {
1999                 const char *dissector_name;
2000
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",
2005                                     dissector_name,
2006                                     proto_get_protocol_short_name(handle->protocol),
2007                                     name);
2008                 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
2009                         abort();
2010                 return;
2011         }
2012
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));
2018
2019         /* Is it already in this list? */
2020         entry = g_slist_find(sub_dissectors->dissector_handles, (gpointer)handle);
2021         if (entry != NULL) {
2022                 /*
2023                  * Yes - don't insert it again.
2024                  */
2025                 return;
2026         }
2027
2028         /* Ensure the protocol is unique.  This prevents confusion when
2029            using Decode As with duplicative entries.
2030
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)
2034         {
2035                 for (entry = sub_dissectors->dissector_handles; entry != NULL; entry = g_slist_next(entry))
2036                 {
2037                         dup_handle = (dissector_handle_t)entry->data;
2038                         if (dup_handle->protocol == handle->protocol)
2039                         {
2040                                 const char *dissector_name, *dup_dissector_name;
2041
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),
2051                                     name);
2052                                 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
2053                                         abort();
2054                         }
2055                 }
2056         }
2057
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);
2061 }
2062
2063 void dissector_add_for_decode_as_with_preference(const char *name,
2064     dissector_handle_t handle)
2065 {
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
2069          */
2070         dissector_add_preference(name, handle, 0);
2071
2072         dissector_add_for_decode_as(name, handle);
2073 }
2074
2075 dissector_handle_t
2076 dtbl_entry_get_initial_handle (dtbl_entry_t *dtbl_entry)
2077 {
2078         return dtbl_entry->initial;
2079 }
2080
2081 GSList *
2082 dissector_table_get_dissector_handles(dissector_table_t dissector_table) {
2083         if (!dissector_table)
2084                 return NULL;
2085
2086         return dissector_table->dissector_handles;
2087 }
2088
2089 /*
2090  * Data structure used as user data when iterating dissector handles
2091  */
2092 typedef struct lookup_entry {
2093         const gchar* dissector_short_name;
2094         dissector_handle_t handle;
2095 } lookup_entry_t;
2096
2097 /*
2098  * A callback function to changed a dissector_handle if matched
2099  * This is used when iterating a dissector table
2100  */
2101 static void
2102 find_dissector_in_table(gpointer item, gpointer user_data)
2103 {
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;
2109         }
2110 }
2111
2112 dissector_handle_t dissector_table_get_dissector_handle(dissector_table_t dissector_table, const gchar* short_name)
2113 {
2114         lookup_entry_t lookup;
2115
2116         lookup.dissector_short_name = short_name;
2117         lookup.handle = NULL;
2118
2119         g_slist_foreach(dissector_table->dissector_handles, find_dissector_in_table, &lookup);
2120         return lookup.handle;
2121 }
2122
2123 ftenum_t
2124 dissector_table_get_type(dissector_table_t dissector_table) {
2125         if (!dissector_table) return FT_NONE;
2126         return dissector_table->type;
2127 }
2128
2129 void
2130 dissector_table_allow_decode_as(dissector_table_t dissector_table)
2131 {
2132         dissector_table->supports_decode_as = TRUE;
2133 }
2134
2135 static gint
2136 uuid_equal(gconstpointer k1, gconstpointer k2)
2137 {
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));
2142 }
2143
2144 static guint
2145 uuid_hash(gconstpointer k)
2146 {
2147     const guid_key *key = (const guid_key *)k;
2148     /* This isn't perfect, but the Data1 part of these is almost always
2149        unique. */
2150     return key->guid.data1;
2151 }
2152
2153 /**************************************************/
2154 /*                                                */
2155 /*       Routines to walk dissector tables        */
2156 /*                                                */
2157 /**************************************************/
2158
2159 typedef struct dissector_foreach_info {
2160         gpointer      caller_data;
2161         DATFunc       caller_func;
2162         GHFunc        next_func;
2163         const gchar  *table_name;
2164         ftenum_t      selector_type;
2165 } dissector_foreach_info_t;
2166
2167 /*
2168  * Called for each entry in a dissector table.
2169  */
2170 static void
2171 dissector_table_foreach_func (gpointer key, gpointer value, gpointer user_data)
2172 {
2173         dissector_foreach_info_t *info;
2174         dtbl_entry_t             *dtbl_entry;
2175
2176         g_assert(value);
2177         g_assert(user_data);
2178
2179         dtbl_entry = (dtbl_entry_t *)value;
2180         if (dtbl_entry->current == NULL ||
2181             dtbl_entry->current->protocol == NULL) {
2182                 /*
2183                  * Either there is no dissector for this entry, or
2184                  * the dissector doesn't have a protocol associated
2185                  * with it.
2186                  *
2187                  * XXX - should the latter check be done?
2188                  */
2189                 return;
2190         }
2191
2192         info = (dissector_foreach_info_t *)user_data;
2193         info->caller_func(info->table_name, info->selector_type, key, value,
2194                           info->caller_data);
2195 }
2196
2197 /*
2198  * Called for each entry in the table of all dissector tables.
2199  */
2200 static void
2201 dissector_all_tables_foreach_func (gpointer key, gpointer value, gpointer user_data)
2202 {
2203         dissector_table_t         sub_dissectors;
2204         dissector_foreach_info_t *info;
2205
2206         g_assert(value);
2207         g_assert(user_data);
2208
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);
2214 }
2215
2216 /*
2217  * Walk all dissector tables calling a user supplied function on each
2218  * entry.
2219  */
2220 static void
2221 dissector_all_tables_foreach (DATFunc func,
2222                               gpointer user_data)
2223 {
2224         dissector_foreach_info_t info;
2225
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);
2230 }
2231
2232 /*
2233  * Walk one dissector table's hash table calling a user supplied function
2234  * on each entry.
2235  */
2236 void
2237 dissector_table_foreach (const char *table_name,
2238                          DATFunc     func,
2239                          gpointer    user_data)
2240 {
2241         dissector_foreach_info_t info;
2242         dissector_table_t        sub_dissectors = find_dissector_table(table_name);
2243
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);
2249 }
2250
2251 /*
2252  * Walk one dissector table's list of handles calling a user supplied
2253  * function on each entry.
2254  */
2255 void
2256 dissector_table_foreach_handle(const char     *table_name,
2257                                DATFunc_handle  func,
2258                                gpointer        user_data)
2259 {
2260         dissector_table_t sub_dissectors = find_dissector_table(table_name);
2261         GSList *tmp;
2262
2263         for (tmp = sub_dissectors->dissector_handles; tmp != NULL;
2264              tmp = g_slist_next(tmp))
2265         func(table_name, tmp->data, user_data);
2266 }
2267
2268 /*
2269  * Called for each entry in a dissector table.
2270  */
2271 static void
2272 dissector_table_foreach_changed_func (gpointer key, gpointer value, gpointer user_data)
2273 {
2274         dtbl_entry_t             *dtbl_entry;
2275         dissector_foreach_info_t *info;
2276
2277         g_assert(value);
2278         g_assert(user_data);
2279
2280         dtbl_entry = (dtbl_entry_t *)value;
2281         if (dtbl_entry->initial == dtbl_entry->current) {
2282                 /*
2283                  * Entry hasn't changed - don't call the function.
2284                  */
2285                 return;
2286         }
2287
2288         info = (dissector_foreach_info_t *)user_data;
2289         info->caller_func(info->table_name, info->selector_type, key, value,
2290                           info->caller_data);
2291 }
2292
2293 /*
2294  * Walk all dissector tables calling a user supplied function only on
2295  * any entry that has been changed from its original state.
2296  */
2297 void
2298 dissector_all_tables_foreach_changed (DATFunc  func,
2299                                       gpointer user_data)
2300 {
2301         dissector_foreach_info_t info;
2302
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);
2307 }
2308
2309 /*
2310  * Walk one dissector table calling a user supplied function only on
2311  * any entry that has been changed from its original state.
2312  */
2313 void
2314 dissector_table_foreach_changed (const char *table_name,
2315                                  DATFunc     func,
2316                                  gpointer    user_data)
2317 {
2318         dissector_foreach_info_t info;
2319         dissector_table_t sub_dissectors = find_dissector_table(table_name);
2320
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);
2327 }
2328
2329 typedef struct dissector_foreach_table_info {
2330         gpointer      caller_data;
2331         DATFunc_table caller_func;
2332 } dissector_foreach_table_info_t;
2333
2334 /*
2335  * Called for each entry in the table of all dissector tables.
2336  * This is used if we directly process the hash table.
2337  */
2338 static void
2339 dissector_all_tables_foreach_table_func (gpointer key, gpointer value, gpointer user_data)
2340 {
2341         dissector_table_t               table;
2342         dissector_foreach_table_info_t *info;
2343
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);
2347 }
2348
2349 /*
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.
2352  */
2353 static void
2354 dissector_all_tables_foreach_list_func (gpointer key, gpointer user_data)
2355 {
2356         dissector_table_t               table;
2357         dissector_foreach_table_info_t *info;
2358
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);
2362 }
2363
2364 /*
2365  * Walk all dissector tables calling a user supplied function on each
2366  * table.
2367  */
2368 void
2369 dissector_all_tables_foreach_table (DATFunc_table func,
2370                                     gpointer      user_data,
2371                                     GCompareFunc  compare_key_func)
2372 {
2373         dissector_foreach_table_info_t info;
2374         GList *list;
2375
2376         info.caller_data = user_data;
2377         info.caller_func = func;
2378         if (compare_key_func != NULL)
2379         {
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);
2383                 g_list_free(list);
2384         }
2385         else
2386         {
2387                 g_hash_table_foreach(dissector_tables, dissector_all_tables_foreach_table_func, &info);
2388         }
2389 }
2390
2391 dissector_table_t
2392 register_dissector_table(const char *name, const char *ui_name, const int proto, const ftenum_t type,
2393                          const int param)
2394 {
2395         dissector_table_t       sub_dissectors;
2396
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);
2400         }
2401
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);
2405         switch (type) {
2406
2407         case FT_UINT8:
2408         case FT_UINT16:
2409         case FT_UINT24:
2410         case FT_UINT32:
2411                 /*
2412                  * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
2413                  * so we use "g_direct_hash()" and "g_direct_equal()".
2414                  */
2415                 sub_dissectors->hash_func = g_direct_hash;
2416                 sub_dissectors->hash_table = g_hash_table_new_full(g_direct_hash,
2417                                                                g_direct_equal,
2418                                                                NULL,
2419                                                                &g_free);
2420                 break;
2421
2422         case FT_STRING:
2423         case FT_STRINGZ:
2424         case FT_STRINGZPAD:
2425                 sub_dissectors->hash_func = g_str_hash;
2426                 sub_dissectors->hash_table = g_hash_table_new_full(g_str_hash,
2427                                                                g_str_equal,
2428                                                                &g_free,
2429                                                                &g_free);
2430                 break;
2431         case FT_GUID:
2432                 sub_dissectors->hash_table = g_hash_table_new_full(uuid_hash,
2433                                                                uuid_equal,
2434                                                                NULL,
2435                                                                &g_free);
2436                 break;
2437
2438         case FT_NONE:
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,
2444                                                                g_direct_equal,
2445                                                                NULL,
2446                                                                &g_free);
2447                 break;
2448
2449         default:
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();
2452         }
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;
2461 }
2462
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)
2465 {
2466         dissector_table_t       sub_dissectors;
2467
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);
2471         }
2472
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,
2478                                                                key_equal_func,
2479                                                                &g_free,
2480                                                                &g_free);
2481
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;
2490 }
2491
2492 void
2493 register_dissector_table_alias(dissector_table_t dissector_table, const char *alias_name) {
2494         if (!dissector_table || !alias_name) return;
2495
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;
2501                         break;
2502                 }
2503         }
2504         g_list_free(list);
2505         if (!name) return;
2506
2507         g_hash_table_insert(dissector_table_aliases, (gpointer) alias_name, (gpointer) name);
2508 }
2509
2510 void
2511 deregister_dissector_table(const char *name)
2512 {
2513         dissector_table_t sub_dissectors = (dissector_table_t) g_hash_table_lookup(dissector_tables, name);
2514         if (!sub_dissectors) return;
2515
2516         g_hash_table_remove(dissector_tables, name);
2517
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);
2523                 }
2524         }
2525         g_list_free(list);
2526 }
2527
2528 const char *
2529 get_dissector_table_ui_name(const char *name)
2530 {
2531         dissector_table_t sub_dissectors = find_dissector_table(name);
2532         if (!sub_dissectors) return NULL;
2533
2534         return sub_dissectors->ui_name;
2535 }
2536
2537 ftenum_t
2538 get_dissector_table_selector_type(const char *name)
2539 {
2540         dissector_table_t sub_dissectors = find_dissector_table(name);
2541         if (!sub_dissectors) return FT_NONE;
2542
2543         return sub_dissectors->type;
2544 }
2545
2546 int
2547 get_dissector_table_param(const char *name)
2548 {
2549         dissector_table_t sub_dissectors = find_dissector_table(name);
2550         if (!sub_dissectors) return 0;
2551
2552         return sub_dissectors->param;
2553 }
2554
2555 /* Finds a heuristic dissector table by table name. */
2556 heur_dissector_list_t
2557 find_heur_dissector_list(const char *name)
2558 {
2559         return (heur_dissector_list_t)g_hash_table_lookup(heur_dissector_lists, name);
2560 }
2561
2562 gboolean
2563 has_heur_dissector_list(const gchar *name) {
2564         return (find_heur_dissector_list(name) != NULL);
2565 }
2566
2567 heur_dtbl_entry_t* find_heur_dissector_by_unique_short_name(const char *short_name)
2568 {
2569         return (heur_dtbl_entry_t*)g_hash_table_lookup(heuristic_short_names, short_name);
2570 }
2571
2572 void
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)
2574 {
2575         heur_dissector_list_t  sub_dissectors = find_heur_dissector_list(name);
2576         const char            *proto_name;
2577         heur_dtbl_entry_t     *hdtbl_entry;
2578         guint                  i, list_size;
2579         GSList                *list_entry;
2580
2581         /*
2582          * Make sure the dissector table exists.
2583          */
2584         if (sub_dissectors == NULL) {
2585                 fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
2586                     name);
2587                 proto_name = proto_get_protocol_name(proto);
2588                 if (proto_name != NULL) {
2589                         fprintf(stderr, "Protocol being registered is \"%s\"\n",
2590                             proto_name);
2591                 }
2592                 if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
2593                         abort();
2594                 return;
2595         }
2596
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++)
2600         {
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)))
2605                 {
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",
2609                                     proto_name, name);
2610                         }
2611                         if (getenv("WIRESHARK_ABORT_ON_DISSECTOR_BUG") != NULL)
2612                                 abort();
2613                         return;
2614                 }
2615         }
2616
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);
2621         }
2622
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);
2630
2631         /* do the table insertion */
2632         g_hash_table_insert(heuristic_short_names, (gpointer)hdtbl_entry->short_name, hdtbl_entry);
2633
2634         sub_dissectors->dissectors = g_slist_prepend(sub_dissectors->dissectors,
2635             (gpointer)hdtbl_entry);
2636
2637         /* XXX - could be optimized to pass hdtbl_entry directly */
2638         proto_add_heuristic_dissector(hdtbl_entry->protocol, hdtbl_entry->short_name);
2639
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));
2645 }
2646
2647
2648
2649 static int
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;
2653
2654         return (hdtbl_entry_a->dissector == hdtbl_entry_b->dissector) &&
2655                 (hdtbl_entry_a->protocol == hdtbl_entry_b->protocol) ? 0 : 1;
2656 }
2657
2658 void
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;
2663
2664         /* sanity check */
2665         g_assert(sub_dissectors != NULL);
2666
2667         hdtbl_entry.dissector = dissector;
2668         hdtbl_entry.protocol  = find_protocol_by_id(proto);
2669
2670         found_entry = g_slist_find_custom(sub_dissectors->dissectors,
2671             (gpointer) &hdtbl_entry, find_matching_heur_dissector);
2672
2673         if (found_entry) {
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,
2680                     found_entry);
2681         }
2682 }
2683
2684 gboolean
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)
2687 {
2688         gboolean           status;
2689         const char        *saved_curr_proto;
2690         const char        *saved_heur_list_name;
2691         GSList            *entry;
2692         guint16            saved_can_desegment;
2693         guint              saved_layers_len = 0;
2694         heur_dtbl_entry_t *hdtbl_entry;
2695         int                proto_id;
2696         int                len;
2697         int                saved_tree_count = tree ? tree->tree_data->count : 0;
2698
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
2702            service can use it.
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.
2707         */
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);
2711
2712         status      = FALSE;
2713         saved_curr_proto = pinfo->current_proto;
2714         saved_heur_list_name = pinfo->heur_list_name;
2715
2716         saved_layers_len = wmem_list_count(pinfo->layers);
2717         *heur_dtbl_entry = NULL;
2718
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;
2724
2725                 if (hdtbl_entry->protocol != NULL &&
2726                         (!proto_is_protocol_enabled(hdtbl_entry->protocol)||(hdtbl_entry->enabled==FALSE))) {
2727                         /*
2728                          * No - don't try this dissector.
2729                          */
2730                         continue;
2731                 }
2732
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);
2739
2740                         /*
2741                          * Add the protocol name to the layers; we'll remove it
2742                          * if the dissector fails.
2743                          */
2744                         pinfo->curr_layer_num++;
2745                         wmem_list_append(pinfo->layers, GINT_TO_POINTER(proto_id));
2746                 }
2747
2748                 pinfo->heur_list_name = hdtbl_entry->list_name;
2749
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))) {
2753                         /*
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.
2757                          */
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));
2761                         }
2762                 }
2763                 if (len) {
2764                         *heur_dtbl_entry = hdtbl_entry;
2765                         status = TRUE;
2766                         break;
2767                 }
2768         }
2769
2770         pinfo->current_proto = saved_curr_proto;
2771         pinfo->heur_list_name = saved_heur_list_name;
2772         pinfo->can_desegment = saved_can_desegment;
2773         return status;
2774 }
2775
2776 typedef struct heur_dissector_foreach_info {
2777         gpointer      caller_data;
2778         DATFunc_heur  caller_func;
2779         GHFunc        next_func;
2780         const gchar  *table_name;
2781 } heur_dissector_foreach_info_t;
2782
2783 /*
2784  * Called for each entry in a heuristic dissector table.
2785  */
2786 static void
2787 heur_dissector_table_foreach_func (gpointer data, gpointer user_data)
2788 {
2789         heur_dissector_foreach_info_t *info;
2790
2791         g_assert(data);
2792         g_assert(user_data);
2793
2794         info = (heur_dissector_foreach_info_t *)user_data;
2795         info->caller_func(info->table_name, (heur_dtbl_entry_t *)data,
2796                           info->caller_data);
2797 }
2798
2799 /*
2800  * Walk one heuristic dissector table's list calling a user supplied function
2801  * on each entry.
2802  */
2803 void
2804 heur_dissector_table_foreach (const char  *table_name,
2805                               DATFunc_heur func,
2806                               gpointer     user_data)
2807 {
2808         heur_dissector_foreach_info_t info;
2809         heur_dissector_list_t         sub_dissectors = find_heur_dissector_list(table_name);
2810
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);
2816 }
2817
2818 /*
2819  * Called for each entry in the table of all heuristic dissector tables.
2820  */
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;
2825
2826 /*
2827  * Called for each entry in the table of all heuristic dissector tables.
2828  * This is used if we directly process the hash table.
2829  */
2830 static void
2831 dissector_all_heur_tables_foreach_table_func (gpointer key, gpointer value, gpointer user_data)
2832 {
2833         heur_dissector_foreach_table_info_t *info;
2834
2835         info = (heur_dissector_foreach_table_info_t *)user_data;
2836     (*info->caller_func)((gchar *)key, (struct heur_dissector_list *)value, info->caller_data);
2837 }
2838
2839 /*
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.
2842  */
2843 static void
2844 dissector_all_heur_tables_foreach_list_func (gpointer key, gpointer user_data)
2845 {
2846     struct heur_dissector_list          *list;
2847         heur_dissector_foreach_table_info_t *info;
2848
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);
2852 }
2853
2854 /*
2855  * Walk all heuristic dissector tables calling a user supplied function on each
2856  * table.
2857  */
2858 void
2859 dissector_all_heur_tables_foreach_table (DATFunc_heur_table func,
2860                                          gpointer           user_data,
2861                                          GCompareFunc       compare_key_func)
2862 {
2863         heur_dissector_foreach_table_info_t info;
2864         GList *list;
2865
2866         info.caller_data = user_data;
2867         info.caller_func = func;
2868         if (compare_key_func != NULL)
2869         {
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);
2873                 g_list_free(list);
2874         }
2875         else
2876         {
2877                 g_hash_table_foreach(heur_dissector_lists, dissector_all_heur_tables_foreach_table_func, &info);
2878         }
2879 }
2880
2881 static void
2882 display_heur_dissector_table_entries(const char *table_name,
2883     heur_dtbl_entry_t *hdtbl_entry, gpointer user_data _U_)
2884 {
2885         if (hdtbl_entry->protocol != NULL) {
2886                 ws_debug_printf("%s\t%s\t%c\n",
2887                        table_name,
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');
2890         }
2891 }
2892
2893 static void
2894 dissector_dump_heur_decodes_display(const gchar *table_name, struct heur_dissector_list *listptr _U_, gpointer user_data _U_)
2895 {
2896         heur_dissector_table_foreach(table_name, display_heur_dissector_table_entries, NULL);
2897 }
2898
2899 /*
2900  * For each heuristic dissector table, dump list of dissectors (filter_names) for that table
2901  */
2902 void
2903 dissector_dump_heur_decodes(void)
2904 {
2905         dissector_all_heur_tables_foreach_table(dissector_dump_heur_decodes_display, NULL, NULL);
2906 }
2907
2908
2909 heur_dissector_list_t
2910 register_heur_dissector_list(const char *name, const int proto)
2911 {
2912         heur_dissector_list_t sub_dissectors;
2913
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);
2917         }
2918
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;
2927 }
2928
2929 /*
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".
2934  */
2935
2936 /* Get the long name of the protocol for a dissector handle, if it has
2937    a protocol. */
2938 const char *
2939 dissector_handle_get_long_name(const dissector_handle_t handle)
2940 {
2941         if (handle == NULL || handle->protocol == NULL) {
2942                 return NULL;
2943         }
2944         return proto_get_protocol_long_name(handle->protocol);
2945 }
2946
2947 /* Get the short name of the protocol for a dissector handle, if it has
2948    a protocol. */
2949 const char *
2950 dissector_handle_get_short_name(const dissector_handle_t handle)
2951 {
2952         if (handle->protocol == NULL) {
2953                 /*
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
2957                  * ID).
2958                  */
2959                 return NULL;
2960         }
2961         return proto_get_protocol_short_name(handle->protocol);
2962 }
2963
2964 /* Get the index of the protocol for a dissector handle, if it has
2965    a protocol. */
2966 int
2967 dissector_handle_get_protocol_index(const dissector_handle_t handle)
2968 {
2969         if (handle->protocol == NULL) {
2970                 /*
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
2974                  * ID).
2975                  */
2976                 return -1;
2977         }
2978         return proto_get_id(handle->protocol);
2979 }
2980
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. */
2984 GList*
2985 get_dissector_names(void)
2986 {
2987         return g_hash_table_get_keys(registered_dissectors);
2988 }
2989
2990 /* Find a registered dissector by name. */
2991 dissector_handle_t
2992 find_dissector(const char *name)
2993 {
2994         return (dissector_handle_t)g_hash_table_lookup(registered_dissectors, name);
2995 }
2996
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)
2999 {
3000         dissector_handle_t handle = (dissector_handle_t)g_hash_table_lookup(registered_dissectors, name);
3001         if ((handle != NULL) && (parent_proto > 0))
3002         {
3003                 register_depend_dissector(proto_get_protocol_short_name(find_protocol_by_id(parent_proto)), dissector_handle_get_short_name(handle));
3004         }
3005
3006         return handle;
3007 }
3008
3009 /* Get a dissector name from handle. */
3010 const char *
3011 dissector_handle_get_dissector_name(const dissector_handle_t handle)
3012 {
3013         if (handle == NULL) {
3014                 return NULL;
3015         }
3016         return handle->name;
3017 }
3018
3019 static dissector_handle_t
3020 new_dissector_handle(enum dissector_e type, void *dissector, const int proto, const char *name, void *cb_data)
3021 {
3022         struct dissector_handle *handle;
3023
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);
3030         return handle;
3031 }
3032
3033 /* Create an anonymous handle for a new dissector. */
3034 dissector_handle_t
3035 create_dissector_handle(dissector_t dissector, const int proto)
3036 {
3037         return new_dissector_handle(DISSECTOR_TYPE_SIMPLE, dissector, proto, NULL, NULL);
3038 }
3039
3040 dissector_handle_t
3041 create_dissector_handle_with_name(dissector_t dissector,
3042                                 const int proto, const char* name)
3043 {
3044         return new_dissector_handle(DISSECTOR_TYPE_SIMPLE, dissector, proto, name, NULL);
3045 }
3046
3047 /* Destroy an anonymous handle for a dissector. */
3048 static void
3049 destroy_dissector_handle(dissector_handle_t handle)
3050 {
3051         if (handle == NULL) return;
3052
3053         dissector_delete_from_all_tables(handle);
3054         deregister_postdissector(handle);
3055         wmem_free(wmem_epan_scope(), handle);
3056 }
3057
3058 static dissector_handle_t
3059 register_dissector_handle(const char *name, dissector_handle_t handle)
3060 {
3061         /* Make sure the registration is unique */
3062         g_assert(g_hash_table_lookup(registered_dissectors, name) == NULL);
3063
3064         g_hash_table_insert(registered_dissectors, (gpointer)name, handle);
3065
3066         return handle;
3067 }
3068
3069 /* Register a new dissector by name. */
3070 dissector_handle_t
3071 register_dissector(const char *name, dissector_t dissector, const int proto)
3072 {
3073         struct dissector_handle *handle;
3074
3075         handle = new_dissector_handle(DISSECTOR_TYPE_SIMPLE, dissector, proto, name, NULL);
3076
3077         return register_dissector_handle(name, handle);
3078 }
3079
3080 dissector_handle_t
3081 register_dissector_with_data(const char *name, dissector_cb_t dissector, const int proto, void *cb_data)
3082 {
3083         struct dissector_handle *handle;
3084
3085         handle = new_dissector_handle(DISSECTOR_TYPE_CALLBACK, dissector, proto, name, cb_data);
3086
3087         return register_dissector_handle(name, handle);
3088 }
3089
3090 static gboolean
3091 remove_depend_dissector_from_list(depend_dissector_list_t sub_dissectors, const char *dependent)
3092 {
3093         GSList *found_entry;
3094
3095         found_entry = g_slist_find_custom(sub_dissectors->dissectors,
3096                 dependent, (GCompareFunc)strcmp);
3097
3098         if (found_entry) {
3099                 g_free(found_entry->data);
3100                 sub_dissectors->dissectors = g_slist_delete_link(sub_dissectors->dissectors, found_entry);
3101                 return TRUE;
3102         }
3103
3104         return FALSE;
3105 }
3106
3107 static void
3108 remove_depend_dissector_ghfunc(gpointer key _U_, gpointer value, gpointer user_data)
3109 {
3110         depend_dissector_list_t sub_dissectors = (depend_dissector_list_t) value;
3111         const char *dependent = (const char *)user_data;
3112
3113         remove_depend_dissector_from_list(sub_dissectors, dependent);
3114 }
3115
3116 /* Deregister a dissector by name. */
3117 void
3118 deregister_dissector(const char *name)
3119 {
3120         dissector_handle_t handle = find_dissector(name);
3121         if (handle == NULL) return;
3122
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);
3127
3128         destroy_dissector_handle(handle);
3129 }
3130
3131 /* Call a dissector through a handle but if the dissector rejected it
3132  * return 0.
3133  */
3134 int
3135 call_dissector_only(dissector_handle_t handle, tvbuff_t *tvb,
3136                     packet_info *pinfo, proto_tree *tree, void *data)
3137 {
3138         int ret;
3139
3140         g_assert(handle != NULL);
3141         ret = call_dissector_work(handle, tvb, pinfo, tree, TRUE, data);
3142         return ret;
3143 }
3144
3145 /* Call a dissector through a handle and if this fails call the "data"
3146  * dissector.
3147  */
3148 int
3149 call_dissector_with_data(dissector_handle_t handle, tvbuff_t *tvb,
3150                          packet_info *pinfo, proto_tree *tree, void *data)
3151 {
3152         int ret;
3153
3154         ret = call_dissector_only(handle, tvb, pinfo, tree, data);
3155         if (ret == 0) {
3156                 /*
3157                  * The protocol was disabled, or the dissector rejected
3158                  * it.  Just dissect this packet as data.
3159                  */
3160                 g_assert(data_handle->protocol != NULL);
3161                 call_dissector_work(data_handle, tvb, pinfo, tree, TRUE, NULL);
3162                 return tvb_captured_length(tvb);
3163         }
3164         return ret;
3165 }
3166
3167 int
3168 call_dissector(dissector_handle_t handle, tvbuff_t *tvb,
3169                packet_info *pinfo, proto_tree *tree)
3170 {
3171         return call_dissector_with_data(handle, tvb, pinfo, tree, NULL);
3172 }
3173
3174 int
3175 call_data_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3176 {
3177         return call_dissector_work(data_handle, tvb, pinfo, tree, TRUE, NULL);
3178 }
3179
3180 /*
3181  * Call a heuristic dissector through a heur_dtbl_entry
3182  */
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)
3185 {
3186         const char        *saved_curr_proto;
3187         const char        *saved_heur_list_name;
3188         guint16            saved_can_desegment;
3189         guint              saved_layers_len = 0;
3190
3191         g_assert(heur_dtbl_entry);
3192
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
3196            service can use it.
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.
3201         */
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);
3205
3206         saved_curr_proto = pinfo->current_proto;
3207         saved_heur_list_name = pinfo->heur_list_name;
3208
3209         saved_layers_len = wmem_list_count(pinfo->layers);
3210
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);
3215                 return;
3216         }
3217
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)));
3224         }
3225
3226         pinfo->heur_list_name = heur_dtbl_entry->list_name;
3227
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);
3231
3232                 /*
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.
3236                  */
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));
3240                 }
3241         }
3242
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;
3247
3248 }
3249
3250 static gint
3251 find_matching_proto_name(gconstpointer arg1, gconstpointer arg2)
3252 {
3253         const char    *protocol_name = (const char*)arg1;
3254         const gchar   *name   = (const gchar *)arg2;
3255
3256         return strcmp(protocol_name, name);
3257 }
3258
3259 gboolean register_depend_dissector(const char* parent, const char* dependent)
3260 {
3261         GSList                *list_entry;
3262         depend_dissector_list_t sub_dissectors;
3263
3264         if ((parent == NULL) || (dependent == NULL))
3265         {
3266                 /* XXX - assert on parent? */
3267                 return FALSE;
3268         }
3269
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);
3276         }
3277
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 */
3282
3283         sub_dissectors->dissectors = g_slist_prepend(sub_dissectors->dissectors, (gpointer)g_strdup(dependent));
3284         return TRUE;
3285 }
3286
3287 gboolean deregister_depend_dissector(const char* parent, const char* dependent)
3288 {
3289         depend_dissector_list_t  sub_dissectors = find_depend_dissector_list(parent);
3290
3291         /* sanity check */
3292         g_assert(sub_dissectors != NULL);
3293
3294         return remove_depend_dissector_from_list(sub_dissectors, dependent);
3295 }
3296
3297 depend_dissector_list_t find_depend_dissector_list(const char* name)
3298 {
3299         return (depend_dissector_list_t)g_hash_table_lookup(depend_dissector_lists, name);
3300 }
3301
3302 /*
3303  * Dumps the "layer type"/"decode as" associations to stdout, similar
3304  * to the proto_registrar_dump_*() routines.
3305  *
3306  * There is one record per line. The fields are tab-delimited.
3307  *
3308  * Field 1 = layer type, e.g. "tcp.port"
3309  * Field 2 = selector in decimal
3310  * Field 3 = "decode as" name, e.g. "http"
3311  */
3312
3313
3314 static void
3315 dissector_dump_decodes_display(const gchar *table_name,
3316                                ftenum_t selector_type _U_, gpointer key, gpointer value,
3317                                gpointer user_data _U_)
3318 {
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;
3323         gint                proto_id;
3324         const gchar        *decode_as;
3325
3326         g_assert(sub_dissectors);
3327         switch (sub_dissectors->type) {
3328
3329                 case FT_UINT8:
3330                 case FT_UINT16:
3331                 case FT_UINT24:
3332                 case FT_UINT32:
3333                         dtbl_entry = (dtbl_entry_t *)value;
3334                         g_assert(dtbl_entry);
3335
3336                         handle   = dtbl_entry->current;
3337                         g_assert(handle);
3338
3339                         proto_id = dissector_handle_get_protocol_index(handle);
3340
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);
3345                         }
3346                         break;
3347
3348         default:
3349                 break;
3350         }
3351 }
3352
3353 void
3354 dissector_dump_decodes(void)
3355 {
3356         dissector_all_tables_foreach(dissector_dump_decodes_display, NULL);
3357 }
3358
3359 /*
3360  * Dumps the "layer type"/"decode as" associations to stdout, similar
3361  * to the proto_registrar_dump_*() routines.
3362  *
3363  * There is one record per line. The fields are tab-delimited.
3364  *
3365  * Field 1 = layer type, e.g. "tcp.port"
3366  * Field 2 = selector in decimal
3367  * Field 3 = "decode as" name, e.g. "http"
3368  */
3369
3370
3371 static void
3372 dissector_dump_dissector_tables_display (gpointer key, gpointer user_data _U_)
3373 {
3374         const char              *table_name = (const char *)key;
3375         dissector_table_t       table;
3376
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) {
3380
3381         case FT_UINT8:
3382         case FT_UINT16:
3383         case FT_UINT24:
3384         case FT_UINT32:
3385                 switch(table->param) {
3386
3387                 case BASE_NONE:
3388                         ws_debug_printf("\tBASE_NONE");
3389                         break;
3390
3391                 case BASE_DEC:
3392                         ws_debug_printf("\tBASE_DEC");
3393                         break;
3394
3395                 case BASE_HEX:
3396                         ws_debug_printf("\tBASE_HEX");
3397                         break;
3398
3399                 case BASE_DEC_HEX:
3400                         ws_debug_printf("\tBASE_DEC_HEX");
3401                         break;
3402
3403                 case BASE_HEX_DEC:
3404                         ws_debug_printf("\tBASE_HEX_DEC");
3405                         break;
3406
3407                 default:
3408                         ws_debug_printf("\t%d", table->param);
3409                         break;
3410                 }
3411                 break;
3412
3413         default:
3414                 break;
3415         }
3416         if (table->protocol != NULL) {
3417                 ws_debug_printf("\t%s",
3418                     proto_get_protocol_short_name(table->protocol));
3419         } else
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");
3424 }
3425
3426 static gint
3427 compare_dissector_key_name(gconstpointer dissector_a, gconstpointer dissector_b)
3428 {
3429   return strcmp((const char*)dissector_a, (const char*)dissector_b);
3430 }
3431
3432 void
3433 dissector_dump_dissector_tables(void)
3434 {
3435         GList *list;
3436
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);
3440         g_list_free(list);
3441 }
3442
3443 void
3444 register_postdissector(dissector_handle_t handle)
3445 {
3446         postdissector p;
3447
3448         if (!postdissectors)
3449                 postdissectors = g_array_sized_new(FALSE, FALSE, (guint)sizeof(postdissector), 1);
3450
3451         p.handle = handle;
3452         p.wanted_hfids = NULL;
3453         postdissectors = g_array_append_val(postdissectors, p);
3454 }
3455
3456 void
3457 set_postdissector_wanted_hfids(dissector_handle_t handle, GArray *wanted_hfids)
3458 {
3459         guint i;
3460
3461         if (!postdissectors) return;
3462
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);
3467                         }
3468                         POSTDISSECTORS(i).wanted_hfids = wanted_hfids;
3469                         break;
3470                 }
3471         }
3472 }
3473
3474 void
3475 deregister_postdissector(dissector_handle_t handle)
3476 {
3477         guint i;
3478
3479         if (!postdissectors) return;
3480
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);
3485                         }
3486                         postdissectors = g_array_remove_index_fast(postdissectors, i);
3487                         break;
3488                 }
3489         }
3490 }
3491
3492 gboolean
3493 have_postdissector(void)
3494 {
3495         guint i;
3496         dissector_handle_t handle;
3497
3498         for (i = 0; i < postdissectors->len; i++) {
3499                 handle = POSTDISSECTORS(i).handle;
3500
3501                 if (handle->protocol != NULL
3502                     && proto_is_protocol_enabled(handle->protocol)) {
3503                         /* We have at least one enabled postdissector */
3504                         return TRUE;
3505                 }
3506         }
3507         return FALSE;
3508 }
3509
3510 void
3511 call_all_postdissectors(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3512 {
3513         guint i;
3514
3515         for (i = 0; i < postdissectors->len; i++) {
3516                 call_dissector_only(POSTDISSECTORS(i).handle,
3517                                     tvb, pinfo, tree, NULL);
3518         }
3519 }
3520
3521 gboolean
3522 postdissectors_want_hfids(void)
3523 {
3524         guint i;
3525
3526         for (i = 0; i < postdissectors->len; i++) {
3527                 if (POSTDISSECTORS(i).wanted_hfids != NULL &&
3528                     POSTDISSECTORS(i).wanted_hfids->len != 0)
3529                         return TRUE;
3530         }
3531         return FALSE;
3532 }
3533
3534 void
3535 prime_epan_dissect_with_postdissector_wanted_hfids(epan_dissect_t *edt)
3536 {
3537         guint i;
3538
3539         if (postdissectors == NULL) {
3540                 /*
3541                  * No postdissector expressed an interest in any hfids.
3542                  */
3543                 return;
3544         }
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);
3550         }
3551 }
3552
3553 /*
3554  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
3555  *
3556  * Local variables:
3557  * c-basic-offset: 8
3558  * tab-width: 8
3559  * indent-tabs-mode: t
3560  * End:
3561  *
3562  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
3563  * :indentSize=8:tabSize=8:noTabs=false:
3564  */