Coverage Report

Created: 2026-01-02 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/packet.c
Line
Count
Source
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
10.1k
#define WS_LOG_DOMAIN LOG_DOMAIN_EPAN
13
14
#include <glib.h>
15
16
#include <stdio.h>
17
#include <stdlib.h>
18
19
#include <stdarg.h>
20
#include <string.h>
21
#include <time.h>
22
23
#include <epan/packet.h>
24
#include "timestamp.h"
25
26
#include "osi-utils.h"
27
#include "to_str.h"
28
29
#include "addr_resolv.h"
30
#include "tvbuff.h"
31
#include "epan_dissect.h"
32
33
#include <epan/wmem_scopes.h>
34
35
#include <epan/column-info.h>
36
#include <epan/exceptions.h>
37
#include <epan/reassemble.h>
38
#include <epan/stream.h>
39
#include <epan/expert.h>
40
#include <epan/prefs.h>
41
#include <epan/range.h>
42
43
#include <wsutil/str_util.h>
44
#include <wsutil/wslog.h>
45
#include <wsutil/ws_assert.h>
46
47
static int proto_malformed;
48
static dissector_handle_t frame_handle;
49
static dissector_handle_t file_handle;
50
static dissector_handle_t data_handle;
51
52
/**
53
 * A data source.
54
 * Has a tvbuff and a name.
55
 */
56
struct data_source {
57
  tvbuff_t *tvb;
58
  char *name;
59
  data_source_media_type_e media_type;
60
};
61
62
/*
63
 * A dissector table.
64
 *
65
 * "hash_table" is a hash table, indexed by port number, supplying
66
 * a "struct dtbl_entry"; it records what dissector is assigned to
67
 * that uint or string value in that table.
68
 *
69
 * "dissector_handles" is a list of all dissectors that *could* be
70
 * used in that table; not all of them are necessarily in the table,
71
 * as they may be for protocols that don't have a fixed uint value,
72
 * e.g. for TCP or UDP port number tables and protocols with no fixed
73
 * port number. It's only non-NULL for tables that allow "Decode As".
74
 * After initial handoff registration, it's sorted by the filter name
75
 * of the protocol associated with the handle (using an empty string
76
 * if there is no protocol.) That's mostly for tshark -d error messages;
77
 * the GUI re-sorts by the dissector handle description. (XXX - They
78
 * could be sorted on first use, especially if that's the only user.)
79
 *
80
 * "da_descriptions" is a hash table, keyed by dissector handle description,
81
 * of all the dissector handles that could be used for Decode As. The
82
 * descriptions are what are presented in the GUI and what are written
83
 * to the decode_as_entries UAT.
84
 *
85
 * "ui_name" is the name the dissector table has in the user interface.
86
 *
87
 * "type" is a field type giving the width of the uint value for that
88
 * dissector table, if it's a uint dissector table.
89
 *
90
 * "param" is the base in which to display the uint value for that
91
 * dissector table, if it's a uint dissector table, or if it's a string
92
 * table, true/false to indicate case-insensitive or not.
93
 *
94
 * "protocol" is the protocol associated with the dissector table. Used
95
 * for determining dependencies.
96
 */
97
struct dissector_table {
98
  GHashTable  *hash_table;
99
  GSList    *dissector_handles;
100
  GHashTable  *da_descriptions;
101
  const char  *ui_name;
102
  ftenum_t  type;
103
  int   param;
104
  protocol_t  *protocol;
105
  GHashFunc hash_func;
106
  bool  supports_decode_as;
107
};
108
109
/*
110
 * Dissector tables. const char * -> dissector_table *
111
 */
112
static GHashTable *dissector_tables;
113
static bool all_tables_handles_sorted = false;
114
115
/*
116
 * Dissector table aliases. const char * -> const char *
117
 */
118
static GHashTable *dissector_table_aliases;
119
120
/*
121
 * List of registered dissectors.
122
 */
123
static GHashTable *registered_dissectors;
124
125
/*
126
 * A dissector dependency list.
127
 * XXX - These are protocol short names, not dissectors (which is likely
128
 * what we want, as protocols are enabled and disabled, not dissectors
129
 * other than heuristic dissectors.)
130
 */
131
struct depend_dissector_list {
132
  GHashTable  *dissectors;
133
};
134
135
/* Maps char * protocol short name to depend_dissector_list_t
136
 * XXX - This doesn't get freed when proto_deregister_dissector
137
 * is called. Might it make sense to store this information in
138
 * the proto_t?
139
 * XXX - Which direction should these be stored? Issue #1402 discusses,
140
 * e.g., if HTTP is enabled then making sure that lower level protocols
141
 * like TLS, TCP, IP, etc. are enabled. But here as registered the key
142
 * is the protocol of the dissector that calls the other handle (whether
143
 * via table or registered with _add_dependency.) That is, "TCP" and
144
 * "TLS" are keys that have "HTTP" in their depend_dissector_list, rather
145
 * than the other way around. Either use could be interesting (a bit moot
146
 * since this isn't actually used yet.)
147
 */
148
static GHashTable *depend_dissector_lists;
149
150
/* Allow protocols to register a "cleanup" routine to be
151
 * run after the initial sequential run through the packets.
152
 * Note that the file can still be open after this; this is not
153
 * the final cleanup. */
154
static GSList *postseq_cleanup_routines;
155
156
/*
157
 * Post-dissector information - handle for the dissector and a list
158
 * of hfids for the fields the post-dissector wants.
159
 */
160
typedef struct {
161
  dissector_handle_t handle;
162
  GArray *wanted_hfids;
163
} postdissector;
164
165
/*
166
 * Array of all postdissectors.
167
 */
168
static GArray *postdissectors;
169
170
/*
171
 * i-th element of that array.
172
 */
173
2.31M
#define POSTDISSECTORS(i) g_array_index(postdissectors, postdissector, i)
174
175
static void
176
destroy_depend_dissector_list(void *data)
177
0
{
178
0
       depend_dissector_list_t dissector_list = (depend_dissector_list_t)data;
179
0
       GHashTable *table = dissector_list->dissectors;
180
181
0
       g_hash_table_destroy(table);
182
0
       g_slice_free(struct depend_dissector_list, dissector_list);
183
0
}
184
185
/*
186
 * A heuristics dissector list.
187
 */
188
struct heur_dissector_list {
189
  const char  *ui_name;
190
  protocol_t  *protocol;
191
  GSList    *dissectors;
192
};
193
194
static GHashTable *heur_dissector_lists;
195
196
/* Name hashtables for fast detection of duplicate names */
197
static GHashTable* heuristic_short_names;
198
199
static void
200
destroy_heuristic_dissector_entry(void *data)
201
0
{
202
0
  heur_dtbl_entry_t *hdtbl_entry = (heur_dtbl_entry_t *)data;
203
0
  g_free(hdtbl_entry->list_name);
204
0
  g_free(hdtbl_entry->short_name);
205
0
  g_slice_free(heur_dtbl_entry_t, data);
206
0
}
207
208
static void
209
destroy_heuristic_dissector_list(void *data)
210
0
{
211
0
  heur_dissector_list_t dissector_list = (heur_dissector_list_t)data;
212
0
  GSList **list = &(dissector_list->dissectors);
213
214
0
  g_slist_free_full(*list, destroy_heuristic_dissector_entry);
215
0
  g_slice_free(struct heur_dissector_list, dissector_list);
216
0
}
217
218
static void
219
destroy_dissector_table(void *data)
220
0
{
221
0
  struct dissector_table *table = (struct dissector_table *)data;
222
223
0
  g_hash_table_destroy(table->hash_table);
224
0
  g_slist_free(table->dissector_handles);
225
0
  if (table->da_descriptions)
226
0
    g_hash_table_destroy(table->da_descriptions);
227
0
  g_slice_free(struct dissector_table, data);
228
0
}
229
230
void
231
packet_init(void)
232
14
{
233
14
  dissector_tables = g_hash_table_new_full(g_str_hash, g_str_equal,
234
14
      NULL, destroy_dissector_table);
235
14
  all_tables_handles_sorted = false;
236
237
14
  dissector_table_aliases = g_hash_table_new_full(g_str_hash, g_str_equal,
238
14
      NULL, NULL);
239
240
14
  registered_dissectors = g_hash_table_new_full(g_str_hash, g_str_equal,
241
14
      NULL, NULL);
242
243
14
  postdissectors = g_array_sized_new(false, false, (unsigned)sizeof(postdissector), 1);
244
245
14
  depend_dissector_lists = g_hash_table_new_full(g_str_hash, g_str_equal,
246
14
      g_free, destroy_depend_dissector_list);
247
248
14
  heur_dissector_lists = g_hash_table_new_full(g_str_hash, g_str_equal,
249
14
      NULL, destroy_heuristic_dissector_list);
250
251
14
  heuristic_short_names  = g_hash_table_new(g_str_hash, g_str_equal);
252
14
}
253
254
void
255
packet_cache_proto_handles(void)
256
14
{
257
14
  frame_handle = find_dissector("frame");
258
14
  ws_assert(frame_handle != NULL);
259
260
14
  file_handle = find_dissector("file");
261
14
  ws_assert(file_handle != NULL);
262
263
14
  data_handle = find_dissector("data");
264
14
  ws_assert(data_handle != NULL);
265
266
14
  proto_malformed = proto_get_id_by_filter_name("_ws.malformed");
267
14
  ws_assert(proto_malformed != -1);
268
14
}
269
270
/* List of routines that are called before we make a pass through a capture file
271
 * and dissect all its packets. See register_init_routine, register_cleanup_routine
272
 * and register_shutdown_routine in packet.h */
273
/**
274
 * List of "init" routines, which are called before we make a pass through
275
 * a capture file and dissect all its packets (e.g., when we read in a
276
 * new capture file, or run a "filter packets" or "colorize packets"
277
 * pass over the current capture file or when the preferences are changed).
278
 *
279
 * See register_init_routine().
280
 */
281
static GSList *init_routines;
282
283
/**
284
 * List of "cleanup" routines, which are called after closing a capture
285
 * file (or when preferences are changed; in that case these routines
286
 * are called before the init routines are executed). They can be used
287
 * to release resources that are allocated in an "init" routine.
288
 *
289
 * See register_cleanup_routine().
290
 */
291
static GSList *cleanup_routines;
292
293
/*
294
 * List of "shutdown" routines, which are called once, just before
295
 * program exit.
296
 *
297
 * See register_shutdown_routine().
298
 */
299
static GSList *shutdown_routines;
300
301
typedef void (*void_func_t)(void);
302
303
/* Initialize all data structures used for dissection. */
304
static void
305
call_routine(void *routine, void *dummy _U_)
306
1.33k
{
307
1.33k
  void_func_t func = (void_func_t)routine;
308
1.33k
  (*func)();
309
1.33k
}
310
311
void
312
packet_cleanup(void)
313
0
{
314
0
  g_slist_free(init_routines);
315
0
  g_slist_free(cleanup_routines);
316
0
  g_slist_free(postseq_cleanup_routines);
317
0
  g_hash_table_destroy(dissector_tables);
318
0
  g_hash_table_destroy(dissector_table_aliases);
319
0
  g_hash_table_destroy(registered_dissectors);
320
0
  g_hash_table_destroy(depend_dissector_lists);
321
0
  g_hash_table_destroy(heur_dissector_lists);
322
0
  g_hash_table_destroy(heuristic_short_names);
323
0
  g_slist_foreach(shutdown_routines, &call_routine, NULL);
324
0
  g_slist_free(shutdown_routines);
325
0
  if (postdissectors) {
326
0
    for (unsigned i = 0; i < postdissectors->len; i++) {
327
0
      if (POSTDISSECTORS(i).wanted_hfids) {
328
0
        g_array_free(POSTDISSECTORS(i).wanted_hfids, true);
329
0
      }
330
0
    }
331
0
    g_array_free(postdissectors, true);
332
0
  }
333
0
}
334
335
/*
336
 * Given a tvbuff, and a length from a packet header, adjust the length
337
 * of the tvbuff to reflect the specified length.
338
 */
339
void
340
set_actual_length(tvbuff_t *tvb, const unsigned specified_len)
341
39.6k
{
342
39.6k
  if (specified_len < tvb_reported_length(tvb)) {
343
    /* Adjust the length of this tvbuff to include only the specified
344
       payload length.
345
346
       The dissector above the one calling us (the dissector above is
347
       probably us) may use that to determine how much of its packet
348
       was padding. */
349
1.33k
    tvb_set_reported_length(tvb, specified_len);
350
1.33k
  }
351
39.6k
}
352
353
void
354
register_init_routine(void (*func)(void))
355
1.33k
{
356
1.33k
  init_routines = g_slist_prepend(init_routines, (void *)func);
357
1.33k
}
358
359
void
360
register_cleanup_routine(void (*func)(void))
361
728
{
362
728
  cleanup_routines = g_slist_prepend(cleanup_routines, (void *)func);
363
728
}
364
365
/* register a new shutdown routine */
366
void
367
register_shutdown_routine(void (*func)(void))
368
322
{
369
322
  shutdown_routines = g_slist_prepend(shutdown_routines, (void *)func);
370
322
}
371
372
/* Initialize all data structures used for dissection. */
373
void
374
init_dissection(const char* app_env_var_prefix)
375
14
{
376
  /*
377
   * Reinitialize resolution information. Don't leak host entries from
378
   * one file to another (e.g. embarrassing-host-name.example.com from
379
   * file1.pcapng into a name resolution block in file2.pcapng).
380
   */
381
14
  host_name_lookup_reset(app_env_var_prefix);
382
383
14
  wmem_enter_file_scope();
384
385
  /* Initialize the table of conversations. */
386
14
  epan_conversation_init();
387
388
  /* Initialize protocol-specific variables. */
389
14
  g_slist_foreach(init_routines, &call_routine, NULL);
390
391
  /* Initialize the stream-handling tables */
392
14
  stream_init();
393
394
  /* Initialize the expert infos */
395
14
  expert_packet_init();
396
14
}
397
398
void
399
cleanup_dissection(void)
400
0
{
401
  /* Cleanup protocol-specific variables. */
402
0
  g_slist_foreach(cleanup_routines, &call_routine, NULL);
403
404
  /* Cleanup the stream-handling tables */
405
0
  stream_cleanup();
406
407
  /* Cleanup the expert infos */
408
0
  expert_packet_cleanup();
409
410
0
  wmem_leave_file_scope();
411
412
  /*
413
   * Keep the name resolution info around until we start the next
414
   * dissection. Lua scripts may potentially do name resolution at
415
   * any time, even if we're not dissecting and have no capture
416
   * file open.
417
   */
418
0
}
419
420
void
421
register_postseq_cleanup_routine(void_func_t func)
422
14
{
423
14
  postseq_cleanup_routines = g_slist_prepend(postseq_cleanup_routines,
424
14
      (void *)func);
425
14
}
426
427
/* Call all the registered "postseq_cleanup" routines. */
428
void
429
postseq_cleanup_all_protocols(void)
430
0
{
431
0
  g_slist_foreach(postseq_cleanup_routines,
432
0
      &call_routine, NULL);
433
0
}
434
435
/*
436
 * Add a new data source to the list of data sources for a frame, given
437
 * the tvbuff for the data source and its name.
438
 */
439
struct data_source *add_new_data_source(packet_info *pinfo, tvbuff_t *tvb, const char *name)
440
695k
{
441
695k
  struct data_source *src;
442
443
695k
  src = wmem_new(pinfo->pool, struct data_source);
444
695k
  src->tvb = tvb;
445
695k
  src->name = wmem_strdup(pinfo->pool, name);
446
695k
  src->media_type = DS_MEDIA_TYPE_APPLICATION_OCTET_STREAM;
447
  /* This could end up slow, but we should never have that many data
448
   * sources so it probably doesn't matter */
449
695k
  pinfo->data_src = g_slist_append(pinfo->data_src, src);
450
695k
  return src;
451
695k
}
452
453
void
454
set_data_source_name(packet_info *pinfo, struct data_source *src, const char *name)
455
0
{
456
0
  if (src) {
457
0
    src->name = wmem_strdup(pinfo->pool, name);
458
0
  }
459
0
}
460
461
void set_data_source_media_type(struct data_source *src, data_source_media_type_e media_type)
462
0
{
463
0
  if (src) {
464
0
    src->media_type = media_type;
465
0
  }
466
0
}
467
468
void
469
remove_last_data_source(packet_info *pinfo)
470
0
{
471
0
  GSList *last;
472
473
0
  last = g_slist_last(pinfo->data_src);
474
0
  pinfo->data_src = g_slist_delete_link(pinfo->data_src, last);
475
0
}
476
477
char*
478
get_data_source_description(const struct data_source *src)
479
0
{
480
0
  unsigned length = tvb_captured_length(src->tvb);
481
482
0
  return wmem_strdup_printf(NULL, "%s (%u byte%s)", src->name, length,
483
0
        plurality(length, "", "s"));
484
0
}
485
486
const char *
487
get_data_source_name(const struct data_source *src)
488
0
{
489
0
  if (src) {
490
0
    return src->name;
491
0
  }
492
0
  return NULL;
493
0
}
494
495
tvbuff_t *
496
get_data_source_tvb(const struct data_source *src)
497
26.7k
{
498
26.7k
  if (src) {
499
26.7k
    return src->tvb;
500
26.7k
  }
501
0
  return NULL;
502
26.7k
}
503
504
/*
505
 * Find and return data source with the given name.
506
 */
507
struct data_source *
508
get_data_source_by_name(const packet_info *pinfo, const char *name)
509
0
{
510
0
  if (!pinfo) {
511
0
    return NULL;
512
0
  }
513
0
  for (GSList *source = pinfo->data_src; source; source = source->next) {
514
0
    struct data_source *this_source = (struct data_source *)source->data;
515
0
    if (this_source->name && strcmp(this_source->name, name) == 0) {
516
0
      return this_source;
517
0
    }
518
0
  }
519
0
  return NULL;
520
0
}
521
522
/*
523
 * Find and return the data source associated with a given tvb.
524
 */
525
struct data_source *
526
get_data_source_by_tvb(const packet_info *pinfo, const tvbuff_t *tvb)
527
0
{
528
0
  if (!pinfo) {
529
0
    return NULL;
530
0
  }
531
0
  for (GSList *source = pinfo->data_src; source; source = source->next) {
532
0
    struct data_source *this_source = (struct data_source *)source->data;
533
0
    if (this_source->tvb == tvb) {
534
0
      return this_source;
535
0
    }
536
0
  }
537
0
  return NULL;
538
0
}
539
540
541
data_source_media_type_e get_data_source_media_type(const struct data_source *src)
542
0
{
543
0
  if (src) {
544
0
    return src->media_type;
545
0
  }
546
0
  return DS_MEDIA_TYPE_APPLICATION_OCTET_STREAM;
547
0
}
548
549
550
/*
551
 * Free up a frame's list of data sources.
552
 */
553
void
554
free_data_sources(packet_info *pinfo)
555
192k
{
556
192k
  if (pinfo->data_src) {
557
192k
    g_slist_free(pinfo->data_src);
558
192k
    pinfo->data_src = NULL;
559
192k
  }
560
192k
}
561
562
void
563
mark_frame_as_depended_upon(frame_data *fd, uint32_t frame_num)
564
10.1k
{
565
  /* Don't mark a frame as dependent on itself */
566
10.1k
  if (frame_num != fd->num) {
567
    /* ws_assert(frame_num < fd->num) - we assume in several other
568
     * places in the code that frames don't depend on future
569
     * frames. */
570
2.27k
    if (fd->dependent_frames == NULL) {
571
497
      fd->dependent_frames = g_hash_table_new(g_direct_hash, g_direct_equal);
572
497
    }
573
2.27k
    g_hash_table_add(fd->dependent_frames, GUINT_TO_POINTER(frame_num));
574
2.27k
  }
575
10.1k
}
576
577
/* Allow dissectors to register a "final_registration" routine
578
 * that is run like the proto_register_XXX() routine, but at the
579
 * end of the epan_init() function; that is, *after* all other
580
 * subsystems, like dfilters, have finished initializing. This is
581
 * useful for dissector registration routines which need to compile
582
 * display filters. dfilters can't initialize itself until all protocols
583
 * have registered themselves. */
584
static GSList *final_registration_routines;
585
586
void
587
register_final_registration_routine(void (*func)(void))
588
0
{
589
0
  final_registration_routines = g_slist_prepend(final_registration_routines,
590
0
      (void *)func);
591
0
}
592
593
/* Call all the registered "final_registration" routines. */
594
void
595
final_registration_all_protocols(void)
596
14
{
597
14
  g_slist_foreach(final_registration_routines,
598
14
      &call_routine, NULL);
599
14
}
600
601
602
/* Creates the top-most tvbuff and calls the "frame" dissector */
603
void
604
dissect_record(epan_dissect_t *edt, int file_type_subtype, wtap_rec *rec,
605
    frame_data *fd, column_info *cinfo)
