Coverage Report

Created: 2026-05-14 06:28

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