Coverage Report

Created: 2026-08-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/proto.c
Line
Count
Source
1
/* proto.c
2
 * Routines for protocol tree
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
524
#define WS_LOG_DOMAIN LOG_DOMAIN_EPAN
13
#include "wireshark.h"
14
15
#include <float.h>
16
#include <errno.h>
17
18
#include <epan/tfs.h>
19
#include <epan/unit_strings.h>
20
21
#include <wsutil/array.h>
22
#include <wsutil/bits_ctz.h>
23
#include <wsutil/bits_count_ones.h>
24
#include <wsutil/sign_ext.h>
25
#include <wsutil/utf8_entities.h>
26
#include <wsutil/json_dumper.h>
27
#include <wsutil/pint.h>
28
#include <wsutil/unicode-utils.h>
29
#include <wsutil/dtoa.h>
30
#include <wsutil/filesystem.h>
31
#ifdef HAVE_UNISTD_H
32
#include <unistd.h>
33
#endif
34
35
#include <ftypes/ftypes.h>
36
#include <ftypes/ftypes-int.h>
37
38
#include <epan/packet.h>
39
#include "exceptions.h"
40
#include "ptvcursor.h"
41
#include "strutil.h"
42
#include "addr_resolv.h"
43
#include "address_types.h"
44
#include "oids.h"
45
#include "proto.h"
46
#include "epan_dissect.h"
47
#include "dfilter/dfilter.h"
48
#include "tvbuff.h"
49
#include "charsets.h"
50
#include "column-info.h"
51
#include "to_str.h"
52
#include "osi-utils.h"
53
#include "expert.h"
54
#include "show_exception.h"
55
#include "in_cksum.h"
56
57
#include <wsutil/crash_info.h>
58
#include <wsutil/epochs.h>
59
60
/* Ptvcursor limits */
61
445
#define SUBTREE_ONCE_ALLOCATION_NUMBER 8
62
#define SUBTREE_MAX_LEVELS 256
63
64
typedef struct __subtree_lvl {
65
  unsigned    cursor_offset;
66
  proto_item *it;
67
  proto_tree *tree;
68
} subtree_lvl;
69
70
struct ptvcursor {
71
  wmem_allocator_t *scope;
72
  subtree_lvl *pushed_tree;
73
  uint8_t      pushed_tree_index;
74
  uint8_t      pushed_tree_max;
75
  proto_tree  *tree;
76
  tvbuff_t    *tvb;
77
  unsigned     offset;
78
};
79
80
#define cVALS(x) (const value_string*)(x)
81
82
/** See inlined comments.
83
 @param tree the tree to append this item to
84
 @param free_block a code block to call to free resources if this returns
85
 @return NULL if 'tree' is null */
86
#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)      \
87
147M
  if (!tree) {             \
88
6.01M
    free_block;           \
89
6.01M
    return NULL;            \
90
6.01M
  }
91
92
/** See inlined comments.
93
 @param tree the tree to append this item to
94
 @return NULL if 'tree' is null */
95
#define CHECK_FOR_NULL_TREE(tree) \
96
147M
  CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))
97
98
/** See inlined comments.
99
 @param length the length of this item
100
 @param cleanup_block a code block to call to free resources if this returns
101
 @return NULL if 'length' is equal to 0 */
102
#define CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, cleanup_block)  \
103
6.20M
  if (length == 0) {                       \
104
22.9k
    cleanup_block;           \
105
0
    return NULL;           \
106
11.4k
  }
107
108
/** See inlined comments.
109
 @param length the length of this item
110
 @return NULL if 'length' is equal to 0 */
111
#define CHECK_FOR_ZERO_LENGTH(length) \
112
  CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, ((void)0))
113
114
/** See inlined comments.
115
 @param tree the tree to append this item to
116
 @param hfindex field index
117
 @param hfinfo header_field
118
 @param free_block a code block to call to free resources if this returns
119
 @return the header field matching 'hfinfo' */
120
#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block) \
121
  /* If the tree is not visible and this item is not referenced \
122
     we don't have to do much work at all but we should still \
123
     return a node so that referenced field items below this node \
124
     (think proto_item_add_subtree()) will still have somewhere \
125
     to attach to or else filtering will not work (they would be  \
126
     ignored since tree would be NULL).       \
127
     DON'T try to fake a node where PTREE_FINFO(tree) is visible  \
128
     because that means we can change its length or repr, and we  \
129
     don't want to do so with calls intended for this faked new \
130
     item, so this item needs a new (hidden) child node.    \
131
     We fake FT_PROTOCOL unless some clients have requested us  \
132
     not to do so.            \
133
  */                \
134
141M
  PTREE_DATA(tree)->count++;          \
135
141M
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);      \
136
141M
  if (PTREE_DATA(tree)->count > prefs.gui_max_tree_items) { \
137
29
    free_block;           \
138
29
    if (wireshark_abort_on_too_many_items) \
139
29
      ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \
140
29
          hfinfo->abbrev, prefs.gui_max_tree_items);  \
141
29
    /* Let the exception handler add items to the tree */ \
142
29
    PTREE_DATA(tree)->count = 0;        \
143
29
    THROW_MESSAGE(DissectorError,        \
144
29
      wmem_strdup_printf(PNODE_POOL(tree),    \
145
29
          "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \
146
29
          hfinfo->abbrev, prefs.gui_max_tree_items)); \
147
29
  }                \
148
141M
  if (!(PTREE_DATA(tree)->visible)) {       \
149
61.8M
    if (PROTO_ITEM_IS_HIDDEN(tree)) {     \
150
61.8M
      if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT)  \
151
61.8M
          && (hfinfo->ref_type != HF_REF_TYPE_PRINT)  \
152
61.8M
          && (hfinfo->type != FT_PROTOCOL ||   \
153
61.8M
        PTREE_DATA(tree)->fake_protocols)) { \
154
61.8M
        free_block;       \
155
61.8M
        /* return fake node with no field info */\
156
61.8M
        return proto_tree_add_fake_node(tree, hfinfo);  \
157
61.8M
      }           \
158
61.8M
    }             \
159
61.8M
  }
160
161
/** See inlined comments.
162
 @param tree the tree to append this item to
163
 @param hfindex field index
164
 @param hfinfo header_field
165
 @return the header field matching 'hfinfo' */
166
#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo) \
167
141M
  TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))
168
169
170
/** See inlined comments.
171
 @param pi the created protocol item we're about to return */
172
#define TRY_TO_FAKE_THIS_REPR(pi) \
173
21.1M
  ws_assert(pi);     \
174
21.1M
  if (!PITEM_FINFO(pi))   \
175
21.1M
    return pi;   \
176
21.1M
  if (!(PTREE_DATA(pi)->visible) && \
177
20.6M
        PROTO_ITEM_IS_HIDDEN(pi)) { \
178
0
    /* If the tree (GUI) or item isn't visible it's pointless for \
179
0
     * us to generate the protocol item's string representation */ \
180
0
    return pi; \
181
0
  }
182
/* Same as above but returning void */
183
#define TRY_TO_FAKE_THIS_REPR_VOID(pi)  \
184
24.4M
  if (!pi || !PITEM_FINFO(pi)) \
185
24.4M
    return;     \
186
24.4M
  if (!(PTREE_DATA(pi)->visible) && \
187
17.0M
        PROTO_ITEM_IS_HIDDEN(pi)) { \
188
0
    /* If the tree (GUI) or item isn't visible it's pointless for \
189
0
     * us to generate the protocol item's string representation */ \
190
0
    return; \
191
0
  }
192
/* Similar to above, but allows a NULL tree */
193
#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)  \
194
254k
  if ((pi == NULL) || (PITEM_FINFO(pi) == NULL) || (!(PTREE_DATA(pi)->visible) && \
195
188k
    PROTO_ITEM_IS_HIDDEN(pi))) { \
196
63.7k
    /* If the tree (GUI) or item isn't visible it's pointless for \
197
63.7k
     * us to generate the protocol item's string representation */ \
198
63.7k
    return pi; \
199
63.7k
  }
200
201
#ifdef ENABLE_CHECK_FILTER
202
#define CHECK_HF_VALUE(type, spec, start_values) \
203
{ \
204
  const type *current; \
205
  int n, m; \
206
  current = start_values; \
207
  for (n=0; current; n++, current++) { \
208
    /* Drop out if we reached the end. */ \
209
    if ((current->value == 0) && (current->strptr == NULL)) { \
210
      break; \
211
    } \
212
    /* Check value against all previous */ \
213
    for (m=0; m < n; m++) { \
214
      /* There are lots of duplicates with the same string, \
215
         so only report if different... */ \
216
      if ((start_values[m].value == current->value) && \
217
          (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218
        ws_error("Field '%s' (%s) has a conflicting entry in its" \
219
            " value_string: %" spec " is at indices %u (%s) and %u (%s)", \
220
            hfinfo->name, hfinfo->abbrev, \
221
            current->value, m, start_values[m].strptr, n, current->strptr); \
222
      } \
223
    } \
224
  } \
225
}
226
#endif
227
228
/* The longest NUMBER-like field label we have is for BASE_OUI, which
229
 * can have up to 64 bytes for the manufacturer name if resolved plus
230
 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231
 */
232
3.05M
#define NUMBER_LABEL_LENGTH 80
233
234
static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235
static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236
static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237
static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238
static int hfinfo_bitoffset(const header_field_info *hfinfo);
239
static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240
static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242
#define label_concat(dst, pos, src) \
243
22.6M
  ws_label_strcpy(dst, ITEM_LABEL_LENGTH, pos, src, 0)
244
245
static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246
static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248
static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249
static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250
static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool is_signed);
251
static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool is_signed);
252
static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253
static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool is_signed);
254
static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool is_signed);
255
256
static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257
static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258
static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259
static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261
static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH], uint32_t value);
262
static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH], uint64_t value);
263
static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264
static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265
static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint32_t value);
266
static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint64_t value);
267
static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint32_t value);
268
static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint64_t value);
269
static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270
static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint32_t value);
271
static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint64_t value);
272
273
static void proto_cleanup_base(void);
274
275
static proto_item *
276
proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278
static proto_item *
279
proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281
static void
282
get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
283
    int *item_length, const unsigned encoding);
284
285
static void
286
get_hfi_length_unsigned(header_field_info * hfinfo, tvbuff_t * tvb, const unsigned start, unsigned* length,
287
  unsigned* item_length, const unsigned encoding);
288
289
static int
290
get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
291
    int length, unsigned item_length, const int encoding);
292
293
static field_info *
294
new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295
         const unsigned start, const int item_length);
296
297
static proto_item *
298
proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
299
      unsigned start, int *length);
300
301
static proto_item *
302
proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
303
      unsigned start, unsigned *length);
304
305
static void
306
proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
307
static void
308
proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
309
310
static void
311
proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
312
static void
313
proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
314
static void
315
proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length);
316
static void
317
proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
318
static void
319
proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
320
static void
321
proto_tree_set_string(field_info *fi, const char* value);
322
static void
323
proto_tree_set_ax25(field_info *fi, const uint8_t* value);
324
static void
325
proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
326
static void
327
proto_tree_set_vines(field_info *fi, const uint8_t* value);
328
static void
329
proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
330
static void
331
proto_tree_set_ether(field_info *fi, const uint8_t* value);
332
static void
333
proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
334
static void
335
proto_tree_set_ipxnet(field_info *fi, uint32_t value);
336
static void
337
proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
338
static void
339
proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
340
static void
341
proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
342
static void
343
proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
344
static void
345
proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
346
static void
347
proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
348
static void
349
proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length);
350
static void
351
proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
352
static void
353
proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length);
354
static void
355
proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
356
static void
357
proto_tree_set_boolean(field_info *fi, uint64_t value);
358
static void
359
proto_tree_set_float(field_info *fi, float value);
360
static void
361
proto_tree_set_double(field_info *fi, double value);
362
static void
363
proto_tree_set_uint(field_info *fi, uint32_t value);
364
static void
365
proto_tree_set_int(field_info *fi, int32_t value);
366
static void
367
proto_tree_set_uint64(field_info *fi, uint64_t value);
368
static void
369
proto_tree_set_int64(field_info *fi, int64_t value);
370
static void
371
proto_tree_set_eui64(field_info *fi, const uint64_t value);
372
static void
373
proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
374
375
/* Handle type length mismatch (now filterable) expert info */
376
static int proto_type_length_mismatch;
377
static expert_field ei_type_length_mismatch_error;
378
static expert_field ei_type_length_mismatch_warn;
379
static void register_type_length_mismatch(void);
380
381
/* Handle byte array string decoding errors with expert info */
382
static int proto_byte_array_string_decoding_error;
383
static expert_field ei_byte_array_string_decoding_failed_error;
384
static void register_byte_array_string_decodinws_error(void);
385
386
/* Handle date and time string decoding errors with expert info */
387
static int proto_date_time_string_decoding_error;
388
static expert_field ei_date_time_string_decoding_failed_error;
389
static void register_date_time_string_decodinws_error(void);
390
391
/* Handle string errors expert info */
392
static int proto_string_errors;
393
static expert_field ei_string_trailing_characters;
394
static void register_string_errors(void);
395
396
/* Handle varint errors expert info */
397
static int proto_varint_errors;
398
static expert_field ei_varint_decoding_failed_error;
399
static void register_varint_errors(void);
400
401
static int proto_register_field_init(header_field_info *hfinfo, const int parent);
402
403
/* special-case header field used within proto.c */
404
static header_field_info hfi_text_only =
405
  { "Text item",  "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
406
int hf_text_only;
407
408
/* Structure for information about a protocol */
409
struct _protocol {
410
  const char *name;               /* long description */
411
  const char *short_name;         /* short description */
412
  const char *filter_name;        /* name of this protocol in filters */
413
  GPtrArray  *fields;             /* fields for this protocol */
414
  int         proto_id;           /* field ID for this protocol */
415
  bool        is_enabled;         /* true if protocol is enabled */
416
  bool        enabled_by_default; /* true if protocol is enabled by default */
417
  bool        can_toggle;         /* true if is_enabled can be changed */
418
  int         parent_proto_id;    /* Used to identify "pino"s (Protocol In Name Only).
419
                                     For dissectors that need a protocol name so they
420
                                     can be added to a dissector table, but use the
421
                                     parent_proto_id for things like enable/disable */
422
  GList      *heur_list;          /* Heuristic dissectors associated with this protocol */
423
};
424
425
/* List of all protocols */
426
static GList *protocols;
427
428
/* Structure stored for deregistered g_slice */
429
struct g_slice_data {
430
  size_t   block_size;
431
  void *mem_block;
432
};
433
434
/* Deregistered fields */
435
static GPtrArray *deregistered_fields;
436
static GPtrArray *deregistered_data;
437
static GPtrArray *deregistered_slice;
438
439
/* indexed by prefix, contains initializers */
440
static GHashTable* prefixes;
441
442
/* Contains information about a field when a dissector calls
443
 * proto_tree_add_item.  */
444
74.6M
#define FIELD_INFO_NEW(pool, fi)  fi = wmem_new(pool, field_info)
445
#define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
446
447
/* Contains the space for proto_nodes. */
448
#define PROTO_NODE_INIT(node)     \
449
136M
  node->first_child = NULL;   \
450
136M
  node->last_child = NULL;    \
451
136M
  node->next = NULL;
452
453
#define PROTO_NODE_FREE(pool, node)     \
454
  wmem_free(pool, node)
455
456
/* String space for protocol and field items for the GUI */
457
#define ITEM_LABEL_NEW(pool, il)      \
458
32.1M
  il = wmem_new(pool, item_label_t);   \
459
32.1M
  il->value_pos = 0;        \
460
32.1M
  il->value_len = 0;
461
#define ITEM_LABEL_FREE(pool, il)     \
462
28.6k
  wmem_free(pool, il);
463
464
#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)            \
465
245M
  if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
466
245M
    ws_error("Unregistered hf! index=%d", hfindex);         \
467
245M
  DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!"); \
468
245M
  DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!"); \
469
245M
  hfinfo = gpa_hfinfo.hfi[hfindex];
470
471
48
#define PROTO_PRE_ALLOC_HF_FIELDS_MEM (300000+PRE_ALLOC_EXPERT_FIELDS_MEM)
472
473
/* List which stores protocols and fields that have been registered */
474
typedef struct _gpa_hfinfo_t {
475
  uint32_t            len;
476
  uint32_t            allocated_len;
477
  header_field_info **hfi;
478
} gpa_hfinfo_t;
479
480
static gpa_hfinfo_t gpa_hfinfo;
481
482
/* Hash table of abbreviations and IDs */
483
static wmem_map_t *gpa_name_map;
484
static header_field_info *same_name_hfinfo;
485
486
/* Hash table protocol aliases. const char * -> const char * */
487
static GHashTable *gpa_protocol_aliases;
488
489
/*
490
 * We're called repeatedly with the same field name when sorting a column.
491
 * Cache our last gpa_name_map hit for faster lookups.
492
 */
493
static char *last_field_name;
494
static header_field_info *last_hfinfo;
495
496
/* Points to the first element of an array of bits, indexed by
497
   a subtree item type; that array element is true if subtrees of
498
   an item of that type are to be expanded. */
499
static uint32_t *tree_is_expanded;
500
501
/* Number of elements in that array. The entry with index 0 is not used. */
502
int   num_tree_types = 1;
503
504
/* Name hashtables for fast detection of duplicate names */
505
static GHashTable* proto_names;
506
static GHashTable* proto_short_names;
507
static GHashTable* proto_filter_names;
508
509
static const char * const reserved_filter_names[] = {
510
  /* Display filter keywords. */
511
  "eq",
512
  "ne",
513
  "all_eq",
514
  "any_eq",
515
  "all_ne",
516
  "any_ne",
517
  "gt",
518
  "ge",
519
  "lt",
520
  "le",
521
  "bitand",
522
  "bitwise_and",
523
  "contains",
524
  "matches",
525
  "not",
526
  "and",
527
  "or",
528
  "xor",
529
  "in",
530
  "any",
531
  "all",
532
  "true",
533
  "false",
534
  "nan",
535
  "inf",
536
  "infinity",
537
  NULL
538
};
539
540
static GHashTable *proto_reserved_filter_names;
541
static GQueue* saved_dir_queue;
542
543
static gboolean
544
proto_strcase_equal(const void* name1, const void* name2)
545
0
{
546
0
  const char* s1 = (const char*)name1;
547
0
  const char* s2 = (const char*)name2;
548
549
0
  return g_ascii_strcasecmp(s1, s2) == 0 ? TRUE : FALSE;
550
0
}
551
552
static int
553
proto_compare_name(const void *p1_arg, const void *p2_arg)
554
477k
{
555
477k
  const protocol_t *p1 = (const protocol_t *)p1_arg;
556
477k
  const protocol_t *p2 = (const protocol_t *)p2_arg;
557
558
477k
  return g_ascii_strcasecmp(p1->short_name, p2->short_name);
559
477k
}
560
561
static GSList *dissector_plugins;
562
563
#ifdef HAVE_PLUGINS
564
void
565
proto_register_plugin(const proto_plugin *plug)
566
{
567
  dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
568
}
569
#else /* HAVE_PLUGINS */
570
void
571
proto_register_plugin(const proto_plugin *plug _U_)
572
0
{
573
0
  ws_warning("proto_register_plugin: built without support for binary plugins");
574
0
}
575
#endif /* HAVE_PLUGINS */
576
577
static void
578
call_plugin_register_protoinfo(void *data, void *user_data _U_)
579
0
{
580
0
  proto_plugin *plug = (proto_plugin *)data;
581
582
0
  if (plug->register_protoinfo) {
583
0
    plug->register_protoinfo();
584
0
  }
585
0
}
586
587
static void
588
call_plugin_register_handoff(void *data, void *user_data _U_)
589
0
{
590
0
  proto_plugin *plug = (proto_plugin *)data;
591
592
0
  if (plug->register_handoff) {
593
0
    plug->register_handoff();
594
0
  }
595
0
}
596
597
void proto_pre_init(void)
598
16
{
599
16
  saved_dir_queue = g_queue_new();
600
601
16
  proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
602
16
  proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
603
16
  proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
604
605
16
  proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, proto_strcase_equal);
606
432
  for (const char* const * ptr = reserved_filter_names; *ptr != NULL; ptr++) {
607
    /* GHashTable has no key destructor so the cast is safe. */
608
416
    g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
609
416
  }
610
611
16
  gpa_hfinfo.len = 0;
612
16
  gpa_hfinfo.allocated_len = 0;
613
16
  gpa_hfinfo.hfi = NULL;
614
16
  gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
615
16
  wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM);
616
16
  gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
617
16
  deregistered_fields = g_ptr_array_new();
618
16
  deregistered_data = g_ptr_array_new();
619
16
  deregistered_slice = g_ptr_array_new();
620
16
}
621
622
/* initialize data structures and register protocols and fields */
623
void
624
proto_init(GSList *register_all_plugin_protocols_list,
625
     GSList *register_all_plugin_handoffs_list,
626
     register_entity_func register_func, register_entity_func handoff_func,
627
     register_cb cb,
628
     void *client_data)
629
16
{
630
  /* Initialize the ftype subsystem */
631
16
  ftypes_initialize();
632
633
  /* Initialize the address type subsystem */
634
16
  address_types_initialize();
635
636
  /* Register one special-case FT_TEXT_ONLY field for use when
637
     converting wireshark to new-style proto_tree. These fields
638
     are merely strings on the GUI tree; they are not filterable */
639
16
  hf_text_only = proto_register_field_init(&hfi_text_only, -1);
640
641
  /* Register the pseudo-protocols used for exceptions. */
642
16
  register_show_exception();
643
16
  register_type_length_mismatch();
644
16
  register_byte_array_string_decodinws_error();
645
16
  register_date_time_string_decodinws_error();
646
16
  register_string_errors();
647
16
  register_varint_errors();
648
16
  ftypes_register_pseudofields();
649
16
  col_register_protocol();
650
651
  /* Have each built-in dissector register its protocols, fields,
652
     dissector tables, and dissectors to be called through a
653
     handle, and do whatever one-time initialization it needs to
654
     do. */
655
16
  if (register_func != NULL)
656
16
    register_func(cb, client_data);
657
658
  /* Now call the registration routines for all epan plugins. */
659
16
  for (GSList *l = register_all_plugin_protocols_list; l != NULL; l = l->next) {
660
0
    ((void (*)(register_cb, void *))l->data)(cb, client_data);
661
0
  }
662
663
  /* Now call the registration routines for all dissector plugins. */
664
16
  if (cb)
665
0
    (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
666
16
  g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL);
667
668
  /* Now call the "handoff registration" routines of all built-in
669
     dissectors; those routines register the dissector in other
670
     dissectors' handoff tables, and fetch any dissector handles
671
     they need. */
672
16
  if (handoff_func != NULL)
673
16
    handoff_func(cb, client_data);
674
675
  /* Now do the same with epan plugins. */
676
16
  for (GSList *l = register_all_plugin_handoffs_list; l != NULL; l = l->next) {
677
0
    ((void (*)(register_cb, void *))l->data)(cb, client_data);
678
0
  }
679
680
  /* Now do the same with dissector plugins. */
681
16
  if (cb)
682
0
    (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
683
16
  g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL);
684
685
  /* sort the protocols by protocol name */
686
16
  protocols = g_list_sort(protocols, proto_compare_name);
687
688
  /* sort the dissector handles in dissector tables (for -G reports
689
   * and -d error messages. The GUI sorts the handles itself.) */
690
16
  packet_all_tables_sort_handles();
691
692
  /* We've assigned all the subtree type values; allocate the array
693
     for them, and zero it out. */
694
16
  tree_is_expanded = g_new0(uint32_t, (num_tree_types/32)+1);
695
16
}
696
697
static void
698
proto_cleanup_base(void)
699
0
{
700
0
  protocol_t *protocol;
701
0
  header_field_info *hfinfo;
702
703
  /* Free the abbrev/ID hash table */
704
0
  if (gpa_name_map) {
705
    // XXX - We don't have a wmem_map_destroy, but
706
    // it does get cleaned up when epan scope is
707
    // destroyed
708
    //g_hash_table_destroy(gpa_name_map);
709
0
    gpa_name_map = NULL;
710
0
  }
711
0
  if (gpa_protocol_aliases) {
712
0
    g_hash_table_destroy(gpa_protocol_aliases);
713
0
    gpa_protocol_aliases = NULL;
714
0
  }
715
0
  g_free(last_field_name);
716
0
  last_field_name = NULL;
717
718
0
  while (protocols) {
719
0
    protocol = (protocol_t *)protocols->data;
720
0
    PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
721
0
    DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
722
723
0
    g_slice_free(header_field_info, hfinfo);
724
0
    if (protocol->parent_proto_id != -1) {
725
      // pino protocol
726
0
      DISSECTOR_ASSERT(protocol->fields == NULL); //helpers should not have any registered fields
727
0
      DISSECTOR_ASSERT(protocol->heur_list == NULL); //helpers should not have a heuristic list
728
0
    } else {
729
0
      if (protocol->fields) {
730
0
        g_ptr_array_free(protocol->fields, true);
731
0
      }
732
0
      g_list_free(protocol->heur_list);
733
0
    }
734
0
    protocols = g_list_remove(protocols, protocol);
735
0
    g_free(protocol);
736
0
  }
737
738
0
  if (proto_names) {
739
0
    g_hash_table_destroy(proto_names);
740
0
    proto_names = NULL;
741
0
  }
742
743
0
  if (proto_short_names) {
744
0
    g_hash_table_destroy(proto_short_names);
745
0
    proto_short_names = NULL;
746
0
  }
747
748
0
  if (proto_filter_names) {
749
0
    g_hash_table_destroy(proto_filter_names);
750
0
    proto_filter_names = NULL;
751
0
  }
752
753
0
  if (proto_reserved_filter_names) {
754
0
    g_hash_table_destroy(proto_reserved_filter_names);
755
0
    proto_reserved_filter_names = NULL;
756
0
  }
757
758
0
  if (gpa_hfinfo.allocated_len) {
759
0
    gpa_hfinfo.len           = 0;
760
0
    gpa_hfinfo.allocated_len = 0;
761
0
    g_free(gpa_hfinfo.hfi);
762
0
    gpa_hfinfo.hfi           = NULL;
763
0
  }
764
765
0
  if (deregistered_fields) {
766
0
    g_ptr_array_free(deregistered_fields, true);
767
0
    deregistered_fields = NULL;
768
0
  }
769
770
0
  if (deregistered_data) {
771
0
    g_ptr_array_free(deregistered_data, true);
772
0
    deregistered_data = NULL;
773
0
  }
774
775
0
  if (deregistered_slice) {
776
0
    g_ptr_array_free(deregistered_slice, true);
777
0
    deregistered_slice = NULL;
778
0
  }
779
780
0
  g_free(tree_is_expanded);
781
0
  tree_is_expanded = NULL;
782
783
0
  if (prefixes)
784
0
    g_hash_table_destroy(prefixes);
785
786
0
  if (saved_dir_queue != NULL) {
787
0
    g_queue_clear_full(saved_dir_queue, g_free);
788
0
    g_queue_free(saved_dir_queue);
789
0
    saved_dir_queue = NULL;
790
0
  }
791
0
}
792
793
void
794
proto_cleanup(void)
795
0
{
796
0
  proto_free_deregistered_fields();
797
0
  proto_cleanup_base();
798
799
0
  g_slist_free(dissector_plugins);
800
0
  dissector_plugins = NULL;
801
0
}
802
803
static bool
804
ws_pushd(const char* dir)
805
3
{
806
  //Save the current working directory
807
3
  const char* save_wd = get_current_working_dir();
808
3
  if (save_wd != NULL)
809
3
    g_queue_push_head(saved_dir_queue, g_strdup(save_wd));
810
811
  //Change to the new one
812
#ifdef _WIN32
813
  SetCurrentDirectory(utf_8to16(dir));
814
  return true;
815
#else
816
3
  return (chdir(dir) == 0);
817
3
#endif
818
3
}
819
820
static bool
821
ws_popd(void)
822
0
{
823
0
  int ret = 0;
824
0
  char* saved_wd = g_queue_pop_head(saved_dir_queue);
825
0
  if (saved_wd == NULL)
826
0
    return false;
827
828
  //Restore the previous one
829
#ifdef _WIN32
830
  SetCurrentDirectory(utf_8to16(saved_wd));
831
#else
832
0
  ret = chdir(saved_wd);
833
0
#endif
834
0
  g_free(saved_wd);
835
0
  return (ret == 0);
836
0
}
837
838
void
839
proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
840
3
{
841
3
  if (ws_pushd(dir))
842
0
  {
843
0
    func(param);
844
0
    ws_popd();
845
0
  }
846
3
}
847
848
static bool
849
// NOLINTNEXTLINE(misc-no-recursion)
850
proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
851
            void *data)
852
0
{
853
0
  proto_node *pnode = tree;
854
0
  proto_node *child;
855
0
  proto_node *current;
856
857
0
  if (func(pnode, data))
858
0
    return true;
859
860
0
  child = pnode->first_child;
861
0
  while (child != NULL) {
862
    /*
863
     * The routine we call might modify the child, e.g. by
864
     * freeing it, so we get the child's successor before
865
     * calling that routine.
866
     */
867
0
    current = child;
868
0
    child   = current->next;
869
    // We recurse here, but we're limited by prefs.gui_max_tree_depth
870
0
    if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
871
0
      return true;
872
0
  }
873
874
0
  return false;
875
0
}
876
877
void
878
proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
879
          void *data)
880
136M
{
881
136M
  proto_node *node = tree;
882
136M
  proto_node *current;
883
884
136M
  if (!node)
885
0
    return;
886
887
136M
  node = node->first_child;
888
273M
  while (node != NULL) {
889
136M
    current = node;
890
136M
    node    = current->next;
891
136M
    func((proto_tree *)current, data);
892
136M
  }
893
136M
}
894
895
static void
896
free_GPtrArray_value(void *key, void *value, void *user_data _U_)
897
248
{
898
248
  GPtrArray         *ptrs = (GPtrArray *)value;
899
248
  int                hfid = GPOINTER_TO_UINT(key);
900
248
  header_field_info *hfinfo;
901
902
248
  PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
903
248
  if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
904
    /* when a field is referenced by a filter this also
905
       affects the refcount for the parent protocol so we need
906
       to adjust the refcount for the parent as well
907
    */
908
248
    if (hfinfo->parent != -1) {
909
248
      header_field_info *parent_hfinfo;
910
248
      PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
911
248
      parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
912
248
    }
913
248
    hfinfo->ref_type = HF_REF_TYPE_NONE;
914
248
  }
915
916
248
  g_ptr_array_free(ptrs, true);
917
248
}
918
919
static void
920
proto_tree_free_node(proto_node *node, void *data _U_)
921
136M
{
922
136M
  field_info *finfo  = PNODE_FINFO(node);
923
924
136M
  proto_tree_children_foreach(node, proto_tree_free_node, NULL);
925
926
136M
  if (finfo) {
927
    // The fvalue_t structure was allocated using fvalue_new_pool()
928
    // (see new_field_info()) and will be reclaimed when the pool is
929
    // freed, so we only release the type-specific data it owns here.
930
74.6M
    fvalue_cleanup(finfo->value);
931
74.6M
    finfo->value = NULL;
932
74.6M
  }
933
136M
}
934
935
void
936
proto_tree_reset(proto_tree *tree)
937
232k
{
938
232k
  tree_data_t *tree_data = PTREE_DATA(tree);
939
940
232k
  proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
941
942
  /* free tree data */
943
232k
  if (tree_data->interesting_hfids) {
944
    /* Free all the GPtrArray's in the interesting_hfids hash. */
945
168k
    g_hash_table_foreach(tree_data->interesting_hfids,
946
168k
      free_GPtrArray_value, NULL);
947
948
    /* And then remove all values. */
949
168k
    g_hash_table_remove_all(tree_data->interesting_hfids);
950
168k
  }
951
952
  /* Reset track of the number of children */
953
232k
  tree_data->count = 0;
954
955
  /* Reset our loop checks */
956
232k
  tree_data->idle_count_ds_tvb = NULL;
957
232k
  tree_data->max_start = 0;
958
232k
  tree_data->start_idle_count = 0;
959
960
232k
  PROTO_NODE_INIT(tree);
961
232k
}
962
963
/* frees the resources that the dissection a proto_tree uses */
964
void
965
proto_tree_free(proto_tree *tree)
966
0
{
967
0
  tree_data_t *tree_data = PTREE_DATA(tree);
968
969
0
  proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
970
971
  /* free tree data */
972
0
  if (tree_data->interesting_hfids) {
973
    /* Free all the GPtrArray's in the interesting_hfids hash. */
974
0
    g_hash_table_foreach(tree_data->interesting_hfids,
975
0
      free_GPtrArray_value, NULL);
976
977
    /* And then destroy the hash. */
978
0
    g_hash_table_destroy(tree_data->interesting_hfids);
979
0
  }
980
981
0
  g_slice_free(tree_data_t, tree_data);
982
983
0
  g_slice_free(proto_tree, tree);
984
0
}
985
986
/* Is the parsing being done for a visible proto_tree or an invisible one?
987
 * By setting this correctly, the proto_tree creation is sped up by not
988
 * having to call vsnprintf and copy strings around.
989
 */
990
bool
991
proto_tree_set_visible(proto_tree *tree, bool visible)
992
16
{
993
16
  bool old_visible = PTREE_DATA(tree)->visible;
994
995
16
  PTREE_DATA(tree)->visible = visible;
996
997
16
  return old_visible;
998
16
}
999
1000
void
1001
proto_tree_set_fake_protocols(proto_tree *tree, bool fake_protocols)
1002
0
{
1003
0
  if (tree)
1004
0
    PTREE_DATA(tree)->fake_protocols = fake_protocols;
1005
0
}
1006
1007
/* Assume dissector set only its protocol fields.
1008
   This function is called by dissectors and allows the speeding up of filtering
1009
   in wireshark; if this function returns false it is safe to reset tree to NULL
1010
   and thus skip calling most of the expensive proto_tree_add_...()
1011
   functions.
1012
   If the tree is visible we implicitly assume the field is referenced.
1013
*/
1014
bool
1015
proto_field_is_referenced(proto_tree *tree, int proto_id)
1016
1.09M
{
1017
1.09M
  register header_field_info *hfinfo;
1018
1019
1020
1.09M
  if (!tree)
1021
0
    return false;
1022
1023
1.09M
  if (PTREE_DATA(tree)->visible)
1024
950k
    return true;
1025
1026
141k
  PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
1027
141k
  if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1028
0
    return true;
1029
1030
141k
  if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
1031
0
    return true;
1032
1033
141k
  return false;
1034
141k
}
1035
1036
1037
/* Finds a record in the hfinfo array by id. */
1038
header_field_info *
1039
proto_registrar_get_nth(unsigned hfindex)
1040
22.9M
{
1041
22.9M
  register header_field_info *hfinfo;
1042
1043
22.9M
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1044
22.9M
  return hfinfo;
1045
22.9M
}
1046
1047
1048
/*  Prefix initialization
1049
 *    this allows for a dissector to register a display filter name prefix
1050
 *    so that it can delay the initialization of the hf array as long as
1051
 *    possible.
1052
 */
1053
1054
/* compute a hash for the part before the dot of a display filter */
1055
static unsigned
1056
478
prefix_hash (const void *key) {
1057
  /* end the string at the dot and compute its hash */
1058
478
  char* copy = g_strdup((const char *)key);
1059
478
  char* c    = copy;
1060
478
  unsigned tmp;
1061
1062
1.74k
  for (; *c; c++) {
1063
1.29k
    if (*c == '.') {
1064
26
      *c = 0;
1065
26
      break;
1066
26
    }
1067
1.29k
  }
1068
1069
478
  tmp = wmem_str_hash(copy);
1070
478
  g_free(copy);
1071
478
  return tmp;
1072
478
}
1073
1074
/* are both strings equal up to the end or the dot? */
1075
static gboolean
1076
26
prefix_equal (const void *ap, const void *bp) {
1077
26
  const char* a = (const char *)ap;
1078
26
  const char* b = (const char *)bp;
1079
1080
178
  do {
1081
178
    char ac = *a++;
1082
178
    char bc = *b++;
1083
1084
178
    if ( (ac == '.' || ac == '\0') &&   (bc == '.' || bc == '\0') ) return TRUE;
1085
1086
152
    if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
1087
152
    if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
1088
1089
152
    if (ac != bc) return FALSE;
1090
152
  } while (1);
1091
1092
0
  return FALSE;
1093
26
}
1094
1095
/* Register a new prefix for "delayed" initialization of field arrays */
1096
void
1097
112
proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1098
112
  if (! prefixes ) {
1099
16
    prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1100
16
  }
1101
1102
112
  g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1103
112
}
1104
1105
/* helper to call all prefix initializers */
1106
static gboolean
1107
0
initialize_prefix(void *k, void *v, void *u _U_) {
1108
0
  ((prefix_initializer_t)v)((const char *)k);
1109
0
  return TRUE;
1110
0
}
1111
1112
/** Initialize every remaining uninitialized prefix. */
1113
void
1114
0
proto_initialize_all_prefixes(void) {
1115
0
  g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
1116
0
}
1117
1118
/* Finds a record in the hfinfo array by name.
1119
 * If it fails to find it in the already registered fields,
1120
 * it tries to find and call an initializer in the prefixes
1121
 * table and if so it looks again.
1122
 */
1123
1124
header_field_info *
1125
proto_registrar_get_byname(const char *field_name)
1126
1.52k
{
1127
1.52k
  header_field_info    *hfinfo;
1128
1.52k
  prefix_initializer_t  pi;
1129
1130
1.52k
  if (!field_name)
1131
16
    return NULL;
1132
1133
1.50k
  if (g_strcmp0(field_name, last_field_name) == 0) {
1134
54
    return last_hfinfo;
1135
54
  }
1136
1137
1.45k
  hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1138
1139
1.45k
  if (hfinfo) {
1140
1.09k
    g_free(last_field_name);
1141
1.09k
    last_field_name = g_strdup(field_name);
1142
1.09k
    last_hfinfo = hfinfo;
1143
1.09k
    return hfinfo;
1144
1.09k
  }
1145
1146
353
  if (!prefixes)
1147
0
    return NULL;
1148
1149
353
  if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
1150
13
    pi(field_name);
1151
13
    g_hash_table_remove(prefixes, field_name);
1152
340
  } else {
1153
340
    return NULL;
1154
340
  }
1155
1156
13
  hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1157
1158
13
  if (hfinfo) {
1159
9
    g_free(last_field_name);
1160
9
    last_field_name = g_strdup(field_name);
1161
9
    last_hfinfo = hfinfo;
1162
9
  }
1163
13
  return hfinfo;
1164
353
}
1165
1166
header_field_info*
1167
proto_registrar_get_byalias(const char *alias_name)
1168
340
{
1169
340
  if (!alias_name) {
1170
0
    return NULL;
1171
0
  }
1172
1173
  /* Find our aliased protocol. */
1174
340
  char *an_copy = g_strdup(alias_name);
1175
340
  char *dot = strchr(an_copy, '.');
1176
340
  if (dot) {
1177
0
    *dot = '\0';
1178
0
  }
1179
340
  const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1180
340
  if (!proto_pfx) {
1181
340
    g_free(an_copy);
1182
340
    return NULL;
1183
340
  }
1184
1185
  /* Construct our aliased field and look it up. */
1186
0
  GString *filter_name = g_string_new(proto_pfx);
1187
0
  if (dot) {
1188
0
    g_string_append_printf(filter_name, ".%s", dot+1);
1189
0
  }
1190
0
  header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1191
0
  g_free(an_copy);
1192
0
  g_string_free(filter_name, TRUE);
1193
1194
0
  return hfinfo;
1195
340
}
1196
1197
int
1198
proto_registrar_get_id_byname(const char *field_name)
1199
750
{
1200
750
  header_field_info *hfinfo;
1201
1202
750
  hfinfo = proto_registrar_get_byname(field_name);
1203
1204
750
  if (!hfinfo)
1205
16
    return -1;
1206
1207
734
  return hfinfo->id;
1208
750
}
1209
1210
static int
1211
label_strcat_flags(const header_field_info *hfinfo)
1212
2.41M
{
1213
2.41M
  if (FIELD_DISPLAY(hfinfo->display) & BASE_STR_WSP)
1214
2.02M
    return FORMAT_LABEL_REPLACE_SPACE;
1215
1216
391k
  return 0;
1217
2.41M
}
1218
1219
static char *
1220
format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1221
    const uint8_t *bytes, unsigned length, size_t max_str_len)
1222
300k
{
1223
300k
  char *str = NULL;
1224
300k
  const uint8_t *p;
1225
300k
  bool is_printable;
1226
1227
300k
  if (bytes) {
1228
296k
    if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE) {
1229
      /*
1230
       * If all bytes are valid and printable UTF-8, show the
1231
       * bytes as a string - in quotes to indicate that it's
1232
       * a string.
1233
       */
1234
857
      if (isprint_utf8_string((const char*)bytes, length)) {
1235
36
        str = wmem_strdup_printf(scope, "\"%.*s\"",
1236
36
            (int)length, bytes);
1237
36
        return str;
1238
36
      }
1239
295k
    } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE) {
1240
      /*
1241
       * Check whether all bytes are printable.
1242
       */
1243
0
      is_printable = true;
1244
0
      for (p = bytes; p < bytes+length; p++) {
1245
0
        if (!g_ascii_isprint(*p)) {
1246
          /* Not printable. */
1247
0
          is_printable = false;
1248
0
          break;
1249
0
        }
1250
0
      }
1251
1252
      /*
1253
       * If all bytes are printable ASCII, show the bytes
1254
       * as a string - in quotes to indicate that it's
1255
       * a string.
1256
       */
1257
0
      if (is_printable) {
1258
0
        str = wmem_strdup_printf(scope, "\"%.*s\"",
1259
0
            (int)length, bytes);
1260
0
        return str;
1261
0
      }
1262
0
    }
1263
1264
    /*
1265
     * Either it's not printable ASCII, or we don't care whether
1266
     * it's printable ASCII; show it as hex bytes.
1267
     */
1268
296k
    switch (FIELD_DISPLAY(hfinfo->display)) {
1269
0
    case SEP_DOT:
1270
0
      str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1271
0
      break;
1272
0
    case SEP_DASH:
1273
0
      str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1274
0
      break;
1275
24
    case SEP_COLON:
1276
24
      str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1277
24
      break;
1278
0
    case SEP_SPACE:
1279
0
      str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1280
0
      break;
1281
296k
    case BASE_NONE:
1282
296k
    default:
1283
296k
      if (prefs.display_byte_fields_with_spaces) {
1284
0
        str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1285
296k
      } else {
1286
296k
        str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1287
296k
      }
1288
296k
      break;
1289
296k
    }
1290
296k
  }
1291
3.59k
  else {
1292
3.59k
    if (hfinfo->display & BASE_ALLOW_ZERO) {
1293
65
      str = wmem_strdup(scope, "<none>");
1294
3.52k
    } else {
1295
3.52k
      str = wmem_strdup(scope, "<MISSING>");
1296
3.52k
    }
1297
3.59k
  }
1298
300k
  return str;
1299
300k
}
1300
1301
static char *
1302
format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1303
    const uint8_t *bytes, unsigned length)
1304
300k
{
1305
300k
  return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH);
1306
300k
}
1307
1308
static void
1309
ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1310
445
{
1311
445
  subtree_lvl *pushed_tree;
1312
1313
445
  DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
1314
445
  ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
1315
1316
445
  pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1317
445
  DISSECTOR_ASSERT(pushed_tree != NULL);
1318
445
  ptvc->pushed_tree = pushed_tree;
1319
445
}
1320
1321
static void
1322
ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1323
1.21k
{
1324
1.21k
  ptvc->pushed_tree       = NULL;
1325
1.21k
  ptvc->pushed_tree_max   = 0;
1326
1.21k
  DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
1327
1.21k
  ptvc->pushed_tree_index = 0;
1328
1.21k
}
1329
1330
/* Allocates an initializes a ptvcursor_t with 3 variables:
1331
 *  proto_tree, tvbuff, and offset. */
1332
ptvcursor_t *
1333
ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1334
1.71k
{
1335
1.71k
  ptvcursor_t *ptvc;
1336
1337
1.71k
  ptvc                    = wmem_new(scope, ptvcursor_t);
1338
1.71k
  ptvc->scope             = scope;
1339
1.71k
  ptvc->tree              = tree;
1340
1.71k
  ptvc->tvb               = tvb;
1341
1.71k
  ptvc->offset            = offset;
1342
1.71k
  ptvc->pushed_tree       = NULL;
1343
1.71k
  ptvc->pushed_tree_max   = 0;
1344
1.71k
  ptvc->pushed_tree_index = 0;
1345
1.71k
  return ptvc;
1346
1.71k
}
1347
1348
1349
/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1350
void
1351
ptvcursor_free(ptvcursor_t *ptvc)
1352
1.21k
{
1353
1.21k
  ptvcursor_free_subtree_levels(ptvc);
1354
1.21k
  wmem_free(ptvc->scope, ptvc);
1355
1.21k
}
1356
1357
/* Returns tvbuff. */
1358
tvbuff_t *
1359
ptvcursor_tvbuff(ptvcursor_t *ptvc)
1360
48.9k
{
1361
48.9k
  return ptvc->tvb;
1362
48.9k
}
1363
1364
/* Returns current offset. */
1365
unsigned
1366
ptvcursor_current_offset(ptvcursor_t *ptvc)
1367
58.9k
{
1368
58.9k
  return ptvc->offset;
1369
58.9k
}
1370
1371
proto_tree *
1372
ptvcursor_tree(ptvcursor_t *ptvc)
1373
32.0k
{
1374
32.0k
  if (!ptvc)
1375
0
    return NULL;
1376
1377
32.0k
  return ptvc->tree;
1378
32.0k
}
1379
1380
void
1381
ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1382
2.09k
{
1383
2.09k
  ptvc->tree = tree;
1384
2.09k
}
1385
1386
/* creates a subtree, sets it as the working tree and pushes the old working tree */
1387
proto_tree *
1388
ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1389
18.1k
{
1390
18.1k
  subtree_lvl *subtree;
1391
18.1k
  if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1392
445
    ptvcursor_new_subtree_levels(ptvc);
1393
1394
18.1k
  subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1395
18.1k
  subtree->tree = ptvc->tree;
1396
18.1k
  subtree->it= NULL;
1397
18.1k
  ptvc->pushed_tree_index++;
1398
18.1k
  return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1399
18.1k
}
1400
1401
/* pops a subtree */
1402
void
1403
ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1404
17.9k
{
1405
17.9k
  subtree_lvl *subtree;
1406
1407
17.9k
  if (ptvc->pushed_tree_index <= 0)
1408
34
    return;
1409
1410
17.8k
  ptvc->pushed_tree_index--;
1411
17.8k
  subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1412
17.8k
  if (subtree->it != NULL)
1413
1.62k
    proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1414
1415
17.8k
  ptvc->tree = subtree->tree;
1416
17.8k
}
1417
1418
/* saves the current tvb offset and the item in the current subtree level */
1419
static void
1420
ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1421
1.71k
{
1422
1.71k
  subtree_lvl *subtree;
1423
1424
1.71k
  DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
1425
1426
1.71k
  subtree                = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1427
1.71k
  subtree->it            = it;
1428
1.71k
  subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1429
1.71k
}
1430
1431
/* Creates a subtree and adds it to the cursor as the working tree but does not
1432
 * save the old working tree */
1433
proto_tree *
1434
ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1435
18.1k
{
1436
18.1k
  ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1437
18.1k
  return ptvc->tree;
1438
18.1k
}
1439
1440
static proto_tree *
1441
ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1442
1.83k
{
1443
1.83k
  ptvcursor_push_subtree(ptvc, it, ett_subtree);
1444
1.83k
  if (length == SUBTREE_UNDEFINED_LENGTH)
1445
1.71k
    ptvcursor_subtree_set_item(ptvc, it);
1446
1.83k
  return ptvcursor_tree(ptvc);
1447
1.83k
}
1448
1449
/* Add an item to the tree and create a subtree
1450
 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1451
 * In this case, when the subtree will be closed, the parent item length will
1452
 * be equal to the advancement of the cursor since the creation of the subtree.
1453
 */
1454
proto_tree *
1455
ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1456
         const unsigned encoding, int ett_subtree)
1457
120
{
1458
120
  proto_item *it;
1459
1460
120
  it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1461
120
  return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1462
120
}
1463
1464
static proto_item *
1465
proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length);
1466
1467
/* Add a text node to the tree and create a subtree
1468
 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1469
 * In this case, when the subtree will be closed, the item length will be equal
1470
 * to the advancement of the cursor since the creation of the subtree.
1471
 */
1472
proto_tree *
1473
ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1474
        int ett_subtree, const char *format, ...)
1475
1.75k
{
1476
1.75k
  proto_item        *pi;
1477
1.75k
  va_list            ap;
1478
1.75k
  header_field_info *hfinfo;
1479
1.75k
  proto_tree        *tree;
1480
1481
1.75k
  tree = ptvcursor_tree(ptvc);
1482
1483
1.75k
  CHECK_FOR_NULL_TREE(tree);
1484
1485
1.75k
  TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1486
1487
1.72k
  pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1488
1.72k
              ptvcursor_current_offset(ptvc), length);
1489
1490
1.72k
  TRY_TO_FAKE_THIS_REPR(pi);
1491
1492
1.72k
  va_start(ap, format);
1493
1.72k
  proto_tree_set_representation(pi, format, ap);
1494
1.72k
  va_end(ap);
1495
1496
1.72k
  return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1497
1.72k
}
1498
1499
/* Add a text-only node, leaving it to our caller to fill the text in */
1500
static proto_item *
1501
proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1502
5.87M
{
1503
5.87M
  proto_item *pi;
1504
1505
5.87M
  if (tree == NULL)
1506
0
    return NULL;
1507
1508
5.87M
  pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1509
1510
5.87M
  return pi;
1511
5.87M
}
1512
1513
/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1514
proto_item *
1515
proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length,
1516
        const char *format, ...)
1517
136k
{
1518
136k
  proto_item    *pi;
1519
136k
  va_list      ap;
1520
136k
  header_field_info *hfinfo;
1521
1522
136k
  tvb_ensure_bytes_exist(tvb, start, length);
1523
1524
136k
  CHECK_FOR_NULL_TREE(tree);
1525
1526
134k
  TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1527
1528
55.7k
  pi = proto_tree_add_text_node(tree, tvb, start, length);
1529
1530
55.7k
  TRY_TO_FAKE_THIS_REPR(pi);
1531
1532
55.7k
  va_start(ap, format);
1533
55.7k
  proto_tree_set_representation(pi, format, ap);
1534
55.7k
  va_end(ap);
1535
1536
55.7k
  return pi;
1537
55.7k
}
1538
1539
/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1540
proto_item *
1541
proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start,
1542
         unsigned length, const char *format, va_list ap)
1543
7.24M
{
1544
7.24M
  proto_item        *pi;
1545
7.24M
  header_field_info *hfinfo;
1546
1547
  /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1548
   * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1549
   * the length to be what's in the tvbuff if length is -1, and the
1550
   * minimum of length and what's in the tvbuff if not.
1551
   */
1552
1553
7.24M
  CHECK_FOR_NULL_TREE(tree);
1554
1555
7.24M
  TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1556
1557
5.81M
  pi = proto_tree_add_text_node(tree, tvb, start, length);
1558
1559
5.81M
  TRY_TO_FAKE_THIS_REPR(pi);
1560
1561
5.81M
  proto_tree_set_representation(pi, format, ap);
1562
1563
5.81M
  return pi;
1564
5.81M
}
1565
1566
/* Add a text-only node that creates a subtree underneath.
1567
 */
1568
proto_tree *
1569
proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *text)
1570
976k
{
1571
976k
  return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1572
976k
}
1573
1574
/* Add a text-only node that creates a subtree underneath.
1575
 */
1576
proto_tree *
1577
proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *format, ...)
1578
6.64M
{
1579
6.64M
  proto_tree *pt;
1580
6.64M
  proto_item *pi;
1581
6.64M
  va_list     ap;
1582
1583
6.64M
  if (length == -1) {
1584
236k
    length = tvb_captured_length_remaining(tvb, start);
1585
236k
  }
1586
1587
6.64M
  va_start(ap, format);
1588
6.64M
  pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1589
6.64M
  va_end(ap);
1590
1591
6.64M
  if (tree_item != NULL)
1592
5.31M
    *tree_item = pi;
1593
1594
6.64M
  pt = proto_item_add_subtree(pi, idx);
1595
1596
6.64M
  return pt;
1597
6.64M
}
1598
1599
/* Add a text-only node for debugging purposes. The caller doesn't need
1600
 * to worry about tvbuff, start, or length. Debug message gets sent to
1601
 * STDOUT, too */
1602
proto_item *
1603
proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1604
0
{
1605
0
  proto_item *pi;
1606
0
  va_list     ap;
1607
1608
0
  pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1609
1610
0
  if (pi) {
1611
0
    va_start(ap, format);
1612
0
    proto_tree_set_representation(pi, format, ap);
1613
0
    va_end(ap);
1614
0
  }
1615
0
  va_start(ap, format);
1616
0
  vprintf(format, ap);
1617
0
  va_end(ap);
1618
0
  printf("\n");
1619
1620
0
  return pi;
1621
0
}
1622
1623
proto_item *
1624
proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1625
23.1k
{
1626
23.1k
  proto_item    *pi;
1627
23.1k
  header_field_info *hfinfo;
1628
1629
23.1k
  CHECK_FOR_NULL_TREE(tree);
1630
1631
23.1k
  TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1632
1633
6.59k
  pi = proto_tree_add_text_node(tree, tvb, start, length);
1634
1635
6.59k
  TRY_TO_FAKE_THIS_REPR(pi);
1636
1637
6.59k
  proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1638
1639
6.59k
  return pi;
1640
6.59k
}
1641
1642
proto_item *
1643
proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1644
827
{
1645
827
  proto_item    *pi;
1646
827
  header_field_info *hfinfo;
1647
827
  char      *str;
1648
1649
827
  CHECK_FOR_NULL_TREE(tree);
1650
1651
827
  TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1652
1653
773
  pi = proto_tree_add_text_node(tree, tvb, start, length);
1654
1655
773
  TRY_TO_FAKE_THIS_REPR(pi);
1656
1657
773
  str = tvb_format_text_wsp(NULL, tvb, start, length);
1658
773
  proto_item_set_text(pi, "%s", str);
1659
773
  wmem_free(NULL, str);
1660
1661
773
  return pi;
1662
773
}
1663
1664
void proto_report_dissector_bug(const char *format, ...)
1665
524
{
1666
524
  va_list args;
1667
1668
524
  if (wireshark_abort_on_dissector_bug) {
1669
    /*
1670
     * Try to have the error message show up in the crash
1671
     * information.
1672
     */
1673
0
    va_start(args, format);
1674
0
    ws_vadd_crash_info(format, args);
1675
0
    va_end(args);
1676
1677
    /*
1678
     * Print the error message.
1679
     */
1680
0
    va_start(args, format);
1681
0
    vfprintf(stderr, format, args);
1682
0
    va_end(args);
1683
0
    putc('\n', stderr);
1684
1685
    /*
1686
     * And crash.
1687
     */
1688
0
    abort();
1689
524
  } else {
1690
524
    va_start(args, format);
1691
524
    VTHROW_FORMATTED(DissectorError, format, args);
1692
524
    va_end(args);
1693
524
    ws_assert_not_reached(); /* GCC 12 with ASAN needs this. */
1694
524
  }
1695
524
}
1696
1697
/* We could probably get away with changing is_error to a minimum length value. */
1698
static void
1699
report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool is_error)
1700
2.24k
{
1701
2.24k
  if (is_error) {
1702
289
    expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1703
1.95k
  } else {
1704
1.95k
    expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1705
1.95k
  }
1706
1707
2.24k
  if (is_error) {
1708
289
    THROW(ReportedBoundsError);
1709
289
  }
1710
2.24k
}
1711
1712
static uint32_t
1713
get_uint_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1714
14.5M
{
1715
14.5M
  uint32_t value;
1716
14.5M
  bool length_error;
1717
1718
14.5M
  switch (length) {
1719
1720
9.78M
  case 1:
1721
9.78M
    value = tvb_get_uint8(tvb, offset);
1722
9.78M
    if (encoding & ENC_ZIGBEE) {
1723
2.44k
      if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1724
913
        value = 0;
1725
913
      }
1726
2.44k
    }
1727
9.78M
    break;
1728
1729
2.87M
  case 2:
1730
2.87M
    value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1731
2.87M
                   : tvb_get_ntohs(tvb, offset);
1732
2.87M
    if (encoding & ENC_ZIGBEE) {
1733
422
      if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1734
164
        value = 0;
1735
164
      }
1736
422
    }
1737
2.87M
    break;
1738
1739
550k
  case 3:
1740
550k
    value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1741
550k
                   : tvb_get_ntoh24(tvb, offset);
1742
550k
    break;
1743
1744
1.32M
  case 4:
1745
1.32M
    value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1746
1.32M
                   : tvb_get_ntohl(tvb, offset);
1747
1.32M
    break;
1748
1749
1.57k
  default:
1750
1.57k
    if (length < 1) {
1751
142
      length_error = true;
1752
142
      value = 0;
1753
1.43k
    } else {
1754
1.43k
      length_error = false;
1755
1.43k
      value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1756
1.43k
                     : tvb_get_ntohl(tvb, offset);
1757
1.43k
    }
1758
1.57k
    report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1759
1.57k
    break;
1760
14.5M
  }
1761
14.5M
  return value;
1762
14.5M
}
1763
1764
static inline uint64_t
1765
get_uint64_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, unsigned length, const unsigned encoding)
1766
4.35M
{
1767
4.35M
  uint64_t value;
1768
1769
4.35M
  value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1770
1771
4.35M
  if (length < 1 || length > 8) {
1772
495
    report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1773
495
  }
1774
1775
4.35M
  return value;
1776
4.35M
}
1777
1778
static int32_t
1779
get_int_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1780
189k
{
1781
189k
  int32_t value;
1782
189k
  bool length_error;
1783
1784
189k
  switch (length) {
1785
1786
107k
  case 1:
1787
107k
    value = tvb_get_int8(tvb, offset);
1788
107k
    break;
1789
1790
44.9k
  case 2:
1791
44.9k
    value = encoding ? tvb_get_letohis(tvb, offset)
1792
44.9k
         : tvb_get_ntohis(tvb, offset);
1793
44.9k
    break;
1794
1795
2.14k
  case 3:
1796
2.14k
    value = encoding ? tvb_get_letohi24(tvb, offset)
1797
2.14k
         : tvb_get_ntohi24(tvb, offset);
1798
2.14k
    break;
1799
1800
34.9k
  case 4:
1801
34.9k
    value = encoding ? tvb_get_letohil(tvb, offset)
1802
34.9k
         : tvb_get_ntohil(tvb, offset);
1803
34.9k
    break;
1804
1805
23
  default:
1806
23
    if (length < 1) {
1807
1
      length_error = true;
1808
1
      value = 0;
1809
22
    } else {
1810
22
      length_error = false;
1811
22
      value = encoding ? tvb_get_letohil(tvb, offset)
1812
22
           : tvb_get_ntohil(tvb, offset);
1813
22
    }
1814
23
    report_type_length_mismatch(tree, "a signed integer", length, length_error);
1815
23
    break;
1816
189k
  }
1817
189k
  return value;
1818
189k
}
1819
1820
/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1821
 * be cast-able as a int64_t. This is weird, but what the code has always done.
1822
 */
1823
static inline uint64_t
1824
get_int64_value(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length, const unsigned encoding)
1825
8.90k
{
1826
8.90k
  uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1827
1828
8.90k
  switch (length) {
1829
982
    case 7:
1830
982
      value = ws_sign_ext64(value, 56);
1831
982
      break;
1832
1.24k
    case 6:
1833
1.24k
      value = ws_sign_ext64(value, 48);
1834
1.24k
      break;
1835
1.18k
    case 5:
1836
1.18k
      value = ws_sign_ext64(value, 40);
1837
1.18k
      break;
1838
792
    case 4:
1839
792
      value = ws_sign_ext64(value, 32);
1840
792
      break;
1841
71
    case 3:
1842
71
      value = ws_sign_ext64(value, 24);
1843
71
      break;
1844
360
    case 2:
1845
360
      value = ws_sign_ext64(value, 16);
1846
360
      break;
1847
831
    case 1:
1848
831
      value = ws_sign_ext64(value, 8);
1849
831
      break;
1850
8.90k
  }
1851
1852
8.90k
  return value;
1853
8.90k
}
1854
1855
/* For FT_STRING */
1856
static inline const uint8_t *
1857
get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1858
    int length, unsigned *ret_length, const unsigned encoding)
1859
142k
{
1860
142k
  if (length == -1) {
1861
43
    *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1862
142k
  } else {
1863
142k
    *ret_length = length;
1864
142k
  }
1865
142k
  return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1866
142k
}
1867
1868
/* For FT_STRINGZ */
1869
static inline const uint8_t *
1870
get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1871
    unsigned start, int length, unsigned *ret_length, const unsigned encoding)
1872
15.2k
{
1873
15.2k
  const uint8_t *value;
1874
1875
15.2k
  if (length < -1) {
1876
1
    report_type_length_mismatch(tree, "a string", length, true);
1877
1
  }
1878
1879
  /* XXX - Ideally, every "null-terminated string which fits into a
1880
   * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1881
   * as appropriate, not a FT_STRINGZ. If so, then we could always call
1882
   * tvb_get_stringz_enc here. Failing that, we could treat length 0
1883
   * as unknown length as well (since there is a trailing '\0', the real
1884
   * length is never zero), allowing switching to unsigned lengths.
1885
   */
1886
15.2k
  if (length == -1) {
1887
    /* This can throw an exception */
1888
6.15k
    value = tvb_get_stringz_enc(scope, tvb, start, ret_length, encoding);
1889
9.12k
  } else {
1890
    /* In this case, length signifies the length of the string.
1891
     *
1892
     * This could either be a null-padded string, which doesn't
1893
     * necessarily have a '\0' at the end, or a null-terminated
1894
     * string, with a trailing '\0'.  (Yes, there are cases
1895
     * where you have a string that's both counted and null-
1896
     * terminated.)
1897
     *
1898
     * In the first case, we must allocate a buffer of length
1899
     * "length+1", to make room for a trailing '\0'.
1900
     *
1901
     * In the second case, we don't assume that there is a
1902
     * trailing '\0' there, as the packet might be malformed.
1903
     * (XXX - should we throw an exception if there's no
1904
     * trailing '\0'?)  Therefore, we allocate a buffer of
1905
     * length "length+1", and put in a trailing '\0', just to
1906
     * be safe.
1907
     *
1908
     * (XXX - this would change if we made string values counted
1909
     * rather than null-terminated.)
1910
     */
1911
9.12k
    *ret_length = length;
1912
9.12k
    value = tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1913
9.12k
  }
1914
15.2k
  return value;
1915
15.2k
}
1916
1917
/* For FT_UINT_STRING */
1918
static inline const uint8_t *
1919
get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1920
    tvbuff_t *tvb, unsigned start, int length, unsigned *ret_length,
1921
    const unsigned encoding)
1922
5.77k
{
1923
5.77k
  uint32_t n;
1924
5.77k
  const uint8_t *value;
1925
1926
  /* I believe it's ok if this is called with a NULL tree */
1927
5.77k
  n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1928
5.77k
  value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1929
5.77k
  *ret_length = length + n;
1930
5.77k
  return value;
1931
5.77k
}
1932
1933
/* For FT_STRINGZPAD */
1934
static inline const uint8_t *
1935
get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1936
    int length, unsigned *ret_length, const unsigned encoding)
1937
2.00k
{
1938
  /*
1939
   * XXX - currently, string values are null-
1940
   * terminated, so a "zero-padded" string
1941
   * isn't special.  If we represent string
1942
   * values as something that includes a counted
1943
   * array of bytes, we'll need to strip the
1944
   * trailing NULs.
1945
   */
1946
2.00k
  if (length == -1) {
1947
0
    *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1948
2.00k
  } else {
1949
2.00k
    *ret_length = length;
1950
2.00k
  }
1951
2.00k
  return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1952
2.00k
}
1953
1954
/* For FT_STRINGZTRUNC */
1955
static inline const uint8_t *
1956
get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1957
    int length, unsigned *ret_length, const unsigned encoding)
1958
1.82k
{
1959
  /*
1960
   * XXX - currently, string values are null-
1961
   * terminated, so a "zero-truncated" string
1962
   * isn't special.  If we represent string
1963
   * values as something that includes a counted
1964
   * array of bytes, we'll need to strip everything
1965
   * starting with the terminating NUL.
1966
   */
1967
1.82k
  if (length == -1) {
1968
0
    *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1969
1.82k
  } else {
1970
1.82k
    *ret_length = length;
1971
1.82k
  }
1972
1.82k
  return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1973
1.82k
}
1974
1975
/*
1976
 * Deltas between the epochs for various non-UN*X time stamp formats and
1977
 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1978
 * stamp format.
1979
 */
1980
1981
/*
1982
 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1983
 * XXX - if it's OK if this is unsigned, can we just use
1984
 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1985
 */
1986
129
#define NTP_TIMEDIFF1900TO1970SEC INT64_C(2208988800)
1987
1988
/*
1989
 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1990
 */
1991
402
#define NTP_TIMEDIFF1970TO2036SEC INT64_C(2085978496)
1992
1993
/* this can be called when there is no tree, so tree may be null */
1994
static void
1995
get_time_value(proto_tree *tree, tvbuff_t *tvb, const unsigned start,
1996
         const int length, const unsigned encoding, nstime_t *time_stamp,
1997
         const bool is_relative)
1998
6.10k
{
1999
6.10k
  uint32_t    tmpsecs;
2000
6.10k
  uint64_t    tmp64secs;
2001
6.10k
  uint64_t    todusecs;
2002
2003
6.10k
  switch (encoding) {
2004
2005
1.43k
    case ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN:
2006
      /*
2007
       * If the length is 16, 8-byte seconds, followed
2008
       * by 8-byte fractional time in nanoseconds,
2009
       * both big-endian.
2010
       *
2011
       * If the length is 12, 8-byte seconds, followed
2012
       * by 4-byte fractional time in nanoseconds,
2013
       * both big-endian.
2014
       *
2015
       * If the length is 8, 4-byte seconds, followed
2016
       * by 4-byte fractional time in nanoseconds,
2017
       * both big-endian.
2018
       *
2019
       * For absolute times, the seconds are seconds
2020
       * since the UN*X epoch.
2021
       */
2022
1.43k
      if (length == 16) {
2023
0
        time_stamp->secs  = (time_t)tvb_get_ntoh64(tvb, start);
2024
0
        time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2025
1.43k
      } else if (length == 12) {
2026
0
        time_stamp->secs  = (time_t)tvb_get_ntoh64(tvb, start);
2027
0
        time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2028
1.43k
      } else if (length == 8) {
2029
1.04k
        time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
2030
1.04k
        time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2031
1.04k
      } else if (length == 4) {
2032
        /*
2033
         * Backwards compatibility.
2034
         * ENC_TIME_SECS_NSECS is 0; using
2035
         * ENC_BIG_ENDIAN by itself with a 4-byte
2036
         * time-in-seconds value was done in the
2037
         * past.
2038
         */
2039
365
        time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
2040
365
        time_stamp->nsecs = 0;
2041
365
      } else {
2042
27
        time_stamp->secs  = 0;
2043
27
        time_stamp->nsecs = 0;
2044
27
        report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2045
27
      }
2046
1.43k
      break;
2047
2048
303
    case ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN:
2049
      /*
2050
       * If the length is 16, 8-byte seconds, followed
2051
       * by 8-byte fractional time in nanoseconds,
2052
       * both little-endian.
2053
       *
2054
       * If the length is 12, 8-byte seconds, followed
2055
       * by 4-byte fractional time in nanoseconds,
2056
       * both little-endian.
2057
       *
2058
       * If the length is 8, 4-byte seconds, followed
2059
       * by 4-byte fractional time in nanoseconds,
2060
       * both little-endian.
2061
       *
2062
       * For absolute times, the seconds are seconds
2063
       * since the UN*X epoch.
2064
       */
2065
303
      if (length == 16) {
2066
12
        time_stamp->secs  = (time_t)tvb_get_letoh64(tvb, start);
2067
12
        time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2068
291
      } else if (length == 12) {
2069
0
        time_stamp->secs  = (time_t)tvb_get_letoh64(tvb, start);
2070
0
        time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2071
291
      } else if (length == 8) {
2072
282
        time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
2073
282
        time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2074
282
      } else if (length == 4) {
2075
        /*
2076
         * Backwards compatibility.
2077
         * ENC_TIME_SECS_NSECS is 0; using
2078
         * ENC_LITTLE_ENDIAN by itself with a 4-byte
2079
         * time-in-seconds value was done in the
2080
         * past.
2081
         */
2082
9
        time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
2083
9
        time_stamp->nsecs = 0;
2084
9
      } else {
2085
0
        time_stamp->secs  = 0;
2086
0
        time_stamp->nsecs = 0;
2087
0
        report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2088
0
      }
2089
303
      break;
2090
2091
521
    case ENC_TIME_NTP|ENC_BIG_ENDIAN:
2092
      /*
2093
       * NTP time stamp, big-endian.
2094
       * Only supported for absolute times.
2095
       */
2096
521
      DISSECTOR_ASSERT(!is_relative);
2097
2098
      /* We need a temporary variable here so the unsigned math
2099
       * works correctly (for years > 2036 according to RFC 2030
2100
       * chapter 3).
2101
       *
2102
       * If bit 0 is set, the UTC time is in the range 1968-2036 and
2103
       * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2104
       * If bit 0 is not set, the time is in the range 2036-2104 and
2105
       * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2106
       */
2107
521
      tmpsecs  = tvb_get_ntohl(tvb, start);
2108
521
      if ((tmpsecs & 0x80000000) != 0)
2109
125
        time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2110
396
      else
2111
396
        time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2112
2113
521
      if (length == 8) {
2114
403
        tmp64secs = tvb_get_ntoh64(tvb, start);
2115
403
        if (tmp64secs == 0) {
2116
          //This is "NULL" time
2117
41
          time_stamp->secs = 0;
2118
41
          time_stamp->nsecs = 0;
2119
362
        } else {
2120
          /*
2121
           * Convert 1/2^32s of a second to
2122
           * nanoseconds.
2123
           */
2124
362
          time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2125
362
        }
2126
403
      } else if (length == 4) {
2127
        /*
2128
         * Backwards compatibility.
2129
         */
2130
116
        if (tmpsecs == 0) {
2131
          //This is "NULL" time
2132
7
          time_stamp->secs = 0;
2133
7
        }
2134
116
        time_stamp->nsecs = 0;
2135
116
      } else {
2136
2
        time_stamp->secs  = 0;
2137
2
        time_stamp->nsecs = 0;
2138
2
        report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2139
2
      }
2140
521
      break;
2141
2142
0
    case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
2143
      /*
2144
       * NTP time stamp, little-endian.
2145
       * Only supported for absolute times.
2146
       *
2147
       * NTP doesn't use this, because it's an Internet format
2148
       * and hence big-endian. Any implementation must decide
2149
       * whether the NTP timestamp is a 64-bit unsigned fixed
2150
       * point number (RFC 1305, RFC 4330) or a 64-bit struct
2151
       * with a 32-bit unsigned seconds field followed by a
2152
       * 32-bit fraction field (cf. RFC 5905, which obsoletes
2153
       * the previous two).
2154
       *
2155
       * XXX: We do the latter, but no dissector uses this format.
2156
       * OTOH, ERF timestamps do the former, so perhaps we
2157
       * should switch the interpretation so that packet-erf.c
2158
       * could use this directly? (ENC_TIME_RTPS is this 64-bit
2159
       * struct with two 32-bit fields, but with the UN*X epoch.)
2160
       */
2161
0
      DISSECTOR_ASSERT(!is_relative);
2162
2163
      /* We need a temporary variable here so the unsigned math
2164
       * works correctly (for years > 2036 according to RFC 2030
2165
       * chapter 3).
2166
       *
2167
       * If bit 0 is set, the UTC time is in the range 1968-2036 and
2168
       * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2169
       * If bit 0 is not set, the time is in the range 2036-2104 and
2170
       * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2171
       */
2172
0
      tmpsecs  = tvb_get_letohl(tvb, start);
2173
0
      if ((tmpsecs & 0x80000000) != 0)
2174
0
        time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2175
0
      else
2176
0
        time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2177
2178
0
      if (length == 8) {
2179
0
        tmp64secs = tvb_get_letoh64(tvb, start);
2180
0
        if (tmp64secs == 0) {
2181
          //This is "NULL" time
2182
0
          time_stamp->secs = 0;
2183
0
          time_stamp->nsecs = 0;
2184
0
        } else {
2185
          /*
2186
           * Convert 1/2^32s of a second to
2187
           * nanoseconds.
2188
           */
2189
0
          time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2190
0
        }
2191
0
      } else if (length == 4) {
2192
        /*
2193
         * Backwards compatibility.
2194
         */
2195
0
        if (tmpsecs == 0) {
2196
          //This is "NULL" time
2197
0
          time_stamp->secs = 0;
2198
0
        }
2199
0
        time_stamp->nsecs = 0;
2200
0
      } else {
2201
0
        time_stamp->secs  = 0;
2202
0
        time_stamp->nsecs = 0;
2203
0
        report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2204
0
      }
2205
0
      break;
2206
2207
0
    case ENC_TIME_TOD|ENC_BIG_ENDIAN:
2208
      /*
2209
       * S/3x0 and z/Architecture TOD clock time stamp,
2210
       * big-endian.  The epoch is January 1, 1900,
2211
       * 00:00:00 (proleptic?) UTC.
2212
       *
2213
       * Only supported for absolute times.
2214
       */
2215
0
      DISSECTOR_ASSERT(!is_relative);
2216
0
      DISSECTOR_ASSERT(length == 8);
2217
2218
0
      if (length == 8) {
2219
0
        todusecs  = tvb_get_ntoh64(tvb, start) >> 12;
2220
0
        time_stamp->secs = (time_t)((todusecs  / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC);
2221
0
        time_stamp->nsecs = (int)((todusecs  % 1000000) * 1000);
2222
0
      } else {
2223
0
        time_stamp->secs  = 0;
2224
0
        time_stamp->nsecs = 0;
2225
0
        report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2226
0
      }
2227
0
      break;
2228
2229
0
    case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
2230
      /*
2231
       * S/3x0 and z/Architecture TOD clock time stamp,
2232
       * little-endian.  The epoch is January 1, 1900,
2233
       * 00:00:00 (proleptic?) UTC.
2234
       *
2235
       * Only supported for absolute times.
2236
       */
2237
0
      DISSECTOR_ASSERT(!is_relative);
2238
2239
0
      if (length == 8) {
2240
0
        todusecs  = tvb_get_letoh64(tvb, start) >> 12 ;
2241
0
        time_stamp->secs = (time_t)((todusecs  / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC);
2242
0
        time_stamp->nsecs = (int)((todusecs  % 1000000) * 1000);
2243
0
      } else {
2244
0
        time_stamp->secs  = 0;
2245
0
        time_stamp->nsecs = 0;
2246
0
        report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2247
0
      }
2248
0
      break;
2249
2250
120
    case ENC_TIME_RTPS|ENC_BIG_ENDIAN:
2251
      /*
2252
       * Time stamp using the same seconds/fraction format
2253
       * as NTP, but with the origin of the time stamp being
2254
       * the UNIX epoch rather than the NTP epoch; big-
2255
       * endian.
2256
       *
2257
       * Only supported for absolute times.
2258
       */
2259
120
      DISSECTOR_ASSERT(!is_relative);
2260
2261
120
      if (length == 8) {
2262
120
        time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2263
        /*
2264
         * Convert 1/2^32s of a second to nanoseconds.
2265
         */
2266
120
        time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2267
120
      } else {
2268
0
        time_stamp->secs  = 0;
2269
0
        time_stamp->nsecs = 0;
2270
0
        report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2271
0
      }
2272
120
      break;
2273
2274
170
    case ENC_TIME_RTPS|ENC_LITTLE_ENDIAN:
2275
      /*
2276
       * Time stamp using the same seconds/fraction format
2277
       * as NTP, but with the origin of the time stamp being
2278
       * the UNIX epoch rather than the NTP epoch; little-
2279
       * endian.
2280
       *
2281
       * Only supported for absolute times.
2282
       *
2283
       * The RTPS specification explicitly supports Little
2284
       * Endian encoding. In one place, it states that its
2285
       * Time_t representation "is the one defined by ...
2286
       * RFC 1305", but in another explicitly defines it as
2287
       * a struct consisting of an 32 bit unsigned seconds
2288
       * field and a 32 bit unsigned fraction field, not a 64
2289
       * bit fixed point, so we do that here.
2290
       * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2291
       */
2292
170
      DISSECTOR_ASSERT(!is_relative);
2293
2294
170
      if (length == 8) {
2295
170
        time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2296
        /*
2297
         * Convert 1/2^32s of a second to nanoseconds.
2298
         */
2299
170
        time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2300
170
      } else {
2301
0
        time_stamp->secs  = 0;
2302
0
        time_stamp->nsecs = 0;
2303
0
        report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2304
0
      }
2305
170
      break;
2306
2307
74
    case ENC_TIME_MIP6 | ENC_BIG_ENDIAN:
2308
      /*
2309
      * MIP6 time stamp, big-endian.
2310
      * A 64-bit unsigned integer field containing a timestamp.  The
2311
      * value indicates the number of seconds since January 1, 1970,
2312
      * 00:00 UTC, by using a fixed point format.  In this format, the
2313
      * integer number of seconds is contained in the first 48 bits of
2314
      * the field, and the remaining 16 bits indicate the number of
2315
      * 1/65536 fractions of a second.
2316
2317
      * Only supported for absolute times.
2318
      */
2319
74
      DISSECTOR_ASSERT(!is_relative);
2320
2321
74
      if (length == 8) {
2322
        /* We need a temporary variable here so the casting and fractions
2323
        * of a second work correctly.
2324
        */
2325
74
        tmp64secs = tvb_get_ntoh48(tvb, start);
2326
74
        tmpsecs = tvb_get_ntohs(tvb, start + 6);
2327
74
        tmpsecs <<= 16;
2328
2329
74
        if ((tmp64secs == 0) && (tmpsecs == 0)) {
2330
          //This is "NULL" time
2331
2
          time_stamp->secs = 0;
2332
2
          time_stamp->nsecs = 0;
2333
72
        } else {
2334
72
          time_stamp->secs = (time_t)tmp64secs;
2335
72
          time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2336
72
        }
2337
74
      } else {
2338
0
        time_stamp->secs = 0;
2339
0
        time_stamp->nsecs = 0;
2340
0
        report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2341
0
      }
2342
74
      break;
2343
2344
84
    case ENC_TIME_SECS_USECS|ENC_BIG_ENDIAN:
2345
      /*
2346
       * If the length is 16, 8-byte seconds, followed
2347
       * by 8-byte fractional time in microseconds,
2348
       * both big-endian.
2349
       *
2350
       * If the length is 12, 8-byte seconds, followed
2351
       * by 4-byte fractional time in microseconds,
2352
       * both big-endian.
2353
       *
2354
       * If the length is 8, 4-byte seconds, followed
2355
       * by 4-byte fractional time in microseconds,
2356
       * both big-endian.
2357
       *
2358
       * For absolute times, the seconds are seconds
2359
       * since the UN*X epoch.
2360
       */
2361
84
      if (length == 16) {
2362
0
        time_stamp->secs  = (time_t)tvb_get_ntoh64(tvb, start);
2363
0
        time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2364
84
      } else if (length == 12) {
2365
0
        time_stamp->secs  = (time_t)tvb_get_ntoh64(tvb, start);
2366
0
        time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2367
84
      } else if (length == 8) {
2368
81
        time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
2369
81
        time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2370
81
      } else {
2371
3
        time_stamp->secs  = 0;
2372
3
        time_stamp->nsecs = 0;
2373
3
        report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2374
3
      }
2375
84
      break;
2376
2377
0
    case ENC_TIME_SECS_USECS|ENC_LITTLE_ENDIAN:
2378
      /*
2379
       * If the length is 16, 8-byte seconds, followed
2380
       * by 8-byte fractional time in microseconds,
2381
       * both little-endian.
2382
       *
2383
       * If the length is 12, 8-byte seconds, followed
2384
       * by 4-byte fractional time in microseconds,
2385
       * both little-endian.
2386
       *
2387
       * If the length is 8, 4-byte seconds, followed
2388
       * by 4-byte fractional time in microseconds,
2389
       * both little-endian.
2390
       *
2391
       * For absolute times, the seconds are seconds
2392
       * since the UN*X epoch.
2393
       */
2394
0
      if (length == 16) {
2395
0
        time_stamp->secs  = (time_t)tvb_get_letoh64(tvb, start);
2396
0
        time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2397
0
      } else if (length == 12) {
2398
0
        time_stamp->secs  = (time_t)tvb_get_letoh64(tvb, start);
2399
0
        time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2400
0
      } else if (length == 8) {
2401
0
        time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
2402
0
        time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2403
0
      } else {
2404
0
        time_stamp->secs  = 0;
2405
0
        time_stamp->nsecs = 0;
2406
0
        report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2407
0
      }
2408
0
      break;
2409
2410
1.42k
    case ENC_TIME_SECS|ENC_BIG_ENDIAN:
2411
1.47k
    case ENC_TIME_SECS|ENC_LITTLE_ENDIAN:
2412
      /*
2413
       * Seconds, 1 to 8 bytes.
2414
       * For absolute times, it's seconds since the
2415
       * UN*X epoch.
2416
       */
2417
1.47k
      if (length >= 1 && length <= 8) {
2418
1.47k
        time_stamp->secs  = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2419
1.47k
        time_stamp->nsecs = 0;
2420
1.47k
      } else {
2421
0
        time_stamp->secs  = 0;
2422
0
        time_stamp->nsecs = 0;
2423
0
        report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2424
0
      }
2425
1.47k
      break;
2426
2427
23
    case ENC_TIME_MSECS|ENC_BIG_ENDIAN:
2428
23
    case ENC_TIME_MSECS|ENC_LITTLE_ENDIAN:
2429
      /*
2430
       * Milliseconds, 1 to 8 bytes.
2431
       * For absolute times, it's milliseconds since the
2432
       * UN*X epoch.
2433
       */
2434
23
      if (length >= 1 && length <= 8) {
2435
23
        uint64_t msecs;
2436
2437
23
        msecs = get_uint64_value(tree, tvb, start, length, encoding);
2438
23
        time_stamp->secs  = (time_t)(msecs / 1000);
2439
23
        time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2440
23
      } else {
2441
0
        time_stamp->secs  = 0;
2442
0
        time_stamp->nsecs = 0;
2443
0
        report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2444
0
      }
2445
23
      break;
2446
2447
1
    case ENC_TIME_USECS|ENC_BIG_ENDIAN:
2448
228
    case ENC_TIME_USECS|ENC_LITTLE_ENDIAN:
2449
      /*
2450
      * Microseconds, 1 to 8 bytes.
2451
      * For absolute times, it's microseconds since the
2452
      * UN*X epoch.
2453
      */
2454
228
      if (length >= 1 && length <= 8) {
2455
228
        uint64_t usecs;
2456
2457
228
        usecs = get_uint64_value(tree, tvb, start, length, encoding);
2458
228
        time_stamp->secs  = (time_t)(usecs / 1000000);
2459
228
        time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2460
228
      } else {
2461
0
        time_stamp->secs  = 0;
2462
0
        time_stamp->nsecs = 0;
2463
0
        report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2464
0
      }
2465
228
      break;
2466
2467
1
    case ENC_TIME_NSECS|ENC_BIG_ENDIAN:
2468
953
    case ENC_TIME_NSECS|ENC_LITTLE_ENDIAN:
2469
      /*
2470
       * nanoseconds, 1 to 8 bytes.
2471
       * For absolute times, it's nanoseconds since the
2472
       * UN*X epoch.
2473
       */
2474
2475
953
      if (length >= 1 && length <= 8) {
2476
953
        uint64_t nsecs;
2477
2478
953
        nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2479
953
        time_stamp->secs  = (time_t)(nsecs / 1000000000);
2480
953
        time_stamp->nsecs = (int)(nsecs % 1000000000);
2481
953
      } else {
2482
0
        time_stamp->secs  = 0;
2483
0
        time_stamp->nsecs = 0;
2484
0
        report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2485
0
      }
2486
953
      break;
2487
2488
13
    case ENC_TIME_RFC_3971|ENC_BIG_ENDIAN:
2489
      /*
2490
       * 1/64ths of a second since the UN*X epoch,
2491
       * big-endian.
2492
       *
2493
       * Only supported for absolute times.
2494
       */
2495
13
      DISSECTOR_ASSERT(!is_relative);
2496
2497
13
      if (length == 8) {
2498
        /*
2499
         * The upper 48 bits are seconds since the
2500
         * UN*X epoch.
2501
         */
2502
13
        time_stamp->secs  = (time_t)tvb_get_ntoh48(tvb, start);
2503
        /*
2504
         * The lower 16 bits are 1/2^16s of a second;
2505
         * convert them to nanoseconds.
2506
         *
2507
         * XXX - this may give the impression of higher
2508
         * precision than you actually get.
2509
         */
2510
13
        time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2511
13
      } else {
2512
0
        time_stamp->secs  = 0;
2513
0
        time_stamp->nsecs = 0;
2514
0
        report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2515
0
      }
2516
13
      break;
2517
2518
0
    case ENC_TIME_RFC_3971|ENC_LITTLE_ENDIAN:
2519
      /*
2520
       * 1/64ths of a second since the UN*X epoch,
2521
       * little-endian.
2522
       *
2523
       * Only supported for absolute times.
2524
       */
2525
0
      DISSECTOR_ASSERT(!is_relative);
2526
2527
0
      if (length == 8) {
2528
        /*
2529
         * XXX - this is assuming that, if anybody
2530
         * were ever to use this format - RFC 3971
2531
         * doesn't, because that's an Internet
2532
         * protocol, and those use network byte
2533
         * order, i.e. big-endian - they'd treat it
2534
         * as a 64-bit count of 1/2^16s of a second,
2535
         * putting the upper 48 bits at the end.
2536
         *
2537
         * The lower 48 bits are seconds since the
2538
         * UN*X epoch.
2539
         */
2540
0
        time_stamp->secs  = (time_t)tvb_get_letoh48(tvb, start+2);
2541
        /*
2542
         * The upper 16 bits are 1/2^16s of a second;
2543
         * convert them to nanoseconds.
2544
         *
2545
         * XXX - this may give the impression of higher
2546
         * precision than you actually get.
2547
         */
2548
0
        time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2549
0
      } else {
2550
0
        time_stamp->secs  = 0;
2551
0
        time_stamp->nsecs = 0;
2552
0
        report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2553
0
      }
2554
0
      break;
2555
2556
6
    case ENC_TIME_SECS_NTP|ENC_BIG_ENDIAN:
2557
      /*
2558
       * NTP time stamp, with 1-second resolution (i.e.,
2559
       * seconds since the NTP epoch), big-endian.
2560
       * Only supported for absolute times.
2561
       */
2562
6
      DISSECTOR_ASSERT(!is_relative);
2563
2564
6
      if (length == 4) {
2565
        /*
2566
        * We need a temporary variable here so the unsigned math
2567
        * works correctly (for years > 2036 according to RFC 2030
2568
        * chapter 3).
2569
        *
2570
        * If bit 0 is set, the UTC time is in the range 1968-2036 and
2571
        * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2572
        * If bit 0 is not set, the time is in the range 2036-2104 and
2573
        * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2574
        */
2575
6
        tmpsecs  = tvb_get_ntohl(tvb, start);
2576
6
        if ((tmpsecs & 0x80000000) != 0)
2577
2
          time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2578
4
        else
2579
4
          time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2580
6
        time_stamp->nsecs = 0;
2581
6
      } else {
2582
0
        time_stamp->secs  = 0;
2583
0
        time_stamp->nsecs = 0;
2584
0
        report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2585
0
      }
2586
6
      break;
2587
2588
0
    case ENC_TIME_SECS_NTP|ENC_LITTLE_ENDIAN:
2589
      /*
2590
       * NTP time stamp, with 1-second resolution (i.e.,
2591
       * seconds since the NTP epoch), little-endian.
2592
       * Only supported for absolute times.
2593
       */
2594
0
      DISSECTOR_ASSERT(!is_relative);
2595
2596
      /*
2597
       * We need a temporary variable here so the unsigned math
2598
       * works correctly (for years > 2036 according to RFC 2030
2599
       * chapter 3).
2600
       *
2601
       * If bit 0 is set, the UTC time is in the range 1968-2036 and
2602
       * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2603
       * If bit 0 is not set, the time is in the range 2036-2104 and
2604
       * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2605
       */
2606
0
      if (length == 4) {
2607
0
        tmpsecs  = tvb_get_letohl(tvb, start);
2608
0
        if ((tmpsecs & 0x80000000) != 0)
2609
0
          time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2610
0
        else
2611
0
          time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2612
0
        time_stamp->nsecs = 0;
2613
0
      } else {
2614
0
        time_stamp->secs  = 0;
2615
0
        time_stamp->nsecs = 0;
2616
0
        report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2617
0
      }
2618
0
      break;
2619
2620
4
    case ENC_TIME_MSEC_NTP | ENC_BIG_ENDIAN:
2621
      /*
2622
      * Milliseconds, 6 to 8 bytes.
2623
      * For absolute times, it's milliseconds since the
2624
      * NTP epoch.
2625
      *
2626
      * ETSI TS 129.274 8.119 defines this as:
2627
      * "a 48 bit unsigned integer in network order format
2628
      * ...encoded as the number of milliseconds since
2629
      * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2630
      * rounded value of 1000 x the value of the 64-bit
2631
      * timestamp (Seconds + (Fraction / (1<<32))) defined
2632
      * in clause 6 of IETF RFC 5905."
2633
      *
2634
      * Taken literally, the part after "i.e." would
2635
      * mean that the value rolls over before reaching
2636
      * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2637
      * when the 64 bit timestamp rolls over, and we have
2638
      * to pick an NTP Era equivalence class to support
2639
      * (such as 1968-01-20 to 2104-02-06).
2640
      *
2641
      * OTOH, the extra room might be used to store Era
2642
      * information instead, in which case times until
2643
      * 10819-08-03 can be represented with 6 bytes without
2644
      * ambiguity. We handle both implementations, and assume
2645
      * that times before 1968-01-20 are not represented.
2646
      *
2647
      * Only 6 bytes or more makes sense as an absolute
2648
      * time. 5 bytes or fewer could express a span of
2649
      * less than 35 years, either 1900-1934 or 2036-2070.
2650
      */
2651
4
      if (length >= 6 && length <= 8) {
2652
4
        uint64_t msecs;
2653
2654
4
        msecs = get_uint64_value(tree, tvb, start, length, encoding);
2655
4
        tmp64secs = (msecs / 1000);
2656
        /*
2657
         * Assume that times in the first half of NTP
2658
         * Era 0 really represent times in the NTP
2659
         * Era 1.
2660
         */
2661
4
        if (tmp64secs >= 0x80000000)
2662
2
          time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC);
2663
2
        else
2664
2
          time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC);
2665
4
        time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2666
4
      }
2667
0
      else {
2668
0
        time_stamp->secs  = 0;
2669
0
        time_stamp->nsecs = 0;
2670
0
        report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2671
0
      }
2672
4
      break;
2673
2674
0
    case ENC_TIME_MP4_FILE_SECS|ENC_BIG_ENDIAN:
2675
      /*
2676
       * MP4 file time stamps, big-endian.
2677
       * Only supported for absolute times.
2678
       */
2679
0
      DISSECTOR_ASSERT(!is_relative);
2680
2681
0
      if (length == 8) {
2682
0
        tmp64secs  = tvb_get_ntoh64(tvb, start);
2683
0
        time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC);
2684
0
        time_stamp->nsecs = 0;
2685
0
      } else if (length == 4) {
2686
0
        tmpsecs  = tvb_get_ntohl(tvb, start);
2687
0
        time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC);
2688
0
        time_stamp->nsecs = 0;
2689
0
      } else {
2690
0
        time_stamp->secs  = 0;
2691
0
        time_stamp->nsecs = 0;
2692
0
        report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2693
0
      }
2694
0
      break;
2695
2696
0
    case ENC_TIME_ZBEE_ZCL | ENC_BIG_ENDIAN:
2697
      /*
2698
       * Zigbee ZCL time stamps, big-endian.
2699
       * Only supported for absolute times.
2700
       */
2701
0
      DISSECTOR_ASSERT(!is_relative);
2702
2703
0
      if (length == 8) {
2704
0
        tmp64secs  = tvb_get_ntoh64(tvb, start);
2705
0
        if (ckd_add(&time_stamp->secs, tmp64secs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)) {
2706
          /* There are several other possible choices for what to do
2707
           * with overflow; make sure to coordinate with whatever
2708
           * packet-zbee-zcl.h does. */
2709
0
          time_stamp->secs = TIME_T_MAX;
2710
0
        }
2711
0
        time_stamp->nsecs = 0;
2712
0
      } else if (length == 4) {
2713
0
        tmpsecs  = tvb_get_ntohl(tvb, start);
2714
0
        if (ckd_add(&time_stamp->secs, tmpsecs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)) {
2715
0
          time_stamp->secs = TIME_T_MAX;
2716
0
        }
2717
0
        time_stamp->nsecs = 0;
2718
0
      } else {
2719
0
        time_stamp->secs  = 0;
2720
0
        time_stamp->nsecs = 0;
2721
0
        report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2722
0
      }
2723
0
      break;
2724
2725
698
    case ENC_TIME_ZBEE_ZCL | ENC_LITTLE_ENDIAN:
2726
      /*
2727
       * Zigbee ZCL time stamps, little-endian.
2728
       * Only supported for absolute times.
2729
       */
2730
698
      DISSECTOR_ASSERT(!is_relative);
2731
2732
698
      if (length == 8) {
2733
0
        tmp64secs  = tvb_get_letoh64(tvb, start);
2734
0
        if (ckd_add(&time_stamp->secs, tmp64secs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)) {
2735
0
          time_stamp->secs = TIME_T_MAX;
2736
0
        }
2737
0
        time_stamp->nsecs = 0;
2738
698
      } else if (length == 4) {
2739
698
        tmpsecs  = tvb_get_letohl(tvb, start);
2740
698
        if (ckd_add(&time_stamp->secs, tmpsecs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)) {
2741
0
          time_stamp->secs = TIME_T_MAX;
2742
0
        }
2743
698
        time_stamp->nsecs = 0;
2744
698
      } else {
2745
0
        time_stamp->secs  = 0;
2746
0
        time_stamp->nsecs = 0;
2747
0
        report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2748
0
      }
2749
698
      break;
2750
2751
0
    case ENC_TIME_WINDOWS | ENC_BIG_ENDIAN:
2752
      /*
2753
       * WINDOWS FILETIME, big-endian.
2754
       * Only supported for absolute times.
2755
       * A FILETIME is a struct with the low 32-bits followed
2756
       * by the high 32-bits:
2757
       * https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
2758
       * There exist cases where the value is stored in a
2759
       * 64-bit integer:
2760
       * (See epan/dissectors/pidl/samr/samr.idl "NTTIME_hyper last_password_change;"
2761
       * which is confirmed as "LARGE_INTEGER PasswordLastSet;" in
2762
       * https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/1cd138b9-cc1b-4706-b115-49e53189e32e
2763
       * That doesn't make a difference when retrieving little-endian,
2764
       * because tvb_get_letoh64 handles unaligned accesses and it's
2765
       * otherwise the same. However, for big-endian, it does matter,
2766
       * analogous to the ENC_TIME_NTP little-endian case. We use the
2767
       * struct version, but that means that this MUST NOT be used
2768
       * for dissect_nttime_hyper in packet-windows-common.h, at
2769
       * least
2770
       */
2771
0
      DISSECTOR_ASSERT(!is_relative);
2772
2773
0
      if (length == 8) {
2774
0
        tmp64secs = tvb_get_ntoh64(tvb, start); // Really 100-ns units
2775
0
        if (!filetime_to_nstime(time_stamp, tmp64secs)) {
2776
          // With 32-bit time_t, this could overflow in
2777
          // either direction. We should probably add some
2778
          // kind of time overflow expert item to all
2779
          // encodings.
2780
0
          time_stamp->secs = TIME_T_MAX;
2781
0
          time_stamp->nsecs = 0;
2782
0
        }
2783
0
      } else {
2784
0
        time_stamp->secs  = 0;
2785
0
        time_stamp->nsecs = 0;
2786
0
        report_type_length_mismatch(tree, "an NTFS FILETIME time stamp", length, (length < 8));
2787
0
      }
2788
0
      break;
2789
2790
0
    case ENC_TIME_WINDOWS | ENC_LITTLE_ENDIAN:
2791
      /*
2792
       * WINDOWS FILETIME, big-endian.
2793
       * Only supported for absolute times.
2794
       * https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
2795
       */
2796
0
      DISSECTOR_ASSERT(!is_relative);
2797
2798
0
      if (length == 8) {
2799
0
        tmp64secs = tvb_get_letoh64(tvb, start); // Really 100-ns units
2800
0
        if (!filetime_to_nstime(time_stamp, tmp64secs)) {
2801
          // With 32-bit time_t, this could overflow in
2802
          // either direction. We should probably add some
2803
          // kind of time overflow expert item to all
2804
          // encodings.
2805
0
          time_stamp->secs = TIME_T_MAX;
2806
0
          time_stamp->nsecs = 0;
2807
0
        }
2808
0
      } else {
2809
0
        time_stamp->secs  = 0;
2810
0
        time_stamp->nsecs = 0;
2811
0
        report_type_length_mismatch(tree, "an NTFS FILETIME time stamp", length, (length < 8));
2812
0
      }
2813
0
      break;
2814
0
    default:
2815
0
      DISSECTOR_ASSERT_NOT_REACHED();
2816
0
      break;
2817
6.10k
  }
2818
6.10k
}
2819
2820
static void
2821
tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2822
74.6M
{
2823
74.6M
  const header_field_info *hfinfo = fi->hfinfo;
2824
2825
74.6M
  if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2826
248
    GPtrArray *ptrs = NULL;
2827
2828
248
    if (tree_data->interesting_hfids == NULL) {
2829
      /* Initialize the hash because we now know that it is needed */
2830
2
      tree_data->interesting_hfids =
2831
2
        g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
2832
246
    } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2833
224
      ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2834
224
             GINT_TO_POINTER(hfinfo->id));
2835
224
    }
2836
2837
248
    if (!ptrs) {
2838
      /* First element triggers the creation of pointer array */
2839
248
      ptrs = g_ptr_array_new();
2840
248
      g_hash_table_insert(tree_data->interesting_hfids,
2841
248
              GINT_TO_POINTER(hfinfo->id), ptrs);
2842
248
    }
2843
2844
248
    g_ptr_array_add(ptrs, fi);
2845
248
  }
2846
74.6M
}
2847
2848
2849
/*
2850
 * Validates that field length bytes are available starting from
2851
 * start (pos/neg). Throws an exception if they aren't.
2852
 */
2853
static void
2854
test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2855
      unsigned start, int length, const unsigned encoding)
2856
47.6M
{
2857
47.6M
  int size = length;
2858
2859
47.6M
  if (!tvb)
2860
1.02M
    return;
2861
2862
46.6M
  if ((hfinfo->type == FT_STRINGZ) ||
2863
46.5M
      ((encoding & ENC_VARINT_MASK) &&
2864
57.1k
       (FT_IS_UINT(hfinfo->type) || FT_IS_INT(hfinfo->type)))) {
2865
    /* If we're fetching until the end of the TVB, only validate
2866
     * that the offset is within range.
2867
     */
2868
57.1k
    if (length == -1)
2869
683
      size = 0;
2870
57.1k
  }
2871
2872
46.6M
  tvb_ensure_bytes_exist(tvb, start, size);
2873
46.6M
}
2874
2875
static void
2876
detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2877
130k
{
2878
130k
  bool found_stray_character = false;
2879
2880
130k
  if (!string)
2881
0
    return;
2882
2883
130k
  switch (encoding & ENC_CHARENCODING_MASK) {
2884
95.8k
    case ENC_ASCII:
2885
119k
    case ENC_UTF_8:
2886
214k
      for (int i = (int)strlen(string); i < length; i++) {
2887
115k
        if (string[i] != '\0') {
2888
20.8k
          found_stray_character = true;
2889
20.8k
          break;
2890
20.8k
        }
2891
115k
      }
2892
119k
      break;
2893
2894
10.6k
    default:
2895
10.6k
      break;
2896
130k
  }
2897
2898
130k
  if (found_stray_character) {
2899
20.8k
    expert_add_info(NULL, pi, &ei_string_trailing_characters);
2900
20.8k
  }
2901
130k
}
2902
2903
/* Add an item to a proto_tree, using the text label registered to that item;
2904
   the item is extracted from the tvbuff handed to it. */
2905
static proto_item *
2906
proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2907
        tvbuff_t *tvb, unsigned start, int length,
2908
        unsigned encoding)
2909
20.3M
{
2910
20.3M
  proto_item *pi;
2911
20.3M
  uint32_t      value, n;
2912
20.3M
  uint64_t      value64;
2913
20.3M
  ws_in4_addr ipv4_value;
2914
20.3M
  float     floatval;
2915
20.3M
  double      doubleval;
2916
20.3M
  const char *stringval = NULL;
2917
20.3M
  nstime_t    time_stamp;
2918
20.3M
  bool        length_error;
2919
20.3M
  unsigned    item_length;
2920
2921
  // new_fi->value is allocated from the packet-scoped pool (see
2922
  // new_field_info()), so if a tvbuff accessor below throws before the
2923
  // node is added to the tree the fvalue_t structure is still reclaimed
2924
  // when the pool is freed; no explicit cleanup handler is needed. This
2925
  // relies on the invariant that the type-specific data an fvalue owns
2926
  // (byte arrays, string buffers, ...) is only allocated *after* the
2927
  // throwing tvbuff read that produced it succeeds, so nothing that would
2928
  // need fvalue_cleanup() is ever leaked on the exception path.
2929
20.3M
  switch (new_fi->hfinfo->type) {
2930
6.25M
    case FT_NONE:
2931
      /* no value to set for FT_NONE */
2932
6.25M
      break;
2933
2934
1.52M
    case FT_PROTOCOL:
2935
      /* Set the protocol_tvb via the start offset, but include
2936
       * rest of the ds_tvb so that if finfo_set_len is called
2937
       * later it can be lengthened as much as possible. */
2938
1.52M
      proto_tree_set_protocol_tvb(new_fi, new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL, new_fi->hfinfo->name, length);
2939
1.52M
      break;
2940
2941
1.49M
    case FT_BYTES:
2942
1.49M
      proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2943
1.49M
      break;
2944
2945
3.06k
    case FT_UINT_BYTES:
2946
3.06k
      n = get_uint_value(tree, tvb, start, length, encoding);
2947
3.06k
      proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2948
2949
      /* Instead of calling proto_item_set_len(), since we don't yet
2950
       * have a proto_item, we set the field_info's length ourselves. */
2951
3.06k
      new_fi->length = n + length;
2952
3.06k
      break;
2953
2954
1.80M
    case FT_BOOLEAN:
2955
      /*
2956
       * Map all non-zero values to little-endian for
2957
       * backwards compatibility.
2958
       */
2959
1.80M
      if (encoding)
2960
216k
        encoding = ENC_LITTLE_ENDIAN;
2961
1.80M
      proto_tree_set_boolean(new_fi,
2962
1.80M
        get_uint64_value(tree, tvb, start, length, encoding));
2963
1.80M
      break;
2964
2965
3.23k
    case FT_CHAR:
2966
    /* XXX - make these just FT_UINT? */
2967
4.94M
    case FT_UINT8:
2968
7.00M
    case FT_UINT16:
2969
7.21M
    case FT_UINT24:
2970
8.46M
    case FT_UINT32:
2971
8.46M
      if (encoding & ENC_VARINT_MASK) {
2972
55
        new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2973
55
        value = (uint32_t)value64;
2974
55
        if (!(encoding & ENC_VARINT_QUIC)) {
2975
55
          new_fi->flags |= FI_VARINT;
2976
55
        }
2977
55
      }
2978
8.46M
      else {
2979
        /*
2980
         * Map all non-zero values to little-endian for
2981
         * backwards compatibility.
2982
         */
2983
8.46M
        if (encoding)
2984
1.17M
          encoding = ENC_LITTLE_ENDIAN;
2985
2986
8.46M
        value = get_uint_value(tree, tvb, start, length, encoding);
2987
8.46M
      }
2988
8.46M
      proto_tree_set_uint(new_fi, value);
2989
8.46M
      break;
2990
2991
27.2k
    case FT_UINT40:
2992
29.6k
    case FT_UINT48:
2993
29.7k
    case FT_UINT56:
2994
90.9k
    case FT_UINT64:
2995
90.9k
      if (encoding & ENC_VARINT_MASK) {
2996
440
        new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2997
440
        if (!(encoding & ENC_VARINT_QUIC)) {
2998
440
          new_fi->flags |= FI_VARINT;
2999
440
        }
3000
440
      }
3001
90.5k
      else {
3002
        /*
3003
         * Map all other non-zero values to little-endian for
3004
         * backwards compatibility.
3005
         */
3006
90.5k
        if (encoding)
3007
33.3k
          encoding = ENC_LITTLE_ENDIAN;
3008
3009
90.5k
        value64 = get_uint64_value(tree, tvb, start, length, encoding);
3010
90.5k
      }
3011
90.9k
      proto_tree_set_uint64(new_fi, value64);
3012
90.9k
      break;
3013
3014
    /* XXX - make these just FT_INT? */
3015
103k
    case FT_INT8:
3016
147k
    case FT_INT16:
3017
149k
    case FT_INT24:
3018
176k
    case FT_INT32:
3019
      /*
3020
       * Map all non-zero values to little-endian for
3021
       * backwards compatibility.
3022
       */
3023
176k
      if (encoding)
3024
25.5k
        encoding = ENC_LITTLE_ENDIAN;
3025
176k
      proto_tree_set_int(new_fi,
3026
176k
        get_int_value(tree, tvb, start, length, encoding));
3027
176k
      break;
3028
3029
0
    case FT_INT40:
3030
1
    case FT_INT48:
3031
1
    case FT_INT56:
3032
8.90k
    case FT_INT64:
3033
      /*
3034
       * Map all non-zero values to little-endian for
3035
       * backwards compatibility.
3036
       */
3037
8.90k
      if (encoding)
3038
4.67k
        encoding = ENC_LITTLE_ENDIAN;
3039
8.90k
      proto_tree_set_int64(new_fi,
3040
8.90k
        get_int64_value(tree, tvb, start, length, encoding));
3041
8.90k
      break;
3042
3043
33.3k
    case FT_IPv4:
3044
      /*
3045
       * Map all non-zero values to little-endian for
3046
       * backwards compatibility.
3047
       */
3048
33.3k
      if (encoding)
3049
325
        encoding = ENC_LITTLE_ENDIAN;
3050
33.3k
      if (length != FT_IPv4_LEN) {
3051
25
        length_error = length < FT_IPv4_LEN ? true : false;
3052
25
        report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
3053
25
      }
3054
33.3k
      ipv4_value = tvb_get_ipv4(tvb, start);
3055
      /*
3056
       * NOTE: to support code written when
3057
       * proto_tree_add_item() took a bool as its
3058
       * last argument, with false meaning "big-endian"
3059
       * and true meaning "little-endian", we treat any
3060
       * non-zero value of "encoding" as meaning
3061
       * "little-endian".
3062
       */
3063
33.3k
      proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(ipv4_value) : ipv4_value);
3064
33.3k
      break;
3065
3066
1.18k
    case FT_IPXNET:
3067
1.18k
      if (length != FT_IPXNET_LEN) {
3068
0
        length_error = length < FT_IPXNET_LEN ? true : false;
3069
0
        report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
3070
0
      }
3071
1.18k
      proto_tree_set_ipxnet(new_fi,
3072
1.18k
        get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
3073
1.18k
      break;
3074
3075
116k
    case FT_IPv6:
3076
116k
      if (length != FT_IPv6_LEN) {
3077
9
        length_error = length < FT_IPv6_LEN ? true : false;
3078
9
        report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
3079
9
      }
3080
116k
      proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
3081
116k
      break;
3082
3083
985
    case FT_FCWWN:
3084
985
      if (length != FT_FCWWN_LEN) {
3085
0
        length_error = length < FT_FCWWN_LEN ? true : false;
3086
0
        report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
3087
0
      }
3088
985
      proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
3089
985
      break;
3090
3091
1.26k
    case FT_AX25:
3092
1.26k
      if (length != 7) {
3093
0
        length_error = length < 7 ? true : false;
3094
0
        report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3095
0
      }
3096
1.26k
      proto_tree_set_ax25_tvb(new_fi, tvb, start);
3097
1.26k
      break;
3098
3099
557
    case FT_VINES:
3100
557
      if (length != VINES_ADDR_LEN) {
3101
0
        length_error = length < VINES_ADDR_LEN ? true : false;
3102
0
        report_type_length_mismatch(tree, "a Vines address", length, length_error);
3103
0
      }
3104
557
      proto_tree_set_vines_tvb(new_fi, tvb, start);
3105
557
      break;
3106
3107
223k
    case FT_ETHER:
3108
223k
      if (length != FT_ETHER_LEN) {
3109
94
        length_error = length < FT_ETHER_LEN ? true : false;
3110
94
        report_type_length_mismatch(tree, "a MAC address", length, length_error);
3111
94
      }
3112
223k
      proto_tree_set_ether_tvb(new_fi, tvb, start);
3113
223k
      break;
3114
3115
10.3k
    case FT_EUI64:
3116
      /*
3117
       * Map all non-zero values to little-endian for
3118
       * backwards compatibility.
3119
       */
3120
10.3k
      if (encoding)
3121
10.2k
        encoding = ENC_LITTLE_ENDIAN;
3122
10.3k
      if (length != FT_EUI64_LEN) {
3123
0
        length_error = length < FT_EUI64_LEN ? true : false;
3124
0
        report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3125
0
      }
3126
10.3k
      proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3127
10.3k
      break;
3128
1.69k
    case FT_GUID:
3129
      /*
3130
       * Map all non-zero values to little-endian for
3131
       * backwards compatibility.
3132
       */
3133
1.69k
      if (encoding)
3134
145
        encoding = ENC_LITTLE_ENDIAN;
3135
1.69k
      if (length != FT_GUID_LEN) {
3136
13
        length_error = length < FT_GUID_LEN ? true : false;
3137
13
        report_type_length_mismatch(tree, "a GUID", length, length_error);
3138
13
      }
3139
1.69k
      proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3140
1.69k
      break;
3141
3142
1.65k
    case FT_OID:
3143
1.72k
    case FT_REL_OID:
3144
1.72k
      proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3145
1.72k
      break;
3146
3147
8.42k
    case FT_SYSTEM_ID:
3148
8.42k
      proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3149
8.42k
      break;
3150
3151
5.06k
    case FT_FLOAT:
3152
      /*
3153
       * NOTE: to support code written when
3154
       * proto_tree_add_item() took a bool as its
3155
       * last argument, with false meaning "big-endian"
3156
       * and true meaning "little-endian", we treat any
3157
       * non-zero value of "encoding" as meaning
3158
       * "little-endian".
3159
       *
3160
       * At some point in the future, we might
3161
       * support non-IEEE-binary floating-point
3162
       * formats in the encoding as well
3163
       * (IEEE decimal, System/3x0, VAX).
3164
       */
3165
5.06k
      if (encoding)
3166
2.10k
        encoding = ENC_LITTLE_ENDIAN;
3167
5.06k
      if (length != 4) {
3168
0
        length_error = length < 4 ? true : false;
3169
0
        report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3170
0
      }
3171
5.06k
      if (encoding)
3172
2.10k
        floatval = tvb_get_letohieee_float(tvb, start);
3173
2.96k
      else
3174
2.96k
        floatval = tvb_get_ntohieee_float(tvb, start);
3175
5.06k
      proto_tree_set_float(new_fi, floatval);
3176
5.06k
      break;
3177
3178
4.24k
    case FT_DOUBLE:
3179
      /*
3180
       * NOTE: to support code written when
3181
       * proto_tree_add_item() took a bool as its
3182
       * last argument, with false meaning "big-endian"
3183
       * and true meaning "little-endian", we treat any
3184
       * non-zero value of "encoding" as meaning
3185
       * "little-endian".
3186
       *
3187
       * At some point in the future, we might
3188
       * support non-IEEE-binary floating-point
3189
       * formats in the encoding as well
3190
       * (IEEE decimal, System/3x0, VAX).
3191
       */
3192
4.24k
      if (encoding == true)
3193
0
        encoding = ENC_LITTLE_ENDIAN;
3194
4.24k
      if (length != 8) {
3195
0
        length_error = length < 8 ? true : false;
3196
0
        report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3197
0
      }
3198
4.24k
      if (encoding)
3199
3.43k
        doubleval = tvb_get_letohieee_double(tvb, start);
3200
815
      else
3201
815
        doubleval = tvb_get_ntohieee_double(tvb, start);
3202
4.24k
      proto_tree_set_double(new_fi, doubleval);
3203
4.24k
      break;
3204
3205
112k
    case FT_STRING:
3206
112k
      stringval = (const char*)get_string_value(PNODE_POOL(tree),
3207
112k
          tvb, start, length, &item_length, encoding);
3208
112k
      proto_tree_set_string(new_fi, stringval);
3209
3210
      /* Instead of calling proto_item_set_len(), since we
3211
       * don't yet have a proto_item, we set the
3212
       * field_info's length ourselves.
3213
       *
3214
       * XXX - our caller can't use that length to
3215
       * advance an offset unless they arrange that
3216
       * there always be a protocol tree into which
3217
       * we're putting this item.
3218
       */
3219
112k
      new_fi->length = item_length;
3220
112k
      break;
3221
3222
8.37k
    case FT_STRINGZ:
3223
8.37k
      stringval = (const char*)get_stringz_value(PNODE_POOL(tree),
3224
8.37k
          tree, tvb, start, length, &item_length, encoding);
3225
8.37k
      proto_tree_set_string(new_fi, stringval);
3226
3227
      /* Instead of calling proto_item_set_len(),
3228
       * since we don't yet have a proto_item, we
3229
       * set the field_info's length ourselves.
3230
       *
3231
       * XXX - our caller can't use that length to
3232
       * advance an offset unless they arrange that
3233
       * there always be a protocol tree into which
3234
       * we're putting this item.
3235
       */
3236
8.37k
      new_fi->length = item_length;
3237
8.37k
      break;
3238
3239
2.94k
    case FT_UINT_STRING:
3240
      /*
3241
       * NOTE: to support code written when
3242
       * proto_tree_add_item() took a bool as its
3243
       * last argument, with false meaning "big-endian"
3244
       * and true meaning "little-endian", if the
3245
       * encoding value is true, treat that as
3246
       * ASCII with a little-endian length.
3247
       *
3248
       * This won't work for code that passes
3249
       * arbitrary non-zero values; that code
3250
       * will need to be fixed.
3251
       */
3252
2.94k
      if (encoding == true)
3253
0
        encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
3254
2.94k
      stringval = (const char*)get_uint_string_value(PNODE_POOL(tree),
3255
2.94k
          tree, tvb, start, length, &item_length, encoding);
3256
2.94k
      proto_tree_set_string(new_fi, stringval);
3257
3258
      /* Instead of calling proto_item_set_len(), since we
3259
       * don't yet have a proto_item, we set the
3260
       * field_info's length ourselves.
3261
       *
3262
       * XXX - our caller can't use that length to
3263
       * advance an offset unless they arrange that
3264
       * there always be a protocol tree into which
3265
       * we're putting this item.
3266
       */
3267
2.94k
      new_fi->length = item_length;
3268
2.94k
      break;
3269
3270
2.00k
    case FT_STRINGZPAD:
3271
2.00k
      stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree),
3272
2.00k
          tvb, start, length, &item_length, encoding);
3273
2.00k
      proto_tree_set_string(new_fi, stringval);
3274
3275
      /* Instead of calling proto_item_set_len(), since we
3276
       * don't yet have a proto_item, we set the
3277
       * field_info's length ourselves.
3278
       *
3279
       * XXX - our caller can't use that length to
3280
       * advance an offset unless they arrange that
3281
       * there always be a protocol tree into which
3282
       * we're putting this item.
3283
       */
3284
2.00k
      new_fi->length = item_length;
3285
2.00k
      break;
3286
3287
1.80k
    case FT_STRINGZTRUNC:
3288
1.80k
      stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree),
3289
1.80k
          tvb, start, length, &item_length, encoding);
3290
1.80k
      proto_tree_set_string(new_fi, stringval);
3291
3292
      /* Instead of calling proto_item_set_len(), since we
3293
       * don't yet have a proto_item, we set the
3294
       * field_info's length ourselves.
3295
       *
3296
       * XXX - our caller can't use that length to
3297
       * advance an offset unless they arrange that
3298
       * there always be a protocol tree into which
3299
       * we're putting this item.
3300
       */
3301
1.80k
      new_fi->length = item_length;
3302
1.80k
      break;
3303
3304
5.34k
    case FT_ABSOLUTE_TIME:
3305
      /*
3306
       * Absolute times can be in any of a number of
3307
       * formats, and they can be big-endian or
3308
       * little-endian.
3309
       *
3310
       * Historically FT_TIMEs were only timespecs;
3311
       * the only question was whether they were stored
3312
       * in big- or little-endian format.
3313
       *
3314
       * For backwards compatibility, we interpret an
3315
       * encoding of 1 as meaning "little-endian timespec",
3316
       * so that passing true is interpreted as that.
3317
       */
3318
5.34k
      if (encoding == true)
3319
0
        encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;
3320
3321
5.34k
      get_time_value(tree, tvb, start, length, encoding, &time_stamp, false);
3322
3323
5.34k
      proto_tree_set_time(new_fi, &time_stamp);
3324
5.34k
      break;
3325
3326
659
    case FT_RELATIVE_TIME:
3327
      /*
3328
       * Relative times can be in any of a number of
3329
       * formats, and they can be big-endian or
3330
       * little-endian.
3331
       *
3332
       * Historically FT_TIMEs were only timespecs;
3333
       * the only question was whether they were stored
3334
       * in big- or little-endian format.
3335
       *
3336
       * For backwards compatibility, we interpret an
3337
       * encoding of 1 as meaning "little-endian timespec",
3338
       * so that passing true is interpreted as that.
3339
       */
3340
659
      if (encoding == true)
3341
0
        encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;
3342
3343
659
      get_time_value(tree, tvb, start, length, encoding, &time_stamp, true);
3344
3345
659
      proto_tree_set_time(new_fi, &time_stamp);
3346
659
      break;
3347
36
    case FT_IEEE_11073_SFLOAT:
3348
36
      if (encoding)
3349
36
        encoding = ENC_LITTLE_ENDIAN;
3350
36
      if (length != 2) {
3351
0
        length_error = length < 2 ? true : false;
3352
0
        report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3353
0
      }
3354
3355
36
      fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3356
3357
36
      break;
3358
0
    case FT_IEEE_11073_FLOAT:
3359
0
      if (encoding)
3360
0
        encoding = ENC_LITTLE_ENDIAN;
3361
0
      if (length != 4) {
3362
0
        length_error = length < 4 ? true : false;
3363
0
        report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3364
0
      }
3365
0
      fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3366
3367
0
      break;
3368
0
    default:
3369
0
      REPORT_DISSECTOR_BUG("field %s is of unknown type %d (%s)",
3370
0
               new_fi->hfinfo->abbrev,
3371
0
               new_fi->hfinfo->type,
3372
0
               ftype_name(new_fi->hfinfo->type));
3373
0
      break;
3374
20.3M
  }
3375
20.3M
  FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
3376
3377
  /* Don't add new node to proto_tree until now so that any exceptions
3378
   * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3379
  /* XXX. wouldn't be better to add this item to tree, with some special
3380
   * flag (FI_EXCEPTION?) to know which item caused exception? For
3381
   * strings and bytes, we would have to set new_fi->value to something
3382
   * non-NULL, or otherwise ensure that proto_item_fill_display_label
3383
   * could handle NULL values. */
3384
20.3M
  pi = proto_tree_add_node(tree, new_fi);
3385
3386
20.3M
  switch (new_fi->hfinfo->type) {
3387
3388
112k
  case FT_STRING:
3389
    /* XXX: trailing stray character detection should be done
3390
           * _before_ conversion to UTF-8, because conversion can change
3391
           * the length, or else get_string_length should return a value
3392
           * for the "length in bytes of the string after conversion
3393
           * including internal nulls." (Noting that we do, for other
3394
           * reasons, still need the "length in bytes in the field",
3395
           * especially for FT_STRINGZ.)
3396
           *
3397
           * This is true even for ASCII and UTF-8, because
3398
           * substituting REPLACEMENT CHARACTERS for illegal characters
3399
           * can also do so (and for UTF-8 possibly even make the
3400
           * string _shorter_).
3401
           */
3402
112k
    detect_trailing_stray_characters(encoding, stringval, item_length, pi);
3403
112k
    break;
3404
3405
20.2M
  default:
3406
20.2M
    break;
3407
20.3M
  }
3408
3409
20.3M
  return pi;
3410
20.3M
}
3411
3412
proto_item *
3413
proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3414
                            const unsigned start, unsigned length,
3415
                            const unsigned encoding, int32_t *retval)
3416
16.5k
{
3417
16.5k
  header_field_info *hfinfo;
3418
16.5k
  field_info    *new_fi;
3419
16.5k
  int32_t      value;
3420
3421
16.5k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3422
3423
16.5k
  switch (hfinfo->type) {
3424
560
  case FT_INT8:
3425
1.71k
  case FT_INT16:
3426
2.08k
  case FT_INT24:
3427
16.5k
  case FT_INT32:
3428
16.5k
    break;
3429
0
  case FT_INT64:
3430
0
    REPORT_DISSECTOR_BUG("64-bit signed integer field %s used with proto_tree_add_item_ret_int()",
3431
0
        hfinfo->abbrev);
3432
0
  default:
3433
0
    REPORT_DISSECTOR_BUG("Non-signed-integer field %s used with proto_tree_add_item_ret_int()",
3434
16.5k
        hfinfo->abbrev);
3435
16.5k
  }
3436
3437
16.5k
  CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,
3438
16.5k
    {
3439
16.5k
      if(retval)
3440
16.5k
      {
3441
16.5k
        *retval = 0;
3442
16.5k
      }
3443
16.5k
    } );
3444
3445
13.2k
  if (encoding & ENC_STRING) {
3446
0
    REPORT_DISSECTOR_BUG("wrong encoding");
3447
0
  }
3448
  /* I believe it's ok if this is called with a NULL tree */
3449
13.2k
  value = get_int_value(tree, tvb, start, length, encoding);
3450
3451
13.2k
  if (retval) {
3452
13.1k
    int no_of_bits;
3453
13.1k
    *retval = value;
3454
13.1k
    if (hfinfo->bitmask) {
3455
      /* Mask out irrelevant portions */
3456
370
      *retval &= (uint32_t)(hfinfo->bitmask);
3457
      /* Shift bits */
3458
370
      *retval >>= hfinfo_bitshift(hfinfo);
3459
370
    }
3460
13.1k
    no_of_bits = ws_count_ones(hfinfo->bitmask);
3461
13.1k
    *retval = ws_sign_ext32(*retval, no_of_bits);
3462
13.1k
  }
3463
3464
13.2k
  CHECK_FOR_NULL_TREE(tree);
3465
3466
13.2k
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3467
3468
12.9k
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3469
3470
12.9k
  proto_tree_set_int(new_fi, value);
3471
3472
12.9k
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3473
3474
12.9k
  return proto_tree_add_node(tree, new_fi);
3475
13.2k
}
3476
3477
proto_item *
3478
proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3479
                             const unsigned start, unsigned length,
3480
                             const unsigned encoding, uint32_t *retval)
3481
6.07M
{
3482
6.07M
  header_field_info *hfinfo;
3483
6.07M
  field_info    *new_fi;
3484
6.07M
  uint32_t       value;
3485
3486
6.07M
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3487
3488
6.07M
  switch (hfinfo->type) {
3489
32.3k
  case FT_CHAR:
3490
4.75M
  case FT_UINT8:
3491
5.60M
  case FT_UINT16:
3492
5.94M
  case FT_UINT24:
3493
6.07M
  case FT_UINT32:
3494
6.07M
    break;
3495
0
  default:
3496
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
3497
6.07M
        hfinfo->abbrev);
3498
6.07M
  }
3499
3500
6.07M
  CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,
3501
6.07M
    {
3502
6.07M
      if (retval) {
3503
6.07M
        *retval = 0;
3504
6.07M
      }
3505
6.07M
      return NULL;
3506
6.07M
    }
3507
6.07M
  );
3508
3509
6.06M
  if (encoding & ENC_STRING) {
3510
0
    REPORT_DISSECTOR_BUG("wrong encoding");
3511
0
  }
3512
  /* I believe it's ok if this is called with a NULL tree */
3513
  /* XXX - modify if we ever support EBCDIC FT_CHAR */
3514
6.06M
  if (encoding & ENC_VARINT_MASK) {
3515
0
    uint64_t temp64;
3516
0
    tvb_get_varint(tvb, start, length, &temp64, encoding);
3517
0
    value = (uint32_t)temp64;
3518
6.06M
  } else {
3519
6.06M
    value = get_uint_value(tree, tvb, start, length, encoding);
3520
6.06M
  }
3521
3522
6.06M
  if (retval) {
3523
6.05M
    *retval = value;
3524
6.05M
    if (hfinfo->bitmask) {
3525
      /* Mask out irrelevant portions */
3526
454k
      *retval &= (uint32_t)(hfinfo->bitmask);
3527
      /* Shift bits */
3528
454k
      *retval >>= hfinfo_bitshift(hfinfo);
3529
454k
    }
3530
6.05M
  }
3531
3532
6.06M
  CHECK_FOR_NULL_TREE(tree);
3533
3534
6.06M
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3535
3536
1.44M
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3537
3538
1.44M
  proto_tree_set_uint(new_fi, value);
3539
3540
1.44M
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3541
1.44M
  if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG|ENC_VARINT_SDNV)) {
3542
0
    new_fi->flags |= FI_VARINT;
3543
0
  }
3544
1.44M
  return proto_tree_add_node(tree, new_fi);
3545
6.06M
}
3546
3547
proto_item *
3548
proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3549
                               const unsigned start, unsigned length,
3550
                               const unsigned encoding, uint32_t *retval)
3551
475
{
3552
475
    return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3553
475
}
3554
3555
proto_item *
3556
proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3557
                              const unsigned start, unsigned length,
3558
                              const unsigned encoding, uint8_t *retval)
3559
3.85M
{
3560
    /* TODO: further restrict by hfinfo->type ? */
3561
3.85M
    uint32_t val32;
3562
3.85M
    proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3563
3.85M
    *retval = (uint8_t)val32;
3564
3.85M
    return item;
3565
3.85M
}
3566
3567
proto_item *
3568
proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3569
                               const unsigned start, unsigned length,
3570
                               const unsigned encoding, uint16_t *retval)
3571
86.4k
{
3572
    /* TODO: further restrict by hfinfo->type ? */
3573
86.4k
    uint32_t val32;
3574
86.4k
    proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3575
86.4k
    *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3576
86.4k
    return item;
3577
86.4k
}
3578
3579
3580
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3581
 * and returns proto_item* and uint value retrieved*/
3582
proto_item *
3583
ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3584
        const unsigned encoding, uint32_t *retval)
3585
1.36k
{
3586
1.36k
  field_info    *new_fi;
3587
1.36k
  header_field_info *hfinfo;
3588
1.36k
  unsigned     item_length;
3589
1.36k
  unsigned     offset;
3590
1.36k
  uint32_t     value;
3591
3592
1.36k
  offset = ptvc->offset;
3593
1.36k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3594
3595
1.36k
  switch (hfinfo->type) {
3596
0
  case FT_CHAR:
3597
359
  case FT_UINT8:
3598
1.36k
  case FT_UINT16:
3599
1.36k
  case FT_UINT24:
3600
1.36k
  case FT_UINT32:
3601
1.36k
    break;
3602
0
  default:
3603
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
3604
1.36k
        hfinfo->abbrev);
3605
1.36k
  }
3606
3607
1.36k
  get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3608
1.36k
  test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3609
3610
  /* I believe it's ok if this is called with a NULL tree */
3611
  /* XXX - modify if we ever support EBCDIC FT_CHAR */
3612
1.36k
  value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3613
3614
1.36k
  if (retval) {
3615
1.36k
    *retval = value;
3616
1.36k
    if (hfinfo->bitmask) {
3617
      /* Mask out irrelevant portions */
3618
0
      *retval &= (uint32_t)(hfinfo->bitmask);
3619
      /* Shift bits */
3620
0
      *retval >>= hfinfo_bitshift(hfinfo);
3621
0
    }
3622
1.36k
  }
3623
3624
1.36k
  ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3625
3626
1.36k
  CHECK_FOR_NULL_TREE(ptvc->tree);
3627
3628
  /* Coast clear. Try and fake it */
3629
1.36k
  TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3630
3631
1.13k
  new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3632
3633
1.13k
  return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3634
1.13k
    offset, length, encoding);
3635
1.36k
}
3636
3637
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3638
 * and returns proto_item* and int value retrieved*/
3639
proto_item *
3640
ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3641
        const unsigned encoding, int32_t *retval)
3642
0
{
3643
0
  field_info    *new_fi;
3644
0
  header_field_info *hfinfo;
3645
0
  unsigned     item_length;
3646
0
  unsigned     offset;
3647
0
  uint32_t     value;
3648
3649
0
  offset = ptvc->offset;
3650
0
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3651
3652
0
  switch (hfinfo->type) {
3653
0
  case FT_INT8:
3654
0
  case FT_INT16:
3655
0
  case FT_INT24:
3656
0
  case FT_INT32:
3657
0
    break;
3658
0
  default:
3659
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
3660
0
        hfinfo->abbrev);
3661
0
  }
3662
3663
0
  get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3664
0
  test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3665
3666
  /* I believe it's ok if this is called with a NULL tree */
3667
  /* XXX - modify if we ever support EBCDIC FT_CHAR */
3668
0
  value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3669
3670
0
  if (retval) {
3671
0
    int no_of_bits;
3672
0
    *retval = value;
3673
0
    if (hfinfo->bitmask) {
3674
      /* Mask out irrelevant portions */
3675
0
      *retval &= (uint32_t)(hfinfo->bitmask);
3676
      /* Shift bits */
3677
0
      *retval >>= hfinfo_bitshift(hfinfo);
3678
0
    }
3679
0
    no_of_bits = ws_count_ones(hfinfo->bitmask);
3680
0
    *retval = ws_sign_ext32(*retval, no_of_bits);
3681
0
  }
3682
3683
0
  ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3684
3685
0
  CHECK_FOR_NULL_TREE(ptvc->tree);
3686
3687
  /* Coast clear. Try and fake it */
3688
0
  TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3689
3690
0
  new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3691
3692
0
  return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3693
0
    offset, length, encoding);
3694
0
}
3695
3696
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3697
 * and returns proto_item* and string value retrieved */
3698
proto_item*
3699
ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3700
0
{
3701
0
  header_field_info *hfinfo;
3702
0
  field_info    *new_fi;
3703
0
  const uint8_t   *value;
3704
0
  unsigned    item_length;
3705
0
  unsigned    offset;
3706
3707
0
  offset = ptvc->offset;
3708
3709
0
  PROTO_REGISTRAR_GET_NTH(hf, hfinfo);
3710
3711
0
  switch (hfinfo->type) {
3712
0
  case FT_STRING:
3713
0
    value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3714
0
    break;
3715
0
  case FT_STRINGZ:
3716
0
    value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3717
0
    break;
3718
0
  case FT_UINT_STRING:
3719
0
    value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3720
0
    break;
3721
0
  case FT_STRINGZPAD:
3722
0
    value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3723
0
    break;
3724
0
  case FT_STRINGZTRUNC:
3725
0
    value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3726
0
    break;
3727
0
  default:
3728
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",
3729
0
        hfinfo->abbrev);
3730
0
  }
3731
3732
0
  if (retval)
3733
0
    *retval = value;
3734
3735
0
  ptvcursor_advance(ptvc, item_length);
3736
3737
0
  CHECK_FOR_NULL_TREE(ptvc->tree);
3738
3739
0
  TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
3740
3741
0
  new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3742
3743
0
  return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3744
0
    offset, length, encoding);
3745
0
}
3746
3747
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3748
 * and returns proto_item* and boolean value retrieved */
3749
proto_item*
3750
ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool *retval)
3751
0
{
3752
0
  header_field_info *hfinfo;
3753
0
  field_info    *new_fi;
3754
0
  unsigned    item_length;
3755
0
  unsigned    offset;
3756
0
  uint64_t    value, bitval;
3757
3758
0
  offset = ptvc->offset;
3759
0
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3760
3761
0
  if (hfinfo->type != FT_BOOLEAN) {
3762
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",
3763
0
        hfinfo->abbrev);
3764
0
  }
3765
3766
0
  CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,
3767
0
    {
3768
0
      if(retval)
3769
0
      {
3770
0
        *retval = false;
3771
0
      }
3772
0
    } );
3773
3774
0
  if (encoding & ENC_STRING) {
3775
0
    REPORT_DISSECTOR_BUG("wrong encoding");
3776
0
  }
3777
3778
0
  get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3779
0
  test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3780
3781
  /* I believe it's ok if this is called with a NULL tree */
3782
0
  value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3783
3784
0
  if (retval) {
3785
0
    bitval = value;
3786
0
    if (hfinfo->bitmask) {
3787
      /* Mask out irrelevant portions */
3788
0
      bitval &= hfinfo->bitmask;
3789
0
    }
3790
0
    *retval = (bitval != 0);
3791
0
  }
3792
3793
0
  ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3794
3795
0
  CHECK_FOR_NULL_TREE(ptvc->tree);
3796
3797
0
  TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
3798
3799
0
  new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3800
3801
0
  return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3802
0
    offset, length, encoding);
3803
0
}
3804
3805
proto_item *
3806
proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3807
    const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval)
3808
8.85k
{
3809
8.85k
  header_field_info *hfinfo;
3810
8.85k
  field_info    *new_fi;
3811
8.85k
  uint64_t       value;
3812
3813
8.85k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3814
3815
8.85k
  switch (hfinfo->type) {
3816
0
  case FT_UINT40:
3817
39
  case FT_UINT48:
3818
39
  case FT_UINT56:
3819
8.85k
  case FT_UINT64:
3820
8.85k
    break;
3821
0
  default:
3822
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",
3823
8.85k
        hfinfo->abbrev);
3824
8.85k
  }
3825
3826
8.85k
  CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,
3827
8.85k
    {
3828
8.85k
      if(retval)
3829
8.85k
      {
3830
8.85k
        *retval = 0;
3831
8.85k
      }
3832
8.85k
    } );
3833
3834
8.85k
  if (encoding & ENC_STRING) {
3835
0
    REPORT_DISSECTOR_BUG("wrong encoding");
3836
0
  }
3837
  /* I believe it's ok if this is called with a NULL tree */
3838
8.85k
  if (encoding & ENC_VARINT_MASK) {
3839
0
    tvb_get_varint(tvb, start, length, &value, encoding);
3840
8.85k
  } else {
3841
8.85k
    value = get_uint64_value(tree, tvb, start, length, encoding);
3842
8.85k
  }
3843
3844
8.85k
  if (retval) {
3845
8.74k
    *retval = value;
3846
8.74k
    if (hfinfo->bitmask) {
3847
      /* Mask out irrelevant portions */
3848
0
      *retval &= hfinfo->bitmask;
3849
      /* Shift bits */
3850
0
      *retval >>= hfinfo_bitshift(hfinfo);
3851
0
    }
3852
8.74k
  }
3853
3854
8.85k
  CHECK_FOR_NULL_TREE(tree);
3855
3856
8.51k
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3857
3858
8.44k
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3859
3860
8.44k
  proto_tree_set_uint64(new_fi, value);
3861
3862
8.44k
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3863
8.44k
  if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG|ENC_VARINT_SDNV)) {
3864
0
    new_fi->flags |= FI_VARINT;
3865
0
  }
3866
3867
8.44k
  return proto_tree_add_node(tree, new_fi);
3868
8.51k
}
3869
3870
proto_item *
3871
proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3872
  const unsigned start, unsigned length, const unsigned encoding, int64_t *retval)
3873
0
{
3874
0
  header_field_info *hfinfo;
3875
0
  field_info    *new_fi;
3876
0
  int64_t      value;
3877
3878
0
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3879
3880
0
  switch (hfinfo->type) {
3881
0
  case FT_INT40:
3882
0
  case FT_INT48:
3883
0
  case FT_INT56:
3884
0
  case FT_INT64:
3885
0
    break;
3886
0
  default:
3887
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
3888
0
      hfinfo->abbrev);
3889
0
  }
3890
3891
0
  CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,
3892
0
    {
3893
0
      if(retval)
3894
0
      {
3895
0
        *retval = 0;
3896
0
      }
3897
0
    } );
3898
3899
0
  if (encoding & ENC_STRING) {
3900
0
    REPORT_DISSECTOR_BUG("wrong encoding");
3901
0
  }
3902
  /* I believe it's ok if this is called with a NULL tree */
3903
0
  if (encoding & ENC_VARINT_MASK) {
3904
0
    tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3905
0
  }
3906
0
  else {
3907
0
    value = get_int64_value(tree, tvb, start, length, encoding);
3908
0
  }
3909
3910
0
  if (retval) {
3911
0
    *retval = value;
3912
0
  }
3913
3914
0
  CHECK_FOR_NULL_TREE(tree);
3915
3916
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3917
3918
0
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3919
3920
0
  proto_tree_set_int64(new_fi, value);
3921
3922
0
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3923
0
  if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG|ENC_VARINT_SDNV)) {
3924
0
    new_fi->flags |= FI_VARINT;
3925
0
  }
3926
3927
0
  return proto_tree_add_node(tree, new_fi);
3928
0
}
3929
3930
proto_item *
3931
proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3932
    const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval, unsigned *lenretval)
3933
83.9k
{
3934
83.9k
  header_field_info *hfinfo;
3935
83.9k
  field_info  *new_fi;
3936
83.9k
  uint64_t  value;
3937
3938
83.9k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3939
3940
83.9k
  if ((!FT_IS_INT(hfinfo->type)) && (!FT_IS_UINT(hfinfo->type))) {
3941
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT or FT_INT",
3942
0
        hfinfo->abbrev);
3943
0
  }
3944
3945
83.9k
  if (!(encoding & ENC_VARINT_MASK)) {
3946
0
    REPORT_DISSECTOR_BUG("Encoding must be a VARINT");
3947
0
  }
3948
3949
83.9k
  if (encoding & ENC_STRING) {
3950
0
    REPORT_DISSECTOR_BUG("wrong encoding");
3951
0
  }
3952
3953
  /* tvb_get_varint clamps the max length to FT_VARINT_MAX_LEN (10)
3954
   * It also handles length 0, setting both return values to 0.
3955
   * XXX - Should the max length be affected by the field type and/or
3956
   * encoding, e.g. 5 for FT_[U]INT32?
3957
   * XXX - Should there be separate _varint and _varuint versions to
3958
   * avoid the changing the sign when casting the return value?
3959
   * XXX - Do we even need the length parameter? Every user of this
3960
   * function passes in -1 or FT_VARINT_MAX_LEN. We could have a
3961
   * separate function, but unlike some field types, variable length
3962
   * is the typical case here, not the exception, and the typical
3963
   * case should have the shorter, more convenient function name.
3964
   * Having the length makes the signature more similar to other
3965
   * functions, though. */
3966
83.9k
  length = tvb_get_varint(tvb, start, length, &value, encoding);
3967
3968
83.9k
  if (length == 0) {
3969
68
    expert_add_info(NULL, tree, &ei_varint_decoding_failed_error);
3970
68
    THROW(ReportedBoundsError);
3971
68
  }
3972
3973
83.9k
  if (retval) {
3974
83.5k
    *retval = value;
3975
83.5k
    if (hfinfo->bitmask) {
3976
      /* Mask out irrelevant portions */
3977
0
      *retval &= hfinfo->bitmask;
3978
      /* Shift bits */
3979
0
      *retval >>= hfinfo_bitshift(hfinfo);
3980
0
    }
3981
83.5k
  }
3982
3983
83.9k
  if (lenretval) {
3984
83.6k
    *lenretval = length;
3985
83.6k
  }
3986
3987
83.9k
  CHECK_FOR_NULL_TREE(tree);
3988
3989
83.9k
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3990
3991
73.3k
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3992
3993
73.3k
  proto_tree_set_uint64(new_fi, value);
3994
3995
73.3k
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3996
73.3k
  if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG|ENC_VARINT_SDNV)) {
3997
72.9k
    new_fi->flags |= FI_VARINT;
3998
72.9k
  }
3999
4000
73.3k
  return proto_tree_add_node(tree, new_fi);
4001
4002
83.9k
}
4003
4004
proto_item *
4005
proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4006
                                const unsigned start, unsigned length,
4007
                                const unsigned encoding, bool *retval)
4008
104k
{
4009
104k
  header_field_info *hfinfo;
4010
104k
  field_info    *new_fi;
4011
104k
  uint64_t       value, bitval;
4012
4013
104k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4014
4015
104k
  if (hfinfo->type != FT_BOOLEAN) {
4016
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",
4017
0
        hfinfo->abbrev);
4018
0
  }
4019
4020
104k
  CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,
4021
104k
    {
4022
104k
      if(retval)
4023
104k
      {
4024
104k
        *retval = false;
4025
104k
      }
4026
104k
    } );
4027
4028
104k
  if (encoding & ENC_STRING) {
4029
0
    REPORT_DISSECTOR_BUG("wrong encoding");
4030
0
  }
4031
  /* I believe it's ok if this is called with a NULL tree */
4032
104k
  value = get_uint64_value(tree, tvb, start, length, encoding);
4033
4034
104k
  if (retval) {
4035
104k
    bitval = value;
4036
104k
    if (hfinfo->bitmask) {
4037
      /* Mask out irrelevant portions */
4038
104k
      bitval &= hfinfo->bitmask;
4039
104k
    }
4040
104k
    *retval = (bitval != 0);
4041
104k
  }
4042
4043
104k
  CHECK_FOR_NULL_TREE(tree);
4044
4045
104k
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4046
4047
52.5k
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4048
4049
52.5k
  proto_tree_set_boolean(new_fi, value);
4050
4051
52.5k
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
4052
4053
52.5k
  return proto_tree_add_node(tree, new_fi);
4054
104k
}
4055
4056
proto_item *
4057
proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4058
                                const unsigned start, unsigned length,
4059
                                const unsigned encoding, float *retval)
4060
0
{
4061
0
  header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4062
0
  field_info    *new_fi;
4063
0
  float      value;
4064
4065
0
  DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4066
4067
0
  if (hfinfo->type != FT_FLOAT) {
4068
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_FLOAT", hfinfo->abbrev);
4069
0
  }
4070
4071
0
  if (length != 4) {
4072
0
    report_type_length_mismatch(tree, "a single-precision floating point number", length, true);
4073
0
  }
4074
4075
  /* treat any nonzero encoding as little endian for backwards compatibility */
4076
0
  value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
4077
0
  if (retval) {
4078
0
    *retval = value;
4079
0
  }
4080
4081
0
  CHECK_FOR_NULL_TREE(tree);
4082
4083
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4084
4085
0
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4086
0
  if (encoding) {
4087
0
    new_fi->flags |= FI_LITTLE_ENDIAN;
4088
0
  }
4089
4090
0
  proto_tree_set_float(new_fi, value);
4091
4092
0
  return proto_tree_add_node(tree, new_fi);
4093
0
}
4094
4095
proto_item *
4096
proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4097
                                const unsigned start, unsigned length,
4098
                                const unsigned encoding, double *retval)
4099
0
{
4100
0
  header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4101
0
  field_info    *new_fi;
4102
0
  double       value;
4103
4104
0
  DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4105
4106
0
  if (hfinfo->type != FT_DOUBLE) {
4107
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_DOUBLE", hfinfo->abbrev);
4108
0
  }
4109
4110
0
  if (length != 8) {
4111
0
    report_type_length_mismatch(tree, "a double-precision floating point number", length, true);
4112
0
  }
4113
4114
  /* treat any nonzero encoding as little endian for backwards compatibility */
4115
0
  value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4116
0
  if (retval) {
4117
0
    *retval = value;
4118
0
  }
4119
4120
0
  CHECK_FOR_NULL_TREE(tree);
4121
4122
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4123
4124
0
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4125
0
  if (encoding) {
4126
0
    new_fi->flags |= FI_LITTLE_ENDIAN;
4127
0
  }
4128
4129
0
  proto_tree_set_double(new_fi, value);
4130
4131
0
  return proto_tree_add_node(tree, new_fi);
4132
0
}
4133
4134
proto_item *
4135
proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4136
                             const unsigned start, unsigned length,
4137
                             const unsigned encoding, ws_in4_addr *retval)
4138
5.32k
{
4139
5.32k
  header_field_info *hfinfo;
4140
5.32k
  field_info    *new_fi;
4141
5.32k
  ws_in4_addr    value;
4142
4143
5.32k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4144
4145
5.32k
  switch (hfinfo->type) {
4146
5.32k
  case FT_IPv4:
4147
5.32k
    break;
4148
0
  default:
4149
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_IPv4",
4150
5.32k
        hfinfo->abbrev);
4151
5.32k
  }
4152
4153
5.32k
  if (length != FT_IPv4_LEN)
4154
5.32k
    REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ipv4",
4155
5.32k
      length);
4156
4157
5.32k
  if (encoding & (ENC_STRING | ENC_VARINT_MASK)) {
4158
0
    REPORT_DISSECTOR_BUG("wrong encoding");
4159
0
  }
4160
4161
  /*
4162
   * NOTE: to support code written when proto_tree_add_item() took
4163
   * a bool as its last argument, with false meaning "big-endian"
4164
   * and true meaning "little-endian", we treat any non-zero value
4165
   * of "encoding" as meaning "little-endian".
4166
   */
4167
5.32k
  value = tvb_get_ipv4(tvb, start);
4168
5.32k
  if (encoding)
4169
0
    value = GUINT32_SWAP_LE_BE(value);
4170
4171
5.32k
  if (retval) {
4172
5.31k
    *retval = value;
4173
5.31k
  }
4174
4175
5.32k
  CHECK_FOR_NULL_TREE(tree);
4176
4177
5.32k
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4178
4179
311
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4180
4181
311
  proto_tree_set_ipv4(new_fi, value);
4182
4183
311
  new_fi->flags |= encoding ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
4184
311
  return proto_tree_add_node(tree, new_fi);
4185
5.32k
}
4186
4187
proto_item *
4188
proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4189
                             const unsigned start, unsigned length,
4190
                             const unsigned encoding, ws_in6_addr *addr)
4191
0
{
4192
0
  header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4193
0
  field_info    *new_fi;
4194
4195
0
  DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4196
4197
0
  switch (hfinfo->type) {
4198
0
  case FT_IPv6:
4199
0
    break;
4200
0
  default:
4201
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_IPv6",
4202
0
        hfinfo->abbrev);
4203
0
  }
4204
4205
0
  if (length != FT_IPv6_LEN)
4206
0
    REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ipv6",
4207
0
      length);
4208
4209
0
  if (encoding) {
4210
0
    REPORT_DISSECTOR_BUG("Encodings not yet implemented for proto_tree_add_item_ret_ipv6");
4211
0
  }
4212
4213
0
  tvb_get_ipv6(tvb, start, addr);
4214
4215
0
  CHECK_FOR_NULL_TREE(tree);
4216
4217
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4218
4219
0
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4220
4221
0
  proto_tree_set_ipv6(new_fi, addr);
4222
4223
0
  return proto_tree_add_node(tree, new_fi);
4224
0
}
4225
4226
proto_item *
4227
proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4228
0
    const unsigned start, unsigned length, const unsigned encoding, uint8_t *retval) {
4229
4230
0
  header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4231
0
  field_info    *new_fi;
4232
4233
0
  DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4234
4235
0
  switch (hfinfo->type) {
4236
0
  case FT_ETHER:
4237
0
    break;
4238
0
  default:
4239
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_ETHER",
4240
0
        hfinfo->abbrev);
4241
0
  }
4242
4243
0
  if (length != FT_ETHER_LEN)
4244
0
    REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ether",
4245
0
      length);
4246
4247
0
  if (encoding) {
4248
0
    REPORT_DISSECTOR_BUG("Encodings not yet implemented for proto_tree_add_item_ret_ether");
4249
0
  }
4250
4251
0
  tvb_memcpy(tvb, retval, start, length);
4252
4253
0
  CHECK_FOR_NULL_TREE(tree);
4254
4255
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4256
4257
0
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4258
4259
0
  proto_tree_set_ether(new_fi, retval);
4260
4261
0
  return proto_tree_add_node(tree, new_fi);
4262
0
}
4263
4264
4265
proto_item *
4266
proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4267
                                          tvbuff_t *tvb,
4268
                                          const unsigned start, int length,
4269
                                          const unsigned encoding,
4270
                                          wmem_allocator_t *scope,
4271
                                          const uint8_t **retval,
4272
                                          unsigned *lenretval)
4273
36.9k
{
4274
36.9k
  proto_item *pi;
4275
36.9k
  header_field_info *hfinfo;
4276
36.9k
  field_info    *new_fi;
4277
36.9k
  const uint8_t   *value;
4278
4279
36.9k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4280
4281
36.9k
  switch (hfinfo->type) {
4282
27.1k
  case FT_STRING:
4283
27.1k
    value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4284
27.1k
    break;
4285
6.90k
  case FT_STRINGZ:
4286
6.90k
    value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4287
6.90k
    break;
4288
2.82k
  case FT_UINT_STRING:
4289
2.82k
    value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4290
2.82k
    break;
4291
8
  case FT_STRINGZPAD:
4292
8
    value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4293
8
    break;
4294
27
  case FT_STRINGZTRUNC:
4295
27
    value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4296
27
    break;
4297
0
  default:
4298
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",
4299
36.9k
        hfinfo->abbrev);
4300
36.9k
  }
4301
4302
35.3k
  if (retval)
4303
34.7k
    *retval = value;
4304
4305
35.3k
  CHECK_FOR_NULL_TREE(tree);
4306
4307
35.1k
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4308
4309
23.6k
  new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4310
4311
23.6k
  proto_tree_set_string(new_fi, (const char*)value);
4312
4313
23.6k
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
4314
4315
23.6k
  pi = proto_tree_add_node(tree, new_fi);
4316
4317
23.6k
  switch (hfinfo->type) {
4318
4319
6.00k
  case FT_STRINGZ:
4320
6.00k
  case FT_STRINGZPAD:
4321
6.02k
  case FT_STRINGZTRUNC:
4322
8.69k
  case FT_UINT_STRING:
4323
8.69k
    break;
4324
4325
14.9k
  case FT_STRING:
4326
14.9k
    detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4327
14.9k
    break;
4328
4329
0
  default:
4330
0
    ws_assert_not_reached();
4331
23.6k
  }
4332
4333
23.6k
  return pi;
4334
23.6k
}
4335
4336
proto_item *
4337
proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4338
                               const unsigned start, int length,
4339
                               const unsigned encoding, wmem_allocator_t *scope,
4340
                               const uint8_t **retval)
4341
28.5k
{
4342
28.5k
  unsigned item_length; // Param cannot be NULL in function below
4343
28.5k
  return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4344
28.5k
      tvb, start, length, encoding, scope, retval, &item_length);
4345
28.5k
}
4346
4347
proto_item *
4348
proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4349
                                                  tvbuff_t *tvb,
4350
                                                  const unsigned start, int length,
4351
                                                  const unsigned encoding,
4352
                                                  wmem_allocator_t *scope,
4353
                                                  char **retval,
4354
                                                  unsigned *lenretval)
4355
6.65k
{
4356
6.65k
  proto_item *pi;
4357
6.65k
  header_field_info *hfinfo;
4358
6.65k
  field_info    *new_fi;
4359
6.65k
  const uint8_t   *value;
4360
6.65k
  uint32_t       n = 0;
4361
4362
6.65k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4363
4364
6.65k
  switch (hfinfo->type) {
4365
3.05k
  case FT_STRING:
4366
3.05k
    value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4367
3.05k
    *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH);
4368
3.05k
    ws_label_strcpy(*retval, ITEM_LABEL_LENGTH, 0, value, label_strcat_flags(hfinfo));
4369
3.05k
    break;
4370
3
  case FT_STRINGZ:
4371
3
    value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4372
3
    *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH);
4373
3
    ws_label_strcpy(*retval, ITEM_LABEL_LENGTH, 0, value, label_strcat_flags(hfinfo));
4374
3
    break;
4375
0
  case FT_UINT_STRING:
4376
0
    value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4377
0
    *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH);
4378
0
    ws_label_strcpy(*retval, ITEM_LABEL_LENGTH, 0, value, label_strcat_flags(hfinfo));
4379
0
    break;
4380
0
  case FT_STRINGZPAD:
4381
0
    value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4382
0
    *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH);
4383
0
    ws_label_strcpy(*retval, ITEM_LABEL_LENGTH, 0, value, label_strcat_flags(hfinfo));
4384
0
    break;
4385
0
  case FT_STRINGZTRUNC:
4386
0
    value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4387
0
    *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH);
4388
0
    ws_label_strcpy(*retval, ITEM_LABEL_LENGTH, 0, value, label_strcat_flags(hfinfo));
4389
0
    break;
4390
3.60k
  case FT_BYTES:
4391
3.60k
    tvb_ensure_bytes_exist(tvb, start, length);
4392
3.60k
    value = tvb_get_ptr(tvb, start, length);
4393
3.60k
    *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4394
3.60k
    *lenretval = length;
4395
3.60k
    break;
4396
0
  case FT_UINT_BYTES:
4397
0
    n = get_uint_value(tree, tvb, start, length, encoding);
4398
0
    tvb_ensure_bytes_exist(tvb, start + length, n);
4399
0
    value = tvb_get_ptr(tvb, start + length, n);
4400
0
    *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4401
0
    *lenretval = length + n;
4402
0
    break;
4403
0
  default:
4404
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, FT_STRINGZTRUNC, FT_BYTES, or FT_UINT_BYTES",
4405
6.65k
        hfinfo->abbrev);
4406
6.65k
  }
4407
4408
6.51k
  CHECK_FOR_NULL_TREE(tree);
4409
4410
6.51k
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4411
4412
6.24k
  new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4413
4414
6.24k
  switch (hfinfo->type) {
4415
4416
2.88k
  case FT_STRING:
4417
2.88k
  case FT_STRINGZ:
4418
2.88k
  case FT_UINT_STRING:
4419
2.88k
  case FT_STRINGZPAD:
4420
2.88k
  case FT_STRINGZTRUNC:
4421
2.88k
    proto_tree_set_string(new_fi, (const char*)value);
4422
2.88k
    break;
4423
4424
3.36k
  case FT_BYTES:
4425
3.36k
    proto_tree_set_bytes(new_fi, value, length);
4426
3.36k
    break;
4427
4428
0
  case FT_UINT_BYTES:
4429
0
    proto_tree_set_bytes(new_fi, value, n);
4430
0
    break;
4431
4432
0
  default:
4433
0
    ws_assert_not_reached();
4434
6.24k
  }
4435
4436
6.24k
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
4437
4438
6.24k
  pi = proto_tree_add_node(tree, new_fi);
4439
4440
6.24k
  switch (hfinfo->type) {
4441
4442
1
  case FT_STRINGZ:
4443
1
  case FT_STRINGZPAD:
4444
1
  case FT_STRINGZTRUNC:
4445
1
  case FT_UINT_STRING:
4446
1
    break;
4447
4448
2.88k
  case FT_STRING:
4449
2.88k
    detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4450
2.88k
    break;
4451
4452
3.36k
  case FT_BYTES:
4453
3.36k
  case FT_UINT_BYTES:
4454
3.36k
    break;
4455
4456
0
  default:
4457
0
    ws_assert_not_reached();
4458
6.24k
  }
4459
4460
6.24k
  return pi;
4461
6.24k
}
4462
4463
proto_item *
4464
proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4465
                                       tvbuff_t *tvb,
4466
                                       const unsigned start, int length,
4467
                                       const unsigned encoding,
4468
                                       wmem_allocator_t *scope,
4469
                                       char **retval)
4470
6.65k
{
4471
6.65k
  unsigned item_length; // Param cannot be NULL in function below
4472
6.65k
  return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4473
6.65k
      tvb, start, length, encoding, scope, retval, &item_length);
4474
6.65k
}
4475
4476
proto_item *
4477
proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4478
  tvbuff_t *tvb,
4479
  const unsigned start, int length, const unsigned encoding,
4480
  wmem_allocator_t *scope, char **retval)
4481
104
{
4482
104
  header_field_info *hfinfo;
4483
104
  field_info    *new_fi;
4484
104
  nstime_t    time_stamp;
4485
104
  int flags;
4486
4487
104
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4488
4489
104
  switch (hfinfo->type) {
4490
104
  case FT_ABSOLUTE_TIME:
4491
104
    get_time_value(tree, tvb, start, length, encoding, &time_stamp, false);
4492
104
    flags = ABS_TIME_TO_STR_SHOW_ZONE;
4493
104
    if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4494
0
      flags |= ABS_TIME_TO_STR_ISO8601;
4495
0
    }
4496
104
    *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4497
104
    break;
4498
0
  case FT_RELATIVE_TIME:
4499
0
    get_time_value(tree, tvb, start, length, encoding, &time_stamp, true);
4500
0
    *retval = rel_time_to_secs_str(scope, &time_stamp);
4501
0
    break;
4502
0
  default:
4503
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME",
4504
104
      hfinfo->abbrev);
4505
104
  }
4506
4507
99
  CHECK_FOR_NULL_TREE(tree);
4508
4509
99
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4510
4511
90
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4512
4513
90
  switch (hfinfo->type) {
4514
4515
90
  case FT_ABSOLUTE_TIME:
4516
90
  case FT_RELATIVE_TIME:
4517
90
    proto_tree_set_time(new_fi, &time_stamp);
4518
90
    break;
4519
0
  default:
4520
0
    ws_assert_not_reached();
4521
90
  }
4522
4523
90
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
4524
4525
90
  return proto_tree_add_node(tree, new_fi);
4526
90
}
4527
4528
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4529
   and returns proto_item* */
4530
proto_item *
4531
ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4532
        const unsigned encoding)
4533
49.8k
{
4534
49.8k
  field_info    *new_fi;
4535
49.8k
  header_field_info *hfinfo;
4536
49.8k
  int      item_length;
4537
49.8k
  unsigned     offset;
4538
4539
49.8k
  offset = ptvc->offset;
4540
49.8k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4541
49.8k
  get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4542
49.8k
  test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4543
4544
49.8k
  ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4545
4546
49.8k
  CHECK_FOR_NULL_TREE(ptvc->tree);
4547
4548
  /* Coast clear. Try and fake it */
4549
49.8k
  TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
4550
4551
48.6k
  new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4552
4553
48.6k
  return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4554
48.6k
    offset, length, encoding);
4555
49.8k
}
4556
4557
/* Add an item to a proto_tree, using the text label registered to that item;
4558
   the item is extracted from the tvbuff handed to it. */
4559
proto_item *
4560
proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4561
      const unsigned start, int length, const unsigned encoding)
4562
40.2M
{
4563
40.2M
  field_info        *new_fi;
4564
40.2M
  int     item_length;
4565
4566
40.2M
  DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4567
4568
40.2M
  get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4569
40.2M
  test_length(hfinfo, tvb, start, item_length, encoding);
4570
4571
40.2M
  CHECK_FOR_NULL_TREE(tree);
4572
4573
39.1M
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4574
4575
20.4M
  new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4576
4577
20.4M
  return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4578
39.1M
}
4579
4580
proto_item *
4581
proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4582
        const unsigned start, int length, const unsigned encoding)
4583
40.2M
{
4584
40.2M
  register header_field_info *hfinfo;
4585
4586
40.2M
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4587
40.2M
  return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4588
40.2M
}
4589
4590
/* Add an item to a proto_tree, using the text label registered to that item;
4591
   the item is extracted from the tvbuff handed to it.
4592
4593
   Return the length of the item through the pointer. */
4594
proto_item *
4595
proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4596
           tvbuff_t *tvb, const unsigned start,
4597
           int length, const unsigned encoding,
4598
           unsigned *lenretval)
4599
3.93k
{
4600
3.93k
  field_info        *new_fi;
4601
3.93k
  int     item_length;
4602
3.93k
  proto_item   *item;
4603
4604
3.93k
  DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4605
4606
3.93k
  get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4607
3.93k
  test_length(hfinfo, tvb, start, item_length, encoding);
4608
4609
3.93k
  if (!tree) {
4610
    /*
4611
     * We need to get the correct item length here.
4612
     * That's normally done by proto_tree_new_item(),
4613
     * but we won't be calling it.
4614
     */
4615
0
    *lenretval = get_full_length(hfinfo, tvb, start, length,
4616
0
        item_length, encoding);
4617
0
    return NULL;
4618
0
  }
4619
4620
3.93k
  TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo, {
4621
    /*
4622
     * Even if the tree item is not referenced (and thus faked),
4623
     * the caller must still be informed of the actual length.
4624
     */
4625
3.93k
    *lenretval = get_full_length(hfinfo, tvb, start, length,
4626
3.93k
        item_length, encoding);
4627
3.93k
  });
4628
4629
3.89k
  new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4630
4631
3.89k
  item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4632
3.89k
  *lenretval = new_fi->length;
4633
3.89k
  return item;
4634
3.93k
}
4635
4636
proto_item *
4637
proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4638
             const unsigned start, int length,
4639
             const unsigned encoding, unsigned *lenretval)
4640
3.93k
{
4641
3.93k
  register header_field_info *hfinfo;
4642
4643
3.93k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4644
3.93k
  return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4645
3.93k
}
4646
4647
/* which FT_ types can use proto_tree_add_bytes_item() */
4648
static inline bool
4649
validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4650
60
{
4651
60
  return (type == FT_BYTES      ||
4652
0
    type == FT_UINT_BYTES ||
4653
0
    type == FT_OID        ||
4654
0
    type == FT_REL_OID    ||
4655
0
    type == FT_SYSTEM_ID  );
4656
60
}
4657
4658
/* Note: this does no validation that the byte array of an FT_OID or
4659
   FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4660
   so I think it's ok to continue not validating it?
4661
 */
4662
proto_item *
4663
proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4664
        const unsigned start, unsigned length,
4665
        const unsigned encoding,
4666
        GByteArray *retval, unsigned *endoff, int *err)
4667
60
{
4668
60
  field_info    *new_fi;
4669
60
  GByteArray    *bytes = retval;
4670
60
  GByteArray    *created_bytes = NULL;
4671
60
  bool       failed = false;
4672
60
  uint32_t     n = 0;
4673
60
  header_field_info *hfinfo;
4674
60
  bool     generate = (bytes || tree) ? true : false;
4675
4676
60
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4677
4678
60
  DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4679
4680
60
  DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
4681
60
    "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
4682
4683
60
  if (length == 0) {
4684
0
    return NULL;
4685
0
  }
4686
4687
60
  if (encoding & ENC_STR_NUM) {
4688
0
    REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
4689
0
  }
4690
4691
60
  if (generate && (encoding & ENC_STR_HEX)) {
4692
0
    if (hfinfo->type == FT_UINT_BYTES) {
4693
      /* can't decode FT_UINT_BYTES from strings */
4694
0
      REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
4695
0
          "FT_UINT_BYTES type, but as ENC_STR_HEX");
4696
0
    }
4697
4698
0
    unsigned hex_encoding = encoding;
4699
0
    if (!(encoding & ENC_SEP_MASK)) {
4700
      /* If none of the separator values are used,
4701
       * assume no separator (the common case). */
4702
0
      hex_encoding |= ENC_SEP_NONE;
4703
#if 0
4704
      REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called "
4705
        "with ENC_STR_HEX but no ENC_SEP_XXX value");
4706
#endif
4707
0
    }
4708
4709
0
    if (!bytes) {
4710
      /* caller doesn't care about return value, but we need it to
4711
         call tvb_get_string_bytes() and set the tree later */
4712
0
      bytes = created_bytes = g_byte_array_new();
4713
0
    }
4714
4715
    /*
4716
     * bytes might be NULL after this, but can't add expert
4717
     * error until later; if it's NULL, just note that
4718
     * it failed.
4719
     */
4720
0
    bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4721
0
    if (bytes == NULL)
4722
0
      failed = true;
4723
0
  }
4724
60
  else if (generate) {
4725
60
    tvb_ensure_bytes_exist(tvb, start, length);
4726
4727
60
    if (hfinfo->type == FT_UINT_BYTES) {
4728
0
      n = length; /* n is now the "header" length */
4729
0
      length = get_uint_value(tree, tvb, start, n, encoding);
4730
      /* length is now the value's length; only store the value in the array */
4731
0
      tvb_ensure_bytes_exist(tvb, start + n, length);
4732
0
      if (!bytes) {
4733
        /* caller doesn't care about return value, but
4734
         * we may need it to set the tree later */
4735
0
        bytes = created_bytes = g_byte_array_new();
4736
0
      }
4737
0
      g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4738
0
    }
4739
60
    else if (length > 0) {
4740
60
      if (!bytes) {
4741
        /* caller doesn't care about return value, but
4742
         * we may need it to set the tree later */
4743
60
        bytes = created_bytes = g_byte_array_new();
4744
60
      }
4745
60
      g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4746
60
    }
4747
4748
60
    if (endoff)
4749
0
        *endoff = start + n + length;
4750
60
  }
4751
4752
60
  if (err)
4753
0
    *err = failed ? EINVAL : 0;
4754
4755
60
  CHECK_FOR_NULL_TREE_AND_FREE(tree,
4756
60
    {
4757
60
        if (created_bytes)
4758
60
      g_byte_array_free(created_bytes, true);
4759
60
        created_bytes = NULL;
4760
60
        bytes = NULL;
4761
60
    } );
4762
4763
60
  TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
4764
60
    {
4765
60
        if (created_bytes)
4766
60
      g_byte_array_free(created_bytes, true);
4767
60
        created_bytes = NULL;
4768
60
        bytes = NULL;
4769
60
    } );
4770
4771
  /* n will be zero except when it's a FT_UINT_BYTES */
4772
60
  new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4773
4774
60
  if (encoding & ENC_STRING) {
4775
0
    if (failed)
4776
0
        expert_add_info(NULL, tree, &ei_byte_array_string_decoding_failed_error);
4777
4778
0
    if (bytes)
4779
0
        proto_tree_set_bytes_gbytearray(new_fi, bytes);
4780
0
    else
4781
0
        proto_tree_set_bytes(new_fi, NULL, 0);
4782
4783
0
    if (created_bytes)
4784
0
        g_byte_array_free(created_bytes, true);
4785
0
  }
4786
60
  else {
4787
    /* n will be zero except when it's a FT_UINT_BYTES */
4788
60
    proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4789
4790
    /* XXX: If we have a non-NULL tree but NULL retval, we don't
4791
     * use the byte array created above in this case.
4792
     */
4793
60
    if (created_bytes)
4794
60
        g_byte_array_free(created_bytes, true);
4795
4796
60
    FI_SET_FLAG(new_fi,
4797
60
      (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
4798
60
  }
4799
4800
60
  return proto_tree_add_node(tree, new_fi);
4801
60
}
4802
4803
4804
proto_item *
4805
proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4806
         const unsigned start, const unsigned length,
4807
         const unsigned encoding,
4808
         nstime_t *retval, unsigned *endoff, int *err)
4809
1
{
4810
1
  field_info    *new_fi;
4811
1
  nstime_t     time_stamp;
4812
1
  int      saved_err = 0;
4813
1
  header_field_info *hfinfo;
4814
4815
1
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4816
4817
1
  DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4818
4819
1
  if (length == 0) {
4820
0
    if(retval) {
4821
0
      nstime_set_zero(retval);
4822
0
    }
4823
0
    return NULL;
4824
0
  }
4825
4826
1
  nstime_set_zero(&time_stamp);
4827
4828
1
  if (encoding & ENC_STR_TIME_MASK) {
4829
0
    DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ABSOLUTE_TIME);
4830
    /* The only string format that could be a relative time is
4831
     * ENC_ISO_8601_TIME, and that is treated as an absolute time
4832
     * relative to "now" currently.
4833
     */
4834
0
    if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4835
0
      saved_err = EINVAL;
4836
0
  }
4837
1
  else {
4838
1
    DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
4839
1
    const bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true : false;
4840
4841
1
    tvb_ensure_bytes_exist(tvb, start, length);
4842
1
    get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4843
1
    if (endoff) *endoff = start + length;
4844
1
  }
4845
4846
1
  if (err) *err = saved_err;
4847
4848
1
  if (retval) {
4849
0
    retval->secs  = time_stamp.secs;
4850
0
    retval->nsecs = time_stamp.nsecs;
4851
0
  }
4852
4853
1
  CHECK_FOR_NULL_TREE(tree);
4854
4855
1
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4856
4857
1
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4858
4859
1
  proto_tree_set_time(new_fi, &time_stamp);
4860
4861
1
  if (encoding & ENC_STRING) {
4862
0
    if (saved_err)
4863
0
        expert_add_info(NULL, tree, &ei_date_time_string_decoding_failed_error);
4864
0
  }
4865
1
  else {
4866
1
    FI_SET_FLAG(new_fi,
4867
1
      (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
4868
1
  }
4869
4870
1
  return proto_tree_add_node(tree, new_fi);
4871
1
}
4872
4873
/* Add a FT_NONE to a proto_tree */
4874
proto_item *
4875
proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4876
         const unsigned start, int length, const char *format,
4877
         ...)
4878
7.12M
{
4879
7.12M
  proto_item    *pi;
4880
7.12M
  va_list      ap;
4881
7.12M
  header_field_info *hfinfo;
4882
4883
7.12M
  CHECK_FOR_NULL_TREE(tree);
4884
4885
7.10M
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4886
4887
2.34M
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
4888
4889
2.34M
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4890
4891
2.34M
  TRY_TO_FAKE_THIS_REPR(pi);
4892
4893
2.34M
  va_start(ap, format);
4894
2.34M
  proto_tree_set_representation(pi, format, ap);
4895
2.34M
  va_end(ap);
4896
4897
  /* no value to set for FT_NONE */
4898
2.34M
  return pi;
4899
2.34M
}
4900
4901
/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4902
 * offset, and returns proto_item* */
4903
proto_item *
4904
ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4905
       const unsigned encoding)
4906
50.4k
{
4907
50.4k
  proto_item *item;
4908
4909
50.4k
  item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4910
50.4k
           length, encoding);
4911
4912
50.4k
  return item;
4913
50.4k
}
4914
4915
/* Advance the ptvcursor's offset within its tvbuff without
4916
 * adding anything to the proto_tree. */
4917
void
4918
ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4919
52.2k
{
4920
52.2k
  if (ckd_add(&ptvc->offset, ptvc->offset, length)) {
4921
1
    THROW(ReportedBoundsError);
4922
1
  }
4923
52.2k
}
4924
4925
4926
static void
4927
proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4928
4.49M
{
4929
4.49M
  ws_assert(length >= 0);
4930
4.49M
  fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4931
4.49M
}
4932
4933
/* Add a FT_PROTOCOL to a proto_tree */
4934
proto_item *
4935
proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4936
             unsigned start, int length, const char *format, ...)
4937
7.87M
{
4938
7.87M
  proto_item    *pi;
4939
7.87M
  field_info    *new_fi;
4940
7.87M
  tvbuff_t    *protocol_tvb;
4941
7.87M
  va_list      ap;
4942
7.87M
  header_field_info *hfinfo;
4943
7.87M
  char* protocol_rep;
4944
4945
7.87M
  CHECK_FOR_NULL_TREE(tree);
4946
4947
7.86M
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4948
4949
2.96M
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
4950
4951
  /*
4952
   * This can throw an exception when it calls get_hfi_length before
4953
   * it allocates anything, if length is nonzero and start is past
4954
   * the end of the tvb. Afterwards it can't throw an exception,
4955
   * as length is clamped to the captured length remaining.
4956
   */
4957
2.96M
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4958
2.96M
  new_fi = PNODE_FINFO(pi);
4959
  /* Start the protocol_tvb at the correct start offset, but allow it
4960
   * to be lengthened later via finfo_set_len. */
4961
2.96M
  protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL;
4962
4963
2.96M
  va_start(ap, format);
4964
2.96M
  protocol_rep = ws_strdup_vprintf(format, ap);
4965
2.96M
  proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4966
2.96M
  g_free(protocol_rep);
4967
2.96M
  va_end(ap);
4968
4969
2.96M
  TRY_TO_FAKE_THIS_REPR(pi);
4970
4971
2.96M
  va_start(ap, format);
4972
2.96M
  proto_tree_set_representation(pi, format, ap);
4973
2.96M
  va_end(ap);
4974
4975
2.96M
  return pi;
4976
2.96M
}
4977
4978
/* Add a FT_BYTES to a proto_tree */
4979
proto_item *
4980
proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4981
         int length, const uint8_t *start_ptr)
4982
256k
{
4983
256k
  proto_item    *pi;
4984
256k
  header_field_info *hfinfo;
4985
256k
  int     item_length;
4986
4987
256k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4988
256k
  get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA);
4989
256k
  test_length(hfinfo, tvb, start, item_length, ENC_NA);
4990
4991
256k
  CHECK_FOR_NULL_TREE(tree);
4992
4993
255k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4994
4995
192k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
4996
4997
192k
  if (start_ptr == NULL && tvb != NULL)
4998
187k
    start_ptr = tvb_get_ptr(tvb, start, length);
4999
5000
192k
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5001
192k
  proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
5002
5003
192k
  return pi;
5004
255k
}
5005
5006
/* Add a FT_BYTES to a proto_tree */
5007
proto_item *
5008
proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5009
             int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
5010
2.94k
{
5011
2.94k
  proto_item    *pi;
5012
2.94k
  header_field_info *hfinfo;
5013
2.94k
  int           item_length;
5014
5015
2.94k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
5016
2.94k
  get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA);
5017
2.94k
  test_length(hfinfo, tvb, start, item_length, ENC_NA);
5018
5019
2.94k
  CHECK_FOR_NULL_TREE(tree);
5020
5021
2.94k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5022
5023
2.93k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
5024
5025
2.93k
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
5026
2.93k
  proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);
5027
5028
2.93k
  return pi;
5029
2.94k
}
5030
5031
proto_item *
5032
proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5033
          unsigned start, int length,
5034
          const uint8_t *start_ptr,
5035
          const char *format, ...)
5036
67.6k
{
5037
67.6k
  proto_item    *pi;
5038
67.6k
  va_list      ap;
5039
5040
67.6k
  pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
5041
5042
67.6k
  TRY_TO_FAKE_THIS_REPR_NESTED(pi);
5043
5044
12.4k
  va_start(ap, format);
5045
12.4k
  proto_tree_set_representation_value(pi, format, ap);
5046
12.4k
  va_end(ap);
5047
5048
12.4k
  return pi;
5049
67.6k
}
5050
5051
proto_item *
5052
proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5053
          unsigned start, int length, const uint8_t *start_ptr,
5054
          const char *format, ...)
5055
186k
{
5056
186k
  proto_item    *pi;
5057
186k
  va_list      ap;
5058
5059
186k
  pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
5060
5061
186k
  TRY_TO_FAKE_THIS_REPR_NESTED(pi);
5062
5063
177k
  va_start(ap, format);
5064
177k
  proto_tree_set_representation(pi, format, ap);
5065
177k
  va_end(ap);
5066
5067
177k
  return pi;
5068
186k
}
5069
5070
static void
5071
proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
5072
1.69M
{
5073
1.69M
  DISSECTOR_ASSERT(length >= 0);
5074
1.69M
  DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
5075
5076
1.69M
  fvalue_set_bytes_data(fi->value, start_ptr, length);
5077
1.69M
}
5078
5079
5080
static void
5081
proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length)
5082
1.49M
{
5083
1.49M
  tvb_ensure_bytes_exist(tvb, offset, length);
5084
1.49M
  proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
5085
1.49M
}
5086
5087
static void
5088
proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
5089
0
{
5090
0
  GByteArray *bytes;
5091
5092
0
  DISSECTOR_ASSERT(value != NULL);
5093
5094
0
  bytes = byte_array_dup(value);
5095
5096
0
  fvalue_set_byte_array(fi->value, bytes);
5097
0
}
5098
5099
/* Add a FT_*TIME to a proto_tree */
5100
proto_item *
5101
proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5102
        unsigned length, const nstime_t *value_ptr)
5103
1.39M
{
5104
1.39M
  proto_item    *pi;
5105
1.39M
  header_field_info *hfinfo;
5106
5107
1.39M
  CHECK_FOR_NULL_TREE(tree);
5108
5109
1.39M
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5110
5111
1.38M
  DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
5112
5113
1.38M
  pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5114
1.38M
  proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
5115
5116
1.38M
  return pi;
5117
1.39M
}
5118
5119
proto_item *
5120
proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5121
         unsigned start, unsigned length, nstime_t *value_ptr,
5122
         const char *format, ...)
5123
5.43k
{
5124
5.43k
  proto_item    *pi;
5125
5.43k
  va_list      ap;
5126
5127
5.43k
  pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5128
5.43k
  if (pi != tree) {
5129
5.43k
    va_start(ap, format);
5130
5.43k
    proto_tree_set_representation_value(pi, format, ap);
5131
5.43k
    va_end(ap);
5132
5.43k
  }
5133
5134
5.43k
  return pi;
5135
5.43k
}
5136
5137
proto_item *
5138
proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5139
         unsigned start, unsigned length, nstime_t *value_ptr,
5140
         const char *format, ...)
5141
139
{
5142
139
  proto_item    *pi;
5143
139
  va_list      ap;
5144
5145
139
  pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5146
139
  if (pi != tree) {
5147
139
    TRY_TO_FAKE_THIS_REPR(pi);
5148
5149
139
    va_start(ap, format);
5150
139
    proto_tree_set_representation(pi, format, ap);
5151
139
    va_end(ap);
5152
139
  }
5153
5154
139
  return pi;
5155
139
}
5156
5157
/* Set the FT_*TIME value */
5158
static void
5159
proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5160
1.38M
{
5161
1.38M
  DISSECTOR_ASSERT(value_ptr != NULL);
5162
5163
1.38M
  fvalue_set_time(fi->value, value_ptr);
5164
1.38M
}
5165
5166
/* Add a FT_IPXNET to a proto_tree */
5167
proto_item *
5168
proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5169
          unsigned length, uint32_t value)
5170
23.8k
{
5171
23.8k
  proto_item    *pi;
5172
23.8k
  header_field_info *hfinfo;
5173
5174
23.8k
  CHECK_FOR_NULL_TREE(tree);
5175
5176
23.8k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5177
5178
23.5k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
5179
5180
23.5k
  pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5181
23.5k
  proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
5182
5183
23.5k
  return pi;
5184
23.8k
}
5185
5186
proto_item *
5187
proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5188
           unsigned start, unsigned length, uint32_t value,
5189
           const char *format, ...)
5190
60
{
5191
60
  proto_item    *pi;
5192
60
  va_list      ap;
5193
5194
60
  pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5195
60
  if (pi != tree) {
5196
60
    va_start(ap, format);
5197
60
    proto_tree_set_representation_value(pi, format, ap);
5198
60
    va_end(ap);
5199
60
  }
5200
5201
60
  return pi;
5202
60
}
5203
5204
proto_item *
5205
proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5206
           unsigned start, unsigned length, uint32_t value,
5207
           const char *format, ...)
5208
0
{
5209
0
  proto_item    *pi;
5210
0
  va_list      ap;
5211
5212
0
  pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5213
0
  if (pi != tree) {
5214
0
    TRY_TO_FAKE_THIS_REPR(pi);
5215
5216
0
    va_start(ap, format);
5217
0
    proto_tree_set_representation(pi, format, ap);
5218
0
    va_end(ap);
5219
0
  }
5220
5221
0
  return pi;
5222
0
}
5223
5224
/* Set the FT_IPXNET value */
5225
static void
5226
proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5227
24.7k
{
5228
24.7k
  fvalue_set_uinteger(fi->value, value);
5229
24.7k
}
5230
5231
/* Add a FT_IPv4 to a proto_tree */
5232
proto_item *
5233
proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5234
        unsigned length, ws_in4_addr value)
5235
362k
{
5236
362k
  proto_item    *pi;
5237
362k
  header_field_info *hfinfo;
5238
5239
362k
  CHECK_FOR_NULL_TREE(tree);
5240
5241
362k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5242
5243
285k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
5244
5245
285k
  pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5246
285k
  proto_tree_set_ipv4(PNODE_FINFO(pi), value);
5247
5248
285k
  return pi;
5249
362k
}
5250
5251
proto_item *
5252
proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5253
         unsigned start, unsigned length, ws_in4_addr value,
5254
         const char *format, ...)
5255
7.49k
{
5256
7.49k
  proto_item    *pi;
5257
7.49k
  va_list      ap;
5258
5259
7.49k
  pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5260
7.49k
  if (pi != tree) {
5261
7.49k
    va_start(ap, format);
5262
7.49k
    proto_tree_set_representation_value(pi, format, ap);
5263
7.49k
    va_end(ap);
5264
7.49k
  }
5265
5266
7.49k
  return pi;
5267
7.49k
}
5268
5269
proto_item *
5270
proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5271
         unsigned start, unsigned length, ws_in4_addr value,
5272
         const char *format, ...)
5273
5.18k
{
5274
5.18k
  proto_item    *pi;
5275
5.18k
  va_list      ap;
5276
5277
5.18k
  pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5278
5.18k
  if (pi != tree) {
5279
5.18k
    TRY_TO_FAKE_THIS_REPR(pi);
5280
5281
4.57k
    va_start(ap, format);
5282
4.57k
    proto_tree_set_representation(pi, format, ap);
5283
4.57k
    va_end(ap);
5284
4.57k
  }
5285
5286
4.57k
  return pi;
5287
5.18k
}
5288
5289
/* Set the FT_IPv4 value */
5290
static void
5291
proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5292
319k
{
5293
319k
  ipv4_addr_and_mask ipv4;
5294
319k
  ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5295
319k
  fvalue_set_ipv4(fi->value, &ipv4);
5296
319k
}
5297
5298
/* Add a FT_IPv6 to a proto_tree */
5299
proto_item *
5300
proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5301
        unsigned length, const ws_in6_addr *value)
5302
84.5k
{
5303
84.5k
  proto_item    *pi;
5304
84.5k
  header_field_info *hfinfo;
5305
5306
84.5k
  CHECK_FOR_NULL_TREE(tree);
5307
5308
84.5k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5309
5310
14.1k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
5311
5312
14.1k
  pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5313
14.1k
  proto_tree_set_ipv6(PNODE_FINFO(pi), value);
5314
5315
14.1k
  return pi;
5316
84.5k
}
5317
5318
proto_item *
5319
proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5320
         unsigned start, unsigned length,
5321
         const ws_in6_addr *value_ptr,
5322
         const char *format, ...)
5323
7.10k
{
5324
7.10k
  proto_item    *pi;
5325
7.10k
  va_list      ap;
5326
5327
7.10k
  pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5328
7.10k
  if (pi != tree) {
5329
7.10k
    va_start(ap, format);
5330
7.10k
    proto_tree_set_representation_value(pi, format, ap);
5331
7.10k
    va_end(ap);
5332
7.10k
  }
5333
5334
7.10k
  return pi;
5335
7.10k
}
5336
5337
proto_item *
5338
proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5339
         unsigned start, unsigned length,
5340
         const ws_in6_addr *value_ptr,
5341
         const char *format, ...)
5342
3.48k
{
5343
3.48k
  proto_item    *pi;
5344
3.48k
  va_list      ap;
5345
5346
3.48k
  pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5347
3.48k
  if (pi != tree) {
5348
3.48k
    TRY_TO_FAKE_THIS_REPR(pi);
5349
5350
3.24k
    va_start(ap, format);
5351
3.24k
    proto_tree_set_representation(pi, format, ap);
5352
3.24k
    va_end(ap);
5353
3.24k
  }
5354
5355
3.24k
  return pi;
5356
3.48k
}
5357
5358
/* Set the FT_IPv6 value */
5359
static void
5360
proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5361
131k
{
5362
131k
  DISSECTOR_ASSERT(value != NULL);
5363
131k
  ipv6_addr_and_prefix ipv6;
5364
131k
  ipv6.addr = *value;
5365
131k
  ipv6.prefix = 128;
5366
131k
  fvalue_set_ipv6(fi->value, &ipv6);
5367
131k
}
5368
5369
static void
5370
proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5371
116k
{
5372
116k
  proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5373
116k
}
5374
5375
/* Set the FT_FCWWN value */
5376
static void
5377
proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5378
985
{
5379
985
  DISSECTOR_ASSERT(value_ptr != NULL);
5380
985
  fvalue_set_fcwwn(fi->value, value_ptr);
5381
985
}
5382
5383
static void
5384
proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5385
985
{
5386
985
  proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5387
985
}
5388
5389
/* Add a FT_GUID to a proto_tree */
5390
proto_item *
5391
proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5392
        unsigned length, const e_guid_t *value_ptr)
5393
1.92k
{
5394
1.92k
  proto_item    *pi;
5395
1.92k
  header_field_info *hfinfo;
5396
5397
1.92k
  CHECK_FOR_NULL_TREE(tree);
5398
5399
1.92k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5400
5401
1.91k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
5402
5403
1.91k
  pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5404
1.91k
  proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
5405
5406
1.91k
  return pi;
5407
1.92k
}
5408
5409
proto_item *
5410
proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5411
         unsigned start, unsigned length,
5412
         const e_guid_t *value_ptr,
5413
         const char *format, ...)
5414
885
{
5415
885
  proto_item    *pi;
5416
885
  va_list      ap;
5417
5418
885
  pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5419
885
  if (pi != tree) {
5420
885
    va_start(ap, format);
5421
885
    proto_tree_set_representation_value(pi, format, ap);
5422
885
    va_end(ap);
5423
885
  }
5424
5425
885
  return pi;
5426
885
}
5427
5428
proto_item *
5429
proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5430
         unsigned start, unsigned length, const e_guid_t *value_ptr,
5431
         const char *format, ...)
5432
1.00k
{
5433
1.00k
  proto_item    *pi;
5434
1.00k
  va_list      ap;
5435
5436
1.00k
  pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5437
1.00k
  if (pi != tree) {
5438
1.00k
    TRY_TO_FAKE_THIS_REPR(pi);
5439
5440
1.00k
    va_start(ap, format);
5441
1.00k
    proto_tree_set_representation(pi, format, ap);
5442
1.00k
    va_end(ap);
5443
1.00k
  }
5444
5445
1.00k
  return pi;
5446
1.00k
}
5447
5448
/* Set the FT_GUID value */
5449
static void
5450
proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5451
3.60k
{
5452
3.60k
  DISSECTOR_ASSERT(value_ptr != NULL);
5453
3.60k
  fvalue_set_guid(fi->value, value_ptr);
5454
3.60k
}
5455
5456
static void
5457
proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start,
5458
      const unsigned encoding)
5459
1.69k
{
5460
1.69k
  e_guid_t guid;
5461
5462
1.69k
  tvb_get_guid(tvb, start, &guid, encoding);
5463
1.69k
  proto_tree_set_guid(fi, &guid);
5464
1.69k
}
5465
5466
/* Add a FT_OID to a proto_tree */
5467
proto_item *
5468
proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5469
       unsigned length, const uint8_t* value_ptr)
5470
0
{
5471
0
  proto_item    *pi;
5472
0
  header_field_info *hfinfo;
5473
5474
0
  CHECK_FOR_NULL_TREE(tree);
5475
5476
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5477
5478
0
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
5479
5480
0
  pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5481
0
  proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
5482
5483
0
  return pi;
5484
0
}
5485
5486
proto_item *
5487
proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5488
        unsigned start, unsigned length,
5489
        const uint8_t* value_ptr,
5490
        const char *format, ...)
5491
0
{
5492
0
  proto_item    *pi;
5493
0
  va_list      ap;
5494
5495
0
  pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5496
0
  if (pi != tree) {
5497
0
    va_start(ap, format);
5498
0
    proto_tree_set_representation_value(pi, format, ap);
5499
0
    va_end(ap);
5500
0
  }
5501
5502
0
  return pi;
5503
0
}
5504
5505
proto_item *
5506
proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5507
        unsigned start, unsigned length, const uint8_t* value_ptr,
5508
        const char *format, ...)
5509
0
{
5510
0
  proto_item    *pi;
5511
0
  va_list      ap;
5512
5513
0
  pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5514
0
  if (pi != tree) {
5515
0
    TRY_TO_FAKE_THIS_REPR(pi);
5516
5517
0
    va_start(ap, format);
5518
0
    proto_tree_set_representation(pi, format, ap);
5519
0
    va_end(ap);
5520
0
  }
5521
5522
0
  return pi;
5523
0
}
5524
5525
/* Set the FT_OID value */
5526
static void
5527
proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length)
5528
1.72k
{
5529
1.72k
  GByteArray *bytes;
5530
5531
1.72k
  DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
5532
5533
1.72k
  bytes = g_byte_array_new();
5534
1.72k
  if (length > 0) {
5535
1.64k
    g_byte_array_append(bytes, value_ptr, length);
5536
1.64k
  }
5537
1.72k
  fvalue_set_byte_array(fi->value, bytes);
5538
1.72k
}
5539
5540
static void
5541
proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5542
1.72k
{
5543
1.72k
  proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5544
1.72k
}
5545
5546
/* Set the FT_SYSTEM_ID value */
5547
static void
5548
proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length)
5549
8.42k
{
5550
8.42k
  GByteArray *bytes;
5551
5552
8.42k
  DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
5553
5554
8.42k
  bytes = g_byte_array_new();
5555
8.42k
  if (length > 0) {
5556
7.65k
    g_byte_array_append(bytes, value_ptr, length);
5557
7.65k
  }
5558
8.42k
  fvalue_set_byte_array(fi->value, bytes);
5559
8.42k
}
5560
5561
static void
5562
proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5563
8.42k
{
5564
8.42k
  proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5565
8.42k
}
5566
5567
/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5568
 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5569
 * is destroyed. */
5570
proto_item *
5571
proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5572
          int length, const char* value)
5573
10.0M
{
5574
10.0M
  proto_item    *pi;
5575
10.0M
  header_field_info *hfinfo;
5576
10.0M
  int     item_length;
5577
5578
10.0M
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
5579
10.0M
  get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA);
5580
  /*
5581
   * Special case - if the length is 0, skip the test, so that
5582
   * we can have an empty string right after the end of the
5583
   * packet.  (This handles URL-encoded forms where the last field
5584
   * has no value so the form ends right after the =.)
5585
   *
5586
   * XXX - length zero makes sense for FT_STRING, and more or less
5587
   * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5588
   * for FT_STRINGZ (except that a number of fields that should be
5589
   * one of the others are actually registered as FT_STRINGZ.)
5590
   */
5591
10.0M
  if (item_length != 0)
5592
2.54M
    test_length(hfinfo, tvb, start, item_length, ENC_NA);
5593
5594
10.0M
  CHECK_FOR_NULL_TREE(tree);
5595
5596
9.41M
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5597
5598
4.48M
  DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
5599
5600
4.48M
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5601
4.48M
  DISSECTOR_ASSERT(length >= 0);
5602
5603
4.48M
  WS_UTF_8_CHECK(value, -1);
5604
4.48M
  proto_tree_set_string(PNODE_FINFO(pi), value);
5605
5606
4.48M
  return pi;
5607
9.41M
}
5608
5609
proto_item *
5610
proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5611
           unsigned start, int length, const char* value,
5612
           const char *format,
5613
           ...)
5614
1.02M
{
5615
1.02M
  proto_item    *pi;
5616
1.02M
  va_list      ap;
5617
5618
1.02M
  pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5619
1.02M
  if (pi != tree) {
5620
441k
    va_start(ap, format);
5621
441k
    proto_tree_set_representation_value(pi, format, ap);
5622
441k
    va_end(ap);
5623
441k
  }
5624
5625
1.02M
  return pi;
5626
1.02M
}
5627
5628
proto_item *
5629
proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5630
           unsigned start, int length, const char* value,
5631
           const char *format, ...)
5632
641k
{
5633
641k
  proto_item    *pi;
5634
641k
  va_list      ap;
5635
5636
641k
  pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5637
641k
  if (pi != tree) {
5638
641k
    TRY_TO_FAKE_THIS_REPR(pi);
5639
5640
633k
    va_start(ap, format);
5641
633k
    proto_tree_set_representation(pi, format, ap);
5642
633k
    va_end(ap);
5643
633k
  }
5644
5645
633k
  return pi;
5646
641k
}
5647
5648
/* Set the FT_STRING value */
5649
static void
5650
proto_tree_set_string(field_info *fi, const char* value)
5651
4.63M
{
5652
4.63M
  if (value) {
5653
4.25M
    fvalue_set_string(fi->value, value);
5654
4.25M
  } else {
5655
    /*
5656
     * XXX - why is a null value for a string field
5657
     * considered valid?
5658
     */
5659
380k
    fvalue_set_string(fi->value, "[ Null ]");
5660
380k
  }
5661
4.63M
}
5662
5663
/* Set the FT_AX25 value */
5664
static void
5665
proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5666
1.26k
{
5667
1.26k
  fvalue_set_ax25(fi->value, value);
5668
1.26k
}
5669
5670
static void
5671
proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5672
1.26k
{
5673
1.26k
  proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5674
1.26k
}
5675
5676
/* Set the FT_VINES value */
5677
static void
5678
proto_tree_set_vines(field_info *fi, const uint8_t* value)
5679
557
{
5680
557
  fvalue_set_vines(fi->value, value);
5681
557
}
5682
5683
static void
5684
proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5685
557
{
5686
557
  proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
5687
557
}
5688
5689
/* Add a FT_ETHER to a proto_tree */
5690
proto_item *
5691
proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5692
         unsigned length, const uint8_t* value)
5693
3.95k
{
5694
3.95k
  proto_item    *pi;
5695
3.95k
  header_field_info *hfinfo;
5696
5697
3.95k
  CHECK_FOR_NULL_TREE(tree);
5698
5699
3.95k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5700
5701
3.87k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
5702
5703
3.87k
  pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5704
3.87k
  proto_tree_set_ether(PNODE_FINFO(pi), value);
5705
5706
3.87k
  return pi;
5707
3.95k
}
5708
5709
proto_item *
5710
proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5711
          unsigned start, unsigned length, const uint8_t* value,
5712
          const char *format, ...)
5713
0
{
5714
0
  proto_item    *pi;
5715
0
  va_list      ap;
5716
5717
0
  pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5718
0
  if (pi != tree) {
5719
0
    va_start(ap, format);
5720
0
    proto_tree_set_representation_value(pi, format, ap);
5721
0
    va_end(ap);
5722
0
  }
5723
5724
0
  return pi;
5725
0
}
5726
5727
proto_item *
5728
proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5729
          unsigned start, unsigned length, const uint8_t* value,
5730
          const char *format, ...)
5731
80
{
5732
80
  proto_item    *pi;
5733
80
  va_list      ap;
5734
5735
80
  pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5736
80
  if (pi != tree) {
5737
80
    TRY_TO_FAKE_THIS_REPR(pi);
5738
5739
80
    va_start(ap, format);
5740
80
    proto_tree_set_representation(pi, format, ap);
5741
80
    va_end(ap);
5742
80
  }
5743
5744
80
  return pi;
5745
80
}
5746
5747
/* Set the FT_ETHER value */
5748
static void
5749
proto_tree_set_ether(field_info *fi, const uint8_t* value)
5750
227k
{
5751
227k
  fvalue_set_ether(fi->value, value);
5752
227k
}
5753
5754
static void
5755
proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5756
223k
{
5757
223k
  proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
5758
223k
}
5759
5760
/* Add a FT_BOOLEAN to a proto_tree */
5761
proto_item *
5762
proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5763
           unsigned length, uint64_t value)
5764
21.3M
{
5765
21.3M
  proto_item    *pi;
5766
21.3M
  header_field_info *hfinfo;
5767
5768
21.3M
  CHECK_FOR_NULL_TREE(tree);
5769
5770
21.3M
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5771
5772
11.3M
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
5773
5774
11.3M
  pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5775
11.3M
  proto_tree_set_boolean(PNODE_FINFO(pi), value);
5776
5777
11.3M
  return pi;
5778
21.3M
}
5779
5780
proto_item *
5781
proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5782
            tvbuff_t *tvb, unsigned start, unsigned length,
5783
            uint64_t value, const char *format, ...)
5784
10.9k
{
5785
10.9k
  proto_item    *pi;
5786
10.9k
  va_list      ap;
5787
5788
10.9k
  pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5789
10.9k
  if (pi != tree) {
5790
10.9k
    va_start(ap, format);
5791
10.9k
    proto_tree_set_representation_value(pi, format, ap);
5792
10.9k
    va_end(ap);
5793
10.9k
  }
5794
5795
10.9k
  return pi;
5796
10.9k
}
5797
5798
proto_item *
5799
proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5800
            unsigned start, unsigned length, uint64_t value,
5801
            const char *format, ...)
5802
8.16M
{
5803
8.16M
  proto_item    *pi;
5804
8.16M
  va_list      ap;
5805
5806
8.16M
  pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5807
8.16M
  if (pi != tree) {
5808
8.16M
    TRY_TO_FAKE_THIS_REPR(pi);
5809
5810
8.06M
    va_start(ap, format);
5811
8.06M
    proto_tree_set_representation(pi, format, ap);
5812
8.06M
    va_end(ap);
5813
8.06M
  }
5814
5815
8.06M
  return pi;
5816
8.16M
}
5817
5818
/* Set the FT_BOOLEAN value */
5819
static void
5820
proto_tree_set_boolean(field_info *fi, uint64_t value)
5821
13.2M
{
5822
13.2M
  proto_tree_set_uint64(fi, value);
5823
13.2M
}
5824
5825
/* Generate, into "buf", a string showing the bits of a bitfield.
5826
   Return a pointer to the character after that string. */
5827
static char *
5828
other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5829
336k
{
5830
336k
  int i = 0;
5831
336k
  uint64_t bit;
5832
336k
  char *p;
5833
5834
336k
  p = buf;
5835
5836
  /* This is a devel error. It is safer to stop here. */
5837
336k
  DISSECTOR_ASSERT(width >= 1);
5838
5839
336k
  bit = UINT64_C(1) << (width - 1);
5840
4.93M
  for (;;) {
5841
4.93M
    if (mask & bit) {
5842
      /* This bit is part of the field.  Show its value. */
5843
2.80M
      if (val & bit)
5844
803k
        *p++ = '1';
5845
2.00M
      else
5846
2.00M
        *p++ = '0';
5847
2.80M
    } else {
5848
      /* This bit is not part of the field. */
5849
2.12M
      *p++ = '.';
5850
2.12M
    }
5851
4.93M
    bit >>= 1;
5852
4.93M
    i++;
5853
4.93M
    if (i >= width)
5854
336k
      break;
5855
4.59M
    if (i % 4 == 0)
5856
898k
      *p++ = ' ';
5857
4.59M
  }
5858
336k
  *p = '\0';
5859
336k
  return p;
5860
336k
}
5861
5862
static char *
5863
decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5864
335k
{
5865
335k
  char *p;
5866
5867
335k
  p = other_decode_bitfield_value(buf, val, mask, width);
5868
335k
  p = g_stpcpy(p, " = ");
5869
5870
335k
  return p;
5871
335k
}
5872
5873
static char *
5874
other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5875
0
{
5876
0
  int i = 0;
5877
0
  uint64_t bit;
5878
0
  char *p;
5879
5880
0
  p = buf;
5881
5882
  /* This is a devel error. It is safer to stop here. */
5883
0
  DISSECTOR_ASSERT(width >= 1);
5884
5885
0
  bit = UINT64_C(1) << (width - 1);
5886
0
  for (;;) {
5887
0
    if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5888
0
      (mask & bit)) {
5889
      /* This bit is part of the field.  Show its value. */
5890
0
      if (val & bit)
5891
0
        *p++ = '1';
5892
0
      else
5893
0
        *p++ = '0';
5894
0
    } else {
5895
      /* This bit is not part of the field. */
5896
0
      *p++ = '.';
5897
0
    }
5898
0
    bit >>= 1;
5899
0
    i++;
5900
0
    if (i >= width)
5901
0
      break;
5902
0
    if (i % 4 == 0)
5903
0
      *p++ = ' ';
5904
0
  }
5905
5906
0
  *p = '\0';
5907
0
  return p;
5908
0
}
5909
5910
static char *
5911
decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5912
0
{
5913
0
  char *p;
5914
5915
0
  p = other_decode_bitfield_varint_value(buf, val, mask, width);
5916
0
  p = g_stpcpy(p, " = ");
5917
5918
0
  return p;
5919
0
}
5920
5921
/* Add a FT_FLOAT to a proto_tree */
5922
proto_item *
5923
proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5924
         unsigned length, float value)
5925
592k
{
5926
592k
  proto_item    *pi;
5927
592k
  header_field_info *hfinfo;
5928
5929
592k
  CHECK_FOR_NULL_TREE(tree);
5930
5931
592k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5932
5933
329k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
5934
5935
329k
  pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5936
329k
  proto_tree_set_float(PNODE_FINFO(pi), value);
5937
5938
329k
  return pi;
5939
592k
}
5940
5941
proto_item *
5942
proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5943
          unsigned start, unsigned length, float value,
5944
          const char *format, ...)
5945
205k
{
5946
205k
  proto_item    *pi;
5947
205k
  va_list      ap;
5948
5949
205k
  pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5950
205k
  if (pi != tree) {
5951
205k
    va_start(ap, format);
5952
205k
    proto_tree_set_representation_value(pi, format, ap);
5953
205k
    va_end(ap);
5954
205k
  }
5955
5956
205k
  return pi;
5957
205k
}
5958
5959
proto_item *
5960
proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5961
          unsigned start, unsigned length, float value,
5962
          const char *format, ...)
5963
260k
{
5964
260k
  proto_item    *pi;
5965
260k
  va_list      ap;
5966
5967
260k
  pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5968
260k
  if (pi != tree) {
5969
260k
    TRY_TO_FAKE_THIS_REPR(pi);
5970
5971
1.41k
    va_start(ap, format);
5972
1.41k
    proto_tree_set_representation(pi, format, ap);
5973
1.41k
    va_end(ap);
5974
1.41k
  }
5975
5976
1.41k
  return pi;
5977
260k
}
5978
5979
/* Set the FT_FLOAT value */
5980
static void
5981
proto_tree_set_float(field_info *fi, float value)
5982
334k
{
5983
334k
  fvalue_set_floating(fi->value, value);
5984
334k
}
5985
5986
/* Add a FT_DOUBLE to a proto_tree */
5987
proto_item *
5988
proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5989
          unsigned length, double value)
5990
957k
{
5991
957k
  proto_item    *pi;
5992
957k
  header_field_info *hfinfo;
5993
5994
957k
  CHECK_FOR_NULL_TREE(tree);
5995
5996
380k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5997
5998
373k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
5999
6000
373k
  pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6001
373k
  proto_tree_set_double(PNODE_FINFO(pi), value);
6002
6003
373k
  return pi;
6004
380k
}
6005
6006
proto_item *
6007
proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6008
           unsigned start, unsigned length, double value,
6009
           const char *format, ...)
6010
987
{
6011
987
  proto_item    *pi;
6012
987
  va_list      ap;
6013
6014
987
  pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
6015
987
  if (pi != tree) {
6016
987
    va_start(ap, format);
6017
987
    proto_tree_set_representation_value(pi, format, ap);
6018
987
    va_end(ap);
6019
987
  }
6020
6021
987
  return pi;
6022
987
}
6023
6024
proto_item *
6025
proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6026
           unsigned start, unsigned length, double value,
6027
           const char *format, ...)
6028
6
{
6029
6
  proto_item    *pi;
6030
6
  va_list      ap;
6031
6032
6
  pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
6033
6
  if (pi != tree) {
6034
6
    TRY_TO_FAKE_THIS_REPR(pi);
6035
6036
6
    va_start(ap, format);
6037
6
    proto_tree_set_representation(pi, format, ap);
6038
6
    va_end(ap);
6039
6
  }
6040
6041
6
  return pi;
6042
6
}
6043
6044
/* Set the FT_DOUBLE value */
6045
static void
6046
proto_tree_set_double(field_info *fi, double value)
6047
378k
{
6048
378k
  fvalue_set_floating(fi->value, value);
6049
378k
}
6050
6051
/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
6052
proto_item *
6053
proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6054
        unsigned length, uint32_t value)
6055
34.8M
{
6056
34.8M
  proto_item    *pi = NULL;
6057
34.8M
  header_field_info *hfinfo;
6058
6059
34.8M
  CHECK_FOR_NULL_TREE(tree);
6060
6061
33.6M
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
6062
6063
22.0M
  switch (hfinfo->type) {
6064
43
    case FT_CHAR:
6065
4.23M
    case FT_UINT8:
6066
5.89M
    case FT_UINT16:
6067
5.94M
    case FT_UINT24:
6068
21.9M
    case FT_UINT32:
6069
22.0M
    case FT_FRAMENUM:
6070
22.0M
      pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6071
22.0M
      proto_tree_set_uint(PNODE_FINFO(pi), value);
6072
22.0M
      break;
6073
6074
12
    default:
6075
12
      REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, or FT_FRAMENUM",
6076
22.0M
          hfinfo->abbrev);
6077
22.0M
  }
6078
6079
22.0M
  return pi;
6080
22.0M
}
6081
6082
proto_item *
6083
proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6084
         unsigned start, unsigned length, uint32_t value,
6085
         const char *format, ...)
6086
15.0M
{
6087
15.0M
  proto_item    *pi;
6088
15.0M
  va_list      ap;
6089
6090
15.0M
  pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6091
15.0M
  if (pi != tree) {
6092
14.9M
    va_start(ap, format);
6093
14.9M
    proto_tree_set_representation_value(pi, format, ap);
6094
14.9M
    va_end(ap);
6095
14.9M
  }
6096
6097
15.0M
  return pi;
6098
15.0M
}
6099
6100
proto_item *
6101
proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6102
         unsigned start, unsigned length, uint32_t value,
6103
         const char *format, ...)
6104
850k
{
6105
850k
  proto_item    *pi;
6106
850k
  va_list      ap;
6107
6108
850k
  pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6109
850k
  if (pi != tree) {
6110
849k
    TRY_TO_FAKE_THIS_REPR(pi);
6111
6112
671k
    va_start(ap, format);
6113
671k
    proto_tree_set_representation(pi, format, ap);
6114
671k
    va_end(ap);
6115
671k
  }
6116
6117
671k
  return pi;
6118
850k
}
6119
6120
/* Set the FT_UINT{8,16,24,32} value */
6121
static void
6122
proto_tree_set_uint(field_info *fi, uint32_t value)
6123
31.9M
{
6124
31.9M
  const header_field_info *hfinfo;
6125
31.9M
  uint32_t       integer;
6126
6127
31.9M
  hfinfo = fi->hfinfo;
6128
31.9M
  integer = value;
6129
6130
31.9M
  if (hfinfo->bitmask) {
6131
    /* Mask out irrelevant portions */
6132
5.00M
    integer &= (uint32_t)(hfinfo->bitmask);
6133
6134
    /* Shift bits */
6135
5.00M
    integer >>= hfinfo_bitshift(hfinfo);
6136
6137
5.00M
    FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
6138
5.00M
    FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
6139
5.00M
  }
6140
6141
31.9M
  fvalue_set_uinteger(fi->value, integer);
6142
31.9M
}
6143
6144
/* Add FT_UINT{40,48,56,64} to a proto_tree */
6145
proto_item *
6146
proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6147
          unsigned length, uint64_t value)
6148
288k
{
6149
288k
  proto_item    *pi = NULL;
6150
288k
  header_field_info *hfinfo;
6151
6152
288k
  CHECK_FOR_NULL_TREE(tree);
6153
6154
287k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
6155
6156
280k
  switch (hfinfo->type) {
6157
204k
    case FT_UINT40:
6158
211k
    case FT_UINT48:
6159
212k
    case FT_UINT56:
6160
280k
    case FT_UINT64:
6161
280k
    case FT_FRAMENUM:
6162
280k
      pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6163
280k
      proto_tree_set_uint64(PNODE_FINFO(pi), value);
6164
280k
      break;
6165
6166
0
    default:
6167
0
      REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, or FT_FRAMENUM",
6168
280k
          hfinfo->abbrev);
6169
280k
  }
6170
6171
280k
  return pi;
6172
280k
}
6173
6174
proto_item *
6175
proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6176
           unsigned start, unsigned length, uint64_t value,
6177
           const char *format, ...)
6178
6.68k
{
6179
6.68k
  proto_item    *pi;
6180
6.68k
  va_list      ap;
6181
6182
6.68k
  pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6183
6.68k
  if (pi != tree) {
6184
6.68k
    va_start(ap, format);
6185
6.68k
    proto_tree_set_representation_value(pi, format, ap);
6186
6.68k
    va_end(ap);
6187
6.68k
  }
6188
6189
6.68k
  return pi;
6190
6.68k
}
6191
6192
proto_item *
6193
proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6194
           unsigned start, unsigned length, uint64_t value,
6195
           const char *format, ...)
6196
139
{
6197
139
  proto_item    *pi;
6198
139
  va_list      ap;
6199
6200
139
  pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6201
139
  if (pi != tree) {
6202
139
    TRY_TO_FAKE_THIS_REPR(pi);
6203
6204
132
    va_start(ap, format);
6205
132
    proto_tree_set_representation(pi, format, ap);
6206
132
    va_end(ap);
6207
132
  }
6208
6209
132
  return pi;
6210
139
}
6211
6212
/* Set the FT_UINT{40,48,56,64} value */
6213
static void
6214
proto_tree_set_uint64(field_info *fi, uint64_t value)
6215
13.6M
{
6216
13.6M
  const header_field_info *hfinfo;
6217
13.6M
  uint64_t       integer;
6218
6219
13.6M
  hfinfo = fi->hfinfo;
6220
13.6M
  integer = value;
6221
6222
13.6M
  if (hfinfo->bitmask) {
6223
    /* Mask out irrelevant portions */
6224
11.8M
    integer &= hfinfo->bitmask;
6225
6226
    /* Shift bits */
6227
11.8M
    integer >>= hfinfo_bitshift(hfinfo);
6228
6229
11.8M
    FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
6230
11.8M
    FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
6231
11.8M
  }
6232
6233
13.6M
  fvalue_set_uinteger64(fi->value, integer);
6234
13.6M
}
6235
6236
/* Add FT_INT{8,16,24,32} to a proto_tree */
6237
proto_item *
6238
proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6239
       unsigned length, int32_t value)
6240
765k
{
6241
765k
  proto_item    *pi = NULL;
6242
765k
  header_field_info *hfinfo;
6243
6244
765k
  CHECK_FOR_NULL_TREE(tree);
6245
6246
745k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
6247
6248
665k
  switch (hfinfo->type) {
6249
47.4k
    case FT_INT8:
6250
271k
    case FT_INT16:
6251
271k
    case FT_INT24:
6252
665k
    case FT_INT32:
6253
665k
      pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6254
665k
      proto_tree_set_int(PNODE_FINFO(pi), value);
6255
665k
      break;
6256
6257
0
    default:
6258
0
      REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
6259
665k
          hfinfo->abbrev);
6260
665k
  }
6261
6262
665k
  return pi;
6263
665k
}
6264
6265
proto_item *
6266
proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6267
        unsigned start, unsigned length, int32_t value,
6268
        const char *format, ...)
6269
17.6k
{
6270
17.6k
  proto_item  *pi;
6271
17.6k
  va_list      ap;
6272
6273
17.6k
  pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6274
17.6k
  if (pi != tree) {
6275
17.6k
    va_start(ap, format);
6276
17.6k
    proto_tree_set_representation_value(pi, format, ap);
6277
17.6k
    va_end(ap);
6278
17.6k
  }
6279
6280
17.6k
  return pi;
6281
17.6k
}
6282
6283
proto_item *
6284
proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6285
        unsigned start, unsigned length, int32_t value,
6286
        const char *format, ...)
6287
28.8k
{
6288
28.8k
  proto_item *pi;
6289
28.8k
  va_list     ap;
6290
6291
28.8k
  pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6292
28.8k
  if (pi != tree) {
6293
28.8k
    TRY_TO_FAKE_THIS_REPR(pi);
6294
6295
28.2k
    va_start(ap, format);
6296
28.2k
    proto_tree_set_representation(pi, format, ap);
6297
28.2k
    va_end(ap);
6298
28.2k
  }
6299
6300
28.2k
  return pi;
6301
28.8k
}
6302
6303
/* Set the FT_INT{8,16,24,32} value */
6304
static void
6305
proto_tree_set_int(field_info *fi, int32_t value)
6306
854k
{
6307
854k
  const header_field_info *hfinfo;
6308
854k
  uint32_t       integer;
6309
854k
  int      no_of_bits;
6310
6311
854k
  hfinfo = fi->hfinfo;
6312
854k
  integer = (uint32_t) value;
6313
6314
854k
  if (hfinfo->bitmask) {
6315
    /* Mask out irrelevant portions */
6316
2.69k
    integer &= (uint32_t)(hfinfo->bitmask);
6317
6318
    /* Shift bits */
6319
2.69k
    integer >>= hfinfo_bitshift(hfinfo);
6320
6321
2.69k
    no_of_bits = ws_count_ones(hfinfo->bitmask);
6322
2.69k
    integer = ws_sign_ext32(integer, no_of_bits);
6323
6324
2.69k
    FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
6325
2.69k
    FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
6326
2.69k
  }
6327
6328
854k
  fvalue_set_sinteger(fi->value, integer);
6329
854k
}
6330
6331
/* Add FT_INT{40,48,56,64} to a proto_tree */
6332
proto_item *
6333
proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6334
         unsigned length, int64_t value)
6335
56.2k
{
6336
56.2k
  proto_item    *pi = NULL;
6337
56.2k
  header_field_info *hfinfo;
6338
6339
56.2k
  CHECK_FOR_NULL_TREE(tree);
6340
6341
56.1k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
6342
6343
55.9k
  switch (hfinfo->type) {
6344
0
    case FT_INT40:
6345
0
    case FT_INT48:
6346
0
    case FT_INT56:
6347
55.9k
    case FT_INT64:
6348
55.9k
      pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6349
55.9k
      proto_tree_set_int64(PNODE_FINFO(pi), value);
6350
55.9k
      break;
6351
6352
0
    default:
6353
0
      REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
6354
55.9k
          hfinfo->abbrev);
6355
55.9k
  }
6356
6357
55.9k
  return pi;
6358
55.9k
}
6359
6360
proto_item *
6361
proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6362
          unsigned start, unsigned length, int64_t value,
6363
          const char *format, ...)
6364
2.03k
{
6365
2.03k
  proto_item    *pi;
6366
2.03k
  va_list      ap;
6367
6368
2.03k
  pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6369
2.03k
  if (pi != tree) {
6370
2.03k
    va_start(ap, format);
6371
2.03k
    proto_tree_set_representation_value(pi, format, ap);
6372
2.03k
    va_end(ap);
6373
2.03k
  }
6374
6375
2.03k
  return pi;
6376
2.03k
}
6377
6378
/* Set the FT_INT{40,48,56,64} value */
6379
static void
6380
proto_tree_set_int64(field_info *fi, int64_t value)
6381
64.8k
{
6382
64.8k
  const header_field_info *hfinfo;
6383
64.8k
  uint64_t       integer;
6384
64.8k
  int      no_of_bits;
6385
6386
64.8k
  hfinfo = fi->hfinfo;
6387
64.8k
  integer = value;
6388
6389
64.8k
  if (hfinfo->bitmask) {
6390
    /* Mask out irrelevant portions */
6391
0
    integer &= hfinfo->bitmask;
6392
6393
    /* Shift bits */
6394
0
    integer >>= hfinfo_bitshift(hfinfo);
6395
6396
0
    no_of_bits = ws_count_ones(hfinfo->bitmask);
6397
0
    integer = ws_sign_ext64(integer, no_of_bits);
6398
6399
0
    FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
6400
0
    FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
6401
0
  }
6402
6403
64.8k
  fvalue_set_sinteger64(fi->value, integer);
6404
64.8k
}
6405
6406
proto_item *
6407
proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6408
         unsigned start, unsigned length, int64_t value,
6409
         const char *format, ...)
6410
9.64k
{
6411
9.64k
  proto_item    *pi;
6412
9.64k
  va_list      ap;
6413
6414
9.64k
  pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6415
9.64k
  if (pi != tree) {
6416
9.64k
    TRY_TO_FAKE_THIS_REPR(pi);
6417
6418
9.60k
    va_start(ap, format);
6419
9.60k
    proto_tree_set_representation(pi, format, ap);
6420
9.60k
    va_end(ap);
6421
9.60k
  }
6422
6423
9.60k
  return pi;
6424
9.64k
}
6425
6426
/* Add a FT_EUI64 to a proto_tree */
6427
proto_item *
6428
proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6429
         unsigned length, const uint64_t value)
6430
3.60k
{
6431
3.60k
  proto_item    *pi;
6432
3.60k
  header_field_info *hfinfo;
6433
6434
3.60k
  CHECK_FOR_NULL_TREE(tree);
6435
6436
3.60k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
6437
6438
3.59k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
6439
6440
3.59k
  pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6441
3.59k
  proto_tree_set_eui64(PNODE_FINFO(pi), value);
6442
6443
3.59k
  return pi;
6444
3.60k
}
6445
6446
proto_item *
6447
proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6448
          unsigned start, unsigned length, const uint64_t value,
6449
          const char *format, ...)
6450
0
{
6451
0
  proto_item    *pi;
6452
0
  va_list      ap;
6453
6454
0
  pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6455
0
  if (pi != tree) {
6456
0
    va_start(ap, format);
6457
0
    proto_tree_set_representation_value(pi, format, ap);
6458
0
    va_end(ap);
6459
0
  }
6460
6461
0
  return pi;
6462
0
}
6463
6464
proto_item *
6465
proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6466
          unsigned start, unsigned length, const uint64_t value,
6467
          const char *format, ...)
6468
0
{
6469
0
  proto_item    *pi;
6470
0
  va_list      ap;
6471
6472
0
  pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6473
0
  if (pi != tree) {
6474
0
    TRY_TO_FAKE_THIS_REPR(pi);
6475
6476
0
    va_start(ap, format);
6477
0
    proto_tree_set_representation(pi, format, ap);
6478
0
    va_end(ap);
6479
0
  }
6480
6481
0
  return pi;
6482
0
}
6483
6484
/* Set the FT_EUI64 value */
6485
static void
6486
proto_tree_set_eui64(field_info *fi, const uint64_t value)
6487
13.9k
{
6488
13.9k
  uint8_t v[FT_EUI64_LEN];
6489
13.9k
  phtonu64(v, value);
6490
13.9k
  fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN);
6491
13.9k
}
6492
6493
static void
6494
proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding)
6495
10.3k
{
6496
10.3k
  if (encoding)
6497
10.2k
  {
6498
10.2k
    proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6499
10.2k
  } else {
6500
59
    proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6501
59
  }
6502
10.3k
}
6503
6504
proto_item *
6505
proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6506
          const mac_hf_list_t *list_generic,
6507
          int idx, tvbuff_t *tvb,
6508
          proto_tree *tree, unsigned offset)
6509
95.5k
{
6510
95.5k
  uint8_t     addr[6];
6511
95.5k
  const char *addr_name = NULL;
6512
95.5k
  const char *oui_name  = NULL;
6513
95.5k
  proto_item *addr_item = NULL;
6514
95.5k
  proto_tree *addr_tree = NULL;
6515
95.5k
  proto_item *ret_val   = NULL;
6516
6517
95.5k
  if (tree == NULL || list_specific == NULL) {
6518
2.24k
    return NULL;
6519
2.24k
  }
6520
6521
  /* Resolve what we can of the address */
6522
93.3k
  tvb_memcpy(tvb, addr, offset, sizeof addr);
6523
93.3k
  if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6524
93.2k
    addr_name = get_ether_name(addr);
6525
93.2k
  }
6526
93.3k
  if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6527
93.2k
    oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6528
93.2k
  }
6529
6530
  /* Add the item for the specific address type */
6531
93.3k
  ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN);
6532
93.3k
  if (idx >= 0) {
6533
86.0k
    addr_tree = proto_item_add_subtree(ret_val, idx);
6534
86.0k
  }
6535
7.32k
  else {
6536
7.32k
    addr_tree = tree;
6537
7.32k
  }
6538
6539
93.3k
  if (list_specific->hf_addr_resolved != NULL) {
6540
93.2k
    addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6541
93.2k
              tvb, offset, 6, addr_name);
6542
93.2k
    proto_item_set_generated(addr_item);
6543
93.2k
    proto_item_set_hidden(addr_item);
6544
93.2k
  }
6545
6546
93.3k
  if (list_specific->hf_oui != NULL) {
6547
93.2k
    addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN);
6548
93.2k
    proto_item_set_generated(addr_item);
6549
93.2k
    proto_item_set_hidden(addr_item);
6550
6551
93.2k
    if (oui_name != NULL && list_specific->hf_oui_resolved != NULL) {
6552
25.9k
      addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6553
25.9k
      proto_item_set_generated(addr_item);
6554
25.9k
      proto_item_set_hidden(addr_item);
6555
25.9k
    }
6556
93.2k
  }
6557
6558
93.3k
  if (list_specific->hf_lg != NULL) {
6559
86.0k
    proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN);
6560
86.0k
  }
6561
93.3k
  if (list_specific->hf_ig != NULL) {
6562
86.0k
    proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN);
6563
86.0k
  }
6564
6565
  /* Were we given a list for generic address fields? If not, stop here */
6566
93.3k
  if (list_generic == NULL) {
6567
24.3k
    return ret_val;
6568
24.3k
  }
6569
6570
68.9k
  addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN);
6571
68.9k
  proto_item_set_hidden(addr_item);
6572
6573
68.9k
  if (list_generic->hf_addr_resolved != NULL) {
6574
68.9k
    addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6575
68.9k
              tvb, offset, 6, addr_name);
6576
68.9k
    proto_item_set_generated(addr_item);
6577
68.9k
    proto_item_set_hidden(addr_item);
6578
68.9k
  }
6579
6580
68.9k
  if (list_generic->hf_oui != NULL) {
6581
68.9k
    addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN);
6582
68.9k
    proto_item_set_generated(addr_item);
6583
68.9k
    proto_item_set_hidden(addr_item);
6584
6585
68.9k
    if (oui_name != NULL && list_generic->hf_oui_resolved != NULL) {
6586
15.7k
      addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6587
15.7k
      proto_item_set_generated(addr_item);
6588
15.7k
      proto_item_set_hidden(addr_item);
6589
15.7k
    }
6590
68.9k
  }
6591
6592
68.9k
  if (list_generic->hf_lg != NULL) {
6593
68.9k
    addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN);
6594
68.9k
    proto_item_set_hidden(addr_item);
6595
68.9k
  }
6596
68.9k
  if (list_generic->hf_ig != NULL) {
6597
68.9k
    addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN);
6598
68.9k
    proto_item_set_hidden(addr_item);
6599
68.9k
  }
6600
68.9k
  return ret_val;
6601
93.3k
}
6602
6603
static proto_item *
6604
proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6605
61.8M
{
6606
61.8M
  proto_node *pnode, *tnode, *sibling;
6607
61.8M
  field_info *tfi;
6608
61.8M
  unsigned depth = 1;
6609
6610
61.8M
  ws_assert(tree);
6611
6612
  /*
6613
   * Restrict our depth. proto_tree_traverse_pre_order and
6614
   * proto_tree_traverse_post_order (and possibly others) are recursive
6615
   * so we need to be mindful of our stack size.
6616
   */
6617
61.8M
  if (tree->first_child == NULL) {
6618
287M
    for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
6619
272M
      depth++;
6620
272M
      if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)) {
6621
0
        THROW_MESSAGE(DissectorError, wmem_strdup_printf(PNODE_POOL(tree),
6622
0
                 "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)",
6623
0
                 prefs.gui_max_tree_depth,
6624
0
                 hfinfo->name, hfinfo->abbrev, G_STRFUNC, __LINE__));
6625
0
      }
6626
272M
    }
6627
14.2M
  }
6628
6629
  /*
6630
   * Make sure "tree" is ready to have subtrees under it, by
6631
   * checking whether it's been given an ett_ value.
6632
   *
6633
   * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6634
   * node of the protocol tree.  That node is not displayed,
6635
   * so it doesn't need an ett_ value to remember whether it
6636
   * was expanded.
6637
   */
6638
61.8M
  tnode = tree;
6639
61.8M
  tfi = PNODE_FINFO(tnode);
6640
61.8M
  if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6641
0
    REPORT_DISSECTOR_BUG("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",
6642
0
             hfinfo->name, hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__);
6643
    /* XXX - is it safe to continue here? */
6644
0
  }
6645
6646
61.8M
  pnode = wmem_new(PNODE_POOL(tree), proto_node);
6647
61.8M
  PROTO_NODE_INIT(pnode);
6648
61.8M
  pnode->parent = tnode;
6649
61.8M
  PNODE_HFINFO(pnode) = hfinfo;
6650
61.8M
  PNODE_FINFO(pnode) = NULL; // Faked
6651
61.8M
  pnode->tree_data = PTREE_DATA(tree);
6652
6653
61.8M
  if (tnode->last_child != NULL) {
6654
47.6M
    sibling = tnode->last_child;
6655
47.6M
    DISSECTOR_ASSERT(sibling->next == NULL);
6656
47.6M
    sibling->next = pnode;
6657
47.6M
  } else
6658
14.2M
    tnode->first_child = pnode;
6659
61.8M
  tnode->last_child = pnode;
6660
6661
  /* We should not be adding a fake node for an interesting field */
6662
61.8M
  ws_assert(hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT);
6663
6664
  /* XXX - Should the proto_item have a header_field_info member, at least
6665
   * for faked items, to know what hfi was faked? (Some dissectors look at
6666
   * the tree items directly.)
6667
   */
6668
61.8M
  return (proto_item *)pnode;
6669
61.8M
}
6670
6671
/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6672
static proto_item *
6673
proto_tree_add_node(proto_tree *tree, field_info *fi)
6674
74.6M
{
6675
74.6M
  proto_node *pnode, *tnode, *sibling;
6676
74.6M
  field_info *tfi;
6677
74.6M
  unsigned depth = 1;
6678
6679
74.6M
  ws_assert(tree);
6680
6681
  /*
6682
   * Restrict our depth. proto_tree_traverse_pre_order and
6683
   * proto_tree_traverse_post_order (and possibly others) are recursive
6684
   * so we need to be mindful of our stack size.
6685
   */
6686
74.6M
  if (tree->first_child == NULL) {
6687
266M
    for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
6688
246M
      depth++;
6689
246M
      if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)) {
6690
        /* The fvalue_t is pool-allocated; just release the
6691
         * type-specific data it owns (see new_field_info()). */
6692
1
        fvalue_cleanup(fi->value);
6693
1
        fi->value = NULL;
6694
1
        THROW_MESSAGE(DissectorError, wmem_strdup_printf(PNODE_POOL(tree),
6695
1
                 "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)",
6696
1
                 prefs.gui_max_tree_depth,
6697
1
                 fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__));
6698
1
      }
6699
246M
    }
6700
20.3M
  }
6701
6702
  /*
6703
   * Make sure "tree" is ready to have subtrees under it, by
6704
   * checking whether it's been given an ett_ value.
6705
   *
6706
   * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6707
   * node of the protocol tree.  That node is not displayed,
6708
   * so it doesn't need an ett_ value to remember whether it
6709
   * was expanded.
6710
   */
6711
74.6M
  tnode = tree;
6712
74.6M
  tfi = PNODE_FINFO(tnode);
6713
74.6M
  if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6714
    /* Since we are not adding fi to a node, its fvalue won't get
6715
     * cleaned up by proto_tree_free_node(), so release the
6716
     * type-specific data it owns now. The fvalue_t structure itself
6717
     * is pool-allocated (see new_field_info()).
6718
     */
6719
0
    fvalue_cleanup(fi->value);
6720
0
    fi->value = NULL;
6721
0
    REPORT_DISSECTOR_BUG("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",
6722
0
             fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__);
6723
    /* XXX - is it safe to continue here? */
6724
0
  }
6725
6726
74.6M
  pnode = wmem_new(PNODE_POOL(tree), proto_node);
6727
74.6M
  PROTO_NODE_INIT(pnode);
6728
74.6M
  pnode->parent = tnode;
6729
74.6M
  PNODE_HFINFO(pnode) = fi->hfinfo;
6730
74.6M
  PNODE_FINFO(pnode) = fi;
6731
74.6M
  pnode->tree_data = PTREE_DATA(tree);
6732
6733
74.6M
  if (tnode->last_child != NULL) {
6734
54.2M
    sibling = tnode->last_child;
6735
54.2M
    DISSECTOR_ASSERT(sibling->next == NULL);
6736
54.2M
    sibling->next = pnode;
6737
54.2M
  } else
6738
20.3M
    tnode->first_child = pnode;
6739
74.6M
  tnode->last_child = pnode;
6740
6741
74.6M
  tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6742
6743
74.6M
  return (proto_item *)pnode;
6744
74.6M
}
6745
6746
6747
/* Generic way to allocate field_info and add to proto_tree.
6748
 * Sets *pfi to address of newly-allocated field_info struct */
6749
static proto_item *
6750
proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6751
      int *length)
6752
15.8M
{
6753
15.8M
  proto_item *pi;
6754
15.8M
  field_info *fi;
6755
15.8M
  int   item_length;
6756
6757
15.8M
  get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA);
6758
15.8M
  fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6759
15.8M
  pi = proto_tree_add_node(tree, fi);
6760
6761
15.8M
  return pi;
6762
15.8M
}
6763
6764
/* Generic way to allocate field_info and add to proto_tree with unsigned length.
6765
 * Eventually this should replace the other function.
6766
 * Sets *pfi to address of newly-allocated field_info struct */
6767
static proto_item *
6768
proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6769
         unsigned *length)
6770
36.8M
{
6771
36.8M
  proto_item *pi;
6772
36.8M
  field_info *fi;
6773
36.8M
  unsigned  item_length;
6774
6775
36.8M
  get_hfi_length_unsigned(hfinfo, tvb, start, length, &item_length, ENC_NA);
6776
36.8M
  fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6777
36.8M
  pi = proto_tree_add_node(tree, fi);
6778
6779
36.8M
  return pi;
6780
36.8M
}
6781
6782
static void
6783
get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
6784
       int *item_length, const unsigned encoding)
6785
66.5M
{
6786
66.5M
  int length_remaining;
6787
6788
  /*
6789
   * We only allow a null tvbuff if the item has a zero length,
6790
   * i.e. if there's no data backing it.
6791
   */
6792
66.5M
  DISSECTOR_ASSERT(tvb != NULL || *length == 0);
6793
6794
  /*
6795
   * XXX - in some protocols, there are 32-bit unsigned length
6796
   * fields, so lengths in protocol tree and tvbuff routines
6797
   * should really be unsigned.  We should have, for those
6798
   * field types for which "to the end of the tvbuff" makes sense,
6799
   * additional routines that take no length argument and
6800
   * add fields that run to the end of the tvbuff.
6801
   */
6802
66.5M
  if (*length == -1) {
6803
    /*
6804
     * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6805
     * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6806
     * of -1 means "set the length to what remains in the
6807
     * tvbuff".
6808
     *
6809
     * The assumption is either that
6810
     *
6811
     *  1) the length of the item can only be determined
6812
     *     by dissection (typically true of items with
6813
     *     subitems, which are probably FT_NONE or
6814
     *     FT_PROTOCOL)
6815
     *
6816
     * or
6817
     *
6818
     *  2) if the tvbuff is "short" (either due to a short
6819
     *     snapshot length or due to lack of reassembly of
6820
     *     fragments/segments/whatever), we want to display
6821
     *     what's available in the field (probably FT_BYTES
6822
     *     or FT_STRING) and then throw an exception later
6823
     *
6824
     * or
6825
     *
6826
     *  3) the field is defined to be "what's left in the
6827
     *     packet"
6828
     *
6829
     * so we set the length to what remains in the tvbuff so
6830
     * that, if we throw an exception while dissecting, it
6831
     * has what is probably the right value.
6832
     *
6833
     * For FT_STRINGZ, it means "the string is null-terminated,
6834
     * not null-padded; set the length to the actual length
6835
     * of the string", and if the tvbuff if short, we just
6836
     * throw an exception.
6837
     *
6838
     * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6839
     * it means "find the end of the string",
6840
     * and if the tvbuff if short, we just throw an exception.
6841
     *
6842
     * It's not valid for any other type of field.  For those
6843
     * fields, we treat -1 the same way we treat other
6844
     * negative values - we assume the length is a Really
6845
     * Big Positive Number, and throw a ReportedBoundsError
6846
     * exception, under the assumption that the Really Big
6847
     * Length would run past the end of the packet.
6848
     */
6849
1.59M
    if ((FT_IS_INT(hfinfo->type)) || (FT_IS_UINT(hfinfo->type))) {
6850
81
      if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG|ENC_VARINT_SDNV)) {
6851
        /*
6852
         * Leave the length as -1, so our caller knows
6853
         * it was -1.
6854
         */
6855
61
        *item_length = *length;
6856
61
        return;
6857
61
      } else if (encoding & ENC_VARINT_QUIC) {
6858
0
        switch (tvb_get_uint8(tvb, start) >> 6)
6859
0
        {
6860
0
        case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6861
0
          *item_length = 1;
6862
0
          break;
6863
0
        case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6864
0
          *item_length = 2;
6865
0
          break;
6866
0
        case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6867
0
          *item_length = 4;
6868
0
          break;
6869
0
        case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6870
0
          *item_length = 8;
6871
0
          break;
6872
0
        }
6873
0
      }
6874
81
    }
6875
6876
1.59M
    switch (hfinfo->type) {
6877
6878
753k
    case FT_PROTOCOL:
6879
1.00M
    case FT_NONE:
6880
1.59M
    case FT_BYTES:
6881
1.59M
    case FT_STRING:
6882
1.59M
    case FT_STRINGZPAD:
6883
1.59M
    case FT_STRINGZTRUNC:
6884
      /*
6885
       * We allow FT_PROTOCOLs to be zero-length -
6886
       * for example, an ONC RPC NULL procedure has
6887
       * neither arguments nor reply, so the
6888
       * payload for that protocol is empty.
6889
       *
6890
       * We also allow the others to be zero-length -
6891
       * because that's the way the code has been for a
6892
       * long, long time.
6893
       *
6894
       * However, we want to ensure that the start
6895
       * offset is not *past* the byte past the end
6896
       * of the tvbuff: we throw an exception in that
6897
       * case.
6898
       */
6899
1.59M
      *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6900
1.59M
      DISSECTOR_ASSERT(*length >= 0);
6901
1.59M
      break;
6902
6903
622
    case FT_STRINGZ:
6904
      /*
6905
       * Leave the length as -1, so our caller knows
6906
       * it was -1.
6907
       */
6908
622
      break;
6909
6910
28
    default:
6911
28
      THROW(ReportedBoundsError);
6912
28
      DISSECTOR_ASSERT_NOT_REACHED();
6913
1.59M
    }
6914
1.59M
    *item_length = *length;
6915
64.9M
  } else {
6916
64.9M
    if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6917
      /*
6918
       * These types are for interior nodes of the
6919
       * tree, and don't have data associated with
6920
       * them; if the length is negative (XXX - see
6921
       * above) or goes past the end of the tvbuff,
6922
       * cut it short at the end of the tvbuff.
6923
       * That way, if this field is selected in
6924
       * Wireshark, we don't highlight stuff past
6925
       * the end of the data.
6926
       *
6927
       * If we don't have a tvb, then length must be zero,
6928
       * per the DISSECTOR_ASSERT() above.
6929
       *
6930
       * If we do have a tvb, and the length requested is
6931
       * nonzero, we want to ensure that the start offset
6932
       * is not *past* the byte past the end of the tvbuff
6933
       * data: we throw an exception in that case as above.
6934
       */
6935
22.7M
      if (tvb && *length) {
6936
8.29M
        length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6937
8.29M
        if (*length < 0 ||
6938
8.24M
          (*length > 0 &&
6939
8.24M
            (length_remaining < *length)))
6940
1.04M
          *length = length_remaining;
6941
8.29M
      }
6942
22.7M
    }
6943
64.9M
    *item_length = *length;
6944
64.9M
    if (*item_length < 0) {
6945
595
      THROW(ReportedBoundsError);
6946
595
    }
6947
64.9M
  }
6948
66.5M
}
6949
6950
static void
6951
get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6952
  unsigned* item_length, const unsigned encoding _U_)
6953
36.8M
{
6954
36.8M
  unsigned length_remaining;
6955
6956
  /*
6957
   * We only allow a null tvbuff if the item has a zero length,
6958
   * i.e. if there's no data backing it.
6959
   */
6960
36.8M
  DISSECTOR_ASSERT(tvb != NULL || *length == 0);
6961
6962
6963
36.8M
  if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6964
    /*
6965
     * These types are for interior nodes of the
6966
     * tree, and don't have data associated with
6967
     * them; if the length is negative (XXX - see
6968
     * above) or goes past the end of the tvbuff,
6969
     * cut it short at the end of the tvbuff.
6970
     * That way, if this field is selected in
6971
     * Wireshark, we don't highlight stuff past
6972
     * the end of the data.
6973
     *
6974
     * If we don't have a tvb, then length must be zero,
6975
     * per the DISSECTOR_ASSERT() above.
6976
     *
6977
     * If we do have a tvb, and the length requested is
6978
     * nonzero, we want to ensure that the start offset
6979
     * is not *past* the byte past the end of the tvbuff
6980
     * data: we throw an exception in that case as above.
6981
     * (If the length requested is zero, then it's quite
6982
     * likely that the start offset is the byte past the
6983
     * end, but that's ok.)
6984
     */
6985
0
    if (tvb && *length) {
6986
0
      length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6987
0
      if (length_remaining < *length) {
6988
0
        *length = length_remaining;
6989
0
      }
6990
0
    }
6991
0
  }
6992
36.8M
  *item_length = *length;
6993
36.8M
}
6994
6995
static int
6996
get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
6997
    int length, unsigned item_length, const int encoding)
6998
50.9k
{
6999
50.9k
  uint32_t n;
7000
7001
  /*
7002
   * We need to get the correct item length here.
7003
   * That's normally done by proto_tree_new_item(),
7004
   * but we won't be calling it.
7005
   */
7006
50.9k
  switch (hfinfo->type) {
7007
7008
96
  case FT_NONE:
7009
96
  case FT_PROTOCOL:
7010
1.54k
  case FT_BYTES:
7011
    /*
7012
     * The length is the specified length.
7013
     */
7014
1.54k
    break;
7015
7016
4
  case FT_UINT_BYTES:
7017
4
    n = get_uint_value(NULL, tvb, start, length, encoding);
7018
4
    item_length += n;
7019
4
    if ((int)item_length < length) {
7020
0
      THROW(ReportedBoundsError);
7021
0
    }
7022
4
    break;
7023
7024
  /* XXX - make these just FT_UINT? */
7025
33.2k
  case FT_UINT8:
7026
40.7k
  case FT_UINT16:
7027
41.2k
  case FT_UINT24:
7028
43.6k
  case FT_UINT32:
7029
43.6k
  case FT_UINT40:
7030
43.6k
  case FT_UINT48:
7031
43.6k
  case FT_UINT56:
7032
43.6k
  case FT_UINT64:
7033
  /* XXX - make these just FT_INT? */
7034
43.6k
  case FT_INT8:
7035
43.6k
  case FT_INT16:
7036
43.6k
  case FT_INT24:
7037
43.6k
  case FT_INT32:
7038
43.6k
  case FT_INT40:
7039
43.6k
  case FT_INT48:
7040
43.6k
  case FT_INT56:
7041
43.6k
  case FT_INT64:
7042
43.6k
    if (encoding & ENC_VARINT_MASK) {
7043
6
      if (length < -1) {
7044
0
        report_type_length_mismatch(NULL, "a FT_[U]INT", length, true);
7045
0
      }
7046
6
      if (length == -1) {
7047
6
        uint64_t dummy;
7048
        /* This can throw an exception */
7049
        /* XXX - do this without fetching the varint? */
7050
6
        length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN, &dummy, encoding);
7051
6
        if (length == 0) {
7052
0
          THROW(ReportedBoundsError);
7053
0
        }
7054
6
      }
7055
6
      item_length = length;
7056
6
      break;
7057
6
    }
7058
7059
    /*
7060
     * The length is the specified length.
7061
     */
7062
43.6k
    break;
7063
7064
43.6k
  case FT_BOOLEAN:
7065
1.30k
  case FT_CHAR:
7066
1.36k
  case FT_IPv4:
7067
1.36k
  case FT_IPXNET:
7068
1.37k
  case FT_IPv6:
7069
1.37k
  case FT_FCWWN:
7070
1.37k
  case FT_AX25:
7071
1.37k
  case FT_VINES:
7072
5.51k
  case FT_ETHER:
7073
5.51k
  case FT_EUI64:
7074
5.51k
  case FT_GUID:
7075
5.51k
  case FT_OID:
7076
5.51k
  case FT_REL_OID:
7077
5.51k
  case FT_SYSTEM_ID:
7078
5.51k
  case FT_FLOAT:
7079
5.51k
  case FT_DOUBLE:
7080
5.54k
  case FT_STRING:
7081
    /*
7082
     * The length is the specified length.
7083
     */
7084
5.54k
    break;
7085
7086
11
  case FT_STRINGZ:
7087
11
    if (length < -1) {
7088
0
      report_type_length_mismatch(NULL, "a string", length, true);
7089
0
    }
7090
11
    if (length == -1) {
7091
      /* This can throw an exception */
7092
2
      item_length = tvb_strsize_enc(tvb, start, encoding);
7093
2
    }
7094
11
    break;
7095
7096
200
  case FT_UINT_STRING:
7097
200
    n = get_uint_value(NULL, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
7098
200
    item_length += n;
7099
200
    if ((int)item_length < length) {
7100
0
      THROW(ReportedBoundsError);
7101
0
    }
7102
200
    break;
7103
7104
0
  case FT_STRINGZPAD:
7105
0
  case FT_STRINGZTRUNC:
7106
0
  case FT_ABSOLUTE_TIME:
7107
0
  case FT_RELATIVE_TIME:
7108
0
  case FT_IEEE_11073_SFLOAT:
7109
0
  case FT_IEEE_11073_FLOAT:
7110
    /*
7111
     * The length is the specified length.
7112
     */
7113
0
    break;
7114
7115
0
  default:
7116
0
    REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in gset_full_length()",
7117
0
             hfinfo->abbrev,
7118
0
             hfinfo->type,
7119
0
             ftype_name(hfinfo->type));
7120
0
    break;
7121
50.9k
  }
7122
50.9k
  return item_length;
7123
50.9k
}
7124
7125
// This was arbitrarily chosen, but if you're adding 50K items to the tree
7126
// without advancing the offset you should probably take a long, hard look
7127
// at what you're doing.
7128
// We *could* make this a configurable option, but I (Gerald) would like to
7129
// avoid adding yet another nerd knob.
7130
40.8M
# define PROTO_TREE_MAX_IDLE 50000
7131
static field_info *
7132
new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
7133
         const unsigned start, const int item_length)
7134
74.6M
{
7135
74.6M
  field_info *fi;
7136
7137
74.6M
  FIELD_INFO_NEW(PNODE_POOL(tree), fi);
7138
7139
74.6M
  fi->hfinfo     = hfinfo;
7140
74.6M
  fi->start      = start;
7141
74.6M
  fi->start     += (tvb)?tvb_raw_offset(tvb):0;
7142
  /* add the data source tvbuff */
7143
74.6M
  fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
7144
7145
  // If our start offset hasn't advanced after adding many items it probably
7146
  // means we're in a large or infinite loop.
7147
74.6M
  if (fi->start > 0) {
7148
56.7M
    if (fi->ds_tvb == PTREE_DATA(tree)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)->max_start) {
7149
40.8M
      PTREE_DATA(tree)->start_idle_count++;
7150
40.8M
      if (PTREE_DATA(tree)->start_idle_count > PROTO_TREE_MAX_IDLE) {
7151
7
        if (wireshark_abort_on_too_many_items) {
7152
0
          ws_error("Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop",
7153
0
              hfinfo->abbrev, PROTO_TREE_MAX_IDLE);
7154
0
        }
7155
        /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7156
         * but if not, we should hit the max item error earlier,
7157
         * so we shouldn't need to reset the tree count to
7158
         * ensure that the exception handler can add the item. */
7159
7
        THROW_MESSAGE(DissectorError,
7160
7
          wmem_strdup_printf(PNODE_POOL(tree),
7161
7
              "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop",
7162
7
              hfinfo->abbrev, PROTO_TREE_MAX_IDLE));
7163
7
      }
7164
40.8M
    } else {
7165
15.9M
      PTREE_DATA(tree)->idle_count_ds_tvb = fi->ds_tvb;
7166
15.9M
      PTREE_DATA(tree)->max_start = fi->start;
7167
15.9M
      PTREE_DATA(tree)->start_idle_count = 0;
7168
15.9M
    }
7169
56.7M
  }
7170
74.6M
  fi->length     = item_length;
7171
74.6M
  fi->tree_type  = -1;
7172
74.6M
  fi->flags      = 0;
7173
74.6M
  if (!PTREE_DATA(tree)->visible) {
7174
    /* If the tree is not visible, set the item hidden, unless we
7175
     * need the representation or length and can't fake them.
7176
     */
7177
0
    if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)->fake_protocols)) {
7178
0
      FI_SET_FLAG(fi, FI_HIDDEN);
7179
0
    }
7180
0
  }
7181
74.6M
  fi->value = fvalue_new_pool(PNODE_POOL(tree), fi->hfinfo->type);
7182
74.6M
  fi->rep        = NULL;
7183
7184
74.6M
  fi->appendix_start  = 0;
7185
74.6M
  fi->appendix_length = 0;
7186
7187
74.6M
  fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7188
74.6M
  fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7189
7190
74.6M
  return fi;
7191
74.6M
}
7192
7193
static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7194
22.8M
{
7195
22.8M
  if (hfinfo->display & BASE_NO_DISPLAY_VALUE) {
7196
261
    return 0;
7197
261
  }
7198
7199
  /* Search for field name */
7200
22.8M
  char *ptr = strstr(representation, hfinfo->name);
7201
22.8M
  if (!ptr) {
7202
7.89M
    return 0;
7203
7.89M
  }
7204
7205
  /* Check if field name ends with the ": " delimiter */
7206
14.9M
  ptr += strlen(hfinfo->name);
7207
14.9M
  if (strncmp(ptr, ": ", 2) == 0) {
7208
10.4M
    ptr += 2;
7209
10.4M
  }
7210
7211
  /* Return offset to after field name */
7212
14.9M
  return ptr - representation;
7213
22.8M
}
7214
7215
static size_t label_find_name_pos(const item_label_t *rep)
7216
13.6k
{
7217
13.6k
  size_t name_pos = 0;
7218
7219
  /* If the value_pos is too small or too large, we can't find the expected format */
7220
13.6k
  if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7221
2.78k
    return 0;
7222
2.78k
  }
7223
7224
  /* Check if the format looks like "label: value", then set name_pos before ':'. */
7225
10.8k
  if (rep->representation[rep->value_pos-2] == ':') {
7226
3.90k
    name_pos = rep->value_pos - 2;
7227
3.90k
  }
7228
7229
10.8k
  return name_pos;
7230
13.6k
}
7231
7232
/* If the protocol tree is to be visible, set the representation of a
7233
   proto_tree entry with the name of the field for the item and with
7234
   the value formatted with the supplied printf-style format and
7235
   argument list. */
7236
static void
7237
proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7238
15.7M
{
7239
15.7M
  ws_assert(pi);
7240
7241
  /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7242
   * items string representation */
7243
15.7M
  if (PTREE_DATA(pi)->visible || !proto_item_is_hidden(pi)) {
7244
5.83M
    size_t            name_pos, ret = 0;
7245
5.83M
    char              *str;
7246
5.83M
    field_info        *fi = PITEM_FINFO(pi);
7247
5.83M
    const header_field_info *hf;
7248
7249
5.83M
    DISSECTOR_ASSERT(fi);
7250
7251
5.83M
    hf = fi->hfinfo;
7252
7253
5.83M
    ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
7254
5.83M
    if (hf->bitmask && (hf->type == FT_BOOLEAN || FT_IS_UINT(hf->type))) {
7255
125k
      uint64_t val;
7256
125k
      char *p;
7257
7258
125k
      if (FT_IS_UINT32(hf->type))
7259
124k
        val = fvalue_get_uinteger(fi->value);
7260
1.45k
      else
7261
1.45k
        val = fvalue_get_uinteger64(fi->value);
7262
7263
125k
      val <<= hfinfo_bitshift(hf);
7264
7265
125k
      p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7266
125k
      ret = (p - fi->rep->representation);
7267
125k
    }
7268
7269
    /* put in the hf name */
7270
5.83M
    name_pos = ret = label_concat(fi->rep->representation, ret, (const uint8_t*)hf->name);
7271
7272
5.83M
    ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ");
7273
    /* If possible, Put in the value of the string */
7274
5.83M
    str = wmem_strdup_vprintf(PNODE_POOL(pi), format, ap);
7275
5.83M
    WS_UTF_8_CHECK(str, -1);
7276
5.83M
    fi->rep->value_pos = ret;
7277
5.83M
    ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH, ret, (const uint8_t*)str, 0);
7278
5.83M
    if (ret >= ITEM_LABEL_LENGTH) {
7279
      /* Uh oh, we don't have enough room.  Tell the user
7280
       * that the field is truncated.
7281
       */
7282
402
      label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7283
402
    }
7284
5.83M
    fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7285
5.83M
  }
7286
15.7M
}
7287
7288
/* If the protocol tree is to be visible, set the representation of a
7289
   proto_tree entry with the representation formatted with the supplied
7290
   printf-style format and argument list. */
7291
static void
7292
proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7293
22.8M
{
7294
22.8M
  size_t      ret;  /*tmp return value */
7295
22.8M
  char       *str;
7296
22.8M
  field_info *fi = PITEM_FINFO(pi);
7297
7298
22.8M
  DISSECTOR_ASSERT(fi);
7299
7300
22.8M
  if (!proto_item_is_hidden(pi)) {
7301
22.8M
    ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
7302
7303
22.8M
    str = wmem_strdup_vprintf(PNODE_POOL(pi), format, ap);
7304
22.8M
    WS_UTF_8_CHECK(str, -1);
7305
22.8M
    fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7306
22.8M
    ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH, 0, (const uint8_t*)str, 0);
7307
22.8M
    if (ret >= ITEM_LABEL_LENGTH) {
7308
      /* Uh oh, we don't have enough room.  Tell the user that the field is truncated. */
7309
7.05k
      size_t name_pos = label_find_name_pos(fi->rep);
7310
7.05k
      label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7311
7.05k
    }
7312
22.8M
    fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7313
22.8M
  }
7314
22.8M
}
7315
7316
static int
7317
proto_strlcpy(char *dest, const char *src, size_t dest_size)
7318
0
{
7319
0
  if (dest_size == 0) return 0;
7320
7321
0
  size_t res = g_strlcpy(dest, src, dest_size);
7322
7323
  /* At most dest_size - 1 characters will be copied
7324
   * (unless dest_size is 0). */
7325
0
  if (res >= dest_size)
7326
0
    res = dest_size - 1;
7327
0
  return (int) res;
7328
0
}
7329
7330
static header_field_info *
7331
hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7332
0
{
7333
0
  header_field_info *dup_hfinfo;
7334
7335
0
  if (hfinfo->same_name_prev_id == -1)
7336
0
    return NULL;
7337
0
  PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
7338
0
  return dup_hfinfo;
7339
0
}
7340
7341
static void
7342
hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7343
0
{
7344
0
  g_free(last_field_name);
7345
0
  last_field_name = NULL;
7346
7347
0
  if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7348
    /* No hfinfo with the same name */
7349
0
    wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7350
0
    return;
7351
0
  }
7352
7353
0
  if (hfinfo->same_name_next) {
7354
0
    hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7355
0
  }
7356
7357
0
  if (hfinfo->same_name_prev_id != -1) {
7358
0
    header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7359
0
    same_name_prev->same_name_next = hfinfo->same_name_next;
7360
0
    if (!hfinfo->same_name_next) {
7361
      /* It's always the latest added hfinfo which is stored in gpa_name_map */
7362
0
      wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7363
0
    }
7364
0
  }
7365
0
}
7366
7367
int
7368
proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7369
0
{
7370
0
  const header_field_info *hfinfo = finfo->hfinfo;
7371
0
  int label_len = 0;
7372
0
  char *tmp_str;
7373
0
  const char *str;
7374
0
  const uint8_t *bytes;
7375
0
  uint32_t number;
7376
0
  uint64_t number64;
7377
0
  const char *hf_str_val;
7378
0
  char number_buf[NUMBER_LABEL_LENGTH];
7379
0
  const char *number_out;
7380
0
  address addr;
7381
0
  const ipv4_addr_and_mask *ipv4;
7382
0
  const ipv6_addr_and_prefix *ipv6;
7383
7384
0
  switch (hfinfo->type) {
7385
7386
0
    case FT_NONE:
7387
0
    case FT_PROTOCOL:
7388
0
      return proto_strlcpy(display_label_str, UTF8_CHECK_MARK, label_str_size);
7389
7390
0
    case FT_UINT_BYTES:
7391
0
    case FT_BYTES:
7392
0
      tmp_str = format_bytes_hfinfo_maxlen(NULL,
7393
0
        hfinfo,
7394
0
        fvalue_get_bytes_data(finfo->value),
7395
0
        (unsigned)fvalue_length2(finfo->value),
7396
0
        label_str_size);
7397
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7398
0
      wmem_free(NULL, tmp_str);
7399
0
      break;
7400
7401
0
    case FT_ABSOLUTE_TIME:
7402
0
    {
7403
0
      const nstime_t *value = fvalue_get_time(finfo->value);
7404
0
      int flags = ABS_TIME_TO_STR_SHOW_ZONE;
7405
0
      if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7406
0
        flags |= ABS_TIME_TO_STR_ISO8601;
7407
0
      }
7408
0
      if (hfinfo->strings) {
7409
0
        const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7410
0
        if (time_string != NULL) {
7411
0
          label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7412
0
          break;
7413
0
        }
7414
0
      }
7415
0
      tmp_str = abs_time_to_str_ex(NULL, value, hfinfo->display, flags);
7416
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7417
0
      wmem_free(NULL, tmp_str);
7418
0
      break;
7419
0
    }
7420
7421
0
    case FT_RELATIVE_TIME:
7422
0
      tmp_str = rel_time_to_secs_str(NULL, fvalue_get_time(finfo->value));
7423
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7424
0
      wmem_free(NULL, tmp_str);
7425
0
      break;
7426
7427
0
    case FT_BOOLEAN:
7428
0
      number64 = fvalue_get_uinteger64(finfo->value);
7429
0
      label_len = proto_strlcpy(display_label_str,
7430
0
          tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7431
0
      break;
7432
7433
0
    case FT_CHAR:
7434
0
      number = fvalue_get_uinteger(finfo->value);
7435
7436
0
      if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
7437
0
        char tmp[ITEM_LABEL_LENGTH];
7438
0
        custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7439
7440
0
        DISSECTOR_ASSERT(fmtfunc);
7441
0
        fmtfunc(tmp, number);
7442
7443
0
        label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7444
7445
0
      } else if (hfinfo->strings) {
7446
0
        number_out = hf_try_val_to_str(number, hfinfo);
7447
7448
0
        if (!number_out) {
7449
0
          number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7450
0
        }
7451
7452
0
        label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7453
7454
0
      } else {
7455
0
        number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7456
7457
0
        label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7458
0
      }
7459
7460
0
      break;
7461
7462
    /* XXX - make these just FT_NUMBER? */
7463
0
    case FT_INT8:
7464
0
    case FT_INT16:
7465
0
    case FT_INT24:
7466
0
    case FT_INT32:
7467
0
    case FT_UINT8:
7468
0
    case FT_UINT16:
7469
0
    case FT_UINT24:
7470
0
    case FT_UINT32:
7471
0
    case FT_FRAMENUM:
7472
0
      hf_str_val = NULL;
7473
0
      number = FT_IS_INT(hfinfo->type) ?
7474
0
        (uint32_t) fvalue_get_sinteger(finfo->value) :
7475
0
        fvalue_get_uinteger(finfo->value);
7476
7477
0
      if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
7478
0
        char tmp[ITEM_LABEL_LENGTH];
7479
0
        custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7480
7481
0
        DISSECTOR_ASSERT(fmtfunc);
7482
0
        fmtfunc(tmp, number);
7483
7484
0
        label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7485
7486
0
      } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7487
0
        if (hfinfo->display & BASE_UNIT_STRING) {
7488
0
          number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7489
0
          label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7490
0
          hf_str_val = hf_try_val_to_str(number, hfinfo);
7491
0
          if (hf_str_val)
7492
0
            label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7493
0
        } else {
7494
0
          number_out = hf_try_val_to_str(number, hfinfo);
7495
7496
0
          if (!number_out) {
7497
0
            number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7498
0
          }
7499
7500
0
          label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7501
0
        }
7502
0
      } else {
7503
0
        number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7504
7505
0
        label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7506
0
      }
7507
7508
0
      break;
7509
7510
0
    case FT_INT40:
7511
0
    case FT_INT48:
7512
0
    case FT_INT56:
7513
0
    case FT_INT64:
7514
0
    case FT_UINT40:
7515
0
    case FT_UINT48:
7516
0
    case FT_UINT56:
7517
0
    case FT_UINT64:
7518
0
      hf_str_val = NULL;
7519
0
      number64 = FT_IS_INT(hfinfo->type) ?
7520
0
        (uint64_t) fvalue_get_sinteger64(finfo->value) :
7521
0
        fvalue_get_uinteger64(finfo->value);
7522
7523
0
      if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
7524
0
        char tmp[ITEM_LABEL_LENGTH];
7525
0
        custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7526
7527
0
        DISSECTOR_ASSERT(fmtfunc64);
7528
0
        fmtfunc64(tmp, number64);
7529
7530
0
        label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7531
0
      } else if (hfinfo->strings) {
7532
0
        if (hfinfo->display & BASE_UNIT_STRING) {
7533
0
          number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7534
0
          label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7535
0
          hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7536
0
          if (hf_str_val)
7537
0
            label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7538
0
        } else {
7539
0
          number_out = hf_try_val64_to_str(number64, hfinfo);
7540
7541
0
          if (!number_out)
7542
0
            number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7543
7544
0
          label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7545
0
        }
7546
0
      } else {
7547
0
        number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7548
7549
0
        label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7550
0
      }
7551
7552
0
      break;
7553
7554
0
    case FT_EUI64:
7555
0
      set_address (&addr, AT_EUI64, EUI64_ADDR_LEN, fvalue_get_bytes_data(finfo->value));
7556
0
      tmp_str = address_to_display(NULL, &addr);
7557
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7558
0
      wmem_free(NULL, tmp_str);
7559
0
      break;
7560
7561
0
    case FT_IPv4:
7562
0
      ipv4 = fvalue_get_ipv4(finfo->value);
7563
      //XXX: Should we ignore the mask?
7564
0
      set_address_ipv4(&addr, ipv4);
7565
0
      tmp_str = address_to_display(NULL, &addr);
7566
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7567
0
      wmem_free(NULL, tmp_str);
7568
0
      free_address(&addr);
7569
0
      break;
7570
7571
0
    case FT_IPv6:
7572
0
      ipv6 = fvalue_get_ipv6(finfo->value);
7573
0
      set_address_ipv6(&addr, ipv6);
7574
0
      tmp_str = address_to_display(NULL, &addr);
7575
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7576
0
      wmem_free(NULL, tmp_str);
7577
0
      free_address(&addr);
7578
0
      break;
7579
7580
0
    case FT_FCWWN:
7581
0
      set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get_bytes_data(finfo->value));
7582
0
      tmp_str = address_to_display(NULL, &addr);
7583
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7584
0
      wmem_free(NULL, tmp_str);
7585
0
      break;
7586
7587
0
    case FT_ETHER:
7588
0
      set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get_bytes_data(finfo->value));
7589
0
      tmp_str = address_to_display(NULL, &addr);
7590
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7591
0
      wmem_free(NULL, tmp_str);
7592
0
      break;
7593
7594
0
    case FT_GUID:
7595
0
      tmp_str = guid_to_str(NULL, fvalue_get_guid(finfo->value));
7596
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7597
0
      wmem_free(NULL, tmp_str);
7598
0
      break;
7599
7600
0
    case FT_REL_OID:
7601
0
      bytes = fvalue_get_bytes_data(finfo->value);
7602
0
      tmp_str = rel_oid_resolved_from_encoded(NULL, bytes, (int)fvalue_length2(finfo->value));
7603
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7604
0
      wmem_free(NULL, tmp_str);
7605
0
      break;
7606
7607
0
    case FT_OID:
7608
0
      bytes = fvalue_get_bytes_data(finfo->value);
7609
0
      tmp_str = oid_resolved_from_encoded(NULL, bytes, (int)fvalue_length2(finfo->value));
7610
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7611
0
      wmem_free(NULL, tmp_str);
7612
0
      break;
7613
7614
0
    case FT_SYSTEM_ID:
7615
0
      bytes = fvalue_get_bytes_data(finfo->value);
7616
0
      tmp_str = print_system_id(NULL, bytes, (int)fvalue_length2(finfo->value));
7617
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7618
0
      wmem_free(NULL, tmp_str);
7619
0
      break;
7620
7621
0
    case FT_FLOAT:
7622
0
    case FT_DOUBLE:
7623
0
      label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7624
0
      break;
7625
7626
0
    case FT_IEEE_11073_SFLOAT:
7627
0
    case FT_IEEE_11073_FLOAT:
7628
0
      label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7629
0
      break;
7630
7631
0
    case FT_STRING:
7632
0
    case FT_STRINGZ:
7633
0
    case FT_UINT_STRING:
7634
0
    case FT_STRINGZPAD:
7635
0
    case FT_STRINGZTRUNC:
7636
0
      str = fvalue_get_string(finfo->value);
7637
0
      label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7638
0
      if (label_len >= label_str_size) {
7639
        /* Truncation occurred. Get the real length
7640
         * copied (not including '\0') */
7641
0
        label_len = label_str_size ? label_str_size - 1 : 0;
7642
0
      }
7643
0
      break;
7644
7645
0
    default:
7646
      /* First try ftype string representation */
7647
0
      tmp_str = fvalue_to_string_repr(NULL, finfo->value, FTREPR_DISPLAY, hfinfo->display);
7648
0
      if (!tmp_str) {
7649
        /* Default to show as bytes */
7650
0
        bytes = fvalue_get_bytes_data(finfo->value);
7651
0
        tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value));
7652
0
      }
7653
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7654
0
      wmem_free(NULL, tmp_str);
7655
0
      break;
7656
0
  }
7657
0
  return label_len;
7658
0
}
7659
7660
const char *
7661
proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool display_details,
7662
     char *result, char *expr, const int size)
7663
0
{
7664
0
  int                 len, prev_len, last, i, offset_r = 0, offset_e = 0;
7665
0
  GPtrArray          *finfos;
7666
0
  field_info         *finfo         = NULL;
7667
0
  header_field_info*  hfinfo;
7668
0
  const char         *abbrev        = NULL;
7669
7670
0
  char *str;
7671
0
  col_custom_t *field_idx;
7672
0
  int field_id;
7673
0
  int ii = 0;
7674
7675
0
  ws_assert(field_ids != NULL);
7676
0
  while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7677
0
    field_id = field_idx->field_id;
7678
0
    if (field_id == 0) {
7679
0
      GPtrArray *fvals = NULL;
7680
0
      bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7681
0
      if (fvals != NULL) {
7682
7683
        // XXX - Handling occurrences is unusual when more
7684
        // than one field is involved, e.g. there's four
7685
        // results for tcp.port + tcp.port. We may really
7686
        // want to apply it to the operands, not the output.
7687
        // Note that occurrences are not quite the same as
7688
        // the layer operator (should the grammar support
7689
        // both?)
7690
        /* Calculate single index or set outer boundaries */
7691
0
        len = g_ptr_array_len(fvals);
7692
0
        if (occurrence < 0) {
7693
0
          i = occurrence + len;
7694
0
          last = i;
7695
0
        } else if (occurrence > 0) {
7696
0
          i = occurrence - 1;
7697
0
          last = i;
7698
0
        } else {
7699
0
          i = 0;
7700
0
          last = len - 1;
7701
0
        }
7702
0
        if (i < 0 || i >= len) {
7703
0
          g_ptr_array_unref(fvals);
7704
0
          continue;
7705
0
        }
7706
0
        for (; i <= last; i++) {
7707
          /* XXX - We could have a "resolved" result
7708
           * for types where the value depends only
7709
           * on the type, e.g. FT_IPv4, and not on
7710
           * hfinfo->strings. Supporting the latter
7711
           * requires knowing which hfinfo matched
7712
           * if there are multiple with the same
7713
           * abbreviation. In any case, we need to
7714
           * know the expected return type of the
7715
           * field expression.
7716
           */
7717
0
          str = fvalue_to_string_repr(NULL, fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7718
0
          if (offset_r && (offset_r < (size - 1)))
7719
0
            result[offset_r++] = ',';
7720
0
          if (offset_e && (offset_e < (size - 1)))
7721
0
            expr[offset_e++] = ',';
7722
0
          offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7723
          // col_{add,append,set}_* calls ws_label_strcpy
7724
0
          offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7725
7726
0
          g_free(str);
7727
0
        }
7728
0
        g_ptr_array_unref(fvals);
7729
0
      } else if (passed) {
7730
        // XXX - Occurrence doesn't make sense for a test
7731
        // output, it should be applied to the operands.
7732
0
        if (offset_r && (offset_r < (size - 1)))
7733
0
          result[offset_r++] = ',';
7734
0
        if (offset_e && (offset_e < (size - 1)))
7735
0
          expr[offset_e++] = ',';
7736
        /* Prevent multiple check marks */
7737
0
        if (strstr(result, UTF8_CHECK_MARK ",") == NULL) {
7738
0
          offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK, size-offset_r);
7739
0
        } else {
7740
0
          result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7741
0
        }
7742
0
        if (strstr(expr, UTF8_CHECK_MARK ",") == NULL) {
7743
0
          offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK, size-offset_e);
7744
0
        } else {
7745
0
          expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7746
0
        }
7747
0
      }
7748
0
      continue;
7749
0
    }
7750
0
    PROTO_REGISTRAR_GET_NTH((unsigned)field_id, hfinfo);
7751
7752
    /* do we need to rewind ? */
7753
0
    if (!hfinfo)
7754
0
      return "";
7755
7756
0
    if (occurrence < 0) {
7757
      /* Search other direction */
7758
0
      while (hfinfo->same_name_prev_id != -1) {
7759
0
        PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
7760
0
      }
7761
0
    }
7762
7763
0
    prev_len = 0; /* Reset handled occurrences */
7764
7765
0
    while (hfinfo) {
7766
0
      finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7767
7768
0
      if (!finfos || !(len = g_ptr_array_len(finfos))) {
7769
0
        if (occurrence < 0) {
7770
0
          hfinfo = hfinfo->same_name_next;
7771
0
        } else {
7772
0
          hfinfo = hfinfo_same_name_get_prev(hfinfo);
7773
0
        }
7774
0
        continue;
7775
0
      }
7776
7777
      /* Are there enough occurrences of the field? */
7778
0
      if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7779
0
        if (occurrence < 0) {
7780
0
          hfinfo = hfinfo->same_name_next;
7781
0
        } else {
7782
0
          hfinfo = hfinfo_same_name_get_prev(hfinfo);
7783
0
        }
7784
0
        prev_len += len;
7785
0
        continue;
7786
0
      }
7787
7788
      /* Calculate single index or set outer boundaries */
7789
0
      if (occurrence < 0) {
7790
0
        i = occurrence + len + prev_len;
7791
0
        last = i;
7792
0
      } else if (occurrence > 0) {
7793
0
        i = occurrence - 1 - prev_len;
7794
0
        last = i;
7795
0
      } else {
7796
0
        i = 0;
7797
0
        last = len - 1;
7798
0
      }
7799
7800
0
      prev_len += len; /* Count handled occurrences */
7801
7802
0
      while (i <= last) {
7803
0
        finfo = (field_info *)g_ptr_array_index(finfos, i);
7804
7805
0
        if (offset_r && (offset_r < (size - 1)))
7806
0
          result[offset_r++] = ',';
7807
7808
0
        if (display_details) {
7809
0
          char representation[ITEM_LABEL_LENGTH];
7810
0
          size_t offset = 0;
7811
7812
0
          if (finfo->rep && finfo->rep->value_len) {
7813
0
            (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7814
0
                MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH));
7815
0
          } else {
7816
0
            proto_item_fill_label(finfo, representation, &offset);
7817
0
          }
7818
0
          offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7819
0
        } else {
7820
0
          switch (hfinfo->type) {
7821
7822
0
          case FT_NONE:
7823
0
          case FT_PROTOCOL:
7824
            /* Prevent multiple check marks */
7825
0
            if (strstr(result, UTF8_CHECK_MARK ",") == NULL) {
7826
0
              offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7827
0
            } else {
7828
0
              result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7829
0
            }
7830
0
            break;
7831
7832
0
          default:
7833
0
            offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7834
0
            break;
7835
0
          }
7836
0
        }
7837
7838
0
        if (offset_e && (offset_e < (size - 1)))
7839
0
          expr[offset_e++] = ',';
7840
7841
0
        if (hfinfo->strings && hfinfo->type != FT_FRAMENUM && FIELD_DISPLAY(hfinfo->display) == BASE_NONE && (FT_IS_INT(hfinfo->type) || FT_IS_UINT(hfinfo->type))) {
7842
0
          const char *hf_str_val;
7843
          /* Integer types with BASE_NONE never get the numeric value. */
7844
0
          if (FT_IS_INT32(hfinfo->type)) {
7845
0
            hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7846
0
          } else if (FT_IS_UINT32(hfinfo->type)) {
7847
0
            hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7848
0
          } else if (FT_IS_INT64(hfinfo->type)) {
7849
0
            hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7850
0
          } else { // if (FT_IS_UINT64(hfinfo->type)) {
7851
0
            hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7852
0
          }
7853
0
          snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7854
0
          offset_e = (int)strlen(expr);
7855
0
        } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7856
          /* Prevent multiple check marks */
7857
0
          if (strstr(expr, UTF8_CHECK_MARK ",") == NULL) {
7858
0
            offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7859
0
          } else {
7860
0
            expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7861
0
          }
7862
0
        } else {
7863
0
          str = fvalue_to_string_repr(NULL, finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7864
          // col_{add,append,set}_* calls ws_label_strcpy
7865
0
          offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7866
0
          wmem_free(NULL, str);
7867
0
        }
7868
0
        i++;
7869
0
      }
7870
7871
      /* XXX: Why is only the first abbreviation returned for a multifield
7872
       * custom column? */
7873
0
      if (!abbrev) {
7874
        /* Store abbrev for return value */
7875
0
        abbrev = hfinfo->abbrev;
7876
0
      }
7877
7878
0
      if (occurrence == 0) {
7879
        /* Fetch next hfinfo with same name (abbrev) */
7880
0
        hfinfo = hfinfo_same_name_get_prev(hfinfo);
7881
0
      } else {
7882
0
        hfinfo = NULL;
7883
0
      }
7884
0
    }
7885
0
  }
7886
7887
0
  if (offset_r >= (size - 1)) {
7888
0
    mark_truncated(result, 0, size, NULL);
7889
0
  }
7890
0
  if (offset_e >= (size - 1)) {
7891
0
    mark_truncated(expr, 0, size, NULL);
7892
0
  }
7893
0
  return abbrev ? abbrev : "";
7894
0
}
7895
7896
char *
7897
proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7898
0
{
7899
0
  int                 len, prev_len, last, i;
7900
0
  GPtrArray          *finfos;
7901
0
  field_info         *finfo         = NULL;
7902
0
  header_field_info*  hfinfo;
7903
7904
0
  char *filter = NULL;
7905
0
  GPtrArray *filter_array;
7906
7907
0
  col_custom_t *col_custom;
7908
0
  int field_id;
7909
7910
0
  ws_assert(field_ids != NULL);
7911
0
  filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7912
0
  for (GSList *iter = field_ids; iter; iter = iter->next) {
7913
0
    col_custom = (col_custom_t*)iter->data;
7914
0
    field_id = col_custom->field_id;
7915
0
    if (field_id == 0) {
7916
0
      GPtrArray *fvals = NULL;
7917
0
      bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7918
0
      if (fvals != NULL) {
7919
        // XXX - Handling occurrences is unusual when more
7920
        // than one field is involved, e.g. there's four
7921
        // results for tcp.port + tcp.port. We really
7922
        // want to apply it to the operands, not the output.
7923
        /* Calculate single index or set outer boundaries */
7924
0
        len = g_ptr_array_len(fvals);
7925
0
        if (occurrence < 0) {
7926
0
          i = occurrence + len;
7927
0
          last = i;
7928
0
        } else if (occurrence > 0) {
7929
0
          i = occurrence - 1;
7930
0
          last = i;
7931
0
        } else {
7932
0
          i = 0;
7933
0
          last = len - 1;
7934
0
        }
7935
0
        if (i < 0 || i >= len) {
7936
0
          g_ptr_array_unref(fvals);
7937
0
          continue;
7938
0
        }
7939
0
        for (; i <= last; i++) {
7940
          /* XXX - Should multiple values for one
7941
           * field use set membership to reduce
7942
           * verbosity, here and below? */
7943
0
          char *str = fvalue_to_string_repr(NULL, fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7944
0
          filter = wmem_strdup_printf(NULL, "%s == %s", col_custom->dftext, str);
7945
0
          wmem_free(NULL, str);
7946
0
          if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL)) {
7947
0
            g_ptr_array_add(filter_array, filter);
7948
0
          }
7949
0
        }
7950
0
        g_ptr_array_unref(fvals);
7951
0
      } else if (passed) {
7952
0
        filter = wmem_strdup(NULL, col_custom->dftext);
7953
0
        if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL)) {
7954
0
          g_ptr_array_add(filter_array, filter);
7955
0
        }
7956
0
      } else {
7957
0
        filter = wmem_strdup_printf(NULL, "!(%s)", col_custom->dftext);
7958
0
        if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL)) {
7959
0
          g_ptr_array_add(filter_array, filter);
7960
0
        }
7961
0
      }
7962
0
      continue;
7963
0
    }
7964
7965
0
    PROTO_REGISTRAR_GET_NTH((unsigned)field_id, hfinfo);
7966
7967
    /* do we need to rewind ? */
7968
0
    if (!hfinfo)
7969
0
      return NULL;
7970
7971
0
    if (occurrence < 0) {
7972
      /* Search other direction */
7973
0
      while (hfinfo->same_name_prev_id != -1) {
7974
0
        PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
7975
0
      }
7976
0
    }
7977
7978
0
    prev_len = 0; /* Reset handled occurrences */
7979
7980
0
    while (hfinfo) {
7981
0
      finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7982
7983
0
      if (!finfos || !(len = g_ptr_array_len(finfos))) {
7984
0
        if (occurrence < 0) {
7985
0
          hfinfo = hfinfo->same_name_next;
7986
0
        } else {
7987
0
          hfinfo = hfinfo_same_name_get_prev(hfinfo);
7988
0
        }
7989
0
        continue;
7990
0
      }
7991
7992
      /* Are there enough occurrences of the field? */
7993
0
      if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7994
0
        if (occurrence < 0) {
7995
0
          hfinfo = hfinfo->same_name_next;
7996
0
        } else {
7997
0
          hfinfo = hfinfo_same_name_get_prev(hfinfo);
7998
0
        }
7999
0
        prev_len += len;
8000
0
        continue;
8001
0
      }
8002
8003
      /* Calculate single index or set outer boundaries */
8004
0
      if (occurrence < 0) {
8005
0
        i = occurrence + len + prev_len;
8006
0
        last = i;
8007
0
      } else if (occurrence > 0) {
8008
0
        i = occurrence - 1 - prev_len;
8009
0
        last = i;
8010
0
      } else {
8011
0
        i = 0;
8012
0
        last = len - 1;
8013
0
      }
8014
8015
0
      prev_len += len; /* Count handled occurrences */
8016
8017
0
      while (i <= last) {
8018
0
        finfo = (field_info *)g_ptr_array_index(finfos, i);
8019
8020
0
        filter = proto_construct_match_selected_string(finfo, edt);
8021
0
        if (filter) {
8022
          /* Only add the same expression once (especially for FT_PROTOCOL).
8023
           * The ptr array doesn't have NULL entries so g_str_equal is fine.
8024
           */
8025
0
          if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL)) {
8026
0
            g_ptr_array_add(filter_array, filter);
8027
0
          }
8028
0
        }
8029
0
        i++;
8030
0
      }
8031
8032
0
      if (occurrence == 0) {
8033
        /* Fetch next hfinfo with same name (abbrev) */
8034
0
        hfinfo = hfinfo_same_name_get_prev(hfinfo);
8035
0
      } else {
8036
0
        hfinfo = NULL;
8037
0
      }
8038
0
    }
8039
0
  }
8040
8041
0
  g_ptr_array_add(filter_array, NULL);
8042
8043
  /* XXX: Should this be || or && ? */
8044
0
  char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
8045
8046
0
  g_ptr_array_free(filter_array, true);
8047
8048
0
  return output;
8049
0
}
8050
8051
/* Set text of proto_item after having already been created. */
8052
void
8053
proto_item_set_text(proto_item *pi, const char *format, ...)
8054
2.12M
{
8055
2.12M
  field_info *fi = NULL;
8056
2.12M
  va_list     ap;
8057
8058
2.12M
  TRY_TO_FAKE_THIS_REPR_VOID(pi);
8059
8060
2.03M
  fi = PITEM_FINFO(pi);
8061
2.03M
  if (fi == NULL)
8062
0
    return;
8063
8064
2.03M
  if (fi->rep) {
8065
28.6k
    ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
8066
28.6k
    fi->rep = NULL;
8067
28.6k
  }
8068
8069
2.03M
  va_start(ap, format);
8070
2.03M
  proto_tree_set_representation(pi, format, ap);
8071
2.03M
  va_end(ap);
8072
2.03M
}
8073
8074
/* Append to text of proto_item after having already been created. */
8075
void
8076
proto_item_append_text(proto_item *pi, const char *format, ...)
8077
21.6M
{
8078
21.6M
  field_info *fi = NULL;
8079
21.6M
  size_t      curlen;
8080
21.6M
  char       *str;
8081
21.6M
  va_list     ap;
8082
8083
21.6M
  TRY_TO_FAKE_THIS_REPR_VOID(pi);
8084
8085
14.5M
  fi = PITEM_FINFO(pi);
8086
14.5M
  if (fi == NULL) {
8087
0
    return;
8088
0
  }
8089
8090
14.5M
  if (!proto_item_is_hidden(pi)) {
8091
    /*
8092
     * If we don't already have a representation,
8093
     * generate the default representation.
8094
     */
8095
14.5M
    if (fi->rep == NULL) {
8096
3.18M
      ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
8097
3.18M
      proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
8098
      /* Check for special case append value to FT_NONE or FT_PROTOCOL */
8099
3.18M
      if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
8100
1.40M
          (strncmp(format, ": ", 2) == 0)) {
8101
451k
        fi->rep->value_pos += 2;
8102
451k
      }
8103
3.18M
    }
8104
14.5M
    if (fi->rep) {
8105
14.5M
      curlen = strlen(fi->rep->representation);
8106
      /* curlen doesn't include the \0 byte.
8107
       * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
8108
       * the representation has already been truncated (of an up
8109
       * to 4 byte UTF-8 character) or is just at the maximum length
8110
       * unless we search for " [truncated]" (which may not be
8111
       * at the start.)
8112
       * It's safer to do nothing.
8113
       */
8114
14.5M
      if (ITEM_LABEL_LENGTH > (curlen + 4)) {
8115
14.2M
        va_start(ap, format);
8116
14.2M
        str = wmem_strdup_vprintf(PNODE_POOL(pi), format, ap);
8117
14.2M
        va_end(ap);
8118
14.2M
        WS_UTF_8_CHECK(str, -1);
8119
        /* Keep fi->rep->value_pos */
8120
14.2M
        curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH, curlen, (const uint8_t*)str, 0);
8121
14.2M
        if (curlen >= ITEM_LABEL_LENGTH) {
8122
          /* Uh oh, we don't have enough room.  Tell the user that the field is truncated. */
8123
6.60k
          size_t name_pos = label_find_name_pos(fi->rep);
8124
6.60k
          label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8125
6.60k
        }
8126
14.2M
        fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8127
14.2M
      }
8128
14.5M
    }
8129
14.5M
  }
8130
14.5M
}
8131
8132
/* Prepend to text of proto_item after having already been created. */
8133
void
8134
proto_item_prepend_text(proto_item *pi, const char *format, ...)
8135
724k
{
8136
724k
  field_info *fi = NULL;
8137
724k
  size_t      pos;
8138
724k
  char        representation[ITEM_LABEL_LENGTH];
8139
724k
  char       *str;
8140
724k
  va_list     ap;
8141
8142
724k
  TRY_TO_FAKE_THIS_REPR_VOID(pi);
8143
8144
483k
  fi = PITEM_FINFO(pi);
8145
483k
  if (fi == NULL) {
8146
0
    return;
8147
0
  }
8148
8149
483k
  if (!proto_item_is_hidden(pi)) {
8150
    /*
8151
     * If we don't already have a representation,
8152
     * generate the default representation.
8153
     */
8154
483k
    if (fi->rep == NULL) {
8155
277k
      ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
8156
277k
      proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8157
277k
    } else
8158
205k
      (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
8159
8160
483k
    va_start(ap, format);
8161
483k
    str = wmem_strdup_vprintf(PNODE_POOL(pi), format, ap);
8162
483k
    va_end(ap);
8163
483k
    WS_UTF_8_CHECK(str, -1);
8164
483k
    fi->rep->value_pos += strlen(str);
8165
483k
    pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH, 0, (const uint8_t*)str, 0);
8166
483k
    pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH, pos, (const uint8_t*)representation, 0);
8167
    /* XXX: As above, if the old representation is close to the label
8168
     * length, it might already be marked as truncated. */
8169
483k
    if (pos >= ITEM_LABEL_LENGTH && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH) {
8170
      /* Uh oh, we don't have enough room.  Tell the user that the field is truncated. */
8171
0
      size_t name_pos = label_find_name_pos(fi->rep);
8172
0
      label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8173
0
    }
8174
483k
    fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8175
483k
  }
8176
483k
}
8177
8178
static void
8179
finfo_set_len(field_info *fi, const unsigned length)
8180
9.77M
{
8181
9.77M
  unsigned length_remaining;
8182
8183
9.77M
  length_remaining = G_LIKELY(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8184
9.77M
  if (length > length_remaining)
8185
84.4k
    fi->length = length_remaining;
8186
9.69M
  else
8187
9.69M
    fi->length = length;
8188
8189
  /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8190
9.77M
  if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8191
282k
    fvalue_set_protocol_length(fi->value, fi->length);
8192
282k
  }
8193
8194
  /*
8195
   * You cannot just make the "len" field of a GByteArray
8196
   * larger, if there's no data to back that length;
8197
   * you can only make it smaller.
8198
   */
8199
9.77M
  if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8200
9.47k
    GBytes *bytes = fvalue_get_bytes(fi->value);
8201
9.47k
    size_t size;
8202
9.47k
    const void *data = g_bytes_get_data(bytes, &size);
8203
9.47k
    if ((size_t)fi->length <= size) {
8204
8.81k
      fvalue_set_bytes_data(fi->value, data, fi->length);
8205
8.81k
    }
8206
9.47k
    g_bytes_unref(bytes);
8207
9.47k
  }
8208
9.77M
}
8209
8210
void
8211
proto_item_set_len(proto_item *pi, const unsigned length)
8212
9.41M
{
8213
9.41M
  field_info *fi;
8214
8215
9.41M
  if (pi == NULL)
8216
160k
    return;
8217
8218
9.25M
  fi = PITEM_FINFO(pi);
8219
9.25M
  if (fi == NULL)
8220
300k
    return;
8221
8222
8.95M
  finfo_set_len(fi, length);
8223
8.95M
}
8224
8225
/*
8226
 * Sets the length of the item based on its start and on the specified
8227
 * offset, which is the offset past the end of the item; as the start
8228
 * in the item is relative to the beginning of the data source tvbuff,
8229
 * we need to pass in a tvbuff - the end offset is relative to the beginning
8230
 * of that tvbuff.
8231
 */
8232
void
8233
proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8234
838k
{
8235
838k
  field_info *fi;
8236
838k
  unsigned length;
8237
8238
838k
  if (pi == NULL)
8239
8.36k
    return;
8240
8241
829k
  fi = PITEM_FINFO(pi);
8242
829k
  if (fi == NULL)
8243
7.79k
    return;
8244
8245
821k
  if (G_LIKELY(tvb)) {
8246
821k
    DISSECTOR_ASSERT(tvb_get_ds_tvb(tvb) == fi->ds_tvb);
8247
821k
    end += tvb_raw_offset(tvb);
8248
821k
  } else {
8249
0
    DISSECTOR_ASSERT(NULL == fi->ds_tvb);
8250
0
  }
8251
821k
  DISSECTOR_ASSERT(end >= fi->start);
8252
821k
  length = end - fi->start;
8253
8254
821k
  finfo_set_len(fi, length);
8255
821k
}
8256
8257
unsigned
8258
proto_item_get_len(const proto_item *pi)
8259
8.68k
{
8260
  /* XXX - The only use case where this is really guaranteed to work is
8261
   * increasing the length of an item (which has no effect if the item
8262
   * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8263
   *
8264
   * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8265
   *
8266
   * Should there be a macro or function to do that, and possibly this
8267
   * be deprecated? As a bonus, we could handle overflow.
8268
   */
8269
8.68k
  field_info *fi;
8270
8271
8.68k
  if (!pi)
8272
0
    return 0;
8273
8.68k
  fi = PITEM_FINFO(pi);
8274
8.68k
  if (fi) {
8275
8.55k
    return fi->length;
8276
8.55k
  }
8277
128
  return 0;
8278
8.68k
}
8279
8280
void
8281
0
proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8282
0
  if (!ti) {
8283
0
    return;
8284
0
  }
8285
0
  FI_SET_FLAG(PNODE_FINFO(ti), FI_BITS_OFFSET(bits_offset));
8286
0
  FI_SET_FLAG(PNODE_FINFO(ti), FI_BITS_SIZE(bits_len));
8287
0
}
8288
8289
char *
8290
proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8291
46
{
8292
46
  field_info *fi;
8293
8294
46
  if (!pi)
8295
0
    return wmem_strdup(scope, "");
8296
46
  fi = PITEM_FINFO(pi);
8297
46
  if (!fi)
8298
0
    return wmem_strdup(scope, "");
8299
46
  DISSECTOR_ASSERT(fi->hfinfo != NULL);
8300
46
  return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8301
46
}
8302
8303
proto_tree *
8304
proto_tree_create_root(packet_info *pinfo)
8305
16
{
8306
16
  proto_node *pnode;
8307
8308
  /* Initialize the proto_node */
8309
16
  pnode = g_slice_new(proto_tree);
8310
16
  PROTO_NODE_INIT(pnode);
8311
16
  pnode->parent = NULL;
8312
16
  PNODE_FINFO(pnode) = NULL;
8313
16
  pnode->tree_data = g_slice_new(tree_data_t);
8314
8315
  /* Make sure we can access pinfo everywhere */
8316
16
  pnode->tree_data->pinfo = pinfo;
8317
8318
  /* Don't initialize the tree_data_t. Wait until we know we need it */
8319
16
  pnode->tree_data->interesting_hfids = NULL;
8320
8321
  /* Set the default to false so it's easier to
8322
   * find errors; if we expect to see the protocol tree
8323
   * but for some reason the default 'visible' is not
8324
   * changed, then we'll find out very quickly. */
8325
16
  pnode->tree_data->visible = false;
8326
8327
  /* Make sure that we fake protocols (if possible) */
8328
16
  pnode->tree_data->fake_protocols = true;
8329
8330
  /* Keep track of the number of children */
8331
16
  pnode->tree_data->count = 0;
8332
8333
  /* Initialize our loop checks */
8334
16
  pnode->tree_data->idle_count_ds_tvb = NULL;
8335
16
  pnode->tree_data->max_start = 0;
8336
16
  pnode->tree_data->start_idle_count = 0;
8337
8338
16
  return (proto_tree *)pnode;
8339
16
}
8340
8341
8342
/* "prime" a proto_tree with a single hfid that a dfilter
8343
 * is interested in. */
8344
void
8345
proto_tree_prime_with_hfid(proto_tree *tree _U_, const int hfid)
8346
998
{
8347
998
  header_field_info *hfinfo;
8348
8349
998
  PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
8350
  /* this field is referenced by a filter so increase the refcount.
8351
     also increase the refcount for the parent, i.e the protocol.
8352
     Don't increase the refcount if we're already printing the
8353
     type, as that is a superset of direct reference.
8354
  */
8355
998
  if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8356
998
    hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8357
998
  }
8358
  /* only increase the refcount if there is a parent.
8359
     if this is a protocol and not a field then parent will be -1
8360
     and there is no parent to add any refcounting for.
8361
  */
8362
998
  if (hfinfo->parent != -1) {
8363
998
    header_field_info *parent_hfinfo;
8364
998
    PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
8365
8366
    /* Mark parent as indirectly referenced unless it is already directly
8367
     * referenced, i.e. the user has specified the parent in a filter.
8368
     */
8369
998
    if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8370
24
      parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8371
998
  }
8372
998
}
8373
8374
/* "prime" a proto_tree with a single hfid that a dfilter
8375
 * is interested in. */
8376
void
8377
proto_tree_prime_with_hfid_print(proto_tree *tree _U_, const int hfid)
8378
0
{
8379
0
  header_field_info *hfinfo;
8380
8381
0
  PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
8382
  /* this field is referenced by an (output) filter so increase the refcount.
8383
     also increase the refcount for the parent, i.e the protocol.
8384
  */
8385
0
  hfinfo->ref_type = HF_REF_TYPE_PRINT;
8386
  /* only increase the refcount if there is a parent.
8387
     if this is a protocol and not a field then parent will be -1
8388
     and there is no parent to add any refcounting for.
8389
  */
8390
0
  if (hfinfo->parent != -1) {
8391
0
    header_field_info *parent_hfinfo;
8392
0
    PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
8393
8394
    /* Mark parent as indirectly referenced unless it is already directly
8395
     * referenced, i.e. the user has specified the parent in a filter.
8396
     */
8397
0
    if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8398
0
      parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8399
0
  }
8400
0
}
8401
8402
proto_tree *
8403
38.4M
proto_item_add_subtree(proto_item *pi,  const int idx) {
8404
38.4M
  field_info *fi;
8405
8406
38.4M
  if (!pi)
8407
1.02M
    return NULL;
8408
8409
38.4M
  DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
8410
8411
37.4M
  fi = PITEM_FINFO(pi);
8412
37.4M
  if (!fi)
8413
16.5M
    return (proto_tree *)pi;
8414
8415
20.8M
  fi->tree_type = idx;
8416
8417
20.8M
  return (proto_tree *)pi;
8418
37.4M
}
8419
8420
proto_tree *
8421
10.9k
proto_item_get_subtree(proto_item *pi) {
8422
10.9k
  field_info *fi;
8423
8424
10.9k
  if (!pi)
8425
0
    return NULL;
8426
10.9k
  fi = PITEM_FINFO(pi);
8427
10.9k
  if ( (fi) && (fi->tree_type == -1) )
8428
0
    return NULL;
8429
10.9k
  return (proto_tree *)pi;
8430
10.9k
}
8431
8432
proto_item *
8433
13.0M
proto_item_get_parent(const proto_item *ti) {
8434
13.0M
  if (!ti)
8435
0
    return NULL;
8436
13.0M
  return ti->parent;
8437
13.0M
}
8438
8439
proto_item *
8440
205k
proto_item_get_parent_nth(proto_item *ti, int gen) {
8441
205k
  if (!ti)
8442
0
    return NULL;
8443
615k
  while (gen--) {
8444
410k
    ti = ti->parent;
8445
410k
    if (!ti)
8446
0
      return NULL;
8447
410k
  }
8448
205k
  return ti;
8449
205k
}
8450
8451
8452
proto_item *
8453
314k
proto_tree_get_parent(proto_tree *tree) {
8454
314k
  if (!tree)
8455
4
    return NULL;
8456
314k
  return (proto_item *)tree;
8457
314k
}
8458
8459
proto_tree *
8460
123k
proto_tree_get_parent_tree(proto_tree *tree) {
8461
123k
  if (!tree)
8462
0
    return NULL;
8463
8464
  /* we're the root tree, there's no parent
8465
     return ourselves so the caller has at least a tree to attach to */
8466
123k
  if (!tree->parent)
8467
17
    return tree;
8468
8469
123k
  return (proto_tree *)tree->parent;
8470
123k
}
8471
8472
proto_tree *
8473
19.5k
proto_tree_get_root(proto_tree *tree) {
8474
19.5k
  if (!tree)
8475
0
    return NULL;
8476
120k
  while (tree->parent) {
8477
100k
    tree = tree->parent;
8478
100k
  }
8479
19.5k
  return tree;
8480
19.5k
}
8481
8482
void
8483
proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8484
         proto_item *item_to_move)
8485
73.1k
{
8486
  /* This function doesn't generate any values. It only reorganizes the protocol tree
8487
   * so we can bail out immediately if it isn't visible. */
8488
73.1k
  if (!tree || !PTREE_DATA(tree)->visible)
8489
38.5k
    return;
8490
8491
73.1k
  DISSECTOR_ASSERT(item_to_move->parent == tree);
8492
34.6k
  DISSECTOR_ASSERT(fixed_item->parent == tree);
8493
8494
  /*** cut item_to_move out ***/
8495
8496
  /* is item_to_move the first? */
8497
34.6k
  if (tree->first_child == item_to_move) {
8498
    /* simply change first child to next */
8499
0
    tree->first_child = item_to_move->next;
8500
8501
0
    DISSECTOR_ASSERT(tree->last_child != item_to_move);
8502
34.6k
  } else {
8503
34.6k
    proto_item *curr_item;
8504
    /* find previous and change it's next */
8505
242k
    for (curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
8506
242k
      if (curr_item->next == item_to_move) {
8507
34.6k
        break;
8508
34.6k
      }
8509
242k
    }
8510
8511
34.6k
    DISSECTOR_ASSERT(curr_item);
8512
8513
34.6k
    curr_item->next = item_to_move->next;
8514
8515
    /* fix last_child if required */
8516
34.6k
    if (tree->last_child == item_to_move) {
8517
34.5k
      tree->last_child = curr_item;
8518
34.5k
    }
8519
34.6k
  }
8520
8521
  /*** insert to_move after fixed ***/
8522
34.6k
  item_to_move->next = fixed_item->next;
8523
34.6k
  fixed_item->next = item_to_move;
8524
34.6k
  if (tree->last_child == fixed_item) {
8525
29
    tree->last_child = item_to_move;
8526
29
  }
8527
34.6k
}
8528
8529
void
8530
proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8531
      const unsigned length)
8532
20.7k
{
8533
20.7k
  field_info *fi;
8534
8535
20.7k
  if (tree == NULL)
8536
1.12k
    return;
8537
8538
19.6k
  fi = PTREE_FINFO(tree);
8539
19.6k
  if (fi == NULL)
8540
483
    return;
8541
8542
  /* We don't store a separate data source tvb for the appendix, so
8543
   * it must be from the same data source. (XXX - Are there any
8544
   * situations where it makes sense to have an appendix from a
8545
   * different data source?) */
8546
19.1k
  if (G_LIKELY(tvb)) {
8547
19.1k
    DISSECTOR_ASSERT(tvb_get_ds_tvb(tvb) == fi->ds_tvb);
8548
19.1k
    start += tvb_raw_offset(tvb);
8549
19.1k
  } else {
8550
0
    DISSECTOR_ASSERT(NULL == fi->ds_tvb);
8551
0
  }
8552
8553
  /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8554
   * main body? */
8555
8556
19.1k
  fi->appendix_start = start;
8557
19.1k
  fi->appendix_length = length;
8558
19.1k
}
8559
8560
static void
8561
check_protocol_filter_name_or_fail(const char *filter_name)
8562
49.8k
{
8563
  /* Require at least two characters. */
8564
49.8k
  if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8565
0
    REPORT_DISSECTOR_BUG("Protocol filter name \"%s\" cannot have length less than two.", filter_name);
8566
0
  }
8567
8568
49.8k
  if (proto_check_field_name(filter_name) != '\0') {
8569
0
    REPORT_DISSECTOR_BUG("Protocol filter name \"%s\" has one or more invalid characters."
8570
0
      " Allowed are letters, digits, '-', '_' and non-repeating '.'."
8571
0
      " This might be caused by an inappropriate plugin or a development error.", filter_name);
8572
0
  }
8573
8574
  /* Check that it doesn't match some very common numeric forms. */
8575
49.8k
  if (filter_name[0] == '0' &&
8576
0
        (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8577
0
        filter_name[1] == 'b' || filter_name[1] == 'B')) {
8578
0
    REPORT_DISSECTOR_BUG("Protocol filter name \"%s\" cannot start with \"%c%c\".",
8579
0
            filter_name, filter_name[0], filter_name[1]);
8580
0
  }
8581
8582
  /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8583
8584
  /* Check that it contains at least one letter. */
8585
49.8k
  bool have_letter = false;
8586
50.1k
  for (const char *s = filter_name; *s != '\0'; s++) {
8587
50.1k
    if (g_ascii_isalpha(*s)) {
8588
49.8k
      have_letter = true;
8589
49.8k
      break;
8590
49.8k
    }
8591
50.1k
  }
8592
49.8k
  if (!have_letter) {
8593
0
    REPORT_DISSECTOR_BUG("Protocol filter name \"%s\" must contain at least one letter a-z.",
8594
0
            filter_name);
8595
0
  }
8596
8597
  /* Check for reserved keywords. */
8598
49.8k
  if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8599
0
    REPORT_DISSECTOR_BUG("Protocol filter name \"%s\" is invalid because it is a reserved keyword."
8600
0
      " This might be caused by an inappropriate plugin or a development error.", filter_name);
8601
0
  }
8602
49.8k
}
8603
8604
int
8605
proto_register_protocol(const char *name, const char *short_name,
8606
      const char *filter_name)
8607
34.0k
{
8608
34.0k
  protocol_t *protocol;
8609
34.0k
  header_field_info *hfinfo;
8610
8611
34.0k
  check_protocol_filter_name_or_fail(filter_name);
8612
8613
  /*
8614
   * Add this protocol to the list of known protocols;
8615
   * the list is sorted by protocol short name.
8616
   */
8617
34.0k
  protocol = g_new(protocol_t, 1);
8618
34.0k
  protocol->name = name;
8619
34.0k
  protocol->short_name = short_name;
8620
34.0k
  protocol->filter_name = filter_name;
8621
34.0k
  protocol->fields = NULL; /* Delegate until actually needed */
8622
34.0k
  protocol->is_enabled = true; /* protocol is enabled by default */
8623
34.0k
  protocol->enabled_by_default = true; /* see previous comment */
8624
34.0k
  protocol->can_toggle = true;
8625
34.0k
  protocol->parent_proto_id = -1;
8626
34.0k
  protocol->heur_list = NULL;
8627
8628
  /* List will be sorted later by name, when all protocols completed registering */
8629
34.0k
  protocols = g_list_prepend(protocols, protocol);
8630
  /*
8631
   * Make sure there's not already a protocol with any of those
8632
   * names.  Crash if there is, as that's an error in the code
8633
   * or an inappropriate plugin.
8634
   * This situation has to be fixed to not register more than one
8635
   * protocol with the same name.
8636
   */
8637
34.0k
  if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8638
    /* ws_error will terminate the program */
8639
0
    REPORT_DISSECTOR_BUG("Duplicate protocol name \"%s\"!"
8640
0
      " This might be caused by an inappropriate plugin or a development error.", name);
8641
0
  }
8642
34.0k
  if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8643
0
    REPORT_DISSECTOR_BUG("Duplicate protocol filter_name \"%s\"!"
8644
0
      " This might be caused by an inappropriate plugin or a development error.", filter_name);
8645
0
  }
8646
34.0k
  if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8647
0
    REPORT_DISSECTOR_BUG("Duplicate protocol short_name \"%s\"!"
8648
0
      " This might be caused by an inappropriate plugin or a development error.", short_name);
8649
0
  }
8650
8651
  /* Here we allocate a new header_field_info struct */
8652
34.0k
  hfinfo = g_slice_new(header_field_info);
8653
34.0k
  hfinfo->name = name;
8654
34.0k
  hfinfo->abbrev = filter_name;
8655
34.0k
  hfinfo->type = FT_PROTOCOL;
8656
34.0k
  hfinfo->display = BASE_NONE;
8657
34.0k
  hfinfo->strings = protocol;
8658
34.0k
  hfinfo->bitmask = 0;
8659
34.0k
  hfinfo->ref_type = HF_REF_TYPE_NONE;
8660
34.0k
  hfinfo->blurb = NULL;
8661
34.0k
  hfinfo->parent = -1; /* This field differentiates protos and fields */
8662
8663
34.0k
  protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8664
34.0k
  return protocol->proto_id;
8665
34.0k
}
8666
8667
int
8668
proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8669
15.7k
{
8670
15.7k
  protocol_t *protocol;
8671
15.7k
  header_field_info *hfinfo;
8672
8673
  /*
8674
   * Helper protocols don't need the strict rules as a "regular" protocol
8675
   * Just register it in a list and make a hf_ field from it
8676
   */
8677
15.7k
  if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8678
0
    REPORT_DISSECTOR_BUG("Pino \"%s\" must be of type FT_PROTOCOL or FT_BYTES.", name);
8679
0
  }
8680
8681
15.7k
  if (parent_proto <= 0) {
8682
0
    REPORT_DISSECTOR_BUG("Must have a valid parent protocol for helper protocol \"%s\"!"
8683
0
      " This might be caused by an inappropriate plugin or a development error.", name);
8684
0
  }
8685
8686
15.7k
  check_protocol_filter_name_or_fail(filter_name);
8687
8688
  /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8689
15.7k
  protocol = g_new(protocol_t, 1);
8690
15.7k
  protocol->name = name;
8691
15.7k
  protocol->short_name = short_name;
8692
15.7k
  protocol->filter_name = filter_name;
8693
15.7k
  protocol->fields = NULL; /* Delegate until actually needed */
8694
8695
  /* Enabling and toggling is really determined by parent protocol,
8696
     but provide default values here */
8697
15.7k
  protocol->is_enabled = true;
8698
15.7k
  protocol->enabled_by_default = true;
8699
15.7k
  protocol->can_toggle = true;
8700
8701
15.7k
  protocol->parent_proto_id = parent_proto;
8702
15.7k
  protocol->heur_list = NULL;
8703
8704
  /* List will be sorted later by name, when all protocols completed registering */
8705
15.7k
  protocols = g_list_prepend(protocols, protocol);
8706
8707
  /* Here we allocate a new header_field_info struct */
8708
15.7k
  hfinfo = g_slice_new(header_field_info);
8709
15.7k
  hfinfo->name = name;
8710
15.7k
  hfinfo->abbrev = filter_name;
8711
15.7k
  hfinfo->type = field_type;
8712
15.7k
  hfinfo->display = BASE_NONE;
8713
15.7k
  if (field_type == FT_BYTES) {
8714
14.6k
    hfinfo->display |= (BASE_NO_DISPLAY_VALUE|BASE_PROTOCOL_INFO);
8715
14.6k
  }
8716
15.7k
  hfinfo->strings = protocol;
8717
15.7k
  hfinfo->bitmask = 0;
8718
15.7k
  hfinfo->ref_type = HF_REF_TYPE_NONE;
8719
15.7k
  hfinfo->blurb = NULL;
8720
15.7k
  hfinfo->parent = -1; /* This field differentiates protos and fields */
8721
8722
15.7k
  protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8723
15.7k
  return protocol->proto_id;
8724
15.7k
}
8725
8726
bool
8727
proto_deregister_protocol(const char *short_name)
8728
0
{
8729
0
  protocol_t *protocol;
8730
0
  header_field_info *hfinfo;
8731
0
  int proto_id;
8732
0
  unsigned i;
8733
8734
0
  proto_id = proto_get_id_by_short_name(short_name);
8735
0
  protocol = find_protocol_by_id(proto_id);
8736
0
  if (protocol == NULL)
8737
0
    return false;
8738
8739
0
  g_hash_table_remove(proto_names, protocol->name);
8740
0
  g_hash_table_remove(proto_short_names, (void *)short_name);
8741
0
  g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8742
8743
0
  if (protocol->fields) {
8744
0
    for (i = 0; i < protocol->fields->len; i++) {
8745
0
      hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
8746
0
      hfinfo_remove_from_gpa_name_map(hfinfo);
8747
0
      expert_deregister_expertinfo(hfinfo->abbrev);
8748
0
      g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8749
0
    }
8750
0
    g_ptr_array_free(protocol->fields, true);
8751
0
    protocol->fields = NULL;
8752
0
  }
8753
8754
0
  g_list_free(protocol->heur_list);
8755
8756
  /* Remove this protocol from the list of known protocols */
8757
0
  protocols = g_list_remove(protocols, protocol);
8758
8759
0
  g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8760
0
  wmem_map_remove(gpa_name_map, protocol->filter_name);
8761
8762
0
  g_free(last_field_name);
8763
0
  last_field_name = NULL;
8764
8765
0
  return true;
8766
0
}
8767
8768
void
8769
proto_register_alias(const int proto_id, const char *alias_name)
8770
176
{
8771
176
  protocol_t *protocol;
8772
8773
176
  protocol = find_protocol_by_id(proto_id);
8774
176
  if (alias_name && protocol) {
8775
176
    g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8776
176
  }
8777
176
}
8778
8779
/*
8780
 * Routines to use to iterate over the protocols.
8781
 * The argument passed to the iterator routines is an opaque cookie to
8782
 * their callers; it's the GList pointer for the current element in
8783
 * the list.
8784
 * The ID of the protocol is returned, or -1 if there is no protocol.
8785
 */
8786
int
8787
proto_get_first_protocol(void **cookie)
8788
0
{
8789
0
  protocol_t *protocol;
8790
8791
0
  if (protocols == NULL)
8792
0
    return -1;
8793
0
  *cookie = protocols;
8794
0
  protocol = (protocol_t *)protocols->data;
8795
0
  return protocol->proto_id;
8796
0
}
8797
8798
int
8799
proto_get_data_protocol(void *cookie)
8800
0
{
8801
0
  GList *list_item = (GList *)cookie;
8802
8803
0
  protocol_t *protocol = (protocol_t *)list_item->data;
8804
0
  return protocol->proto_id;
8805
0
}
8806
8807
int
8808
proto_get_next_protocol(void **cookie)
8809
0
{
8810
0
  GList      *list_item = (GList *)*cookie;
8811
0
  protocol_t *protocol;
8812
8813
0
  list_item = g_list_next(list_item);
8814
0
  if (list_item == NULL)
8815
0
    return -1;
8816
0
  *cookie = list_item;
8817
0
  protocol = (protocol_t *)list_item->data;
8818
0
  return protocol->proto_id;
8819
0
}
8820
8821
header_field_info *
8822
proto_get_first_protocol_field(const int proto_id, void **cookie)
8823
0
{
8824
0
  protocol_t *protocol = find_protocol_by_id(proto_id);
8825
8826
0
  if ((protocol == NULL) || (protocol->fields == NULL) || (protocol->fields->len == 0))
8827
0
    return NULL;
8828
8829
0
  *cookie = GUINT_TO_POINTER(0);
8830
0
  return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
8831
0
}
8832
8833
header_field_info *
8834
proto_get_next_protocol_field(const int proto_id, void **cookie)
8835
0
{
8836
0
  protocol_t *protocol = find_protocol_by_id(proto_id);
8837
0
  unsigned    i        = GPOINTER_TO_UINT(*cookie);
8838
8839
0
  i++;
8840
8841
0
  if ((protocol->fields == NULL) || (i >= protocol->fields->len))
8842
0
    return NULL;
8843
8844
0
  *cookie = GUINT_TO_POINTER(i);
8845
0
  return (header_field_info *)g_ptr_array_index(protocol->fields, i);
8846
0
}
8847
8848
protocol_t *
8849
find_protocol_by_id(const int proto_id)
8850
1.07M
{
8851
1.07M
  header_field_info *hfinfo;
8852
8853
1.07M
  if (proto_id <= 0)
8854
6.29k
    return NULL;
8855
8856
1.06M
  PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
8857
1.06M
  if (hfinfo->type != FT_PROTOCOL) {
8858
153k
    DISSECTOR_ASSERT(hfinfo->display & BASE_PROTOCOL_INFO);
8859
153k
  }
8860
1.06M
  return (protocol_t *)hfinfo->strings;
8861
1.07M
}
8862
8863
int
8864
proto_get_id(const protocol_t *protocol)
8865
2.59M
{
8866
2.59M
  return protocol->proto_id;
8867
2.59M
}
8868
8869
bool
8870
proto_name_already_registered(const char *name)
8871
0
{
8872
0
  DISSECTOR_ASSERT_HINT(name, "No name present");
8873
8874
0
  if (g_hash_table_lookup(proto_names, name) != NULL)
8875
0
    return true;
8876
0
  return false;
8877
0
}
8878
8879
int
8880
proto_get_id_by_filter_name(const char *filter_name)
8881
2.18k
{
8882
2.18k
  const protocol_t *protocol = NULL;
8883
8884
2.18k
  DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
8885
8886
2.18k
  protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8887
8888
2.18k
  if (protocol == NULL)
8889
80
    return -1;
8890
2.10k
  return protocol->proto_id;
8891
2.18k
}
8892
8893
int
8894
proto_get_id_by_short_name(const char *short_name)
8895
12.4k
{
8896
12.4k
  const protocol_t *protocol = NULL;
8897
8898
12.4k
  DISSECTOR_ASSERT_HINT(short_name, "No short name present");
8899
8900
12.4k
  protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8901
8902
12.4k
  if (protocol == NULL)
8903
0
    return -1;
8904
12.4k
  return protocol->proto_id;
8905
12.4k
}
8906
8907
const char *
8908
proto_get_protocol_name(const int proto_id)
8909
14.6k
{
8910
14.6k
  protocol_t *protocol;
8911
8912
14.6k
  protocol = find_protocol_by_id(proto_id);
8913
8914
14.6k
  if (protocol == NULL)
8915
0
    return NULL;
8916
14.6k
  return protocol->name;
8917
14.6k
}
8918
8919
const char *
8920
proto_get_protocol_short_name(const protocol_t *protocol)
8921
4.67M
{
8922
4.67M
  if (protocol == NULL)
8923
16
    return "(none)";
8924
4.67M
  return protocol->short_name;
8925
4.67M
}
8926
8927
const char *
8928
proto_get_protocol_long_name(const protocol_t *protocol)
8929
111
{
8930
111
  if (protocol == NULL)
8931
0
    return "(none)";
8932
111
  return protocol->name;
8933
111
}
8934
8935
const char *
8936
proto_get_protocol_filter_name(const int proto_id)
8937
586k
{
8938
586k
  protocol_t *protocol;
8939
8940
586k
  protocol = find_protocol_by_id(proto_id);
8941
586k
  if (protocol == NULL)
8942
20
    return "(none)";
8943
586k
  return protocol->filter_name;
8944
586k
}
8945
8946
void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8947
7.12k
{
8948
7.12k
  heur_dtbl_entry_t* heuristic_dissector;
8949
8950
7.12k
  if (protocol == NULL)
8951
0
    return;
8952
8953
7.12k
  heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8954
7.12k
  if (heuristic_dissector != NULL)
8955
7.12k
  {
8956
7.12k
    protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8957
7.12k
  }
8958
7.12k
}
8959
8960
void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8961
0
{
8962
0
  if (protocol == NULL)
8963
0
    return;
8964
8965
0
  g_list_foreach(protocol->heur_list, func, user_data);
8966
0
}
8967
8968
void
8969
proto_get_frame_protocols(const wmem_list_t *layers, bool *is_ip,
8970
        bool *is_tcp, bool *is_udp,
8971
        bool *is_sctp, bool *is_tls,
8972
        bool *is_rtp,
8973
        bool *is_lte_rlc)
8974
0
{
8975
0
  wmem_list_frame_t *protos = wmem_list_head(layers);
8976
0
  int     proto_id;
8977
0
  const char *proto_name;
8978
8979
  /* Walk the list of a available protocols in the packet and
8980
     attempt to find "major" ones. */
8981
  /* It might make more sense to assemble and return a bitfield. */
8982
0
  while (protos != NULL)
8983
0
  {
8984
0
    proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
8985
0
    proto_name = proto_get_protocol_filter_name(proto_id);
8986
8987
0
    if (is_ip && ((!strcmp(proto_name, "ip")) ||
8988
0
            (!strcmp(proto_name, "ipv6")))) {
8989
0
      *is_ip = true;
8990
0
    } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8991
0
      *is_tcp = true;
8992
0
    } else if (is_udp && !strcmp(proto_name, "udp")) {
8993
0
      *is_udp = true;
8994
0
    } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8995
0
      *is_sctp = true;
8996
0
    } else if (is_tls && !strcmp(proto_name, "tls")) {
8997
0
      *is_tls = true;
8998
0
    } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8999
0
      *is_rtp = true;
9000
0
    } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
9001
0
      *is_lte_rlc = true;
9002
0
    }
9003
9004
0
    protos = wmem_list_frame_next(protos);
9005
0
  }
9006
0
}
9007
9008
bool
9009
proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
9010
4.51k
{
9011
4.51k
  wmem_list_frame_t *protos = wmem_list_head(layers);
9012
4.51k
  int     proto_id;
9013
4.51k
  const char *name;
9014
9015
  /* Walk the list of a available protocols in the packet and
9016
     attempt to find the specified protocol. */
9017
34.2k
  while (protos != NULL)
9018
30.2k
  {
9019
30.2k
    proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
9020
30.2k
    name = proto_get_protocol_filter_name(proto_id);
9021
9022
30.2k
    if (!strcmp(name, proto_name))
9023
452
    {
9024
452
      return true;
9025
452
    }
9026
9027
29.7k
    protos = wmem_list_frame_next(protos);
9028
29.7k
  }
9029
9030
4.06k
  return false;
9031
4.51k
}
9032
9033
char *
9034
proto_list_layers(const packet_info *pinfo)
9035
0
{
9036
0
  wmem_strbuf_t *buf;
9037
0
  wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
9038
9039
0
  buf = wmem_strbuf_new_sized(pinfo->pool, 128);
9040
9041
  /* Walk the list of layers in the packet and
9042
     return a string of all entries. */
9043
0
  while (layers != NULL)
9044
0
  {
9045
0
    wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))));
9046
9047
0
    layers = wmem_list_frame_next(layers);
9048
0
    if (layers != NULL) {
9049
0
      wmem_strbuf_append_c(buf, ':');
9050
0
    }
9051
0
  }
9052
9053
0
  return wmem_strbuf_finalize(buf);
9054
0
}
9055
9056
uint8_t
9057
proto_get_layer_num(const packet_info *pinfo, const int proto_id)
9058
218
{
9059
218
  int *proto_layer_num_ptr;
9060
9061
218
  proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id));
9062
218
  if (proto_layer_num_ptr == NULL) {
9063
218
    return 0;
9064
218
  }
9065
9066
0
  return (uint8_t)*proto_layer_num_ptr;
9067
218
}
9068
9069
bool
9070
proto_is_pino(const protocol_t *protocol)
9071
9.41M
{
9072
9.41M
  return (protocol->parent_proto_id != -1);
9073
9.41M
}
9074
9075
bool
9076
proto_is_bytes_pino(const protocol_t *protocol)
9077
5.19M
{
9078
5.19M
  header_field_info *hfinfo;
9079
9080
5.19M
  if (!proto_is_pino(protocol))
9081
5.11M
    return false;
9082
9083
79.5k
  PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
9084
79.5k
  return hfinfo->type != FT_PROTOCOL;
9085
5.19M
}
9086
9087
bool
9088
// NOLINTNEXTLINE(misc-no-recursion)
9089
proto_is_protocol_enabled(const protocol_t *protocol)
9090
4.22M
{
9091
4.22M
  if (protocol == NULL)
9092
0
    return false;
9093
9094
  //parent protocol determines enable/disable for helper dissectors
9095
4.22M
  if (proto_is_pino(protocol))
9096
27.1k
    return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
9097
9098
4.20M
  return protocol->is_enabled;
9099
4.22M
}
9100
9101
bool
9102
// NOLINTNEXTLINE(misc-no-recursion)
9103
proto_is_protocol_enabled_by_default(const protocol_t *protocol)
9104
0
{
9105
  //parent protocol determines enable/disable for helper dissectors
9106
0
  if (proto_is_pino(protocol))
9107
0
    return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
9108
9109
0
  return protocol->enabled_by_default;
9110
0
}
9111
9112
bool
9113
// NOLINTNEXTLINE(misc-no-recursion)
9114
proto_can_toggle_protocol(const int proto_id)
9115
116
{
9116
116
  protocol_t *protocol;
9117
9118
116
  protocol = find_protocol_by_id(proto_id);
9119
  //parent protocol determines toggling for helper dissectors
9120
116
  if (proto_is_pino(protocol))
9121
0
    return proto_can_toggle_protocol(protocol->parent_proto_id);
9122
9123
116
  return protocol->can_toggle;
9124
116
}
9125
9126
void
9127
proto_disable_by_default(const int proto_id)
9128
80
{
9129
80
  protocol_t *protocol;
9130
9131
80
  protocol = find_protocol_by_id(proto_id);
9132
80
  DISSECTOR_ASSERT(protocol->can_toggle);
9133
80
  DISSECTOR_ASSERT(proto_is_pino(protocol) == false);
9134
80
  protocol->is_enabled = false;
9135
80
  protocol->enabled_by_default = false;
9136
80
}
9137
9138
void
9139
proto_set_decoding(const int proto_id, const bool enabled)
9140
116
{
9141
116
  protocol_t *protocol;
9142
9143
116
  protocol = find_protocol_by_id(proto_id);
9144
116
  DISSECTOR_ASSERT(protocol->can_toggle);
9145
116
  DISSECTOR_ASSERT(proto_is_pino(protocol) == false);
9146
116
  protocol->is_enabled = enabled;
9147
116
}
9148
9149
void
9150
proto_disable_all(void)
9151
0
{
9152
  /* This doesn't explicitly disable heuristic protocols,
9153
   * but the heuristic doesn't get called if the parent
9154
   * protocol isn't enabled.
9155
   */
9156
0
  protocol_t *protocol;
9157
0
  GList      *list_item = protocols;
9158
9159
0
  if (protocols == NULL)
9160
0
    return;
9161
9162
0
  while (list_item) {
9163
0
    protocol = (protocol_t *)list_item->data;
9164
0
    if (protocol->can_toggle) {
9165
0
      protocol->is_enabled = false;
9166
0
    }
9167
0
    list_item = g_list_next(list_item);
9168
0
  }
9169
0
}
9170
9171
static void
9172
heur_reenable_cb(void *data, void *user_data _U_)
9173
0
{
9174
0
  heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9175
9176
0
  heur->enabled = heur->enabled_by_default;
9177
0
}
9178
9179
void
9180
proto_reenable_all(void)
9181
0
{
9182
0
  protocol_t *protocol;
9183
0
  GList      *list_item = protocols;
9184
9185
0
  if (protocols == NULL)
9186
0
    return;
9187
9188
0
  while (list_item) {
9189
0
    protocol = (protocol_t *)list_item->data;
9190
0
    if (protocol->can_toggle)
9191
0
      protocol->is_enabled = protocol->enabled_by_default;
9192
0
    proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL);
9193
0
    list_item = g_list_next(list_item);
9194
0
  }
9195
0
}
9196
9197
void
9198
proto_set_cant_toggle(const int proto_id)
9199
368
{
9200
368
  protocol_t *protocol;
9201
9202
368
  protocol = find_protocol_by_id(proto_id);
9203
368
  protocol->can_toggle = false;
9204
368
}
9205
9206
static int
9207
proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9208
3.90M
{
9209
3.90M
  g_ptr_array_add(proto->fields, hfi);
9210
9211
3.90M
  return proto_register_field_init(hfi, parent);
9212
3.90M
}
9213
9214
/* for use with static arrays only, since we don't allocate our own copies
9215
of the header_field_info struct contained within the hf_register_info struct */
9216
void
9217
proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9218
102k
{
9219
102k
  hf_register_info *ptr = hf;
9220
102k
  protocol_t   *proto;
9221
102k
  int     i;
9222
9223
102k
  proto = find_protocol_by_id(parent);
9224
9225
  /* if (proto == NULL) - error or return? */
9226
9227
102k
  if (proto->fields == NULL) {
9228
    /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9229
     * GLib introduced g_ptr_array_new_from_array, which might have
9230
     * given a reason to actually use it. (#17774)
9231
     */
9232
31.7k
    proto->fields = g_ptr_array_sized_new(num_records);
9233
31.7k
  }
9234
9235
4.00M
  for (i = 0; i < num_records; i++, ptr++) {
9236
    /*
9237
     * Make sure we haven't registered this yet.
9238
     * Most fields have variables associated with them that
9239
     * are initialized to 0; some are initialized to -1 (which
9240
     * was the standard before 4.4).
9241
     *
9242
     * XXX - Since this is called almost 300000 times at startup,
9243
     * it might be nice to compare to only 0 and require
9244
     * dissectors to pass in zero for unregistered fields.
9245
     */
9246
3.90M
    if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9247
0
      REPORT_DISSECTOR_BUG(
9248
0
        "Duplicate field detected in call to proto_register_field_array: %s is already registered",
9249
0
        ptr->hfinfo.abbrev);
9250
0
      return;
9251
0
    }
9252
9253
3.90M
    *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9254
3.90M
  }
9255
102k
}
9256
9257
/* deregister already registered fields */
9258
void
9259
proto_deregister_field (const int parent, int hf_id)
9260
0
{
9261
0
  header_field_info *hfi;
9262
0
  protocol_t       *proto;
9263
0
  unsigned          i;
9264
9265
0
  g_free(last_field_name);
9266
0
  last_field_name = NULL;
9267
9268
0
  if (hf_id == -1 || hf_id == 0)
9269
0
    return;
9270
9271
0
  proto = find_protocol_by_id (parent);
9272
0
  if (!proto || proto->fields == NULL) {
9273
0
    return;
9274
0
  }
9275
9276
0
  for (i = 0; i < proto->fields->len; i++) {
9277
0
    hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
9278
0
    if (hfi->id == hf_id) {
9279
      /* Found the hf_id in this protocol */
9280
0
      wmem_map_remove(gpa_name_map, hfi->abbrev);
9281
0
      g_ptr_array_remove_index_fast(proto->fields, i);
9282
0
      g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9283
0
      return;
9284
0
    }
9285
0
  }
9286
0
}
9287
9288
/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9289
void
9290
proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9291
144
{
9292
144
  header_field_info *hfinfo;
9293
144
  protocol_t        *proto;
9294
9295
144
  g_free(last_field_name);
9296
144
  last_field_name = NULL;
9297
9298
144
  proto = find_protocol_by_id(parent);
9299
144
  if (proto && proto->fields && proto->fields->len > 0) {
9300
144
    unsigned i = proto->fields->len;
9301
6.19k
    do {
9302
6.19k
      i--;
9303
9304
6.19k
      hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i);
9305
6.19k
      if (g_str_has_prefix(hfinfo->abbrev, prefix)) {
9306
0
        hfinfo_remove_from_gpa_name_map(hfinfo);
9307
0
        expert_deregister_expertinfo(hfinfo->abbrev);
9308
0
        g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9309
0
        g_ptr_array_remove_index_fast(proto->fields, i);
9310
0
      }
9311
6.19k
    } while (i > 0);
9312
144
  }
9313
144
}
9314
9315
void
9316
proto_add_deregistered_data (void *data)
9317
0
{
9318
0
  g_ptr_array_add(deregistered_data, data);
9319
0
}
9320
9321
void
9322
proto_add_deregistered_slice (size_t block_size, void *mem_block)
9323
0
{
9324
0
  struct g_slice_data *slice_data = g_slice_new(struct g_slice_data);
9325
9326
0
  slice_data->block_size = block_size;
9327
0
  slice_data->mem_block = mem_block;
9328
9329
0
  g_ptr_array_add(deregistered_slice, slice_data);
9330
0
}
9331
9332
void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9333
0
{
9334
0
  if (field_strings == NULL) {
9335
0
    return;
9336
0
  }
9337
9338
0
  switch (field_type) {
9339
0
    case FT_FRAMENUM:
9340
      /* This is just an integer represented as a pointer */
9341
0
      break;
9342
0
    case FT_PROTOCOL: {
9343
0
      protocol_t *protocol = (protocol_t *)field_strings;
9344
0
      g_free((char *)protocol->short_name);
9345
0
      break;
9346
0
    }
9347
0
    case FT_BOOLEAN: {
9348
0
      true_false_string *tf = (true_false_string *)field_strings;
9349
0
      g_free((char *)tf->true_string);
9350
0
      g_free((char *)tf->false_string);
9351
0
      break;
9352
0
    }
9353
0
    case FT_UINT40:
9354
0
    case FT_INT40:
9355
0
    case FT_UINT48:
9356
0
    case FT_INT48:
9357
0
    case FT_UINT56:
9358
0
    case FT_INT56:
9359
0
    case FT_UINT64:
9360
0
    case FT_INT64: {
9361
0
      if (field_display & BASE_UNIT_STRING) {
9362
0
        unit_name_string *unit = (unit_name_string *)field_strings;
9363
0
        g_free((char *)unit->singular);
9364
0
        g_free((char *)unit->plural);
9365
0
      } else if (field_display & BASE_RANGE_STRING) {
9366
0
        range_string *rs = (range_string *)field_strings;
9367
0
        while (rs->strptr) {
9368
0
          g_free((char *)rs->strptr);
9369
0
          rs++;
9370
0
        }
9371
0
      } else if (field_display & BASE_EXT_STRING) {
9372
0
        val64_string_ext *vse = (val64_string_ext *)field_strings;
9373
0
        val64_string *vs = (val64_string *)vse->_vs_p;
9374
0
        while (vs->strptr) {
9375
0
          g_free((char *)vs->strptr);
9376
0
          vs++;
9377
0
        }
9378
0
        val64_string_ext_free(vse);
9379
0
        field_strings = NULL;
9380
0
      } else if (field_display == BASE_CUSTOM) {
9381
        /* this will be a pointer to a function, don't free that */
9382
0
        field_strings = NULL;
9383
0
      } else {
9384
0
        val64_string *vs64 = (val64_string *)field_strings;
9385
0
        while (vs64->strptr) {
9386
0
          g_free((char *)vs64->strptr);
9387
0
          vs64++;
9388
0
        }
9389
0
      }
9390
0
      break;
9391
0
    }
9392
0
    case FT_CHAR:
9393
0
    case FT_UINT8:
9394
0
    case FT_INT8:
9395
0
    case FT_UINT16:
9396
0
    case FT_INT16:
9397
0
    case FT_UINT24:
9398
0
    case FT_INT24:
9399
0
    case FT_UINT32:
9400
0
    case FT_INT32:
9401
0
    case FT_FLOAT:
9402
0
    case FT_DOUBLE: {
9403
0
      if (field_display & BASE_UNIT_STRING) {
9404
0
        unit_name_string *unit = (unit_name_string *)field_strings;
9405
0
        g_free((char *)unit->singular);
9406
0
        g_free((char *)unit->plural);
9407
0
      } else if (field_display & BASE_RANGE_STRING) {
9408
0
        range_string *rs = (range_string *)field_strings;
9409
0
        while (rs->strptr) {
9410
0
          g_free((char *)rs->strptr);
9411
0
          rs++;
9412
0
        }
9413
0
      } else if (field_display & BASE_EXT_STRING) {
9414
0
        value_string_ext *vse = (value_string_ext *)field_strings;
9415
0
        value_string *vs = (value_string *)vse->_vs_p;
9416
0
        while (vs->strptr) {
9417
0
          g_free((char *)vs->strptr);
9418
0
          vs++;
9419
0
        }
9420
0
        value_string_ext_free(vse);
9421
0
        field_strings = NULL;
9422
0
      } else if (field_display == BASE_CUSTOM) {
9423
        /* this will be a pointer to a function, don't free that */
9424
0
        field_strings = NULL;
9425
0
      } else {
9426
0
        value_string *vs = (value_string *)field_strings;
9427
0
        while (vs->strptr) {
9428
0
          g_free((char *)vs->strptr);
9429
0
          vs++;
9430
0
        }
9431
0
      }
9432
0
      break;
9433
0
    default:
9434
0
      break;
9435
0
    }
9436
0
  }
9437
9438
0
  if (field_type != FT_FRAMENUM) {
9439
0
    g_free((void *)field_strings);
9440
0
  }
9441
0
}
9442
9443
static void
9444
free_deregistered_field (void *data, void *user_data _U_)
9445
0
{
9446
0
  header_field_info *hfi = (header_field_info *) data;
9447
0
  int hf_id = hfi->id;
9448
9449
0
  g_free((char *)hfi->name);
9450
0
  g_free((char *)hfi->abbrev);
9451
0
  g_free((char *)hfi->blurb);
9452
9453
0
  proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9454
9455
0
  if (hfi->parent == -1)
9456
0
    g_slice_free(header_field_info, hfi);
9457
9458
0
  gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
9459
0
}
9460
9461
static void
9462
free_deregistered_data (void *data, void *user_data _U_)
9463
0
{
9464
0
  g_free (data);
9465
0
}
9466
9467
static void
9468
free_deregistered_slice (void *data, void *user_data _U_)
9469
0
{
9470
0
  struct g_slice_data *slice_data = (struct g_slice_data *)data;
9471
9472
0
  g_slice_free1(slice_data->block_size, slice_data->mem_block);
9473
0
  g_slice_free(struct g_slice_data, slice_data);
9474
0
}
9475
9476
/* free deregistered fields and data */
9477
void
9478
proto_free_deregistered_fields (void)
9479
0
{
9480
0
  expert_free_deregistered_expertinfos();
9481
9482
0
  g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
9483
0
  g_ptr_array_free(deregistered_fields, true);
9484
0
  deregistered_fields = g_ptr_array_new();
9485
9486
0
  g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
9487
0
  g_ptr_array_free(deregistered_data, true);
9488
0
  deregistered_data = g_ptr_array_new();
9489
9490
0
  g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL);
9491
0
  g_ptr_array_free(deregistered_slice, true);
9492
0
  deregistered_slice = g_ptr_array_new();
9493
0
}
9494
9495
static const value_string hf_display[] = {
9496
  { BASE_NONE,        "BASE_NONE"        },
9497
  { BASE_DEC,       "BASE_DEC"         },
9498
  { BASE_HEX,       "BASE_HEX"         },
9499
  { BASE_OCT,       "BASE_OCT"         },
9500
  { BASE_DEC_HEX,       "BASE_DEC_HEX"       },
9501
  { BASE_HEX_DEC,       "BASE_HEX_DEC"       },
9502
  { BASE_CUSTOM,        "BASE_CUSTOM"        },
9503
  { BASE_NONE|BASE_RANGE_STRING,    "BASE_NONE|BASE_RANGE_STRING"    },
9504
  { BASE_DEC|BASE_RANGE_STRING,     "BASE_DEC|BASE_RANGE_STRING"     },
9505
  { BASE_HEX|BASE_RANGE_STRING,     "BASE_HEX|BASE_RANGE_STRING"     },
9506
  { BASE_OCT|BASE_RANGE_STRING,     "BASE_OCT|BASE_RANGE_STRING"     },
9507
  { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9508
  { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9509
  { BASE_CUSTOM|BASE_RANGE_STRING,  "BASE_CUSTOM|BASE_RANGE_STRING"  },
9510
  { BASE_NONE|BASE_VAL64_STRING,    "BASE_NONE|BASE_VAL64_STRING"    },
9511
  { BASE_DEC|BASE_VAL64_STRING,     "BASE_DEC|BASE_VAL64_STRING"     },
9512
  { BASE_HEX|BASE_VAL64_STRING,     "BASE_HEX|BASE_VAL64_STRING"     },
9513
  { BASE_OCT|BASE_VAL64_STRING,     "BASE_OCT|BASE_VAL64_STRING"     },
9514
  { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9515
  { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9516
  { BASE_CUSTOM|BASE_VAL64_STRING,  "BASE_CUSTOM|BASE_VAL64_STRING"  },
9517
  { ABSOLUTE_TIME_LOCAL,      "ABSOLUTE_TIME_LOCAL"      },
9518
  { ABSOLUTE_TIME_UTC,      "ABSOLUTE_TIME_UTC"      },
9519
  { ABSOLUTE_TIME_DOY_UTC,    "ABSOLUTE_TIME_DOY_UTC"    },
9520
  { BASE_PT_UDP,        "BASE_PT_UDP"        },
9521
  { BASE_PT_TCP,        "BASE_PT_TCP"        },
9522
  { BASE_PT_DCCP,       "BASE_PT_DCCP"       },
9523
  { BASE_PT_SCTP,       "BASE_PT_SCTP"       },
9524
  { BASE_OUI,       "BASE_OUI"         },
9525
  { 0,          NULL } };
9526
9527
const char* proto_field_display_to_string(int field_display)
9528
0
{
9529
0
  return val_to_str_const(field_display, hf_display, "Unknown");
9530
0
}
9531
9532
static inline port_type
9533
display_to_port_type(field_display_e e)
9534
0
{
9535
0
  switch (e) {
9536
0
  case BASE_PT_UDP:
9537
0
    return PT_UDP;
9538
0
  case BASE_PT_TCP:
9539
0
    return PT_TCP;
9540
0
  case BASE_PT_DCCP:
9541
0
    return PT_DCCP;
9542
0
  case BASE_PT_SCTP:
9543
0
    return PT_SCTP;
9544
0
  default:
9545
0
    break;
9546
0
  }
9547
0
  return PT_NONE;
9548
0
}
9549
9550
/* temporary function containing assert part for easier profiling */
9551
static void
9552
tmp_fld_check_assert(header_field_info *hfinfo)
9553
3.95M
{
9554
3.95M
  char* tmp_str;
9555
9556
  /* The field must have a name (with length > 0) */
9557
3.95M
  if (!hfinfo->name || !hfinfo->name[0]) {
9558
0
    if (hfinfo->abbrev)
9559
      /* Try to identify the field */
9560
0
      REPORT_DISSECTOR_BUG("Field (abbrev='%s') does not have a name",
9561
0
        hfinfo->abbrev);
9562
0
    else
9563
      /* Hum, no luck */
9564
0
      REPORT_DISSECTOR_BUG("Field does not have a name (nor an abbreviation)");
9565
0
  }
9566
9567
  /* fields with an empty string for an abbreviation aren't filterable */
9568
3.95M
  if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9569
3.95M
    REPORT_DISSECTOR_BUG("Field '%s' does not have an abbreviation", hfinfo->name);
9570
9571
  /* TODO: This check is a significant percentage of startup time (~10%),
9572
     although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9573
     It might be nice to have a way to disable this check when, e.g.,
9574
     running TShark many times with the same configuration. */
9575
  /* Check that the filter name (abbreviation) is legal;
9576
   * it must contain only alphanumerics, '-', "_", and ".". */
9577
3.95M
  unsigned char c;
9578
3.95M
  c = module_check_valid_name(hfinfo->abbrev, false);
9579
3.95M
  if (c) {
9580
0
    if (c == '.') {
9581
0
      REPORT_DISSECTOR_BUG("Invalid leading, duplicated or trailing '.' found in filter name '%s'", hfinfo->abbrev);
9582
0
    } else if (g_ascii_isprint(c)) {
9583
0
      REPORT_DISSECTOR_BUG("Invalid character '%c' in filter name '%s'", c, hfinfo->abbrev);
9584
0
    } else {
9585
0
      REPORT_DISSECTOR_BUG("Invalid byte \\%03o in filter name '%s'", c, hfinfo->abbrev);
9586
0
    }
9587
0
  }
9588
9589
  /*  These types of fields are allowed to have value_strings,
9590
   *  true_false_strings or a protocol_t struct
9591
   */
9592
3.95M
  if (hfinfo->strings != NULL && FIELD_DISPLAY(hfinfo->display) != BASE_CUSTOM) {
9593
942k
    switch (hfinfo->type) {
9594
9595
    /*
9596
     * These types are allowed to support display value_strings,
9597
     * value64_strings, the extended versions of the previous
9598
     * two, range strings, or unit strings.
9599
     */
9600
3.55k
    case FT_CHAR:
9601
199k
    case FT_UINT8:
9602
262k
    case FT_UINT16:
9603
265k
    case FT_UINT24:
9604
640k
    case FT_UINT32:
9605
640k
    case FT_UINT40:
9606
641k
    case FT_UINT48:
9607
641k
    case FT_UINT56:
9608
645k
    case FT_UINT64:
9609
646k
    case FT_INT8:
9610
647k
    case FT_INT16:
9611
647k
    case FT_INT24:
9612
660k
    case FT_INT32:
9613
660k
    case FT_INT40:
9614
660k
    case FT_INT48:
9615
660k
    case FT_INT56:
9616
661k
    case FT_INT64:
9617
885k
    case FT_BOOLEAN:
9618
920k
    case FT_PROTOCOL:
9619
920k
      break;
9620
9621
    /*
9622
     * This is allowed to have a value of type
9623
     * enum ft_framenum_type to indicate what relationship
9624
     * the frame in question has to the frame in which
9625
     * the field is put.
9626
     */
9627
3.83k
    case FT_FRAMENUM:
9628
3.83k
      break;
9629
9630
    /*
9631
     * These types are allowed to support only unit strings.
9632
     */
9633
1.16k
    case FT_FLOAT:
9634
2.76k
    case FT_DOUBLE:
9635
2.76k
    case FT_IEEE_11073_SFLOAT:
9636
2.76k
    case FT_IEEE_11073_FLOAT:
9637
2.76k
      if (!(hfinfo->display & BASE_UNIT_STRING)) {
9638
0
        REPORT_DISSECTOR_BUG("Field '%s' (%s) has a non-unit-strings 'strings' value but is of type %s"
9639
0
          " (which is only allowed to have unit strings)",
9640
0
          hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
9641
0
      }
9642
2.76k
      break;
9643
9644
    /*
9645
     * These types are allowed to support display
9646
     * time_value_strings.
9647
     */
9648
416
    case FT_ABSOLUTE_TIME:
9649
416
      if (hfinfo->display & BASE_RANGE_STRING ||
9650
416
          hfinfo->display & BASE_EXT_STRING ||
9651
416
          hfinfo->display & BASE_VAL64_STRING ||
9652
416
          hfinfo->display & BASE_UNIT_STRING) {
9653
0
        REPORT_DISSECTOR_BUG("Field '%s' (%s) has a non-time-value-strings 'strings' value but is of type %s"
9654
0
          " (which is only allowed to have time-value strings)",
9655
0
          hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
9656
0
      }
9657
416
      break;
9658
9659
    /*
9660
     * This type is only allowed to support a string if it's
9661
     * a protocol (for pinos).
9662
     */
9663
14.6k
    case FT_BYTES:
9664
14.6k
      if (!(hfinfo->display & BASE_PROTOCOL_INFO)) {
9665
0
        REPORT_DISSECTOR_BUG("Field '%s' (%s) has a non-protocol-info 'strings' value but is of type %s"
9666
0
          " (which is only allowed to have protocol-info strings)",
9667
0
          hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
9668
0
      }
9669
14.6k
      break;
9670
9671
0
    default:
9672
0
      REPORT_DISSECTOR_BUG("Field '%s' (%s) has a 'strings' value but is of type %s"
9673
942k
        " (which is not allowed to have strings)",
9674
942k
        hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
9675
942k
    }
9676
942k
  }
9677
9678
  /* TODO: This check may slow down startup, and output quite a few warnings.
9679
     It would be good to be able to enable this (and possibly other checks?)
9680
     in non-release builds.   */
9681
#ifdef ENABLE_CHECK_FILTER
9682
  /* Check for duplicate value_string values.
9683
     There are lots that have the same value *and* string, so for now only
9684
     report those that have same value but different string. */
9685
  if ((hfinfo->strings != NULL) &&
9686
      !(hfinfo->display & BASE_RANGE_STRING) &&
9687
      !(hfinfo->display & BASE_UNIT_STRING) &&
9688
      !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
9689
      (
9690
        (hfinfo->type == FT_CHAR)  ||
9691
        (hfinfo->type == FT_UINT8)  ||
9692
        (hfinfo->type == FT_UINT16) ||
9693
        (hfinfo->type == FT_UINT24) ||
9694
        (hfinfo->type == FT_UINT32) ||
9695
        (hfinfo->type == FT_INT8)   ||
9696
        (hfinfo->type == FT_INT16)  ||
9697
        (hfinfo->type == FT_INT24)  ||
9698
        (hfinfo->type == FT_INT32)  )) {
9699
9700
    if (hfinfo->display & BASE_EXT_STRING) {
9701
      if (hfinfo->display & BASE_VAL64_STRING) {
9702
        const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings);
9703
        CHECK_HF_VALUE(val64_string, PRIu64, start_values);
9704
      } else {
9705
        const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings);
9706
        CHECK_HF_VALUE(value_string, "u", start_values);
9707
      }
9708
    } else {
9709
      const value_string *start_values = (const value_string*)hfinfo->strings;
9710
      CHECK_HF_VALUE(value_string, "u", start_values);
9711
    }
9712
  }
9713
9714
  if (hfinfo->type == FT_BOOLEAN) {
9715
    const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9716
    if (tfs) {
9717
      if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9718
        ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",
9719
               hfinfo->name, hfinfo->abbrev,
9720
               tfs->false_string, tfs->true_string);
9721
      }
9722
    }
9723
  }
9724
9725
  if (hfinfo->display & BASE_RANGE_STRING) {
9726
    const range_string *rs = (const range_string*)(hfinfo->strings);
9727
    if (rs) {
9728
      const range_string *this_it = rs;
9729
9730
      do {
9731
        if (this_it->value_max < this_it->value_min) {
9732
          ws_warning("value_range_string error:  %s (%s) entry for \"%s\" - max(%"PRIu64" 0x%"PRIx64") is less than min(%"PRIu64" 0x%"PRIx64")",
9733
                hfinfo->name, hfinfo->abbrev,
9734
                this_it->strptr,
9735
                this_it->value_max, this_it->value_max,
9736
                this_it->value_min, this_it->value_min);
9737
          ++this_it;
9738
          continue;
9739
        }
9740
9741
        for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9742
          /* Not OK if this one is completely hidden by an earlier one! */
9743
          if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9744
            ws_warning("value_range_string error:  %s (%s) hidden by earlier entry "
9745
                  "(prev=\"%s\":  %"PRIu64" 0x%"PRIx64" -> %"PRIu64" 0x%"PRIx64")  (this=\"%s\":  %"PRIu64" 0x%"PRIx64" -> %"PRIu64" 0x%"PRIx64")",
9746
                  hfinfo->name, hfinfo->abbrev,
9747
                  prev_it->strptr, prev_it->value_min, prev_it->value_min,
9748
                  prev_it->value_max, prev_it->value_max,
9749
                  this_it->strptr, this_it->value_min, this_it->value_min,
9750
                  this_it->value_max, this_it->value_max);
9751
          }
9752
        }
9753
        ++this_it;
9754
      } while (this_it->strptr);
9755
    }
9756
  }
9757
#endif
9758
9759
3.95M
  switch (hfinfo->type) {
9760
9761
4.32k
    case FT_CHAR:
9762
      /*  Require the char type to have BASE_HEX, BASE_OCT,
9763
       *  BASE_CUSTOM, or BASE_NONE as its base.
9764
       *
9765
       *  If the display value is BASE_NONE and there is a
9766
       *  strings conversion then the dissector writer is
9767
       *  telling us that the field's numerical value is
9768
       *  meaningless; we'll avoid showing the value to the
9769
       *  user.
9770
       */
9771
4.32k
      switch (FIELD_DISPLAY(hfinfo->display)) {
9772
2.38k
        case BASE_HEX:
9773
2.38k
        case BASE_OCT:
9774
2.38k
        case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9775
2.38k
          break;
9776
1.93k
        case BASE_NONE:
9777
1.93k
          if (hfinfo->strings == NULL)
9778
1.93k
            REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"
9779
1.93k
              " but is being displayed as BASE_NONE but"
9780
1.93k
              " without a strings conversion",
9781
1.93k
              hfinfo->name, hfinfo->abbrev,
9782
1.93k
              ftype_name(hfinfo->type));
9783
1.93k
          break;
9784
0
        default:
9785
0
          tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
9786
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is a character value (%s)"
9787
4.32k
            " but is being displayed as %s",
9788
4.32k
            hfinfo->name, hfinfo->abbrev,
9789
4.32k
            ftype_name(hfinfo->type), tmp_str);
9790
          //wmem_free(NULL, tmp_str);
9791
4.32k
      }
9792
4.32k
      if (hfinfo->display & BASE_UNIT_STRING) {
9793
0
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is a character value (%s) but has a unit string",
9794
0
          hfinfo->name, hfinfo->abbrev,
9795
0
          ftype_name(hfinfo->type));
9796
0
      }
9797
4.32k
      break;
9798
6.16k
    case FT_INT8:
9799
14.5k
    case FT_INT16:
9800
14.9k
    case FT_INT24:
9801
79.2k
    case FT_INT32:
9802
79.2k
    case FT_INT40:
9803
79.2k
    case FT_INT48:
9804
79.2k
    case FT_INT56:
9805
86.7k
    case FT_INT64:
9806
      /*  Hexadecimal and octal are, in printf() and everywhere
9807
       *  else, unsigned so don't allow dissectors to register a
9808
       *  signed field to be displayed unsigned.  (Else how would
9809
       *  we display negative values?)
9810
       */
9811
86.7k
      switch (FIELD_DISPLAY(hfinfo->display)) {
9812
0
        case BASE_HEX:
9813
0
        case BASE_OCT:
9814
0
        case BASE_DEC_HEX:
9815
0
        case BASE_HEX_DEC:
9816
0
          tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
9817
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)",
9818
86.7k
            hfinfo->name, hfinfo->abbrev,
9819
86.7k
            ftype_name(hfinfo->type), tmp_str);
9820
          //wmem_free(NULL, tmp_str);
9821
86.7k
      }
9822
      /* FALL THROUGH */
9823
661k
    case FT_UINT8:
9824
986k
    case FT_UINT16:
9825
1.00M
    case FT_UINT24:
9826
2.02M
    case FT_UINT32:
9827
2.02M
    case FT_UINT40:
9828
2.02M
    case FT_UINT48:
9829
2.02M
    case FT_UINT56:
9830
2.08M
    case FT_UINT64:
9831
2.08M
      if (IS_BASE_PORT(hfinfo->display)) {
9832
1.53k
        tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
9833
1.53k
        if (hfinfo->type != FT_UINT16) {
9834
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s",
9835
0
            hfinfo->name, hfinfo->abbrev,
9836
0
            tmp_str, ftype_name(hfinfo->type));
9837
0
        }
9838
1.53k
        if (hfinfo->strings != NULL) {
9839
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s (%s) but has a strings value",
9840
0
            hfinfo->name, hfinfo->abbrev,
9841
0
            ftype_name(hfinfo->type), tmp_str);
9842
0
        }
9843
1.53k
        if (hfinfo->bitmask != 0) {
9844
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s (%s) but has a bitmask",
9845
0
            hfinfo->name, hfinfo->abbrev,
9846
0
            ftype_name(hfinfo->type), tmp_str);
9847
0
        }
9848
1.53k
        wmem_free(NULL, tmp_str);
9849
1.53k
        break;
9850
1.53k
      }
9851
9852
2.08M
      if (hfinfo->display == BASE_OUI) {
9853
1.05k
        tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
9854
1.05k
        if (!FT_IS_UINT(hfinfo->type) || ftype_wire_size(hfinfo->type) < 3) {
9855
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT24, not %s",
9856
0
            hfinfo->name, hfinfo->abbrev,
9857
0
            tmp_str, ftype_name(hfinfo->type));
9858
0
        }
9859
1.05k
        if (hfinfo->strings != NULL) {
9860
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s (%s) but has a strings value",
9861
0
            hfinfo->name, hfinfo->abbrev,
9862
0
            ftype_name(hfinfo->type), tmp_str);
9863
0
        }
9864
        /* It can be a FT_UINT24 with a 0 bitmask, or
9865
         * larger with a bitmask with 24 bits set. */
9866
1.05k
        if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9867
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s (%s) but has a bitmask",
9868
0
            hfinfo->name, hfinfo->abbrev,
9869
0
            ftype_name(hfinfo->type), tmp_str);
9870
0
        }
9871
1.05k
        wmem_free(NULL, tmp_str);
9872
1.05k
        break;
9873
1.05k
      }
9874
9875
      /*  Require integral types (other than frame number,
9876
       *  which is always displayed in decimal) to have a
9877
       *  number base.
9878
       *
9879
       *  If the display value is BASE_NONE and there is a
9880
       *  strings conversion then the dissector writer is
9881
       *  telling us that the field's numerical value is
9882
       *  meaningless; we'll avoid showing the value to the
9883
       *  user.
9884
       */
9885
2.08M
      switch (FIELD_DISPLAY(hfinfo->display)) {
9886
1.57M
        case BASE_DEC:
9887
1.98M
        case BASE_HEX:
9888
1.98M
        case BASE_OCT:
9889
2.00M
        case BASE_DEC_HEX:
9890
2.04M
        case BASE_HEX_DEC:
9891
2.08M
        case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9892
2.08M
          break;
9893
2.93k
        case BASE_NONE:
9894
2.93k
          if (hfinfo->strings == NULL) {
9895
0
            REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"
9896
0
              " but is being displayed as BASE_NONE but"
9897
0
              " without a strings conversion",
9898
0
              hfinfo->name, hfinfo->abbrev,
9899
0
              ftype_name(hfinfo->type));
9900
0
          }
9901
2.93k
          if (hfinfo->display & BASE_SPECIAL_VALS) {
9902
0
            REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"
9903
0
              " that is being displayed as BASE_NONE but"
9904
0
              " with BASE_SPECIAL_VALS",
9905
0
              hfinfo->name, hfinfo->abbrev,
9906
0
              ftype_name(hfinfo->type));
9907
0
          }
9908
2.93k
          break;
9909
9910
0
        default:
9911
0
          tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
9912
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"
9913
2.08M
            " but is being displayed as %s",
9914
2.08M
            hfinfo->name, hfinfo->abbrev,
9915
2.08M
            ftype_name(hfinfo->type), tmp_str);
9916
          //wmem_free(NULL, tmp_str);
9917
2.08M
      }
9918
2.08M
      break;
9919
2.08M
    case FT_BYTES:
9920
264k
    case FT_UINT_BYTES:
9921
      /*  Require bytes to have a "display type" that could
9922
       *  add a character between displayed bytes.
9923
       */
9924
264k
      switch (FIELD_DISPLAY(hfinfo->display)) {
9925
261k
        case BASE_NONE:
9926
261k
        case SEP_DOT:
9927
261k
        case SEP_DASH:
9928
263k
        case SEP_COLON:
9929
264k
        case SEP_SPACE:
9930
264k
          break;
9931
0
        default:
9932
0
          tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
9933
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is an byte array but is being displayed as %s instead of BASE_NONE, SEP_DOT, SEP_DASH, SEP_COLON, or SEP_SPACE",
9934
264k
            hfinfo->name, hfinfo->abbrev, tmp_str);
9935
          //wmem_free(NULL, tmp_str);
9936
264k
      }
9937
264k
      if (hfinfo->bitmask != 0)
9938
264k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",
9939
264k
          hfinfo->name, hfinfo->abbrev,
9940
264k
          ftype_name(hfinfo->type));
9941
      //allowed to support string if its a protocol (for pinos)
9942
264k
      if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_PROTOCOL_INFO)))
9943
264k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",
9944
264k
          hfinfo->name, hfinfo->abbrev,
9945
264k
          ftype_name(hfinfo->type));
9946
264k
      break;
9947
9948
37.2k
    case FT_PROTOCOL:
9949
53.3k
    case FT_FRAMENUM:
9950
53.3k
      if (hfinfo->display != BASE_NONE) {
9951
0
        tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
9952
0
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE",
9953
0
          hfinfo->name, hfinfo->abbrev,
9954
0
          ftype_name(hfinfo->type), tmp_str);
9955
        //wmem_free(NULL, tmp_str);
9956
0
      }
9957
53.3k
      if (hfinfo->bitmask != 0)
9958
53.3k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",
9959
53.3k
          hfinfo->name, hfinfo->abbrev,
9960
53.3k
          ftype_name(hfinfo->type));
9961
53.3k
      break;
9962
9963
520k
    case FT_BOOLEAN:
9964
520k
      break;
9965
9966
15.2k
    case FT_ABSOLUTE_TIME:
9967
15.2k
      if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)) {
9968
0
        tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
9969
0
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time",
9970
0
          hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
9971
        //wmem_free(NULL, tmp_str);
9972
0
      }
9973
15.2k
      if (hfinfo->bitmask != 0)
9974
15.2k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",
9975
15.2k
          hfinfo->name, hfinfo->abbrev,
9976
15.2k
          ftype_name(hfinfo->type));
9977
15.2k
      break;
9978
9979
196k
    case FT_STRING:
9980
210k
    case FT_STRINGZ:
9981
216k
    case FT_UINT_STRING:
9982
217k
    case FT_STRINGZPAD:
9983
219k
    case FT_STRINGZTRUNC:
9984
219k
      switch (FIELD_DISPLAY(hfinfo->display)) {
9985
219k
        case BASE_NONE:
9986
219k
        case BASE_STR_WSP:
9987
219k
          break;
9988
9989
0
        default:
9990
0
          tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
9991
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is an string value (%s)"
9992
219k
            " but is being displayed as %s",
9993
219k
            hfinfo->name, hfinfo->abbrev,
9994
219k
            ftype_name(hfinfo->type), tmp_str);
9995
          //wmem_free(NULL, tmp_str);
9996
219k
      }
9997
9998
219k
      if (hfinfo->bitmask != 0)
9999
219k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",
10000
219k
          hfinfo->name, hfinfo->abbrev,
10001
219k
          ftype_name(hfinfo->type));
10002
219k
      if (hfinfo->strings != NULL)
10003
219k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",
10004
219k
          hfinfo->name, hfinfo->abbrev,
10005
219k
          ftype_name(hfinfo->type));
10006
219k
      break;
10007
10008
23.3k
    case FT_IPv4:
10009
23.3k
      switch (hfinfo->display) {
10010
22.8k
        case BASE_NONE:
10011
23.3k
        case BASE_NETMASK:
10012
23.3k
          break;
10013
10014
0
        default:
10015
0
          tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
10016
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is an IPv4 value (%s)"
10017
0
            " but is being displayed as %s",
10018
0
            hfinfo->name, hfinfo->abbrev,
10019
0
            ftype_name(hfinfo->type), tmp_str);
10020
          //wmem_free(NULL, tmp_str);
10021
0
          break;
10022
23.3k
      }
10023
23.3k
      break;
10024
23.3k
    case FT_FLOAT:
10025
27.7k
    case FT_DOUBLE:
10026
27.7k
      switch (FIELD_DISPLAY(hfinfo->display)) {
10027
25.8k
        case BASE_NONE:
10028
27.6k
        case BASE_DEC:
10029
27.6k
        case BASE_HEX:
10030
27.7k
        case BASE_EXP:
10031
27.7k
        case BASE_CUSTOM:
10032
27.7k
          break;
10033
0
        default:
10034
0
          tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
10035
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is a float value (%s)"
10036
27.7k
            " but is being displayed as %s",
10037
27.7k
            hfinfo->name, hfinfo->abbrev,
10038
27.7k
            ftype_name(hfinfo->type), tmp_str);
10039
          //wmem_free(NULL, tmp_str);
10040
27.7k
      }
10041
27.7k
      if (hfinfo->bitmask != 0)
10042
27.7k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",
10043
27.7k
          hfinfo->name, hfinfo->abbrev,
10044
27.7k
          ftype_name(hfinfo->type));
10045
27.7k
      if (FIELD_DISPLAY(hfinfo->display) != BASE_CUSTOM && (hfinfo->strings != NULL) && !(hfinfo->display & BASE_UNIT_STRING))
10046
27.7k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",
10047
27.7k
          hfinfo->name, hfinfo->abbrev,
10048
27.7k
          ftype_name(hfinfo->type));
10049
27.7k
      break;
10050
384
    case FT_IEEE_11073_SFLOAT:
10051
432
    case FT_IEEE_11073_FLOAT:
10052
432
      if (FIELD_DISPLAY(hfinfo->display) != BASE_NONE) {
10053
0
        tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
10054
0
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE",
10055
0
          hfinfo->name, hfinfo->abbrev,
10056
0
          ftype_name(hfinfo->type),
10057
0
          tmp_str);
10058
        //wmem_free(NULL, tmp_str);
10059
0
      }
10060
432
      if (hfinfo->bitmask != 0)
10061
432
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",
10062
432
          hfinfo->name, hfinfo->abbrev,
10063
432
          ftype_name(hfinfo->type));
10064
432
      if ((hfinfo->strings != NULL) && !(hfinfo->display & BASE_UNIT_STRING))
10065
432
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",
10066
432
          hfinfo->name, hfinfo->abbrev,
10067
432
          ftype_name(hfinfo->type));
10068
432
      break;
10069
733k
    default:
10070
733k
      if (hfinfo->display != BASE_NONE) {
10071
0
        tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
10072
0
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE",
10073
0
          hfinfo->name, hfinfo->abbrev,
10074
0
          ftype_name(hfinfo->type),
10075
0
          tmp_str);
10076
        //wmem_free(NULL, tmp_str);
10077
0
      }
10078
733k
      if (hfinfo->bitmask != 0)
10079
733k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",
10080
733k
          hfinfo->name, hfinfo->abbrev,
10081
733k
          ftype_name(hfinfo->type));
10082
733k
      if (hfinfo->strings != NULL)
10083
733k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",
10084
733k
          hfinfo->name, hfinfo->abbrev,
10085
733k
          ftype_name(hfinfo->type));
10086
733k
      break;
10087
3.95M
  }
10088
3.95M
}
10089
10090
static void
10091
register_type_length_mismatch(void)
10092
16
{
10093
16
  static ei_register_info ei[] = {
10094
16
    { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
10095
16
    { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch_warn", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
10096
16
  };
10097
10098
16
  expert_module_t* expert_type_length_mismatch;
10099
10100
16
  proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
10101
10102
16
  expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
10103
16
  expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
10104
10105
  /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
10106
     disabling them makes no sense. */
10107
16
  proto_set_cant_toggle(proto_type_length_mismatch);
10108
16
}
10109
10110
static void
10111
register_byte_array_string_decodinws_error(void)
10112
16
{
10113
16
  static ei_register_info ei[] = {
10114
16
    { &ei_byte_array_string_decoding_failed_error,
10115
16
      { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
10116
16
        "Failed to decode byte array from string", EXPFILL
10117
16
      }
10118
16
    },
10119
16
  };
10120
10121
16
  expert_module_t* expert_byte_array_string_decoding_error;
10122
10123
16
  proto_byte_array_string_decoding_error =
10124
16
    proto_register_protocol("Byte Array-String Decoding Error",
10125
16
          "Byte Array-string decoding error",
10126
16
          "_ws.byte_array_string.decoding_error");
10127
10128
16
  expert_byte_array_string_decoding_error =
10129
16
    expert_register_protocol(proto_byte_array_string_decoding_error);
10130
16
  expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei));
10131
10132
  /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
10133
     disabling them makes no sense. */
10134
16
  proto_set_cant_toggle(proto_byte_array_string_decoding_error);
10135
16
}
10136
10137
static void
10138
register_date_time_string_decodinws_error(void)
10139
16
{
10140
16
  static ei_register_info ei[] = {
10141
16
    { &ei_date_time_string_decoding_failed_error,
10142
16
      { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
10143
16
        "Failed to decode date and time from string", EXPFILL
10144
16
      }
10145
16
    },
10146
16
  };
10147
10148
16
  expert_module_t* expert_date_time_string_decoding_error;
10149
10150
16
  proto_date_time_string_decoding_error =
10151
16
    proto_register_protocol("Date and Time-String Decoding Error",
10152
16
          "Date and Time-string decoding error",
10153
16
          "_ws.date_time_string.decoding_error");
10154
10155
16
  expert_date_time_string_decoding_error =
10156
16
    expert_register_protocol(proto_date_time_string_decoding_error);
10157
16
  expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei));
10158
10159
  /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10160
     disabling them makes no sense. */
10161
16
  proto_set_cant_toggle(proto_date_time_string_decoding_error);
10162
16
}
10163
10164
static void
10165
register_string_errors(void)
10166
16
{
10167
16
  static ei_register_info ei[] = {
10168
16
    { &ei_string_trailing_characters,
10169
16
      { "_ws.string.trailing_stray_characters", PI_UNDECODED, PI_WARN, "Trailing stray characters", EXPFILL }
10170
16
    },
10171
16
  };
10172
10173
16
  expert_module_t* expert_string_errors;
10174
10175
16
  proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10176
10177
16
  expert_string_errors = expert_register_protocol(proto_string_errors);
10178
16
  expert_register_field_array(expert_string_errors, ei, array_length(ei));
10179
10180
  /* "String Errors" isn't really a protocol, it's an error indication;
10181
     disabling them makes no sense. */
10182
16
  proto_set_cant_toggle(proto_string_errors);
10183
16
}
10184
10185
static void
10186
register_varint_errors(void)
10187
16
{
10188
16
  static ei_register_info ei[] = {
10189
16
    { &ei_varint_decoding_failed_error,
10190
16
      { "_ws.varint.decoding_failed", PI_MALFORMED, PI_ERROR, "Varint decoding failed", EXPFILL }
10191
16
    },
10192
16
  };
10193
10194
16
  expert_module_t* expert_varint_errors;
10195
10196
16
  proto_varint_errors = proto_register_protocol("Varint Errors", "Varint errors", "_ws.varint");
10197
10198
16
  expert_varint_errors = expert_register_protocol(proto_varint_errors);
10199
16
  expert_register_field_array(expert_varint_errors, ei, array_length(ei));
10200
10201
  /* "Varint Errors" isn't really a protocol, it's an error indication;
10202
     disabling them makes no sense. */
10203
16
  proto_set_cant_toggle(proto_varint_errors);
10204
16
}
10205
10206
static int
10207
proto_register_field_init(header_field_info *hfinfo, const int parent)
10208
3.95M
{
10209
10210
3.95M
  tmp_fld_check_assert(hfinfo);
10211
10212
3.95M
  hfinfo->parent         = parent;
10213
3.95M
  hfinfo->same_name_next = NULL;
10214
3.95M
  hfinfo->same_name_prev_id = -1;
10215
10216
  /* if we always add and never delete, then id == len - 1 is correct */
10217
3.95M
  if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10218
16
    if (!gpa_hfinfo.hfi) {
10219
16
      gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
10220
16
      gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
10221
      /* The entry with index 0 is not used. */
10222
16
      gpa_hfinfo.hfi[0] = NULL;
10223
16
      gpa_hfinfo.len = 1;
10224
16
    } else {
10225
0
      gpa_hfinfo.allocated_len += 1000;
10226
0
      gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10227
0
               sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10228
      /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10229
0
    }
10230
16
  }
10231
3.95M
  gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10232
3.95M
  gpa_hfinfo.len++;
10233
3.95M
  hfinfo->id = gpa_hfinfo.len - 1;
10234
10235
  /* if we have real names, enter this field in the name tree */
10236
  /* Already checked in tmp_fld_check_assert */
10237
  /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10238
3.95M
  {
10239
10240
3.95M
    header_field_info *same_name_next_hfinfo;
10241
10242
    /* We allow multiple hfinfo's to be registered under the same
10243
     * abbreviation. This was done for X.25, as, depending
10244
     * on whether it's modulo-8 or modulo-128 operation,
10245
     * some bitfield fields may be in different bits of
10246
     * a byte, and we want to be able to refer to that field
10247
     * with one name regardless of whether the packets
10248
     * are modulo-8 or modulo-128 packets. */
10249
10250
    /* wmem_map_insert - if key is already present the previous
10251
     * hfinfo with the same key/name is returned, otherwise NULL */
10252
3.95M
    same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10253
3.95M
    if (same_name_hfinfo) {
10254
      /* There's already a field with this name.
10255
       * Put the current field *before* that field
10256
       * in the list of fields with this name, Thus,
10257
       * we end up with an effectively
10258
       * doubly-linked-list of same-named hfinfo's,
10259
       * with the head of the list (stored in the
10260
       * hash) being the last seen hfinfo.
10261
       */
10262
235k
      same_name_next_hfinfo =
10263
235k
        same_name_hfinfo->same_name_next;
10264
10265
235k
      hfinfo->same_name_next = same_name_next_hfinfo;
10266
235k
      if (same_name_next_hfinfo)
10267
0
        same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10268
10269
235k
      same_name_hfinfo->same_name_next = hfinfo;
10270
235k
      hfinfo->same_name_prev_id = same_name_hfinfo->id;
10271
#ifdef ENABLE_CHECK_FILTER
10272
      while (same_name_hfinfo) {
10273
        if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10274
          ws_error("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type));
10275
        same_name_hfinfo = same_name_hfinfo->same_name_next;
10276
      }
10277
#endif
10278
235k
    }
10279
3.95M
  }
10280
10281
3.95M
  return hfinfo->id;
10282
3.95M
}
10283
10284
void
10285
proto_register_subtree_array(int * const *indices, const int num_indices)
10286
30.7k
{
10287
30.7k
  int i;
10288
30.7k
  int *const *ptr = indices;
10289
10290
  /*
10291
   * If we've already allocated the array of tree types, expand
10292
   * it; this lets plugins such as mate add tree types after
10293
   * the initial startup.  (If we haven't already allocated it,
10294
   * we don't allocate it; on the first pass, we just assign
10295
   * ett values and keep track of how many we've assigned, and
10296
   * when we're finished registering all dissectors we allocate
10297
   * the array, so that we do only one allocation rather than
10298
   * wasting CPU time and memory by growing the array for each
10299
   * dissector that registers ett values.)
10300
   */
10301
30.7k
  if (tree_is_expanded != NULL) {
10302
155
    tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10303
10304
    /* set new items to 0 */
10305
    /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10306
510
    for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10307
355
      tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10308
155
  }
10309
10310
  /*
10311
   * Assign "num_indices" subtree numbers starting at "num_tree_types",
10312
   * returning the indices through the pointers in the array whose
10313
   * first element is pointed to by "indices", and update
10314
   * "num_tree_types" appropriately.
10315
   */
10316
1.04M
  for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10317
1.01M
    if (**ptr != -1 && **ptr != 0) {
10318
0
      REPORT_DISSECTOR_BUG("register_subtree_array: subtree item type (ett_...) not -1 or 0 !"
10319
0
        " This is a development error:"
10320
0
        " Either the subtree item type has already been assigned or"
10321
0
        " was not initialized to -1 or 0.");
10322
0
    }
10323
1.01M
    **ptr = num_tree_types;
10324
1.01M
  }
10325
30.7k
}
10326
10327
static void
10328
mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10329
17.2k
{
10330
17.2k
  static const char  trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS "] ";
10331
17.2k
  const size_t       trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10332
17.2k
  char              *last_char;
10333
10334
  /* ..... field_name: dataaaaaaaaaaaaa
10335
   *                 |
10336
   *                 ^^^^^ name_pos
10337
   *
10338
   * ..... field_name […]: dataaaaaaaaaaaaa
10339
   *
10340
   * name_pos==0 means that we have only data or only a field_name
10341
   */
10342
10343
17.2k
  ws_abort_if_fail(size > trunc_len);
10344
10345
17.2k
  if (name_pos >= size - trunc_len) {
10346
    /* No room for trunc_str after the field_name, put it first. */
10347
0
    name_pos = 0;
10348
0
  }
10349
10350
17.2k
  memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10351
17.2k
  if (name_pos == 0) {
10352
    /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10353
9.75k
    memcpy(label_str, trunc_str + 1, trunc_len);
10354
9.75k
  } else {
10355
7.49k
    memcpy(label_str + name_pos, trunc_str, trunc_len);
10356
7.49k
  }
10357
  /* in general, label_str is UTF-8
10358
     we can truncate it only at the beginning of a new character
10359
     we go backwards from the byte right after our buffer and
10360
      find the next starting byte of a UTF-8 character, this is
10361
      where we cut
10362
     there's no need to use g_utf8_find_prev_char(), the search
10363
      will always succeed since we copied trunc_str into the
10364
      buffer */
10365
  /* g_utf8_prev_char does not deference the memory address
10366
   * passed in (until after decrementing it, so it is perfectly
10367
   * legal to pass in a pointer one past the last element.
10368
   */
10369
17.2k
  last_char = g_utf8_prev_char(label_str + size);
10370
17.2k
  *last_char = '\0';
10371
  /* This is unnecessary (above always terminates), but try to
10372
   * convince Coverity to avoid dozens of false positives. */
10373
17.2k
  label_str[size - 1] = '\0';
10374
10375
17.2k
  if (value_pos && *value_pos > 0) {
10376
11.5k
    if (name_pos == 0) {
10377
6.98k
      *value_pos += trunc_len;
10378
6.98k
    } else {
10379
      /* Move one back to include trunc_str in the value. */
10380
4.59k
      *value_pos -= 1;
10381
4.59k
    }
10382
11.5k
  }
10383
10384
  /* Check if value_pos is past label_str. */
10385
17.2k
  if (value_pos && *value_pos >= size) {
10386
16
    *value_pos = size - 1;
10387
16
  }
10388
17.2k
}
10389
10390
static void
10391
label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10392
17.2k
{
10393
17.2k
  mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH, value_pos);
10394
17.2k
}
10395
10396
static size_t
10397
label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10398
2.41M
{
10399
2.41M
  size_t name_pos;
10400
10401
  /* "%s: %s", hfinfo->name, text */
10402
2.41M
  name_pos = pos = label_concat(label_str, pos, (const uint8_t*)hfinfo->name);
10403
2.41M
  if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
10404
2.41M
    pos = label_concat(label_str, pos, (const uint8_t*)": ");
10405
2.41M
    if (value_pos) {
10406
1.77M
      *value_pos = pos;
10407
1.77M
    }
10408
2.41M
    pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10409
2.41M
  }
10410
10411
2.41M
  if (pos >= ITEM_LABEL_LENGTH) {
10412
    /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10413
283
    label_mark_truncated(label_str, name_pos, value_pos);
10414
283
  }
10415
10416
2.41M
  return pos;
10417
2.41M
}
10418
10419
static size_t
10420
label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10421
1.03M
{
10422
1.03M
  size_t name_pos;
10423
10424
  /* "%s: %s (%s)", hfinfo->name, text, descr */
10425
1.03M
  name_pos = pos = label_concat(label_str, pos, (const uint8_t*)hfinfo->name);
10426
1.03M
  if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
10427
1.03M
    pos = label_concat(label_str, pos, (const uint8_t*)": ");
10428
1.03M
    if (value_pos) {
10429
62.6k
      *value_pos = pos;
10430
62.6k
    }
10431
1.03M
    if (hfinfo->display & BASE_UNIT_STRING) {
10432
2.44k
      pos = label_concat(label_str, pos, (const uint8_t*)(descr ? descr : "(null)"));
10433
2.44k
      pos = label_concat(label_str, pos, (const uint8_t*)(text ? text : "(null)"));
10434
1.02M
    } else {
10435
1.02M
      pos = label_concat(label_str, pos, (const uint8_t*)(text ? text : "(null)"));
10436
1.02M
      pos = label_concat(label_str, pos, (const uint8_t*)" (");
10437
1.02M
      pos = label_concat(label_str, pos, (const uint8_t*)(descr ? descr : "(null)"));
10438
1.02M
      pos = label_concat(label_str, pos, (const uint8_t*)")");
10439
1.02M
    }
10440
1.03M
  }
10441
10442
1.03M
  if (pos >= ITEM_LABEL_LENGTH) {
10443
    /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10444
2.90k
    label_mark_truncated(label_str, name_pos, value_pos);
10445
2.90k
  }
10446
10447
1.03M
  return pos;
10448
1.03M
}
10449
10450
void
10451
proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10452
3.46M
{
10453
3.46M
  const header_field_info  *hfinfo;
10454
3.46M
  const char     *str;
10455
3.46M
  const uint8_t    *bytes;
10456
3.46M
  uint32_t        integer;
10457
3.46M
  const ipv4_addr_and_mask *ipv4;
10458
3.46M
  const ipv6_addr_and_prefix *ipv6;
10459
3.46M
  const e_guid_t     *guid;
10460
3.46M
  char       *name;
10461
3.46M
  address       addr;
10462
3.46M
  char       *addr_str;
10463
3.46M
  char       *tmp;
10464
10465
3.46M
  if (!label_str) {
10466
0
    ws_warning("NULL label_str passed to proto_item_fill_label.");
10467
0
    return;
10468
0
  }
10469
10470
3.46M
  label_str[0]= '\0';
10471
10472
3.46M
  if (!fi) {
10473
0
    return;
10474
0
  }
10475
10476
3.46M
  hfinfo = fi->hfinfo;
10477
10478
3.46M
  switch (hfinfo->type) {
10479
1.18M
    case FT_NONE:
10480
1.62M
    case FT_PROTOCOL:
10481
1.62M
      (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
10482
1.62M
      if (value_pos) {
10483
1.62M
        *value_pos = strlen(hfinfo->name);
10484
1.62M
      }
10485
1.62M
      break;
10486
10487
13.1k
    case FT_BOOLEAN:
10488
13.1k
      fill_label_boolean(fi, label_str, value_pos);
10489
13.1k
      break;
10490
10491
296k
    case FT_BYTES:
10492
296k
    case FT_UINT_BYTES:
10493
296k
      tmp = format_bytes_hfinfo(NULL, hfinfo,
10494
296k
          fvalue_get_bytes_data(fi->value),
10495
296k
          (unsigned)fvalue_length2(fi->value));
10496
296k
      label_fill(label_str, 0, hfinfo, tmp, value_pos);
10497
296k
      wmem_free(NULL, tmp);
10498
296k
      break;
10499
10500
0
    case FT_CHAR:
10501
0
      if (hfinfo->bitmask) {
10502
0
        fill_label_bitfield_char(fi, label_str, value_pos);
10503
0
      } else {
10504
0
        fill_label_char(fi, label_str, value_pos);
10505
0
      }
10506
0
      break;
10507
10508
    /* Four types of integers to take care of:
10509
     *  Bitfield, with val_string
10510
     *  Bitfield, w/o val_string
10511
     *  Non-bitfield, with val_string
10512
     *  Non-bitfield, w/o val_string
10513
     */
10514
399k
    case FT_UINT8:
10515
823k
    case FT_UINT16:
10516
830k
    case FT_UINT24:
10517
1.43M
    case FT_UINT32:
10518
1.43M
      if (hfinfo->bitmask) {
10519
207k
        fill_label_bitfield(fi, label_str, value_pos, false);
10520
1.22M
      } else {
10521
1.22M
        fill_label_number(fi, label_str, value_pos, false);
10522
1.22M
      }
10523
1.43M
      break;
10524
10525
0
    case FT_FRAMENUM:
10526
0
      fill_label_number(fi, label_str, value_pos, false);
10527
0
      break;
10528
10529
15.7k
    case FT_UINT40:
10530
15.7k
    case FT_UINT48:
10531
15.7k
    case FT_UINT56:
10532
16.4k
    case FT_UINT64:
10533
16.4k
      if (hfinfo->bitmask) {
10534
438
        fill_label_bitfield64(fi, label_str, value_pos, false);
10535
16.0k
      } else {
10536
16.0k
        fill_label_number64(fi, label_str, value_pos, false);
10537
16.0k
      }
10538
16.4k
      break;
10539
10540
548
    case FT_INT8:
10541
2.31k
    case FT_INT16:
10542
2.77k
    case FT_INT24:
10543
2.90k
    case FT_INT32:
10544
2.90k
      if (hfinfo->bitmask) {
10545
458
        fill_label_bitfield(fi, label_str, value_pos, true);
10546
2.45k
      } else {
10547
2.45k
        fill_label_number(fi, label_str, value_pos, true);
10548
2.45k
      }
10549
2.90k
      break;
10550
10551
0
    case FT_INT40:
10552
0
    case FT_INT48:
10553
0
    case FT_INT56:
10554
49
    case FT_INT64:
10555
49
      if (hfinfo->bitmask) {
10556
0
        fill_label_bitfield64(fi, label_str, value_pos, true);
10557
49
      } else {
10558
49
        fill_label_number64(fi, label_str, value_pos, true);
10559
49
      }
10560
49
      break;
10561
10562
7.39k
    case FT_FLOAT:
10563
9.46k
    case FT_DOUBLE:
10564
9.46k
      fill_label_float(fi, label_str, value_pos);
10565
9.46k
      break;
10566
10567
670
    case FT_ABSOLUTE_TIME:
10568
670
    {
10569
670
      const nstime_t *value = fvalue_get_time(fi->value);
10570
670
      int flags = ABS_TIME_TO_STR_SHOW_ZONE;
10571
670
      if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10572
0
        flags |= ABS_TIME_TO_STR_ISO8601;
10573
0
      }
10574
670
      if (hfinfo->strings) {
10575
        /*
10576
         * Table of time values to be displayed
10577
         * specially.
10578
         *
10579
         * XXX - Initializing these time_value_strings can be a pain
10580
         * because the special times usually have special values in
10581
         * the original encoding, not when converted to a nstime_t
10582
         * relative to the UN*X epoch.
10583
         */
10584
0
        const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10585
0
        if (time_string != NULL) {
10586
0
          label_fill(label_str, 0, hfinfo, time_string, value_pos);
10587
0
          break;
10588
0
        }
10589
0
      }
10590
670
      tmp = abs_time_to_str_ex(NULL, value, hfinfo->display, flags);
10591
670
      label_fill(label_str, 0, hfinfo, tmp, value_pos);
10592
670
      wmem_free(NULL, tmp);
10593
670
      break;
10594
670
    }
10595
7
    case FT_RELATIVE_TIME:
10596
7
      tmp = rel_time_to_str(NULL, fvalue_get_time(fi->value));
10597
7
      label_fill(label_str, 0, hfinfo, tmp, value_pos);
10598
7
      wmem_free(NULL, tmp);
10599
7
      break;
10600
10601
0
    case FT_IPXNET:
10602
0
      integer = fvalue_get_uinteger(fi->value);
10603
0
      tmp = get_ipxnet_name(NULL, integer);
10604
0
      addr_str = wmem_strdup_printf(NULL, "0x%08X", integer);
10605
0
      label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10606
0
      wmem_free(NULL, tmp);
10607
0
      wmem_free(NULL, addr_str);
10608
0
      break;
10609
10610
0
    case FT_VINES:
10611
0
      addr.type = AT_VINES;
10612
0
      addr.len  = VINES_ADDR_LEN;
10613
0
      addr.data = fvalue_get_bytes_data(fi->value);
10614
10615
0
      addr_str = (char*)address_to_str(NULL, &addr);
10616
0
      label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10617
0
      wmem_free(NULL, addr_str);
10618
0
      break;
10619
10620
35
    case FT_ETHER:
10621
35
      bytes = fvalue_get_bytes_data(fi->value);
10622
10623
35
      addr.type = AT_ETHER;
10624
35
      addr.len  = 6;
10625
35
      addr.data = bytes;
10626
10627
35
      addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
10628
35
      label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10629
35
      wmem_free(NULL, addr_str);
10630
35
      break;
10631
10632
623
    case FT_IPv4:
10633
623
      ipv4 = fvalue_get_ipv4(fi->value);
10634
623
      set_address_ipv4(&addr, ipv4);
10635
10636
623
      if (hfinfo->display == BASE_NETMASK) {
10637
0
        addr_str = (char*)address_to_str(NULL, &addr);
10638
623
      } else {
10639
623
        addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
10640
623
      }
10641
623
      label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10642
623
      wmem_free(NULL, addr_str);
10643
623
      free_address(&addr);
10644
623
      break;
10645
10646
61
    case FT_IPv6:
10647
61
      ipv6 = fvalue_get_ipv6(fi->value);
10648
61
      set_address_ipv6(&addr, ipv6);
10649
10650
61
      addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
10651
61
      label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10652
61
      wmem_free(NULL, addr_str);
10653
61
      free_address(&addr);
10654
61
      break;
10655
10656
0
    case FT_FCWWN:
10657
0
      bytes = fvalue_get_bytes_data(fi->value);
10658
0
      addr.type = AT_FCWWN;
10659
0
      addr.len  = FCWWN_ADDR_LEN;
10660
0
      addr.data = bytes;
10661
10662
0
      addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
10663
0
      label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10664
0
      wmem_free(NULL, addr_str);
10665
0
      break;
10666
10667
0
    case FT_GUID:
10668
0
      guid = fvalue_get_guid(fi->value);
10669
0
      tmp = guid_to_str(NULL, guid);
10670
0
      label_fill(label_str, 0, hfinfo, tmp, value_pos);
10671
0
      wmem_free(NULL, tmp);
10672
0
      break;
10673
10674
0
    case FT_OID:
10675
0
      bytes = fvalue_get_bytes_data(fi->value);
10676
0
      name = oid_resolved_from_encoded(NULL, bytes, (int)fvalue_length2(fi->value));
10677
0
      tmp = oid_encoded2string(NULL, bytes, (unsigned)fvalue_length2(fi->value));
10678
0
      if (name) {
10679
0
        label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10680
0
        wmem_free(NULL, name);
10681
0
      } else {
10682
0
        label_fill(label_str, 0, hfinfo, tmp, value_pos);
10683
0
      }
10684
0
      wmem_free(NULL, tmp);
10685
0
      break;
10686
10687
0
    case FT_REL_OID:
10688
0
      bytes = fvalue_get_bytes_data(fi->value);
10689
0
      name = rel_oid_resolved_from_encoded(NULL, bytes, (int)fvalue_length2(fi->value));
10690
0
      tmp = rel_oid_encoded2string(NULL, bytes, (unsigned)fvalue_length2(fi->value));
10691
0
      if (name) {
10692
0
        label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10693
0
        wmem_free(NULL, name);
10694
0
      } else {
10695
0
        label_fill(label_str, 0, hfinfo, tmp, value_pos);
10696
0
      }
10697
0
      wmem_free(NULL, tmp);
10698
0
      break;
10699
10700
0
    case FT_SYSTEM_ID:
10701
0
      bytes = fvalue_get_bytes_data(fi->value);
10702
0
      tmp = print_system_id(NULL, bytes, (int)fvalue_length2(fi->value));
10703
0
      label_fill(label_str, 0, hfinfo, tmp, value_pos);
10704
0
      wmem_free(NULL, tmp);
10705
0
      break;
10706
10707
383
    case FT_EUI64:
10708
383
      bytes = fvalue_get_bytes_data(fi->value);
10709
383
      addr.type = AT_EUI64;
10710
383
      addr.len  = EUI64_ADDR_LEN;
10711
383
      addr.data = bytes;
10712
10713
383
      addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
10714
383
      label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10715
383
      wmem_free(NULL, addr_str);
10716
383
      break;
10717
73.2k
    case FT_STRING:
10718
73.2k
    case FT_STRINGZ:
10719
73.2k
    case FT_UINT_STRING:
10720
73.2k
    case FT_STRINGZPAD:
10721
73.2k
    case FT_STRINGZTRUNC:
10722
73.2k
    case FT_AX25:
10723
73.2k
      str = fvalue_get_string(fi->value);
10724
73.2k
      label_fill(label_str, 0, hfinfo, str, value_pos);
10725
73.2k
      break;
10726
10727
0
    case FT_IEEE_11073_SFLOAT:
10728
0
    case FT_IEEE_11073_FLOAT:
10729
0
      fill_label_ieee_11073_float(fi, label_str, value_pos);
10730
0
      break;
10731
10732
0
    default:
10733
0
      REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_fill_label()",
10734
0
               hfinfo->abbrev,
10735
0
               hfinfo->type,
10736
0
               ftype_name(hfinfo->type));
10737
0
      break;
10738
3.46M
  }
10739
3.46M
}
10740
10741
static void
10742
fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10743
13.1k
{
10744
13.1k
  char  *p;
10745
13.1k
  unsigned bitfield_byte_length = 0;
10746
13.1k
  int  bitwidth;
10747
13.1k
  uint64_t unshifted_value;
10748
13.1k
  uint64_t value;
10749
10750
13.1k
  const header_field_info *hfinfo   = fi->hfinfo;
10751
10752
13.1k
  value = fvalue_get_uinteger64(fi->value);
10753
13.1k
  if (hfinfo->bitmask) {
10754
    /* Figure out the bit width */
10755
570
    bitwidth = hfinfo_container_bitwidth(hfinfo);
10756
10757
    /* Un-shift bits */
10758
570
    unshifted_value = value;
10759
570
    unshifted_value <<= hfinfo_bitshift(hfinfo);
10760
10761
    /* Create the bitfield first */
10762
570
    p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10763
570
    bitfield_byte_length = (unsigned) (p - label_str);
10764
570
  }
10765
10766
  /* Fill in the textual info */
10767
13.1k
  label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10768
13.1k
}
10769
10770
static const char *
10771
hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10772
1.59M
{
10773
1.59M
  if (hfinfo->display & BASE_RANGE_STRING)
10774
16.1k
    return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10775
10776
1.58M
  if (hfinfo->display & BASE_EXT_STRING) {
10777
12.2k
    if (hfinfo->display & BASE_VAL64_STRING)
10778
0
      return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10779
12.2k
    else
10780
12.2k
      return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10781
12.2k
  }
10782
10783
1.56M
  if (hfinfo->display & BASE_VAL64_STRING)
10784
0
    return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10785
10786
1.56M
  if (hfinfo->display & BASE_UNIT_STRING)
10787
2.44k
    return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10788
10789
1.56M
  return try_val_to_str(value, (const value_string *) hfinfo->strings);
10790
1.56M
}
10791
10792
static const char *
10793
hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10794
6
{
10795
6
  if (hfinfo->display & BASE_VAL64_STRING) {
10796
6
    if (hfinfo->display & BASE_EXT_STRING)
10797
1
      return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10798
5
    else
10799
5
      return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10800
6
  }
10801
10802
0
  if (hfinfo->display & BASE_RANGE_STRING)
10803
0
    return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10804
10805
0
  if (hfinfo->display & BASE_UNIT_STRING)
10806
0
    return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10807
10808
  /* If this is reached somebody registered a 64-bit field with a 32-bit
10809
   * value-string, which isn't right. */
10810
0
  REPORT_DISSECTOR_BUG("field %s is a 64-bit field with a 32-bit value_string",
10811
0
      hfinfo->abbrev);
10812
10813
  /* This is necessary to squelch MSVC errors; is there
10814
     any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10815
     never returns? */
10816
0
  return NULL;
10817
0
}
10818
10819
static const char *
10820
hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10821
0
{
10822
0
  if (hfinfo->display & BASE_UNIT_STRING)
10823
0
    return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10824
10825
0
  REPORT_DISSECTOR_BUG("field %s (FT_DOUBLE) has no base_unit_string", hfinfo->abbrev);
10826
10827
  /* This is necessary to squelch MSVC errors; is there
10828
     any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10829
     never returns? */
10830
0
  return NULL;
10831
0
}
10832
10833
static const char *
10834
hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10835
564k
{
10836
564k
  const char *str = hf_try_val_to_str(value, hfinfo);
10837
10838
564k
  return (str) ? str : unknown_str;
10839
564k
}
10840
10841
static const char *
10842
hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10843
5
{
10844
5
  const char *str = hf_try_val64_to_str(value, hfinfo);
10845
10846
5
  return (str) ? str : unknown_str;
10847
5
}
10848
10849
/* Fills data for bitfield chars with val_strings */
10850
static void
10851
fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10852
0
{
10853
0
  char       *p;
10854
0
  unsigned    bitfield_byte_length;
10855
0
  int     bitwidth;
10856
0
  uint32_t    unshifted_value;
10857
0
  uint32_t    value;
10858
10859
0
  char        buf[32];
10860
0
  const char *out;
10861
10862
0
  const header_field_info *hfinfo = fi->hfinfo;
10863
10864
  /* Figure out the bit width */
10865
0
  bitwidth = hfinfo_container_bitwidth(hfinfo);
10866
10867
  /* Un-shift bits */
10868
0
  value = fvalue_get_uinteger(fi->value);
10869
10870
0
  unshifted_value = value;
10871
0
  if (hfinfo->bitmask) {
10872
0
    unshifted_value <<= hfinfo_bitshift(hfinfo);
10873
0
  }
10874
10875
  /* Create the bitfield first */
10876
0
  p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10877
0
  bitfield_byte_length = (unsigned) (p - label_str);
10878
10879
  /* Fill in the textual info using stored (shifted) value */
10880
0
  if (hfinfo->display == BASE_CUSTOM) {
10881
0
    char tmp[ITEM_LABEL_LENGTH];
10882
0
    const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10883
10884
0
    DISSECTOR_ASSERT(fmtfunc);
10885
0
    fmtfunc(tmp, value);
10886
0
    label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10887
0
  }
10888
0
  else if (hfinfo->strings) {
10889
0
    const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10890
10891
0
    out = hfinfo_char_vals_format(hfinfo, buf, value);
10892
0
    if (out == NULL) /* BASE_NONE so don't put integer in descr */
10893
0
      label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10894
0
    else
10895
0
      label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10896
0
  }
10897
0
  else {
10898
0
    out = hfinfo_char_value_format(hfinfo, buf, value);
10899
10900
0
    label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10901
0
  }
10902
0
}
10903
10904
/* Fills data for bitfield ints with val_strings */
10905
static void
10906
fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool is_signed)
10907
208k
{
10908
208k
  char       *p;
10909
208k
  unsigned    bitfield_byte_length;
10910
208k
  int     bitwidth;
10911
208k
  uint32_t    value, unshifted_value;
10912
208k
  char        buf[NUMBER_LABEL_LENGTH];
10913
208k
  const char *out;
10914
10915
208k
  const header_field_info *hfinfo = fi->hfinfo;
10916
10917
  /* Figure out the bit width */
10918
208k
  if (fi->flags & FI_VARINT)
10919
0
    bitwidth = fi->length*8;
10920
208k
  else
10921
208k
    bitwidth = hfinfo_container_bitwidth(hfinfo);
10922
10923
  /* Un-shift bits */
10924
208k
  if (is_signed)
10925
458
    value = fvalue_get_sinteger(fi->value);
10926
207k
  else
10927
207k
    value = fvalue_get_uinteger(fi->value);
10928
10929
208k
  unshifted_value = value;
10930
208k
  if (hfinfo->bitmask) {
10931
208k
    unshifted_value <<= hfinfo_bitshift(hfinfo);
10932
208k
  }
10933
10934
  /* Create the bitfield first */
10935
208k
  if (fi->flags & FI_VARINT)
10936
0
    p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10937
208k
  else
10938
208k
    p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10939
208k
  bitfield_byte_length = (unsigned) (p - label_str);
10940
10941
  /* Fill in the textual info using stored (shifted) value */
10942
208k
  if (hfinfo->display == BASE_CUSTOM) {
10943
484
    char tmp[ITEM_LABEL_LENGTH];
10944
484
    const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10945
10946
484
    DISSECTOR_ASSERT(fmtfunc);
10947
484
    fmtfunc(tmp, value);
10948
484
    label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10949
484
  }
10950
207k
  else if (hfinfo->strings) {
10951
7.02k
    const char *val_str = hf_try_val_to_str(value, hfinfo);
10952
10953
7.02k
    out = hfinfo_number_vals_format(hfinfo, buf, value);
10954
7.02k
    if (hfinfo->display & BASE_SPECIAL_VALS) {
10955
      /*
10956
       * Unique values only display value_string string
10957
       * if there is a match. Otherwise it's just a number
10958
       */
10959
0
      if (val_str) {
10960
0
        label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10961
0
      } else {
10962
0
        label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10963
0
      }
10964
7.02k
    } else {
10965
7.02k
      if (val_str == NULL)
10966
102
        val_str = "Unknown";
10967
10968
7.02k
      if (out == NULL) /* BASE_NONE so don't put integer in descr */
10969
0
        label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10970
7.02k
      else
10971
7.02k
        label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10972
7.02k
    }
10973
7.02k
  }
10974
200k
  else {
10975
200k
    out = hfinfo_number_value_format(hfinfo, buf, value);
10976
10977
200k
    label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10978
200k
  }
10979
208k
}
10980
10981
static void
10982
fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool is_signed)
10983
438
{
10984
438
  char       *p;
10985
438
  unsigned    bitfield_byte_length;
10986
438
  int     bitwidth;
10987
438
  uint64_t    value, unshifted_value;
10988
438
  char        buf[NUMBER_LABEL_LENGTH];
10989
438
  const char *out;
10990
10991
438
  const header_field_info *hfinfo = fi->hfinfo;
10992
10993
  /* Figure out the bit width */
10994
438
  if (fi->flags & FI_VARINT)
10995
0
    bitwidth = fi->length*8;
10996
438
  else
10997
438
    bitwidth = hfinfo_container_bitwidth(hfinfo);
10998
10999
  /* Un-shift bits */
11000
438
  if (is_signed)
11001
0
    value = fvalue_get_sinteger64(fi->value);
11002
438
  else
11003
438
    value = fvalue_get_uinteger64(fi->value);
11004
11005
438
  unshifted_value = value;
11006
438
  if (hfinfo->bitmask) {
11007
438
    unshifted_value <<= hfinfo_bitshift(hfinfo);
11008
438
  }
11009
11010
  /* Create the bitfield first */
11011
438
  if (fi->flags & FI_VARINT)
11012
0
    p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
11013
438
  else
11014
438
    p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
11015
438
  bitfield_byte_length = (unsigned) (p - label_str);
11016
11017
  /* Fill in the textual info using stored (shifted) value */
11018
438
  if (hfinfo->display == BASE_CUSTOM) {
11019
0
    char tmp[ITEM_LABEL_LENGTH];
11020
0
    const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11021
11022
0
    DISSECTOR_ASSERT(fmtfunc64);
11023
0
    fmtfunc64(tmp, value);
11024
0
    label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
11025
0
  }
11026
438
  else if (hfinfo->strings) {
11027
0
    const char *val_str = hf_try_val64_to_str(value, hfinfo);
11028
11029
0
    out = hfinfo_number_vals_format64(hfinfo, buf, value);
11030
0
    if (hfinfo->display & BASE_SPECIAL_VALS) {
11031
      /*
11032
       * Unique values only display value_string string
11033
       * if there is a match. Otherwise it's just a number
11034
       */
11035
0
      if (val_str) {
11036
0
        label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
11037
0
      } else {
11038
0
        label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
11039
0
      }
11040
0
    } else {
11041
0
      if (val_str == NULL)
11042
0
        val_str = "Unknown";
11043
11044
0
      if (out == NULL) /* BASE_NONE so don't put integer in descr */
11045
0
        label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
11046
0
      else
11047
0
        label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
11048
0
    }
11049
0
  }
11050
438
  else {
11051
438
    out = hfinfo_number_value_format64(hfinfo, buf, value);
11052
11053
438
    label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
11054
438
  }
11055
438
}
11056
11057
static void
11058
fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
11059
0
{
11060
0
  const header_field_info *hfinfo = fi->hfinfo;
11061
0
  uint32_t           value;
11062
11063
0
  char               buf[32];
11064
0
  const char        *out;
11065
11066
0
  value = fvalue_get_uinteger(fi->value);
11067
11068
  /* Fill in the textual info */
11069
0
  if (hfinfo->display == BASE_CUSTOM) {
11070
0
    char tmp[ITEM_LABEL_LENGTH];
11071
0
    const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
11072
11073
0
    DISSECTOR_ASSERT(fmtfunc);
11074
0
    fmtfunc(tmp, value);
11075
0
    label_fill(label_str, 0, hfinfo, tmp, value_pos);
11076
0
  }
11077
0
  else if (hfinfo->strings) {
11078
0
    const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
11079
11080
0
    out = hfinfo_char_vals_format(hfinfo, buf, value);
11081
0
    label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11082
0
  }
11083
0
  else {
11084
0
    out = hfinfo_char_value_format(hfinfo, buf, value);
11085
11086
0
    label_fill(label_str, 0, hfinfo, out, value_pos);
11087
0
  }
11088
0
}
11089
11090
static void
11091
fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool is_signed)
11092
2.82M
{
11093
2.82M
  const header_field_info *hfinfo = fi->hfinfo;
11094
2.82M
  uint32_t           value;
11095
11096
2.82M
  char               buf[NUMBER_LABEL_LENGTH];
11097
2.82M
  const char        *out;
11098
11099
2.82M
  if (is_signed)
11100
2.47k
    value = fvalue_get_sinteger(fi->value);
11101
2.82M
  else
11102
2.82M
    value = fvalue_get_uinteger(fi->value);
11103
11104
  /* Fill in the textual info */
11105
2.82M
  if (hfinfo->display == BASE_CUSTOM) {
11106
1.32k
    char tmp[ITEM_LABEL_LENGTH];
11107
1.32k
    const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
11108
11109
1.32k
    DISSECTOR_ASSERT(fmtfunc);
11110
1.32k
    fmtfunc(tmp, value);
11111
1.32k
    label_fill(label_str, 0, hfinfo, tmp, value_pos);
11112
1.32k
  }
11113
2.82M
  else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
11114
    /*
11115
     * It makes no sense to have a value-string table for a
11116
     * frame-number field - they're just integers giving
11117
     * the ordinal frame number.
11118
     */
11119
1.02M
    const char *val_str = hf_try_val_to_str(value, hfinfo);
11120
11121
1.02M
    out = hfinfo_number_vals_format(hfinfo, buf, value);
11122
1.02M
    if (hfinfo->display & BASE_SPECIAL_VALS) {
11123
      /*
11124
       * Unique values only display value_string string
11125
       * if there is a match. Otherwise it's just a number
11126
       */
11127
1.38k
      if (val_str) {
11128
2
        label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11129
1.37k
      } else {
11130
1.37k
        label_fill(label_str, 0, hfinfo, out, value_pos);
11131
1.37k
      }
11132
1.02M
    } else {
11133
1.02M
      if (val_str == NULL)
11134
56.6k
        val_str = "Unknown";
11135
11136
1.02M
      if (out == NULL) /* BASE_NONE so don't put integer in descr */
11137
235
        label_fill(label_str, 0, hfinfo, val_str, value_pos);
11138
1.02M
      else
11139
1.02M
        label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11140
1.02M
    }
11141
1.02M
  }
11142
1.80M
  else if (IS_BASE_PORT(hfinfo->display)) {
11143
0
    char tmp[ITEM_LABEL_LENGTH];
11144
11145
0
    port_with_resolution_to_str_buf(tmp, sizeof(tmp),
11146
0
      display_to_port_type((field_display_e)hfinfo->display), value);
11147
0
    label_fill(label_str, 0, hfinfo, tmp, value_pos);
11148
0
  }
11149
1.80M
  else {
11150
1.80M
    out = hfinfo_number_value_format(hfinfo, buf, value);
11151
11152
1.80M
    label_fill(label_str, 0, hfinfo, out, value_pos);
11153
1.80M
  }
11154
2.82M
}
11155
11156
static void
11157
fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool is_signed)
11158
16.3k
{
11159
16.3k
  const header_field_info *hfinfo = fi->hfinfo;
11160
16.3k
  uint64_t           value;
11161
11162
16.3k
  char               buf[NUMBER_LABEL_LENGTH];
11163
16.3k
  const char        *out;
11164
11165
16.3k
  if (is_signed)
11166
49
    value = fvalue_get_sinteger64(fi->value);
11167
16.3k
  else
11168
16.3k
    value = fvalue_get_uinteger64(fi->value);
11169
11170
  /* Fill in the textual info */
11171
16.3k
  if (hfinfo->display == BASE_CUSTOM) {
11172
0
    char tmp[ITEM_LABEL_LENGTH];
11173
0
    const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11174
11175
0
    DISSECTOR_ASSERT(fmtfunc64);
11176
0
    fmtfunc64(tmp, value);
11177
0
    label_fill(label_str, 0, hfinfo, tmp, value_pos);
11178
0
  }
11179
16.3k
  else if (hfinfo->strings) {
11180
1
    const char *val_str = hf_try_val64_to_str(value, hfinfo);
11181
11182
1
    out = hfinfo_number_vals_format64(hfinfo, buf, value);
11183
1
    if (hfinfo->display & BASE_SPECIAL_VALS) {
11184
      /*
11185
       * Unique values only display value_string string
11186
       * if there is a match. Otherwise it's just a number
11187
       */
11188
0
      if (val_str) {
11189
0
        label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11190
0
      } else {
11191
0
        label_fill(label_str, 0, hfinfo, out, value_pos);
11192
0
      }
11193
1
    } else {
11194
1
      if (val_str == NULL)
11195
1
        val_str = "Unknown";
11196
11197
1
      if (out == NULL) /* BASE_NONE so don't put integer in descr */
11198
0
        label_fill(label_str, 0, hfinfo, val_str, value_pos);
11199
1
      else
11200
1
        label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11201
1
    }
11202
1
  }
11203
16.3k
  else {
11204
16.3k
    out = hfinfo_number_value_format64(hfinfo, buf, value);
11205
11206
16.3k
    label_fill(label_str, 0, hfinfo, out, value_pos);
11207
16.3k
  }
11208
16.3k
}
11209
11210
static size_t
11211
fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11212
9.46k
{
11213
9.46k
  int display;
11214
9.46k
  int n;
11215
9.46k
  double value;
11216
11217
9.46k
  if (label_str_size < 12) {
11218
    /* Not enough room to write an entire floating point value. */
11219
0
    return 0;
11220
0
  }
11221
11222
9.46k
  display = FIELD_DISPLAY(fi->hfinfo->display);
11223
9.46k
  value = fvalue_get_floating(fi->value);
11224
11225
9.46k
  if (display == BASE_CUSTOM) {
11226
0
    const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11227
0
    DISSECTOR_ASSERT(fmtfunc);
11228
0
    fmtfunc(label_str, value);
11229
0
    return strlen(label_str);
11230
0
  }
11231
11232
9.46k
  switch (display) {
11233
7.39k
    case BASE_NONE:
11234
7.39k
      if (fi->hfinfo->type == FT_FLOAT) {
11235
7.39k
        n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG, value);
11236
7.39k
      } else {
11237
0
        n = (int)strlen(dtoa_g_fmt(label_str, value));
11238
0
      }
11239
7.39k
      break;
11240
0
    case BASE_DEC:
11241
0
      n = snprintf(label_str, label_str_size, "%f", value);
11242
0
      break;
11243
0
    case BASE_HEX:
11244
0
      n = snprintf(label_str, label_str_size, "%a", value);
11245
0
      break;
11246
2.06k
    case BASE_EXP:
11247
2.06k
      n = snprintf(label_str, label_str_size, "%e", value);
11248
2.06k
      break;
11249
0
    default:
11250
0
      ws_assert_not_reached();
11251
9.46k
  }
11252
9.46k
  if (n < 0) {
11253
0
    return 0; /* error */
11254
0
  }
11255
9.46k
  if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING)) {
11256
0
    const char *hf_str_val;
11257
0
    hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11258
0
    n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11259
0
  }
11260
9.46k
  if (n > label_str_size) {
11261
0
    ws_warning("label length too small");
11262
0
    return strlen(label_str);
11263
0
  }
11264
11265
9.46k
  return n;
11266
9.46k
}
11267
11268
void
11269
fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11270
9.46k
{
11271
9.46k
  char tmp[ITEM_LABEL_LENGTH];
11272
11273
9.46k
  fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH);
11274
9.46k
  label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11275
9.46k
}
11276
11277
static size_t
11278
fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11279
0
{
11280
0
  int display;
11281
0
  size_t pos = 0;
11282
0
  double value;
11283
0
  char* tmp_str;
11284
11285
0
  if (label_str_size < 12) {
11286
    /* Not enough room to write an entire floating point value. */
11287
0
    return 0;
11288
0
  }
11289
11290
0
  display = FIELD_DISPLAY(fi->hfinfo->display);
11291
0
  tmp_str = fvalue_to_string_repr(NULL, fi->value, FTREPR_DISPLAY, display);
11292
0
  pos = label_concat(label_str, pos, (const uint8_t*)tmp_str);
11293
0
  wmem_free(NULL, tmp_str);
11294
11295
0
  if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING)) {
11296
0
    const char *hf_str_val;
11297
0
    fvalue_to_double(fi->value, &value);
11298
0
    hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11299
0
    pos = label_concat(label_str, pos, (const uint8_t*)hf_str_val);
11300
0
  }
11301
0
  if ((int)pos > label_str_size) {
11302
0
    ws_warning("label length too small");
11303
0
    return strlen(label_str);
11304
0
  }
11305
11306
0
  return pos;
11307
0
}
11308
11309
void
11310
fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11311
0
{
11312
0
  char tmp[ITEM_LABEL_LENGTH];
11313
11314
0
  fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH);
11315
0
  label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11316
0
}
11317
11318
int
11319
hfinfo_bitshift(const header_field_info *hfinfo)
11320
30.3M
{
11321
30.3M
  return ws_ctz(hfinfo->bitmask);
11322
30.3M
}
11323
11324
11325
static int
11326
hfinfo_bitoffset(const header_field_info *hfinfo)
11327
16.8M
{
11328
16.8M
  if (!hfinfo->bitmask) {
11329
0
    return 0;
11330
0
  }
11331
11332
  /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11333
   * as the first bit */
11334
16.8M
  return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11335
16.8M
}
11336
11337
static int
11338
hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11339
16.9M
{
11340
16.9M
  if (!hfinfo->bitmask) {
11341
0
    return 0;
11342
0
  }
11343
11344
  /* ilog2 = first set bit, ctz = last set bit */
11345
16.9M
  return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11346
16.9M
}
11347
11348
static int
11349
hfinfo_type_bitwidth(enum ftenum type)
11350
6.25M
{
11351
6.25M
  int bitwidth = 0;
11352
11353
6.25M
  switch (type) {
11354
0
    case FT_CHAR:
11355
3.64M
    case FT_UINT8:
11356
3.64M
    case FT_INT8:
11357
3.64M
      bitwidth = 8;
11358
3.64M
      break;
11359
1.33M
    case FT_UINT16:
11360
1.33M
    case FT_INT16:
11361
1.33M
      bitwidth = 16;
11362
1.33M
      break;
11363
62.4k
    case FT_UINT24:
11364
63.3k
    case FT_INT24:
11365
63.3k
      bitwidth = 24;
11366
63.3k
      break;
11367
970k
    case FT_UINT32:
11368
970k
    case FT_INT32:
11369
970k
      bitwidth = 32;
11370
970k
      break;
11371
223k
    case FT_UINT40:
11372
223k
    case FT_INT40:
11373
223k
      bitwidth = 40;
11374
223k
      break;
11375
6.36k
    case FT_UINT48:
11376
6.36k
    case FT_INT48:
11377
6.36k
      bitwidth = 48;
11378
6.36k
      break;
11379
1.58k
    case FT_UINT56:
11380
1.58k
    case FT_INT56:
11381
1.58k
      bitwidth = 56;
11382
1.58k
      break;
11383
8.48k
    case FT_UINT64:
11384
8.48k
    case FT_INT64:
11385
8.48k
      bitwidth = 64;
11386
8.48k
      break;
11387
0
    default:
11388
0
      DISSECTOR_ASSERT_NOT_REACHED();
11389
0
      ;
11390
6.25M
  }
11391
6.25M
  return bitwidth;
11392
6.25M
}
11393
11394
11395
static int
11396
hfinfo_container_bitwidth(const header_field_info *hfinfo)
11397
17.1M
{
11398
17.1M
  if (!hfinfo->bitmask) {
11399
0
    return 0;
11400
0
  }
11401
11402
17.1M
  if (hfinfo->type == FT_BOOLEAN) {
11403
11.6M
    return hfinfo->display; /* hacky? :) */
11404
11.6M
  }
11405
11406
5.56M
  return hfinfo_type_bitwidth(hfinfo->type);
11407
17.1M
}
11408
11409
static int
11410
hfinfo_hex_digits(const header_field_info *hfinfo)
11411
833k
{
11412
833k
  int bitwidth;
11413
11414
  /* If we have a bitmask, hfinfo->type is the width of the container, so not
11415
   * appropriate to determine the number of hex digits for the field.
11416
   * So instead, we compute it from the bitmask.
11417
   */
11418
833k
  if (hfinfo->bitmask != 0) {
11419
136k
    bitwidth = hfinfo_mask_bitwidth(hfinfo);
11420
696k
  } else {
11421
696k
    bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11422
696k
  }
11423
11424
  /* Divide by 4, rounding up, to get number of hex digits. */
11425
833k
  return (bitwidth + 3) / 4;
11426
833k
}
11427
11428
const char *
11429
hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11430
0
{
11431
0
  char *ptr = &buf[6];
11432
0
  static const char hex_digits[16] =
11433
0
  { '0', '1', '2', '3', '4', '5', '6', '7',
11434
0
    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11435
11436
0
  *ptr = '\0';
11437
0
  *(--ptr) = '\'';
11438
  /* Properly format value */
11439
0
  if (g_ascii_isprint(value)) {
11440
    /*
11441
     * Printable, so just show the character, and, if it needs
11442
     * to be escaped, escape it.
11443
     */
11444
0
    *(--ptr) = value;
11445
0
    if (value == '\\' || value == '\'')
11446
0
      *(--ptr) = '\\';
11447
0
  } else {
11448
    /*
11449
     * Non-printable; show it as an escape sequence.
11450
     */
11451
0
    switch (value) {
11452
11453
0
    case '\0':
11454
      /*
11455
       * Show a NUL with only one digit.
11456
       */
11457
0
      *(--ptr) = '0';
11458
0
      break;
11459
11460
0
    case '\a':
11461
0
    case '\b':
11462
0
    case '\f':
11463
0
    case '\n':
11464
0
    case '\r':
11465
0
    case '\t':
11466
0
    case '\v':
11467
0
      *(--ptr) = value - '\a' + 'a';
11468
0
      break;
11469
11470
0
    default:
11471
0
      switch (FIELD_DISPLAY(display)) {
11472
11473
0
      case BASE_OCT:
11474
0
        *(--ptr) = (value & 0x7) + '0';
11475
0
        value >>= 3;
11476
0
        *(--ptr) = (value & 0x7) + '0';
11477
0
        value >>= 3;
11478
0
        *(--ptr) = (value & 0x7) + '0';
11479
0
        break;
11480
11481
0
      case BASE_HEX:
11482
0
        *(--ptr) = hex_digits[value & 0x0F];
11483
0
        value >>= 4;
11484
0
        *(--ptr) = hex_digits[value & 0x0F];
11485
0
        *(--ptr) = 'x';
11486
0
        break;
11487
11488
0
      default:
11489
0
        REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display));
11490
0
      }
11491
0
    }
11492
0
    *(--ptr) = '\\';
11493
0
  }
11494
0
  *(--ptr) = '\'';
11495
0
  return ptr;
11496
0
}
11497
11498
static const char *
11499
hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH], uint32_t value)
11500
3.04M
{
11501
3.04M
  char *ptr = &buf[NUMBER_LABEL_LENGTH-1];
11502
3.04M
  bool isint = FT_IS_INT(hfinfo->type);
11503
11504
3.04M
  *ptr = '\0';
11505
  /* Properly format value */
11506
3.04M
  switch (FIELD_DISPLAY(display)) {
11507
2.22M
    case BASE_DEC:
11508
2.22M
      return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11509
11510
3.55k
    case BASE_DEC_HEX:
11511
3.55k
      *(--ptr) = ')';
11512
3.55k
      ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11513
3.55k
      *(--ptr) = '(';
11514
3.55k
      *(--ptr) = ' ';
11515
3.55k
      ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11516
3.55k
      return ptr;
11517
11518
7
    case BASE_OCT:
11519
7
      return oct_to_str_back(ptr, value);
11520
11521
712k
    case BASE_HEX:
11522
712k
      return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11523
11524
100k
    case BASE_HEX_DEC:
11525
100k
      *(--ptr) = ')';
11526
100k
      ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11527
100k
      *(--ptr) = '(';
11528
100k
      *(--ptr) = ' ';
11529
100k
      ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11530
100k
      return ptr;
11531
11532
0
    case BASE_PT_UDP:
11533
0
    case BASE_PT_TCP:
11534
0
    case BASE_PT_DCCP:
11535
0
    case BASE_PT_SCTP:
11536
0
      port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH,
11537
0
          display_to_port_type((field_display_e)display), value);
11538
0
      return buf;
11539
0
    case BASE_OUI:
11540
0
      {
11541
0
      uint8_t p_oui[3];
11542
0
      const char *manuf_name;
11543
11544
0
      p_oui[0] = value >> 16 & 0xFF;
11545
0
      p_oui[1] = value >> 8 & 0xFF;
11546
0
      p_oui[2] = value & 0xFF;
11547
11548
      /* Attempt an OUI lookup. */
11549
0
      manuf_name = uint_get_manuf_name_if_known(value);
11550
0
      if (manuf_name == NULL) {
11551
        /* Could not find an OUI. */
11552
0
        snprintf(buf, NUMBER_LABEL_LENGTH, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11553
0
      }
11554
0
      else {
11555
        /* Found an address string. */
11556
0
        snprintf(buf, NUMBER_LABEL_LENGTH, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11557
0
      }
11558
0
      return buf;
11559
0
      }
11560
11561
0
    default:
11562
0
      REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display));
11563
3.04M
  }
11564
0
  return ptr;
11565
3.04M
}
11566
11567
static const char *
11568
hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH], uint64_t value)
11569
16.8k
{
11570
16.8k
  char *ptr = &buf[NUMBER_LABEL_LENGTH-1];
11571
16.8k
  bool isint = FT_IS_INT(hfinfo->type);
11572
11573
16.8k
  *ptr = '\0';
11574
  /* Properly format value */
11575
16.8k
  switch (FIELD_DISPLAY(display)) {
11576
185
    case BASE_DEC:
11577
185
      return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11578
11579
0
    case BASE_DEC_HEX:
11580
0
      *(--ptr) = ')';
11581
0
      ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11582
0
      *(--ptr) = '(';
11583
0
      *(--ptr) = ' ';
11584
0
      ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11585
0
      return ptr;
11586
11587
0
    case BASE_OCT:
11588
0
      return oct64_to_str_back(ptr, value);
11589
11590
16.5k
    case BASE_HEX:
11591
16.5k
      return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11592
11593
111
    case BASE_HEX_DEC:
11594
111
      *(--ptr) = ')';
11595
111
      ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11596
111
      *(--ptr) = '(';
11597
111
      *(--ptr) = ' ';
11598
111
      ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11599
111
      return ptr;
11600
11601
0
    default:
11602
0
      REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display));
11603
16.8k
  }
11604
11605
0
  return ptr;
11606
16.8k
}
11607
11608
static const char *
11609
hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint32_t value)
11610
2.00M
{
11611
2.00M
  int display = hfinfo->display;
11612
11613
2.00M
  if (hfinfo->type == FT_FRAMENUM) {
11614
    /*
11615
     * Frame numbers are always displayed in decimal.
11616
     */
11617
0
    display = BASE_DEC;
11618
0
  }
11619
11620
2.00M
  return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11621
2.00M
}
11622
11623
static const char *
11624
hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint64_t value)
11625
16.8k
{
11626
16.8k
  int display = hfinfo->display;
11627
11628
16.8k
  if (hfinfo->type == FT_FRAMENUM) {
11629
    /*
11630
     * Frame numbers are always displayed in decimal.
11631
     */
11632
0
    display = BASE_DEC;
11633
0
  }
11634
11635
16.8k
  return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11636
16.8k
}
11637
11638
static const char *
11639
hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11640
0
{
11641
  /* Get the underlying BASE_ value */
11642
0
  int display = FIELD_DISPLAY(hfinfo->display);
11643
11644
0
  return hfinfo_char_value_format_display(display, buf, value);
11645
0
}
11646
11647
static const char *
11648
hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint32_t value)
11649
0
{
11650
  /* Get the underlying BASE_ value */
11651
0
  int display = FIELD_DISPLAY(hfinfo->display);
11652
11653
0
  if (hfinfo->type == FT_FRAMENUM) {
11654
    /*
11655
     * Frame numbers are always displayed in decimal.
11656
     */
11657
0
    display = BASE_DEC;
11658
0
  }
11659
11660
0
  if (IS_BASE_PORT(display)) {
11661
0
    display = BASE_DEC;
11662
0
  } else if (display == BASE_OUI) {
11663
0
    display = BASE_HEX;
11664
0
  }
11665
11666
0
  switch (display) {
11667
0
    case BASE_NONE:
11668
    /* case BASE_DEC: */
11669
0
    case BASE_DEC_HEX:
11670
0
    case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11671
0
    case BASE_CUSTOM:
11672
0
      display = BASE_DEC;
11673
0
      break;
11674
11675
    /* case BASE_HEX: */
11676
0
    case BASE_HEX_DEC:
11677
0
      display = BASE_HEX;
11678
0
      break;
11679
0
  }
11680
11681
0
  return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11682
0
}
11683
11684
static const char *
11685
hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint64_t value)
11686
0
{
11687
  /* Get the underlying BASE_ value */
11688
0
  int display = FIELD_DISPLAY(hfinfo->display);
11689
11690
0
  if (hfinfo->type == FT_FRAMENUM) {
11691
    /*
11692
     * Frame numbers are always displayed in decimal.
11693
     */
11694
0
    display = BASE_DEC;
11695
0
  }
11696
11697
0
  switch (display) {
11698
0
    case BASE_NONE:
11699
    /* case BASE_DEC: */
11700
0
    case BASE_DEC_HEX:
11701
0
    case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11702
0
    case BASE_CUSTOM:
11703
0
      display = BASE_DEC;
11704
0
      break;
11705
11706
    /* case BASE_HEX: */
11707
0
    case BASE_HEX_DEC:
11708
0
      display = BASE_HEX;
11709
0
      break;
11710
0
  }
11711
11712
0
  return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11713
0
}
11714
11715
static const char *
11716
hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11717
0
{
11718
  /* Get the underlying BASE_ value */
11719
0
  int display = FIELD_DISPLAY(hfinfo->display);
11720
11721
0
  return hfinfo_char_value_format_display(display, buf, value);
11722
0
}
11723
11724
static const char *
11725
hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint32_t value)
11726
1.03M
{
11727
  /* Get the underlying BASE_ value */
11728
1.03M
  int display = FIELD_DISPLAY(hfinfo->display);
11729
11730
1.03M
  if (display == BASE_NONE)
11731
235
    return NULL;
11732
11733
1.03M
  if (display == BASE_DEC_HEX)
11734
0
    display = BASE_DEC;
11735
1.03M
  if (display == BASE_HEX_DEC)
11736
12.5k
    display = BASE_HEX;
11737
11738
1.03M
  return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11739
1.03M
}
11740
11741
static const char *
11742
hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint64_t value)
11743
1
{
11744
  /* Get the underlying BASE_ value */
11745
1
  int display = FIELD_DISPLAY(hfinfo->display);
11746
11747
1
  if (display == BASE_NONE)
11748
0
    return NULL;
11749
11750
1
  if (display == BASE_DEC_HEX)
11751
0
    display = BASE_DEC;
11752
1
  if (display == BASE_HEX_DEC)
11753
0
    display = BASE_HEX;
11754
11755
1
  return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11756
1
}
11757
11758
const char *
11759
proto_registrar_get_name(const int n)
11760
42.3k
{
11761
42.3k
  header_field_info *hfinfo;
11762
11763
42.3k
  PROTO_REGISTRAR_GET_NTH(n, hfinfo);
11764
42.3k
  return hfinfo->name;
11765
42.3k
}
11766
11767
const char *
11768
proto_registrar_get_abbrev(const int n)
11769
0
{
11770
0
  header_field_info *hfinfo;
11771
11772
0
  PROTO_REGISTRAR_GET_NTH(n, hfinfo);
11773
0
  return hfinfo->abbrev;
11774
0
}
11775
11776
enum ftenum
11777
proto_registrar_get_ftype(const int n)
11778
8.49k
{
11779
8.49k
  header_field_info *hfinfo;
11780
11781
8.49k
  PROTO_REGISTRAR_GET_NTH(n, hfinfo);
11782
8.49k
  return hfinfo->type;
11783
8.49k
}
11784
11785
int
11786
proto_registrar_get_parent(const int n)
11787
0
{
11788
0
  header_field_info *hfinfo;
11789
11790
0
  PROTO_REGISTRAR_GET_NTH(n, hfinfo);
11791
0
  return hfinfo->parent;
11792
0
}
11793
11794
bool
11795
proto_registrar_is_protocol(const int n)
11796
0
{
11797
0
  header_field_info *hfinfo;
11798
11799
0
  PROTO_REGISTRAR_GET_NTH(n, hfinfo);
11800
0
  return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true : false);
11801
0
}
11802
11803
/* Returns length of field in packet (not necessarily the length
11804
 * in our internal representation, as in the case of IPv4).
11805
 * 0 means undeterminable at time of registration
11806
 * -1 means the field is not registered. */
11807
int
11808
proto_registrar_get_length(const int n)
11809
351
{
11810
351
  header_field_info *hfinfo;
11811
11812
351
  PROTO_REGISTRAR_GET_NTH(n, hfinfo);
11813
351
  return ftype_wire_size(hfinfo->type);
11814
351
}
11815
11816
size_t
11817
proto_registrar_get_count(struct proto_registrar_stats *stats)
11818
0
{
11819
0
  header_field_info *hfinfo;
11820
11821
  // Index zero is not used. We have to skip it.
11822
0
  size_t total_count = gpa_hfinfo.len - 1;
11823
0
  if (stats == NULL) {
11824
0
    return total_count;
11825
0
  }
11826
0
  for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11827
0
    if (gpa_hfinfo.hfi[id] == NULL) {
11828
0
      stats->deregistered_count++;
11829
0
      continue; /* This is a deregistered protocol or header field */
11830
0
    }
11831
11832
0
    PROTO_REGISTRAR_GET_NTH(id, hfinfo);
11833
11834
0
    if (proto_registrar_is_protocol(id))
11835
0
      stats->protocol_count++;
11836
11837
0
    if (hfinfo->same_name_prev_id != -1)
11838
0
      stats->same_name_count++;
11839
0
  }
11840
11841
0
  return total_count;
11842
0
}
11843
11844
/* Looks for a protocol or a field in a proto_tree. Returns true if
11845
 * it exists anywhere, or false if it exists nowhere. */
11846
bool
11847
proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11848
0
{
11849
0
  GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11850
11851
0
  if (g_ptr_array_len(ptrs) > 0) {
11852
0
    return true;
11853
0
  }
11854
0
  else {
11855
0
    return false;
11856
0
  }
11857
0
}
11858
11859
/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11860
 * This only works if the hfindex was "primed" before the dissection
11861
 * took place, as we just pass back the already-created GPtrArray*.
11862
 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11863
 * handles that. */
11864
GPtrArray *
11865
proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11866
821
{
11867
821
  if (!tree)
11868
0
    return NULL;
11869
11870
821
  if (PTREE_DATA(tree)->interesting_hfids != NULL)
11871
773
    return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
11872
773
             GINT_TO_POINTER(id));
11873
48
  else
11874
48
    return NULL;
11875
821
}
11876
11877
bool
11878
proto_tracking_interesting_fields(const proto_tree *tree)
11879
0
{
11880
0
  GHashTable *interesting_hfids;
11881
11882
0
  if (!tree)
11883
0
    return false;
11884
11885
0
  interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
11886
11887
0
  return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
11888
0
}
11889
11890
/* Helper struct for proto_find_info() and  proto_all_finfos() */
11891
typedef struct {
11892
  GPtrArray *array;
11893
  int    id;
11894
} ffdata_t;
11895
11896
/* Helper function for proto_find_info() */
11897
static bool
11898
find_finfo(proto_node *node, void * data)
11899
0
{
11900
0
  field_info *fi = PNODE_FINFO(node);
11901
0
  if (fi && fi->hfinfo) {
11902
0
    if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11903
0
      g_ptr_array_add(((ffdata_t*)data)->array, fi);
11904
0
    }
11905
0
  }
11906
11907
  /* Don't stop traversing. */
11908
0
  return false;
11909
0
}
11910
11911
/* Helper function for proto_find_first_info() */
11912
static bool
11913
find_first_finfo(proto_node *node, void *data)
11914
0
{
11915
0
  field_info *fi = PNODE_FINFO(node);
11916
0
  if (fi && fi->hfinfo) {
11917
0
    if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11918
0
      g_ptr_array_add(((ffdata_t*)data)->array, fi);
11919
11920
      /* Stop traversing. */
11921
0
      return true;
11922
0
    }
11923
0
  }
11924
11925
  /* Continue traversing. */
11926
0
  return false;
11927
0
}
11928
11929
/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11930
* This works on any proto_tree, primed or unprimed, but actually searches
11931
* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11932
* The caller does need to free the returned GPtrArray with
11933
* g_ptr_array_free(<array>, true).
11934
*/
11935
GPtrArray *
11936
proto_find_finfo(proto_tree *tree, const int id)
11937
0
{
11938
0
  ffdata_t ffdata;
11939
11940
0
  ffdata.array = g_ptr_array_new();
11941
0
  ffdata.id = id;
11942
11943
0
  proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11944
11945
0
  return ffdata.array;
11946
0
}
11947
11948
/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11949
* This works on any proto_tree, primed or unprimed, but actually searches
11950
* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11951
* The caller does need to free the returned GPtrArray with
11952
* g_ptr_array_free(<array>, true).
11953
*/
11954
GPtrArray *
11955
proto_find_first_finfo(proto_tree *tree, const int id)
11956
0
{
11957
0
  ffdata_t ffdata;
11958
11959
0
  ffdata.array = g_ptr_array_new();
11960
0
  ffdata.id = id;
11961
11962
0
  proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11963
11964
0
  return ffdata.array;
11965
0
}
11966
11967
/* Helper function for proto_all_finfos() */
11968
static bool
11969
every_finfo(proto_node *node, void * data)
11970
0
{
11971
0
  field_info *fi = PNODE_FINFO(node);
11972
0
  if (fi && fi->hfinfo) {
11973
0
    g_ptr_array_add(((ffdata_t*)data)->array, fi);
11974
0
  }
11975
11976
  /* Don't stop traversing. */
11977
0
  return false;
11978
0
}
11979
11980
/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11981
 * The caller does need to free the returned GPtrArray with
11982
 * g_ptr_array_free(<array>, true).
11983
 */
11984
GPtrArray *
11985
proto_all_finfos(proto_tree *tree)
11986
0
{
11987
0
  ffdata_t ffdata;
11988
11989
  /* Pre allocate enough space to hold all fields in most cases */
11990
0
  ffdata.array = g_ptr_array_sized_new(512);
11991
0
  ffdata.id = 0;
11992
11993
0
  proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11994
11995
0
  return ffdata.array;
11996
0
}
11997
11998
11999
typedef struct {
12000
  unsigned      offset;
12001
  field_info *finfo;
12002
  tvbuff_t   *tvb;
12003
} offset_search_t;
12004
12005
static bool
12006
check_for_offset(proto_node *node, void * data)
12007
0
{
12008
0
  field_info  *fi        = PNODE_FINFO(node);
12009
0
  offset_search_t *offsearch = (offset_search_t *)data;
12010
12011
  /* !fi == the top most container node which holds nothing */
12012
0
  if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
12013
0
    if (offsearch->offset >= (unsigned) fi->start &&
12014
0
        offsearch->offset < (unsigned) (fi->start + fi->length)) {
12015
12016
0
      offsearch->finfo = fi;
12017
0
      return false; /* keep traversing */
12018
0
    }
12019
0
  }
12020
0
  return false; /* keep traversing */
12021
0
}
12022
12023
/* Search a proto_tree backwards (from leaves to root) looking for the field
12024
 * whose start/length occupies 'offset' */
12025
/* XXX - I couldn't find an easy way to search backwards, so I search
12026
 * forwards, w/o stopping. Therefore, the last finfo I find will the be
12027
 * the one I want to return to the user. This algorithm is inefficient
12028
 * and could be re-done, but I'd have to handle all the children and
12029
 * siblings of each node myself. When I have more time I'll do that.
12030
 * (yeah right) */
12031
field_info *
12032
proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
12033
0
{
12034
0
  offset_search_t offsearch;
12035
12036
0
  offsearch.offset = offset;
12037
0
  offsearch.finfo  = NULL;
12038
0
  offsearch.tvb    = tvb;
12039
12040
0
  proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
12041
12042
0
  return offsearch.finfo;
12043
0
}
12044
12045
typedef struct {
12046
  unsigned length;
12047
  char *buf;
12048
} decoded_data_t;
12049
12050
static bool
12051
check_for_undecoded(proto_node *node, void * data)
12052
0
{
12053
0
  field_info *fi = PNODE_FINFO(node);
12054
0
  decoded_data_t* decoded = (decoded_data_t*)data;
12055
0
  unsigned i;
12056
0
  unsigned byte;
12057
0
  unsigned bit;
12058
12059
0
  if (fi && fi->hfinfo->type != FT_PROTOCOL) {
12060
0
    for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
12061
0
      byte = i / 8;
12062
0
      bit = i % 8;
12063
0
      decoded->buf[byte] |= (1 << bit);
12064
0
    }
12065
0
  }
12066
12067
0
  return false;
12068
0
}
12069
12070
char*
12071
proto_find_undecoded_data(proto_tree *tree, unsigned length)
12072
0
{
12073
0
  decoded_data_t decoded;
12074
0
  decoded.length = length;
12075
0
  decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree), length / 8 + 1);
12076
12077
0
  proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
12078
0
  return decoded.buf;
12079
0
}
12080
12081
/* Dumps the protocols in the registration database to stdout.  An independent
12082
 * program can take this output and format it into nice tables or HTML or
12083
 * whatever.
12084
 *
12085
 * There is one record per line. The fields are tab-delimited.
12086
 *
12087
 * Field 1 = protocol name
12088
 * Field 2 = protocol short name
12089
 * Field 3 = protocol filter name
12090
 * Field 4 = protocol enabled
12091
 * Field 5 = protocol enabled by default
12092
 * Field 6 = protocol can toggle
12093
 */
12094
void
12095
proto_registrar_dump_protocols(void)
12096
0
{
12097
0
  protocol_t *protocol;
12098
0
  int     i;
12099
0
  void     *cookie = NULL;
12100
12101
12102
0
  i = proto_get_first_protocol(&cookie);
12103
0
  while (i != -1) {
12104
0
    protocol = find_protocol_by_id(i);
12105
0
    printf("%s\t%s\t%s\t%c\t%c\t%c\n",
12106
0
        protocol->name,
12107
0
        protocol->short_name,
12108
0
        protocol->filter_name,
12109
0
        (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
12110
0
        (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
12111
0
        (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
12112
0
    i = proto_get_next_protocol(&cookie);
12113
0
  }
12114
0
}
12115
12116
/* Dumps the value_strings, extended value string headers, range_strings
12117
 * or true/false strings for fields that have them.
12118
 * There is one record per line. Fields are tab-delimited.
12119
 * There are four types of records: Value String, Extended Value String Header,
12120
 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
12121
 * the type of record.
12122
 *
12123
 * Note that a record will be generated only if the value_string,... is referenced
12124
 * in a registered hfinfo entry.
12125
 *
12126
 *
12127
 * Value Strings
12128
 * -------------
12129
 * Field 1 = 'V'
12130
 * Field 2 = Field abbreviation to which this value string corresponds
12131
 * Field 3 = Integer value
12132
 * Field 4 = String
12133
 *
12134
 * Extended Value String Headers
12135
 * -----------------------------
12136
 * Field 1 = 'E'
12137
 * Field 2 = Field abbreviation to which this extended value string header corresponds
12138
 * Field 3 = Extended Value String "Name"
12139
 * Field 4 = Number of entries in the associated value_string array
12140
 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
12141
 *
12142
 * Range Strings
12143
 * -------------
12144
 * Field 1 = 'R'
12145
 * Field 2 = Field abbreviation to which this range string corresponds
12146
 * Field 3 = Integer value: lower bound
12147
 * Field 4 = Integer value: upper bound
12148
 * Field 5 = String
12149
 *
12150
 * True/False Strings
12151
 * ------------------
12152
 * Field 1 = 'T'
12153
 * Field 2 = Field abbreviation to which this true/false string corresponds
12154
 * Field 3 = True String
12155
 * Field 4 = False String
12156
 */
12157
void
12158
proto_registrar_dump_values(void)
12159
0
{
12160
0
  header_field_info *hfinfo;
12161
0
  int     i, len, vi;
12162
0
  const value_string  *vals;
12163
0
  const val64_string  *vals64;
12164
0
  const range_string  *range;
12165
0
  const true_false_string *tfs;
12166
0
  const unit_name_string  *units;
12167
12168
0
  len = gpa_hfinfo.len;
12169
0
  for (i = 1; i < len ; i++) {
12170
0
    if (gpa_hfinfo.hfi[i] == NULL)
12171
0
      continue; /* This is a deregistered protocol or field */
12172
12173
0
    PROTO_REGISTRAR_GET_NTH(i, hfinfo);
12174
12175
0
    if (hfinfo->id == hf_text_only) {
12176
0
      continue;
12177
0
    }
12178
12179
    /* ignore protocols */
12180
0
    if (proto_registrar_is_protocol(i)) {
12181
0
      continue;
12182
0
    }
12183
    /* process header fields */
12184
#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12185
    /*
12186
     * If this field isn't at the head of the list of
12187
     * fields with this name, skip this field - all
12188
     * fields with the same name are really just versions
12189
     * of the same field stored in different bits, and
12190
     * should have the same type/radix/value list, and
12191
     * just differ in their bit masks.  (If a field isn't
12192
     * a bitfield, but can be, say, 1 or 2 bytes long,
12193
     * it can just be made FT_UINT16, meaning the
12194
     * *maximum* length is 2 bytes, and be used
12195
     * for all lengths.)
12196
     */
12197
    if (hfinfo->same_name_prev_id != -1)
12198
      continue;
12199
#endif
12200
0
    vals   = NULL;
12201
0
    vals64 = NULL;
12202
0
    range  = NULL;
12203
0
    tfs    = NULL;
12204
0
    units  = NULL;
12205
12206
0
    if (hfinfo->strings != NULL) {
12207
0
      if (FIELD_DISPLAY(hfinfo->display) != BASE_CUSTOM &&
12208
0
          (hfinfo->type == FT_CHAR  ||
12209
0
           hfinfo->type == FT_UINT8  ||
12210
0
           hfinfo->type == FT_UINT16 ||
12211
0
           hfinfo->type == FT_UINT24 ||
12212
0
           hfinfo->type == FT_UINT32 ||
12213
0
           hfinfo->type == FT_UINT40 ||
12214
0
           hfinfo->type == FT_UINT48 ||
12215
0
           hfinfo->type == FT_UINT56 ||
12216
0
           hfinfo->type == FT_UINT64 ||
12217
0
           hfinfo->type == FT_INT8   ||
12218
0
           hfinfo->type == FT_INT16  ||
12219
0
           hfinfo->type == FT_INT24  ||
12220
0
           hfinfo->type == FT_INT32  ||
12221
0
           hfinfo->type == FT_INT40  ||
12222
0
           hfinfo->type == FT_INT48  ||
12223
0
           hfinfo->type == FT_INT56  ||
12224
0
           hfinfo->type == FT_INT64  ||
12225
0
           hfinfo->type == FT_FLOAT  ||
12226
0
           hfinfo->type == FT_DOUBLE)) {
12227
12228
0
        if (hfinfo->display & BASE_RANGE_STRING) {
12229
0
          range = (const range_string *)hfinfo->strings;
12230
0
        } else if (hfinfo->display & BASE_EXT_STRING) {
12231
0
          if (hfinfo->display & BASE_VAL64_STRING) {
12232
0
            vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings);
12233
0
          } else {
12234
0
            vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings);
12235
0
          }
12236
0
        } else if (hfinfo->display & BASE_VAL64_STRING) {
12237
0
          vals64 = (const val64_string *)hfinfo->strings;
12238
0
        } else if (hfinfo->display & BASE_UNIT_STRING) {
12239
0
          units = (const unit_name_string *)hfinfo->strings;
12240
0
        } else {
12241
0
          vals = (const value_string *)hfinfo->strings;
12242
0
        }
12243
0
      }
12244
0
      else if (hfinfo->type == FT_BOOLEAN) {
12245
0
        tfs = (const struct true_false_string *)hfinfo->strings;
12246
0
      }
12247
0
    }
12248
12249
    /* Print value strings? */
12250
0
    if (vals) {
12251
0
      if (hfinfo->display & BASE_EXT_STRING) {
12252
0
        if (hfinfo->display & BASE_VAL64_STRING) {
12253
0
          val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12254
0
          if (!val64_string_ext_validate(vse_p)) {
12255
0
            ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev);
12256
0
            continue;
12257
0
          }
12258
0
          try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12259
0
          printf("E\t%s\t%u\t%s\t%s\n",
12260
0
                 hfinfo->abbrev,
12261
0
                 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p),
12262
0
                 VAL64_STRING_EXT_VS_NAME(vse_p),
12263
0
                 val64_string_ext_match_type_str(vse_p));
12264
0
        } else {
12265
0
          value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12266
0
          if (!value_string_ext_validate(vse_p)) {
12267
0
            ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
12268
0
            continue;
12269
0
          }
12270
0
          try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12271
0
          printf("E\t%s\t%u\t%s\t%s\n",
12272
0
                 hfinfo->abbrev,
12273
0
                 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
12274
0
                 VALUE_STRING_EXT_VS_NAME(vse_p),
12275
0
                 value_string_ext_match_type_str(vse_p));
12276
0
        }
12277
0
      }
12278
0
      vi = 0;
12279
0
      while (vals[vi].strptr) {
12280
        /* Print in the proper base */
12281
0
        if (hfinfo->type == FT_CHAR) {
12282
0
          if (g_ascii_isprint(vals[vi].value)) {
12283
0
            printf("V\t%s\t'%c'\t%s\n",
12284
0
                   hfinfo->abbrev,
12285
0
                   vals[vi].value,
12286
0
                   vals[vi].strptr);
12287
0
          } else {
12288
0
            if (hfinfo->display == BASE_HEX) {
12289
0
              printf("V\t%s\t'\\x%02x'\t%s\n",
12290
0
                     hfinfo->abbrev,
12291
0
                     vals[vi].value,
12292
0
                     vals[vi].strptr);
12293
0
            }
12294
0
            else {
12295
0
              printf("V\t%s\t'\\%03o'\t%s\n",
12296
0
                     hfinfo->abbrev,
12297
0
                     vals[vi].value,
12298
0
                     vals[vi].strptr);
12299
0
            }
12300
0
          }
12301
0
        } else {
12302
0
          if (hfinfo->display == BASE_HEX) {
12303
0
            printf("V\t%s\t0x%x\t%s\n",
12304
0
                   hfinfo->abbrev,
12305
0
                   vals[vi].value,
12306
0
                   vals[vi].strptr);
12307
0
          }
12308
0
          else {
12309
0
            printf("V\t%s\t%u\t%s\n",
12310
0
                   hfinfo->abbrev,
12311
0
                   vals[vi].value,
12312
0
                   vals[vi].strptr);
12313
0
          }
12314
0
        }
12315
0
        vi++;
12316
0
      }
12317
0
    }
12318
0
    else if (vals64) {
12319
0
      vi = 0;
12320
0
      while (vals64[vi].strptr) {
12321
0
        printf("V64\t%s\t%" PRIu64 "\t%s\n",
12322
0
               hfinfo->abbrev,
12323
0
               vals64[vi].value,
12324
0
               vals64[vi].strptr);
12325
0
        vi++;
12326
0
      }
12327
0
    }
12328
12329
    /* print range strings? */
12330
0
    else if (range) {
12331
0
      vi = 0;
12332
0
      while (range[vi].strptr) {
12333
        /* Print in the proper base */
12334
0
        if (FIELD_DISPLAY(hfinfo->display) == BASE_HEX) {
12335
0
          printf("R\t%s\t0x%"PRIx64"\t0x%"PRIx64"\t%s\n",
12336
0
                 hfinfo->abbrev,
12337
0
                 range[vi].value_min,
12338
0
                 range[vi].value_max,
12339
0
                 range[vi].strptr);
12340
0
        }
12341
0
        else {
12342
0
          printf("R\t%s\t%"PRIu64"\t%"PRIu64"\t%s\n",
12343
0
                 hfinfo->abbrev,
12344
0
                 range[vi].value_min,
12345
0
                 range[vi].value_max,
12346
0
                 range[vi].strptr);
12347
0
        }
12348
0
        vi++;
12349
0
      }
12350
0
    }
12351
12352
    /* Print true/false strings? */
12353
0
    else if (tfs) {
12354
0
      printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12355
0
             tfs->true_string, tfs->false_string);
12356
0
    }
12357
    /* Print unit strings? */
12358
0
    else if (units) {
12359
0
      printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12360
0
             units->singular, units->plural ? units->plural : "(no plural)");
12361
0
    }
12362
0
  }
12363
0
}
12364
12365
/* Prints the number of registered fields.
12366
 * Useful for determining an appropriate value for
12367
 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12368
 *
12369
 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12370
 * the number of fields, true otherwise.
12371
 */
12372
bool
12373
proto_registrar_dump_fieldcount(void)
12374
0
{
12375
0
  struct proto_registrar_stats stats = {0, 0, 0};
12376
0
  size_t total_count = proto_registrar_get_count(&stats);
12377
12378
0
  printf("There are %zu header fields registered, of which:\n"
12379
0
    "\t%zu are deregistered\n"
12380
0
    "\t%zu are protocols\n"
12381
0
    "\t%zu have the same name as another field\n\n",
12382
0
    total_count, stats.deregistered_count, stats.protocol_count,
12383
0
    stats.same_name_count);
12384
12385
0
  printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
12386
0
    (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
12387
0
        "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12388
0
        "\n");
12389
12390
0
  printf("The header field table consumes %u KiB of memory.\n",
12391
0
    (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12392
0
  printf("The fields themselves consume %u KiB of memory.\n",
12393
0
    (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12394
12395
0
  return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
12396
0
}
12397
12398
static void
12399
elastic_add_base_mapping(json_dumper *dumper)
12400
0
{
12401
0
  json_dumper_set_member_name(dumper, "index_patterns");
12402
0
  json_dumper_begin_array(dumper);
12403
  // The index names from write_json_index() in print.c
12404
0
  json_dumper_value_string(dumper, "packets-*");
12405
0
  json_dumper_end_array(dumper);
12406
12407
0
  json_dumper_set_member_name(dumper, "settings");
12408
0
  json_dumper_begin_object(dumper);
12409
0
  json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12410
0
  json_dumper_value_anyf(dumper, "%d", 1000000);
12411
0
  json_dumper_end_object(dumper);
12412
0
}
12413
12414
static char*
12415
ws_type_to_elastic(unsigned type)
12416
0
{
12417
0
  switch(type) {
12418
0
    case FT_INT8:
12419
0
      return "byte";
12420
0
    case FT_UINT8:
12421
0
    case FT_INT16:
12422
0
      return "short";
12423
0
    case FT_UINT16:
12424
0
    case FT_INT32:
12425
0
    case FT_UINT24:
12426
0
    case FT_INT24:
12427
0
      return "integer";
12428
0
    case FT_FRAMENUM:
12429
0
    case FT_UINT32:
12430
0
    case FT_UINT40:
12431
0
    case FT_UINT48:
12432
0
    case FT_UINT56:
12433
0
    case FT_INT40:
12434
0
    case FT_INT48:
12435
0
    case FT_INT56:
12436
0
    case FT_INT64:
12437
0
      return "long";
12438
0
    case FT_UINT64:
12439
0
      return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12440
0
    case FT_FLOAT:
12441
0
      return "float";
12442
0
    case FT_DOUBLE:
12443
0
    case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12444
0
      return "double";
12445
0
    case FT_IPv6:
12446
0
    case FT_IPv4:
12447
0
      return "ip";
12448
0
    case FT_ABSOLUTE_TIME:
12449
0
      return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12450
0
    case FT_BOOLEAN:
12451
0
      return "boolean";
12452
0
    default:
12453
0
      return NULL;
12454
0
  }
12455
0
}
12456
12457
static char*
12458
dot_to_underscore(char* str)
12459
0
{
12460
0
  unsigned i;
12461
0
  for (i = 0; i < strlen(str); i++) {
12462
0
    if (str[i] == '.')
12463
0
      str[i] = '_';
12464
0
  }
12465
0
  return str;
12466
0
}
12467
12468
/* Dumps a mapping file for ElasticSearch
12469
 * This is the v1 (legacy) _template API.
12470
 * At some point it may need to be updated with the composable templates
12471
 * introduced in Elasticsearch 7.8 (_index_template)
12472
 */
12473
void
12474
proto_registrar_dump_elastic(const char* filter)
12475
0
{
12476
0
  header_field_info *hfinfo;
12477
0
  header_field_info *parent_hfinfo;
12478
0
  unsigned i;
12479
0
  bool open_object = true;
12480
0
  const char* prev_proto = NULL;
12481
0
  char* str;
12482
0
  char** protos = NULL;
12483
0
  char* proto;
12484
0
  bool found;
12485
0
  unsigned j;
12486
0
  char* type;
12487
0
  char* prev_item = NULL;
12488
12489
  /* We have filtering protocols. Extract them. */
12490
0
  if (filter) {
12491
0
    protos = g_strsplit(filter, ",", -1);
12492
0
  }
12493
12494
  /*
12495
   * To help tracking down the json tree, objects have been appended with a comment:
12496
   * n.label -> where n is the indentation level and label the name of the object
12497
   */
12498
12499
0
  json_dumper dumper = {
12500
0
    .output_file = stdout,
12501
0
    .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT,
12502
0
  };
12503
0
  json_dumper_begin_object(&dumper); // 1.root
12504
0
  elastic_add_base_mapping(&dumper);
12505
12506
0
  json_dumper_set_member_name(&dumper, "mappings");
12507
0
  json_dumper_begin_object(&dumper); // 2.mappings
12508
12509
0
  json_dumper_set_member_name(&dumper, "properties");
12510
0
  json_dumper_begin_object(&dumper); // 3.properties
12511
0
  json_dumper_set_member_name(&dumper, "timestamp");
12512
0
  json_dumper_begin_object(&dumper); // 4.timestamp
12513
0
  json_dumper_set_member_name(&dumper, "type");
12514
0
  json_dumper_value_string(&dumper, "date");
12515
0
  json_dumper_end_object(&dumper); // 4.timestamp
12516
12517
0
  json_dumper_set_member_name(&dumper, "layers");
12518
0
  json_dumper_begin_object(&dumper); // 4.layers
12519
0
  json_dumper_set_member_name(&dumper, "properties");
12520
0
  json_dumper_begin_object(&dumper); // 5.properties
12521
12522
0
  for (i = 1; i < gpa_hfinfo.len; i++) {
12523
0
    if (gpa_hfinfo.hfi[i] == NULL)
12524
0
      continue; /* This is a deregistered protocol or header field */
12525
12526
0
    PROTO_REGISTRAR_GET_NTH(i, hfinfo);
12527
12528
    /*
12529
     * Skip the pseudo-field for "proto_tree_add_text()" since
12530
     * we don't want it in the list of filterable protocols.
12531
     */
12532
0
    if (hfinfo->id == hf_text_only)
12533
0
      continue;
12534
12535
0
    if (!proto_registrar_is_protocol(i)) {
12536
0
      PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
12537
12538
      /*
12539
       * Skip the field if filter protocols have been set and this one's
12540
       * parent is not listed.
12541
       */
12542
0
      if (protos) {
12543
0
        found = false;
12544
0
        j = 0;
12545
0
        proto = protos[0];
12546
0
        while(proto) {
12547
0
          if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12548
0
            found = true;
12549
0
            break;
12550
0
          }
12551
0
          j++;
12552
0
          proto = protos[j];
12553
0
        }
12554
0
        if (!found)
12555
0
          continue;
12556
0
      }
12557
12558
0
      if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12559
0
        json_dumper_end_object(&dumper); // 7.properties
12560
0
        json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12561
0
        open_object = true;
12562
0
      }
12563
12564
0
      prev_proto = parent_hfinfo->abbrev;
12565
12566
0
      if (open_object) {
12567
0
        json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12568
0
        json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12569
0
        json_dumper_set_member_name(&dumper, "properties");
12570
0
        json_dumper_begin_object(&dumper); // 7.properties
12571
0
        open_object = false;
12572
0
      }
12573
      /* Skip the fields that would map into string. This is the default in elasticsearch. */
12574
0
      type = ws_type_to_elastic(hfinfo->type);
12575
      /* when type is NULL, we have the default mapping: string */
12576
0
      if (type) {
12577
0
        str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev);
12578
0
        dot_to_underscore(str);
12579
0
        if (g_strcmp0(prev_item, str)) {
12580
0
          json_dumper_set_member_name(&dumper, str);
12581
0
          json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12582
0
          json_dumper_set_member_name(&dumper, "type");
12583
0
          json_dumper_value_string(&dumper, type);
12584
0
          json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12585
0
        }
12586
0
        g_free(prev_item);
12587
0
        prev_item = str;
12588
0
      }
12589
0
    }
12590
0
  }
12591
0
  g_free(prev_item);
12592
12593
0
  if (prev_proto) {
12594
0
    json_dumper_end_object(&dumper); // 7.properties
12595
0
    json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12596
0
  }
12597
12598
0
  json_dumper_end_object(&dumper); // 5.properties
12599
0
  json_dumper_end_object(&dumper); // 4.layers
12600
0
  json_dumper_end_object(&dumper); // 3.properties
12601
0
  json_dumper_end_object(&dumper); // 2.mappings
12602
0
  json_dumper_end_object(&dumper); // 1.root
12603
0
  bool ret = json_dumper_finish(&dumper);
12604
0
  DISSECTOR_ASSERT(ret);
12605
12606
0
  g_strfreev(protos);
12607
0
}
12608
12609
/* Dumps the contents of the registration database to stdout. An independent
12610
 * program can take this output and format it into nice tables or HTML or
12611
 * whatever.
12612
 *
12613
 * There is one record per line. Each record is either a protocol or a header
12614
 * field, differentiated by the first field. The fields are tab-delimited.
12615
 *
12616
 * Protocols
12617
 * ---------
12618
 * Field 1 = 'P'
12619
 * Field 2 = descriptive protocol name
12620
 * Field 3 = protocol abbreviation
12621
 *
12622
 * Header Fields
12623
 * -------------
12624
 * Field 1 = 'F'
12625
 * Field 2 = descriptive field name
12626
 * Field 3 = field abbreviation
12627
 * Field 4 = type ( textual representation of the ftenum type )
12628
 * Field 5 = parent protocol abbreviation
12629
 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12630
 * Field 7 = bitmask: format: hex: 0x....
12631
 * Field 8 = blurb describing field
12632
 */
12633
void
12634
proto_registrar_dump_fields(void)
12635
0
{
12636
0
  header_field_info *hfinfo, *parent_hfinfo;
12637
0
  int      i, len;
12638
0
  const char    *enum_name;
12639
0
  const char    *base_name;
12640
0
  const char    *blurb;
12641
0
  char       width[5];
12642
12643
0
  len = gpa_hfinfo.len;
12644
0
  for (i = 1; i < len ; i++) {
12645
0
    if (gpa_hfinfo.hfi[i] == NULL)
12646
0
      continue; /* This is a deregistered protocol or header field */
12647
12648
0
    PROTO_REGISTRAR_GET_NTH(i, hfinfo);
12649
12650
    /*
12651
     * Skip the pseudo-field for "proto_tree_add_text()" since
12652
     * we don't want it in the list of filterable fields.
12653
     */
12654
0
    if (hfinfo->id == hf_text_only)
12655
0
      continue;
12656
12657
    /* format for protocols */
12658
0
    if (proto_registrar_is_protocol(i)) {
12659
0
      printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12660
0
    }
12661
    /* format for header fields */
12662
0
    else {
12663
      /*
12664
       * If this field isn't at the head of the list of
12665
       * fields with this name, skip this field - all
12666
       * fields with the same name are really just versions
12667
       * of the same field stored in different bits, and
12668
       * should have the same type/radix/value list, and
12669
       * just differ in their bit masks.  (If a field isn't
12670
       * a bitfield, but can be, say, 1 or 2 bytes long,
12671
       * it can just be made FT_UINT16, meaning the
12672
       * *maximum* length is 2 bytes, and be used
12673
       * for all lengths.)
12674
       */
12675
0
      if (hfinfo->same_name_prev_id != -1)
12676
0
        continue;
12677
12678
0
      PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
12679
12680
0
      enum_name = ftype_name(hfinfo->type);
12681
0
      base_name = "";
12682
12683
0
      if (hfinfo->type == FT_CHAR  ||
12684
0
          hfinfo->type == FT_UINT8  ||
12685
0
          hfinfo->type == FT_UINT16 ||
12686
0
          hfinfo->type == FT_UINT24 ||
12687
0
          hfinfo->type == FT_UINT32 ||
12688
0
          hfinfo->type == FT_UINT40 ||
12689
0
          hfinfo->type == FT_UINT48 ||
12690
0
          hfinfo->type == FT_UINT56 ||
12691
0
          hfinfo->type == FT_UINT64 ||
12692
0
          hfinfo->type == FT_INT8   ||
12693
0
          hfinfo->type == FT_INT16  ||
12694
0
          hfinfo->type == FT_INT24  ||
12695
0
          hfinfo->type == FT_INT32  ||
12696
0
          hfinfo->type == FT_INT40 ||
12697
0
          hfinfo->type == FT_INT48 ||
12698
0
          hfinfo->type == FT_INT56 ||
12699
0
          hfinfo->type == FT_INT64) {
12700
12701
0
        switch (FIELD_DISPLAY(hfinfo->display)) {
12702
0
          case BASE_NONE:
12703
0
          case BASE_DEC:
12704
0
          case BASE_HEX:
12705
0
          case BASE_OCT:
12706
0
          case BASE_DEC_HEX:
12707
0
          case BASE_HEX_DEC:
12708
0
          case BASE_CUSTOM:
12709
0
          case BASE_PT_UDP:
12710
0
          case BASE_PT_TCP:
12711
0
          case BASE_PT_DCCP:
12712
0
          case BASE_PT_SCTP:
12713
0
          case BASE_OUI:
12714
0
            base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
12715
0
            break;
12716
0
          default:
12717
0
            base_name = "????";
12718
0
            break;
12719
0
        }
12720
0
      } else if (hfinfo->type == FT_BOOLEAN) {
12721
        /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12722
0
        snprintf(width, sizeof(width), "%d", hfinfo->display);
12723
0
        base_name = width;
12724
0
      }
12725
12726
0
      blurb = hfinfo->blurb;
12727
0
      if (blurb == NULL)
12728
0
        blurb = "";
12729
0
      else if (strlen(blurb) == 0)
12730
0
        blurb = "\"\"";
12731
12732
0
      printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64 "\t%s\n",
12733
0
        hfinfo->name, hfinfo->abbrev, enum_name,
12734
0
        parent_hfinfo->abbrev, base_name,
12735
0
        hfinfo->bitmask, blurb);
12736
0
    }
12737
0
  }
12738
0
}
12739
12740
/* Dumps all abbreviated field and protocol completions of the given string to
12741
 * stdout.  An independent program may use this for command-line tab completion
12742
 * of fields.
12743
 */
12744
bool
12745
proto_registrar_dump_field_completions(const char *prefix)
12746
0
{
12747
0
  header_field_info *hfinfo;
12748
0
  int      i, len;
12749
0
  size_t       prefix_len;
12750
0
  bool     matched = false;
12751
12752
0
  prefix_len = strlen(prefix);
12753
0
  len = gpa_hfinfo.len;
12754
0
  for (i = 1; i < len ; i++) {
12755
0
    if (gpa_hfinfo.hfi[i] == NULL)
12756
0
      continue; /* This is a deregistered protocol or header field */
12757
12758
0
    PROTO_REGISTRAR_GET_NTH(i, hfinfo);
12759
12760
    /*
12761
     * Skip the pseudo-field for "proto_tree_add_text()" since
12762
     * we don't want it in the list of filterable fields.
12763
     */
12764
0
    if (hfinfo->id == hf_text_only)
12765
0
      continue;
12766
12767
    /* format for protocols */
12768
0
    if (proto_registrar_is_protocol(i)) {
12769
0
      if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12770
0
        matched = true;
12771
0
        printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12772
0
      }
12773
0
    }
12774
    /* format for header fields */
12775
0
    else {
12776
      /*
12777
       * If this field isn't at the head of the list of
12778
       * fields with this name, skip this field - all
12779
       * fields with the same name are really just versions
12780
       * of the same field stored in different bits, and
12781
       * should have the same type/radix/value list, and
12782
       * just differ in their bit masks.  (If a field isn't
12783
       * a bitfield, but can be, say, 1 or 2 bytes long,
12784
       * it can just be made FT_UINT16, meaning the
12785
       * *maximum* length is 2 bytes, and be used
12786
       * for all lengths.)
12787
       */
12788
0
      if (hfinfo->same_name_prev_id != -1)
12789
0
        continue;
12790
12791
0
      if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12792
0
        matched = true;
12793
0
        printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12794
0
      }
12795
0
    }
12796
0
  }
12797
0
  return matched;
12798
0
}
12799
12800
/* Dumps field types and descriptive names to stdout. An independent
12801
 * program can take this output and format it into nice tables or HTML or
12802
 * whatever.
12803
 *
12804
 * There is one record per line. The fields are tab-delimited.
12805
 *
12806
 * Field 1 = field type name, e.g. FT_UINT8
12807
 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12808
 */
12809
void
12810
proto_registrar_dump_ftypes(void)
12811
0
{
12812
0
  int fte;
12813
12814
0
  for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12815
0
    printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12816
0
  }
12817
0
}
12818
12819
/* This function indicates whether it's possible to construct a
12820
 * "match selected" display filter string for the specified field,
12821
 * returns an indication of whether it's possible, and, if it's
12822
 * possible and "filter" is non-null, constructs the filter and
12823
 * sets "*filter" to point to it.
12824
 * You do not need to [g_]free() this string since it will be automatically
12825
 * freed once the next packet is dissected.
12826
 */
12827
static bool
12828
construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12829
        char **filter)
12830
0
{
12831
0
  const header_field_info *hfinfo;
12832
0
  int      start, length, length_remaining;
12833
12834
0
  if (!finfo)
12835
0
    return false;
12836
12837
0
  hfinfo     = finfo->hfinfo;
12838
0
  DISSECTOR_ASSERT(hfinfo);
12839
12840
  /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12841
   * then "the numeric value ... is not used when preparing
12842
   * filters for the field in question." If it's any other
12843
   * base, we'll generate the filter normally (which will
12844
   * be numeric, even though the human-readable string does
12845
   * work for filtering.)
12846
   *
12847
   * XXX - It might be nice to use fvalue_to_string_repr() in
12848
   * "proto_item_fill_label()" as well, although, there, you'd
12849
   * have to deal with the base *and* with resolved values for
12850
   * addresses.
12851
   *
12852
   * Perhaps in addition to taking the repr type (DISPLAY
12853
   * or DFILTER) and the display (base), fvalue_to_string_repr()
12854
   * should have the the "strings" values in the header_field_info
12855
   * structure for the field as a parameter, so it can have
12856
   * if the field is Boolean or an enumerated integer type,
12857
   * the tables used to generate human-readable values.
12858
   */
12859
0
  if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
12860
0
    const char *str = NULL;
12861
12862
0
    switch (hfinfo->type) {
12863
12864
0
    case FT_INT8:
12865
0
    case FT_INT16:
12866
0
    case FT_INT24:
12867
0
    case FT_INT32:
12868
0
      str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12869
0
      break;
12870
12871
0
    case FT_CHAR:
12872
0
    case FT_UINT8:
12873
0
    case FT_UINT16:
12874
0
    case FT_UINT24:
12875
0
    case FT_UINT32:
12876
0
      str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12877
0
      break;
12878
12879
0
    default:
12880
0
      break;
12881
0
    }
12882
12883
0
    if (str != NULL && filter != NULL) {
12884
0
      *filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
12885
0
      return true;
12886
0
    }
12887
0
  }
12888
12889
0
  switch (hfinfo->type) {
12890
12891
0
    case FT_PROTOCOL:
12892
0
      if (filter != NULL)
12893
0
        *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
12894
0
      break;
12895
12896
0
    case FT_NONE:
12897
      /*
12898
       * If the length is 0, just match the name of the
12899
       * field.
12900
       *
12901
       * (Also check for negative values, just in case,
12902
       * as we'll cast it to an unsigned value later.)
12903
       */
12904
0
      length = finfo->length;
12905
0
      if (length == 0) {
12906
0
        if (filter != NULL)
12907
0
          *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
12908
0
        break;
12909
0
      }
12910
0
      if (length < 0)
12911
0
        return false;
12912
12913
      /*
12914
       * This doesn't have a value, so we'd match
12915
       * on the raw bytes at this address.
12916
       *
12917
       * Should we be allowed to access to the raw bytes?
12918
       * If "edt" is NULL, the answer is "no".
12919
       */
12920
0
      if (edt == NULL)
12921
0
        return false;
12922
12923
      /*
12924
       * Is this field part of the raw frame tvbuff?
12925
       * If not, we can't use "frame[N:M]" to match
12926
       * it.
12927
       *
12928
       * XXX - should this be frame-relative, or
12929
       * protocol-relative?
12930
       *
12931
       * XXX - does this fallback for non-registered
12932
       * fields even make sense?
12933
       */
12934
0
      if (finfo->ds_tvb != edt->tvb)
12935
0
        return false; /* you lose */
12936
12937
      /*
12938
       * Don't go past the end of that tvbuff.
12939
       */
12940
0
      length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12941
0
      if (length > length_remaining)
12942
0
        length = length_remaining;
12943
0
      if (length <= 0)
12944
0
        return false;
12945
12946
0
      if (filter != NULL) {
12947
0
        start = finfo->start;
12948
0
        char *str = bytes_to_dfilter_repr(NULL, tvb_get_ptr(finfo->ds_tvb, start, length), length);
12949
0
        *filter = wmem_strdup_printf(NULL, "frame[%d:%d] == %s", finfo->start, length, str);
12950
0
        wmem_free(NULL, str);
12951
0
      }
12952
0
      break;
12953
12954
    /* By default, use the fvalue's "to_string_repr" method. */
12955
0
    default:
12956
0
      if (filter != NULL) {
12957
0
        char *str = fvalue_to_string_repr(NULL, finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12958
0
        *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, str);
12959
0
        wmem_free(NULL, str);
12960
0
      }
12961
0
      break;
12962
0
  }
12963
12964
0
  return true;
12965
0
}
12966
12967
/*
12968
 * Returns true if we can do a "match selected" on the field, false
12969
 * otherwise.
12970
 */
12971
bool
12972
proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12973
0
{
12974
0
  return construct_match_selected_string(finfo, edt, NULL);
12975
0
}
12976
12977
/* This function attempts to construct a "match selected" display filter
12978
 * string for the specified field; if it can do so, it returns a pointer
12979
 * to the string, otherwise it returns NULL.
12980
 *
12981
 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12982
 */
12983
char *
12984
proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12985
0
{
12986
0
  char *filter = NULL;
12987
12988
0
  if (!construct_match_selected_string(finfo, edt, &filter))
12989
0
  {
12990
0
    wmem_free(NULL, filter);
12991
0
    return NULL;
12992
0
  }
12993
0
  return filter;
12994
0
}
12995
12996
/* This function is common code for all proto_tree_add_bitmask... functions.
12997
 */
12998
12999
static bool
13000
proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const unsigned offset,
13001
          const unsigned len, const int ett, int * const *fields,
13002
          const int flags, bool first,
13003
          bool use_parent_tree,
13004
          proto_tree* tree, uint64_t value)
13005
2.42M
{
13006
2.42M
  uint64_t           available_bits = UINT64_MAX;
13007
2.42M
  uint64_t           bitmask = 0;
13008
2.42M
  uint64_t           tmpval;
13009
2.42M
  header_field_info *hf;
13010
2.42M
  uint32_t           integer32;
13011
2.42M
  int                bit_offset;
13012
2.42M
  int                no_of_bits;
13013
13014
2.42M
  if (!*fields)
13015
2.42M
    REPORT_DISSECTOR_BUG("Illegal call of proto_item_add_bitmask_tree without fields");
13016
13017
2.42M
  if (len > 8)
13018
2.42M
    REPORT_DISSECTOR_BUG("Invalid len: %d", len);
13019
  /**
13020
   * packet-frame.c uses len=0 since the value is taken from the packet
13021
   * metadata, not the packet bytes. In that case, assume that all bits
13022
   * in the provided value are valid.
13023
   */
13024
2.42M
  if (len > 0) {
13025
2.37M
    available_bits >>= (8 - len)*8;
13026
2.37M
  }
13027
13028
2.42M
  if (use_parent_tree == false)
13029
2.31M
    tree = proto_item_add_subtree(item, ett);
13030
13031
16.3M
  while (*fields) {
13032
13.9M
    uint64_t present_bits;
13033
13.9M
    PROTO_REGISTRAR_GET_NTH(**fields,hf);
13034
13.9M
    DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
13035
13036
13.9M
    bitmask |= hf->bitmask;
13037
13038
    /* Skip fields that aren't fully present */
13039
13.9M
    present_bits = available_bits & hf->bitmask;
13040
13.9M
    if (present_bits != hf->bitmask) {
13041
5.74k
      fields++;
13042
5.74k
      continue;
13043
5.74k
    }
13044
13045
13.9M
    switch (hf->type) {
13046
0
    case FT_CHAR:
13047
991k
    case FT_UINT8:
13048
1.36M
    case FT_UINT16:
13049
1.37M
    case FT_UINT24:
13050
1.48M
    case FT_UINT32:
13051
1.48M
      proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
13052
1.48M
      break;
13053
13054
0
    case FT_INT8:
13055
117
    case FT_INT16:
13056
117
    case FT_INT24:
13057
117
    case FT_INT32:
13058
117
      proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
13059
117
      break;
13060
13061
208k
    case FT_UINT40:
13062
214k
    case FT_UINT48:
13063
216k
    case FT_UINT56:
13064
224k
    case FT_UINT64:
13065
224k
      proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
13066
224k
      break;
13067
13068
0
    case FT_INT40:
13069
0
    case FT_INT48:
13070
0
    case FT_INT56:
13071
0
    case FT_INT64:
13072
0
      proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
13073
0
      break;
13074
13075
12.2M
    case FT_BOOLEAN:
13076
12.2M
      proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
13077
12.2M
      break;
13078
13079
0
    default:
13080
0
      REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()",
13081
0
               hf->abbrev,
13082
0
               hf->type,
13083
0
               ftype_name(hf->type));
13084
0
      break;
13085
13.9M
    }
13086
13.9M
    if (flags & BMT_NO_APPEND) {
13087
1.28M
      fields++;
13088
1.28M
      continue;
13089
1.28M
    }
13090
12.6M
    tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
13091
13092
    /* XXX: README.developer and the comments have always defined
13093
     * BMT_NO_INT as "only boolean flags are added to the title /
13094
     * don't add non-boolean (integral) fields", but the
13095
     * implementation has always added BASE_CUSTOM and fields with
13096
     * value_strings, though not fields with unit_strings.
13097
     * Possibly this is because some dissectors use a FT_UINT8
13098
     * with a value_string for fields that should be a FT_BOOLEAN.
13099
     */
13100
12.6M
    switch (hf->type) {
13101
0
    case FT_CHAR:
13102
0
      if (hf->display == BASE_CUSTOM) {
13103
0
        char lbl[ITEM_LABEL_LENGTH];
13104
0
        const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13105
13106
0
        DISSECTOR_ASSERT(fmtfunc);
13107
0
        fmtfunc(lbl, (uint32_t) tmpval);
13108
0
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13109
0
            hf->name, lbl);
13110
0
        first = false;
13111
0
      }
13112
0
      else if (hf->strings) {
13113
0
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13114
0
                   hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13115
0
        first = false;
13116
0
      }
13117
0
      else if (!(flags & BMT_NO_INT)) {
13118
0
        char buf[32];
13119
0
        const char *out;
13120
13121
0
        if (!first) {
13122
0
          proto_item_append_text(item, ", ");
13123
0
        }
13124
13125
0
        out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
13126
0
        proto_item_append_text(item, "%s: %s", hf->name, out);
13127
0
        first = false;
13128
0
      }
13129
13130
0
      break;
13131
13132
931k
    case FT_UINT8:
13133
1.20M
    case FT_UINT16:
13134
1.21M
    case FT_UINT24:
13135
1.22M
    case FT_UINT32:
13136
1.22M
      if (hf->display == BASE_CUSTOM) {
13137
2.41k
        char lbl[ITEM_LABEL_LENGTH];
13138
2.41k
        const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13139
13140
2.41k
        DISSECTOR_ASSERT(fmtfunc);
13141
2.41k
        fmtfunc(lbl, (uint32_t) tmpval);
13142
2.41k
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13143
2.41k
            hf->name, lbl);
13144
2.41k
        first = false;
13145
2.41k
      }
13146
1.22M
      else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING|BASE_SPECIAL_VALS)))) {
13147
564k
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13148
564k
                    hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13149
564k
        first = false;
13150
564k
      }
13151
657k
      else if (!(flags & BMT_NO_INT)) {
13152
6.07k
        char buf[NUMBER_LABEL_LENGTH];
13153
6.07k
        const char *out = NULL;
13154
13155
6.07k
        if (!first) {
13156
5.88k
          proto_item_append_text(item, ", ");
13157
5.88k
        }
13158
13159
6.07k
        if (hf->strings && hf->display & BASE_SPECIAL_VALS) {
13160
0
          out = hf_try_val_to_str((uint32_t) tmpval, hf);
13161
0
        }
13162
6.07k
        if (out == NULL) {
13163
6.07k
          out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
13164
6.07k
        }
13165
6.07k
        proto_item_append_text(item, "%s: %s", hf->name, out);
13166
6.07k
        if (hf->strings && hf->display & BASE_UNIT_STRING) {
13167
0
          proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13168
0
        }
13169
6.07k
        first = false;
13170
6.07k
      }
13171
13172
1.22M
      break;
13173
13174
0
    case FT_INT8:
13175
117
    case FT_INT16:
13176
117
    case FT_INT24:
13177
117
    case FT_INT32:
13178
117
      integer32 = (uint32_t) tmpval;
13179
117
      if (hf->bitmask) {
13180
117
        no_of_bits = ws_count_ones(hf->bitmask);
13181
117
        integer32 = ws_sign_ext32(integer32, no_of_bits);
13182
117
      }
13183
117
      if (hf->display == BASE_CUSTOM) {
13184
0
        char lbl[ITEM_LABEL_LENGTH];
13185
0
        const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13186
13187
0
        DISSECTOR_ASSERT(fmtfunc);
13188
0
        fmtfunc(lbl, (int32_t) integer32);
13189
0
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13190
0
            hf->name, lbl);
13191
0
        first = false;
13192
0
      }
13193
117
      else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING|BASE_SPECIAL_VALS)))) {
13194
0
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13195
0
            hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13196
0
        first = false;
13197
0
      }
13198
117
      else if (!(flags & BMT_NO_INT)) {
13199
115
        char buf[NUMBER_LABEL_LENGTH];
13200
115
        const char *out = NULL;
13201
13202
115
        if (!first) {
13203
115
          proto_item_append_text(item, ", ");
13204
115
        }
13205
13206
115
        if (hf->strings && hf->display & BASE_SPECIAL_VALS) {
13207
0
          out = hf_try_val_to_str((int32_t) integer32, hf);
13208
0
        }
13209
115
        if (out == NULL) {
13210
115
          out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13211
115
        }
13212
115
        proto_item_append_text(item, "%s: %s", hf->name, out);
13213
115
        if (hf->strings && hf->display & BASE_UNIT_STRING) {
13214
115
          proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13215
115
        }
13216
115
        first = false;
13217
115
      }
13218
13219
117
      break;
13220
13221
140k
    case FT_UINT40:
13222
140k
    case FT_UINT48:
13223
140k
    case FT_UINT56:
13224
140k
    case FT_UINT64:
13225
140k
      if (hf->display == BASE_CUSTOM) {
13226
75.4k
        char lbl[ITEM_LABEL_LENGTH];
13227
75.4k
        const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13228
13229
75.4k
        DISSECTOR_ASSERT(fmtfunc);
13230
75.4k
        fmtfunc(lbl, tmpval);
13231
75.4k
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13232
75.4k
            hf->name, lbl);
13233
75.4k
        first = false;
13234
75.4k
      }
13235
65.2k
      else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING|BASE_SPECIAL_VALS)))) {
13236
5
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13237
5
            hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13238
5
        first = false;
13239
5
      }
13240
65.2k
      else if (!(flags & BMT_NO_INT)) {
13241
0
        char buf[NUMBER_LABEL_LENGTH];
13242
0
        const char *out = NULL;
13243
13244
0
        if (!first) {
13245
0
          proto_item_append_text(item, ", ");
13246
0
        }
13247
13248
0
        if (hf->strings && hf->display & BASE_SPECIAL_VALS) {
13249
0
          out = hf_try_val64_to_str(tmpval, hf);
13250
0
        }
13251
0
        if (out == NULL) {
13252
0
          out = hfinfo_number_value_format64(hf, buf, tmpval);
13253
0
        }
13254
0
        proto_item_append_text(item, "%s: %s", hf->name, out);
13255
0
        if (hf->strings && hf->display & BASE_UNIT_STRING) {
13256
0
          proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13257
0
        }
13258
0
        first = false;
13259
0
      }
13260
13261
140k
      break;
13262
13263
0
    case FT_INT40:
13264
0
    case FT_INT48:
13265
0
    case FT_INT56:
13266
0
    case FT_INT64:
13267
0
      if (hf->bitmask) {
13268
0
        no_of_bits = ws_count_ones(hf->bitmask);
13269
0
        tmpval = ws_sign_ext64(tmpval, no_of_bits);
13270
0
      }
13271
0
      if (hf->display == BASE_CUSTOM) {
13272
0
        char lbl[ITEM_LABEL_LENGTH];
13273
0
        const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13274
13275
0
        DISSECTOR_ASSERT(fmtfunc);
13276
0
        fmtfunc(lbl, (int64_t) tmpval);
13277
0
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13278
0
            hf->name, lbl);
13279
0
        first = false;
13280
0
      }
13281
0
      else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING|BASE_SPECIAL_VALS)))) {
13282
0
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13283
0
            hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13284
0
        first = false;
13285
0
      }
13286
0
      else if (!(flags & BMT_NO_INT)) {
13287
0
        char buf[NUMBER_LABEL_LENGTH];
13288
0
        const char *out = NULL;
13289
13290
0
        if (!first) {
13291
0
          proto_item_append_text(item, ", ");
13292
0
        }
13293
13294
0
        if (hf->strings && hf->display & BASE_SPECIAL_VALS) {
13295
0
          out = hf_try_val64_to_str((int64_t) tmpval, hf);
13296
0
        }
13297
0
        if (out == NULL) {
13298
0
          out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13299
0
        }
13300
0
        proto_item_append_text(item, "%s: %s", hf->name, out);
13301
0
        if (hf->strings && hf->display & BASE_UNIT_STRING) {
13302
0
          proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13303
0
        }
13304
0
        first = false;
13305
0
      }
13306
13307
0
      break;
13308
13309
11.2M
    case FT_BOOLEAN:
13310
11.2M
      if (hf->strings && !(flags & BMT_NO_TFS)) {
13311
        /* If we have true/false strings, emit full - otherwise messages
13312
           might look weird */
13313
21.6k
        const struct true_false_string *tfs =
13314
21.6k
          (const struct true_false_string *)hf->strings;
13315
13316
21.6k
        if (tmpval) {
13317
6.24k
          proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13318
6.24k
              hf->name, tfs->true_string);
13319
6.24k
          first = false;
13320
15.4k
        } else if (!(flags & BMT_NO_FALSE)) {
13321
13.5k
          proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13322
13.5k
              hf->name, tfs->false_string);
13323
13.5k
          first = false;
13324
13.5k
        }
13325
11.2M
      } else if (hf->bitmask & value) {
13326
        /* If the flag is set, show the name */
13327
4.30M
        proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13328
4.30M
        first = false;
13329
4.30M
      }
13330
11.2M
      break;
13331
0
    default:
13332
0
      REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()",
13333
0
               hf->abbrev,
13334
0
               hf->type,
13335
0
               ftype_name(hf->type));
13336
0
      break;
13337
12.6M
    }
13338
13339
12.6M
    fields++;
13340
12.6M
  }
13341
13342
  /* XXX: We don't pass the hfi into this function. Perhaps we should,
13343
   * but then again most dissectors don't set the bitmask field for
13344
   * the higher level bitmask hfi, so calculate the bitmask from the
13345
   * fields present. */
13346
2.42M
  if (item) {
13347
2.31M
    bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13348
2.31M
    no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13349
2.31M
    FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
13350
2.31M
    FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
13351
2.31M
  }
13352
2.42M
  return first;
13353
2.42M
}
13354
13355
/* This function will dissect a sequence of bytes that describe a
13356
 * bitmask and supply the value of that sequence through a pointer.
13357
 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13358
 * to be dissected.
13359
 * This field will form an expansion under which the individual fields of the
13360
 * bitmask is dissected and displayed.
13361
 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13362
 *
13363
 * fields is an array of pointers to int that lists all the fields of the
13364
 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13365
 * or another integer of the same type/size as hf_hdr with a mask specified.
13366
 * This array is terminated by a NULL entry.
13367
 *
13368
 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13369
 * FT_integer fields that have a value_string attached will have the
13370
 * matched string displayed on the expansion line.
13371
 */
13372
proto_item *
13373
proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13374
           const unsigned offset, const int hf_hdr,
13375
           const int ett, int * const *fields,
13376
           const unsigned encoding, uint64_t *retval)
13377
45.0k
{
13378
45.0k
  return proto_tree_add_bitmask_with_flags_ret_uint64(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS, retval);
13379
45.0k
}
13380
13381
/* This function will dissect a sequence of bytes that describe a
13382
 * bitmask.
13383
 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13384
 * to be dissected.
13385
 * This field will form an expansion under which the individual fields of the
13386
 * bitmask is dissected and displayed.
13387
 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13388
 *
13389
 * fields is an array of pointers to int that lists all the fields of the
13390
 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13391
 * or another integer of the same type/size as hf_hdr with a mask specified.
13392
 * This array is terminated by a NULL entry.
13393
 *
13394
 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13395
 * FT_integer fields that have a value_string attached will have the
13396
 * matched string displayed on the expansion line.
13397
 */
13398
proto_item *
13399
proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13400
           const unsigned offset, const int hf_hdr,
13401
           const int ett, int * const *fields,
13402
           const unsigned encoding)
13403
2.02M
{
13404
2.02M
  return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
13405
2.02M
}
13406
13407
/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13408
 * what data is appended to the header.
13409
 */
13410
proto_item *
13411
proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13412
    const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13413
    uint64_t *retval)
13414
49.8k
{
13415
49.8k
  proto_item        *item = NULL;
13416
49.8k
  header_field_info *hf;
13417
49.8k
  unsigned           len;
13418
49.8k
  uint64_t           value;
13419
13420
49.8k
  PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
13421
49.8k
  DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
13422
49.8k
  len = ftype_wire_size(hf->type);
13423
49.8k
  value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13424
13425
49.8k
  if (parent_tree) {
13426
49.6k
    item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13427
49.6k
    proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13428
49.6k
        flags, false, false, NULL, value);
13429
49.6k
  }
13430
13431
49.8k
  *retval = value;
13432
49.8k
  if (hf->bitmask) {
13433
    /* Mask out irrelevant portions */
13434
37.0k
    *retval &= hf->bitmask;
13435
    /* Shift bits */
13436
37.0k
    *retval >>= hfinfo_bitshift(hf);
13437
37.0k
  }
13438
13439
49.8k
  return item;
13440
49.8k
}
13441
13442
/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13443
 * what data is appended to the header.
13444
 */
13445
proto_item *
13446
proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13447
    const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13448
2.20M
{
13449
2.20M
  proto_item        *item = NULL;
13450
2.20M
  header_field_info *hf;
13451
2.20M
  unsigned           len;
13452
2.20M
  uint64_t           value;
13453
13454
2.20M
  PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
13455
2.20M
  DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
13456
13457
2.20M
  if (parent_tree) {
13458
2.20M
    len = ftype_wire_size(hf->type);
13459
2.20M
    item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13460
2.20M
    value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13461
2.20M
    proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13462
2.20M
        flags, false, false, NULL, value);
13463
2.20M
  }
13464
13465
2.20M
  return item;
13466
2.20M
}
13467
13468
/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13469
   can't be retrieved directly from tvb) */
13470
proto_item *
13471
proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13472
    const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13473
2.10k
{
13474
2.10k
  return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13475
2.10k
            hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
13476
2.10k
}
13477
13478
/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13479
WS_DLL_PUBLIC proto_item *
13480
proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13481
    const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13482
56.2k
{
13483
56.2k
  proto_item        *item = NULL;
13484
56.2k
  header_field_info *hf;
13485
56.2k
  unsigned           len;
13486
13487
56.2k
  PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
13488
56.2k
  DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
13489
  /* the proto_tree_add_uint/_uint64() calls below
13490
     will fail if tvb==NULL and len!=0 */
13491
56.2k
  len = tvb ? ftype_wire_size(hf->type) : 0;
13492
13493
56.2k
  if (parent_tree) {
13494
56.2k
    if (len <= 4)
13495
56.2k
      item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13496
0
    else
13497
0
      item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13498
13499
56.2k
    proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13500
56.2k
        flags, false, false, NULL, value);
13501
56.2k
  }
13502
13503
56.2k
  return item;
13504
56.2k
}
13505
13506
/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13507
void
13508
proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13509
                const unsigned len, int * const *fields, const unsigned encoding)
13510
71.8k
{
13511
71.8k
  uint64_t value;
13512
13513
71.8k
  if (tree) {
13514
71.7k
    value = get_uint64_value(tree, tvb, offset, len, encoding);
13515
71.7k
    proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
13516
71.7k
        BMT_NO_APPEND, false, true, tree, value);
13517
71.7k
  }
13518
71.8k
}
13519
13520
WS_DLL_PUBLIC void
13521
proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13522
          const unsigned len, int * const *fields, const unsigned encoding, uint64_t *retval)
13523
1.12k
{
13524
1.12k
  uint64_t value;
13525
13526
1.12k
  value = get_uint64_value(tree, tvb, offset, len, encoding);
13527
1.12k
  if (tree) {
13528
1.11k
    proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
13529
1.11k
        BMT_NO_APPEND, false, true, tree, value);
13530
1.11k
  }
13531
1.12k
  if (retval) {
13532
1.11k
    *retval = value;
13533
1.11k
  }
13534
1.12k
}
13535
13536
WS_DLL_PUBLIC void
13537
proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13538
                const unsigned len, int * const *fields, const uint64_t value)
13539
29.8k
{
13540
29.8k
  if (tree) {
13541
29.8k
    proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
13542
29.8k
        BMT_NO_APPEND, false, true, tree, value);
13543
29.8k
  }
13544
29.8k
}
13545
13546
13547
/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13548
 * This is intended to support bitmask fields whose lengths can vary, perhaps
13549
 * as the underlying standard evolves over time.
13550
 * With this API there is the possibility of being called to display more or
13551
 * less data than the dissector was coded to support.
13552
 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13553
 * Thus when presented with "too much" or "too little" data, MSbits will be
13554
 * ignored or MSfields sacrificed.
13555
 *
13556
 * Only fields for which all defined bits are available are displayed.
13557
 */
13558
proto_item *
13559
proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13560
           const unsigned offset,  const unsigned len, const int hf_hdr,
13561
           const int ett, int * const *fields, struct expert_field* exp,
13562
           const unsigned encoding)
13563
3
{
13564
3
  proto_item        *item = NULL;
13565
3
  header_field_info *hf;
13566
3
  unsigned   decodable_len;
13567
3
  unsigned   decodable_offset;
13568
3
  uint32_t decodable_value;
13569
3
  uint64_t value;
13570
13571
3
  PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
13572
3
  DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
13573
13574
3
  decodable_offset = offset;
13575
3
  decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type));
13576
13577
  /* If we are ftype_wire_size-limited,
13578
   * make sure we decode as many LSBs as possible.
13579
   */
13580
3
  if (encoding == ENC_BIG_ENDIAN) {
13581
0
    decodable_offset += (len - decodable_len);
13582
0
  }
13583
13584
3
  if (parent_tree) {
13585
3
    decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13586
3
             decodable_len, encoding);
13587
13588
    /* The root item covers all the bytes even if we can't decode them all */
13589
3
    item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13590
3
             decodable_value);
13591
3
  }
13592
13593
3
  if (decodable_len < len) {
13594
    /* Dissector likely requires updating for new protocol revision */
13595
0
    expert_add_info_format(NULL, item, exp,
13596
0
               "Only least-significant %d of %d bytes decoded",
13597
0
               decodable_len, len);
13598
0
  }
13599
13600
3
  if (item) {
13601
3
    value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13602
3
    proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13603
3
        ett, fields, BMT_NO_INT|BMT_NO_TFS, false, false, NULL, value);
13604
3
  }
13605
13606
3
  return item;
13607
3
}
13608
13609
/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13610
proto_item *
13611
proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13612
          const unsigned offset, const unsigned len,
13613
          const char *name, const char *fallback,
13614
          const int ett, int * const *fields,
13615
          const unsigned encoding, const int flags)
13616
3.78k
{
13617
3.78k
  proto_item *item = NULL;
13618
3.78k
  uint64_t    value;
13619
13620
3.78k
  if (parent_tree) {
13621
3.78k
    item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13622
3.78k
    value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13623
3.78k
    if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13624
3.78k
        flags, true, false, NULL, value) && fallback) {
13625
      /* Still at first item - append 'fallback' text if any */
13626
0
      proto_item_append_text(item, "%s", fallback);
13627
0
    }
13628
3.78k
  }
13629
13630
3.78k
  return item;
13631
3.78k
}
13632
13633
proto_item *
13634
proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13635
       const unsigned bit_offset, const int no_of_bits,
13636
       const unsigned encoding)
13637
4.51M
{
13638
4.51M
  header_field_info *hfinfo;
13639
4.51M
  int      octet_length;
13640
4.51M
  unsigned     octet_offset;
13641
13642
4.51M
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
13643
13644
4.51M
  if (no_of_bits < 0) {
13645
1
    THROW(ReportedBoundsError);
13646
1
  }
13647
4.51M
  octet_length = (no_of_bits + 7) >> 3;
13648
4.51M
  octet_offset = bit_offset >> 3;
13649
4.51M
  test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13650
13651
  /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13652
   * but only after doing a bunch more work (which we can, in the common
13653
   * case, shortcut here).
13654
   */
13655
4.51M
  CHECK_FOR_NULL_TREE(tree);
13656
2.06M
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
13657
13658
1.99M
  return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
13659
2.06M
}
13660
13661
/*
13662
 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13663
 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13664
 * Offset should be given in bits from the start of the tvb.
13665
 */
13666
13667
static proto_item *
13668
_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13669
          const unsigned bit_offset, const int no_of_bits,
13670
          uint64_t *return_value, const unsigned encoding)
13671
2.08M
{
13672
2.08M
  unsigned offset;
13673
2.08M
  unsigned length;
13674
2.08M
  uint8_t  tot_no_bits;
13675
2.08M
  char    *bf_str;
13676
2.08M
  char     lbl_str[ITEM_LABEL_LENGTH];
13677
2.08M
  uint64_t value = 0;
13678
2.08M
  uint8_t *bytes = NULL;
13679
2.08M
  size_t bytes_length = 0;
13680
13681
2.08M
  proto_item        *pi;
13682
2.08M
  header_field_info *hf_field;
13683
13684
  /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13685
2.08M
  PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
13686
13687
2.08M
  if (hf_field->bitmask != 0) {
13688
0
    REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_ret_val"
13689
0
             " with field '%s' (%s) with bitmask != 0",
13690
0
             hf_field->abbrev, hf_field->name);
13691
0
  }
13692
13693
2.08M
  if (no_of_bits < 0) {
13694
0
    THROW(ReportedBoundsError);
13695
2.08M
  } else if (no_of_bits == 0) {
13696
3
    REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of 0",
13697
3
             hf_field->abbrev);
13698
3
  }
13699
13700
  /* Byte align offset */
13701
2.08M
  offset = bit_offset>>3;
13702
13703
  /*
13704
   * Calculate the number of octets used to hold the bits
13705
   */
13706
2.08M
  tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13707
2.08M
  length = (tot_no_bits + 7) >> 3;
13708
13709
2.08M
  if (no_of_bits < 65) {
13710
2.08M
    value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13711
2.08M
  } else if (hf_field->type != FT_BYTES) {
13712
58
    REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 64",
13713
58
             hf_field->abbrev, no_of_bits);
13714
58
    return NULL;
13715
58
  }
13716
13717
  /* Sign extend for signed types */
13718
2.08M
  switch (hf_field->type) {
13719
15
    case FT_INT8:
13720
25
    case FT_INT16:
13721
25
    case FT_INT24:
13722
25
    case FT_INT32:
13723
25
    case FT_INT40:
13724
25
    case FT_INT48:
13725
25
    case FT_INT56:
13726
25
    case FT_INT64:
13727
25
      value = ws_sign_ext64(value, no_of_bits);
13728
25
      break;
13729
13730
2.08M
    default:
13731
2.08M
      break;
13732
2.08M
  }
13733
13734
2.08M
  if (return_value) {
13735
104k
    *return_value = value;
13736
104k
  }
13737
13738
  /* Coast clear. Try and fake it */
13739
2.08M
  CHECK_FOR_NULL_TREE(tree);
13740
2.08M
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
13741
13742
2.07M
  bf_str = decode_bits_in_field(PNODE_POOL(tree), bit_offset, no_of_bits, value, encoding);
13743
13744
2.07M
  switch (hf_field->type) {
13745
473k
  case FT_BOOLEAN:
13746
    /* Boolean field */
13747
473k
    return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13748
473k
      "%s = %s: %s",
13749
473k
      bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13750
0
    break;
13751
13752
0
  case FT_CHAR:
13753
0
    pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13754
0
    fill_label_char(PITEM_FINFO(pi), lbl_str, NULL);
13755
0
    break;
13756
13757
1.53M
  case FT_UINT8:
13758
1.56M
  case FT_UINT16:
13759
1.56M
  case FT_UINT24:
13760
1.60M
  case FT_UINT32:
13761
1.60M
    pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13762
1.60M
    fill_label_number(PITEM_FINFO(pi), lbl_str, NULL, false);
13763
1.60M
    break;
13764
13765
15
  case FT_INT8:
13766
25
  case FT_INT16:
13767
25
  case FT_INT24:
13768
25
  case FT_INT32:
13769
25
    pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13770
25
    fill_label_number(PITEM_FINFO(pi), lbl_str, NULL, true);
13771
25
    break;
13772
13773
0
  case FT_UINT40:
13774
0
  case FT_UINT48:
13775
0
  case FT_UINT56:
13776
316
  case FT_UINT64:
13777
316
    pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13778
316
    fill_label_number64(PITEM_FINFO(pi), lbl_str, NULL, false);
13779
316
    break;
13780
13781
0
  case FT_INT40:
13782
0
  case FT_INT48:
13783
0
  case FT_INT56:
13784
0
  case FT_INT64:
13785
0
    pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13786
0
    fill_label_number64(PITEM_FINFO(pi), lbl_str, NULL, true);
13787
0
    break;
13788
13789
1.40k
  case FT_BYTES:
13790
1.40k
    bytes = tvb_get_bits_array(PNODE_POOL(tree), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13791
1.40k
    pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13792
1.40k
    proto_item_fill_label(PITEM_FINFO(pi), lbl_str, NULL);
13793
1.40k
    proto_item_set_text(pi, "%s", lbl_str);
13794
1.40k
    return pi;
13795
13796
  /* TODO: should handle FT_UINT_BYTES ? */
13797
13798
0
  default:
13799
0
    REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_bits_ret_val()",
13800
0
             hf_field->abbrev,
13801
0
             hf_field->type,
13802
0
             ftype_name(hf_field->type));
13803
0
    return NULL;
13804
2.07M
  }
13805
13806
1.60M
  proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13807
1.60M
  return pi;
13808
2.07M
}
13809
13810
proto_item *
13811
proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13812
               const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13813
               uint64_t *return_value)
13814
1.03k
{
13815
1.03k
  proto_item *pi;
13816
1.03k
  int         no_of_bits;
13817
1.03k
  unsigned    octet_offset;
13818
1.03k
  unsigned    mask_initial_bit_offset;
13819
1.03k
  unsigned    mask_greatest_bit_offset;
13820
1.03k
  unsigned    octet_length;
13821
1.03k
  uint8_t     i;
13822
1.03k
  char        bf_str[256];
13823
1.03k
  char        lbl_str[ITEM_LABEL_LENGTH];
13824
1.03k
  uint64_t    value;
13825
1.03k
  uint64_t    composite_bitmask;
13826
1.03k
  uint64_t    composite_bitmap;
13827
13828
1.03k
  header_field_info       *hf_field;
13829
13830
  /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13831
1.03k
  PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
13832
13833
1.03k
  if (hf_field->bitmask != 0) {
13834
0
    REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_split_bits_item_ret_val"
13835
0
             " with field '%s' (%s) with bitmask != 0",
13836
0
             hf_field->abbrev, hf_field->name);
13837
0
  }
13838
13839
1.03k
  mask_initial_bit_offset = bit_offset % 8;
13840
13841
1.03k
  no_of_bits = 0;
13842
1.03k
  value      = 0;
13843
1.03k
  i          = 0;
13844
1.03k
  mask_greatest_bit_offset = 0;
13845
1.03k
  composite_bitmask        = 0;
13846
1.03k
  composite_bitmap         = 0;
13847
13848
3.09k
  while (crumb_spec[i].crumb_bit_length != 0) {
13849
2.06k
    uint64_t crumb_mask, crumb_value;
13850
2.06k
    uint8_t crumb_end_bit_offset;
13851
13852
2.06k
    crumb_value = tvb_get_bits64(tvb,
13853
2.06k
               bit_offset + crumb_spec[i].crumb_bit_offset,
13854
2.06k
               crumb_spec[i].crumb_bit_length,
13855
2.06k
               ENC_BIG_ENDIAN);
13856
2.06k
    value      += crumb_value;
13857
2.06k
    no_of_bits += crumb_spec[i].crumb_bit_length;
13858
2.06k
    DISSECTOR_ASSERT_HINT(no_of_bits <= 64, "a value larger than 64 bits cannot be represented");
13859
13860
    /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13861
       octet containing the initial offset.
13862
       If the mask is beyond 32 bits, then give up on bit map display.
13863
       This could be improved in future, probably showing a table
13864
       of 32 or 64 bits per row */
13865
2.06k
    if (mask_greatest_bit_offset < 32) {
13866
2.05k
      crumb_end_bit_offset = mask_initial_bit_offset
13867
2.05k
        + crumb_spec[i].crumb_bit_offset
13868
2.05k
        + crumb_spec[i].crumb_bit_length;
13869
2.05k
      crumb_mask = (UINT64_C(1) << crumb_spec[i].crumb_bit_length) - 1;
13870
13871
2.05k
      if (crumb_end_bit_offset > mask_greatest_bit_offset) {
13872
1.42k
        mask_greatest_bit_offset = crumb_end_bit_offset;
13873
1.42k
      }
13874
      /* Currently the bitmap of the crumbs are only shown if
13875
       * smaller than 32 bits. Do not bother calculating the
13876
       * mask if it is larger than that. */
13877
2.05k
      if (crumb_end_bit_offset <= 32) {
13878
2.05k
        composite_bitmask |= (crumb_mask  << (64 - crumb_end_bit_offset));
13879
2.05k
        composite_bitmap  |= (crumb_value << (64 - crumb_end_bit_offset));
13880
2.05k
      }
13881
2.05k
    }
13882
    /* Shift left for the next segment */
13883
2.06k
    value <<= crumb_spec[++i].crumb_bit_length;
13884
2.06k
  }
13885
13886
  /* Sign extend for signed types */
13887
1.03k
  switch (hf_field->type) {
13888
0
    case FT_INT8:
13889
0
    case FT_INT16:
13890
0
    case FT_INT24:
13891
0
    case FT_INT32:
13892
0
    case FT_INT40:
13893
0
    case FT_INT48:
13894
0
    case FT_INT56:
13895
0
    case FT_INT64:
13896
0
      value = ws_sign_ext64(value, no_of_bits);
13897
0
      break;
13898
1.01k
    default:
13899
1.01k
      break;
13900
1.03k
  }
13901
13902
1.01k
  if (return_value) {
13903
215
    *return_value = value;
13904
215
  }
13905
13906
  /* Coast clear. Try and fake it */
13907
1.01k
  CHECK_FOR_NULL_TREE(tree);
13908
1.01k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
13909
13910
  /* initialise the format string */
13911
978
  bf_str[0] = '\0';
13912
13913
978
  octet_offset = bit_offset >> 3;
13914
13915
  /* Round up mask length to nearest octet */
13916
978
  octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13917
978
  mask_greatest_bit_offset = octet_length << 3;
13918
13919
  /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13920
     It would be a useful enhancement to eliminate this restriction. */
13921
978
  if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13922
978
    other_decode_bitfield_value(bf_str,
13923
978
              (uint32_t)(composite_bitmap  >> (64 - mask_greatest_bit_offset)),
13924
978
              (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13925
978
              mask_greatest_bit_offset);
13926
978
  } else {
13927
    /* If the bitmask is too large, try to describe its contents. */
13928
0
    snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13929
0
  }
13930
13931
978
  switch (hf_field->type) {
13932
0
  case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13933
    /* Boolean field */
13934
0
    return proto_tree_add_boolean_format(tree, hfindex,
13935
0
                 tvb, octet_offset, octet_length, value,
13936
0
                 "%s = %s: %s",
13937
0
                 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13938
0
    break;
13939
13940
0
  case FT_CHAR:
13941
0
    pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13942
0
    fill_label_char(PITEM_FINFO(pi), lbl_str, NULL);
13943
0
    break;
13944
13945
206
  case FT_UINT8:
13946
932
  case FT_UINT16:
13947
932
  case FT_UINT24:
13948
978
  case FT_UINT32:
13949
978
    pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13950
978
    fill_label_number(PITEM_FINFO(pi), lbl_str, NULL, false);
13951
978
    break;
13952
13953
0
  case FT_INT8:
13954
0
  case FT_INT16:
13955
0
  case FT_INT24:
13956
0
  case FT_INT32:
13957
0
    pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13958
0
    fill_label_number(PITEM_FINFO(pi), lbl_str, NULL, true);
13959
0
    break;
13960
13961
0
  case FT_UINT40:
13962
0
  case FT_UINT48:
13963
0
  case FT_UINT56:
13964
0
  case FT_UINT64:
13965
0
    pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13966
0
    fill_label_number64(PITEM_FINFO(pi), lbl_str, NULL, false);
13967
0
    break;
13968
13969
0
  case FT_INT40:
13970
0
  case FT_INT48:
13971
0
  case FT_INT56:
13972
0
  case FT_INT64:
13973
0
    pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13974
0
    fill_label_number64(PITEM_FINFO(pi), lbl_str, NULL, true);
13975
0
    break;
13976
13977
0
  default:
13978
0
    REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_split_bits_item_ret_val()",
13979
0
             hf_field->abbrev,
13980
0
             hf_field->type,
13981
0
             ftype_name(hf_field->type));
13982
0
    return NULL;
13983
978
  }
13984
978
  proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13985
978
  return pi;
13986
978
}
13987
13988
void
13989
proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13990
        const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13991
203
{
13992
203
  header_field_info *hfinfo;
13993
203
  unsigned start = bit_offset >> 3;
13994
203
  unsigned length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13995
13996
  /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13997
   * so that we can use the tree's memory scope in calculating the string */
13998
203
  tvb_ensure_bytes_exist(tvb, start, length);
13999
203
  if (!tree) return;
14000
14001
203
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
14002
203
  proto_tree_add_text_internal(tree, tvb, start, length,
14003
203
          "%s crumb %d of %s (decoded above)",
14004
203
          decode_bits_in_field(PNODE_POOL(tree), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
14005
203
             tvb_get_bits32(tvb,
14006
203
                      bit_offset,
14007
203
                      crumb_spec[crumb_index].crumb_bit_length,
14008
203
                      ENC_BIG_ENDIAN),
14009
203
             ENC_BIG_ENDIAN),
14010
203
          crumb_index,
14011
203
          hfinfo->name);
14012
203
}
14013
14014
proto_item *
14015
proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14016
          const unsigned bit_offset, const int no_of_bits,
14017
          uint64_t *return_value, const unsigned encoding)
14018
2.08M
{
14019
2.08M
  proto_item *item;
14020
14021
2.08M
  if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
14022
2.08M
             bit_offset, no_of_bits,
14023
2.08M
             return_value, encoding))) {
14024
2.08M
    FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset&0x7));
14025
2.08M
    FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
14026
2.08M
  }
14027
2.08M
  return item;
14028
2.08M
}
14029
14030
static proto_item *
14031
_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14032
         tvbuff_t *tvb, const unsigned bit_offset,
14033
         const int no_of_bits, void *value_ptr,
14034
         const unsigned encoding, char *value_str)
14035
142k
{
14036
142k
  unsigned offset;
14037
142k
  unsigned length;
14038
142k
  uint8_t  tot_no_bits;
14039
142k
  char    *str;
14040
142k
  uint64_t value = 0;
14041
142k
  header_field_info *hf_field;
14042
14043
  /* We do not have to return a value, try to fake it as soon as possible */
14044
142k
  CHECK_FOR_NULL_TREE(tree);
14045
142k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
14046
14047
142k
  if (hf_field->bitmask != 0) {
14048
0
    REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_format_value"
14049
0
             " with field '%s' (%s) with bitmask != 0",
14050
0
             hf_field->abbrev, hf_field->name);
14051
0
  }
14052
14053
142k
  if (no_of_bits < 0) {
14054
0
    THROW(ReportedBoundsError);
14055
142k
  } else if (no_of_bits == 0) {
14056
2
    REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_format_value() has a bit width of 0",
14057
2
             hf_field->abbrev);
14058
2
  }
14059
14060
  /* Byte align offset */
14061
142k
  offset = bit_offset>>3;
14062
14063
  /*
14064
   * Calculate the number of octets used to hold the bits
14065
   */
14066
142k
  tot_no_bits = ((bit_offset&0x7) + no_of_bits);
14067
142k
  length      = tot_no_bits>>3;
14068
  /* If we are using part of the next octet, increase length by 1 */
14069
142k
  if (tot_no_bits & 0x07)
14070
52.3k
    length++;
14071
14072
142k
  if (no_of_bits < 65) {
14073
142k
    value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
14074
142k
  } else {
14075
2
    REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_format_value() has a bit width of %u > 65",
14076
2
             hf_field->abbrev, no_of_bits);
14077
2
    return NULL;
14078
2
  }
14079
14080
142k
  str = decode_bits_in_field(PNODE_POOL(tree), bit_offset, no_of_bits, value, encoding);
14081
14082
142k
  (void) g_strlcat(str, " = ", 256+64);
14083
142k
  (void) g_strlcat(str, hf_field->name, 256+64);
14084
14085
  /*
14086
   * This function does not receive an actual value but a dimensionless pointer to that value.
14087
   * For this reason, the type of the header field is examined in order to determine
14088
   * what kind of value we should read from this address.
14089
   * The caller of this function must make sure that for the specific header field type the address of
14090
   * a compatible value is provided.
14091
   */
14092
142k
  switch (hf_field->type) {
14093
0
  case FT_BOOLEAN:
14094
0
    return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
14095
0
                 "%s: %s", str, value_str);
14096
0
    break;
14097
14098
0
  case FT_CHAR:
14099
122k
  case FT_UINT8:
14100
122k
  case FT_UINT16:
14101
122k
  case FT_UINT24:
14102
134k
  case FT_UINT32:
14103
134k
    return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
14104
134k
              "%s: %s", str, value_str);
14105
0
    break;
14106
14107
0
  case FT_UINT40:
14108
0
  case FT_UINT48:
14109
0
  case FT_UINT56:
14110
0
  case FT_UINT64:
14111
0
    return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
14112
0
                "%s: %s", str, value_str);
14113
0
    break;
14114
14115
0
  case FT_INT8:
14116
0
  case FT_INT16:
14117
0
  case FT_INT24:
14118
0
  case FT_INT32:
14119
0
    return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
14120
0
             "%s: %s", str, value_str);
14121
0
    break;
14122
14123
0
  case FT_INT40:
14124
0
  case FT_INT48:
14125
0
  case FT_INT56:
14126
7.63k
  case FT_INT64:
14127
7.63k
    return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
14128
7.63k
               "%s: %s", str, value_str);
14129
0
    break;
14130
14131
0
  case FT_FLOAT:
14132
0
    return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
14133
0
               "%s: %s", str, value_str);
14134
0
    break;
14135
14136
0
  default:
14137
0
    REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_bits_format_value()",
14138
0
             hf_field->abbrev,
14139
0
             hf_field->type,
14140
0
             ftype_name(hf_field->type));
14141
0
    return NULL;
14142
142k
  }
14143
142k
}
14144
14145
static proto_item *
14146
proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14147
         tvbuff_t *tvb, const unsigned bit_offset,
14148
         const int no_of_bits, void *value_ptr,
14149
         const unsigned encoding, char *value_str)
14150
142k
{
14151
142k
  proto_item *item;
14152
14153
142k
  if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
14154
142k
                  tvb, bit_offset, no_of_bits,
14155
142k
                  value_ptr, encoding, value_str))) {
14156
142k
    FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset&0x7));
14157
142k
    FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
14158
142k
  }
14159
142k
  return item;
14160
142k
}
14161
14162
#define CREATE_VALUE_STRING(tree,dst,format,ap) \
14163
142k
  va_start(ap, format); \
14164
142k
  dst = wmem_strdup_vprintf(PNODE_POOL(tree), format, ap); \
14165
142k
  va_end(ap);
14166
14167
proto_item *
14168
proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
14169
              tvbuff_t *tvb, const unsigned bit_offset,
14170
              const int no_of_bits, uint32_t value,
14171
              const unsigned encoding,
14172
              const char *format, ...)
14173
152k
{
14174
152k
  va_list ap;
14175
152k
  char   *dst;
14176
152k
  header_field_info *hf_field;
14177
14178
152k
  CHECK_FOR_NULL_TREE(tree);
14179
14180
152k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
14181
14182
134k
  switch (hf_field->type) {
14183
122k
    case FT_UINT8:
14184
122k
    case FT_UINT16:
14185
122k
    case FT_UINT24:
14186
134k
    case FT_UINT32:
14187
134k
      break;
14188
14189
0
    default:
14190
0
      REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
14191
0
          hf_field->abbrev);
14192
0
      return NULL;
14193
134k
  }
14194
14195
134k
  CREATE_VALUE_STRING(tree, dst, format, ap);
14196
14197
134k
  return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14198
134k
}
14199
14200
proto_item *
14201
proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14202
              tvbuff_t *tvb, const unsigned bit_offset,
14203
              const int no_of_bits, uint64_t value,
14204
              const unsigned encoding,
14205
              const char *format, ...)
14206
60
{
14207
60
  va_list ap;
14208
60
  char   *dst;
14209
60
  header_field_info *hf_field;
14210
14211
60
  CHECK_FOR_NULL_TREE(tree);
14212
14213
60
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
14214
14215
60
  switch (hf_field->type) {
14216
0
    case FT_UINT40:
14217
0
    case FT_UINT48:
14218
0
    case FT_UINT56:
14219
0
    case FT_UINT64:
14220
0
      break;
14221
14222
60
    default:
14223
60
      REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",
14224
60
          hf_field->abbrev);
14225
60
      return NULL;
14226
60
  }
14227
14228
60
  CREATE_VALUE_STRING(tree, dst, format, ap);
14229
14230
0
  return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14231
60
}
14232
14233
proto_item *
14234
proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14235
               tvbuff_t *tvb, const unsigned bit_offset,
14236
               const int no_of_bits, float value,
14237
               const unsigned encoding,
14238
               const char *format, ...)
14239
0
{
14240
0
  va_list ap;
14241
0
  char   *dst;
14242
0
  header_field_info *hf_field;
14243
14244
0
  CHECK_FOR_NULL_TREE(tree);
14245
14246
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
14247
14248
0
  DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
14249
14250
0
  CREATE_VALUE_STRING(tree, dst, format, ap);
14251
14252
0
  return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14253
0
}
14254
14255
proto_item *
14256
proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14257
             tvbuff_t *tvb, const unsigned bit_offset,
14258
             const int no_of_bits, int32_t value,
14259
                               const unsigned encoding,
14260
             const char *format, ...)
14261
0
{
14262
0
  va_list ap;
14263
0
  char   *dst;
14264
0
  header_field_info *hf_field;
14265
14266
0
  CHECK_FOR_NULL_TREE(tree);
14267
14268
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
14269
14270
0
  switch (hf_field->type) {
14271
0
    case FT_INT8:
14272
0
    case FT_INT16:
14273
0
    case FT_INT24:
14274
0
    case FT_INT32:
14275
0
      break;
14276
14277
0
    default:
14278
0
      REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
14279
0
          hf_field->abbrev);
14280
0
      return NULL;
14281
0
  }
14282
14283
0
  CREATE_VALUE_STRING(tree, dst, format, ap);
14284
14285
0
  return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14286
0
}
14287
14288
proto_item *
14289
proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14290
             tvbuff_t *tvb, const unsigned bit_offset,
14291
             const int no_of_bits, int64_t value,
14292
             const unsigned encoding,
14293
             const char *format, ...)
14294
8.47k
{
14295
8.47k
  va_list ap;
14296
8.47k
  char   *dst;
14297
8.47k
  header_field_info *hf_field;
14298
14299
8.47k
  CHECK_FOR_NULL_TREE(tree);
14300
14301
7.63k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
14302
14303
7.63k
  switch (hf_field->type) {
14304
0
    case FT_INT40:
14305
0
    case FT_INT48:
14306
0
    case FT_INT56:
14307
7.63k
    case FT_INT64:
14308
7.63k
      break;
14309
14310
0
    default:
14311
0
      REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
14312
0
          hf_field->abbrev);
14313
0
      return NULL;
14314
7.63k
  }
14315
14316
7.63k
  CREATE_VALUE_STRING(tree, dst, format, ap);
14317
14318
7.63k
  return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14319
7.63k
}
14320
14321
proto_item *
14322
proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14323
           tvbuff_t *tvb, const unsigned bit_offset,
14324
           const int no_of_bits, uint64_t value,
14325
                 const unsigned encoding,
14326
           const char *format, ...)
14327
0
{
14328
0
  va_list ap;
14329
0
  char   *dst;
14330
0
  header_field_info *hf_field;
14331
14332
0
  CHECK_FOR_NULL_TREE(tree);
14333
14334
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
14335
14336
0
  DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
14337
14338
0
  CREATE_VALUE_STRING(tree, dst, format, ap);
14339
14340
0
  return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14341
0
}
14342
14343
proto_item *
14344
proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14345
  const unsigned bit_offset, const int no_of_chars)
14346
95
{
14347
95
  proto_item    *pi;
14348
95
  header_field_info *hfinfo;
14349
95
  int      byte_length;
14350
95
  unsigned     byte_offset;
14351
95
  char      *string;
14352
14353
95
  CHECK_FOR_NULL_TREE(tree);
14354
14355
95
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
14356
14357
23
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
14358
14359
23
  byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14360
23
  byte_offset = bit_offset >> 3;
14361
14362
23
  string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree), tvb, bit_offset, no_of_chars);
14363
14364
23
  pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14365
23
  DISSECTOR_ASSERT(byte_length >= 0);
14366
23
  proto_tree_set_string(PNODE_FINFO(pi), string);
14367
14368
23
  return pi;
14369
95
}
14370
14371
proto_item *
14372
proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14373
  const unsigned bit_offset, const int no_of_chars)
14374
0
{
14375
0
  proto_item    *pi;
14376
0
  header_field_info *hfinfo;
14377
0
  int      byte_length;
14378
0
  unsigned     byte_offset;
14379
0
  char      *string;
14380
14381
0
  CHECK_FOR_NULL_TREE(tree);
14382
14383
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
14384
14385
0
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
14386
14387
0
  byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14388
0
  byte_offset = bit_offset >> 3;
14389
14390
0
  string = tvb_get_ascii_7bits_string(PNODE_POOL(tree), tvb, bit_offset, no_of_chars);
14391
14392
0
  pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14393
0
  DISSECTOR_ASSERT(byte_length >= 0);
14394
0
  proto_tree_set_string(PNODE_FINFO(pi), string);
14395
14396
0
  return pi;
14397
0
}
14398
14399
const value_string proto_checksum_vals[] = {
14400
  { PROTO_CHECKSUM_E_BAD,        "Bad"  },
14401
  { PROTO_CHECKSUM_E_GOOD,       "Good" },
14402
  { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14403
  { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14404
  { PROTO_CHECKSUM_E_ILLEGAL,    "Illegal" },
14405
14406
  { 0,        NULL }
14407
};
14408
14409
#define PROTO_CHECKSUM_COMPUTED_USED (PROTO_CHECKSUM_VERIFY|PROTO_CHECKSUM_GENERATED|PROTO_CHECKSUM_NOT_PRESENT)
14410
14411
proto_item *
14412
proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14413
    const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14414
    packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14415
211k
{
14416
211k
  header_field_info *hfinfo;
14417
211k
  uint32_t checksum;
14418
211k
  uint32_t len;
14419
211k
  proto_item* ti = NULL;
14420
211k
  proto_item* ti2;
14421
211k
  bool incorrect_checksum = true;
14422
14423
211k
  PROTO_REGISTRAR_GET_NTH(hf_checksum, hfinfo);
14424
14425
211k
  switch (hfinfo->type) {
14426
1.36k
  case FT_UINT8:
14427
1.36k
    len = 1;
14428
1.36k
    break;
14429
171k
  case FT_UINT16:
14430
171k
    len = 2;
14431
171k
    break;
14432
41
  case FT_UINT24:
14433
41
    len = 3;
14434
41
    break;
14435
38.7k
  case FT_UINT32:
14436
38.7k
    len = 4;
14437
38.7k
    break;
14438
0
  default:
14439
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
14440
211k
        hfinfo->abbrev);
14441
211k
  }
14442
14443
211k
  if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
14444
706
    ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14445
706
    proto_item_set_generated(ti);
14446
    // Backward compatible with use of -1
14447
706
    if (hf_checksum_status > 0) {
14448
687
      ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14449
687
      proto_item_set_generated(ti2);
14450
687
    }
14451
706
    return ti;
14452
706
  }
14453
14454
210k
  if (flags & PROTO_CHECKSUM_GENERATED) {
14455
0
    ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14456
0
    proto_item_set_generated(ti);
14457
210k
  } else {
14458
210k
    ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14459
210k
    if (flags & PROTO_CHECKSUM_VERIFY) {
14460
15.0k
      if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) {
14461
8.60k
        if (computed_checksum == 0) {
14462
42
          proto_item_append_text(ti, " [correct]");
14463
          // Backward compatible with use of -1
14464
42
          if (hf_checksum_status > 0) {
14465
42
            ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14466
42
            proto_item_set_generated(ti2);
14467
42
          }
14468
42
          incorrect_checksum = false;
14469
8.56k
        } else if (flags & PROTO_CHECKSUM_IN_CKSUM) {
14470
8.19k
          computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14471
          /* XXX - This can't distinguish between "shouldbe"
14472
           * 0x0000 and 0xFFFF unless we know whether there
14473
           * were any nonzero bits (other than the checksum).
14474
           * Protocols should not use this path if they might
14475
           * have an all zero packet.
14476
           * Some implementations put the wrong zero; maybe
14477
           * we should have a special expert info for that?
14478
           */
14479
8.19k
        }
14480
8.60k
      } else {
14481
6.43k
        if (checksum == computed_checksum) {
14482
22
          proto_item_append_text(ti, " [correct]");
14483
          // Backward compatible with use of -1
14484
22
          if (hf_checksum_status > 0) {
14485
10
            ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14486
10
            proto_item_set_generated(ti2);
14487
10
          }
14488
22
          incorrect_checksum = false;
14489
22
        }
14490
6.43k
      }
14491
14492
15.0k
      if (incorrect_checksum) {
14493
        // Backward compatible with use of -1
14494
14.9k
        if (hf_checksum_status > 0) {
14495
14.8k
          ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14496
14.8k
          proto_item_set_generated(ti2);
14497
14.8k
        }
14498
14.9k
        if (flags & PROTO_CHECKSUM_ZERO) {
14499
367
          proto_item_append_text(ti, " [incorrect]");
14500
367
          if (bad_checksum_expert != NULL)
14501
367
            expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14502
14.6k
        } else {
14503
14.6k
          proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14504
14.6k
          if (bad_checksum_expert != NULL)
14505
14.4k
            expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%0*x]", expert_get_summary(bad_checksum_expert), len * 2, computed_checksum);
14506
14.6k
        }
14507
14.9k
      }
14508
195k
    } else {
14509
      // Backward compatible with use of -1
14510
195k
      if (hf_checksum_status > 0) {
14511
185k
        proto_item_append_text(ti, " [unverified]");
14512
185k
        ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14513
185k
        proto_item_set_generated(ti2);
14514
185k
      }
14515
195k
    }
14516
210k
  }
14517
14518
210k
  return ti;
14519
211k
}
14520
14521
proto_item *
14522
proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14523
    const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14524
    packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14525
73
{
14526
73
  header_field_info *hfinfo;
14527
73
  uint8_t *checksum = NULL;
14528
73
  proto_item* ti = NULL;
14529
73
  proto_item* ti2;
14530
73
  bool incorrect_checksum = true;
14531
14532
73
  PROTO_REGISTRAR_GET_NTH(hf_checksum, hfinfo);
14533
14534
73
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
14535
14536
  /* Make sure a NULL computed_checksum isn't dereferenced.
14537
   * If checksum_len is 0 it probably won't crash, but in the VERIFY
14538
   * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14539
   * cases the behavior is unexpected and still a programmer error;
14540
   * proto_tree_add_bytes retrieves it from the tvb, thus neither
14541
   * _NOT_PRESENT nor _GENERATED is correct.
14542
   */
14543
73
  DISSECTOR_ASSERT(computed_checksum || ((flags & PROTO_CHECKSUM_COMPUTED_USED) == PROTO_CHECKSUM_NO_FLAGS));
14544
14545
73
  if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
14546
0
    ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14547
0
    proto_item_set_generated(ti);
14548
    // Backward compatible with use of -1
14549
0
    if (hf_checksum_status > 0) {
14550
0
      ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14551
0
      proto_item_set_generated(ti2);
14552
0
    }
14553
0
    return ti;
14554
0
  }
14555
14556
73
  if (flags & PROTO_CHECKSUM_GENERATED) {
14557
0
    ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14558
0
    proto_item_set_generated(ti);
14559
0
    return ti;
14560
0
  }
14561
14562
73
  checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14563
73
  ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14564
73
  if (flags & PROTO_CHECKSUM_VERIFY) {
14565
0
    if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) {
14566
0
      bool non_zero_flag = false;
14567
0
      for (size_t index = 0; index < checksum_len; index++) {
14568
0
        if (computed_checksum[index]) {
14569
0
          non_zero_flag = true;
14570
0
          break;
14571
0
        }
14572
0
      }
14573
0
      if (!non_zero_flag) {
14574
0
        proto_item_append_text(ti, " [correct]");
14575
        // Backward compatible with use of -1
14576
0
        if (hf_checksum_status > 0) {
14577
0
          ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14578
0
          proto_item_set_generated(ti2);
14579
0
        }
14580
0
        incorrect_checksum = false;
14581
0
      }
14582
0
    } else {
14583
0
      if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14584
0
        proto_item_append_text(ti, " [correct]");
14585
        // Backward compatible with use of -1
14586
0
        if (hf_checksum_status > 0) {
14587
0
          ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14588
0
          proto_item_set_generated(ti2);
14589
0
        }
14590
0
        incorrect_checksum = false;
14591
0
      }
14592
0
    }
14593
14594
0
    if (incorrect_checksum) {
14595
      // Backward compatible with use of -1
14596
0
      if (hf_checksum_status > 0) {
14597
0
        ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14598
0
        proto_item_set_generated(ti2);
14599
0
      }
14600
0
      if (flags & PROTO_CHECKSUM_ZERO) {
14601
0
        proto_item_append_text(ti, " [incorrect]");
14602
0
        if (bad_checksum_expert != NULL)
14603
0
          expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14604
0
      } else {
14605
0
        char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14606
0
        proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14607
0
        if (bad_checksum_expert != NULL)
14608
0
          expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14609
0
      }
14610
0
    }
14611
73
  } else {
14612
    // Backward compatible with use of -1
14613
73
    if (hf_checksum_status > 0) {
14614
0
      proto_item_append_text(ti, " [unverified]");
14615
0
      ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14616
0
      proto_item_set_generated(ti2);
14617
0
    }
14618
73
  }
14619
14620
73
  return ti;
14621
73
}
14622
14623
unsigned char
14624
proto_check_field_name(const char *field_name)
14625
96.8k
{
14626
96.8k
  return module_check_valid_name(field_name, false);
14627
96.8k
}
14628
14629
unsigned char
14630
proto_check_field_name_lower(const char *field_name)
14631
7.12k
{
14632
7.12k
  return module_check_valid_name(field_name, true);
14633
7.12k
}
14634
14635
bool
14636
tree_expanded(int tree_type)
14637
0
{
14638
0
  if (tree_type <= 0) {
14639
0
    return false;
14640
0
  }
14641
0
  ws_assert(tree_type >= 0 && tree_type < num_tree_types);
14642
0
  return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14643
0
}
14644
14645
void
14646
tree_expanded_set(int tree_type, bool value)
14647
165
{
14648
165
  ws_assert(tree_type >= 0 && tree_type < num_tree_types);
14649
14650
165
  if (value)
14651
165
    tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14652
0
  else
14653
0
    tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14654
165
}
14655
14656
/*
14657
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
14658
 *
14659
 * Local variables:
14660
 * c-basic-offset: 8
14661
 * tab-width: 8
14662
 * indent-tabs-mode: t
14663
 * End:
14664
 *
14665
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14666
 * :indentSize=8:tabSize=8:noTabs=false:
14667
 */