606
192k
{
607
192k
  frame_data_t frame_dissector_data;
608
609
192k
  if (!fd->visited) {
610
    /* This is the first pass, so prime the epan_dissect_t with the
611
      hfids postdissectors want on the first pass. */
612
    /* XXX - This can fail with an unhandled exception, e.g., if a
613
     * field was deregistered.  */
614
192k
    prime_epan_dissect_with_postdissector_wanted_hfids(edt);
615
192k
  }
616
617
192k
  if (cinfo != NULL)
618
0
    col_init(cinfo, edt->session);
619
192k
  edt->pi.epan = edt->session;
620
  /* edt->pi.pool created in epan_dissect_init() */
621
192k
  edt->pi.current_proto = "<Missing Protocol Name>";
622
192k
  edt->pi.cinfo = cinfo;
623
192k
  edt->pi.presence_flags = 0;
624
192k
  edt->pi.num = fd->num;
625
  /*
626
   * XXX - this doesn't check the wtap_rec because, for
627
   * some capture files, time stamps are supplied only
628
   * when reading sequentially, so we keep the time stamp
629
   * in the frame_data structure.
630
   */
631
192k
  if (fd->has_ts) {
632
192k
    edt->pi.presence_flags |= PINFO_HAS_TS;
633
192k
    edt->pi.abs_ts = fd->abs_ts;
634
192k
  }
635
192k
  switch (rec->rec_type) {
636
637
192k
  case REC_TYPE_PACKET:
638
192k
    edt->pi.pseudo_header = &rec->rec_header.packet_header.pseudo_header;
639
192k
    break;
640
641
0
  case REC_TYPE_FT_SPECIFIC_EVENT:
642
0
  case REC_TYPE_FT_SPECIFIC_REPORT:
643
0
    edt->pi.pseudo_header = &rec->rec_header.ft_specific_header.pseudo_header;
644
0
    break;
645
646
0
  case REC_TYPE_SYSCALL:
647
0
    edt->pi.pseudo_header = NULL;
648
0
    break;
649
650
0
  case REC_TYPE_SYSTEMD_JOURNAL_EXPORT:
651
0
    edt->pi.pseudo_header = NULL;
652
0
    break;
653
654
0
  case REC_TYPE_CUSTOM_BLOCK:
655
0
    edt->pi.pseudo_header = NULL;
656
0
    break;
657
658
192k
  }
659
660
192k
  edt->pi.fd            = fd;
661
192k
  edt->pi.rec           = rec;
662
192k
  clear_address(&edt->pi.dl_src);
663
192k
  clear_address(&edt->pi.dl_dst);
664
192k
  clear_address(&edt->pi.net_src);
665
192k
  clear_address(&edt->pi.net_dst);
666
192k
  clear_address(&edt->pi.src);
667
192k
  clear_address(&edt->pi.dst);
668
192k
  edt->pi.noreassembly_reason = "";
669
192k
  edt->pi.ptype = PT_NONE;
670
192k
  edt->pi.use_conv_addr_port_endpoints = false;
671
192k
  edt->pi.conv_addr_port_endpoints = NULL;
672
192k
  edt->pi.conv_elements = NULL;
673
192k
  edt->pi.p2p_dir = P2P_DIR_UNKNOWN;
674
192k
  edt->pi.link_dir = LINK_DIR_UNKNOWN;
675
192k
  edt->pi.src_win_scale = -1; /* unknown Rcv.Wind.Shift */
676
192k
  edt->pi.dst_win_scale = -1; /* unknown Rcv.Wind.Shift */
677
192k
  edt->pi.layers = wmem_list_new(edt->pi.pool);
678
192k
  edt->tvb = NULL;
679
680
  /*
681
   * This is time relative to the first frame in the capture,
682
   * regardless of what time reference frames precede it.
683
   *
684
   * XXX - should there be a field indicating whether the
685
   * frame *has* a relative time stamp?
686
   *
687
   * XXX - what is pinfo->rel_ts used for?  All times are
688
   * relative to some zero point on the t axis, so why
689
   * is pinfo->rel_ts used instead of pinfo->abs_ts?
690
   *
691
   * XXX - Some records aren't packets, and some, packets or not, don't
692
   * have time stamps. Should pinfo->rel_ts be relative to the first
693
   * frame (or packet record, or record of the time type as the current
694
   * record?) that *has* a time stamp?
695
   */
696
192k
  frame_rel_first_frame_time(edt->session, fd, &edt->pi.rel_ts);
697
698
  /* pinfo->rel_cap_ts is used by the new Plot dialog, though
699
   * it could probably just use frame_rel_start_time instead.
700
   */
701
192k
  nstime_t rel_time;
702
192k
  if (frame_rel_start_time(edt->session, fd, &rel_time)) {
703
0
    nstime_copy(&edt->pi.rel_cap_ts, &rel_time);
704
0
    edt->pi.rel_cap_ts_present = true;
705
0
  }
706
707
  /*
708
   * If the block has been modified, use the modified block,
709
   * otherwise use the block from the file.
710
   */
711
192k
  if (fd->has_modified_block) {
712
0
    frame_dissector_data.pkt_block = epan_get_modified_block(edt->session, fd);
713
0
  }
714
192k
  else {
715
192k
    frame_dissector_data.pkt_block = rec->block;
716
192k
  }
717
192k
  frame_dissector_data.file_type_subtype = file_type_subtype;
718
192k
  frame_dissector_data.color_edt = edt; /* Used strictly for "coloring rules" */
719
720
192k
  TRY {
721
    /*
722
     * XXX - currently, the length arguments in
723
     * tvbuff structure are signed, but the captured
724
     * and reported length values are unsigned; this means
725
     * that length values > 2^31 - 1 will appear as
726
     * negative lengths
727
     *
728
     * Captured length values that large will already
729
     * have been filtered out by the Wiretap modules
730
     * (the file will be reported as corrupted), to
731
     * avoid trying to allocate large chunks of data.
732
     *
733
     * Reported length values will not have been
734
     * filtered out, and should not be filtered out,
735
     * as those lengths are not necessarily invalid.
736
     *
737
     * For now, we clip the reported length at INT_MAX
738
     *
739
     * (XXX, is this still a problem?) There was an exception when we call
740
     * tvb_new_real_data() now there's not.
741
     */
742
192k
    edt->tvb = tvb_new_real_data(ws_buffer_start_ptr(&rec->data),
743
192k
                    fd->cap_len, fd->pkt_len > INT_MAX ? INT_MAX : fd->pkt_len);
744
    /* Add this tvbuffer into the data_src list */
745
192k
    add_new_data_source(&edt->pi, edt->tvb, rec->rec_type_name);
746
747
    /* Even though dissect_frame() catches all the exceptions a
748
     * sub-dissector can throw, dissect_frame() itself may throw
749
     * a ReportedBoundsError in bizarre cases. Thus, we catch the exception
750
     * in this function. */
751
192k
    call_dissector_with_data(frame_handle, edt->tvb, &edt->pi, edt->tree, &frame_dissector_data);
752
192k
  }
753
192k
  CATCH(BoundsError) {
754
0
    ws_assert_not_reached();
755
0
  }
756
192k
  CATCH2(FragmentBoundsError, ReportedBoundsError) {
757
0
    proto_tree_add_protocol_format(edt->tree, proto_malformed, edt->tvb, 0, 0,
758
0
                 "[Malformed %s: Packet Length]",
759
0
                 rec->rec_type_name);
760
0
  }
761
192k
  ENDTRY;
762
192k
  wtap_block_unref(rec->block);
763
192k
  rec->block = NULL;
764
765
192k
  fd->visited = 1;
766
192k
}
767
768
/* Creates the top-most tvbuff and calls the "file" dissector */
769
void
770
dissect_file(epan_dissect_t *edt, wtap_rec *rec,
771
    frame_data *fd, column_info *cinfo)
772
0
{
773
0
  file_data_t file_dissector_data;
774
775
0
  if (!fd->visited) {
776
         /* This is the first pass, so prime the epan_dissect_t with the
777
      hfids postdissectors want on the first pass. */
778
0
         prime_epan_dissect_with_postdissector_wanted_hfids(edt);
779
0
  }
780
781
0
  if (cinfo != NULL)
782
0
    col_init(cinfo, edt->session);
783
0
  edt->pi.epan = edt->session;
784
  /* edt->pi.pool created in epan_dissect_init() */
785
0
  edt->pi.current_proto = "<Missing Filetype Name>";
786
0
  edt->pi.cinfo = cinfo;
787
0
  edt->pi.fd    = fd;
788
0
  edt->pi.rec   = rec;
789
0
  edt->pi.pseudo_header = NULL;
790
0
  clear_address(&edt->pi.dl_src);
791
0
  clear_address(&edt->pi.dl_dst);
792
0
  clear_address(&edt->pi.net_src);
793
0
  clear_address(&edt->pi.net_dst);
794
0
  clear_address(&edt->pi.src);
795
0
  clear_address(&edt->pi.dst);
796
0
  edt->pi.noreassembly_reason = "";
797
0
  edt->pi.ptype = PT_NONE;
798
0
  edt->pi.use_conv_addr_port_endpoints = false;
799
0
  edt->pi.conv_addr_port_endpoints = NULL;
800
0
  edt->pi.conv_elements = NULL;
801
0
  edt->pi.p2p_dir = P2P_DIR_UNKNOWN;
802
0
  edt->pi.link_dir = LINK_DIR_UNKNOWN;
803
0
  edt->pi.layers = wmem_list_new(edt->pi.pool);
804
0
  edt->tvb = NULL;
805
806
0
  frame_rel_first_frame_time(edt->session, fd, &edt->pi.rel_ts);
807
808
0
  TRY {
809
    /*
810
     * If the block has been modified, use the modified block,
811
     * otherwise use the block from the file.
812
     */
813
0
    if (fd->has_modified_block) {
814
0
      file_dissector_data.pkt_block = epan_get_modified_block(edt->session, fd);
815
0
    }
816
0
    else {
817
0
      file_dissector_data.pkt_block = rec->block;
818
0
    }
819
0
    file_dissector_data.color_edt = edt; /* Used strictly for "coloring rules" */
820
821
0
    edt->tvb = tvb_new_real_data(ws_buffer_start_ptr(&rec->data),
822
0
                    fd->cap_len, fd->pkt_len > INT_MAX ? INT_MAX : fd->pkt_len);
823
    /* Add this tvbuffer into the data_src list */
824
0
    add_new_data_source(&edt->pi, edt->tvb, "File");
825
826
    /* Even though dissect_file() catches all the exceptions a
827
     * sub-dissector can throw, dissect_frame() itself may throw
828
     * a ReportedBoundsError in bizarre cases. Thus, we catch the exception
829
     * in this function. */
830
0
    call_dissector_with_data(file_handle, edt->tvb, &edt->pi, edt->tree, &file_dissector_data);
831
832
0
  }
833
0
  CATCH(BoundsError) {
834
0
    ws_assert_not_reached();
835
0
  }
836
0
  CATCH3(FragmentBoundsError, ContainedBoundsError, ReportedBoundsError) {
837
0
    proto_tree_add_protocol_format(edt->tree, proto_malformed, edt->tvb, 0, 0,
838
0
                 "[Malformed Record: Packet Length]");
839
0
  }
840
0
  ENDTRY;
841
0
  wtap_block_unref(rec->block);
842
0
  rec->block = NULL;
843
844
0
  fd->visited = 1;
845
0
}
846
847
/*********************** code added for sub-dissector lookup *********************/
848
849
enum dissector_e {
850
  DISSECTOR_TYPE_SIMPLE,
851
  DISSECTOR_TYPE_CALLBACK
852
};
853
854
/*
855
 * A dissector handle.
856
 */
857
struct dissector_handle {
858
  const char  *name;    /* dissector name */
859
  const char  *description; /* dissector description */
860
  char            *pref_suffix;
861
  enum dissector_e dissector_type;
862
  union {
863
    dissector_t dissector_type_simple;
864
    dissector_cb_t  dissector_type_callback;
865
  } dissector_func;
866
  void    *dissector_data;
867
  protocol_t  *protocol;
868
};
869
870
static void
871
add_layer(packet_info *pinfo, int proto_id)
872
1.91M
{
873
1.91M
  int *proto_layer_num_ptr;
874
875
1.91M
  pinfo->curr_layer_num++;
876
1.91M
  wmem_list_append(pinfo->layers, GINT_TO_POINTER(proto_id));
877
878
  /* Increment layer number for this proto id. */
879
1.91M
  if (pinfo->proto_layers == NULL) {
880
192k
    pinfo->proto_layers = wmem_map_new(pinfo->pool, g_direct_hash, g_direct_equal);
881
192k
  }
882
883
1.91M
  proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id));
884
1.91M
  if (proto_layer_num_ptr == NULL) {
885
    /* Insert new layer */
886
1.40M
    proto_layer_num_ptr = wmem_new(pinfo->pool, int);
887
1.40M
    *proto_layer_num_ptr = 1;
888
1.40M
    wmem_map_insert(pinfo->proto_layers, GINT_TO_POINTER(proto_id), proto_layer_num_ptr);
889
1.40M
  }
890
515k
  else {
891
    /* Increment layer number */
892
515k
    (*proto_layer_num_ptr)++;
893
515k
  }
894
1.91M
  pinfo->curr_proto_layer_num = *proto_layer_num_ptr;
895
1.91M
}
896
897
static void
898
remove_last_layer(packet_info *pinfo, bool reduce_count)
899
539k
{
900
539k
  int *proto_layer_num_ptr;
901
539k
  wmem_list_frame_t *frame;
902
539k
  int proto_id;
903
904
539k
  if (reduce_count) {
905
536k
    pinfo->curr_layer_num--;
906
536k
  }
907
908
539k
  frame = wmem_list_tail(pinfo->layers);
909
539k
  proto_id = GPOINTER_TO_INT(wmem_list_frame_data(frame));
910
539k
  wmem_list_remove_frame(pinfo->layers, frame);
911
912
539k
  if (reduce_count) {
913
    /* Reduce count for removed protocol layer. */
914
536k
    proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id));
915
536k
    if (proto_layer_num_ptr && *proto_layer_num_ptr > 0) {
916
536k
      (*proto_layer_num_ptr)--;
917
536k
    }
918
536k
  }
919
539k
}
920
921
922
/* This function will return
923
 *   >0  this protocol was successfully dissected and this was this protocol.
924
 *   0   this packet did not match this protocol.
925
 *
926
 * XXX - if the dissector only dissects metadata passed through the data
927
 * pointer, and dissects none of the packet data, that's indistinguishable
928
 * from "packet did not match this protocol".  See issues #12366 and
929
 * #12368.
930
 */
931
static int
932
call_dissector_through_handle(dissector_handle_t handle, tvbuff_t *tvb,
933
            packet_info *pinfo, proto_tree *tree, void *data)
934
1.57M
{
935
1.57M
  const char *saved_proto;
936
1.57M
  int     saved_proto_layer_num;
937
1.57M
  int         len;
938
939
1.57M
  saved_proto = pinfo->current_proto;
940
1.57M
  saved_proto_layer_num = pinfo->curr_proto_layer_num;
941
942
1.57M
  if ((handle->protocol != NULL) && (!proto_is_pino(handle->protocol))) {
943
1.48M
    pinfo->current_proto =
944
1.48M
      proto_get_protocol_short_name(handle->protocol);
945
1.48M
  }
946
947
1.57M
  switch (handle->dissector_type) {
948
949
1.57M
  case DISSECTOR_TYPE_SIMPLE:
950
1.57M
    len = (handle->dissector_func.dissector_type_simple)(tvb, pinfo, tree, data);
951
1.57M
    break;
952
953
22
  case DISSECTOR_TYPE_CALLBACK:
954
22
    len = (handle->dissector_func.dissector_type_callback)(tvb, pinfo, tree, data, handle->dissector_data);
955
22
    break;
956
957
0
  default:
958
0
    ws_assert_not_reached();
959
1.57M
  }
960
1.17M
  pinfo->current_proto = saved_proto;
961
1.17M
  pinfo->curr_proto_layer_num = saved_proto_layer_num;
962
963
1.17M
  return len;
964
1.57M
}
965
966
/*
967
 * Call a dissector through a handle.
968
 * If the protocol for that handle isn't enabled, return 0 without
969
 * calling the dissector.
970
 * Otherwise, if the handle refers to a new-style dissector, call the
971
 * dissector and return its return value, otherwise call it and return
972
 * the length of the tvbuff pointed to by the argument.
973
 */
974
975
static int
976
call_dissector_work_error(dissector_handle_t handle, tvbuff_t *tvb,
977
        packet_info *pinfo_arg, proto_tree *tree, void *);
978
979
static int
980
call_dissector_work(dissector_handle_t handle, tvbuff_t *tvb, packet_info *pinfo,
981
        proto_tree *tree, bool add_proto_name, void *data)
982
2.15M
{
983
2.15M
  const char  *saved_proto;
984
2.15M
  int          saved_proto_layer_num;
985
2.15M
  uint16_t     saved_can_desegment;
986
2.15M
  int          len;
987
2.15M
  unsigned     saved_layers_len = 0;
988
2.15M
  unsigned     saved_tree_count = tree ? tree->tree_data->count : 0;
989
2.15M
  unsigned     saved_desegment_len = pinfo->desegment_len;
990
2.15M
  bool         consumed_none;
991
992
2.15M
  if (handle->protocol != NULL &&
993
2.08M
      !proto_is_protocol_enabled(handle->protocol)) {
994
    /*
995
     * The protocol isn't enabled.
996
     */
997
578k
    return 0;
998
578k
  }
999
1000
1.57M
  saved_proto = pinfo->current_proto;
1001
1.57M
  saved_proto_layer_num = pinfo->curr_proto_layer_num;
1002
1.57M
  saved_can_desegment = pinfo->can_desegment;
1003
1.57M
  saved_layers_len = wmem_list_count(pinfo->layers);
1004
1.57M
  DISSECTOR_ASSERT(saved_layers_len < prefs.gui_max_tree_depth);
1005
1006
  /*
1007
   * can_desegment is set to 2 by anyone which offers the
1008
   * desegmentation api/service.
1009
   * Then every time a subdissector is called it is decremented
1010
   * by one.
1011
   * Thus only the subdissector immediately on top of whoever
1012
   * offers this service can use it.
1013
   * We save the current value of "can_desegment" for the
1014
   * benefit of TCP proxying dissectors such as SOCKS, so they
1015
   * can restore it and allow the dissectors they call to use
1016
   * the desegmentation service.
1017
   */
1018
1.57M
  pinfo->saved_can_desegment = saved_can_desegment;
1019
1.57M
  pinfo->can_desegment = saved_can_desegment-(saved_can_desegment>0);
1020
1.57M
  if ((handle->protocol != NULL) && (!proto_is_pino(handle->protocol))) {
1021
1.48M
    pinfo->current_proto =
1022
1.48M
      proto_get_protocol_short_name(handle->protocol);
1023
1024
    /*
1025
     * Add the protocol name to the layers only if told to
1026
     * do so. Asn2wrs generated dissectors may be added
1027
     * multiple times otherwise.
1028
     */
1029
    /* XXX Should we check for a duplicate layer here? */
1030
1.48M
    if (add_proto_name) {
1031
1.39M
      add_layer(pinfo, proto_get_id(handle->protocol));
1032
1.39M
    }
1033
1.48M
  }
1034
1035
1.57M
  if (pinfo->flags.in_error_pkt) {
1036
188k
    len = call_dissector_work_error(handle, tvb, pinfo, tree, data);
1037
1.38M
  } else {
1038
    /*
1039
     * Just call the subdissector.
1040
     */
1041
1.38M
    len = call_dissector_through_handle(handle, tvb, pinfo, tree, data);
1042
1.38M
  }
1043
1.57M
  consumed_none = len == 0 || (pinfo->desegment_len != saved_desegment_len && pinfo->desegment_offset == 0);
1044
  /* If len == 0, then the dissector didn't accept the packet.
1045
   * In the latter case, the dissector accepted the packet, but didn't
1046
   * consume any bytes because they all belong in a later segment.
1047
   * In the latter case, we probably won't call a dissector here again
1048
   * on the next pass, so removing the layer keeps any *further* layers
1049
   * past this one the same on subsequent passes.
1050
   *
1051
   * XXX: DISSECTOR_ASSERT that the tree count didn't change? If the
1052
   * dissector didn't consume any bytes but added items to the tree,
1053
   * that's improper behavior and needs a rethink. We could also move the
1054
   * test that the packet didn't change desegment_offset and desegment_len
1055
   * while rejecting the packet from packet-tcp.c decode_tcp_ports to here.
1056
   */
1057
1.57M
  if (handle->protocol != NULL && !proto_is_pino(handle->protocol) && add_proto_name &&
1058
1.06M
    (consumed_none || (tree && saved_tree_count == tree->tree_data->count))) {
1059
    /*
1060
     * We've added a layer and either the dissector didn't
1061
     * consume any data or we didn't add any items to the
1062
     * tree. Remove it.
1063
     */
1064
84.0k
    while (wmem_list_count(pinfo->layers) > saved_layers_len) {
1065
      /*
1066
       * Only reduce the layer number if the dissector didn't
1067
       * consume any data. Since tree can be NULL on
1068
       * the first pass, we cannot check it or it will
1069
       * break dissectors that rely on a stable value.
1070
       */
1071
43.4k
      remove_last_layer(pinfo, consumed_none);
1072
43.4k
    }
1073
40.5k
  }
1074
1.57M
  pinfo->current_proto = saved_proto;
1075
1.57M
  pinfo->curr_proto_layer_num = saved_proto_layer_num;
1076
1.57M
  pinfo->can_desegment = saved_can_desegment;
1077
1.57M
  return len;
1078
2.15M
}
1079
1080
1081
static int
1082
call_dissector_work_error(dissector_handle_t handle, tvbuff_t *tvb,
1083
        packet_info *pinfo_arg, proto_tree *tree, void *data)
1084
188k
{
1085
188k
  packet_info  *pinfo = pinfo_arg;
1086
188k
  const char   *saved_proto;
1087
188k
  uint16_t      saved_can_desegment;
1088
188k
  volatile int  len = 0;
1089
188k
  bool          save_writable;
1090
188k
  address       save_dl_src;
1091
188k
  address       save_dl_dst;
1092
188k
  address       save_net_src;
1093
188k
  address       save_net_dst;
1094
188k
  address       save_src;
1095
188k
  address       save_dst;
1096
188k
  uint32_t        save_ptype;
1097
188k
  uint32_t        save_srcport;
1098
188k
  uint32_t        save_destport;
1099
1100
  /*
1101
  * This isn't a packet being transported inside
1102
  * the protocol whose dissector is calling us,
1103
  * it's a copy of a packet that caused an error
1104
  * in some protocol included in a packet that
1105
  * reports the error (e.g., an ICMP Unreachable
1106
  * packet).
1107
  */
1108
1109
  /*
1110
  * Save the current state of the writability of
1111
  * the columns, and restore them after the
1112
  * dissector returns, so that the columns
1113
  * don't reflect the packet that got the error,
1114
  * they reflect the packet that reported the
1115
  * error.
1116
  */
1117
188k
  saved_proto = pinfo->current_proto;
1118
188k
  saved_can_desegment = pinfo->can_desegment;
1119
1120
188k
  save_writable = col_get_writable(pinfo->cinfo, -1);
1121
188k
  col_set_writable(pinfo->cinfo, -1, false);
1122
188k
  copy_address_shallow(&save_dl_src, &pinfo->dl_src);
1123
188k
  copy_address_shallow(&save_dl_dst, &pinfo->dl_dst);
1124
188k
  copy_address_shallow(&save_net_src, &pinfo->net_src);
1125
188k
  copy_address_shallow(&save_net_dst, &pinfo->net_dst);
1126
188k
  copy_address_shallow(&save_src, &pinfo->src);
1127
188k
  copy_address_shallow(&save_dst, &pinfo->dst);
1128
188k
  save_ptype = pinfo->ptype;
1129
188k
  save_srcport = pinfo->srcport;
1130
188k
  save_destport = pinfo->destport;
1131
1132
  /* Dissect the contained packet. */
1133
188k
  TRY {
1134
188k
    len = call_dissector_through_handle(handle, tvb,pinfo, tree, data);
1135
188k
  }
1136
188k
  CATCH(BoundsError) {
1137
    /*
1138
    * Restore the column writability and addresses and ports.
1139
    */
1140
68
    col_set_writable(pinfo->cinfo, -1, save_writable);
1141
68
    copy_address_shallow(&pinfo->dl_src, &save_dl_src);
1142
68
    copy_address_shallow(&pinfo->dl_dst, &save_dl_dst);
1143
68
    copy_address_shallow(&pinfo->net_src, &save_net_src);
1144
68
    copy_address_shallow(&pinfo->net_dst, &save_net_dst);
1145
68
    copy_address_shallow(&pinfo->src, &save_src);
1146
68
    copy_address_shallow(&pinfo->dst, &save_dst);
1147
68
    pinfo->ptype = save_ptype;
1148
68
    pinfo->srcport = save_srcport;
1149
68
    pinfo->destport = save_destport;
1150
1151
    /*
1152
    * Restore the current protocol, so any
1153
    * "Short Frame" indication reflects that
1154
    * protocol, not the protocol for the
1155
    * packet that got the error.
1156
    */
1157
68
    pinfo->current_proto = saved_proto;
1158
1159
    /*
1160
    * Restore the desegmentability state.
1161
    */
1162
68
    pinfo->can_desegment = saved_can_desegment;
1163
1164
    /*
1165
    * Rethrow the exception, so this will be
1166
    * reported as a short frame.
1167
    */
1168
68
    RETHROW;
1169
0
  }
1170
188k
  CATCH3(FragmentBoundsError, ContainedBoundsError, ReportedBoundsError) {
1171
    /*
1172
    * "ret" wasn't set because an exception was thrown
1173
    * before "call_dissector_through_handle()" returned.
1174
    * As it called something, at least one dissector
1175
    * accepted the packet, and, as an exception was
1176
    * thrown, not only was all the tvbuff dissected,
1177
    * a dissector tried dissecting past the end of
1178
    * the data in some tvbuff, so we'll assume that
1179
    * the entire tvbuff was dissected.
1180
    */
1181
56.0k
    len = tvb_captured_length(tvb);
1182
56.0k
  }
1183
188k
  ENDTRY;
1184
1185
188k
  col_set_writable(pinfo->cinfo, -1, save_writable);
1186
188k
  copy_address_shallow(&pinfo->dl_src, &save_dl_src);
1187
188k
  copy_address_shallow(&pinfo->dl_dst, &save_dl_dst);
1188
188k
  copy_address_shallow(&pinfo->net_src, &save_net_src);
1189
188k
  copy_address_shallow(&pinfo->net_dst, &save_net_dst);
1190
188k
  copy_address_shallow(&pinfo->src, &save_src);
1191
188k
  copy_address_shallow(&pinfo->dst, &save_dst);
1192
188k
  pinfo->ptype = save_ptype;
1193
188k
  pinfo->srcport = save_srcport;
1194
188k
  pinfo->destport = save_destport;
1195
188k
  pinfo->want_pdu_tracking = 0;
1196
188k
  return len;
1197
188k
}
1198
1199
/*
1200
 * An entry in the hash table portion of a dissector table.
1201
 */
1202
struct dtbl_entry {
1203
  dissector_handle_t initial;
1204
  dissector_handle_t current;
1205
};
1206
1207
/* Finds a dissector table by table name. */
1208
dissector_table_t
1209
find_dissector_table(const char *name)
1210
282k
{
1211
282k
  dissector_table_t dissector_table = (dissector_table_t) g_hash_table_lookup(dissector_tables, name);
1212
282k
  if (! dissector_table) {
1213
0
    const char *new_name = (const char *) g_hash_table_lookup(dissector_table_aliases, name);
1214
0
    if (new_name) {
1215
0
      dissector_table = (dissector_table_t) g_hash_table_lookup(dissector_tables, new_name);
1216
0
    }
1217
0
    if (dissector_table) {
1218
0
      ws_warning("%s is now %s", name, new_name);
1219
0
    }
1220
0
  }
1221
282k
  return dissector_table;
1222
282k
}
1223
1224
/* Find an entry in a uint dissector table. */
1225
static dtbl_entry_t *
1226
find_uint_dtbl_entry(dissector_table_t sub_dissectors, const uint32_t pattern)
1227
1.37M
{
1228
1.37M
  switch (sub_dissectors->type) {
1229
1230
392k
  case FT_UINT8:
1231
1.03M
  case FT_UINT16:
1232
1.03M
  case FT_UINT24:
1233
1.37M
  case FT_UINT32:
1234
    /*
1235
     * You can do a uint lookup in these tables.
1236
     */
1237
1.37M
    break;
1238
521
  case FT_NONE:
1239
    /* For now treat as uint */
1240
521
    break;
1241
1242
0
  default:
1243
    /*
1244
     * But you can't do a uint lookup in any other types
1245
     * of tables.
1246
     */
1247
0
    ws_assert_not_reached();
1248
1.37M
  }
1249
1250
  /*
1251
   * Find the entry.
1252
   */
1253
1.37M
  return (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table,
1254
1.37M
           GUINT_TO_POINTER(pattern));
1255
1.37M
}
1256
1257
#if 0
1258
static void
1259
dissector_add_uint_sanity_check(const char *name, uint32_t pattern, dissector_handle_t handle, dissector_table_t sub_dissectors)
1260
{
1261
  dtbl_entry_t *dtbl_entry;
1262
1263
  if (pattern == 0) {
1264
    ws_warning("%s: %s registering using a pattern of 0",
1265
        name, proto_get_protocol_filter_name(proto_get_id(handle->protocol)));
1266
  }
1267
1268
  dtbl_entry = g_hash_table_lookup(sub_dissectors->hash_table, GUINT_TO_POINTER(pattern));
1269
  if (dtbl_entry != NULL) {
1270
    ws_warning("%s: %s registering using pattern %d already registered by %s",
1271
        name, proto_get_protocol_filter_name(proto_get_id(handle->protocol)),
1272
        pattern, proto_get_protocol_filter_name(proto_get_id(dtbl_entry->initial->protocol)));
1273
  }
1274
}
1275
#endif
1276
1277
/* Get and check subdissector table and handle
1278
 * @return true if subdissector and handle exist */
1279
static bool
1280
dissector_get_table_checked(const char *name, dissector_handle_t handle, dissector_table_t *sub_dissectors)
1281
253k
{
1282
253k
  *sub_dissectors = find_dissector_table(name);
1283
1284
  /*
1285
   * Make sure the handle and the dissector table exist.
1286
   */
1287
253k
  if (handle == NULL) {
1288
0
    ws_dissector_oops("handle to register \"%s\" to doesn't exist\n",
1289
0
        name);
1290
0
    return false;
1291
0
  }
1292
253k
  if (*sub_dissectors == NULL) {
1293
0
    ws_dissector_oops("dissector table \"%s\" doesn't exist\n"
1294
0
        "Protocol being registered is \"%s\"\n",
1295
0
        name, proto_get_protocol_long_name(handle->protocol));
1296
0
    return false;
1297
0
  }
1298
1299
253k
  return true;
1300
253k
}
1301
1302
static void
1303
dissector_add_uint_real(const char *name _U_, const uint32_t pattern, dissector_handle_t handle, dissector_table_t sub_dissectors)
1304
158k
{
1305
158k
  dtbl_entry_t      *dtbl_entry;
1306
1307
158k
  switch (sub_dissectors->type) {
1308
1309
17.1k
  case FT_UINT8:
1310
46.7k
  case FT_UINT16:
1311
47.0k
  case FT_UINT24:
1312
158k
  case FT_UINT32:
1313
    /*
1314
     * You can do a uint lookup in these tables.
1315
     */
1316
158k
    break;
1317
1318
0
  default:
1319
    /*
1320
     * But you can't do a uint lookup in any other types
1321
     * of tables.
1322
     */
1323
0
    ws_assert_not_reached();
1324
158k
  }
1325
1326
#if 0
1327
  dissector_add_uint_sanity_check(name, pattern, handle, sub_dissectors);
1328
#endif
1329
1330
158k
  dtbl_entry = g_new(dtbl_entry_t, 1);
1331
158k
  dtbl_entry->current = handle;
1332
158k
  dtbl_entry->initial = dtbl_entry->current;
1333
1334
  /* do the table insertion */
1335
158k
  g_hash_table_insert(sub_dissectors->hash_table,
1336
158k
           GUINT_TO_POINTER(pattern), (void *)dtbl_entry);
1337
158k
}
1338
1339
/* Add an entry to a uint dissector table. */
1340
void
1341
dissector_add_uint(const char *name, const uint32_t pattern, dissector_handle_t handle)
1342
149k
{
1343
149k
  dissector_table_t sub_dissectors;
1344
1345
149k
  if (!dissector_get_table_checked(name, handle, &sub_dissectors))
1346
0
    return;
1347
1348
149k
  dissector_add_uint_real(name, pattern, handle, sub_dissectors);
1349
1350
  /*
1351
   * Now, if this table supports "Decode As", add this handle
1352
   * to the list of handles that could be used for "Decode As"
1353
   * with this table, because it *is* being used with this table.
1354
   */
1355
149k
  if (sub_dissectors->supports_decode_as)
1356
15.5k
    dissector_add_for_decode_as(name, handle);
1357
149k
}
1358
1359
void dissector_add_uint_range(const char *name, range_t *range,
1360
            dissector_handle_t handle)
1361
2.31k
{
1362
2.31k
  dissector_table_t  sub_dissectors;
1363
2.31k
  uint32_t i, j;
1364
1365
2.31k
  if (range) {
1366
2.31k
    if (!dissector_get_table_checked(name, handle, &sub_dissectors))
1367
0
      return;
1368
1369
5.26k
    for (i = 0; i < range->nranges; i++) {
1370
8.58k
      for (j = range->ranges[i].low; j < range->ranges[i].high; j++)
1371
5.62k
        dissector_add_uint_real(name, j, handle, sub_dissectors);
1372
2.95k
      dissector_add_uint_real(name, range->ranges[i].high, handle, sub_dissectors);
1373
2.95k
    }
1374
    /*
1375
     * Even an empty range would want a chance for
1376
     * Decode As, if the dissector table supports
1377
     * it.
1378
     */
1379
2.31k
    if (sub_dissectors->supports_decode_as)
1380
2.18k
      dissector_add_for_decode_as(name, handle);
1381
2.31k
  }
1382
2.31k
}
1383
1384
static range_t*
1385
dissector_add_range_preference(const char *name, dissector_handle_t handle, const char* range_str)
1386
9.99k
{
1387
9.99k
  range_t** range;
1388
9.99k
  module_t *module;
1389
9.99k
  char *description, *title;
1390
9.99k
  dissector_table_t  pref_dissector_table = find_dissector_table(name);
1391
9.99k
  int proto_id = proto_get_id(handle->protocol);
1392
9.99k
  uint32_t max_value = 0;
1393
1394
  /* If a dissector is added for Decode As only, it's dissector
1395
    table value would default to 0.
1396
    Set up a preference value with that information
1397
   */
1398
9.99k
  range = wmem_new0(wmem_epan_scope(), range_t*);
1399
1400
  /* If the dissector's protocol already has a preference module, use it */
1401
9.99k
  const char* module_name = proto_get_protocol_filter_name(proto_id);
1402
9.99k
  module = prefs_find_module(module_name);
1403
9.99k
  if (module == NULL) {
1404
    /* Otherwise create a new one */
1405
4.31k
    module = prefs_register_protocol(proto_id, NULL);
1406
4.31k
  }
1407
1408
9.99k
  const char *pref_suffix = dissector_handle_get_pref_suffix(handle);
1409
9.99k
  const char *fullname = wmem_strdup_printf(wmem_epan_scope(), "%s%s", name, pref_suffix);
1410
1411
  /* Some preference callback functions use the proto_reg_handoff_
1412
    routine to apply preferences, which could duplicate the
1413
    registration of a preference.  Check for that here */
1414
9.99k
  if (prefs_find_preference(module, fullname) == NULL) {
1415
9.98k
    const char *handle_desc = dissector_handle_get_description(handle);
1416
9.98k
    if (g_strcmp0(range_str, "") > 0) {
1417
6.70k
      description = wmem_strdup_printf(wmem_epan_scope(), "%s %s(s) (default: %s)",
1418
6.70k
                      handle_desc, pref_dissector_table->ui_name, range_str);
1419
6.70k
    } else {
1420
3.27k
      description = wmem_strdup_printf(wmem_epan_scope(), "%s %s(s)",
1421
3.27k
                      handle_desc, pref_dissector_table->ui_name);
1422
3.27k
    }
1423
9.98k
    title = wmem_strdup_printf(wmem_epan_scope(), "%s %s(s)", handle_desc, pref_dissector_table->ui_name);
1424
1425
    /* Max value is based on datatype of dissector table */
1426
9.98k
    switch (pref_dissector_table->type) {
1427
1428
350
    case FT_UINT8:
1429
350
      max_value = 0xFF;
1430
350
      break;
1431
9.59k
    case FT_UINT16:
1432
9.59k
      max_value = 0xFFFF;
1433
9.59k
      break;
1434
0
    case FT_UINT24:
1435
0
      max_value = 0xFFFFFF;
1436
0
      break;
1437
42
    case FT_UINT32:
1438
42
      max_value = 0xFFFFFFFF;
1439
42
      break;
1440
1441
0
    default:
1442
0
      ws_error("The dissector table %s (%s) is not an integer type - are you using a buggy plugin?", name, pref_dissector_table->ui_name);
1443
0
      ws_assert_not_reached();
1444
9.98k
    }
1445
1446
9.98k
    range_convert_str(wmem_epan_scope(), range, range_str, max_value);
1447
9.98k
    prefs_register_decode_as_range_preference(module, fullname, title, description, range, max_value, name, handle_desc);
1448
9.98k
  } else {
1449
    /* We have a duplicate. This might just be the handoff routine
1450
     * getting called twice, which isn't ideal but we can ignore
1451
     * for now. Log it at a level that isn't printed by default.
1452
     */
1453
14
    ws_info("Registering automatic preference %s in %s twice", fullname, module_name);
1454
    /* Check this is just registering the same handle to the same
1455
     * preference, and not registering a different handle of the
1456
     * same protocol and the same pref_suffix to the same table.
1457
     */
1458
14
    dissector_handle_t dup_handle;
1459
5.20k
    for (GSList *entry = pref_dissector_table->dissector_handles; entry != NULL; entry = g_slist_next(entry))
1460
5.19k
    {
1461
5.19k
      dup_handle = (dissector_handle_t)entry->data;
1462
5.19k
      if (handle->protocol != dup_handle->protocol) {
1463
5.18k
        continue;
1464
5.18k
      }
1465
14
      if ((g_strcmp0(pref_suffix, dissector_handle_get_pref_suffix(dup_handle)) == 0) &&
1466
14
          (handle != dup_handle))
1467
0
      {
1468
0
        const char *dissector_name = dissector_handle_get_dissector_name(handle);
1469
0
        if (dissector_name == NULL)
1470
0
          dissector_name = "(anonymous)";
1471
0
        const char *dup_dissector_name;
1472
0
        dup_dissector_name = dissector_handle_get_dissector_name(dup_handle);
1473
0
        if (dup_dissector_name == NULL) {
1474
0
          dup_dissector_name = "(anonymous)";
1475
0
        }
1476
0
        ws_dissector_bug("Dissectors %s and %s in dissector table %s would have the same Decode As preference\n",
1477
0
            dissector_name,
1478
0
            dup_dissector_name,
1479
0
            name);
1480
0
      }
1481
14
    }
1482
14
  }
1483
1484
9.99k
  return *range;
1485
9.99k
}
1486
1487
void dissector_add_uint_with_preference(const char *name, const uint32_t pattern,
1488
    dissector_handle_t handle)
1489
5.33k
{
1490
5.33k
  char* range_str;
1491
1492
5.33k
  range_str = wmem_strdup_printf(NULL, "%d", pattern);
1493
5.33k
  dissector_add_range_preference(name, handle, range_str);
1494
5.33k
  wmem_free(NULL, range_str);
1495
5.33k
  dissector_add_uint(name, pattern, handle);
1496
5.33k
}
1497
1498
void dissector_add_uint_range_with_preference(const char *name, const char* range_str,
1499
    dissector_handle_t handle)
1500
2.10k
{
1501
2.10k
  range_t* range;
1502
1503
2.10k
  range = dissector_add_range_preference(name, handle, range_str);
1504
2.10k
  dissector_add_uint_range(name, range, handle);
1505
2.10k
}
1506
1507
/* Delete the entry for a dissector in a uint dissector table
1508
   with a particular pattern. */
1509
1510
/* NOTE: this doesn't use the dissector call variable. It is included to */
1511
/*  be consistent with the dissector_add_uint and more importantly to be used */
1512
/*  if the technique of adding a temporary dissector is implemented.  */
1513
/*  If temporary dissectors are deleted, then the original dissector must */
1514
/*  be available. */
1515
void
1516
dissector_delete_uint(const char *name, const uint32_t pattern,
1517
  dissector_handle_t handle _U_)
1518
14
{
1519
14
  dissector_table_t sub_dissectors = find_dissector_table(name);
1520
14
  dtbl_entry_t *dtbl_entry;
1521
1522
  /* sanity check */
1523
14
  ws_assert(sub_dissectors);
1524
1525
  /*
1526
   * Find the entry.
1527
   */
1528
14
  dtbl_entry = find_uint_dtbl_entry(sub_dissectors, pattern);
1529
1530
14
  if (dtbl_entry != NULL) {
1531
    /*
1532
     * Found - remove it.
1533
     */
1534
0
    g_hash_table_remove(sub_dissectors->hash_table,
1535
0
            GUINT_TO_POINTER(pattern));
1536
0
  }
1537
14
}
1538
1539
void dissector_delete_uint_range(const char *name, range_t *range,
1540
         dissector_handle_t handle)
1541
14
{
1542
14
  uint32_t i, j;
1543
1544
14
  if (range) {
1545
0
    for (i = 0; i < range->nranges; i++) {
1546
0
      for (j = range->ranges[i].low; j < range->ranges[i].high; j++)
1547
0
        dissector_delete_uint(name, j, handle);
1548
0
      dissector_delete_uint(name, range->ranges[i].high, handle);
1549
0
    }
1550
0
  }
1551
14
}
1552
1553
/* Remove an entry from a guid dissector table. */
1554
void dissector_delete_guid(const char *name, guid_key* guid_val, dissector_handle_t handle)
1555
0
{
1556
0
  dissector_table_t  sub_dissectors;
1557
0
  dtbl_entry_t      *dtbl_entry;
1558
1559
0
  sub_dissectors = find_dissector_table(name);
1560
1561
  /* sanity check */
1562
0
  ws_assert(sub_dissectors);
1563
1564
  /* Find the table entry */
1565
0
  dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, guid_val);
1566
1567
0
  if (dtbl_entry == NULL) {
1568
0
    fprintf(stderr, "OOPS: guid not found in dissector table \"%s\"\n", name);
1569
0
    return;
1570
0
  }
1571
1572
  /* Make sure the handles match */
1573
0
  if (dtbl_entry->current != handle) {
1574
0
    fprintf(stderr, "OOPS: handle does not match for guid in dissector table \"%s\"\n", name);
1575
0
    return;
1576
0
  }
1577
1578
  /* Remove the table entry */
1579
0
  g_hash_table_remove(sub_dissectors->hash_table, guid_val);
1580
0
}
1581
1582
1583
static gboolean
1584
dissector_delete_all_check (void *key _U_, void *value, void *user_data)
1585
70
{
1586
70
  dtbl_entry_t *dtbl_entry = (dtbl_entry_t *) value;
1587
70
  dissector_handle_t handle = (dissector_handle_t) user_data;
1588
1589
70
  if (!dtbl_entry->current->protocol) {
1590
    /*
1591
     * Not all dissectors are registered with a protocol, so we need this
1592
     * check when running from dissector_delete_from_all_tables.
1593
     */
1594
0
    return FALSE;
1595
0
  }
1596
1597
70
  return (proto_get_id (dtbl_entry->current->protocol) == proto_get_id (handle->protocol));
1598
70
}
1599
1600
/* Delete all entries from a dissector table. */
1601
void dissector_delete_all(const char *name, dissector_handle_t handle)
1602
252
{
1603
252
  dissector_table_t sub_dissectors = find_dissector_table(name);
1604
252
  ws_assert (sub_dissectors);
1605
1606
252
  g_hash_table_foreach_remove (sub_dissectors->hash_table, dissector_delete_all_check, handle);
1607
252
}
1608
1609
static void
1610
dissector_delete_from_table(void *key _U_, void *value, void *user_data)
1611
0
{
1612
0
  dissector_table_t sub_dissectors = (dissector_table_t) value;
1613
0
  ws_assert (sub_dissectors);
1614
1615
0
  dissector_handle_t handle = (dissector_handle_t) user_data;
1616
1617
0
  g_hash_table_foreach_remove(sub_dissectors->hash_table, dissector_delete_all_check, user_data);
1618
0
  sub_dissectors->dissector_handles = g_slist_remove(sub_dissectors->dissector_handles, user_data);
1619
0
  if (sub_dissectors->da_descriptions)
1620
0
    g_hash_table_remove(sub_dissectors->da_descriptions, handle->description);
1621
0
}
1622
1623
/* Delete handle from all tables and dissector_handles lists */
1624
static void
1625
dissector_delete_from_all_tables(dissector_handle_t handle)
1626
0
{
1627
0
  g_hash_table_foreach(dissector_tables, dissector_delete_from_table, handle);
1628
0
}
1629
1630
/* Change the entry for a dissector in a uint dissector table
1631
   with a particular pattern to use a new dissector handle. */
1632
void
1633
dissector_change_uint(const char *name, const uint32_t pattern, dissector_handle_t handle)
1634
0
{
1635
0
  dissector_table_t sub_dissectors = find_dissector_table(name);
1636
0
  dtbl_entry_t *dtbl_entry;
1637
1638
  /* sanity check */
1639
0
  ws_assert(sub_dissectors);
1640
1641
  /*
1642
   * See if the entry already exists. If so, reuse it.
1643
   */
1644
0
  dtbl_entry = find_uint_dtbl_entry(sub_dissectors, pattern);
1645
0
  if (dtbl_entry != NULL) {
1646
    /*
1647
     * If there's no initial value, and the user said not
1648
     * to decode it, just remove the entry to save memory.
1649
     */
1650
0
    if (handle == NULL && dtbl_entry->initial == NULL) {
1651
0
      g_hash_table_remove(sub_dissectors->hash_table,
1652
0
              GUINT_TO_POINTER(pattern));
1653
0
      return;
1654
0
    }
1655
0
    dtbl_entry->current = handle;
1656
0
    return;
1657
0
  }
1658
1659
  /*
1660
   * Don't create an entry if there is no dissector handle - I.E. the
1661
   * user said not to decode something that wasn't being decoded
1662
   * in the first place.
1663
   */
1664
0
  if (handle == NULL)
1665
0
    return;
1666
1667
0
  dtbl_entry = g_new(dtbl_entry_t, 1);
1668
0
  dtbl_entry->initial = NULL;
1669
0
  dtbl_entry->current = handle;
1670
1671
  /* do the table insertion */
1672
0
  g_hash_table_insert(sub_dissectors->hash_table,
1673
0
           GUINT_TO_POINTER(pattern), (void *)dtbl_entry);
1674
0
}
1675
1676
/* Reset an entry in a uint dissector table to its initial value. */
1677
void
1678
dissector_reset_uint(const char *name, const uint32_t pattern)
1679
0
{
1680
0
  dissector_table_t  sub_dissectors = find_dissector_table(name);
1681
0
  dtbl_entry_t      *dtbl_entry;
1682
1683
  /* sanity check */
1684
0
  ws_assert(sub_dissectors);
1685
1686
  /*
1687
   * Find the entry.
1688
   */
1689
0
  dtbl_entry = find_uint_dtbl_entry(sub_dissectors, pattern);
1690
1691
0
  if (dtbl_entry == NULL)
1692
0
    return;
1693
1694
  /*
1695
   * Found - is there an initial value?
1696
   */
1697
0
  if (dtbl_entry->initial != NULL) {
1698
0
    dtbl_entry->current = dtbl_entry->initial;
1699
0
  } else {
1700
0
    g_hash_table_remove(sub_dissectors->hash_table,
1701
0
            GUINT_TO_POINTER(pattern));
1702
0
  }
1703
0
}
1704
1705
/* Return true if an entry in a uint dissector table is found and has been
1706
 * changed (i.e. dissector_change_uint() has been called, such as from
1707
 * Decode As, prefs registered via dissector_add_uint_[range_]with_preference),
1708
 * etc.), otherwise return false.
1709
 */
1710
bool
1711
dissector_is_uint_changed(dissector_table_t const sub_dissectors, const uint32_t uint_val)
1712
301k
{
1713
301k
  if (sub_dissectors != NULL) {
1714
301k
    dtbl_entry_t *dtbl_entry = find_uint_dtbl_entry(sub_dissectors, uint_val);
1715
301k
    if (dtbl_entry != NULL)
1716
155k
      return (dtbl_entry->current != dtbl_entry->initial);
1717
301k
  }
1718
146k
  return false;
1719
301k
}
1720
1721
/* Look for a given value in a given uint dissector table and, if found,
1722
   call the dissector with the arguments supplied, and return the number
1723
   of bytes consumed by the dissector, otherwise return 0. */
1724
1725
int
1726
dissector_try_uint_with_data(dissector_table_t sub_dissectors, const uint32_t uint_val,
1727
           tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1728
           const bool add_proto_name, void *data)
1729
703k
{
1730
703k
  dtbl_entry_t            *dtbl_entry;
1731
703k
  struct dissector_handle *handle;
1732
703k
  uint32_t                 saved_match_uint;
1733
703k
  int len;
1734
1735
703k
  dtbl_entry = find_uint_dtbl_entry(sub_dissectors, uint_val);
1736
703k
  if (dtbl_entry == NULL) {
1737
    /*
1738
     * There's no entry in the table for our value.
1739
     */
1740
166k
    return 0;
1741
166k
  }
1742
1743
  /*
1744
   * Is there currently a dissector handle for this entry?
1745
   */
1746
536k
  handle = dtbl_entry->current;
1747
536k
  if (handle == NULL) {
1748
    /*
1749
     * No - pretend this dissector didn't exist,
1750
     * so that other dissectors might have a chance
1751
     * to dissect this packet.
1752
     */
1753
0
    return 0;
1754
0
  }
1755
1756
  /*
1757
   * Save the current value of "pinfo->match_uint",
1758
   * set it to the uint_val that matched, call the
1759
   * dissector, and restore "pinfo->match_uint".
1760
   */
1761
536k
  saved_match_uint  = pinfo->match_uint;
1762
536k
  pinfo->match_uint = uint_val;
1763
536k
  len = call_dissector_work(handle, tvb, pinfo, tree, add_proto_name, data);
1764
536k
  pinfo->match_uint = saved_match_uint;
1765
1766
  /*
1767
   * If a new-style dissector returned 0, it means that
1768
   * it didn't think this tvbuff represented a packet for
1769
   * its protocol, and didn't dissect anything.
1770
   *
1771
   * Old-style dissectors can't reject the packet.
1772
   *
1773
   * 0 is also returned if the protocol wasn't enabled.
1774
   *
1775
   * If the packet was rejected, we return 0, so that
1776
   * other dissectors might have a chance to dissect this
1777
   * packet, otherwise we return the dissected length.
1778
   */
1779
536k
  return len;
1780
536k
}
1781
1782
int
1783
dissector_try_uint(dissector_table_t sub_dissectors, const uint32_t uint_val,
1784
       tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1785
289k
{
1786
1787
289k
  return dissector_try_uint_with_data(sub_dissectors, uint_val, tvb, pinfo, tree, true, NULL);
1788
289k
}
1789
1790
/* Look for a given value in a given uint dissector table and, if found,
1791
   return the dissector handle for that value. */
1792
dissector_handle_t
1793
dissector_get_uint_handle(dissector_table_t const sub_dissectors, const uint32_t uint_val)
1794
369k
{
1795
369k
  dtbl_entry_t *dtbl_entry;
1796
1797
369k
  dtbl_entry = find_uint_dtbl_entry(sub_dissectors, uint_val);
1798
369k
  if (dtbl_entry != NULL)
1799
36.1k
    return dtbl_entry->current;
1800
333k
  else
1801
333k
    return NULL;
1802
369k
}
1803
1804
dissector_handle_t
1805
dissector_get_default_uint_handle(const char *name, const uint32_t uint_val)
1806
55
{
1807
55
  dissector_table_t sub_dissectors = find_dissector_table(name);
1808
1809
55
  if (sub_dissectors != NULL) {
1810
55
    dtbl_entry_t *dtbl_entry = find_uint_dtbl_entry(sub_dissectors, uint_val);
1811
55
    if (dtbl_entry != NULL)
1812
55
      return dtbl_entry->initial;
1813
55
  }
1814
0
  return NULL;
1815
55
}
1816
1817
/* Find an entry in a string dissector table. */
1818
static dtbl_entry_t *
1819
find_string_dtbl_entry(dissector_table_t const sub_dissectors, const char *pattern)
1820
13.4k
{
1821
13.4k
  dtbl_entry_t *ret;
1822
13.4k
  char *key;
1823
1824
13.4k
  switch (sub_dissectors->type) {
1825
1826
13.4k
  case FT_STRING:
1827
13.4k
  case FT_STRINGZ:
1828
13.4k
  case FT_STRINGZPAD:
1829
13.4k
  case FT_STRINGZTRUNC:
1830
    /*
1831
     * You can do a string lookup in these tables.
1832
     */
1833
13.4k
    break;
1834
1835
0
  default:
1836
    /*
1837
     * But you can't do a string lookup in any other types
1838
     * of tables.
1839
     */
1840
0
    ws_assert_not_reached();
1841
13.4k
  }
1842
1843
13.4k
  if (sub_dissectors->param == STRING_CASE_INSENSITIVE) {
1844
5.83k
    key = g_ascii_strdown(pattern, -1);
1845
7.63k
  } else {
1846
7.63k
    key = g_strdup(pattern);
1847
7.63k
  }
1848
1849
  /*
1850
   * Find the entry.
1851
   */
1852
13.4k
  ret = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, key);
1853
1854
13.4k
  g_free(key);
1855
1856
13.4k
  return ret;
1857
13.4k
}
1858
1859
/* Add an entry to a string dissector table. */
1860
void
1861
dissector_add_string(const char *name, const char *pattern,
1862
         dissector_handle_t handle)
1863
37.1k
{
1864
37.1k
  dissector_table_t  sub_dissectors;
1865
37.1k
  dtbl_entry_t      *dtbl_entry;
1866
37.1k
  char *key;
1867
1868
37.1k
  if (!dissector_get_table_checked(name, handle, &sub_dissectors))
1869
0
    return;
1870
1871
37.1k
  switch (sub_dissectors->type) {
1872
1873
37.0k
  case FT_STRING:
1874
37.1k
  case FT_STRINGZ:
1875
37.1k
  case FT_STRINGZPAD:
1876
37.1k
  case FT_STRINGZTRUNC:
1877
    /*
1878
     * You can do a string lookup in these tables.
1879
     */
1880
37.1k
    break;
1881
1882
0
  default:
1883
    /*
1884
     * But you can't do a string lookup in any other types
1885
     * of tables.
1886
     */
1887
0
    ws_assert_not_reached();
1888
37.1k
  }
1889
1890
37.1k
  dtbl_entry = g_new(dtbl_entry_t, 1);
1891
37.1k
  dtbl_entry->current = handle;
1892
37.1k
  dtbl_entry->initial = dtbl_entry->current;
1893
1894
37.1k
  if (sub_dissectors->param == STRING_CASE_INSENSITIVE) {
1895
6.02k
    key = g_ascii_strdown(pattern, -1);
1896
31.0k
  } else {
1897
31.0k
    key = g_strdup(pattern);
1898
31.0k
  }
1899
1900
  /* do the table insertion */
1901
37.1k
  g_hash_table_insert(sub_dissectors->hash_table, (void *)key,
1902
37.1k
           (void *)dtbl_entry);
1903
1904
  /*
1905
   * Now, if this table supports "Decode As", add this handle
1906
   * to the list of handles that could be used for "Decode As"
1907
   * with this table, because it *is* being used with this table.
1908
   */
1909
37.1k
  if (sub_dissectors->supports_decode_as)
1910
7.08k
    dissector_add_for_decode_as(name, handle);
1911
37.1k
}
1912
1913
/* Delete the entry for a dissector in a string dissector table
1914
   with a particular pattern. */
1915
1916
/* NOTE: this doesn't use the dissector call variable. It is included to */
1917
/*  be consistent with the dissector_add_string and more importantly to */
1918
/*      be used if the technique of adding a temporary dissector is */
1919
/*      implemented.  */
1920
/*  If temporary dissectors are deleted, then the original dissector must */
1921
/*  be available. */
1922
void
1923
dissector_delete_string(const char *name, const char *pattern,
1924
  dissector_handle_t handle _U_)
1925
0
{
1926
0
  dissector_table_t  sub_dissectors = find_dissector_table(name);
1927
0
  dtbl_entry_t      *dtbl_entry;
1928
1929
  /* sanity check */
1930
0
  ws_assert(sub_dissectors);
1931
1932
  /*
1933
   * Find the entry.
1934
   */
1935
0
  dtbl_entry = find_string_dtbl_entry(sub_dissectors, pattern);
1936
1937
0
  if (dtbl_entry != NULL) {
1938
    /*
1939
     * Found - remove it.
1940
     */
1941
0
    g_hash_table_remove(sub_dissectors->hash_table, pattern);
1942
0
  }
1943
0
}
1944
1945
/* Change the entry for a dissector in a string dissector table
1946
   with a particular pattern to use a new dissector handle. */
1947
void
1948
dissector_change_string(const char *name, const char *pattern,
1949
      dissector_handle_t handle)
1950
0
{
1951
0
  dissector_table_t  sub_dissectors = find_dissector_table(name);
1952
0
  dtbl_entry_t      *dtbl_entry;
1953
1954
  /* sanity check */
1955
0
  ws_assert(sub_dissectors);
1956
1957
  /*
1958
   * See if the entry already exists. If so, reuse it.
1959
   */
1960
0
  dtbl_entry = find_string_dtbl_entry(sub_dissectors, pattern);
1961
0
  if (dtbl_entry != NULL) {
1962
    /*
1963
     * If there's no initial value, and the user said not
1964
     * to decode it, just remove the entry to save memory.
1965
     */
1966
0
    if (handle == NULL && dtbl_entry->initial == NULL) {
1967
0
      g_hash_table_remove(sub_dissectors->hash_table,
1968
0
              pattern);
1969
0
      return;
1970
0
    }
1971
0
    dtbl_entry->current = handle;
1972
0
    return;
1973
0
  }
1974
1975
  /*
1976
   * Don't create an entry if there is no dissector handle - I.E. the
1977
   * user said not to decode something that wasn't being decoded
1978
   * in the first place.
1979
   */
1980
0
  if (handle == NULL)
1981
0
    return;
1982
1983
0
  dtbl_entry = g_new(dtbl_entry_t, 1);
1984
0
  dtbl_entry->initial = NULL;
1985
0
  dtbl_entry->current = handle;
1986
1987
  /* do the table insertion */
1988
0
  g_hash_table_insert(sub_dissectors->hash_table, (void *)g_strdup(pattern),
1989
0
           (void *)dtbl_entry);
1990
0
}
1991
1992
/* Reset an entry in a string sub-dissector table to its initial value. */
1993
void
1994
dissector_reset_string(const char *name, const char *pattern)
1995
0
{
1996
0
  dissector_table_t  sub_dissectors = find_dissector_table(name);
1997
0
  dtbl_entry_t      *dtbl_entry;
1998
1999
  /* sanity check */
2000
0
  ws_assert(sub_dissectors);
2001
2002
  /*
2003
   * Find the entry.
2004
   */
2005
0
  dtbl_entry = find_string_dtbl_entry(sub_dissectors, pattern);
2006
2007
0
  if (dtbl_entry == NULL)
2008
0
    return;
2009
2010
  /*
2011
   * Found - is there an initial value?
2012
   */
2013
0
  if (dtbl_entry->initial != NULL) {
2014
0
    dtbl_entry->current = dtbl_entry->initial;
2015
0
  } else {
2016
0
    g_hash_table_remove(sub_dissectors->hash_table, pattern);
2017
0
  }
2018
0
}
2019
2020
/* Return true if an entry in a uint dissector table is found and has been
2021
 * changed (i.e. dissector_change_uint() has been called, such as from
2022
 * Decode As, prefs registered via dissector_add_uint_[range_]with_preference),
2023
 * etc.), otherwise return false.
2024
 */
2025
bool
2026
dissector_is_string_changed(dissector_table_t const sub_dissectors, const char *string)
2027
0
{
2028
0
  if (sub_dissectors != NULL) {
2029
0
    dtbl_entry_t *dtbl_entry = find_string_dtbl_entry(sub_dissectors, string);
2030
0
    if (dtbl_entry != NULL)
2031
0
      return (dtbl_entry->current != dtbl_entry->initial);
2032
0
  }
2033
0
  return false;
2034
0
}
2035
2036
/* Look for a given string in a given dissector table and, if found, call
2037
   the dissector with the arguments supplied, and return length of dissected data,
2038
   otherwise return 0. */
2039
int
2040
dissector_try_string_with_data(dissector_table_t sub_dissectors, const char *string,
2041
         tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const bool add_proto_name, void *data)
2042
12.6k
{
2043
12.6k
  dtbl_entry_t            *dtbl_entry;
2044
12.6k
  struct dissector_handle *handle;
2045
12.6k
  int                      len;
2046
12.6k
  const char              *saved_match_string;
2047
2048
  /* XXX ASSERT instead ? */
2049
12.6k
  if (!string) return 0;
2050
12.6k
  dtbl_entry = find_string_dtbl_entry(sub_dissectors, string);
2051
12.6k
  if (dtbl_entry != NULL) {
2052
    /*
2053
     * Is there currently a dissector handle for this entry?
2054
     */
2055
5.17k
    handle = dtbl_entry->current;
2056
5.17k
    if (handle == NULL) {
2057
      /*
2058
       * No - pretend this dissector didn't exist,
2059
       * so that other dissectors might have a chance
2060
       * to dissect this packet.
2061
       */
2062
0
      return 0;
2063
0
    }
2064
2065
    /*
2066
     * Save the current value of "pinfo->match_string",
2067
     * set it to the string that matched, call the
2068
     * dissector, and restore "pinfo->match_string".
2069
     */
2070
5.17k
    saved_match_string = pinfo->match_string;
2071
5.17k
    pinfo->match_string = string;
2072
5.17k
    len = call_dissector_work(handle, tvb, pinfo, tree, add_proto_name, data);
2073
5.17k
    pinfo->match_string = saved_match_string;
2074
2075
    /*
2076
     * If a new-style dissector returned 0, it means that
2077
     * it didn't think this tvbuff represented a packet for
2078
     * its protocol, and didn't dissect anything.
2079
     *
2080
     * Old-style dissectors can't reject the packet.
2081
     *
2082
     * 0 is also returned if the protocol wasn't enabled.
2083
     *
2084
     * If the packet was rejected, we return 0, so that
2085
     * other dissectors might have a chance to dissect this
2086
     * packet, otherwise we return the dissected length.
2087
     */
2088
5.17k
    return len;
2089
5.17k
  }
2090
7.49k
  return 0;
2091
12.6k
}
2092
2093
/* Look for a given value in a given string dissector table and, if found,
2094
   return the dissector handle for that value. */
2095
dissector_handle_t
2096
dissector_get_string_handle(dissector_table_t sub_dissectors,
2097
          const char *string)
2098
804
{
2099
804
  dtbl_entry_t *dtbl_entry;
2100
2101
  /* XXX ASSERT instead ? */
2102
804
  if (!string) return NULL;
2103
804
  dtbl_entry = find_string_dtbl_entry(sub_dissectors, string);
2104
804
  if (dtbl_entry != NULL)
2105
65
    return dtbl_entry->current;
2106
739
  else
2107
739
    return NULL;
2108
804
}
2109
2110
dissector_handle_t
2111
dissector_get_default_string_handle(const char *name, const char *string)
2112
0
{
2113
0
  dissector_table_t sub_dissectors;
2114
2115
  /* XXX ASSERT instead ? */
2116
0
  if (!string) return NULL;
2117
0
  sub_dissectors = find_dissector_table(name);
2118
0
  if (sub_dissectors != NULL) {
2119
0
    dtbl_entry_t *dtbl_entry = find_string_dtbl_entry(sub_dissectors, string);
2120
0
    if (dtbl_entry != NULL)
2121
0
      return dtbl_entry->initial;
2122
0
  }
2123
0
  return NULL;
2124
0
}
2125
2126
/* Add an entry to a "custom" dissector table. */
2127
void dissector_add_custom_table_handle(const char *name, void *pattern, dissector_handle_t handle)
2128
21.1k
{
2129
21.1k
  dissector_table_t  sub_dissectors;
2130
21.1k
  dtbl_entry_t      *dtbl_entry;
2131
2132
21.1k
  if (!dissector_get_table_checked(name, handle, &sub_dissectors))
2133
0
    return;
2134
2135
21.1k
  ws_assert(sub_dissectors->type == FT_BYTES);
2136
2137
21.1k
  dtbl_entry = g_new(dtbl_entry_t, 1);
2138
21.1k
  dtbl_entry->current = handle;
2139
21.1k
  dtbl_entry->initial = dtbl_entry->current;
2140
2141
  /* do the table insertion */
2142
21.1k
  g_hash_table_insert(sub_dissectors->hash_table, (void *)pattern,
2143
21.1k
           (void *)dtbl_entry);
2144
2145
  /*
2146
   * Now, if this table supports "Decode As", add this handle
2147
   * to the list of handles that could be used for "Decode As"
2148
   * with this table, because it *is* being used with this table.
2149
   */
2150
21.1k
  if (sub_dissectors->supports_decode_as)
2151
0
    dissector_add_for_decode_as(name, handle);
2152
21.1k
}
2153
2154
dissector_handle_t dissector_get_custom_table_handle(dissector_table_t sub_dissectors, void *key)
2155
36.2k
{
2156
36.2k
  dtbl_entry_t *dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, key);
2157
2158
36.2k
  if (dtbl_entry != NULL)
2159
5.87k
    return dtbl_entry->current;
2160
2161
30.3k
  return NULL;
2162
36.2k
}
2163
/* Add an entry to a guid dissector table. */
2164
void dissector_add_guid(const char *name, guid_key* guid_val, dissector_handle_t handle)
2165
1.41k
{
2166
1.41k
  dissector_table_t  sub_dissectors;
2167
1.41k
  dtbl_entry_t      *dtbl_entry;
2168
2169
1.41k
  if (!dissector_get_table_checked(name, handle, &sub_dissectors))
2170
0
    return;
2171
2172
1.41k
  if (sub_dissectors->type != FT_GUID) {
2173
0
    ws_assert_not_reached();
2174
0
  }
2175
2176
1.41k
  dtbl_entry = g_new(dtbl_entry_t, 1);
2177
1.41k
  dtbl_entry->current = handle;
2178
1.41k
  dtbl_entry->initial = dtbl_entry->current;
2179
2180
  /* do the table insertion */
2181
1.41k
  g_hash_table_insert(sub_dissectors->hash_table,
2182
1.41k
           guid_val, (void *)dtbl_entry);
2183
2184
  /*
2185
   * Now, if this table supports "Decode As", add this handle
2186
   * to the list of handles that could be used for "Decode As"
2187
   * with this table, because it *is* being used with this table.
2188
   */
2189
1.41k
  if (sub_dissectors->supports_decode_as)
2190
1.33k
    dissector_add_for_decode_as(name, handle);
2191
1.41k
}
2192
2193
/* Look for a given value in a given guid dissector table and, if found,
2194
   call the dissector with the arguments supplied, and return true,
2195
   otherwise return false. */
2196
int dissector_try_guid_with_data(dissector_table_t sub_dissectors,
2197
    guid_key* guid_val, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const bool add_proto_name, void *data)
2198
4
{
2199
4
  dtbl_entry_t            *dtbl_entry;
2200
4
  struct dissector_handle *handle;
2201
4
  int len;
2202
2203
4
  dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, guid_val);
2204
4
  if (dtbl_entry != NULL) {
2205
    /*
2206
     * Is there currently a dissector handle for this entry?
2207
     */
2208
4
    handle = dtbl_entry->current;
2209
4
    if (handle == NULL) {
2210
      /*
2211
       * No - pretend this dissector didn't exist,
2212
       * so that other dissectors might have a chance
2213
       * to dissect this packet.
2214
       */
2215
0
      return 0;
2216
0
    }
2217
2218
    /*
2219
     * Save the current value of "pinfo->match_uint",
2220
     * set it to the uint_val that matched, call the
2221
     * dissector, and restore "pinfo->match_uint".
2222
     */
2223
4
    len = call_dissector_work(handle, tvb, pinfo, tree, add_proto_name, data);
2224
2225
    /*
2226
     * If a new-style dissector returned 0, it means that
2227
     * it didn't think this tvbuff represented a packet for
2228
     * its protocol, and didn't dissect anything.
2229
     *
2230
     * Old-style dissectors can't reject the packet.
2231
     *
2232
     * 0 is also returned if the protocol wasn't enabled.
2233
     *
2234
     * If the packet was rejected, we return 0, so that
2235
     * other dissectors might have a chance to dissect this
2236
     * packet, otherwise we return the dissected length.
2237
     */
2238
4
    return len;
2239
4
  }
2240
0
  return 0;
2241
4
}
2242
2243
/** Look for a given value in a given guid dissector table and, if found,
2244
 * return the current dissector handle for that value.
2245
 *
2246
 * @param[in] sub_dissectors Dissector table to search.
2247
 * @param[in] guid_val Value to match.
2248
 * @return The matching dissector handle on success, NULL if no match is found.
2249
 */
2250
dissector_handle_t dissector_get_guid_handle(
2251
    dissector_table_t const sub_dissectors, guid_key* guid_val)
2252
0
{
2253
0
  dtbl_entry_t *dtbl_entry;
2254
2255
0
  dtbl_entry = (dtbl_entry_t *)g_hash_table_lookup(sub_dissectors->hash_table, guid_val);
2256
0
  if (dtbl_entry != NULL)
2257
0
    return dtbl_entry->current;
2258
0
  else
2259
0
    return NULL;
2260
0
}
2261
2262
/* Use the currently assigned payload dissector for the dissector table and,
2263
   if any, call the dissector with the arguments supplied, and return the
2264
   number of bytes consumed, otherwise return 0. */
2265
int dissector_try_payload_with_data(dissector_table_t sub_dissectors,
2266
    tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const bool add_proto_name, void *data)
2267
521
{
2268
521
  return dissector_try_uint_with_data(sub_dissectors, 0, tvb, pinfo, tree, add_proto_name, data);
2269
521
}
2270
2271
/* Change the entry for a dissector in a payload (FT_NONE) dissector table
2272
   with a particular pattern to use a new dissector handle. */
2273
void dissector_change_payload(const char *name, dissector_handle_t handle)
2274
0
{
2275
0
  dissector_change_uint(name, 0, handle);
2276
0
}
2277
2278
/* Reset payload (FT_NONE) dissector table to its initial value. */
2279
void dissector_reset_payload(const char *name)
2280
0
{
2281
0
  dissector_reset_uint(name, 0);
2282
0
}
2283
2284
/* Given a payload dissector table (type FT_NONE), return the handle of
2285
   the dissector that is currently active, i.e. that was selected via
2286
   Decode As. */
2287
dissector_handle_t
2288
dissector_get_payload_handle(dissector_table_t const dissector_table)
2289
0
{
2290
0
  return dissector_get_uint_handle(dissector_table, 0);
2291
0
}
2292
2293
dissector_handle_t
2294
dtbl_entry_get_handle (dtbl_entry_t *dtbl_entry)
2295
0
{
2296
0
  return dtbl_entry->current;
2297
0
}
2298
2299
static int
2300
dissector_compare_filter_name(const void *dissector_a, const void *dissector_b)
2301
152k
{
2302
152k
  const struct dissector_handle *a = (const struct dissector_handle *)dissector_a;
2303
152k
  const struct dissector_handle *b = (const struct dissector_handle *)dissector_b;
2304
152k
  const char *a_name, *b_name;
2305
152k
  int ret;
2306
2307
152k
  if (a->protocol == NULL)
2308
42
    a_name = "";
2309
152k
  else
2310
152k
    a_name = proto_get_protocol_filter_name(proto_get_id(a->protocol));
2311
2312
152k
  if (b->protocol == NULL)
2313
84
    b_name = "";
2314
152k
  else
2315
152k
    b_name = proto_get_protocol_filter_name(proto_get_id(b->protocol));
2316
2317
152k
  ret = strcmp(a_name, b_name);
2318
152k
  return ret;
2319
152k
}
2320
2321
void
2322
packet_all_tables_sort_handles(void)
2323
14
{
2324
14
  GHashTableIter iter;
2325
14
  g_hash_table_iter_init(&iter, dissector_tables);
2326
14
  void *key, *value;
2327
14
  dissector_table_t table;
2328
8.23k
  while (g_hash_table_iter_next(&iter, &key, &value)) {
2329
8.21k
    table = (dissector_table_t)value;
2330
8.21k
    table->dissector_handles = g_slist_sort(table->dissector_handles, (GCompareFunc)dissector_compare_filter_name);
2331
8.21k
  }
2332
  /* Any handles added to a table after this (e.g., by a Lua dissector,
2333
   * by reloading Lua dissectors, by a UAT or other preference) will
2334
   * be added using g_slist_insert_sorted. */
2335
14
  all_tables_handles_sorted = true;
2336
14
}
2337
2338
/* Add a handle to the list of handles that *could* be used with this
2339
   table.  That list is used by the "Decode As"/"-d" code in the UI. */
2340
void
2341
dissector_add_for_decode_as(const char *name, dissector_handle_t handle)
2342
42.0k
{
2343
42.0k
  dissector_table_t  sub_dissectors;
2344
42.0k
  dissector_handle_t dup_handle;
2345
2346
42.0k
  if (!dissector_get_table_checked(name, handle, &sub_dissectors))
2347
0
    return;
2348
2349
42.0k
  const char *dissector_name;
2350
42.0k
  dissector_name = dissector_handle_get_dissector_name(handle);
2351
42.0k
  if (dissector_name == NULL)
2352
4.38k
    dissector_name = "(anonymous)";
2353
2354
  /*
2355
   * Make sure it supports Decode As.
2356
   */
2357
42.0k
  if (!sub_dissectors->supports_decode_as) {
2358
0
    ws_dissector_bug("Registering dissector %s for protocol %s in dissector table %s, which doesn't support Decode As\n",
2359
0
            dissector_name,
2360
0
            proto_get_protocol_short_name(handle->protocol),
2361
0
            name);
2362
0
    return;
2363
0
  }
2364
2365
  /* For Decode As selection to work, there has to be a description.
2366
   * One is generated if there's a protocol (PINOs are used in some
2367
   * cases to guarantee unique descriptions), but some dissectors are
2368
   * registered without a protocol. That is allowed for fixed tables
2369
   * that don't support Decode As.
2370
   */
2371
42.0k
  if (handle->description == NULL) {
2372
0
    ws_dissector_bug("Cannot register dissector %s in dissector table %s for Decode As without a protocol or description\n",
2373
0
        dissector_name, name);
2374
0
    return;
2375
0
  }
2376
2377
  /* Ensure that the description is unique in the table, so that Decode As
2378
   * selection and UAT preference writing works.
2379
   *
2380
   * XXX - We could do the insert first and then check the return value,
2381
   * saving on a hash comparison. (The failure mode would be slightly
2382
   * different, as it would become last insertion wins.)
2383
   */
2384
42.0k
  dup_handle = g_hash_table_lookup(sub_dissectors->da_descriptions, handle->description);
2385
42.0k
  if (dup_handle != NULL) {
2386
    /* Is this a different handle with the same description, or
2387
     * just trying to insert the same handle a second time? */
2388
8.56k
    if (dup_handle != handle) {
2389
0
      const char *dup_dissector_name;
2390
2391
0
      dup_dissector_name = dissector_handle_get_dissector_name(dup_handle);
2392
0
      if (dup_dissector_name == NULL)
2393
0
        dup_dissector_name = "(anonymous)";
2394
0
      ws_dissector_bug("Dissectors %s and %s in dissector table %s have the same description %s\n",
2395
0
          dissector_name,
2396
0
          dup_dissector_name,
2397
0
          name, handle->description);
2398
0
    }
2399
8.56k
    return;
2400
8.56k
  }
2401
2402
  /* Add the dissector as a dependency
2403
    (some dissector tables don't have protocol association, so there is
2404
    the need for the NULL check */
2405
33.5k
  if (sub_dissectors->protocol != NULL)
2406
32.3k
    register_depend_dissector(proto_get_protocol_short_name(sub_dissectors->protocol), proto_get_protocol_short_name(handle->protocol));
2407
2408
  /* Add it to the list. */
2409
33.5k
  g_hash_table_insert(sub_dissectors->da_descriptions, (void *)handle->description, handle);
2410
33.5k
  if (all_tables_handles_sorted) {
2411
0
    sub_dissectors->dissector_handles =
2412
0
      g_slist_insert_sorted(sub_dissectors->dissector_handles, (void *)handle, (GCompareFunc)dissector_compare_filter_name);
2413
33.5k
  } else {
2414
33.5k
    sub_dissectors->dissector_handles =
2415
33.5k
      g_slist_prepend(sub_dissectors->dissector_handles, (void *)handle);
2416
33.5k
  }
2417
33.5k
}
2418
2419
void dissector_add_for_decode_as_with_preference(const char *name,
2420
    dissector_handle_t handle)
2421
2.56k
{
2422
  /* If a dissector is added for Decode As only, it's dissector
2423
     table value would default to 0.
2424
     Set up a preference value with that information
2425
   */
2426
2.56k
  dissector_add_range_preference(name, handle, "");
2427
2428
2.56k
  dissector_add_for_decode_as(name, handle);
2429
2.56k
}
2430
2431
dissector_handle_t
2432
dtbl_entry_get_initial_handle (dtbl_entry_t *dtbl_entry)
2433
0
{
2434
0
  return dtbl_entry->initial;
2435
0
}
2436
2437
GSList *
2438
12
dissector_table_get_dissector_handles(dissector_table_t dissector_table) {
2439
12
  if (!dissector_table)
2440
0
    return NULL;
2441
2442
12
  return dissector_table->dissector_handles;
2443
12
}
2444
2445
/*
2446
 * Data structure used as user data when iterating dissector handles
2447
 */
2448
typedef struct lookup_entry {
2449
  const char* dissector_description;
2450
  dissector_handle_t handle;
2451
} lookup_entry_t;
2452
2453
/*
2454
 * A callback function to changed a dissector_handle if matched
2455
 * This is used when iterating a dissector table
2456
 */
2457
static void
2458
find_dissector_in_table(void *item, void *user_data)
2459
0
{
2460
0
  dissector_handle_t handle = (dissector_handle_t)item;
2461
0
  lookup_entry_t * lookup = (lookup_entry_t *)user_data;
2462
0
  const char *description = dissector_handle_get_description(handle);
2463
0
  if (description && strcmp(lookup->dissector_description, description) == 0) {
2464
0
    lookup->handle = handle;
2465
0
  }
2466
0
}
2467
2468
dissector_handle_t dissector_table_get_dissector_handle(dissector_table_t dissector_table, const char* description)
2469
0
{
2470
  /* Can this even be called for tables that don't support Decode As? */
2471
0
  if (dissector_table->da_descriptions) {
2472
0
    return g_hash_table_lookup(dissector_table->da_descriptions, description);
2473
0
  }
2474
2475
0
  lookup_entry_t lookup;
2476
2477
0
  lookup.dissector_description = description;
2478
0
  lookup.handle = NULL;
2479
2480
0
  g_slist_foreach(dissector_table->dissector_handles, find_dissector_in_table, &lookup);
2481
0
  return lookup.handle;
2482
0
}
2483
2484
ftenum_t
2485
0
dissector_table_get_type(dissector_table_t dissector_table) {
2486
0
  if (!dissector_table) return FT_NONE;
2487
0
  return dissector_table->type;
2488
0
}
2489
2490
void
2491
dissector_table_allow_decode_as(dissector_table_t dissector_table)
2492
1.06k
{
2493
1.06k
  dissector_table->supports_decode_as = true;
2494
1.06k
  if (dissector_table->da_descriptions == NULL) {
2495
924
    dissector_table->da_descriptions = g_hash_table_new(wmem_str_hash, g_str_equal);
2496
924
  }
2497
1.06k
}
2498
2499
bool
2500
dissector_table_supports_decode_as(dissector_table_t dissector_table)
2501
8.21k
{
2502
8.21k
  return dissector_table->supports_decode_as;
2503
8.21k
}
2504
2505
static int
2506
uuid_equal(const void *k1, const void *k2)
2507
676
{
2508
676
  const guid_key *key1 = (const guid_key *)k1;
2509
676
  const guid_key *key2 = (const guid_key *)k2;
2510
676
  return ((memcmp(&key1->guid, &key2->guid, sizeof (e_guid_t)) == 0)
2511
18
    && (key1->ver == key2->ver));
2512
676
}
2513
2514
static unsigned
2515
uuid_hash(const void *k)
2516
1.41k
{
2517
1.41k
  const guid_key *key = (const guid_key *)k;
2518
  /* This isn't perfect, but the Data1 part of these is almost always unique. */
2519
1.41k
  return key->guid.data1;
2520
1.41k
}
2521
2522
/**************************************************/
2523
/*                                                */
2524
/*       Routines to walk dissector tables        */
2525
/*                                                */
2526
/**************************************************/
2527
2528
typedef struct dissector_foreach_info {
2529
  void *        caller_data;
2530
  DATFunc       caller_func;
2531
  GHFunc        next_func;
2532
  const char   *table_name;
2533
  ftenum_t      selector_type;
2534
} dissector_foreach_info_t;
2535
2536
/*
2537
 * Called for each entry in a dissector table.
2538
 */
2539
static void
2540
dissector_table_foreach_func (void *key, void *value, void *user_data)
2541
826
{
2542
826
  dissector_foreach_info_t *info;
2543
826
  dtbl_entry_t             *dtbl_entry;
2544
2545
826
  ws_assert(value);
2546
826
  ws_assert(user_data);
2547
2548
826
  dtbl_entry = (dtbl_entry_t *)value;
2549
826
  if (dtbl_entry->current == NULL ||
2550
826
      dtbl_entry->current->protocol == NULL) {
2551
    /*
2552
     * Either there is no dissector for this entry, or
2553
     * the dissector doesn't have a protocol associated
2554
     * with it.
2555
     *
2556
     * XXX - should the latter check be done?
2557
     */
2558
0
    return;
2559
0
  }
2560
2561
826
  info = (dissector_foreach_info_t *)user_data;
2562
826
  info->caller_func(info->table_name, info->selector_type, key, value,
2563
826
        info->caller_data);
2564
826
}
2565
2566
/*
2567
 * Called for each entry in the table of all dissector tables.
2568
 */
2569
static void
2570
dissector_all_tables_foreach_func (void *key, void *value, void *user_data)
2571
8.21k
{
2572
8.21k
  dissector_table_t         sub_dissectors;
2573
8.21k
  dissector_foreach_info_t *info;
2574
2575
8.21k
  ws_assert(value);
2576
8.21k
  ws_assert(user_data);
2577
2578
8.21k
  sub_dissectors = (dissector_table_t)value;
2579
8.21k
  info = (dissector_foreach_info_t *)user_data;
2580
8.21k
  info->table_name = (char*) key;
2581
8.21k
  info->selector_type = get_dissector_table_selector_type(info->table_name);
2582
8.21k
  g_hash_table_foreach(sub_dissectors->hash_table, info->next_func, info);
2583
8.21k
}
2584
2585
#if 0
2586
/*
2587
 * Walk all dissector tables calling a user supplied function on each
2588
 * entry.
2589
 */
2590
static void
2591
dissector_all_tables_foreach (DATFunc func,
2592
            void *user_data)
2593
{
2594
  dissector_foreach_info_t info;
2595
2596
  info.caller_data = user_data;
2597
  info.caller_func = func;
2598
  info.next_func   = dissector_table_foreach_func;
2599
  g_hash_table_foreach(dissector_tables, dissector_all_tables_foreach_func, &info);
2600
}
2601
#endif
2602
2603
/*
2604
 * Walk one dissector table's hash table calling a user supplied function
2605
 * on each entry.
2606
 */
2607
void
2608
dissector_table_foreach (const char *table_name,
2609
       DATFunc     func,
2610
       void *      user_data)
2611
14
{
2612
14
  dissector_foreach_info_t info;
2613
14
  dissector_table_t        sub_dissectors = find_dissector_table(table_name);
2614
2615
14
  info.table_name    = table_name;
2616
14
  info.selector_type = sub_dissectors->type;
2617
14
  info.caller_func   = func;
2618
14
  info.caller_data   = user_data;
2619
14
  g_hash_table_foreach(sub_dissectors->hash_table, dissector_table_foreach_func, &info);
2620
14
}
2621
2622
/*
2623
 * Walk one dissector table's list of handles calling a user supplied
2624
 * function on each entry.
2625
 */
2626
void
2627
dissector_table_foreach_handle(const char     *table_name,
2628
             DATFunc_handle  func,
2629
             void *          user_data)
2630
0
{
2631
0
  dissector_table_t sub_dissectors = find_dissector_table(table_name);
2632
0
  GSList *tmp;
2633
2634
0
  for (tmp = sub_dissectors->dissector_handles; tmp != NULL;
2635
0
       tmp = g_slist_next(tmp))
2636
0
    func(table_name, tmp->data, user_data);
2637
0
}
2638
2639
/*
2640
 * Called for each entry in a dissector table.
2641
 */
2642
static void
2643
dissector_table_foreach_changed_func (void *key, void *value, void *user_data)
2644
216k
{
2645
216k
  dtbl_entry_t             *dtbl_entry;
2646
216k
  dissector_foreach_info_t *info;
2647
2648
216k
  ws_assert(value);
2649
216k
  ws_assert(user_data);
2650
2651
216k
  dtbl_entry = (dtbl_entry_t *)value;
2652
216k
  if (dtbl_entry->initial == dtbl_entry->current) {
2653
    /*
2654
     * Entry hasn't changed - don't call the function.
2655
     */
2656
216k
    return;
2657
216k
  }
2658
2659
0
  info = (dissector_foreach_info_t *)user_data;
2660
0
  info->caller_func(info->table_name, info->selector_type, key, value,
2661
0
        info->caller_data);
2662
0
}
2663
2664
/*
2665
 * Walk all dissector tables calling a user supplied function only on
2666
 * any entry that has been changed from its original state.
2667
 */
2668
void
2669
dissector_all_tables_foreach_changed (DATFunc  func,
2670
              void *user_data)
2671
14
{
2672
14
  dissector_foreach_info_t info;
2673
2674
14
  info.caller_data = user_data;
2675
14
  info.caller_func = func;
2676
14
  info.next_func   = dissector_table_foreach_changed_func;
2677
14
  g_hash_table_foreach(dissector_tables, dissector_all_tables_foreach_func, &info);
2678
14
}
2679
2680
/*
2681
 * Walk one dissector table calling a user supplied function only on
2682
 * any entry that has been changed from its original state.
2683
 */
2684
void
2685
dissector_table_foreach_changed (const char *table_name,
2686
         DATFunc     func,
2687
         void *      user_data)
2688
0
{
2689
0
  dissector_foreach_info_t info;
2690
0
  dissector_table_t sub_dissectors = find_dissector_table(table_name);
2691
2692
0
  info.table_name    = table_name;
2693
0
  info.selector_type = sub_dissectors->type;
2694
0
  info.caller_func   = func;
2695
0
  info.caller_data   = user_data;
2696
0
  g_hash_table_foreach(sub_dissectors->hash_table,
2697
0
           dissector_table_foreach_changed_func, &info);
2698
0
}
2699
2700
typedef struct dissector_foreach_table_info {
2701
  void *        caller_data;
2702
  DATFunc_table caller_func;
2703
} dissector_foreach_table_info_t;
2704
2705
/*
2706
 * Called for each entry in the table of all dissector tables.
2707
 * This is used if we directly process the hash table.
2708
 */
2709
static void
2710
dissector_all_tables_foreach_table_func (void *key, void *value, void *user_data)
2711
8.21k
{
2712
8.21k
  dissector_table_t               table;
2713
8.21k
  dissector_foreach_table_info_t *info;
2714
2715
8.21k
  table = (dissector_table_t)value;
2716
8.21k
  info  = (dissector_foreach_table_info_t *)user_data;
2717
8.21k
  (*info->caller_func)((char *)key, table->ui_name, info->caller_data);
2718
8.21k
}
2719
2720
/*
2721
 * Called for each key in the table of all dissector tables.
2722
 * This is used if we get a list of table names, sort it, and process the list.
2723
 */
2724
static void
2725
dissector_all_tables_foreach_list_func (void *key, void *user_data)
2726
0
{
2727
0
  dissector_table_t               table;
2728
0
  dissector_foreach_table_info_t *info;
2729
2730
0
  table = (dissector_table_t)g_hash_table_lookup(dissector_tables, key);
2731
0
  info  = (dissector_foreach_table_info_t *)user_data;
2732
0
  (*info->caller_func)((char*)key, table->ui_name, info->caller_data);
2733
0
}
2734
2735
/*
2736
 * Walk all dissector tables calling a user supplied function on each
2737
 * table.
2738
 */
2739
void
2740
dissector_all_tables_foreach_table (DATFunc_table func,
2741
            void *        user_data,
2742
            GCompareFunc  compare_key_func)
2743
14
{
2744
14
  dissector_foreach_table_info_t info;
2745
14
  GList *list;
2746
2747
14
  info.caller_data = user_data;
2748
14
  info.caller_func = func;
2749
14
  if (compare_key_func != NULL)
2750
0
  {
2751
0
    list = g_hash_table_get_keys(dissector_tables);
2752
0
    list = g_list_sort(list, compare_key_func);
2753
0
    g_list_foreach(list, dissector_all_tables_foreach_list_func, &info);
2754
0
    g_list_free(list);
2755
0
  }
2756
14
  else
2757
14
  {
2758
14
    g_hash_table_foreach(dissector_tables, dissector_all_tables_foreach_table_func, &info);
2759
14
  }
2760
14
}
2761
2762
dissector_table_t
2763
register_dissector_table(const char *name, const char *ui_name, const int proto, const ftenum_t type,
2764
       const int param)
2765
8.06k
{
2766
8.06k
  dissector_table_t sub_dissectors;
2767
2768
  /* Create and register the dissector table for this name; returns */
2769
  /* a pointer to the dissector table. */
2770
8.06k
  sub_dissectors = g_slice_new(struct dissector_table);
2771
8.06k
  switch (type) {
2772
2773
2.12k
  case FT_UINT8:
2774
3.54k
  case FT_UINT16:
2775
3.68k
  case FT_UINT24:
2776
6.69k
  case FT_UINT32:
2777
    /*
2778
     * XXX - there's no "g_uint_hash()" or "g_uint_equal()",
2779
     * so we use "g_direct_hash()" and "g_direct_equal()".
2780
     */
2781
6.69k
    sub_dissectors->hash_func = g_direct_hash;
2782
6.69k
    sub_dissectors->hash_table = g_hash_table_new_full(g_direct_hash,
2783
6.69k
                     g_direct_equal,
2784
6.69k
                     NULL,
2785
6.69k
                     &g_free);
2786
6.69k
    break;
2787
2788
980
  case FT_STRING:
2789
994
  case FT_STRINGZ:
2790
994
  case FT_STRINGZPAD:
2791
994
  case FT_STRINGZTRUNC:
2792
994
    sub_dissectors->hash_func = g_str_hash;
2793
994
    sub_dissectors->hash_table = g_hash_table_new_full(g_str_hash,
2794
994
                     g_str_equal,
2795
994
                     &g_free,
2796
994
                     &g_free);
2797
994
    break;
2798
28
  case FT_GUID:
2799
28
    sub_dissectors->hash_table = g_hash_table_new_full(uuid_hash,
2800
28
                     uuid_equal,
2801
28
                     NULL,
2802
28
                     &g_free);
2803
28
    break;
2804
2805
350
  case FT_NONE:
2806
    /* Dissector tables with FT_NONE don't have values associated with
2807
       dissectors so this will always be a hash table size of 1 just
2808
       to store the single dtbl_entry_t */
2809
350
    sub_dissectors->hash_func = g_direct_hash;
2810
350
    sub_dissectors->hash_table = g_hash_table_new_full(g_direct_hash,
2811
350
                     g_direct_equal,
2812
350
                     NULL,
2813
350
                     &g_free);
2814
350
    break;
2815
2816
0
  default:
2817
0
    ws_error("The dissector table %s (%s) is registering an unsupported type - are you using a buggy plugin?", name, ui_name);
2818
0
    ws_assert_not_reached();
2819
8.06k
  }
2820
8.06k
  sub_dissectors->dissector_handles = NULL;
2821
8.06k
  sub_dissectors->da_descriptions = NULL;
2822
8.06k
  sub_dissectors->ui_name = ui_name;
2823
8.06k
  sub_dissectors->type    = type;
2824
8.06k
  sub_dissectors->param   = param;
2825
8.06k
  sub_dissectors->protocol  = (proto == -1) ? NULL : find_protocol_by_id(proto);
2826
8.06k
  sub_dissectors->supports_decode_as = false;
2827
  /* Make sure the registration is unique */
2828
8.06k
  if (!g_hash_table_insert(dissector_tables, (void *)name, (void *) sub_dissectors)) {
2829
0
    ws_error("The dissector table %s (%s) is already registered - are you using a buggy plugin?", name, ui_name);
2830
0
  }
2831
8.06k
  return sub_dissectors;
2832
8.06k
}
2833
2834
dissector_table_t register_custom_dissector_table(const char *name,
2835
  const char *ui_name, const int proto, GHashFunc hash_func, GEqualFunc key_equal_func,
2836
  GDestroyNotify key_destroy_func)
2837
154
{
2838
154
  dissector_table_t sub_dissectors;
2839
2840
  /* Create and register the dissector table for this name; returns */
2841
  /* a pointer to the dissector table. */
2842
154
  sub_dissectors = g_slice_new(struct dissector_table);
2843
154
  sub_dissectors->hash_func = hash_func;
2844
154
  sub_dissectors->hash_table = g_hash_table_new_full(hash_func,
2845
154
                     key_equal_func,
2846
154
                     key_destroy_func,
2847
154
                     &g_free);
2848
2849
154
  sub_dissectors->dissector_handles = NULL;
2850
154
  sub_dissectors->da_descriptions = NULL;
2851
154
  sub_dissectors->ui_name = ui_name;
2852
154
  sub_dissectors->type    = FT_BYTES; /* Consider key a "blob" of data, no need to really create new type */
2853
154
  sub_dissectors->param   = BASE_NONE;
2854
154
  sub_dissectors->protocol  = (proto == -1) ? NULL : find_protocol_by_id(proto);
2855
154
  sub_dissectors->supports_decode_as = false;
2856
  /* Make sure the registration is unique */
2857
154
  if (!g_hash_table_insert(dissector_tables, (void *)name, (void *) sub_dissectors)) {
2858
0
    ws_error("The dissector table %s (%s) is already registered - are you using a buggy plugin?", name, ui_name);
2859
0
  }
2860
154
  return sub_dissectors;
2861
154
}
2862
2863
void
2864
42
register_dissector_table_alias(dissector_table_t dissector_table, const char *alias_name) {
2865
42
  if (!dissector_table || !alias_name) return;
2866
2867
28
  const char *name = NULL;
2868
28
  GList *list = g_hash_table_get_keys(dissector_tables);
2869
5.50k
  for (GList *cur = list; cur; cur = cur->next) {
2870
5.50k
    if (g_hash_table_lookup(dissector_tables, cur->data) == dissector_table) {
2871
28
      name = (const char *) cur->data;
2872
28
      break;
2873
28
    }
2874
5.50k
  }
2875
28
  g_list_free(list);
2876
28
  if (!name) return;
2877
2878
28
  g_hash_table_insert(dissector_table_aliases, (void *) alias_name, (void *) name);
2879
28
}
2880
2881
void
2882
deregister_dissector_table(const char *name)
2883
0
{
2884
0
  dissector_table_t sub_dissectors = (dissector_table_t) g_hash_table_lookup(dissector_tables, name);
2885
0
  if (!sub_dissectors) return;
2886
2887
0
  g_hash_table_remove(dissector_tables, name);
2888
2889
0
  GList *list = g_hash_table_get_keys(dissector_table_aliases);
2890
0
  for (GList *cur = list; cur; cur = cur->next) {
2891
0
    void *alias_name = cur->data;
2892
0
    if (g_hash_table_lookup(dissector_table_aliases, alias_name) == name) {
2893
0
      g_hash_table_remove(dissector_table_aliases, alias_name);
2894
0
    }
2895
0
  }
2896
0
  g_list_free(list);
2897
0
}
2898
2899
const char *
2900
get_dissector_table_ui_name(const char *name)
2901
0
{
2902
0
  dissector_table_t sub_dissectors = find_dissector_table(name);
2903
0
  if (!sub_dissectors) return NULL;
2904
2905
0
  return sub_dissectors->ui_name;
2906
0
}
2907
2908
ftenum_t
2909
get_dissector_table_selector_type(const char *name)
2910
8.21k
{
2911
8.21k
  dissector_table_t sub_dissectors = find_dissector_table(name);
2912
8.21k
  if (!sub_dissectors) return FT_NONE;
2913
2914
8.21k
  return sub_dissectors->type;
2915
8.21k
}
2916
2917
int
2918
get_dissector_table_param(const char *name)
2919
0
{
2920
0
  dissector_table_t sub_dissectors = find_dissector_table(name);
2921
0
  if (!sub_dissectors) return 0;
2922
2923
0
  return sub_dissectors->param;
2924
0
}
2925
2926
static void
2927
check_valid_heur_name_or_fail(const char *heur_name)
2928
5.57k
{
2929
5.57k
  if (proto_check_field_name_lower(heur_name)) {
2930
0
    ws_error("Heuristic Protocol internal name \"%s\" has one or more invalid characters."
2931
0
      " Allowed are lowercase, digits, '-', '_' and non-repeating '.'."
2932
0
      " This might be caused by an inappropriate plugin or a development error.", heur_name);
2933
0
  }
2934
5.57k
}
2935
2936
/* Finds a heuristic dissector table by table name. */
2937
heur_dissector_list_t
2938
find_heur_dissector_list(const char *name)
2939
5.61k
{
2940
5.61k
  return (heur_dissector_list_t)g_hash_table_lookup(heur_dissector_lists, name);
2941
5.61k
}
2942
2943
bool
2944
0
has_heur_dissector_list(const char *name) {
2945
0
  return (find_heur_dissector_list(name) != NULL);
2946
0
}
2947
2948
heur_dtbl_entry_t* find_heur_dissector_by_unique_short_name(const char *short_name)
2949
5.58k
{
2950
5.58k
  return (heur_dtbl_entry_t*)g_hash_table_lookup(heuristic_short_names, short_name);
2951
5.58k
}
2952
2953
void
2954
heur_dissector_add(const char *name, heur_dissector_t dissector, const char *display_name, const char *internal_name, const int proto, heuristic_enable_e enable)
2955
5.57k
{
2956
5.57k
  heur_dissector_list_t  sub_dissectors = find_heur_dissector_list(name);
2957
5.57k
  const char            *proto_name;
2958
5.57k
  heur_dtbl_entry_t     *hdtbl_entry;
2959
5.57k
  GSList                *list_entry;
2960
2961
  /*
2962
   * Make sure the dissector table exists.
2963
   */
2964
5.57k
  if (sub_dissectors == NULL) {
2965
0
    fprintf(stderr, "OOPS: dissector table \"%s\" doesn't exist\n",
2966
0
        name);
2967
0
    proto_name = proto_get_protocol_name(proto);
2968
0
    if (proto_name != NULL) {
2969
0
      fprintf(stderr, "Protocol being registered is \"%s\"\n",
2970
0
          proto_name);
2971
0
    }
2972
0
    if (wireshark_abort_on_dissector_bug)
2973
0
      abort();
2974
0
    return;
2975
0
  }
2976
2977
  /* Verify that sub-dissector is not already in the list */
2978
5.57k
  for (list_entry = sub_dissectors->dissectors;
2979
147k
    list_entry != NULL; list_entry = list_entry->next)
2980
141k
  {
2981
141k
    hdtbl_entry = (heur_dtbl_entry_t *)list_entry->data;
2982
141k
    if ((hdtbl_entry->dissector == dissector) &&
2983
0
      (hdtbl_entry->protocol == find_protocol_by_id(proto)))
2984
0
    {
2985
0
      proto_name = proto_get_protocol_name(proto);
2986
0
      if (proto_name != NULL) {
2987
0
        fprintf(stderr, "Protocol %s is already registered in \"%s\" table\n",
2988
0
            proto_name, name);
2989
0
      }
2990
0
      if (wireshark_abort_on_dissector_bug)
2991
0
        abort();
2992
0
      return;
2993
0
    }
2994
141k
  }
2995
2996
  /* Make sure short_name is "parsing friendly" since it should only be used internally */
2997
5.57k
  check_valid_heur_name_or_fail(internal_name);
2998
2999
5.57k
  hdtbl_entry = g_slice_new(heur_dtbl_entry_t);
3000
5.57k
  hdtbl_entry->dissector = dissector;
3001
5.57k
  hdtbl_entry->protocol  = find_protocol_by_id(proto);
3002
5.57k
  hdtbl_entry->display_name = display_name;
3003
5.57k
  hdtbl_entry->short_name = g_strdup(internal_name);
3004
5.57k
  hdtbl_entry->list_name = g_strdup(name);
3005
5.57k
  hdtbl_entry->enabled   = (enable == HEURISTIC_ENABLE);
3006
5.57k
  hdtbl_entry->enabled_by_default = (enable == HEURISTIC_ENABLE);
3007
3008
  /* do the table insertion */
3009
  /* Ensure short_name is unique */
3010
5.57k
  if (!g_hash_table_insert(heuristic_short_names, (void *)hdtbl_entry->short_name, hdtbl_entry)) {
3011
0
    ws_error("Duplicate heuristic short_name \"%s\"!"
3012
0
      " This might be caused by an inappropriate plugin or a development error.", internal_name);
3013
0
  }
3014
3015
5.57k
  sub_dissectors->dissectors = g_slist_prepend(sub_dissectors->dissectors,
3016
5.57k
      (void *)hdtbl_entry);
3017
3018
  /* XXX - could be optimized to pass hdtbl_entry directly */
3019
5.57k
  proto_add_heuristic_dissector(hdtbl_entry->protocol, hdtbl_entry->short_name);
3020
3021
  /* Add the dissector as a dependency
3022
    (some heuristic tables don't have protocol association, so there is
3023
    the need for the NULL check */
3024
5.57k
  if (sub_dissectors->protocol != NULL)
3025
5.57k
    register_depend_dissector(proto_get_protocol_short_name(sub_dissectors->protocol), proto_get_protocol_short_name(hdtbl_entry->protocol));
3026
5.57k
}
3027
3028
3029
3030
static int
3031
14
find_matching_heur_dissector(const void *a, const void *b) {
3032
14
  const heur_dtbl_entry_t *hdtbl_entry_a = (const heur_dtbl_entry_t *) a;
3033
14
  const heur_dtbl_entry_t *hdtbl_entry_b = (const heur_dtbl_entry_t *) b;
3034
3035
14
  return (hdtbl_entry_a->dissector == hdtbl_entry_b->dissector) &&
3036
14
    (hdtbl_entry_a->protocol == hdtbl_entry_b->protocol) ? 0 : 1;
3037
14
}
3038
3039
void
3040
14
heur_dissector_delete(const char *name, heur_dissector_t dissector, const int proto) {
3041
14
  heur_dissector_list_t  sub_dissectors = find_heur_dissector_list(name);
3042
14
  heur_dtbl_entry_t      hdtbl_entry;
3043
14
  GSList                *found_entry;
3044
3045
  /* sanity check */
3046
14
  ws_assert(sub_dissectors != NULL);
3047
3048
14
  hdtbl_entry.dissector = dissector;
3049
14
  hdtbl_entry.protocol  = find_protocol_by_id(proto);
3050
3051
14
  found_entry = g_slist_find_custom(sub_dissectors->dissectors,
3052
14
      (void *) &hdtbl_entry, find_matching_heur_dissector);
3053
3054
14
  if (found_entry) {
3055
0
    heur_dtbl_entry_t *found_hdtbl_entry = (heur_dtbl_entry_t *)(found_entry->data);
3056
0
    proto_add_deregistered_data(found_hdtbl_entry->list_name);
3057
0
    g_hash_table_remove(heuristic_short_names, found_hdtbl_entry->short_name);
3058
0
    proto_add_deregistered_data(found_hdtbl_entry->short_name);
3059
0
    proto_add_deregistered_slice(sizeof(heur_dtbl_entry_t), found_hdtbl_entry);
3060
0
    sub_dissectors->dissectors = g_slist_delete_link(sub_dissectors->dissectors,
3061
0
        found_entry);
3062
0
  }
3063
14
}
3064
3065
bool
3066
dissector_try_heuristic(heur_dissector_list_t sub_dissectors, tvbuff_t *tvb,
3067
      packet_info *pinfo, proto_tree *tree, heur_dtbl_entry_t **heur_dtbl_entry, void *data)
3068
73.1k
{
3069
73.1k
  bool               status;
3070
73.1k
  const char        *saved_curr_proto;
3071
73.1k
  int                saved_proto_layer_num;
3072
73.1k
  const char        *saved_heur_list_name;
3073
73.1k
  GSList            *entry;
3074
73.1k
  GSList            *prev_entry = NULL;
3075
73.1k
  uint16_t           saved_can_desegment;
3076
73.1k
  unsigned           saved_layers_len = 0;
3077
73.1k
  heur_dtbl_entry_t *hdtbl_entry;
3078
73.1k
  int                proto_id;
3079
73.1k
  int                len;
3080
73.1k
  bool               consumed_none;
3081
73.1k
  unsigned           saved_desegment_len;
3082
73.1k
  unsigned           saved_tree_count = tree ? tree->tree_data->count : 0;
3083
3084
  /* can_desegment is set to 2 by anyone which offers this api/service.
3085
     then every time a subdissector is called it is decremented by one.
3086
     thus only the subdissector immediately on top of whoever offers this
3087
     service can use it.
3088
     We save the current value of "can_desegment" for the
3089
     benefit of TCP proxying dissectors such as SOCKS, so they
3090
     can restore it and allow the dissectors they call to use
3091
     the desegmentation service.
3092
  */
3093
73.1k
  saved_can_desegment        = pinfo->can_desegment;
3094
73.1k
  pinfo->saved_can_desegment = saved_can_desegment;
3095
73.1k
  pinfo->can_desegment       = saved_can_desegment-(saved_can_desegment>0);
3096
3097
73.1k
  status      = false;
3098
73.1k
  saved_curr_proto = pinfo->current_proto;
3099
73.1k
  saved_proto_layer_num = pinfo->curr_proto_layer_num;
3100
73.1k
  saved_heur_list_name = pinfo->heur_list_name;
3101
3102
73.1k
  saved_layers_len = wmem_list_count(pinfo->layers);
3103
73.1k
  *heur_dtbl_entry = NULL;
3104
3105
73.1k
  DISSECTOR_ASSERT(saved_layers_len < prefs.gui_max_tree_depth);
3106
3107
726k
  for (entry = sub_dissectors->dissectors; entry != NULL;
3108
663k
      entry = g_slist_next(entry)) {
3109
    /* XXX - why set this now and above? */
3110
663k
    pinfo->can_desegment = saved_can_desegment-(saved_can_desegment>0);
3111
663k
    hdtbl_entry = (heur_dtbl_entry_t *)entry->data;
3112
3113
663k
    if (hdtbl_entry->protocol != NULL &&
3114
663k
      (!proto_is_protocol_enabled(hdtbl_entry->protocol)||(hdtbl_entry->enabled==false))) {
3115
      /*
3116
       * No - don't try this dissector.
3117
       */
3118
146k
      continue;
3119
146k
    }
3120
3121
517k
    if (hdtbl_entry->protocol != NULL) {
3122
517k
      proto_id = proto_get_id(hdtbl_entry->protocol);
3123
      /* do NOT change this behavior - wslua uses the protocol short name set here in order
3124
         to determine which Lua-based heuristic dissector to call */
3125
517k
      pinfo->current_proto =
3126
517k
        proto_get_protocol_short_name(hdtbl_entry->protocol);
3127
3128
      /*
3129
       * Add the protocol name to the layers; we'll remove it
3130
       * if the dissector fails.
3131
       */
3132
517k
      add_layer(pinfo, proto_id);
3133
517k
    }
3134
3135
517k
    pinfo->heur_list_name = hdtbl_entry->list_name;
3136
3137
517k
    saved_desegment_len = pinfo->desegment_len;
3138
517k
    len = (hdtbl_entry->dissector)(tvb, pinfo, tree, data);
3139
517k
    consumed_none = len == 0 || (pinfo->desegment_len != saved_desegment_len && pinfo->desegment_offset == 0);
3140
517k
    if (hdtbl_entry->protocol != NULL &&
3141
505k
      (consumed_none || (tree && saved_tree_count == tree->tree_data->count))) {
3142
      /*
3143
       * We added a protocol layer above. The dissector
3144
       * didn't consume any data or it didn't add any
3145
       * items to the tree so remove it from the list.
3146
       */
3147
991k
      while (wmem_list_count(pinfo->layers) > saved_layers_len) {
3148
        /*
3149
         * Only reduce the layer number if the dissector
3150
         * didn't consume data. Since tree can be NULL on
3151
         * the first pass, we cannot check it or it will
3152
         * break dissectors that rely on a stable value.
3153
         */
3154
495k
        remove_last_layer(pinfo, consumed_none);
3155
495k
      }
3156
495k
    }
3157
517k
    if (len) {
3158
10.1k
      if (ws_log_msg_is_active(WS_LOG_DOMAIN, LOG_LEVEL_DEBUG)) {
3159
0
        ws_debug("Frame: %d | Layers: %s | Dissector: %s\n", pinfo->num, proto_list_layers(pinfo), hdtbl_entry->short_name);
3160
0
      }
3161
3162
10.1k
      *heur_dtbl_entry = hdtbl_entry;
3163
3164
      /* Bubble the matched entry to the top for faster search next time. */
3165
10.1k
      if (prev_entry != NULL) {
3166
4.77k
        sub_dissectors->dissectors = g_slist_remove_link(sub_dissectors->dissectors, entry);
3167
4.77k
        sub_dissectors->dissectors = g_slist_concat(entry, sub_dissectors->dissectors);
3168
4.77k
      }
3169
10.1k
      status = true;
3170
10.1k
      break;
3171
10.1k
    }
3172
507k
    prev_entry = entry;
3173
507k
  }
3174
3175
73.1k
  pinfo->current_proto = saved_curr_proto;
3176
73.1k
  pinfo->curr_proto_layer_num = saved_proto_layer_num;
3177
73.1k
  pinfo->heur_list_name = saved_heur_list_name;
3178
73.1k
  pinfo->can_desegment = saved_can_desegment;
3179
73.1k
  return status;
3180
73.1k
}
3181
3182
typedef struct heur_dissector_foreach_info {
3183
  void *        caller_data;
3184
  DATFunc_heur  caller_func;
3185
  GHFunc        next_func;
3186
  const char   *table_name;
3187
} heur_dissector_foreach_info_t;
3188
3189
/*
3190
 * Called for each entry in a heuristic dissector table.
3191
 */
3192
static void
3193
heur_dissector_table_foreach_func (void *data, void *user_data)
3194
0
{
3195
0
  heur_dissector_foreach_info_t *info;
3196
3197
0
  ws_assert(data);
3198
0
  ws_assert(user_data);
3199
3200
0
  info = (heur_dissector_foreach_info_t *)user_data;
3201
0
  info->caller_func(info->table_name, (heur_dtbl_entry_t *)data,
3202
0
        info->caller_data);
3203
0
}
3204
3205
/*
3206
 * Walk one heuristic dissector table's list calling a user supplied function
3207
 * on each entry.
3208
 */
3209
void
3210
heur_dissector_table_foreach (const char  *table_name,
3211
            DATFunc_heur func,
3212
            void *       user_data)
3213
0
{
3214
0
  heur_dissector_foreach_info_t info;
3215
0
  heur_dissector_list_t         sub_dissectors = find_heur_dissector_list(table_name);
3216
0
  DISSECTOR_ASSERT(sub_dissectors != NULL);
3217
3218
0
  info.table_name    = table_name;
3219
0
  info.caller_func   = func;
3220
0
  info.caller_data   = user_data;
3221
0
  g_slist_foreach(sub_dissectors->dissectors,
3222
0
      heur_dissector_table_foreach_func, &info);
3223
0
}
3224
3225
/*
3226
 * Called for each entry in the table of all heuristic dissector tables.
3227
 */
3228
typedef struct heur_dissector_foreach_table_info {
3229
  void *             caller_data;
3230
  DATFunc_heur_table caller_func;
3231
} heur_dissector_foreach_table_info_t;
3232
3233
/*
3234
 * Called for each entry in the table of all heuristic dissector tables.
3235
 * This is used if we directly process the hash table.
3236
 */
3237
static void
3238
dissector_all_heur_tables_foreach_table_func (void *key, void *value, void *user_data)
3239
0
{
3240
0
  heur_dissector_foreach_table_info_t *info;
3241
3242
0
  info = (heur_dissector_foreach_table_info_t *)user_data;
3243
0
  (*info->caller_func)((char *)key, (struct heur_dissector_list *)value, info->caller_data);
3244
0
}
3245
3246
/*
3247
 * Called for each key in the table of all dissector tables.
3248
 * This is used if we get a list of table names, sort it, and process the list.
3249
 */
3250
static void
3251
dissector_all_heur_tables_foreach_list_func (void *key, void *user_data)
3252
0
{
3253
0
  struct heur_dissector_list          *list;
3254
0
  heur_dissector_foreach_table_info_t *info;
3255
3256
0
  list = (struct heur_dissector_list *)g_hash_table_lookup(heur_dissector_lists, key);
3257
0
  info = (heur_dissector_foreach_table_info_t *)user_data;
3258
0
  (*info->caller_func)((char*)key, list, info->caller_data);
3259
0
}
3260
3261
/*
3262
 * Walk all heuristic dissector tables calling a user supplied function on each
3263
 * table.
3264
 */
3265
void
3266
dissector_all_heur_tables_foreach_table (DATFunc_heur_table func,
3267
           void *             user_data,
3268
           GCompareFunc       compare_key_func)
3269
0
{
3270
0
  heur_dissector_foreach_table_info_t info;
3271
0
  GList *list;
3272
3273
0
  info.caller_data = user_data;
3274
0
  info.caller_func = func;
3275
0
  if (compare_key_func != NULL)
3276
0
  {
3277
0
    list = g_hash_table_get_keys(dissector_tables);
3278
0
    list = g_list_sort(list, compare_key_func);
3279
0
    g_list_foreach(list, dissector_all_heur_tables_foreach_list_func, &info);
3280
0
    g_list_free(list);
3281
0
  }
3282
0
  else
3283
0
  {
3284
0
    g_hash_table_foreach(heur_dissector_lists, dissector_all_heur_tables_foreach_table_func, &info);
3285
0
  }
3286
0
}
3287
3288
static void
3289
display_heur_dissector_table_entries(const char *table_name,
3290
    heur_dtbl_entry_t *hdtbl_entry, void *user_data _U_)
3291
0
{
3292
0
  if (hdtbl_entry->protocol != NULL) {
3293
0
    printf("%s\t%s\t%c\t%c\t%s\t%s\n",
3294
0
           table_name,
3295
0
           proto_get_protocol_filter_name(proto_get_id(hdtbl_entry->protocol)),
3296
0
           (proto_is_protocol_enabled(hdtbl_entry->protocol) && hdtbl_entry->enabled) ? 'T' : 'F',
3297
0
           (proto_is_protocol_enabled_by_default(hdtbl_entry->protocol) && hdtbl_entry->enabled_by_default) ? 'T' : 'F',
3298
0
           hdtbl_entry->short_name,
3299
0
           hdtbl_entry->display_name);
3300
0
  }
3301
0
}
3302
3303
static void
3304
dissector_dump_heur_decodes_display(const char *table_name, struct heur_dissector_list *listptr _U_, void *user_data _U_)
3305
0
{
3306
0
  heur_dissector_table_foreach(table_name, display_heur_dissector_table_entries, NULL);
3307
0
}
3308
3309
/*
3310
 * For each heuristic dissector table, dump list of dissectors (filter_names) for that table
3311
 */
3312
void
3313
dissector_dump_heur_decodes(void)
3314
0
{
3315
0
  dissector_all_heur_tables_foreach_table(dissector_dump_heur_decodes_display, NULL, NULL);
3316
0
}
3317
3318
3319
heur_dissector_list_t
3320
register_heur_dissector_list_with_description(const char *name, const char *ui_name, const int proto)
3321
1.30k
{
3322
1.30k
  heur_dissector_list_t sub_dissectors;
3323
3324
  /* Create and register the dissector table for this name; returns */
3325
  /* a pointer to the dissector table. */
3326
1.30k
  sub_dissectors = g_slice_new(struct heur_dissector_list);
3327
1.30k
  sub_dissectors->protocol  = (proto == -1) ? NULL : find_protocol_by_id(proto);
3328
1.30k
  sub_dissectors->ui_name = ui_name;
3329
1.30k
  sub_dissectors->dissectors = NULL; /* initially empty */
3330
  /* Make sure the registration is unique */
3331
1.30k
  if (!g_hash_table_insert(heur_dissector_lists, (void *)name,
3332
1.30k
          (void *) sub_dissectors)) {
3333
0
    ws_error("The heuristic dissector list %s is already registered - are you using a buggy plugin?", name);
3334
0
  }
3335
1.30k
  return sub_dissectors;
3336
1.30k
}
3337
3338
heur_dissector_list_t
3339
register_heur_dissector_list(const char *name, const int proto)
3340
28
{
3341
28
  return register_heur_dissector_list_with_description(name, NULL, proto);
3342
28
}
3343
3344
void
3345
deregister_heur_dissector_list(const char *name)
3346
0
{
3347
0
  heur_dissector_list_t sub_dissectors = find_heur_dissector_list(name);
3348
0
  if (sub_dissectors == NULL) {
3349
0
    return;
3350
0
  }
3351
3352
0
  g_hash_table_remove(heur_dissector_lists, name);
3353
0
}
3354
3355
const char *
3356
heur_dissector_list_get_description(heur_dissector_list_t list)
3357
0
{
3358
0
  return list ? list->ui_name : NULL;
3359
0
}
3360
3361
/*
3362
 * Register dissectors by name; used if one dissector always calls a
3363
 * particular dissector, or if it bases the decision of which dissector
3364
 * to call on something other than a numerical value or on "try a bunch
3365
 * of dissectors until one likes the packet".
3366
 */
3367
3368
/* Get the long name of the protocol for a dissector handle, if it has
3369
   a protocol. */
3370
const char *
3371
dissector_handle_get_protocol_long_name(const dissector_handle_t handle)
3372
13
{
3373
13
  if (handle == NULL || handle->protocol == NULL) {
3374
0
    return NULL;
3375
0
  }
3376
13
  return proto_get_protocol_long_name(handle->protocol);
3377
13
}
3378
3379
/* Get the short name of the protocol for a dissector handle, if it has
3380
   a protocol. */
3381
const char *
3382
dissector_handle_get_protocol_short_name(const dissector_handle_t handle)
3383
34.0k
{
3384
34.0k
  if (handle == NULL || handle->protocol == NULL) {
3385
14
    return NULL;
3386
14
  }
3387
33.9k
  return proto_get_protocol_short_name(handle->protocol);
3388
34.0k
}
3389
3390
/* For backwards source and binary compatibility */
3391
const char *
3392
dissector_handle_get_short_name(const dissector_handle_t handle)
3393
0
{
3394
0
  return dissector_handle_get_protocol_short_name(handle);
3395
0
}
3396
3397
/* Get the description for what the dissector in the dissector handle
3398
   dissects, if it has one. */
3399
const char *
3400
dissector_handle_get_description(const dissector_handle_t handle)
3401
31.5k
{
3402
31.5k
  if (handle == NULL) {
3403
15.3k
    return NULL;
3404
15.3k
  }
3405
16.1k
  return handle->description;
3406
31.5k
}
3407
3408
/* Get the index of the protocol for a dissector handle, if it has
3409
   a protocol. */
3410
int
3411
dissector_handle_get_protocol_index(const dissector_handle_t handle)
3412
3.59k
{
3413
3.59k
  if (handle->protocol == NULL) {
3414
    /*
3415
     * No protocol (see, for example, the handle for
3416
     * dissecting the set of protocols where the first
3417
     * octet of the payload is an OSI network layer protocol
3418
     * ID).
3419
     */
3420
4
    return -1;
3421
4
  }
3422
3.58k
  return proto_get_id(handle->protocol);
3423
3.59k
}
3424
3425
/* Get a GList of all registered dissector names. The content of the list
3426
   is owned by the hash table and should not be modified or freed.
3427
   Use g_list_free() when done using the list. */
3428
GList*
3429
get_dissector_names(void)
3430
0
{
3431
0
  if (!registered_dissectors) {
3432
0
    return NULL;
3433
0
  }
3434
3435
0
  return g_hash_table_get_keys(registered_dissectors);
3436
0
}
3437
3438
/* Find a registered dissector by name. */
3439
dissector_handle_t
3440
find_dissector(const char *name)
3441
9.09k
{
3442
9.09k
  return (dissector_handle_t)g_hash_table_lookup(registered_dissectors, name);
3443
9.09k
}
3444
3445
/** Find a dissector by name and add parent protocol as a dependency*/
3446
dissector_handle_t find_dissector_add_dependency(const char *name, const int parent_proto)
3447
14.0k
{
3448
14.0k
  dissector_handle_t handle = (dissector_handle_t)g_hash_table_lookup(registered_dissectors, name);
3449
14.0k
  if ((handle != NULL) && (parent_proto > 0))
3450
13.8k
  {
3451
13.8k
    register_depend_dissector(proto_get_protocol_short_name(find_protocol_by_id(parent_proto)), dissector_handle_get_protocol_short_name(handle));
3452
13.8k
  }
3453
3454
14.0k
  return handle;
3455
14.0k
}
3456
3457
/* Get a dissector name from handle. */
3458
const char *
3459
dissector_handle_get_dissector_name(const dissector_handle_t handle)
3460
42.6k
{
3461
42.6k
  if (handle == NULL) {
3462
11
    return NULL;
3463
11
  }
3464
42.6k
  return handle->name;
3465
42.6k
}
3466
3467
const char *
3468
dissector_handle_get_pref_suffix(const dissector_handle_t handle)
3469
10.0k
{
3470
10.0k
  if (handle == NULL) {
3471
0
    return "";
3472
0
  }
3473
10.0k
  return handle->pref_suffix ? handle->pref_suffix : "";
3474
10.0k
}
3475
3476
static void
3477
check_valid_dissector_name_or_fail(const char *name)
3478
40.4k
{
3479
40.4k
  if (proto_check_field_name(name)) {
3480
0
    ws_error("Dissector name \"%s\" has one or more invalid characters."
3481
0
      " Allowed are letters, digits, '-', '_' and non-repeating '.'."
3482
0
      " This might be caused by an inappropriate plugin or a development error.", name);
3483
0
  }
3484
40.4k
}
3485
3486
static dissector_handle_t
3487
new_dissector_handle(const int proto, const char *name, const char *description)
3488
196k
{
3489
196k
  struct dissector_handle *handle;
3490
3491
  /* Make sure name is "parsing friendly" - descriptions should be
3492
   * used for complicated phrases. NULL for anonymous unregistered
3493
   * dissectors is allowed; we check for that in various places.
3494
   *
3495
   * (It might be safer to have a default name used for anonymous
3496
   * dissectors rather than NULL checks scattered in the code.)
3497
   */
3498
196k
  if (name) {
3499
40.4k
    check_valid_dissector_name_or_fail(name);
3500
40.4k
  }
3501
3502
196k
  handle      = wmem_new(wmem_epan_scope(), struct dissector_handle);
3503
196k
  handle->name    = name;
3504
196k
  handle->description = description;
3505
196k
  handle->protocol  = find_protocol_by_id(proto);
3506
196k
  handle->pref_suffix     = NULL;
3507
3508
196k
  if (handle->description == NULL) {
3509
    /*
3510
     * No description for what this dissector dissects
3511
     * was supplied; use the short name for the protocol,
3512
     * if we have the protocol.
3513
     *
3514
     * (We may have no protocol; see, for example, the handle
3515
     * for dissecting the set of protocols where the first
3516
     * octet of the payload is an OSI network layer protocol
3517
     * ID.)
3518
     */
3519
173k
    if (handle->protocol != NULL)
3520
168k
      handle->description = proto_get_protocol_short_name(handle->protocol);
3521
173k
  } else {
3522
23.2k
    if (name && g_strcmp0(name, proto_get_protocol_filter_name(proto)) != 0) {
3523
560
      handle->pref_suffix = ascii_strdown_inplace(wmem_strdup_printf(wmem_epan_scope(), ".%s", name));
3524
560
      char *pos = handle->pref_suffix;
3525
574
      while ((pos = strchr(pos, '-')) != NULL) {
3526
14
        *pos++ = '_';
3527
14
      }
3528
560
    }
3529
23.2k
  }
3530
196k
  return handle;
3531
196k
}
3532
3533
dissector_handle_t
3534
create_dissector_handle_with_name_and_description(dissector_t dissector,
3535
            const int proto,
3536
            const char* name,
3537
            const char* description)
3538
185k
{
3539
185k
  dissector_handle_t handle;
3540
3541
185k
  handle = new_dissector_handle(proto, name, description);
3542
185k
  handle->dissector_type = DISSECTOR_TYPE_SIMPLE;
3543
185k
  handle->dissector_func.dissector_type_simple = dissector;
3544
185k
  handle->dissector_data = NULL;
3545
185k
  return handle;
3546
185k
}
3547
3548
dissector_handle_t
3549
create_dissector_handle_with_name(dissector_t dissector,
3550
        const int proto, const char* name)
3551
30.8k
{
3552
30.8k
  return create_dissector_handle_with_name_and_description(dissector, proto, name, NULL);
3553
30.8k
}
3554
3555
/* Create an anonymous handle for a new dissector. */
3556
dissector_handle_t
3557
create_dissector_handle(dissector_t dissector, const int proto)
3558
131k
{
3559
131k
  return create_dissector_handle_with_name_and_description(dissector, proto, NULL, NULL);
3560
131k
}
3561
3562
static dissector_handle_t
3563
create_dissector_handle_with_name_and_data(dissector_cb_t dissector, const int proto, const char *name, void* cb_data)
3564
11.0k
{
3565
11.0k
  dissector_handle_t handle;
3566
3567
11.0k
  handle = new_dissector_handle(proto, name, NULL);
3568
11.0k
  handle->dissector_type = DISSECTOR_TYPE_CALLBACK;
3569
11.0k
  handle->dissector_func.dissector_type_callback = dissector;
3570
11.0k
  handle->dissector_data = cb_data;
3571
11.0k
  return handle;
3572
11.0k
}
3573
3574
dissector_handle_t
3575
create_dissector_handle_with_data(dissector_cb_t dissector, const int proto, void* cb_data)
3576
2.18k
{
3577
2.18k
  return create_dissector_handle_with_name_and_data(dissector, proto, NULL, cb_data);
3578
2.18k
}
3579
3580
/* Destroy an anonymous handle for a dissector. */
3581
static void
3582
destroy_dissector_handle(dissector_handle_t handle)
3583
0
{
3584
0
  if (handle == NULL) return;
3585
3586
0
  dissector_delete_from_all_tables(handle);
3587
0
  deregister_postdissector(handle);
3588
0
  if (handle->pref_suffix) {
3589
0
    wmem_free(wmem_epan_scope(), handle->pref_suffix);
3590
0
  }
3591
0
  wmem_free(wmem_epan_scope(), handle);
3592
0
}
3593
3594
static dissector_handle_t
3595
register_dissector_handle(const char *name, dissector_handle_t handle)
3596
40.3k
{
3597
40.3k
  bool new_entry;
3598
3599
  /* A registered dissector should have a name. */
3600
40.3k
  if (name == NULL || name[0] == '\0') {
3601
0
    ws_error("A registered dissector name cannot be NULL or the empty string."
3602
0
      " Anonymous dissector handles can be created with create_dissector_handle()."
3603
0
      " This might be caused by an inappropriate plugin or a development error.");
3604
0
  }
3605
3606
40.3k
  new_entry = g_hash_table_insert(registered_dissectors, (void *)name, handle);
3607
40.3k
  if (!new_entry) {
3608
    /* Make sure the registration is unique */
3609
0
    ws_error("dissector handle name \"%s\" is already registered", name);
3610
0
  }
3611
3612
40.3k
  return handle;
3613
40.3k
}
3614
3615
/* Register a new dissector by name. */
3616
dissector_handle_t
3617
register_dissector(const char *name, dissector_t dissector, const int proto)
3618
30.8k
{
3619
30.8k
  dissector_handle_t handle;
3620
3621
30.8k
  handle = create_dissector_handle_with_name(dissector, proto, name);
3622
3623
30.8k
  return register_dissector_handle(name, handle);
3624
30.8k
}
3625
3626
dissector_handle_t
3627
register_dissector_with_description(const char *name, const char *description, dissector_t dissector, const int proto)
3628
672
{
3629
672
  dissector_handle_t handle;
3630
3631
672
  handle = create_dissector_handle_with_name_and_description(dissector, proto, name, description);
3632
3633
672
  return register_dissector_handle(name, handle);
3634
672
}
3635
3636
dissector_handle_t
3637
register_dissector_with_data(const char *name, dissector_cb_t dissector, const int proto, void *cb_data)
3638
8.89k
{
3639
8.89k
  dissector_handle_t handle;
3640
3641
8.89k
  handle = create_dissector_handle_with_name_and_data(dissector, proto, name, cb_data);
3642
3643
8.89k
  return register_dissector_handle(name, handle);
3644
8.89k
}
3645
3646
static bool
3647
remove_depend_dissector_from_list(depend_dissector_list_t sub_dissectors, const char *dependent)
3648
0
{
3649
0
  return g_hash_table_remove(sub_dissectors->dissectors, dependent);
3650
0
}
3651
3652
static void
3653
remove_depend_dissector_ghfunc(void *key _U_, void *value, void *user_data)
3654
0
{
3655
0
  depend_dissector_list_t sub_dissectors = (depend_dissector_list_t) value;
3656
0
  const char *dependent = (const char *)user_data;
3657
3658
0
  remove_depend_dissector_from_list(sub_dissectors, dependent);
3659
0
}
3660
3661
/* Deregister a dissector by name. */
3662
void
3663
deregister_dissector(const char *name)
3664
0
{
3665
0
  dissector_handle_t handle = find_dissector(name);
3666
0
  if (handle == NULL) return;
3667
3668
0
  g_hash_table_remove(registered_dissectors, name);
3669
0
  g_hash_table_remove(depend_dissector_lists, name);
3670
0
  g_hash_table_foreach(depend_dissector_lists, remove_depend_dissector_ghfunc, (void *)name);
3671
3672
0
  destroy_dissector_handle(handle);
3673
0
}
3674
3675
/* Call a dissector through a handle but if the dissector rejected it
3676
 * return 0.
3677
 */
3678
int
3679
call_dissector_only(dissector_handle_t handle, tvbuff_t *tvb,
3680
        packet_info *pinfo, proto_tree *tree, void *data)
3681
1.33M
{
3682
1.33M
  int ret;
3683
3684
1.33M
  DISSECTOR_ASSERT(handle != NULL);
3685
1.33M
  ret = call_dissector_work(handle, tvb, pinfo, tree, true, data);
3686
1.33M
  return ret;
3687
1.33M
}
3688
3689
/* Call a dissector through a handle and if this fails call the "data"
3690
 * dissector.
3691
 */
3692
int
3693
call_dissector_with_data(dissector_handle_t handle, tvbuff_t *tvb,
3694
                   packet_info *pinfo, proto_tree *tree, void *data)
3695
556k
{
3696
556k
  int ret;
3697
3698
556k
  ret = call_dissector_only(handle, tvb, pinfo, tree, data);
3699
556k
  if (ret == 0) {
3700
    /*
3701
     * The protocol was disabled, or the dissector rejected
3702
     * it.  Just dissect this packet as data.
3703
     */
3704
9.82k
    return call_data_dissector(tvb, pinfo, tree);
3705
9.82k
  }
3706
546k
  return ret;
3707
556k
}
3708
3709
int
3710
call_dissector(dissector_handle_t handle, tvbuff_t *tvb,
3711
         packet_info *pinfo, proto_tree *tree)
3712
293k
{
3713
293k
  return call_dissector_with_data(handle, tvb, pinfo, tree, NULL);
3714
293k
}
3715
3716
int
3717
call_data_dissector(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3718
273k
{
3719
273k
  DISSECTOR_ASSERT(data_handle->protocol != NULL);
3720
273k
  return call_dissector_work(data_handle, tvb, pinfo, tree, true, NULL);
3721
273k
}
3722
3723
/*
3724
 * Call a heuristic dissector through a heur_dtbl_entry
3725
 */
3726
void call_heur_dissector_direct(heur_dtbl_entry_t *heur_dtbl_entry, tvbuff_t *tvb,
3727
  packet_info *pinfo, proto_tree *tree, void *data)
3728
2
{
3729
2
  const char        *saved_curr_proto;
3730
2
  unsigned           saved_proto_layer_num;
3731
2
  const char        *saved_heur_list_name;
3732
2
  uint16_t           saved_can_desegment;
3733
2
  unsigned           saved_layers_len = 0;
3734
3735
2
  DISSECTOR_ASSERT(heur_dtbl_entry);
3736
3737
  /* can_desegment is set to 2 by anyone which offers this api/service.
3738
     then every time a subdissector is called it is decremented by one.
3739
     thus only the subdissector immediately on top of whoever offers this
3740
     service can use it.
3741
     We save the current value of "can_desegment" for the
3742
     benefit of TCP proxying dissectors such as SOCKS, so they
3743
     can restore it and allow the dissectors they call to use
3744
     the desegmentation service.
3745
  */
3746
2
  saved_can_desegment        = pinfo->can_desegment;
3747
2
  pinfo->saved_can_desegment = saved_can_desegment;
3748
2
  pinfo->can_desegment       = saved_can_desegment-(saved_can_desegment>0);
3749
3750
2
  saved_curr_proto = pinfo->current_proto;
3751
2
  saved_proto_layer_num = pinfo->curr_proto_layer_num;
3752
2
  saved_heur_list_name = pinfo->heur_list_name;
3753
3754
2
  saved_layers_len = wmem_list_count(pinfo->layers);
3755
3756
2
  if (!heur_dtbl_entry->enabled ||
3757
2
    (heur_dtbl_entry->protocol != NULL && !proto_is_protocol_enabled(heur_dtbl_entry->protocol))) {
3758
0
    DISSECTOR_ASSERT(data_handle->protocol != NULL);
3759
0
    call_dissector_work(data_handle, tvb, pinfo, tree, true, NULL);
3760
0
    return;
3761
0
  }
3762
3763
2
  if (heur_dtbl_entry->protocol != NULL) {
3764
    /* do NOT change this behavior - wslua uses the protocol short name set here in order
3765
      to determine which Lua-based heuristic dissector to call */
3766
2
    pinfo->current_proto = proto_get_protocol_short_name(heur_dtbl_entry->protocol);
3767
2
    add_layer(pinfo, proto_get_id(heur_dtbl_entry->protocol));
3768
2
  }
3769
3770
2
  pinfo->heur_list_name = heur_dtbl_entry->list_name;
3771
3772
  /* call the dissector, in case of failure call data handle (might happen with exported PDUs) */
3773
2
  if (!(*heur_dtbl_entry->dissector)(tvb, pinfo, tree, data)) {
3774
    /*
3775
     * We added a protocol layer above. The dissector
3776
     * didn't accept the packet or it didn't add any
3777
     * items to the tree so remove it from the list.
3778
     */
3779
2
    while (wmem_list_count(pinfo->layers) > saved_layers_len) {
3780
1
      remove_last_layer(pinfo, true);
3781
1
    }
3782
3783
1
    call_dissector_work(data_handle, tvb, pinfo, tree, true, NULL);
3784
1
  }
3785
3786
  /* XXX: Remove layers if it was accepted but didn't actually consume
3787
   * data due to desegmentation? (Currently the only callers of this
3788
   * are UDP and exported PDUs, so not yet necessary.)
3789
   */
3790
3791
  /* Restore info from caller */
3792
2
  pinfo->can_desegment = saved_can_desegment;
3793
2
  pinfo->current_proto = saved_curr_proto;
3794
2
  pinfo->curr_proto_layer_num = saved_proto_layer_num;
3795
2
  pinfo->heur_list_name = saved_heur_list_name;
3796
3797
2
}
3798
3799
bool register_depend_dissector(const char* parent, const char* dependent)
3800
51.8k
{
3801
51.8k
  depend_dissector_list_t sub_dissectors;
3802
3803
51.8k
  if ((parent == NULL) || (dependent == NULL))
3804
14
  {
3805
    /* XXX - assert on parent? */
3806
14
    return false;
3807
14
  }
3808
3809
51.8k
  sub_dissectors = find_depend_dissector_list(parent);
3810
51.8k
  if (sub_dissectors == NULL) {
3811
    /* parent protocol doesn't exist, create it */
3812
7.08k
    sub_dissectors = g_slice_new(struct depend_dissector_list);
3813
7.08k
    sub_dissectors->dissectors = g_hash_table_new(g_str_hash, g_str_equal); /* initially empty */
3814
7.08k
    g_hash_table_insert(depend_dissector_lists, (void *)g_strdup(parent), (void *) sub_dissectors);
3815
7.08k
  }
3816
3817
  /* Verify that sub-dissector is not already in the list */
3818
51.8k
  g_hash_table_add(sub_dissectors->dissectors, (void *)dependent);
3819
51.8k
  return true;
3820
51.8k
}
3821
3822
bool deregister_depend_dissector(const char* parent, const char* dependent)
3823
0
{
3824
0
  depend_dissector_list_t  sub_dissectors = find_depend_dissector_list(parent);
3825
3826
  /* sanity check */
3827
0
  ws_assert(sub_dissectors != NULL);
3828
3829
0
  return remove_depend_dissector_from_list(sub_dissectors, dependent);
3830
0
}
3831
3832
depend_dissector_list_t find_depend_dissector_list(const char* name)
3833
51.8k
{
3834
51.8k
  return (depend_dissector_list_t)g_hash_table_lookup(depend_dissector_lists, name);
3835
51.8k
}
3836
3837
/*
3838
 * Dumps the "layer type"/"decode as" associations to stdout, similar
3839
 * to the proto_registrar_dump_*() routines.
3840
 *
3841
 * There is one record per line. The fields are tab-delimited.
3842
 *
3843
 * Field 1 = layer type, e.g. "tcp.port"
3844
 * Field 2 = selector - decimal for integer tables, strings for string tables,
3845
 *           blank for payload tables. Custom and GUID tables aren't shown.
3846
 * Field 3 = "decode as" name, e.g. "http"
3847
 *
3848
 * XXX - View -> Internals -> Dissector Tables in the GUI includes the UI name,
3849
 * and separates tables by category. We could add fields for the the UI name
3850
 * and category.
3851
 *
3852
 * The GUI doesn't display FT_NONE (it should) nor FT_GUID tables, but does
3853
 * FT_BYTES (Custom) tables with the handle description name as key.
3854
 * That may or may not be helpful.
3855
 */
3856
3857
3858
static void
3859
dissector_dump_decodes_display(const char *table_name,
3860
             ftenum_t selector_type _U_, void *key, void *value)
3861
0
{
3862
0
  dissector_table_t   sub_dissectors = find_dissector_table(table_name);
3863
0
  dtbl_entry_t       *dtbl_entry;
3864
0
  dissector_handle_t  handle;
3865
0
  int                 proto_id;
3866
0
  const char         *decode_as;
3867
0
  char                fstring[32];
3868
0
  int                 field_width = 0;
3869
3870
0
  ws_assert(sub_dissectors);
3871
3872
0
  dtbl_entry = (dtbl_entry_t *)value;
3873
0
  ws_assert(dtbl_entry);
3874
3875
0
  handle   = dtbl_entry->current;
3876
  /* current might be NULL, if there was an initial value but then
3877
   * set to no handle via Decode As. */
3878
0
  if (!handle)
3879
0
    return;
3880
3881
0
  proto_id = dissector_handle_get_protocol_index(handle);
3882
3883
0
  if (proto_id != -1) {
3884
0
    decode_as = proto_get_protocol_filter_name(proto_id);
3885
0
    ws_assert(decode_as != NULL);
3886
0
    switch (sub_dissectors->type) {
3887
0
      case FT_UINT32:
3888
0
        field_width += 2;
3889
        // fallthrough
3890
0
      case FT_UINT24:
3891
0
        field_width += 2;
3892
        // fallthrough
3893
0
      case FT_UINT16:
3894
0
        field_width += 2;
3895
        // fallthrough
3896
0
      case FT_UINT8:
3897
0
        field_width += 2;
3898
0
        switch (sub_dissectors->param)
3899
0
        {
3900
0
          case BASE_OCT:
3901
0
            snprintf(fstring, 32, "%%s\t0%%o\t%%s\n");
3902
0
            break;
3903
3904
0
          case BASE_HEX:
3905
0
            snprintf(fstring, 32, "%%s\t0x%%0%ux\t%%s\n", field_width);
3906
0
            break;
3907
3908
0
          case BASE_DEC:
3909
0
          default:
3910
0
            snprintf(fstring, 32, "%%s\t%%u\t%%s\n");
3911
0
            break;
3912
0
        };
3913
3914
0
        printf(fstring, table_name, GPOINTER_TO_UINT(key), decode_as);
3915
0
        break;
3916
3917
0
      case FT_STRING:
3918
0
        printf("%s\t%s\t%s\n", table_name, (char*)key, decode_as);
3919
0
        break;
3920
3921
0
      case FT_NONE:
3922
0
        printf("%s\t\t%s\n", table_name, decode_as);
3923
0
        break;
3924
3925
0
      case FT_GUID:
3926
        // We could output something here with the guid_key
3927
0
        break;
3928
3929
0
      case FT_BYTES:
3930
        // View->Internals->Dissector Tables uses the description,
3931
        // but that doesn't tell anything about how the table is
3932
        // configured. (This isn't a list of all possible handles.)
3933
        // Is it useful to output?
3934
0
        break;
3935
3936
0
      default:
3937
0
        break;
3938
0
    }
3939
0
  }
3940
0
}
3941
3942
static int compare_ints(const void *a, const void *b)
3943
0
{
3944
0
  uint32_t inta, intb;
3945
3946
0
  inta = GPOINTER_TO_UINT(a);
3947
0
  intb = GPOINTER_TO_UINT(b);
3948
3949
0
  if (inta < intb)
3950
0
    return -1;
3951
0
  if (inta > intb)
3952
0
    return 1;
3953
0
  return 0;
3954
0
}
3955
3956
static void
3957
dissector_dump_table_decodes(const char *table_name, const char *ui_name _U_, void *user_data _U_)
3958
0
{
3959
0
  dissector_table_t   sub_dissectors = find_dissector_table(table_name);
3960
0
  GList *keys;
3961
3962
0
  ws_assert(sub_dissectors);
3963
0
  keys = g_hash_table_get_keys(sub_dissectors->hash_table);
3964
3965
0
  switch (sub_dissectors->type) {
3966
0
    case FT_UINT8:
3967
0
    case FT_UINT16:
3968
0
    case FT_UINT24:
3969
0
    case FT_UINT32:
3970
0
      keys = g_list_sort(keys, compare_ints);
3971
0
      break;
3972
3973
0
    case FT_STRING:
3974
0
    case FT_STRINGZ:
3975
0
    case FT_UINT_STRING:
3976
0
    case FT_STRINGZPAD:
3977
0
    case FT_STRINGZTRUNC:
3978
0
      keys = g_list_sort(keys, (GCompareFunc)strcmp);
3979
0
      break;
3980
3981
    /* FT_NONE we don't need to sort. We could do something for
3982
     * FT_GUID and FT_BYTES (Custom) if we were to output them,
3983
     * possibly with g_list_sort_with_data.
3984
     */
3985
0
    default:
3986
0
      break;
3987
0
  }
3988
3989
0
  for (GList *entry = g_list_first(keys); entry; entry = entry->next) {
3990
0
    void *key = entry->data;
3991
0
    void *value = g_hash_table_lookup(sub_dissectors->hash_table, key);
3992
0
    dissector_dump_decodes_display(table_name, sub_dissectors->type, key, value);
3993
0
  }
3994
3995
0
  g_list_free(keys);
3996
0
}
3997
3998
void
3999
dissector_dump_decodes(void)
4000
0
{
4001
0
  dissector_all_tables_foreach_table(dissector_dump_table_decodes, NULL, (GCompareFunc)strcmp);
4002
0
}
4003
4004
/*
4005
 * Dumps information about dissector tables to stdout.
4006
 *
4007
 * There is one record per line. The fields are tab-delimited.
4008
 *
4009
 * Field 1 = dissector table name, e.g. "tcp.port"
4010
 * Field 2 = name used for the dissector table in the GUI
4011
 * Field 3 = type (textual representation of the ftenum type)
4012
 * Field 4 = base for display (for integer types)
4013
 * Field 5 = protocol name
4014
 * Field 6 = "decode as" support
4015
 *
4016
 * This does not dump the *individual entries* in the dissector tables,
4017
 * i.e. it doesn't show what dissector handles what particular value
4018
 * of the key in the dissector table.
4019
 */
4020
4021
static void
4022
dissector_dump_dissector_tables_display (void *key, void *user_data _U_)
4023
0
{
4024
0
  const char    *table_name = (const char *)key;
4025
0
  dissector_table_t table;
4026
4027
0
  table = (dissector_table_t)g_hash_table_lookup(dissector_tables, key);
4028
0
  printf("%s\t%s\t%s", table_name, table->ui_name, ftype_name(table->type));
4029
0
  switch (table->type) {
4030
4031
0
  case FT_UINT8:
4032
0
  case FT_UINT16:
4033
0
  case FT_UINT24:
4034
0
  case FT_UINT32:
4035
0
    switch(table->param) {
4036
4037
0
    case BASE_NONE:
4038
0
      printf("\tBASE_NONE");
4039
0
      break;
4040
4041
0
    case BASE_DEC:
4042
0
      printf("\tBASE_DEC");
4043
0
      break;
4044
4045
0
    case BASE_HEX:
4046
0
      printf("\tBASE_HEX");
4047
0
      break;
4048
4049
0
    case BASE_OCT:
4050
0
      printf("\tBASE_OCT");
4051
0
      break;
4052
4053
0
    default:
4054
0
      printf("\t%d", table->param);
4055
0
      break;
4056
0
    }
4057
0
    break;
4058
4059
0
  default:
4060
0
    break;
4061
0
  }
4062
0
  if (table->protocol != NULL) {
4063
0
    printf("\t%s",
4064
0
        proto_get_protocol_short_name(table->protocol));
4065
0
  } else
4066
0
    printf("\t(no protocol)");
4067
0
  printf("\tDecode As %ssupported",
4068
0
      table->supports_decode_as ? "" : "not ");
4069
0
  printf("\n");
4070
0
}
4071
4072
/** The output format of this function is meant to parallel
4073
 * that of dissector_dump_dissector_tables_display().
4074
 * Field 3 is shown as "heuristic".
4075
 * Field 4 is omitted, as it is for FT_STRING dissector tables above.
4076
 * Field 6 is omitted since "Decode As" doesn't apply.
4077
 */
4078
4079
static void
4080
dissector_dump_heur_dissector_tables_display (void *key, void *user_data _U_)
4081
0
{
4082
0
  const char    *list_name = (const char *)key;
4083
0
  heur_dissector_list_t list;
4084
4085
0
  list = (heur_dissector_list_t)g_hash_table_lookup(heur_dissector_lists, key);
4086
0
  printf("%s\t%s\theuristic", list_name, list->ui_name ? list->ui_name : list_name);
4087
4088
0
  if (list->protocol != NULL) {
4089
0
    printf("\t%s",
4090
0
        proto_get_protocol_short_name(list->protocol));
4091
0
  } else
4092
0
    printf("\t(no protocol)");
4093
0
  printf("\n");
4094
0
}
4095
4096
static int
4097
compare_dissector_key_name(const void *dissector_a, const void *dissector_b)
4098
0
{
4099
0
  return strcmp((const char*)dissector_a, (const char*)dissector_b);
4100
0
}
4101
4102
void
4103
dissector_dump_dissector_tables(void)
4104
0
{
4105
0
  GList *list;
4106
4107
0
  list = g_hash_table_get_keys(dissector_tables);
4108
0
  list = g_list_sort(list, compare_dissector_key_name);
4109
0
  g_list_foreach(list, dissector_dump_dissector_tables_display, NULL);
4110
0
  g_list_free(list);
4111
4112
0
  list = g_hash_table_get_keys(heur_dissector_lists);
4113
0
  list = g_list_sort(list, compare_dissector_key_name);
4114
0
  g_list_foreach(list, dissector_dump_heur_dissector_tables_display, NULL);
4115
0
  g_list_free(list);
4116
0
}
4117
4118
/*
4119
 * Dumps the entries in the table of registered dissectors.
4120
 *
4121
 * There is one record per line. The fields are tab-delimited.
4122
 *
4123
 * Field 1 = dissector name
4124
 * Field 2 = dissector description
4125
 */
4126
4127
struct dissector_info {
4128
  const char *name;
4129
  const char *description;
4130
};
4131
4132
static int
4133
compare_dissector_info_names(const void *arg1, const void *arg2)
4134
0
{
4135
0
  const struct dissector_info *info1 = (const struct dissector_info *) arg1;
4136
0
  const struct dissector_info *info2 = (const struct dissector_info *) arg2;
4137
4138
0
  return strcmp(info1->name, info2->name);
4139
0
}
4140
4141
void
4142
dissector_dump_dissectors(void)
4143
0
{
4144
0
  GHashTableIter iter;
4145
0
  struct dissector_info *dissectors_info;
4146
0
  unsigned num_protocols;
4147
0
  void *key, *value;
4148
0
  unsigned proto_index;
4149
4150
0
  g_hash_table_iter_init(&iter, registered_dissectors);
4151
0
  num_protocols = g_hash_table_size(registered_dissectors);
4152
0
  dissectors_info = g_new(struct dissector_info, num_protocols);
4153
0
  proto_index = 0;
4154
0
  while (g_hash_table_iter_next(&iter, &key, &value)) {
4155
0
    dissectors_info[proto_index].name = (const char *)key;
4156
0
    dissectors_info[proto_index].description =
4157
0
        ((dissector_handle_t) value)->description;
4158
0
    proto_index++;
4159
0
  }
4160
0
  qsort(dissectors_info, num_protocols, sizeof(struct dissector_info),
4161
0
      compare_dissector_info_names);
4162
0
  for (proto_index = 0; proto_index < num_protocols; proto_index++) {
4163
0
    printf("%s\t%s\n", dissectors_info[proto_index].name,
4164
0
        dissectors_info[proto_index].description);
4165
0
  }
4166
0
  g_free(dissectors_info);
4167
0
}
4168
4169
void
4170
register_postdissector(dissector_handle_t handle)
4171
56
{
4172
56
  postdissector p;
4173
4174
56
  p.handle = handle;
4175
56
  p.wanted_hfids = NULL;
4176
56
  postdissectors = g_array_append_val(postdissectors, p);
4177
56
}
4178
4179
void
4180
set_postdissector_wanted_hfids(dissector_handle_t handle, GArray *wanted_hfids)
4181
0
{
4182
0
  unsigned i;
4183
4184
0
  if (!postdissectors) return;
4185
4186
0
  for (i = 0; i < postdissectors->len; i++) {
4187
0
    if (POSTDISSECTORS(i).handle == handle) {
4188
0
      if (POSTDISSECTORS(i).wanted_hfids) {
4189
0
        g_array_free(POSTDISSECTORS(i).wanted_hfids, true);
4190
0
      }
4191
0
      POSTDISSECTORS(i).wanted_hfids = wanted_hfids;
4192
0
      break;
4193
0
    }
4194
0
  }
4195
0
}
4196
4197
void
4198
deregister_postdissector(dissector_handle_t handle)
4199
0
{
4200
0
  unsigned i;
4201
4202
0
  if (!postdissectors) return;
4203
4204
0
  for (i = 0; i < postdissectors->len; i++) {
4205
0
    if (POSTDISSECTORS(i).handle == handle) {
4206
0
      if (POSTDISSECTORS(i).wanted_hfids) {
4207
0
        g_array_free(POSTDISSECTORS(i).wanted_hfids, true);
4208
0
      }
4209
0
      postdissectors = g_array_remove_index_fast(postdissectors, i);
4210
0
      break;
4211
0
    }
4212
0
  }
4213
0
}
4214
4215
bool
4216
have_postdissector(void)
4217
192k
{
4218
192k
  unsigned i;
4219
192k
  dissector_handle_t handle;
4220
4221
770k
  for (i = 0; i < postdissectors->len; i++) {
4222
770k
    handle = POSTDISSECTORS(i).handle;
4223
4224
770k
    if (handle->protocol != NULL
4225
770k
        && proto_is_protocol_enabled(handle->protocol)) {
4226
      /* We have at least one enabled postdissector */
4227
192k
      return true;
4228
192k
    }
4229
770k
  }
4230
0
  return false;
4231
192k
}
4232
4233
void
4234
call_all_postdissectors(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4235
192k
{
4236
192k
  unsigned i;
4237
4238
963k
  for (i = 0; i < postdissectors->len; i++) {
4239
770k
    call_dissector_only(POSTDISSECTORS(i).handle,
4240
770k
            tvb, pinfo, tree, NULL);
4241
770k
  }
4242
192k
}
4243
4244
bool
4245
postdissectors_want_hfids(void)
4246
0
{
4247
0
  unsigned i;
4248
4249
0
  for (i = 0; i < postdissectors->len; i++) {
4250
0
    if (POSTDISSECTORS(i).wanted_hfids != NULL &&
4251
0
        POSTDISSECTORS(i).wanted_hfids->len != 0 &&
4252
0
        (POSTDISSECTORS(i).handle->protocol == NULL ||
4253
0
         proto_is_protocol_enabled(POSTDISSECTORS(i).handle->protocol)))
4254
0
      return true;
4255
0
  }
4256
0
  return false;
4257
0
}
4258
4259
void
4260
prime_epan_dissect_with_postdissector_wanted_hfids(epan_dissect_t *edt)
4261
192k
{
4262
192k
  unsigned i;
4263
4264
192k
  if (postdissectors == NULL) {
4265
    /*
4266
     * No postdissector expressed an interest in any hfids.
4267
     */
4268
0
    return;
4269
0
  }
4270
963k
  for (i = 0; i < postdissectors->len; i++) {
4271
770k
    if (POSTDISSECTORS(i).wanted_hfids != NULL &&
4272
0
        POSTDISSECTORS(i).wanted_hfids->len != 0 &&
4273
0
        (POSTDISSECTORS(i).handle->protocol == NULL ||
4274
0
         proto_is_protocol_enabled(POSTDISSECTORS(i).handle->protocol)))
4275
0
      epan_dissect_prime_with_hfid_array(edt,
4276
0
          POSTDISSECTORS(i).wanted_hfids);
4277
770k
  }
4278
192k
}
4279
4280
void
4281
7.86M
increment_dissection_depth(packet_info *pinfo) {
4282
7.86M
  pinfo->dissection_depth++;
4283
7.86M
  DISSECTOR_ASSERT(pinfo->dissection_depth < (int)prefs.gui_max_tree_depth);
4284
7.86M
}
4285
4286
void
4287
7.83M
decrement_dissection_depth(packet_info *pinfo) {
4288
7.83M
  pinfo->dissection_depth--;
4289
7.83M
  DISSECTOR_ASSERT(pinfo->dissection_depth >= 0);
4290
7.83M
}
4291
4292
/*
4293
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
4294
 *
4295
 * Local variables:
4296
 * c-basic-offset: 8
4297
 * tab-width: 8
4298
 * indent-tabs-mode: t
4299
 * End:
4300
 *
4301
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
4302
 * :indentSize=8:tabSize=8:noTabs=false:
4303
 */