Coverage Report

Created: 2026-05-14 06:28

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
134
#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
193
#define SUBTREE_ONCE_ALLOCATION_NUMBER 8
62
#define SUBTREE_MAX_LEVELS 256
63
64
typedef struct __subtree_lvl {
65
  int         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
95.8M
  if (!tree) {             \
88
4.26M
    free_block;           \
89
4.26M
    return NULL;            \
90
4.26M
  }
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
95.8M
  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 lower -1 or equal 0 */
102
#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block) \
103
34.5k
  if (length < -1 || length == 0 ) {       \
104
2.95k
    cleanup_block;           \
105
1.47k
    return NULL;            \
106
1.47k
  }
107
108
/** See inlined comments.
109
 @param length the length of this item
110
 @return NULL if 'length' is lower -1 or equal 0 */
111
#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length) \
112
  CHECK_FOR_ZERO_OR_MINUS_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
91.6M
  PTREE_DATA(tree)->count++;          \
135
91.6M
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);      \
136
91.6M
  if (PTREE_DATA(tree)->count > prefs.gui_max_tree_items) { \
137
31
    free_block;           \
138
31
    if (wireshark_abort_on_too_many_items) \
139
31
      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
31
          hfinfo->abbrev, prefs.gui_max_tree_items);  \
141
31
    /* Let the exception handler add items to the tree */ \
142
31
    PTREE_DATA(tree)->count = 0;        \
143
31
    THROW_MESSAGE(DissectorError,        \
144
31
      wmem_strdup_printf(PNODE_POOL(tree),    \
145
31
          "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
31
          hfinfo->abbrev, prefs.gui_max_tree_items)); \
147
31
  }                \
148
91.6M
  if (!(PTREE_DATA(tree)->visible)) {       \
149
54.1M
    if (PROTO_ITEM_IS_HIDDEN(tree)) {     \
150
54.1M
      if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT)  \
151
54.1M
          && (hfinfo->ref_type != HF_REF_TYPE_PRINT)  \
152
54.1M
          && (hfinfo->type != FT_PROTOCOL ||   \
153
54.1M
        PTREE_DATA(tree)->fake_protocols)) { \
154
54.1M
        free_block;       \
155
54.1M
        /* return fake node with no field info */\
156
54.1M
        return proto_tree_add_fake_node(tree, hfinfo);  \
157
54.1M
      }           \
158
54.1M
    }             \
159
54.1M
  }
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
91.6M
  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
9.76M
  ws_assert(pi);     \
174
9.76M
  if (!PITEM_FINFO(pi))   \
175
9.76M
    return pi;   \
176
9.76M
  if (!(PTREE_DATA(pi)->visible) && \
177
9.36M
        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
11.8M
  if (!pi || !PITEM_FINFO(pi)) \
185
11.8M
    return;     \
186
11.8M
  if (!(PTREE_DATA(pi)->visible) && \
187
7.49M
        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
95.0k
  if ((pi == NULL) || (PITEM_FINFO(pi) == NULL) || (!(PTREE_DATA(pi)->visible) && \
195
81.8k
    PROTO_ITEM_IS_HIDDEN(pi))) { \
196
12.3k
    /* If the tree (GUI) or item isn't visible it's pointless for \
197
12.3k
     * us to generate the protocol item's string representation */ \
198
12.3k
    return pi; \
199
12.3k
  }
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
1.38M
#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
9.90M
  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 int 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 int 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 int 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
      int start, int *length);
300
301
static void
302
proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
303
static void
304
proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
305
306
static void
307
proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
308
static void
309
proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
310
static void
311
proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
312
static void
313
proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
314
static void
315
proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
316
static void
317
proto_tree_set_string(field_info *fi, const char* value);
318
static void
319
proto_tree_set_ax25(field_info *fi, const uint8_t* value);
320
static void
321
proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
322
static void
323
proto_tree_set_vines(field_info *fi, const uint8_t* value);
324
static void
325
proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
326
static void
327
proto_tree_set_ether(field_info *fi, const uint8_t* value);
328
static void
329
proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
330
static void
331
proto_tree_set_ipxnet(field_info *fi, uint32_t value);
332
static void
333
proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
334
static void
335
proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
336
static void
337
proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
338
static void
339
proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
340
static void
341
proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
342
static void
343
proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
344
static void
345
proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
346
static void
347
proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
348
static void
349
proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
350
static void
351
proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
352
static void
353
proto_tree_set_boolean(field_info *fi, uint64_t value);
354
static void
355
proto_tree_set_float(field_info *fi, float value);
356
static void
357
proto_tree_set_double(field_info *fi, double value);
358
static void
359
proto_tree_set_uint(field_info *fi, uint32_t value);
360
static void
361
proto_tree_set_int(field_info *fi, int32_t value);
362
static void
363
proto_tree_set_uint64(field_info *fi, uint64_t value);
364
static void
365
proto_tree_set_int64(field_info *fi, int64_t value);
366
static void
367
proto_tree_set_eui64(field_info *fi, const uint64_t value);
368
static void
369
proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
370
371
/* Handle type length mismatch (now filterable) expert info */
372
static int proto_type_length_mismatch;
373
static expert_field ei_type_length_mismatch_error;
374
static expert_field ei_type_length_mismatch_warn;
375
static void register_type_length_mismatch(void);
376
377
/* Handle byte array string decoding errors with expert info */
378
static int proto_byte_array_string_decoding_error;
379
static expert_field ei_byte_array_string_decoding_failed_error;
380
static void register_byte_array_string_decodinws_error(void);
381
382
/* Handle date and time string decoding errors with expert info */
383
static int proto_date_time_string_decoding_error;
384
static expert_field ei_date_time_string_decoding_failed_error;
385
static void register_date_time_string_decodinws_error(void);
386
387
/* Handle string errors expert info */
388
static int proto_string_errors;
389
static expert_field ei_string_trailing_characters;
390
static void register_string_errors(void);
391
392
static int proto_register_field_init(header_field_info *hfinfo, const int parent);
393
394
/* special-case header field used within proto.c */
395
static header_field_info hfi_text_only =
396
  { "Text item",  "text", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL };
397
int hf_text_only;
398
399
/* Structure for information about a protocol */
400
struct _protocol {
401
  const char *name;               /* long description */
402
  const char *short_name;         /* short description */
403
  const char *filter_name;        /* name of this protocol in filters */
404
  GPtrArray  *fields;             /* fields for this protocol */
405
  int         proto_id;           /* field ID for this protocol */
406
  bool        is_enabled;         /* true if protocol is enabled */
407
  bool        enabled_by_default; /* true if protocol is enabled by default */
408
  bool        can_toggle;         /* true if is_enabled can be changed */
409
  int         parent_proto_id;    /* Used to identify "pino"s (Protocol In Name Only).
410
                                     For dissectors that need a protocol name so they
411
                                     can be added to a dissector table, but use the
412
                                     parent_proto_id for things like enable/disable */
413
  GList      *heur_list;          /* Heuristic dissectors associated with this protocol */
414
};
415
416
/* List of all protocols */
417
static GList *protocols;
418
419
/* Structure stored for deregistered g_slice */
420
struct g_slice_data {
421
  size_t   block_size;
422
  void *mem_block;
423
};
424
425
/* Deregistered fields */
426
static GPtrArray *deregistered_fields;
427
static GPtrArray *deregistered_data;
428
static GPtrArray *deregistered_slice;
429
430
/* indexed by prefix, contains initializers */
431
static GHashTable* prefixes;
432
433
/* Contains information about a field when a dissector calls
434
 * proto_tree_add_item.  */
435
35.4M
#define FIELD_INFO_NEW(pool, fi)  fi = wmem_new(pool, field_info)
436
#define FIELD_INFO_FREE(pool, fi) wmem_free(pool, fi)
437
438
/* Contains the space for proto_nodes. */
439
#define PROTO_NODE_INIT(node)     \
440
89.7M
  node->first_child = NULL;   \
441
89.7M
  node->last_child = NULL;    \
442
89.7M
  node->next = NULL;
443
444
#define PROTO_NODE_FREE(pool, node)     \
445
  wmem_free(pool, node)
446
447
/* String space for protocol and field items for the GUI */
448
#define ITEM_LABEL_NEW(pool, il)      \
449
14.3M
  il = wmem_new(pool, item_label_t);   \
450
14.3M
  il->value_pos = 0;        \
451
14.3M
  il->value_len = 0;
452
#define ITEM_LABEL_FREE(pool, il)     \
453
12.5k
  wmem_free(pool, il);
454
455
#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)            \
456
160M
  if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
457
160M
    ws_error("Unregistered hf! index=%d", hfindex);         \
458
160M
  DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!"); \
459
160M
  DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!"); \
460
160M
  hfinfo = gpa_hfinfo.hfi[hfindex];
461
462
45
#define PROTO_PRE_ALLOC_HF_FIELDS_MEM (300000+PRE_ALLOC_EXPERT_FIELDS_MEM)
463
464
/* List which stores protocols and fields that have been registered */
465
typedef struct _gpa_hfinfo_t {
466
  uint32_t            len;
467
  uint32_t            allocated_len;
468
  header_field_info **hfi;
469
} gpa_hfinfo_t;
470
471
static gpa_hfinfo_t gpa_hfinfo;
472
473
/* Hash table of abbreviations and IDs */
474
static wmem_map_t *gpa_name_map;
475
static header_field_info *same_name_hfinfo;
476
477
/* Hash table protocol aliases. const char * -> const char * */
478
static GHashTable *gpa_protocol_aliases;
479
480
/*
481
 * We're called repeatedly with the same field name when sorting a column.
482
 * Cache our last gpa_name_map hit for faster lookups.
483
 */
484
static char *last_field_name;
485
static header_field_info *last_hfinfo;
486
487
/* Points to the first element of an array of bits, indexed by
488
   a subtree item type; that array element is true if subtrees of
489
   an item of that type are to be expanded. */
490
static uint32_t *tree_is_expanded;
491
492
/* Number of elements in that array. The entry with index 0 is not used. */
493
int   num_tree_types = 1;
494
495
/* Name hashtables for fast detection of duplicate names */
496
static GHashTable* proto_names;
497
static GHashTable* proto_short_names;
498
static GHashTable* proto_filter_names;
499
500
static const char * const reserved_filter_names[] = {
501
  /* Display filter keywords. */
502
  "eq",
503
  "ne",
504
  "all_eq",
505
  "any_eq",
506
  "all_ne",
507
  "any_ne",
508
  "gt",
509
  "ge",
510
  "lt",
511
  "le",
512
  "bitand",
513
  "bitwise_and",
514
  "contains",
515
  "matches",
516
  "not",
517
  "and",
518
  "or",
519
  "xor",
520
  "in",
521
  "any",
522
  "all",
523
  "true",
524
  "false",
525
  "nan",
526
  "inf",
527
  "infinity",
528
  NULL
529
};
530
531
static GHashTable *proto_reserved_filter_names;
532
static GQueue* saved_dir_queue;
533
534
static int
535
proto_compare_name(const void *p1_arg, const void *p2_arg)
536
443k
{
537
443k
  const protocol_t *p1 = (const protocol_t *)p1_arg;
538
443k
  const protocol_t *p2 = (const protocol_t *)p2_arg;
539
540
443k
  return g_ascii_strcasecmp(p1->short_name, p2->short_name);
541
443k
}
542
543
static GSList *dissector_plugins;
544
545
#ifdef HAVE_PLUGINS
546
void
547
proto_register_plugin(const proto_plugin *plug)
548
{
549
  dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
550
}
551
#else /* HAVE_PLUGINS */
552
void
553
proto_register_plugin(const proto_plugin *plug _U_)
554
0
{
555
0
  ws_warning("proto_register_plugin: built without support for binary plugins");
556
0
}
557
#endif /* HAVE_PLUGINS */
558
559
static void
560
call_plugin_register_protoinfo(void *data, void *user_data _U_)
561
0
{
562
0
  proto_plugin *plug = (proto_plugin *)data;
563
564
0
  if (plug->register_protoinfo) {
565
0
    plug->register_protoinfo();
566
0
  }
567
0
}
568
569
static void
570
call_plugin_register_handoff(void *data, void *user_data _U_)
571
0
{
572
0
  proto_plugin *plug = (proto_plugin *)data;
573
574
0
  if (plug->register_handoff) {
575
0
    plug->register_handoff();
576
0
  }
577
0
}
578
579
void proto_pre_init(void)
580
15
{
581
15
  saved_dir_queue = g_queue_new();
582
583
15
  proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
584
15
  proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
585
15
  proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
586
587
15
  proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588
405
  for (const char* const * ptr = reserved_filter_names; *ptr != NULL; ptr++) {
589
    /* GHashTable has no key destructor so the cast is safe. */
590
390
    g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
591
390
  }
592
593
15
  gpa_hfinfo.len = 0;
594
15
  gpa_hfinfo.allocated_len = 0;
595
15
  gpa_hfinfo.hfi = NULL;
596
15
  gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
597
15
  wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM);
598
15
  gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
599
15
  deregistered_fields = g_ptr_array_new();
600
15
  deregistered_data = g_ptr_array_new();
601
15
  deregistered_slice = g_ptr_array_new();
602
15
}
603
604
/* initialize data structures and register protocols and fields */
605
void
606
proto_init(GSList *register_all_plugin_protocols_list,
607
     GSList *register_all_plugin_handoffs_list,
608
     register_entity_func register_func, register_entity_func handoff_func,
609
     register_cb cb,
610
     void *client_data)
611
15
{
612
  /* Initialize the ftype subsystem */
613
15
  ftypes_initialize();
614
615
  /* Initialize the address type subsystem */
616
15
  address_types_initialize();
617
618
  /* Register one special-case FT_TEXT_ONLY field for use when
619
     converting wireshark to new-style proto_tree. These fields
620
     are merely strings on the GUI tree; they are not filterable */
621
15
  hf_text_only = proto_register_field_init(&hfi_text_only, -1);
622
623
  /* Register the pseudo-protocols used for exceptions. */
624
15
  register_show_exception();
625
15
  register_type_length_mismatch();
626
15
  register_byte_array_string_decodinws_error();
627
15
  register_date_time_string_decodinws_error();
628
15
  register_string_errors();
629
15
  ftypes_register_pseudofields();
630
15
  col_register_protocol();
631
632
  /* Have each built-in dissector register its protocols, fields,
633
     dissector tables, and dissectors to be called through a
634
     handle, and do whatever one-time initialization it needs to
635
     do. */
636
15
  if (register_func != NULL)
637
15
    register_func(cb, client_data);
638
639
  /* Now call the registration routines for all epan plugins. */
640
15
  for (GSList *l = register_all_plugin_protocols_list; l != NULL; l = l->next) {
641
0
    ((void (*)(register_cb, void *))l->data)(cb, client_data);
642
0
  }
643
644
  /* Now call the registration routines for all dissector plugins. */
645
15
  if (cb)
646
0
    (*cb)(RA_PLUGIN_REGISTER, NULL, client_data);
647
15
  g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL);
648
649
  /* Now call the "handoff registration" routines of all built-in
650
     dissectors; those routines register the dissector in other
651
     dissectors' handoff tables, and fetch any dissector handles
652
     they need. */
653
15
  if (handoff_func != NULL)
654
15
    handoff_func(cb, client_data);
655
656
  /* Now do the same with epan plugins. */
657
15
  for (GSList *l = register_all_plugin_handoffs_list; l != NULL; l = l->next) {
658
0
    ((void (*)(register_cb, void *))l->data)(cb, client_data);
659
0
  }
660
661
  /* Now do the same with dissector plugins. */
662
15
  if (cb)
663
0
    (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data);
664
15
  g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL);
665
666
  /* sort the protocols by protocol name */
667
15
  protocols = g_list_sort(protocols, proto_compare_name);
668
669
  /* sort the dissector handles in dissector tables (for -G reports
670
   * and -d error messages. The GUI sorts the handles itself.) */
671
15
  packet_all_tables_sort_handles();
672
673
  /* We've assigned all the subtree type values; allocate the array
674
     for them, and zero it out. */
675
15
  tree_is_expanded = g_new0(uint32_t, (num_tree_types/32)+1);
676
15
}
677
678
static void
679
proto_cleanup_base(void)
680
0
{
681
0
  protocol_t *protocol;
682
0
  header_field_info *hfinfo;
683
684
  /* Free the abbrev/ID hash table */
685
0
  if (gpa_name_map) {
686
    // XXX - We don't have a wmem_map_destroy, but
687
    // it does get cleaned up when epan scope is
688
    // destroyed
689
    //g_hash_table_destroy(gpa_name_map);
690
0
    gpa_name_map = NULL;
691
0
  }
692
0
  if (gpa_protocol_aliases) {
693
0
    g_hash_table_destroy(gpa_protocol_aliases);
694
0
    gpa_protocol_aliases = NULL;
695
0
  }
696
0
  g_free(last_field_name);
697
0
  last_field_name = NULL;
698
699
0
  while (protocols) {
700
0
    protocol = (protocol_t *)protocols->data;
701
0
    PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo);
702
0
    DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id);
703
704
0
    g_slice_free(header_field_info, hfinfo);
705
0
    if (protocol->parent_proto_id != -1) {
706
      // pino protocol
707
0
      DISSECTOR_ASSERT(protocol->fields == NULL); //helpers should not have any registered fields
708
0
      DISSECTOR_ASSERT(protocol->heur_list == NULL); //helpers should not have a heuristic list
709
0
    } else {
710
0
      if (protocol->fields) {
711
0
        g_ptr_array_free(protocol->fields, true);
712
0
      }
713
0
      g_list_free(protocol->heur_list);
714
0
    }
715
0
    protocols = g_list_remove(protocols, protocol);
716
0
    g_free(protocol);
717
0
  }
718
719
0
  if (proto_names) {
720
0
    g_hash_table_destroy(proto_names);
721
0
    proto_names = NULL;
722
0
  }
723
724
0
  if (proto_short_names) {
725
0
    g_hash_table_destroy(proto_short_names);
726
0
    proto_short_names = NULL;
727
0
  }
728
729
0
  if (proto_filter_names) {
730
0
    g_hash_table_destroy(proto_filter_names);
731
0
    proto_filter_names = NULL;
732
0
  }
733
734
0
  if (proto_reserved_filter_names) {
735
0
    g_hash_table_destroy(proto_reserved_filter_names);
736
0
    proto_reserved_filter_names = NULL;
737
0
  }
738
739
0
  if (gpa_hfinfo.allocated_len) {
740
0
    gpa_hfinfo.len           = 0;
741
0
    gpa_hfinfo.allocated_len = 0;
742
0
    g_free(gpa_hfinfo.hfi);
743
0
    gpa_hfinfo.hfi           = NULL;
744
0
  }
745
746
0
  if (deregistered_fields) {
747
0
    g_ptr_array_free(deregistered_fields, true);
748
0
    deregistered_fields = NULL;
749
0
  }
750
751
0
  if (deregistered_data) {
752
0
    g_ptr_array_free(deregistered_data, true);
753
0
    deregistered_data = NULL;
754
0
  }
755
756
0
  if (deregistered_slice) {
757
0
    g_ptr_array_free(deregistered_slice, true);
758
0
    deregistered_slice = NULL;
759
0
  }
760
761
0
  g_free(tree_is_expanded);
762
0
  tree_is_expanded = NULL;
763
764
0
  if (prefixes)
765
0
    g_hash_table_destroy(prefixes);
766
767
0
  if (saved_dir_queue != NULL) {
768
0
    g_queue_clear_full(saved_dir_queue, g_free);
769
0
    g_queue_free(saved_dir_queue);
770
0
    saved_dir_queue = NULL;
771
0
  }
772
0
}
773
774
void
775
proto_cleanup(void)
776
0
{
777
0
  proto_free_deregistered_fields();
778
0
  proto_cleanup_base();
779
780
0
  g_slist_free(dissector_plugins);
781
0
  dissector_plugins = NULL;
782
0
}
783
784
static bool
785
ws_pushd(const char* dir)
786
2
{
787
  //Save the current working directory
788
2
  const char* save_wd = get_current_working_dir();
789
2
  if (save_wd != NULL)
790
2
    g_queue_push_head(saved_dir_queue, g_strdup(save_wd));
791
792
  //Change to the new one
793
#ifdef _WIN32
794
  SetCurrentDirectory(utf_8to16(dir));
795
  return true;
796
#else
797
2
  return (chdir(dir) == 0);
798
2
#endif
799
2
}
800
801
static bool
802
ws_popd(void)
803
0
{
804
0
  int ret = 0;
805
0
  char* saved_wd = g_queue_pop_head(saved_dir_queue);
806
0
  if (saved_wd == NULL)
807
0
    return false;
808
809
  //Restore the previous one
810
#ifdef _WIN32
811
  SetCurrentDirectory(utf_8to16(saved_wd));
812
#else
813
0
  ret = chdir(saved_wd);
814
0
#endif
815
0
  g_free(saved_wd);
816
0
  return (ret == 0);
817
0
}
818
819
void
820
proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
821
2
{
822
2
  if (ws_pushd(dir))
823
0
  {
824
0
    func(param);
825
0
    ws_popd();
826
0
  }
827
2
}
828
829
static bool
830
// NOLINTNEXTLINE(misc-no-recursion)
831
proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
832
            void *data)
833
0
{
834
0
  proto_node *pnode = tree;
835
0
  proto_node *child;
836
0
  proto_node *current;
837
838
0
  if (func(pnode, data))
839
0
    return true;
840
841
0
  child = pnode->first_child;
842
0
  while (child != NULL) {
843
    /*
844
     * The routine we call might modify the child, e.g. by
845
     * freeing it, so we get the child's successor before
846
     * calling that routine.
847
     */
848
0
    current = child;
849
0
    child   = current->next;
850
    // We recurse here, but we're limited by prefs.gui_max_tree_depth
851
0
    if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
852
0
      return true;
853
0
  }
854
855
0
  return false;
856
0
}
857
858
void
859
proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
860
          void *data)
861
89.7M
{
862
89.7M
  proto_node *node = tree;
863
89.7M
  proto_node *current;
864
865
89.7M
  if (!node)
866
0
    return;
867
868
89.7M
  node = node->first_child;
869
179M
  while (node != NULL) {
870
89.6M
    current = node;
871
89.6M
    node    = current->next;
872
89.6M
    func((proto_tree *)current, data);
873
89.6M
  }
874
89.7M
}
875
876
static void
877
free_GPtrArray_value(void *key, void *value, void *user_data _U_)
878
75
{
879
75
  GPtrArray         *ptrs = (GPtrArray *)value;
880
75
  int                hfid = GPOINTER_TO_UINT(key);
881
75
  header_field_info *hfinfo;
882
883
75
  PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
884
75
  if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
885
    /* when a field is referenced by a filter this also
886
       affects the refcount for the parent protocol so we need
887
       to adjust the refcount for the parent as well
888
    */
889
75
    if (hfinfo->parent != -1) {
890
75
      header_field_info *parent_hfinfo;
891
75
      PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
892
75
      parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
893
75
    }
894
75
    hfinfo->ref_type = HF_REF_TYPE_NONE;
895
75
  }
896
897
75
  g_ptr_array_free(ptrs, true);
898
75
}
899
900
static void
901
proto_tree_free_node(proto_node *node, void *data _U_)
902
89.6M
{
903
89.6M
  field_info *finfo  = PNODE_FINFO(node);
904
905
89.6M
  proto_tree_children_foreach(node, proto_tree_free_node, NULL);
906
907
89.6M
  if (finfo) {
908
35.4M
    fvalue_free(finfo->value);
909
35.4M
    finfo->value = NULL;
910
35.4M
  }
911
89.6M
}
912
913
void
914
proto_tree_reset(proto_tree *tree)
915
114k
{
916
114k
  tree_data_t *tree_data = PTREE_DATA(tree);
917
918
114k
  proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
919
920
  /* free tree data */
921
114k
  if (tree_data->interesting_hfids) {
922
    /* Free all the GPtrArray's in the interesting_hfids hash. */
923
71.3k
    g_hash_table_foreach(tree_data->interesting_hfids,
924
71.3k
      free_GPtrArray_value, NULL);
925
926
    /* And then remove all values. */
927
71.3k
    g_hash_table_remove_all(tree_data->interesting_hfids);
928
71.3k
  }
929
930
  /* Reset track of the number of children */
931
114k
  tree_data->count = 0;
932
933
  /* Reset our loop checks */
934
114k
  tree_data->idle_count_ds_tvb = NULL;
935
114k
  tree_data->max_start = 0;
936
114k
  tree_data->start_idle_count = 0;
937
938
114k
  PROTO_NODE_INIT(tree);
939
114k
}
940
941
/* frees the resources that the dissection a proto_tree uses */
942
void
943
proto_tree_free(proto_tree *tree)
944
0
{
945
0
  tree_data_t *tree_data = PTREE_DATA(tree);
946
947
0
  proto_tree_children_foreach(tree, proto_tree_free_node, NULL);
948
949
  /* free tree data */
950
0
  if (tree_data->interesting_hfids) {
951
    /* Free all the GPtrArray's in the interesting_hfids hash. */
952
0
    g_hash_table_foreach(tree_data->interesting_hfids,
953
0
      free_GPtrArray_value, NULL);
954
955
    /* And then destroy the hash. */
956
0
    g_hash_table_destroy(tree_data->interesting_hfids);
957
0
  }
958
959
0
  g_slice_free(tree_data_t, tree_data);
960
961
0
  g_slice_free(proto_tree, tree);
962
0
}
963
964
/* Is the parsing being done for a visible proto_tree or an invisible one?
965
 * By setting this correctly, the proto_tree creation is sped up by not
966
 * having to call vsnprintf and copy strings around.
967
 */
968
bool
969
proto_tree_set_visible(proto_tree *tree, bool visible)
970
15
{
971
15
  bool old_visible = PTREE_DATA(tree)->visible;
972
973
15
  PTREE_DATA(tree)->visible = visible;
974
975
15
  return old_visible;
976
15
}
977
978
void
979
proto_tree_set_fake_protocols(proto_tree *tree, bool fake_protocols)
980
0
{
981
0
  if (tree)
982
0
    PTREE_DATA(tree)->fake_protocols = fake_protocols;
983
0
}
984
985
/* Assume dissector set only its protocol fields.
986
   This function is called by dissectors and allows the speeding up of filtering
987
   in wireshark; if this function returns false it is safe to reset tree to NULL
988
   and thus skip calling most of the expensive proto_tree_add_...()
989
   functions.
990
   If the tree is visible we implicitly assume the field is referenced.
991
*/
992
bool
993
proto_field_is_referenced(proto_tree *tree, int proto_id)
994
508k
{
995
508k
  register header_field_info *hfinfo;
996
997
998
508k
  if (!tree)
999
0
    return false;
1000
1001
508k
  if (PTREE_DATA(tree)->visible)
1002
417k
    return true;
1003
1004
91.0k
  PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
1005
91.0k
  if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1006
0
    return true;
1007
1008
91.0k
  if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)->fake_protocols)
1009
0
    return true;
1010
1011
91.0k
  return false;
1012
91.0k
}
1013
1014
1015
/* Finds a record in the hfinfo array by id. */
1016
header_field_info *
1017
proto_registrar_get_nth(unsigned hfindex)
1018
10.5M
{
1019
10.5M
  register header_field_info *hfinfo;
1020
1021
10.5M
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
1022
10.5M
  return hfinfo;
1023
10.5M
}
1024
1025
1026
/*  Prefix initialization
1027
 *    this allows for a dissector to register a display filter name prefix
1028
 *    so that it can delay the initialization of the hf array as long as
1029
 *    possible.
1030
 */
1031
1032
/* compute a hash for the part before the dot of a display filter */
1033
static unsigned
1034
467
prefix_hash (const void *key) {
1035
  /* end the string at the dot and compute its hash */
1036
467
  char* copy = g_strdup((const char *)key);
1037
467
  char* c    = copy;
1038
467
  unsigned tmp;
1039
1040
1.67k
  for (; *c; c++) {
1041
1.22k
    if (*c == '.') {
1042
22
      *c = 0;
1043
22
      break;
1044
22
    }
1045
1.22k
  }
1046
1047
467
  tmp = wmem_str_hash(copy);
1048
467
  g_free(copy);
1049
467
  return tmp;
1050
467
}
1051
1052
/* are both strings equal up to the end or the dot? */
1053
static gboolean
1054
22
prefix_equal (const void *ap, const void *bp) {
1055
22
  const char* a = (const char *)ap;
1056
22
  const char* b = (const char *)bp;
1057
1058
146
  do {
1059
146
    char ac = *a++;
1060
146
    char bc = *b++;
1061
1062
146
    if ( (ac == '.' || ac == '\0') &&   (bc == '.' || bc == '\0') ) return TRUE;
1063
1064
124
    if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE;
1065
124
    if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE;
1066
1067
124
    if (ac != bc) return FALSE;
1068
124
  } while (1);
1069
1070
0
  return FALSE;
1071
22
}
1072
1073
/* Register a new prefix for "delayed" initialization of field arrays */
1074
void
1075
105
proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1076
105
  if (! prefixes ) {
1077
15
    prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1078
15
  }
1079
1080
105
  g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1081
105
}
1082
1083
/* helper to call all prefix initializers */
1084
static gboolean
1085
0
initialize_prefix(void *k, void *v, void *u _U_) {
1086
0
  ((prefix_initializer_t)v)((const char *)k);
1087
0
  return TRUE;
1088
0
}
1089
1090
/** Initialize every remaining uninitialized prefix. */
1091
void
1092
0
proto_initialize_all_prefixes(void) {
1093
0
  g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL);
1094
0
}
1095
1096
/* Finds a record in the hfinfo array by name.
1097
 * If it fails to find it in the already registered fields,
1098
 * it tries to find and call an initializer in the prefixes
1099
 * table and if so it looks again.
1100
 */
1101
1102
header_field_info *
1103
proto_registrar_get_byname(const char *field_name)
1104
1.44k
{
1105
1.44k
  header_field_info    *hfinfo;
1106
1.44k
  prefix_initializer_t  pi;
1107
1108
1.44k
  if (!field_name)
1109
0
    return NULL;
1110
1111
1.44k
  if (g_strcmp0(field_name, last_field_name) == 0) {
1112
45
    return last_hfinfo;
1113
45
  }
1114
1115
1.39k
  hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1116
1117
1.39k
  if (hfinfo) {
1118
1.04k
    g_free(last_field_name);
1119
1.04k
    last_field_name = g_strdup(field_name);
1120
1.04k
    last_hfinfo = hfinfo;
1121
1.04k
    return hfinfo;
1122
1.04k
  }
1123
1124
351
  if (!prefixes)
1125
0
    return NULL;
1126
1127
351
  if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL) {
1128
11
    pi(field_name);
1129
11
    g_hash_table_remove(prefixes, field_name);
1130
340
  } else {
1131
340
    return NULL;
1132
340
  }
1133
1134
11
  hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1135
1136
11
  if (hfinfo) {
1137
8
    g_free(last_field_name);
1138
8
    last_field_name = g_strdup(field_name);
1139
8
    last_hfinfo = hfinfo;
1140
8
  }
1141
11
  return hfinfo;
1142
351
}
1143
1144
header_field_info*
1145
proto_registrar_get_byalias(const char *alias_name)
1146
340
{
1147
340
  if (!alias_name) {
1148
0
    return NULL;
1149
0
  }
1150
1151
  /* Find our aliased protocol. */
1152
340
  char *an_copy = g_strdup(alias_name);
1153
340
  char *dot = strchr(an_copy, '.');
1154
340
  if (dot) {
1155
0
    *dot = '\0';
1156
0
  }
1157
340
  const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1158
340
  if (!proto_pfx) {
1159
340
    g_free(an_copy);
1160
340
    return NULL;
1161
340
  }
1162
1163
  /* Construct our aliased field and look it up. */
1164
0
  GString *filter_name = g_string_new(proto_pfx);
1165
0
  if (dot) {
1166
0
    g_string_append_printf(filter_name, ".%s", dot+1);
1167
0
  }
1168
0
  header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1169
0
  g_free(an_copy);
1170
0
  g_string_free(filter_name, TRUE);
1171
1172
0
  return hfinfo;
1173
340
}
1174
1175
int
1176
proto_registrar_get_id_byname(const char *field_name)
1177
675
{
1178
675
  header_field_info *hfinfo;
1179
1180
675
  hfinfo = proto_registrar_get_byname(field_name);
1181
1182
675
  if (!hfinfo)
1183
0
    return -1;
1184
1185
675
  return hfinfo->id;
1186
675
}
1187
1188
static int
1189
label_strcat_flags(const header_field_info *hfinfo)
1190
1.16M
{
1191
1.16M
  if (FIELD_DISPLAY(hfinfo->display) & BASE_STR_WSP)
1192
956k
    return FORMAT_LABEL_REPLACE_SPACE;
1193
1194
208k
  return 0;
1195
1.16M
}
1196
1197
static char *
1198
format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1199
    const uint8_t *bytes, unsigned length, size_t max_str_len)
1200
151k
{
1201
151k
  char *str = NULL;
1202
151k
  const uint8_t *p;
1203
151k
  bool is_printable;
1204
1205
151k
  if (bytes) {
1206
149k
    if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE) {
1207
      /*
1208
       * If all bytes are valid and printable UTF-8, show the
1209
       * bytes as a string - in quotes to indicate that it's
1210
       * a string.
1211
       */
1212
461
      if (isprint_utf8_string((const char*)bytes, length)) {
1213
22
        str = wmem_strdup_printf(scope, "\"%.*s\"",
1214
22
            (int)length, bytes);
1215
22
        return str;
1216
22
      }
1217
149k
    } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE) {
1218
      /*
1219
       * Check whether all bytes are printable.
1220
       */
1221
0
      is_printable = true;
1222
0
      for (p = bytes; p < bytes+length; p++) {
1223
0
        if (!g_ascii_isprint(*p)) {
1224
          /* Not printable. */
1225
0
          is_printable = false;
1226
0
          break;
1227
0
        }
1228
0
      }
1229
1230
      /*
1231
       * If all bytes are printable ASCII, show the bytes
1232
       * as a string - in quotes to indicate that it's
1233
       * a string.
1234
       */
1235
0
      if (is_printable) {
1236
0
        str = wmem_strdup_printf(scope, "\"%.*s\"",
1237
0
            (int)length, bytes);
1238
0
        return str;
1239
0
      }
1240
0
    }
1241
1242
    /*
1243
     * Either it's not printable ASCII, or we don't care whether
1244
     * it's printable ASCII; show it as hex bytes.
1245
     */
1246
149k
    switch (FIELD_DISPLAY(hfinfo->display)) {
1247
0
    case SEP_DOT:
1248
0
      str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1249
0
      break;
1250
0
    case SEP_DASH:
1251
0
      str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1252
0
      break;
1253
6
    case SEP_COLON:
1254
6
      str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1255
6
      break;
1256
0
    case SEP_SPACE:
1257
0
      str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1258
0
      break;
1259
149k
    case BASE_NONE:
1260
149k
    default:
1261
149k
      if (prefs.display_byte_fields_with_spaces) {
1262
0
        str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1263
149k
      } else {
1264
149k
        str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1265
149k
      }
1266
149k
      break;
1267
149k
    }
1268
149k
  }
1269
1.68k
  else {
1270
1.68k
    if (hfinfo->display & BASE_ALLOW_ZERO) {
1271
19
      str = wmem_strdup(scope, "<none>");
1272
1.66k
    } else {
1273
1.66k
      str = wmem_strdup(scope, "<MISSING>");
1274
1.66k
    }
1275
1.68k
  }
1276
151k
  return str;
1277
151k
}
1278
1279
static char *
1280
format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1281
    const uint8_t *bytes, unsigned length)
1282
151k
{
1283
151k
  return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH);
1284
151k
}
1285
1286
static void
1287
ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1288
193
{
1289
193
  subtree_lvl *pushed_tree;
1290
1291
193
  DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER);
1292
193
  ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER;
1293
1294
193
  pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1295
193
  DISSECTOR_ASSERT(pushed_tree != NULL);
1296
193
  ptvc->pushed_tree = pushed_tree;
1297
193
}
1298
1299
static void
1300
ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1301
411
{
1302
411
  ptvc->pushed_tree       = NULL;
1303
411
  ptvc->pushed_tree_max   = 0;
1304
411
  DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0);
1305
411
  ptvc->pushed_tree_index = 0;
1306
411
}
1307
1308
/* Allocates an initializes a ptvcursor_t with 3 variables:
1309
 *  proto_tree, tvbuff, and offset. */
1310
ptvcursor_t *
1311
ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1312
592
{
1313
592
  ptvcursor_t *ptvc;
1314
1315
592
  ptvc                    = wmem_new(scope, ptvcursor_t);
1316
592
  ptvc->scope             = scope;
1317
592
  ptvc->tree              = tree;
1318
592
  ptvc->tvb               = tvb;
1319
592
  ptvc->offset            = offset;
1320
592
  ptvc->pushed_tree       = NULL;
1321
592
  ptvc->pushed_tree_max   = 0;
1322
592
  ptvc->pushed_tree_index = 0;
1323
592
  return ptvc;
1324
592
}
1325
1326
1327
/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1328
void
1329
ptvcursor_free(ptvcursor_t *ptvc)
1330
411
{
1331
411
  ptvcursor_free_subtree_levels(ptvc);
1332
411
  wmem_free(ptvc->scope, ptvc);
1333
411
}
1334
1335
/* Returns tvbuff. */
1336
tvbuff_t *
1337
ptvcursor_tvbuff(ptvcursor_t *ptvc)
1338
22.7k
{
1339
22.7k
  return ptvc->tvb;
1340
22.7k
}
1341
1342
/* Returns current offset. */
1343
unsigned
1344
ptvcursor_current_offset(ptvcursor_t *ptvc)
1345
26.0k
{
1346
26.0k
  return ptvc->offset;
1347
26.0k
}
1348
1349
proto_tree *
1350
ptvcursor_tree(ptvcursor_t *ptvc)
1351
15.1k
{
1352
15.1k
  if (!ptvc)
1353
0
    return NULL;
1354
1355
15.1k
  return ptvc->tree;
1356
15.1k
}
1357
1358
void
1359
ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1360
665
{
1361
665
  ptvc->tree = tree;
1362
665
}
1363
1364
/* creates a subtree, sets it as the working tree and pushes the old working tree */
1365
proto_tree *
1366
ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1367
8.43k
{
1368
8.43k
  subtree_lvl *subtree;
1369
8.43k
  if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1370
193
    ptvcursor_new_subtree_levels(ptvc);
1371
1372
8.43k
  subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1373
8.43k
  subtree->tree = ptvc->tree;
1374
8.43k
  subtree->it= NULL;
1375
8.43k
  ptvc->pushed_tree_index++;
1376
8.43k
  return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1377
8.43k
}
1378
1379
/* pops a subtree */
1380
void
1381
ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1382
8.36k
{
1383
8.36k
  subtree_lvl *subtree;
1384
1385
8.36k
  if (ptvc->pushed_tree_index <= 0)
1386
27
    return;
1387
1388
8.33k
  ptvc->pushed_tree_index--;
1389
8.33k
  subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1390
8.33k
  if (subtree->it != NULL)
1391
619
    proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1392
1393
8.33k
  ptvc->tree = subtree->tree;
1394
8.33k
}
1395
1396
/* saves the current tvb offset and the item in the current subtree level */
1397
static void
1398
ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1399
648
{
1400
648
  subtree_lvl *subtree;
1401
1402
648
  DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0);
1403
1404
648
  subtree                = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1405
648
  subtree->it            = it;
1406
648
  subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1407
648
}
1408
1409
/* Creates a subtree and adds it to the cursor as the working tree but does not
1410
 * save the old working tree */
1411
proto_tree *
1412
ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1413
8.43k
{
1414
8.43k
  ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1415
8.43k
  return ptvc->tree;
1416
8.43k
}
1417
1418
static proto_tree *
1419
ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1420
696
{
1421
696
  ptvcursor_push_subtree(ptvc, it, ett_subtree);
1422
696
  if (length == SUBTREE_UNDEFINED_LENGTH)
1423
648
    ptvcursor_subtree_set_item(ptvc, it);
1424
696
  return ptvcursor_tree(ptvc);
1425
696
}
1426
1427
/* Add an item to the tree and create a subtree
1428
 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1429
 * In this case, when the subtree will be closed, the parent item length will
1430
 * be equal to the advancement of the cursor since the creation of the subtree.
1431
 */
1432
proto_tree *
1433
ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1434
         const unsigned encoding, int ett_subtree)
1435
48
{
1436
48
  proto_item *it;
1437
1438
48
  it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1439
48
  return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1440
48
}
1441
1442
static proto_item *
1443
proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1444
1445
/* Add a text node to the tree and create a subtree
1446
 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1447
 * In this case, when the subtree will be closed, the item length will be equal
1448
 * to the advancement of the cursor since the creation of the subtree.
1449
 */
1450
proto_tree *
1451
ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1452
        int ett_subtree, const char *format, ...)
1453
672
{
1454
672
  proto_item        *pi;
1455
672
  va_list            ap;
1456
672
  header_field_info *hfinfo;
1457
672
  proto_tree        *tree;
1458
1459
672
  tree = ptvcursor_tree(ptvc);
1460
1461
672
  CHECK_FOR_NULL_TREE(tree);
1462
1463
672
  TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1464
1465
652
  pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1466
652
              ptvcursor_current_offset(ptvc), length);
1467
1468
652
  TRY_TO_FAKE_THIS_REPR(pi);
1469
1470
652
  va_start(ap, format);
1471
652
  proto_tree_set_representation(pi, format, ap);
1472
652
  va_end(ap);
1473
1474
652
  return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1475
652
}
1476
1477
/* Add a text-only node, leaving it to our caller to fill the text in */
1478
static proto_item *
1479
proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1480
2.88M
{
1481
2.88M
  proto_item *pi;
1482
1483
2.88M
  if (tree == NULL)
1484
0
    return NULL;
1485
1486
2.88M
  pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1487
1488
2.88M
  return pi;
1489
2.88M
}
1490
1491
/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1492
proto_item *
1493
proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1494
        const char *format, ...)
1495
61.3k
{
1496
61.3k
  proto_item    *pi;
1497
61.3k
  va_list      ap;
1498
61.3k
  header_field_info *hfinfo;
1499
1500
61.3k
  if (length == -1) {
1501
0
    length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1502
61.3k
  } else {
1503
61.3k
    tvb_ensure_bytes_exist(tvb, start, length);
1504
61.3k
  }
1505
1506
61.3k
  CHECK_FOR_NULL_TREE(tree);
1507
1508
60.7k
  TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1509
1510
24.9k
  pi = proto_tree_add_text_node(tree, tvb, start, length);
1511
1512
24.9k
  TRY_TO_FAKE_THIS_REPR(pi);
1513
1514
24.9k
  va_start(ap, format);
1515
24.9k
  proto_tree_set_representation(pi, format, ap);
1516
24.9k
  va_end(ap);
1517
1518
24.9k
  return pi;
1519
24.9k
}
1520
1521
/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1522
proto_item *
1523
proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1524
         int length, const char *format, va_list ap)
1525
4.01M
{
1526
4.01M
  proto_item        *pi;
1527
4.01M
  header_field_info *hfinfo;
1528
1529
  /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1530
   * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1531
   * the length to be what's in the tvbuff if length is -1, and the
1532
   * minimum of length and what's in the tvbuff if not.
1533
   */
1534
1535
4.01M
  CHECK_FOR_NULL_TREE(tree);
1536
1537
4.01M
  TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1538
1539
2.85M
  pi = proto_tree_add_text_node(tree, tvb, start, length);
1540
1541
2.85M
  TRY_TO_FAKE_THIS_REPR(pi);
1542
1543
2.85M
  proto_tree_set_representation(pi, format, ap);
1544
1545
2.85M
  return pi;
1546
2.85M
}
1547
1548
/* Add a text-only node that creates a subtree underneath.
1549
 */
1550
proto_tree *
1551
proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1552
494k
{
1553
494k
  return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1554
494k
}
1555
1556
/* Add a text-only node that creates a subtree underneath.
1557
 */
1558
proto_tree *
1559
proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1560
3.81M
{
1561
3.81M
  proto_tree *pt;
1562
3.81M
  proto_item *pi;
1563
3.81M
  va_list     ap;
1564
1565
3.81M
  va_start(ap, format);
1566
3.81M
  pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1567
3.81M
  va_end(ap);
1568
1569
3.81M
  if (tree_item != NULL)
1570
3.12M
    *tree_item = pi;
1571
1572
3.81M
  pt = proto_item_add_subtree(pi, idx);
1573
1574
3.81M
  return pt;
1575
3.81M
}
1576
1577
/* Add a text-only node for debugging purposes. The caller doesn't need
1578
 * to worry about tvbuff, start, or length. Debug message gets sent to
1579
 * STDOUT, too */
1580
proto_item *
1581
proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1582
0
{
1583
0
  proto_item *pi;
1584
0
  va_list     ap;
1585
1586
0
  pi = proto_tree_add_text_node(tree, NULL, 0, 0);
1587
1588
0
  if (pi) {
1589
0
    va_start(ap, format);
1590
0
    proto_tree_set_representation(pi, format, ap);
1591
0
    va_end(ap);
1592
0
  }
1593
0
  va_start(ap, format);
1594
0
  vprintf(format, ap);
1595
0
  va_end(ap);
1596
0
  printf("\n");
1597
1598
0
  return pi;
1599
0
}
1600
1601
proto_item *
1602
proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1603
18.0k
{
1604
18.0k
  proto_item    *pi;
1605
18.0k
  header_field_info *hfinfo;
1606
1607
18.0k
  CHECK_FOR_NULL_TREE(tree);
1608
1609
18.0k
  TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1610
1611
2.23k
  pi = proto_tree_add_text_node(tree, tvb, start, length);
1612
1613
2.23k
  TRY_TO_FAKE_THIS_REPR(pi);
1614
1615
2.23k
  proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1616
1617
2.23k
  return pi;
1618
2.23k
}
1619
1620
proto_item *
1621
proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1622
334
{
1623
334
  proto_item    *pi;
1624
334
  header_field_info *hfinfo;
1625
334
  char      *str;
1626
1627
334
  CHECK_FOR_NULL_TREE(tree);
1628
1629
334
  TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo);
1630
1631
284
  pi = proto_tree_add_text_node(tree, tvb, start, length);
1632
1633
284
  TRY_TO_FAKE_THIS_REPR(pi);
1634
1635
284
  str = tvb_format_text_wsp(NULL, tvb, start, length);
1636
284
  proto_item_set_text(pi, "%s", str);
1637
284
  wmem_free(NULL, str);
1638
1639
284
  return pi;
1640
284
}
1641
1642
void proto_report_dissector_bug(const char *format, ...)
1643
134
{
1644
134
  va_list args;
1645
1646
134
  if (wireshark_abort_on_dissector_bug) {
1647
    /*
1648
     * Try to have the error message show up in the crash
1649
     * information.
1650
     */
1651
0
    va_start(args, format);
1652
0
    ws_vadd_crash_info(format, args);
1653
0
    va_end(args);
1654
1655
    /*
1656
     * Print the error message.
1657
     */
1658
0
    va_start(args, format);
1659
0
    vfprintf(stderr, format, args);
1660
0
    va_end(args);
1661
0
    putc('\n', stderr);
1662
1663
    /*
1664
     * And crash.
1665
     */
1666
0
    abort();
1667
134
  } else {
1668
134
    va_start(args, format);
1669
134
    VTHROW_FORMATTED(DissectorError, format, args);
1670
134
    va_end(args);
1671
134
    ws_assert_not_reached(); /* GCC 12 with ASAN needs this. */
1672
134
  }
1673
134
}
1674
1675
/* We could probably get away with changing is_error to a minimum length value. */
1676
static void
1677
report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool is_error)
1678
1.07k
{
1679
1.07k
  if (is_error) {
1680
131
    expert_add_info_format(NULL, tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1681
940
  } else {
1682
940
    expert_add_info_format(NULL, tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1683
940
  }
1684
1685
1.07k
  if (is_error) {
1686
131
    THROW(ReportedBoundsError);
1687
131
  }
1688
1.07k
}
1689
1690
static uint32_t
1691
get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1692
10.2M
{
1693
10.2M
  uint32_t value;
1694
10.2M
  bool length_error;
1695
1696
10.2M
  switch (length) {
1697
1698
7.33M
  case 1:
1699
7.33M
    value = tvb_get_uint8(tvb, offset);
1700
7.33M
    if (encoding & ENC_ZIGBEE) {
1701
1.42k
      if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1702
261
        value = 0;
1703
261
      }
1704
1.42k
    }
1705
7.33M
    break;
1706
1707
1.70M
  case 2:
1708
1.70M
    value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohs(tvb, offset)
1709
1.70M
                   : tvb_get_ntohs(tvb, offset);
1710
1.70M
    if (encoding & ENC_ZIGBEE) {
1711
252
      if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1712
75
        value = 0;
1713
75
      }
1714
252
    }
1715
1.70M
    break;
1716
1717
561k
  case 3:
1718
561k
    value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letoh24(tvb, offset)
1719
561k
                   : tvb_get_ntoh24(tvb, offset);
1720
561k
    break;
1721
1722
609k
  case 4:
1723
609k
    value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1724
609k
                   : tvb_get_ntohl(tvb, offset);
1725
609k
    break;
1726
1727
722
  default:
1728
722
    if (length < 1) {
1729
61
      length_error = true;
1730
61
      value = 0;
1731
661
    } else {
1732
661
      length_error = false;
1733
661
      value = (encoding & ENC_LITTLE_ENDIAN) ? tvb_get_letohl(tvb, offset)
1734
661
                     : tvb_get_ntohl(tvb, offset);
1735
661
    }
1736
722
    report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1737
722
    break;
1738
10.2M
  }
1739
10.2M
  return value;
1740
10.2M
}
1741
1742
static inline uint64_t
1743
get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1744
2.84M
{
1745
2.84M
  uint64_t value;
1746
1747
2.84M
  value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1748
1749
2.84M
  if (length < 1 || length > 8) {
1750
185
    report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1751
185
  }
1752
1753
2.84M
  return value;
1754
2.84M
}
1755
1756
static int32_t
1757
get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1758
664k
{
1759
664k
  int32_t value;
1760
664k
  bool length_error;
1761
1762
664k
  switch (length) {
1763
1764
347k
  case 1:
1765
347k
    value = tvb_get_int8(tvb, offset);
1766
347k
    break;
1767
1768
295k
  case 2:
1769
295k
    value = encoding ? tvb_get_letohis(tvb, offset)
1770
295k
         : tvb_get_ntohis(tvb, offset);
1771
295k
    break;
1772
1773
1.63k
  case 3:
1774
1.63k
    value = encoding ? tvb_get_letohi24(tvb, offset)
1775
1.63k
         : tvb_get_ntohi24(tvb, offset);
1776
1.63k
    break;
1777
1778
19.9k
  case 4:
1779
19.9k
    value = encoding ? tvb_get_letohil(tvb, offset)
1780
19.9k
         : tvb_get_ntohil(tvb, offset);
1781
19.9k
    break;
1782
1783
4
  default:
1784
4
    if (length < 1) {
1785
1
      length_error = true;
1786
1
      value = 0;
1787
3
    } else {
1788
3
      length_error = false;
1789
3
      value = encoding ? tvb_get_letohil(tvb, offset)
1790
3
           : tvb_get_ntohil(tvb, offset);
1791
3
    }
1792
4
    report_type_length_mismatch(tree, "a signed integer", length, length_error);
1793
4
    break;
1794
664k
  }
1795
664k
  return value;
1796
664k
}
1797
1798
/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1799
 * be cast-able as a int64_t. This is weird, but what the code has always done.
1800
 */
1801
static inline uint64_t
1802
get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1803
5.28k
{
1804
5.28k
  uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1805
1806
5.28k
  switch (length) {
1807
502
    case 7:
1808
502
      value = ws_sign_ext64(value, 56);
1809
502
      break;
1810
891
    case 6:
1811
891
      value = ws_sign_ext64(value, 48);
1812
891
      break;
1813
620
    case 5:
1814
620
      value = ws_sign_ext64(value, 40);
1815
620
      break;
1816
383
    case 4:
1817
383
      value = ws_sign_ext64(value, 32);
1818
383
      break;
1819
44
    case 3:
1820
44
      value = ws_sign_ext64(value, 24);
1821
44
      break;
1822
189
    case 2:
1823
189
      value = ws_sign_ext64(value, 16);
1824
189
      break;
1825
422
    case 1:
1826
422
      value = ws_sign_ext64(value, 8);
1827
422
      break;
1828
5.28k
  }
1829
1830
5.28k
  return value;
1831
5.28k
}
1832
1833
/* For FT_STRING */
1834
static inline const uint8_t *
1835
get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1836
    int length, int *ret_length, const unsigned encoding)
1837
116k
{
1838
116k
  if (length == -1) {
1839
11
    length = tvb_ensure_captured_length_remaining(tvb, start);
1840
11
  }
1841
116k
  *ret_length = length;
1842
116k
  return tvb_get_string_enc(scope, tvb, start, length, encoding);
1843
116k
}
1844
1845
/* For FT_STRINGZ */
1846
static inline const uint8_t *
1847
get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1848
    int start, int length, int *ret_length, const unsigned encoding)
1849
6.66k
{
1850
6.66k
  const uint8_t *value;
1851
1852
6.66k
  if (length < -1) {
1853
0
    report_type_length_mismatch(tree, "a string", length, true);
1854
0
  }
1855
1856
  /* XXX - Ideally, every "null-terminated string which fits into a
1857
   * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1858
   * as appropriate, not a FT_STRINGZ. If so, then we could always call
1859
   * tvb_get_stringz_enc here. Failing that, we could treat length 0
1860
   * as unknown length as well (since there is a trailing '\0', the real
1861
   * length is never zero), allowing switching to unsigned lengths.
1862
   */
1863
6.66k
  if (length == -1) {
1864
    /* This can throw an exception */
1865
2.39k
    value = tvb_get_stringz_enc(scope, tvb, start, (unsigned*)&length, encoding);
1866
4.27k
  } else {
1867
    /* In this case, length signifies the length of the string.
1868
     *
1869
     * This could either be a null-padded string, which doesn't
1870
     * necessarily have a '\0' at the end, or a null-terminated
1871
     * string, with a trailing '\0'.  (Yes, there are cases
1872
     * where you have a string that's both counted and null-
1873
     * terminated.)
1874
     *
1875
     * In the first case, we must allocate a buffer of length
1876
     * "length+1", to make room for a trailing '\0'.
1877
     *
1878
     * In the second case, we don't assume that there is a
1879
     * trailing '\0' there, as the packet might be malformed.
1880
     * (XXX - should we throw an exception if there's no
1881
     * trailing '\0'?)  Therefore, we allocate a buffer of
1882
     * length "length+1", and put in a trailing '\0', just to
1883
     * be safe.
1884
     *
1885
     * (XXX - this would change if we made string values counted
1886
     * rather than null-terminated.)
1887
     */
1888
4.27k
    value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1889
4.27k
  }
1890
6.66k
  *ret_length = length;
1891
6.66k
  return value;
1892
6.66k
}
1893
1894
/* For FT_UINT_STRING */
1895
static inline const uint8_t *
1896
get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1897
    tvbuff_t *tvb, int start, int length, int *ret_length,
1898
    const unsigned encoding)
1899
2.56k
{
1900
2.56k
  uint32_t n;
1901
2.56k
  const uint8_t *value;
1902
1903
  /* I believe it's ok if this is called with a NULL tree */
1904
2.56k
  n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
1905
2.56k
  value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1906
2.56k
  length += n;
1907
2.56k
  *ret_length = length;
1908
2.56k
  return value;
1909
2.56k
}
1910
1911
/* For FT_STRINGZPAD */
1912
static inline const uint8_t *
1913
get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1914
    int length, int *ret_length, const unsigned encoding)
1915
391
{
1916
  /*
1917
   * XXX - currently, string values are null-
1918
   * terminated, so a "zero-padded" string
1919
   * isn't special.  If we represent string
1920
   * values as something that includes a counted
1921
   * array of bytes, we'll need to strip the
1922
   * trailing NULs.
1923
   */
1924
391
  if (length == -1) {
1925
0
    length = tvb_ensure_captured_length_remaining(tvb, start);
1926
0
  }
1927
391
  *ret_length = length;
1928
391
  return tvb_get_string_enc(scope, tvb, start, length, encoding);
1929
391
}
1930
1931
/* For FT_STRINGZTRUNC */
1932
static inline const uint8_t *
1933
get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1934
    int length, int *ret_length, const unsigned encoding)
1935
694
{
1936
  /*
1937
   * XXX - currently, string values are null-
1938
   * terminated, so a "zero-truncated" string
1939
   * isn't special.  If we represent string
1940
   * values as something that includes a counted
1941
   * array of bytes, we'll need to strip everything
1942
   * starting with the terminating NUL.
1943
   */
1944
694
  if (length == -1) {
1945
0
    length = tvb_ensure_captured_length_remaining(tvb, start);
1946
0
  }
1947
694
  *ret_length = length;
1948
694
  return tvb_get_string_enc(scope, tvb, start, length, encoding);
1949
694
}
1950
1951
/*
1952
 * Deltas between the epochs for various non-UN*X time stamp formats and
1953
 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1954
 * stamp format.
1955
 */
1956
1957
/*
1958
 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1959
 * XXX - if it's OK if this is unsigned, can we just use
1960
 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1961
 */
1962
64
#define NTP_TIMEDIFF1900TO1970SEC INT64_C(2208988800)
1963
1964
/*
1965
 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1966
 */
1967
2.23k
#define NTP_TIMEDIFF1970TO2036SEC INT64_C(2085978496)
1968
1969
/* this can be called when there is no tree, so tree may be null */
1970
static void
1971
get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1972
         const int length, const unsigned encoding, nstime_t *time_stamp,
1973
         const bool is_relative)
1974
4.86k
{
1975
4.86k
  uint32_t    tmpsecs;
1976
4.86k
  uint64_t    tmp64secs;
1977
4.86k
  uint64_t    todusecs;
1978
1979
4.86k
  switch (encoding) {
1980
1981
593
    case ENC_TIME_SECS_NSECS|ENC_BIG_ENDIAN:
1982
      /*
1983
       * If the length is 16, 8-byte seconds, followed
1984
       * by 8-byte fractional time in nanoseconds,
1985
       * both big-endian.
1986
       *
1987
       * If the length is 12, 8-byte seconds, followed
1988
       * by 4-byte fractional time in nanoseconds,
1989
       * both big-endian.
1990
       *
1991
       * If the length is 8, 4-byte seconds, followed
1992
       * by 4-byte fractional time in nanoseconds,
1993
       * both big-endian.
1994
       *
1995
       * For absolute times, the seconds are seconds
1996
       * since the UN*X epoch.
1997
       */
1998
593
      if (length == 16) {
1999
0
        time_stamp->secs  = (time_t)tvb_get_ntoh64(tvb, start);
2000
0
        time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2001
593
      } else if (length == 12) {
2002
0
        time_stamp->secs  = (time_t)tvb_get_ntoh64(tvb, start);
2003
0
        time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2004
593
      } else if (length == 8) {
2005
412
        time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
2006
412
        time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2007
412
      } else if (length == 4) {
2008
        /*
2009
         * Backwards compatibility.
2010
         * ENC_TIME_SECS_NSECS is 0; using
2011
         * ENC_BIG_ENDIAN by itself with a 4-byte
2012
         * time-in-seconds value was done in the
2013
         * past.
2014
         */
2015
167
        time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
2016
167
        time_stamp->nsecs = 0;
2017
167
      } else {
2018
14
        time_stamp->secs  = 0;
2019
14
        time_stamp->nsecs = 0;
2020
14
        report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2021
14
      }
2022
593
      break;
2023
2024
172
    case ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN:
2025
      /*
2026
       * If the length is 16, 8-byte seconds, followed
2027
       * by 8-byte fractional time in nanoseconds,
2028
       * both little-endian.
2029
       *
2030
       * If the length is 12, 8-byte seconds, followed
2031
       * by 4-byte fractional time in nanoseconds,
2032
       * both little-endian.
2033
       *
2034
       * If the length is 8, 4-byte seconds, followed
2035
       * by 4-byte fractional time in nanoseconds,
2036
       * both little-endian.
2037
       *
2038
       * For absolute times, the seconds are seconds
2039
       * since the UN*X epoch.
2040
       */
2041
172
      if (length == 16) {
2042
4
        time_stamp->secs  = (time_t)tvb_get_letoh64(tvb, start);
2043
4
        time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2044
168
      } else if (length == 12) {
2045
0
        time_stamp->secs  = (time_t)tvb_get_letoh64(tvb, start);
2046
0
        time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2047
168
      } else if (length == 8) {
2048
168
        time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
2049
168
        time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2050
168
      } else if (length == 4) {
2051
        /*
2052
         * Backwards compatibility.
2053
         * ENC_TIME_SECS_NSECS is 0; using
2054
         * ENC_LITTLE_ENDIAN by itself with a 4-byte
2055
         * time-in-seconds value was done in the
2056
         * past.
2057
         */
2058
0
        time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
2059
0
        time_stamp->nsecs = 0;
2060
0
      } else {
2061
0
        time_stamp->secs  = 0;
2062
0
        time_stamp->nsecs = 0;
2063
0
        report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2064
0
      }
2065
172
      break;
2066
2067
2.29k
    case ENC_TIME_NTP|ENC_BIG_ENDIAN:
2068
      /*
2069
       * NTP time stamp, big-endian.
2070
       * Only supported for absolute times.
2071
       */
2072
2.29k
      DISSECTOR_ASSERT(!is_relative);
2073
2074
      /* We need a temporary variable here so the unsigned math
2075
       * works correctly (for years > 2036 according to RFC 2030
2076
       * chapter 3).
2077
       *
2078
       * If bit 0 is set, the UTC time is in the range 1968-2036 and
2079
       * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2080
       * If bit 0 is not set, the time is in the range 2036-2104 and
2081
       * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2082
       */
2083
2.29k
      tmpsecs  = tvb_get_ntohl(tvb, start);
2084
2.29k
      if ((tmpsecs & 0x80000000) != 0)
2085
61
        time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2086
2.23k
      else
2087
2.23k
        time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2088
2089
2.29k
      if (length == 8) {
2090
2.25k
        tmp64secs = tvb_get_ntoh64(tvb, start);
2091
2.25k
        if (tmp64secs == 0) {
2092
          //This is "NULL" time
2093
542
          time_stamp->secs = 0;
2094
542
          time_stamp->nsecs = 0;
2095
1.71k
        } else {
2096
          /*
2097
           * Convert 1/2^32s of a second to
2098
           * nanoseconds.
2099
           */
2100
1.71k
          time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2101
1.71k
        }
2102
2.25k
      } else if (length == 4) {
2103
        /*
2104
         * Backwards compatibility.
2105
         */
2106
43
        if (tmpsecs == 0) {
2107
          //This is "NULL" time
2108
4
          time_stamp->secs = 0;
2109
4
        }
2110
43
        time_stamp->nsecs = 0;
2111
43
      } else {
2112
1
        time_stamp->secs  = 0;
2113
1
        time_stamp->nsecs = 0;
2114
1
        report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2115
1
      }
2116
2.29k
      break;
2117
2118
0
    case ENC_TIME_NTP|ENC_LITTLE_ENDIAN:
2119
      /*
2120
       * NTP time stamp, little-endian.
2121
       * Only supported for absolute times.
2122
       *
2123
       * NTP doesn't use this, because it's an Internet format
2124
       * and hence big-endian. Any implementation must decide
2125
       * whether the NTP timestamp is a 64-bit unsigned fixed
2126
       * point number (RFC 1305, RFC 4330) or a 64-bit struct
2127
       * with a 32-bit unsigned seconds field followed by a
2128
       * 32-bit fraction field (cf. RFC 5905, which obsoletes
2129
       * the previous two).
2130
       *
2131
       * XXX: We do the latter, but no dissector uses this format.
2132
       * OTOH, ERF timestamps do the former, so perhaps we
2133
       * should switch the interpretation so that packet-erf.c
2134
       * could use this directly?
2135
       */
2136
0
      DISSECTOR_ASSERT(!is_relative);
2137
2138
      /* We need a temporary variable here so the unsigned math
2139
       * works correctly (for years > 2036 according to RFC 2030
2140
       * chapter 3).
2141
       *
2142
       * If bit 0 is set, the UTC time is in the range 1968-2036 and
2143
       * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2144
       * If bit 0 is not set, the time is in the range 2036-2104 and
2145
       * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2146
       */
2147
0
      tmpsecs  = tvb_get_letohl(tvb, start);
2148
0
      if ((tmpsecs & 0x80000000) != 0)
2149
0
        time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2150
0
      else
2151
0
        time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2152
2153
0
      if (length == 8) {
2154
0
        tmp64secs = tvb_get_letoh64(tvb, start);
2155
0
        if (tmp64secs == 0) {
2156
          //This is "NULL" time
2157
0
          time_stamp->secs = 0;
2158
0
          time_stamp->nsecs = 0;
2159
0
        } else {
2160
          /*
2161
           * Convert 1/2^32s of a second to
2162
           * nanoseconds.
2163
           */
2164
0
          time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2165
0
        }
2166
0
      } else if (length == 4) {
2167
        /*
2168
         * Backwards compatibility.
2169
         */
2170
0
        if (tmpsecs == 0) {
2171
          //This is "NULL" time
2172
0
          time_stamp->secs = 0;
2173
0
        }
2174
0
        time_stamp->nsecs = 0;
2175
0
      } else {
2176
0
        time_stamp->secs  = 0;
2177
0
        time_stamp->nsecs = 0;
2178
0
        report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2179
0
      }
2180
0
      break;
2181
2182
0
    case ENC_TIME_TOD|ENC_BIG_ENDIAN:
2183
      /*
2184
       * S/3x0 and z/Architecture TOD clock time stamp,
2185
       * big-endian.  The epoch is January 1, 1900,
2186
       * 00:00:00 (proleptic?) UTC.
2187
       *
2188
       * Only supported for absolute times.
2189
       */
2190
0
      DISSECTOR_ASSERT(!is_relative);
2191
0
      DISSECTOR_ASSERT(length == 8);
2192
2193
0
      if (length == 8) {
2194
0
        todusecs  = tvb_get_ntoh64(tvb, start) >> 12;
2195
0
        time_stamp->secs = (time_t)((todusecs  / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC);
2196
0
        time_stamp->nsecs = (int)((todusecs  % 1000000) * 1000);
2197
0
      } else {
2198
0
        time_stamp->secs  = 0;
2199
0
        time_stamp->nsecs = 0;
2200
0
        report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2201
0
      }
2202
0
      break;
2203
2204
0
    case ENC_TIME_TOD|ENC_LITTLE_ENDIAN:
2205
      /*
2206
       * S/3x0 and z/Architecture TOD clock time stamp,
2207
       * little-endian.  The epoch is January 1, 1900,
2208
       * 00:00:00 (proleptic?) UTC.
2209
       *
2210
       * Only supported for absolute times.
2211
       */
2212
0
      DISSECTOR_ASSERT(!is_relative);
2213
2214
0
      if (length == 8) {
2215
0
        todusecs  = tvb_get_letoh64(tvb, start) >> 12 ;
2216
0
        time_stamp->secs = (time_t)((todusecs  / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC);
2217
0
        time_stamp->nsecs = (int)((todusecs  % 1000000) * 1000);
2218
0
      } else {
2219
0
        time_stamp->secs  = 0;
2220
0
        time_stamp->nsecs = 0;
2221
0
        report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2222
0
      }
2223
0
      break;
2224
2225
49
    case ENC_TIME_RTPS|ENC_BIG_ENDIAN:
2226
      /*
2227
       * Time stamp using the same seconds/fraction format
2228
       * as NTP, but with the origin of the time stamp being
2229
       * the UNIX epoch rather than the NTP epoch; big-
2230
       * endian.
2231
       *
2232
       * Only supported for absolute times.
2233
       */
2234
49
      DISSECTOR_ASSERT(!is_relative);
2235
2236
49
      if (length == 8) {
2237
49
        time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2238
        /*
2239
         * Convert 1/2^32s of a second to nanoseconds.
2240
         */
2241
49
        time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2242
49
      } else {
2243
0
        time_stamp->secs  = 0;
2244
0
        time_stamp->nsecs = 0;
2245
0
        report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2246
0
      }
2247
49
      break;
2248
2249
63
    case ENC_TIME_RTPS|ENC_LITTLE_ENDIAN:
2250
      /*
2251
       * Time stamp using the same seconds/fraction format
2252
       * as NTP, but with the origin of the time stamp being
2253
       * the UNIX epoch rather than the NTP epoch; little-
2254
       * endian.
2255
       *
2256
       * Only supported for absolute times.
2257
       *
2258
       * The RTPS specification explicitly supports Little
2259
       * Endian encoding. In one place, it states that its
2260
       * Time_t representation "is the one defined by ...
2261
       * RFC 1305", but in another explicitly defines it as
2262
       * a struct consisting of an 32 bit unsigned seconds
2263
       * field and a 32 bit unsigned fraction field, not a 64
2264
       * bit fixed point, so we do that here.
2265
       * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2266
       */
2267
63
      DISSECTOR_ASSERT(!is_relative);
2268
2269
63
      if (length == 8) {
2270
63
        time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2271
        /*
2272
         * Convert 1/2^32s of a second to nanoseconds.
2273
         */
2274
63
        time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2275
63
      } else {
2276
0
        time_stamp->secs  = 0;
2277
0
        time_stamp->nsecs = 0;
2278
0
        report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2279
0
      }
2280
63
      break;
2281
2282
65
    case ENC_TIME_MIP6 | ENC_BIG_ENDIAN:
2283
      /*
2284
      * MIP6 time stamp, big-endian.
2285
      * A 64-bit unsigned integer field containing a timestamp.  The
2286
      * value indicates the number of seconds since January 1, 1970,
2287
      * 00:00 UTC, by using a fixed point format.  In this format, the
2288
      * integer number of seconds is contained in the first 48 bits of
2289
      * the field, and the remaining 16 bits indicate the number of
2290
      * 1/65536 fractions of a second.
2291
2292
      * Only supported for absolute times.
2293
      */
2294
65
      DISSECTOR_ASSERT(!is_relative);
2295
2296
65
      if (length == 8) {
2297
        /* We need a temporary variable here so the casting and fractions
2298
        * of a second work correctly.
2299
        */
2300
65
        tmp64secs = tvb_get_ntoh48(tvb, start);
2301
65
        tmpsecs = tvb_get_ntohs(tvb, start + 6);
2302
65
        tmpsecs <<= 16;
2303
2304
65
        if ((tmp64secs == 0) && (tmpsecs == 0)) {
2305
          //This is "NULL" time
2306
1
          time_stamp->secs = 0;
2307
1
          time_stamp->nsecs = 0;
2308
64
        } else {
2309
64
          time_stamp->secs = (time_t)tmp64secs;
2310
64
          time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2311
64
        }
2312
65
      } else {
2313
0
        time_stamp->secs = 0;
2314
0
        time_stamp->nsecs = 0;
2315
0
        report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2316
0
      }
2317
65
      break;
2318
2319
41
    case ENC_TIME_SECS_USECS|ENC_BIG_ENDIAN:
2320
      /*
2321
       * If the length is 16, 8-byte seconds, followed
2322
       * by 8-byte fractional time in microseconds,
2323
       * both big-endian.
2324
       *
2325
       * If the length is 12, 8-byte seconds, followed
2326
       * by 4-byte fractional time in microseconds,
2327
       * both big-endian.
2328
       *
2329
       * If the length is 8, 4-byte seconds, followed
2330
       * by 4-byte fractional time in microseconds,
2331
       * both big-endian.
2332
       *
2333
       * For absolute times, the seconds are seconds
2334
       * since the UN*X epoch.
2335
       */
2336
41
      if (length == 16) {
2337
0
        time_stamp->secs  = (time_t)tvb_get_ntoh64(tvb, start);
2338
0
        time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2339
41
      } else if (length == 12) {
2340
0
        time_stamp->secs  = (time_t)tvb_get_ntoh64(tvb, start);
2341
0
        time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2342
41
      } else if (length == 8) {
2343
40
        time_stamp->secs  = (time_t)tvb_get_ntohl(tvb, start);
2344
40
        time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2345
40
      } else {
2346
1
        time_stamp->secs  = 0;
2347
1
        time_stamp->nsecs = 0;
2348
1
        report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2349
1
      }
2350
41
      break;
2351
2352
0
    case ENC_TIME_SECS_USECS|ENC_LITTLE_ENDIAN:
2353
      /*
2354
       * If the length is 16, 8-byte seconds, followed
2355
       * by 8-byte fractional time in microseconds,
2356
       * both little-endian.
2357
       *
2358
       * If the length is 12, 8-byte seconds, followed
2359
       * by 4-byte fractional time in microseconds,
2360
       * both little-endian.
2361
       *
2362
       * If the length is 8, 4-byte seconds, followed
2363
       * by 4-byte fractional time in microseconds,
2364
       * both little-endian.
2365
       *
2366
       * For absolute times, the seconds are seconds
2367
       * since the UN*X epoch.
2368
       */
2369
0
      if (length == 16) {
2370
0
        time_stamp->secs  = (time_t)tvb_get_letoh64(tvb, start);
2371
0
        time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2372
0
      } else if (length == 12) {
2373
0
        time_stamp->secs  = (time_t)tvb_get_letoh64(tvb, start);
2374
0
        time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2375
0
      } else if (length == 8) {
2376
0
        time_stamp->secs  = (time_t)tvb_get_letohl(tvb, start);
2377
0
        time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2378
0
      } else {
2379
0
        time_stamp->secs  = 0;
2380
0
        time_stamp->nsecs = 0;
2381
0
        report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2382
0
      }
2383
0
      break;
2384
2385
613
    case ENC_TIME_SECS|ENC_BIG_ENDIAN:
2386
623
    case ENC_TIME_SECS|ENC_LITTLE_ENDIAN:
2387
      /*
2388
       * Seconds, 1 to 8 bytes.
2389
       * For absolute times, it's seconds since the
2390
       * UN*X epoch.
2391
       */
2392
623
      if (length >= 1 && length <= 8) {
2393
623
        time_stamp->secs  = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2394
623
        time_stamp->nsecs = 0;
2395
623
      } else {
2396
0
        time_stamp->secs  = 0;
2397
0
        time_stamp->nsecs = 0;
2398
0
        report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2399
0
      }
2400
623
      break;
2401
2402
2
    case ENC_TIME_MSECS|ENC_BIG_ENDIAN:
2403
2
    case ENC_TIME_MSECS|ENC_LITTLE_ENDIAN:
2404
      /*
2405
       * Milliseconds, 1 to 8 bytes.
2406
       * For absolute times, it's milliseconds since the
2407
       * UN*X epoch.
2408
       */
2409
2
      if (length >= 1 && length <= 8) {
2410
2
        uint64_t msecs;
2411
2412
2
        msecs = get_uint64_value(tree, tvb, start, length, encoding);
2413
2
        time_stamp->secs  = (time_t)(msecs / 1000);
2414
2
        time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2415
2
      } else {
2416
0
        time_stamp->secs  = 0;
2417
0
        time_stamp->nsecs = 0;
2418
0
        report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2419
0
      }
2420
2
      break;
2421
2422
0
    case ENC_TIME_USECS|ENC_BIG_ENDIAN:
2423
58
    case ENC_TIME_USECS|ENC_LITTLE_ENDIAN:
2424
      /*
2425
      * Microseconds, 1 to 8 bytes.
2426
      * For absolute times, it's microseconds since the
2427
      * UN*X epoch.
2428
      */
2429
58
      if (length >= 1 && length <= 8) {
2430
58
        uint64_t usecs;
2431
2432
58
        usecs = get_uint64_value(tree, tvb, start, length, encoding);
2433
58
        time_stamp->secs  = (time_t)(usecs / 1000000);
2434
58
        time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2435
58
      } else {
2436
0
        time_stamp->secs  = 0;
2437
0
        time_stamp->nsecs = 0;
2438
0
        report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2439
0
      }
2440
58
      break;
2441
2442
1
    case ENC_TIME_NSECS|ENC_BIG_ENDIAN:
2443
663
    case ENC_TIME_NSECS|ENC_LITTLE_ENDIAN:
2444
      /*
2445
       * nanoseconds, 1 to 8 bytes.
2446
       * For absolute times, it's nanoseconds since the
2447
       * UN*X epoch.
2448
       */
2449
2450
663
      if (length >= 1 && length <= 8) {
2451
663
        uint64_t nsecs;
2452
2453
663
        nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2454
663
        time_stamp->secs  = (time_t)(nsecs / 1000000000);
2455
663
        time_stamp->nsecs = (int)(nsecs % 1000000000);
2456
663
      } else {
2457
0
        time_stamp->secs  = 0;
2458
0
        time_stamp->nsecs = 0;
2459
0
        report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2460
0
      }
2461
663
      break;
2462
2463
10
    case ENC_TIME_RFC_3971|ENC_BIG_ENDIAN:
2464
      /*
2465
       * 1/64ths of a second since the UN*X epoch,
2466
       * big-endian.
2467
       *
2468
       * Only supported for absolute times.
2469
       */
2470
10
      DISSECTOR_ASSERT(!is_relative);
2471
2472
10
      if (length == 8) {
2473
        /*
2474
         * The upper 48 bits are seconds since the
2475
         * UN*X epoch.
2476
         */
2477
10
        time_stamp->secs  = (time_t)tvb_get_ntoh48(tvb, start);
2478
        /*
2479
         * The lower 16 bits are 1/2^16s of a second;
2480
         * convert them to nanoseconds.
2481
         *
2482
         * XXX - this may give the impression of higher
2483
         * precision than you actually get.
2484
         */
2485
10
        time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2486
10
      } else {
2487
0
        time_stamp->secs  = 0;
2488
0
        time_stamp->nsecs = 0;
2489
0
        report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2490
0
      }
2491
10
      break;
2492
2493
0
    case ENC_TIME_RFC_3971|ENC_LITTLE_ENDIAN:
2494
      /*
2495
       * 1/64ths of a second since the UN*X epoch,
2496
       * little-endian.
2497
       *
2498
       * Only supported for absolute times.
2499
       */
2500
0
      DISSECTOR_ASSERT(!is_relative);
2501
2502
0
      if (length == 8) {
2503
        /*
2504
         * XXX - this is assuming that, if anybody
2505
         * were ever to use this format - RFC 3971
2506
         * doesn't, because that's an Internet
2507
         * protocol, and those use network byte
2508
         * order, i.e. big-endian - they'd treat it
2509
         * as a 64-bit count of 1/2^16s of a second,
2510
         * putting the upper 48 bits at the end.
2511
         *
2512
         * The lower 48 bits are seconds since the
2513
         * UN*X epoch.
2514
         */
2515
0
        time_stamp->secs  = (time_t)tvb_get_letoh48(tvb, start+2);
2516
        /*
2517
         * The upper 16 bits are 1/2^16s of a second;
2518
         * convert them to nanoseconds.
2519
         *
2520
         * XXX - this may give the impression of higher
2521
         * precision than you actually get.
2522
         */
2523
0
        time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2524
0
      } else {
2525
0
        time_stamp->secs  = 0;
2526
0
        time_stamp->nsecs = 0;
2527
0
        report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2528
0
      }
2529
0
      break;
2530
2531
2
    case ENC_TIME_SECS_NTP|ENC_BIG_ENDIAN:
2532
      /*
2533
       * NTP time stamp, with 1-second resolution (i.e.,
2534
       * seconds since the NTP epoch), big-endian.
2535
       * Only supported for absolute times.
2536
       */
2537
2
      DISSECTOR_ASSERT(!is_relative);
2538
2539
2
      if (length == 4) {
2540
        /*
2541
        * We need a temporary variable here so the unsigned math
2542
        * works correctly (for years > 2036 according to RFC 2030
2543
        * chapter 3).
2544
        *
2545
        * If bit 0 is set, the UTC time is in the range 1968-2036 and
2546
        * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2547
        * If bit 0 is not set, the time is in the range 2036-2104 and
2548
        * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2549
        */
2550
2
        tmpsecs  = tvb_get_ntohl(tvb, start);
2551
2
        if ((tmpsecs & 0x80000000) != 0)
2552
1
          time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2553
1
        else
2554
1
          time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2555
2
        time_stamp->nsecs = 0;
2556
2
      } else {
2557
0
        time_stamp->secs  = 0;
2558
0
        time_stamp->nsecs = 0;
2559
0
        report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2560
0
      }
2561
2
      break;
2562
2563
0
    case ENC_TIME_SECS_NTP|ENC_LITTLE_ENDIAN:
2564
      /*
2565
       * NTP time stamp, with 1-second resolution (i.e.,
2566
       * seconds since the NTP epoch), little-endian.
2567
       * Only supported for absolute times.
2568
       */
2569
0
      DISSECTOR_ASSERT(!is_relative);
2570
2571
      /*
2572
       * We need a temporary variable here so the unsigned math
2573
       * works correctly (for years > 2036 according to RFC 2030
2574
       * chapter 3).
2575
       *
2576
       * If bit 0 is set, the UTC time is in the range 1968-2036 and
2577
       * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2578
       * If bit 0 is not set, the time is in the range 2036-2104 and
2579
       * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2580
       */
2581
0
      if (length == 4) {
2582
0
        tmpsecs  = tvb_get_letohl(tvb, start);
2583
0
        if ((tmpsecs & 0x80000000) != 0)
2584
0
          time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC);
2585
0
        else
2586
0
          time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC);
2587
0
        time_stamp->nsecs = 0;
2588
0
      } else {
2589
0
        time_stamp->secs  = 0;
2590
0
        time_stamp->nsecs = 0;
2591
0
        report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2592
0
      }
2593
0
      break;
2594
2595
3
    case ENC_TIME_MSEC_NTP | ENC_BIG_ENDIAN:
2596
      /*
2597
      * Milliseconds, 6 to 8 bytes.
2598
      * For absolute times, it's milliseconds since the
2599
      * NTP epoch.
2600
      *
2601
      * ETSI TS 129.274 8.119 defines this as:
2602
      * "a 48 bit unsigned integer in network order format
2603
      * ...encoded as the number of milliseconds since
2604
      * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2605
      * rounded value of 1000 x the value of the 64-bit
2606
      * timestamp (Seconds + (Fraction / (1<<32))) defined
2607
      * in clause 6 of IETF RFC 5905."
2608
      *
2609
      * Taken literally, the part after "i.e." would
2610
      * mean that the value rolls over before reaching
2611
      * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2612
      * when the 64 bit timestamp rolls over, and we have
2613
      * to pick an NTP Era equivalence class to support
2614
      * (such as 1968-01-20 to 2104-02-06).
2615
      *
2616
      * OTOH, the extra room might be used to store Era
2617
      * information instead, in which case times until
2618
      * 10819-08-03 can be represented with 6 bytes without
2619
      * ambiguity. We handle both implementations, and assume
2620
      * that times before 1968-01-20 are not represented.
2621
      *
2622
      * Only 6 bytes or more makes sense as an absolute
2623
      * time. 5 bytes or fewer could express a span of
2624
      * less than 35 years, either 1900-1934 or 2036-2070.
2625
      */
2626
3
      if (length >= 6 && length <= 8) {
2627
3
        uint64_t msecs;
2628
2629
3
        msecs = get_uint64_value(tree, tvb, start, length, encoding);
2630
3
        tmp64secs = (msecs / 1000);
2631
        /*
2632
         * Assume that times in the first half of NTP
2633
         * Era 0 really represent times in the NTP
2634
         * Era 1.
2635
         */
2636
3
        if (tmp64secs >= 0x80000000)
2637
2
          time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC);
2638
1
        else
2639
1
          time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC);
2640
3
        time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2641
3
      }
2642
0
      else {
2643
0
        time_stamp->secs  = 0;
2644
0
        time_stamp->nsecs = 0;
2645
0
        report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2646
0
      }
2647
3
      break;
2648
2649
0
    case ENC_TIME_MP4_FILE_SECS|ENC_BIG_ENDIAN:
2650
      /*
2651
       * MP4 file time stamps, big-endian.
2652
       * Only supported for absolute times.
2653
       */
2654
0
      DISSECTOR_ASSERT(!is_relative);
2655
2656
0
      if (length == 8) {
2657
0
        tmp64secs  = tvb_get_ntoh64(tvb, start);
2658
0
        time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC);
2659
0
        time_stamp->nsecs = 0;
2660
0
      } else if (length == 4) {
2661
0
        tmpsecs  = tvb_get_ntohl(tvb, start);
2662
0
        time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC);
2663
0
        time_stamp->nsecs = 0;
2664
0
      } else {
2665
0
        time_stamp->secs  = 0;
2666
0
        time_stamp->nsecs = 0;
2667
0
        report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2668
0
      }
2669
0
      break;
2670
2671
0
    case ENC_TIME_ZBEE_ZCL | ENC_BIG_ENDIAN:
2672
      /*
2673
       * Zigbee ZCL time stamps, big-endian.
2674
       * Only supported for absolute times.
2675
       */
2676
0
      DISSECTOR_ASSERT(!is_relative);
2677
2678
0
      if (length == 8) {
2679
0
        tmp64secs  = tvb_get_ntoh64(tvb, start);
2680
0
        time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC);
2681
0
        time_stamp->nsecs = 0;
2682
0
      } else if (length == 4) {
2683
0
        tmpsecs  = tvb_get_ntohl(tvb, start);
2684
0
        time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC);
2685
0
        time_stamp->nsecs = 0;
2686
0
      } else {
2687
0
        time_stamp->secs  = 0;
2688
0
        time_stamp->nsecs = 0;
2689
0
        report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2690
0
      }
2691
0
      break;
2692
2693
224
    case ENC_TIME_ZBEE_ZCL | ENC_LITTLE_ENDIAN:
2694
      /*
2695
       * Zigbee ZCL time stamps, little-endian.
2696
       * Only supported for absolute times.
2697
       */
2698
224
      DISSECTOR_ASSERT(!is_relative);
2699
2700
224
      if (length == 8) {
2701
0
        tmp64secs  = tvb_get_letoh64(tvb, start);
2702
0
        time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC);
2703
0
        time_stamp->nsecs = 0;
2704
224
      } else if (length == 4) {
2705
224
        tmpsecs  = tvb_get_letohl(tvb, start);
2706
224
        time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC);
2707
224
        time_stamp->nsecs = 0;
2708
224
      } else {
2709
0
        time_stamp->secs  = 0;
2710
0
        time_stamp->nsecs = 0;
2711
0
        report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2712
0
      }
2713
224
      break;
2714
2715
0
    default:
2716
0
      DISSECTOR_ASSERT_NOT_REACHED();
2717
0
      break;
2718
4.86k
  }
2719
4.86k
}
2720
2721
static void
2722
tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2723
35.4M
{
2724
35.4M
  const header_field_info *hfinfo = fi->hfinfo;
2725
2726
35.4M
  if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2727
75
    GPtrArray *ptrs = NULL;
2728
2729
75
    if (tree_data->interesting_hfids == NULL) {
2730
      /* Initialize the hash because we now know that it is needed */
2731
2
      tree_data->interesting_hfids =
2732
2
        g_hash_table_new(g_direct_hash, NULL /* g_direct_equal */);
2733
73
    } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2734
66
      ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2735
66
             GINT_TO_POINTER(hfinfo->id));
2736
66
    }
2737
2738
75
    if (!ptrs) {
2739
      /* First element triggers the creation of pointer array */
2740
75
      ptrs = g_ptr_array_new();
2741
75
      g_hash_table_insert(tree_data->interesting_hfids,
2742
75
              GINT_TO_POINTER(hfinfo->id), ptrs);
2743
75
    }
2744
2745
75
    g_ptr_array_add(ptrs, fi);
2746
75
  }
2747
35.4M
}
2748
2749
2750
/*
2751
 * Validates that field length bytes are available starting from
2752
 * start (pos/neg). Throws an exception if they aren't.
2753
 */
2754
static void
2755
test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2756
      int start, int length, const unsigned encoding)
2757
31.8M
{
2758
31.8M
  int size = length;
2759
2760
31.8M
  if (!tvb)
2761
395k
    return;
2762
2763
31.4M
  if ((hfinfo->type == FT_STRINGZ) ||
2764
31.4M
      ((encoding & ENC_VARINT_MASK) &&
2765
38.2k
       (FT_IS_UINT(hfinfo->type) || FT_IS_INT(hfinfo->type)))) {
2766
    /* If we're fetching until the end of the TVB, only validate
2767
     * that the offset is within range.
2768
     */
2769
38.2k
    if (length == -1)
2770
309
      size = 0;
2771
38.2k
  }
2772
2773
31.4M
  tvb_ensure_bytes_exist(tvb, start, size);
2774
31.4M
}
2775
2776
static void
2777
detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2778
92.7k
{
2779
92.7k
  bool found_stray_character = false;
2780
2781
92.7k
  if (!string)
2782
0
    return;
2783
2784
92.7k
  switch (encoding & ENC_CHARENCODING_MASK) {
2785
79.5k
    case ENC_ASCII:
2786
89.2k
    case ENC_UTF_8:
2787
177k
      for (int i = (int)strlen(string); i < length; i++) {
2788
109k
        if (string[i] != '\0') {
2789
21.2k
          found_stray_character = true;
2790
21.2k
          break;
2791
21.2k
        }
2792
109k
      }
2793
89.2k
      break;
2794
2795
3.42k
    default:
2796
3.42k
      break;
2797
92.7k
  }
2798
2799
92.7k
  if (found_stray_character) {
2800
21.2k
    expert_add_info(NULL, pi, &ei_string_trailing_characters);
2801
21.2k
  }
2802
92.7k
}
2803
2804
static void
2805
free_fvalue_cb(void *data)
2806
286
{
2807
286
  fvalue_t *fv = (fvalue_t*)data;
2808
286
  fvalue_free(fv);
2809
286
}
2810
2811
/* Add an item to a proto_tree, using the text label registered to that item;
2812
   the item is extracted from the tvbuff handed to it. */
2813
static proto_item *
2814
proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2815
        tvbuff_t *tvb, int start, int length,
2816
        unsigned encoding)
2817
10.7M
{
2818
10.7M
  proto_item *pi;
2819
10.7M
  uint32_t      value, n;
2820
10.7M
  uint64_t      value64;
2821
10.7M
  ws_in4_addr ipv4_value;
2822
10.7M
  float     floatval;
2823
10.7M
  double      doubleval;
2824
10.7M
  const char *stringval = NULL;
2825
10.7M
  nstime_t    time_stamp;
2826
10.7M
  bool        length_error;
2827
2828
  /* Ensure that the newly created fvalue_t is freed if we throw an
2829
   * exception before adding it to the tree. (gcc creates clobbering
2830
   * when it optimizes the equivalent TRY..EXCEPT implementation.)
2831
   * XXX: Move the new_field_info() call inside here?
2832
   */
2833
10.7M
  CLEANUP_PUSH(free_fvalue_cb, new_fi->value);
2834
2835
10.7M
  switch (new_fi->hfinfo->type) {
2836
2.76M
    case FT_NONE:
2837
      /* no value to set for FT_NONE */
2838
2.76M
      break;
2839
2840
673k
    case FT_PROTOCOL:
2841
673k
      proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2842
673k
      break;
2843
2844
642k
    case FT_BYTES:
2845
642k
      proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2846
642k
      break;
2847
2848
1.85k
    case FT_UINT_BYTES:
2849
1.85k
      n = get_uint_value(tree, tvb, start, length, encoding);
2850
1.85k
      proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2851
2852
      /* Instead of calling proto_item_set_len(), since we don't yet
2853
       * have a proto_item, we set the field_info's length ourselves. */
2854
1.85k
      new_fi->length = n + length;
2855
1.85k
      break;
2856
2857
838k
    case FT_BOOLEAN:
2858
      /*
2859
       * Map all non-zero values to little-endian for
2860
       * backwards compatibility.
2861
       */
2862
838k
      if (encoding)
2863
101k
        encoding = ENC_LITTLE_ENDIAN;
2864
838k
      proto_tree_set_boolean(new_fi,
2865
838k
        get_uint64_value(tree, tvb, start, length, encoding));
2866
838k
      break;
2867
2868
1.36k
    case FT_CHAR:
2869
    /* XXX - make these just FT_UINT? */
2870
3.08M
    case FT_UINT8:
2871
4.17M
    case FT_UINT16:
2872
4.27M
    case FT_UINT24:
2873
4.83M
    case FT_UINT32:
2874
4.83M
      if (encoding & ENC_VARINT_MASK) {
2875
13
        new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2876
13
        value = (uint32_t)value64;
2877
13
        if (!(encoding & ENC_VARINT_QUIC)) {
2878
13
          new_fi->flags |= FI_VARINT;
2879
13
        }
2880
13
      }
2881
4.83M
      else {
2882
        /*
2883
         * Map all non-zero values to little-endian for
2884
         * backwards compatibility.
2885
         */
2886
4.83M
        if (encoding)
2887
605k
          encoding = ENC_LITTLE_ENDIAN;
2888
2889
4.83M
        value = get_uint_value(tree, tvb, start, length, encoding);
2890
4.83M
      }
2891
4.83M
      proto_tree_set_uint(new_fi, value);
2892
4.83M
      break;
2893
2894
14.0k
    case FT_UINT40:
2895
15.0k
    case FT_UINT48:
2896
15.0k
    case FT_UINT56:
2897
42.4k
    case FT_UINT64:
2898
42.4k
      if (encoding & ENC_VARINT_MASK) {
2899
181
        new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value64, encoding);
2900
181
        if (!(encoding & ENC_VARINT_QUIC)) {
2901
181
          new_fi->flags |= FI_VARINT;
2902
181
        }
2903
181
      }
2904
42.2k
      else {
2905
        /*
2906
         * Map all other non-zero values to little-endian for
2907
         * backwards compatibility.
2908
         */
2909
42.2k
        if (encoding)
2910
17.5k
          encoding = ENC_LITTLE_ENDIAN;
2911
2912
42.2k
        value64 = get_uint64_value(tree, tvb, start, length, encoding);
2913
42.2k
      }
2914
42.4k
      proto_tree_set_uint64(new_fi, value64);
2915
42.4k
      break;
2916
2917
    /* XXX - make these just FT_INT? */
2918
345k
    case FT_INT8:
2919
641k
    case FT_INT16:
2920
642k
    case FT_INT24:
2921
658k
    case FT_INT32:
2922
      /*
2923
       * Map all non-zero values to little-endian for
2924
       * backwards compatibility.
2925
       */
2926
658k
      if (encoding)
2927
13.2k
        encoding = ENC_LITTLE_ENDIAN;
2928
658k
      proto_tree_set_int(new_fi,
2929
658k
        get_int_value(tree, tvb, start, length, encoding));
2930
658k
      break;
2931
2932
0
    case FT_INT40:
2933
0
    case FT_INT48:
2934
0
    case FT_INT56:
2935
5.28k
    case FT_INT64:
2936
      /*
2937
       * Map all non-zero values to little-endian for
2938
       * backwards compatibility.
2939
       */
2940
5.28k
      if (encoding)
2941
2.61k
        encoding = ENC_LITTLE_ENDIAN;
2942
5.28k
      proto_tree_set_int64(new_fi,
2943
5.28k
        get_int64_value(tree, tvb, start, length, encoding));
2944
5.28k
      break;
2945
2946
27.4k
    case FT_IPv4:
2947
      /*
2948
       * Map all non-zero values to little-endian for
2949
       * backwards compatibility.
2950
       */
2951
27.4k
      if (encoding)
2952
96
        encoding = ENC_LITTLE_ENDIAN;
2953
27.4k
      if (length != FT_IPv4_LEN) {
2954
5
        length_error = length < FT_IPv4_LEN ? true : false;
2955
5
        report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2956
5
      }
2957
27.4k
      ipv4_value = tvb_get_ipv4(tvb, start);
2958
      /*
2959
       * NOTE: to support code written when
2960
       * proto_tree_add_item() took a bool as its
2961
       * last argument, with false meaning "big-endian"
2962
       * and true meaning "little-endian", we treat any
2963
       * non-zero value of "encoding" as meaning
2964
       * "little-endian".
2965
       */
2966
27.4k
      proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(ipv4_value) : ipv4_value);
2967
27.4k
      break;
2968
2969
443
    case FT_IPXNET:
2970
443
      if (length != FT_IPXNET_LEN) {
2971
0
        length_error = length < FT_IPXNET_LEN ? true : false;
2972
0
        report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2973
0
      }
2974
443
      proto_tree_set_ipxnet(new_fi,
2975
443
        get_uint_value(tree, tvb, start, FT_IPXNET_LEN, ENC_BIG_ENDIAN));
2976
443
      break;
2977
2978
62.5k
    case FT_IPv6:
2979
62.5k
      if (length != FT_IPv6_LEN) {
2980
6
        length_error = length < FT_IPv6_LEN ? true : false;
2981
6
        report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2982
6
      }
2983
62.5k
      proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2984
62.5k
      break;
2985
2986
382
    case FT_FCWWN:
2987
382
      if (length != FT_FCWWN_LEN) {
2988
0
        length_error = length < FT_FCWWN_LEN ? true : false;
2989
0
        report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2990
0
      }
2991
382
      proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2992
382
      break;
2993
2994
478
    case FT_AX25:
2995
478
      if (length != 7) {
2996
0
        length_error = length < 7 ? true : false;
2997
0
        report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2998
0
      }
2999
478
      proto_tree_set_ax25_tvb(new_fi, tvb, start);
3000
478
      break;
3001
3002
227
    case FT_VINES:
3003
227
      if (length != VINES_ADDR_LEN) {
3004
0
        length_error = length < VINES_ADDR_LEN ? true : false;
3005
0
        report_type_length_mismatch(tree, "a Vines address", length, length_error);
3006
0
      }
3007
227
      proto_tree_set_vines_tvb(new_fi, tvb, start);
3008
227
      break;
3009
3010
105k
    case FT_ETHER:
3011
105k
      if (length != FT_ETHER_LEN) {
3012
149
        length_error = length < FT_ETHER_LEN ? true : false;
3013
149
        report_type_length_mismatch(tree, "a MAC address", length, length_error);
3014
149
      }
3015
105k
      proto_tree_set_ether_tvb(new_fi, tvb, start);
3016
105k
      break;
3017
3018
5.14k
    case FT_EUI64:
3019
      /*
3020
       * Map all non-zero values to little-endian for
3021
       * backwards compatibility.
3022
       */
3023
5.14k
      if (encoding)
3024
5.11k
        encoding = ENC_LITTLE_ENDIAN;
3025
5.14k
      if (length != FT_EUI64_LEN) {
3026
0
        length_error = length < FT_EUI64_LEN ? true : false;
3027
0
        report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3028
0
      }
3029
5.14k
      proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3030
5.14k
      break;
3031
793
    case FT_GUID:
3032
      /*
3033
       * Map all non-zero values to little-endian for
3034
       * backwards compatibility.
3035
       */
3036
793
      if (encoding)
3037
14
        encoding = ENC_LITTLE_ENDIAN;
3038
793
      if (length != FT_GUID_LEN) {
3039
11
        length_error = length < FT_GUID_LEN ? true : false;
3040
11
        report_type_length_mismatch(tree, "a GUID", length, length_error);
3041
11
      }
3042
793
      proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3043
793
      break;
3044
3045
684
    case FT_OID:
3046
710
    case FT_REL_OID:
3047
710
      proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3048
710
      break;
3049
3050
3.79k
    case FT_SYSTEM_ID:
3051
3.79k
      proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3052
3.79k
      break;
3053
3054
2.05k
    case FT_FLOAT:
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
       * At some point in the future, we might
3064
       * support non-IEEE-binary floating-point
3065
       * formats in the encoding as well
3066
       * (IEEE decimal, System/3x0, VAX).
3067
       */
3068
2.05k
      if (encoding)
3069
897
        encoding = ENC_LITTLE_ENDIAN;
3070
2.05k
      if (length != 4) {
3071
0
        length_error = length < 4 ? true : false;
3072
0
        report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3073
0
      }
3074
2.05k
      if (encoding)
3075
897
        floatval = tvb_get_letohieee_float(tvb, start);
3076
1.15k
      else
3077
1.15k
        floatval = tvb_get_ntohieee_float(tvb, start);
3078
2.05k
      proto_tree_set_float(new_fi, floatval);
3079
2.05k
      break;
3080
3081
1.73k
    case FT_DOUBLE:
3082
      /*
3083
       * NOTE: to support code written when
3084
       * proto_tree_add_item() took a bool as its
3085
       * last argument, with false meaning "big-endian"
3086
       * and true meaning "little-endian", we treat any
3087
       * non-zero value of "encoding" as meaning
3088
       * "little-endian".
3089
       *
3090
       * At some point in the future, we might
3091
       * support non-IEEE-binary floating-point
3092
       * formats in the encoding as well
3093
       * (IEEE decimal, System/3x0, VAX).
3094
       */
3095
1.73k
      if (encoding == true)
3096
0
        encoding = ENC_LITTLE_ENDIAN;
3097
1.73k
      if (length != 8) {
3098
0
        length_error = length < 8 ? true : false;
3099
0
        report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3100
0
      }
3101
1.73k
      if (encoding)
3102
1.33k
        doubleval = tvb_get_letohieee_double(tvb, start);
3103
394
      else
3104
394
        doubleval = tvb_get_ntohieee_double(tvb, start);
3105
1.73k
      proto_tree_set_double(new_fi, doubleval);
3106
1.73k
      break;
3107
3108
84.6k
    case FT_STRING:
3109
84.6k
      stringval = (const char*)get_string_value(PNODE_POOL(tree),
3110
84.6k
          tvb, start, length, &length, encoding);
3111
84.6k
      proto_tree_set_string(new_fi, stringval);
3112
3113
      /* Instead of calling proto_item_set_len(), since we
3114
       * don't yet have a proto_item, we set the
3115
       * field_info's length ourselves.
3116
       *
3117
       * XXX - our caller can't use that length to
3118
       * advance an offset unless they arrange that
3119
       * there always be a protocol tree into which
3120
       * we're putting this item.
3121
       */
3122
84.6k
      new_fi->length = length;
3123
84.6k
      break;
3124
3125
3.57k
    case FT_STRINGZ:
3126
3.57k
      stringval = (const char*)get_stringz_value(PNODE_POOL(tree),
3127
3.57k
          tree, tvb, start, length, &length, encoding);
3128
3.57k
      proto_tree_set_string(new_fi, stringval);
3129
3130
      /* Instead of calling proto_item_set_len(),
3131
       * since we don't yet have a proto_item, we
3132
       * set the field_info's length ourselves.
3133
       *
3134
       * XXX - our caller can't use that length to
3135
       * advance an offset unless they arrange that
3136
       * there always be a protocol tree into which
3137
       * we're putting this item.
3138
       */
3139
3.57k
      new_fi->length = length;
3140
3.57k
      break;
3141
3142
1.32k
    case FT_UINT_STRING:
3143
      /*
3144
       * NOTE: to support code written when
3145
       * proto_tree_add_item() took a bool as its
3146
       * last argument, with false meaning "big-endian"
3147
       * and true meaning "little-endian", if the
3148
       * encoding value is true, treat that as
3149
       * ASCII with a little-endian length.
3150
       *
3151
       * This won't work for code that passes
3152
       * arbitrary non-zero values; that code
3153
       * will need to be fixed.
3154
       */
3155
1.32k
      if (encoding == true)
3156
0
        encoding = ENC_ASCII|ENC_LITTLE_ENDIAN;
3157
1.32k
      stringval = (const char*)get_uint_string_value(PNODE_POOL(tree),
3158
1.32k
          tree, tvb, start, length, &length, encoding);
3159
1.32k
      proto_tree_set_string(new_fi, stringval);
3160
3161
      /* Instead of calling proto_item_set_len(), since we
3162
       * don't yet have a proto_item, we set the
3163
       * field_info's length ourselves.
3164
       *
3165
       * XXX - our caller can't use that length to
3166
       * advance an offset unless they arrange that
3167
       * there always be a protocol tree into which
3168
       * we're putting this item.
3169
       */
3170
1.32k
      new_fi->length = length;
3171
1.32k
      break;
3172
3173
389
    case FT_STRINGZPAD:
3174
389
      stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree),
3175
389
          tvb, start, length, &length, encoding);
3176
389
      proto_tree_set_string(new_fi, stringval);
3177
3178
      /* Instead of calling proto_item_set_len(), since we
3179
       * don't yet have a proto_item, we set the
3180
       * field_info's length ourselves.
3181
       *
3182
       * XXX - our caller can't use that length to
3183
       * advance an offset unless they arrange that
3184
       * there always be a protocol tree into which
3185
       * we're putting this item.
3186
       */
3187
389
      new_fi->length = length;
3188
389
      break;
3189
3190
674
    case FT_STRINGZTRUNC:
3191
674
      stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree),
3192
674
          tvb, start, length, &length, encoding);
3193
674
      proto_tree_set_string(new_fi, stringval);
3194
3195
      /* Instead of calling proto_item_set_len(), since we
3196
       * don't yet have a proto_item, we set the
3197
       * field_info's length ourselves.
3198
       *
3199
       * XXX - our caller can't use that length to
3200
       * advance an offset unless they arrange that
3201
       * there always be a protocol tree into which
3202
       * we're putting this item.
3203
       */
3204
674
      new_fi->length = length;
3205
674
      break;
3206
3207
4.55k
    case FT_ABSOLUTE_TIME:
3208
      /*
3209
       * Absolute times can be in any of a number of
3210
       * formats, and they can be big-endian or
3211
       * little-endian.
3212
       *
3213
       * Historically FT_TIMEs were only timespecs;
3214
       * the only question was whether they were stored
3215
       * in big- or little-endian format.
3216
       *
3217
       * For backwards compatibility, we interpret an
3218
       * encoding of 1 as meaning "little-endian timespec",
3219
       * so that passing true is interpreted as that.
3220
       */
3221
4.55k
      if (encoding == true)
3222
0
        encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;
3223
3224
4.55k
      get_time_value(tree, tvb, start, length, encoding, &time_stamp, false);
3225
3226
4.55k
      proto_tree_set_time(new_fi, &time_stamp);
3227
4.55k
      break;
3228
3229
226
    case FT_RELATIVE_TIME:
3230
      /*
3231
       * Relative times can be in any of a number of
3232
       * formats, and they can be big-endian or
3233
       * little-endian.
3234
       *
3235
       * Historically FT_TIMEs were only timespecs;
3236
       * the only question was whether they were stored
3237
       * in big- or little-endian format.
3238
       *
3239
       * For backwards compatibility, we interpret an
3240
       * encoding of 1 as meaning "little-endian timespec",
3241
       * so that passing true is interpreted as that.
3242
       */
3243
226
      if (encoding == true)
3244
0
        encoding = ENC_TIME_SECS_NSECS|ENC_LITTLE_ENDIAN;
3245
3246
226
      get_time_value(tree, tvb, start, length, encoding, &time_stamp, true);
3247
3248
226
      proto_tree_set_time(new_fi, &time_stamp);
3249
226
      break;
3250
10
    case FT_IEEE_11073_SFLOAT:
3251
10
      if (encoding)
3252
10
        encoding = ENC_LITTLE_ENDIAN;
3253
10
      if (length != 2) {
3254
0
        length_error = length < 2 ? true : false;
3255
0
        report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3256
0
      }
3257
3258
10
      fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3259
3260
10
      break;
3261
0
    case FT_IEEE_11073_FLOAT:
3262
0
      if (encoding)
3263
0
        encoding = ENC_LITTLE_ENDIAN;
3264
0
      if (length != 4) {
3265
0
        length_error = length < 4 ? true : false;
3266
0
        report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3267
0
      }
3268
0
      fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3269
3270
0
      break;
3271
0
    default:
3272
0
      REPORT_DISSECTOR_BUG("field %s is of unknown type %d (%s)",
3273
0
               new_fi->hfinfo->abbrev,
3274
0
               new_fi->hfinfo->type,
3275
0
               ftype_name(new_fi->hfinfo->type));
3276
0
      break;
3277
10.7M
  }
3278
10.7M
  FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
3279
3280
  /* Don't add new node to proto_tree until now so that any exceptions
3281
   * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3282
  /* XXX. wouldn't be better to add this item to tree, with some special
3283
   * flag (FI_EXCEPTION?) to know which item caused exception? For
3284
   * strings and bytes, we would have to set new_fi->value to something
3285
   * non-NULL, or otherwise ensure that proto_item_fill_display_label
3286
   * could handle NULL values. */
3287
10.7M
  CLEANUP_POP
3288
0
  pi = proto_tree_add_node(tree, new_fi);
3289
3290
10.7M
  switch (new_fi->hfinfo->type) {
3291
3292
84.6k
  case FT_STRING:
3293
    /* XXX: trailing stray character detection should be done
3294
           * _before_ conversion to UTF-8, because conversion can change
3295
           * the length, or else get_string_length should return a value
3296
           * for the "length in bytes of the string after conversion
3297
           * including internal nulls." (Noting that we do, for other
3298
           * reasons, still need the "length in bytes in the field",
3299
           * especially for FT_STRINGZ.)
3300
           *
3301
           * This is true even for ASCII and UTF-8, because
3302
           * substituting REPLACEMENT CHARACTERS for illegal characters
3303
           * can also do so (and for UTF-8 possibly even make the
3304
           * string _shorter_).
3305
           */
3306
84.6k
    detect_trailing_stray_characters(encoding, stringval, length, pi);
3307
84.6k
    break;
3308
3309
10.6M
  default:
3310
10.6M
    break;
3311
10.7M
  }
3312
3313
10.7M
  return pi;
3314
10.7M
}
3315
3316
proto_item *
3317
proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3318
                            const int start, int length,
3319
                            const unsigned encoding, int32_t *retval)
3320
7.44k
{
3321
7.44k
  header_field_info *hfinfo;
3322
7.44k
  field_info    *new_fi;
3323
7.44k
  int32_t      value;
3324
3325
7.44k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3326
3327
7.44k
  switch (hfinfo->type) {
3328
292
  case FT_INT8:
3329
692
  case FT_INT16:
3330
916
  case FT_INT24:
3331
7.44k
  case FT_INT32:
3332
7.44k
    break;
3333
0
  case FT_INT64:
3334
0
    REPORT_DISSECTOR_BUG("64-bit signed integer field %s used with proto_tree_add_item_ret_int()",
3335
0
        hfinfo->abbrev);
3336
0
  default:
3337
0
    REPORT_DISSECTOR_BUG("Non-signed-integer field %s used with proto_tree_add_item_ret_int()",
3338
7.44k
        hfinfo->abbrev);
3339
7.44k
  }
3340
3341
7.44k
  CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,
3342
7.44k
    {
3343
7.44k
      if(retval)
3344
7.44k
      {
3345
7.44k
        *retval = 0;
3346
7.44k
      }
3347
7.44k
    } );
3348
3349
5.97k
  if (encoding & ENC_STRING) {
3350
0
    REPORT_DISSECTOR_BUG("wrong encoding");
3351
0
  }
3352
  /* I believe it's ok if this is called with a NULL tree */
3353
5.97k
  value = get_int_value(tree, tvb, start, length, encoding);
3354
3355
5.97k
  if (retval) {
3356
5.91k
    int no_of_bits;
3357
5.91k
    *retval = value;
3358
5.91k
    if (hfinfo->bitmask) {
3359
      /* Mask out irrelevant portions */
3360
224
      *retval &= (uint32_t)(hfinfo->bitmask);
3361
      /* Shift bits */
3362
224
      *retval >>= hfinfo_bitshift(hfinfo);
3363
224
    }
3364
5.91k
    no_of_bits = ws_count_ones(hfinfo->bitmask);
3365
5.91k
    *retval = ws_sign_ext32(*retval, no_of_bits);
3366
5.91k
  }
3367
3368
5.97k
  CHECK_FOR_NULL_TREE(tree);
3369
3370
5.97k
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3371
3372
5.84k
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3373
3374
5.84k
  proto_tree_set_int(new_fi, value);
3375
3376
5.84k
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3377
3378
5.84k
  return proto_tree_add_node(tree, new_fi);
3379
5.97k
}
3380
3381
proto_item *
3382
proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3383
                             const int start, int length,
3384
                             const unsigned encoding, uint32_t *retval)
3385
5.37M
{
3386
5.37M
  header_field_info *hfinfo;
3387
5.37M
  field_info    *new_fi;
3388
5.37M
  uint32_t       value;
3389
3390
5.37M
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3391
3392
5.37M
  switch (hfinfo->type) {
3393
8.31k
  case FT_CHAR:
3394
4.21M
  case FT_UINT8:
3395
4.84M
  case FT_UINT16:
3396
5.30M
  case FT_UINT24:
3397
5.37M
  case FT_UINT32:
3398
5.37M
    break;
3399
0
  default:
3400
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
3401
5.37M
        hfinfo->abbrev);
3402
5.37M
  }
3403
3404
5.37M
  if (length == 0) {
3405
4.21k
    if (retval) {
3406
4.21k
      *retval = 0;
3407
4.21k
    }
3408
4.21k
    return NULL;
3409
4.21k
  }
3410
3411
5.37M
  if (encoding & ENC_STRING) {
3412
0
    REPORT_DISSECTOR_BUG("wrong encoding");
3413
0
  }
3414
  /* I believe it's ok if this is called with a NULL tree */
3415
  /* XXX - modify if we ever support EBCDIC FT_CHAR */
3416
5.37M
  if (encoding & ENC_VARINT_MASK) {
3417
0
    uint64_t temp64;
3418
0
    tvb_get_varint(tvb, start, length, &temp64, encoding);
3419
0
    value = (uint32_t)temp64;
3420
5.37M
  } else {
3421
5.37M
    value = get_uint_value(tree, tvb, start, length, encoding);
3422
5.37M
  }
3423
3424
5.37M
  if (retval) {
3425
5.36M
    *retval = value;
3426
5.36M
    if (hfinfo->bitmask) {
3427
      /* Mask out irrelevant portions */
3428
192k
      *retval &= (uint32_t)(hfinfo->bitmask);
3429
      /* Shift bits */
3430
192k
      *retval >>= hfinfo_bitshift(hfinfo);
3431
192k
    }
3432
5.36M
  }
3433
3434
5.37M
  CHECK_FOR_NULL_TREE(tree);
3435
3436
5.37M
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3437
3438
624k
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3439
3440
624k
  proto_tree_set_uint(new_fi, value);
3441
3442
624k
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3443
624k
  if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG|ENC_VARINT_SDNV)) {
3444
0
    new_fi->flags |= FI_VARINT;
3445
0
  }
3446
624k
  return proto_tree_add_node(tree, new_fi);
3447
5.37M
}
3448
3449
proto_item *
3450
proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3451
                               const int start, int length,
3452
                               const unsigned encoding, uint32_t *retval)
3453
2
{
3454
2
    return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3455
2
}
3456
3457
proto_item *
3458
proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3459
                              const int start, int length,
3460
                              const unsigned encoding, uint8_t *retval)
3461
3.48M
{
3462
    /* TODO: further restrict by hfinfo->type ? */
3463
3.48M
    uint32_t val32;
3464
3.48M
    proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3465
3.48M
    *retval = (uint8_t)val32;
3466
3.48M
    return item;
3467
3.48M
}
3468
3469
proto_item *
3470
proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3471
                               const int start, int length,
3472
                               const unsigned encoding, uint16_t *retval)
3473
46.0k
{
3474
    /* TODO: further restrict by hfinfo->type ? */
3475
46.0k
    uint32_t val32;
3476
46.0k
    proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3477
46.0k
    *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3478
46.0k
    return item;
3479
46.0k
}
3480
3481
3482
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3483
 * and returns proto_item* and uint value retrieved*/
3484
proto_item *
3485
ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3486
        const unsigned encoding, uint32_t *retval)
3487
506
{
3488
506
  field_info    *new_fi;
3489
506
  header_field_info *hfinfo;
3490
506
  unsigned     item_length;
3491
506
  unsigned     offset;
3492
506
  uint32_t     value;
3493
3494
506
  offset = ptvc->offset;
3495
506
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3496
3497
506
  switch (hfinfo->type) {
3498
0
  case FT_CHAR:
3499
130
  case FT_UINT8:
3500
506
  case FT_UINT16:
3501
506
  case FT_UINT24:
3502
506
  case FT_UINT32:
3503
506
    break;
3504
0
  default:
3505
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
3506
506
        hfinfo->abbrev);
3507
506
  }
3508
3509
506
  get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3510
506
  test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3511
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
506
  value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3515
3516
506
  if (retval) {
3517
505
    *retval = value;
3518
505
    if (hfinfo->bitmask) {
3519
      /* Mask out irrelevant portions */
3520
0
      *retval &= (uint32_t)(hfinfo->bitmask);
3521
      /* Shift bits */
3522
0
      *retval >>= hfinfo_bitshift(hfinfo);
3523
0
    }
3524
505
  }
3525
3526
506
  ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3527
3528
506
  CHECK_FOR_NULL_TREE(ptvc->tree);
3529
3530
  /* Coast clear. Try and fake it */
3531
506
  TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3532
3533
354
  new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3534
3535
354
  return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3536
354
    offset, length, encoding);
3537
506
}
3538
3539
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3540
 * and returns proto_item* and int value retrieved*/
3541
proto_item *
3542
ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3543
        const unsigned encoding, int32_t *retval)
3544
0
{
3545
0
  field_info    *new_fi;
3546
0
  header_field_info *hfinfo;
3547
0
  unsigned     item_length;
3548
0
  unsigned     offset;
3549
0
  uint32_t     value;
3550
3551
0
  offset = ptvc->offset;
3552
0
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3553
3554
0
  switch (hfinfo->type) {
3555
0
  case FT_INT8:
3556
0
  case FT_INT16:
3557
0
  case FT_INT24:
3558
0
  case FT_INT32:
3559
0
    break;
3560
0
  default:
3561
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
3562
0
        hfinfo->abbrev);
3563
0
  }
3564
3565
0
  get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3566
0
  test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3567
3568
  /* I believe it's ok if this is called with a NULL tree */
3569
  /* XXX - modify if we ever support EBCDIC FT_CHAR */
3570
0
  value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3571
3572
0
  if (retval) {
3573
0
    int no_of_bits;
3574
0
    *retval = value;
3575
0
    if (hfinfo->bitmask) {
3576
      /* Mask out irrelevant portions */
3577
0
      *retval &= (uint32_t)(hfinfo->bitmask);
3578
      /* Shift bits */
3579
0
      *retval >>= hfinfo_bitshift(hfinfo);
3580
0
    }
3581
0
    no_of_bits = ws_count_ones(hfinfo->bitmask);
3582
0
    *retval = ws_sign_ext32(*retval, no_of_bits);
3583
0
  }
3584
3585
0
  ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3586
3587
0
  CHECK_FOR_NULL_TREE(ptvc->tree);
3588
3589
  /* Coast clear. Try and fake it */
3590
0
  TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
3591
3592
0
  new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3593
3594
0
  return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3595
0
    offset, length, encoding);
3596
0
}
3597
3598
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3599
 * and returns proto_item* and string value retrieved */
3600
proto_item*
3601
ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3602
0
{
3603
0
  header_field_info *hfinfo;
3604
0
  field_info    *new_fi;
3605
0
  const uint8_t   *value;
3606
0
  unsigned    item_length;
3607
0
  unsigned    offset;
3608
3609
0
  offset = ptvc->offset;
3610
3611
0
  PROTO_REGISTRAR_GET_NTH(hf, hfinfo);
3612
3613
0
  switch (hfinfo->type) {
3614
0
  case FT_STRING:
3615
0
    value = get_string_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3616
0
    break;
3617
0
  case FT_STRINGZ:
3618
0
    value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3619
0
    break;
3620
0
  case FT_UINT_STRING:
3621
0
    value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3622
0
    break;
3623
0
  case FT_STRINGZPAD:
3624
0
    value = get_stringzpad_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3625
0
    break;
3626
0
  case FT_STRINGZTRUNC:
3627
0
    value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3628
0
    break;
3629
0
  default:
3630
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",
3631
0
        hfinfo->abbrev);
3632
0
  }
3633
3634
0
  if (retval)
3635
0
    *retval = value;
3636
3637
0
  ptvcursor_advance(ptvc, item_length);
3638
3639
0
  CHECK_FOR_NULL_TREE(ptvc->tree);
3640
3641
0
  TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
3642
3643
0
  new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3644
3645
0
  return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3646
0
    offset, length, encoding);
3647
0
}
3648
3649
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3650
 * and returns proto_item* and boolean value retrieved */
3651
proto_item*
3652
ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool *retval)
3653
0
{
3654
0
  header_field_info *hfinfo;
3655
0
  field_info    *new_fi;
3656
0
  unsigned    item_length;
3657
0
  unsigned    offset;
3658
0
  uint64_t    value, bitval;
3659
3660
0
  offset = ptvc->offset;
3661
0
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3662
3663
0
  if (hfinfo->type != FT_BOOLEAN) {
3664
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",
3665
0
        hfinfo->abbrev);
3666
0
  }
3667
3668
0
  if (length == 0) {
3669
0
    if (retval) {
3670
0
      *retval = 0;
3671
0
    }
3672
0
    return NULL;
3673
0
  }
3674
0
  if (encoding & ENC_STRING) {
3675
0
    REPORT_DISSECTOR_BUG("wrong encoding");
3676
0
  }
3677
3678
0
  get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3679
0
  test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3680
3681
  /* I believe it's ok if this is called with a NULL tree */
3682
0
  value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3683
3684
0
  if (retval) {
3685
0
    bitval = value;
3686
0
    if (hfinfo->bitmask) {
3687
      /* Mask out irrelevant portions */
3688
0
      bitval &= hfinfo->bitmask;
3689
0
    }
3690
0
    *retval = (bitval != 0);
3691
0
  }
3692
3693
0
  ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3694
3695
0
  CHECK_FOR_NULL_TREE(ptvc->tree);
3696
3697
0
  TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo);
3698
3699
0
  new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3700
3701
0
  return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3702
0
    offset, length, encoding);
3703
0
}
3704
3705
proto_item *
3706
proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3707
    const int start, int length, const unsigned encoding, uint64_t *retval)
3708
4.52k
{
3709
4.52k
  header_field_info *hfinfo;
3710
4.52k
  field_info    *new_fi;
3711
4.52k
  uint64_t       value;
3712
3713
4.52k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3714
3715
4.52k
  switch (hfinfo->type) {
3716
0
  case FT_UINT40:
3717
22
  case FT_UINT48:
3718
22
  case FT_UINT56:
3719
4.52k
  case FT_UINT64:
3720
4.52k
    break;
3721
0
  default:
3722
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",
3723
4.52k
        hfinfo->abbrev);
3724
4.52k
  }
3725
3726
4.52k
  CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,
3727
4.52k
    {
3728
4.52k
      if(retval)
3729
4.52k
      {
3730
4.52k
        *retval = 0;
3731
4.52k
      }
3732
4.52k
    } );
3733
3734
4.52k
  if (encoding & ENC_STRING) {
3735
0
    REPORT_DISSECTOR_BUG("wrong encoding");
3736
0
  }
3737
  /* I believe it's ok if this is called with a NULL tree */
3738
4.52k
  if (encoding & ENC_VARINT_MASK) {
3739
0
    tvb_get_varint(tvb, start, length, &value, encoding);
3740
4.52k
  } else {
3741
4.52k
    value = get_uint64_value(tree, tvb, start, length, encoding);
3742
4.52k
  }
3743
3744
4.52k
  if (retval) {
3745
4.46k
    *retval = value;
3746
4.46k
    if (hfinfo->bitmask) {
3747
      /* Mask out irrelevant portions */
3748
0
      *retval &= hfinfo->bitmask;
3749
      /* Shift bits */
3750
0
      *retval >>= hfinfo_bitshift(hfinfo);
3751
0
    }
3752
4.46k
  }
3753
3754
4.52k
  CHECK_FOR_NULL_TREE(tree);
3755
3756
4.42k
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3757
3758
4.38k
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3759
3760
4.38k
  proto_tree_set_uint64(new_fi, value);
3761
3762
4.38k
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3763
4.38k
  if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG|ENC_VARINT_SDNV)) {
3764
0
    new_fi->flags |= FI_VARINT;
3765
0
  }
3766
3767
4.38k
  return proto_tree_add_node(tree, new_fi);
3768
4.42k
}
3769
3770
proto_item *
3771
proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3772
  const int start, int length, const unsigned encoding, int64_t *retval)
3773
0
{
3774
0
  header_field_info *hfinfo;
3775
0
  field_info    *new_fi;
3776
0
  int64_t      value;
3777
3778
0
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3779
3780
0
  switch (hfinfo->type) {
3781
0
  case FT_INT40:
3782
0
  case FT_INT48:
3783
0
  case FT_INT56:
3784
0
  case FT_INT64:
3785
0
    break;
3786
0
  default:
3787
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
3788
0
      hfinfo->abbrev);
3789
0
  }
3790
3791
0
  CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,
3792
0
    {
3793
0
      if(retval)
3794
0
      {
3795
0
        *retval = 0;
3796
0
      }
3797
0
    } );
3798
3799
0
  if (encoding & ENC_STRING) {
3800
0
    REPORT_DISSECTOR_BUG("wrong encoding");
3801
0
  }
3802
  /* I believe it's ok if this is called with a NULL tree */
3803
0
  if (encoding & ENC_VARINT_MASK) {
3804
0
    tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3805
0
  }
3806
0
  else {
3807
0
    value = get_int64_value(tree, tvb, start, length, encoding);
3808
0
  }
3809
3810
0
  if (retval) {
3811
0
    *retval = value;
3812
0
  }
3813
3814
0
  CHECK_FOR_NULL_TREE(tree);
3815
3816
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3817
3818
0
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3819
3820
0
  proto_tree_set_int64(new_fi, value);
3821
3822
0
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3823
0
  if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG|ENC_VARINT_SDNV)) {
3824
0
    new_fi->flags |= FI_VARINT;
3825
0
  }
3826
3827
0
  return proto_tree_add_node(tree, new_fi);
3828
0
}
3829
3830
proto_item *
3831
proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3832
    const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3833
56.2k
{
3834
56.2k
  header_field_info *hfinfo;
3835
56.2k
  field_info  *new_fi;
3836
56.2k
  uint64_t    value;
3837
3838
56.2k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3839
3840
56.2k
  if ((!FT_IS_INT(hfinfo->type)) && (!FT_IS_UINT(hfinfo->type))) {
3841
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT or FT_INT",
3842
0
        hfinfo->abbrev);
3843
0
  }
3844
3845
  /* length validation for native number encoding caught by get_uint64_value() */
3846
  /* length has to be -1 or > 0 regardless of encoding */
3847
56.2k
  if (length == 0)
3848
56.2k
    REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_varint",
3849
56.2k
      length);
3850
3851
56.2k
  if (encoding & ENC_STRING) {
3852
0
    REPORT_DISSECTOR_BUG("wrong encoding");
3853
0
  }
3854
3855
56.2k
  length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN : length, &value, encoding);
3856
3857
56.2k
  if (retval) {
3858
56.0k
    *retval = value;
3859
56.0k
    if (hfinfo->bitmask) {
3860
      /* Mask out irrelevant portions */
3861
0
      *retval &= hfinfo->bitmask;
3862
      /* Shift bits */
3863
0
      *retval >>= hfinfo_bitshift(hfinfo);
3864
0
    }
3865
56.0k
  }
3866
3867
56.2k
  if (lenretval) {
3868
56.0k
    *lenretval = length;
3869
56.0k
  }
3870
3871
56.2k
  CHECK_FOR_NULL_TREE(tree);
3872
3873
56.2k
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3874
3875
54.6k
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3876
3877
54.6k
  proto_tree_set_uint64(new_fi, value);
3878
3879
54.6k
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3880
54.6k
  if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG|ENC_VARINT_SDNV)) {
3881
54.5k
    new_fi->flags |= FI_VARINT;
3882
54.5k
  }
3883
3884
54.6k
  return proto_tree_add_node(tree, new_fi);
3885
3886
56.2k
}
3887
3888
proto_item *
3889
proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3890
                                const int start, int length,
3891
                                const unsigned encoding, bool *retval)
3892
22.5k
{
3893
22.5k
  header_field_info *hfinfo;
3894
22.5k
  field_info    *new_fi;
3895
22.5k
  uint64_t       value, bitval;
3896
3897
22.5k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
3898
3899
22.5k
  if (hfinfo->type != FT_BOOLEAN) {
3900
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",
3901
0
        hfinfo->abbrev);
3902
0
  }
3903
3904
22.5k
  CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,
3905
22.5k
    {
3906
22.5k
      if(retval)
3907
22.5k
      {
3908
22.5k
        *retval = false;
3909
22.5k
      }
3910
22.5k
    } );
3911
3912
22.5k
  if (encoding & ENC_STRING) {
3913
0
    REPORT_DISSECTOR_BUG("wrong encoding");
3914
0
  }
3915
  /* I believe it's ok if this is called with a NULL tree */
3916
22.5k
  value = get_uint64_value(tree, tvb, start, length, encoding);
3917
3918
22.5k
  if (retval) {
3919
22.5k
    bitval = value;
3920
22.5k
    if (hfinfo->bitmask) {
3921
      /* Mask out irrelevant portions */
3922
22.4k
      bitval &= hfinfo->bitmask;
3923
22.4k
    }
3924
22.5k
    *retval = (bitval != 0);
3925
22.5k
  }
3926
3927
22.5k
  CHECK_FOR_NULL_TREE(tree);
3928
3929
22.5k
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3930
3931
21.8k
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3932
3933
21.8k
  proto_tree_set_boolean(new_fi, value);
3934
3935
21.8k
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
3936
3937
21.8k
  return proto_tree_add_node(tree, new_fi);
3938
22.5k
}
3939
3940
proto_item *
3941
proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3942
                                const int start, int length,
3943
                                const unsigned encoding, float *retval)
3944
0
{
3945
0
  header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3946
0
  field_info    *new_fi;
3947
0
  float      value;
3948
3949
0
  DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3950
3951
0
  if (hfinfo->type != FT_FLOAT) {
3952
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_FLOAT", hfinfo->abbrev);
3953
0
  }
3954
3955
0
  if (length != 4) {
3956
0
    report_type_length_mismatch(tree, "a single-precision floating point number", length, true);
3957
0
  }
3958
3959
  /* treat any nonzero encoding as little endian for backwards compatibility */
3960
0
  value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3961
0
  if (retval) {
3962
0
    *retval = value;
3963
0
  }
3964
3965
0
  CHECK_FOR_NULL_TREE(tree);
3966
3967
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
3968
3969
0
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3970
0
  if (encoding) {
3971
0
    new_fi->flags |= FI_LITTLE_ENDIAN;
3972
0
  }
3973
3974
0
  proto_tree_set_float(new_fi, value);
3975
3976
0
  return proto_tree_add_node(tree, new_fi);
3977
0
}
3978
3979
proto_item *
3980
proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3981
                                const int start, int length,
3982
                                const unsigned encoding, double *retval)
3983
0
{
3984
0
  header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3985
0
  field_info    *new_fi;
3986
0
  double       value;
3987
3988
0
  DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
3989
3990
0
  if (hfinfo->type != FT_DOUBLE) {
3991
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_DOUBLE", hfinfo->abbrev);
3992
0
  }
3993
3994
0
  if (length != 8) {
3995
0
    report_type_length_mismatch(tree, "a double-precision floating point number", length, true);
3996
0
  }
3997
3998
  /* treat any nonzero encoding as little endian for backwards compatibility */
3999
0
  value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4000
0
  if (retval) {
4001
0
    *retval = value;
4002
0
  }
4003
4004
0
  CHECK_FOR_NULL_TREE(tree);
4005
4006
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4007
4008
0
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4009
0
  if (encoding) {
4010
0
    new_fi->flags |= FI_LITTLE_ENDIAN;
4011
0
  }
4012
4013
0
  proto_tree_set_double(new_fi, value);
4014
4015
0
  return proto_tree_add_node(tree, new_fi);
4016
0
}
4017
4018
proto_item *
4019
proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4020
                             const int start, int length,
4021
                             const unsigned encoding, ws_in4_addr *retval)
4022
5.01k
{
4023
5.01k
  header_field_info *hfinfo;
4024
5.01k
  field_info    *new_fi;
4025
5.01k
  ws_in4_addr    value;
4026
4027
5.01k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4028
4029
5.01k
  switch (hfinfo->type) {
4030
5.01k
  case FT_IPv4:
4031
5.01k
    break;
4032
0
  default:
4033
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_IPv4",
4034
5.01k
        hfinfo->abbrev);
4035
5.01k
  }
4036
4037
5.01k
  if (length != FT_IPv4_LEN)
4038
5.01k
    REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ipv4",
4039
5.01k
      length);
4040
4041
5.01k
  if (encoding & (ENC_STRING | ENC_VARINT_MASK)) {
4042
0
    REPORT_DISSECTOR_BUG("wrong encoding");
4043
0
  }
4044
4045
  /*
4046
   * NOTE: to support code written when proto_tree_add_item() took
4047
   * a bool as its last argument, with false meaning "big-endian"
4048
   * and true meaning "little-endian", we treat any non-zero value
4049
   * of "encoding" as meaning "little-endian".
4050
   */
4051
5.01k
  value = tvb_get_ipv4(tvb, start);
4052
5.01k
  if (encoding)
4053
0
    value = GUINT32_SWAP_LE_BE(value);
4054
4055
5.01k
  if (retval) {
4056
5.00k
    *retval = value;
4057
5.00k
  }
4058
4059
5.01k
  CHECK_FOR_NULL_TREE(tree);
4060
4061
5.01k
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4062
4063
145
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4064
4065
145
  proto_tree_set_ipv4(new_fi, value);
4066
4067
145
  new_fi->flags |= encoding ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
4068
145
  return proto_tree_add_node(tree, new_fi);
4069
5.01k
}
4070
4071
proto_item *
4072
proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4073
                             const int start, int length,
4074
                             const unsigned encoding, ws_in6_addr *addr)
4075
0
{
4076
0
  header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4077
0
  field_info    *new_fi;
4078
4079
0
  DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4080
4081
0
  switch (hfinfo->type) {
4082
0
  case FT_IPv6:
4083
0
    break;
4084
0
  default:
4085
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_IPv6",
4086
0
        hfinfo->abbrev);
4087
0
  }
4088
4089
0
  if (length != FT_IPv6_LEN)
4090
0
    REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ipv6",
4091
0
      length);
4092
4093
0
  if (encoding) {
4094
0
    REPORT_DISSECTOR_BUG("Encodings not yet implemented for proto_tree_add_item_ret_ipv6");
4095
0
  }
4096
4097
0
  tvb_get_ipv6(tvb, start, addr);
4098
4099
0
  CHECK_FOR_NULL_TREE(tree);
4100
4101
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4102
4103
0
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4104
4105
0
  proto_tree_set_ipv6(new_fi, addr);
4106
4107
0
  return proto_tree_add_node(tree, new_fi);
4108
0
}
4109
4110
proto_item *
4111
proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4112
0
    const int start, int length, const unsigned encoding, uint8_t *retval) {
4113
4114
0
  header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4115
0
  field_info    *new_fi;
4116
4117
0
  DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4118
4119
0
  switch (hfinfo->type) {
4120
0
  case FT_ETHER:
4121
0
    break;
4122
0
  default:
4123
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_ETHER",
4124
0
        hfinfo->abbrev);
4125
0
  }
4126
4127
0
  if (length != FT_ETHER_LEN)
4128
0
    REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ether",
4129
0
      length);
4130
4131
0
  if (encoding) {
4132
0
    REPORT_DISSECTOR_BUG("Encodings not yet implemented for proto_tree_add_item_ret_ether");
4133
0
  }
4134
4135
0
  tvb_memcpy(tvb, retval, start, length);
4136
4137
0
  CHECK_FOR_NULL_TREE(tree);
4138
4139
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4140
4141
0
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4142
4143
0
  proto_tree_set_ether(new_fi, retval);
4144
4145
0
  return proto_tree_add_node(tree, new_fi);
4146
0
}
4147
4148
4149
proto_item *
4150
proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4151
                                          tvbuff_t *tvb,
4152
                                          const int start, int length,
4153
                                          const unsigned encoding,
4154
                                          wmem_allocator_t *scope,
4155
                                          const uint8_t **retval,
4156
                                          int *lenretval)
4157
34.5k
{
4158
34.5k
  proto_item *pi;
4159
34.5k
  header_field_info *hfinfo;
4160
34.5k
  field_info    *new_fi;
4161
34.5k
  const uint8_t   *value;
4162
4163
34.5k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4164
4165
34.5k
  switch (hfinfo->type) {
4166
30.2k
  case FT_STRING:
4167
30.2k
    value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4168
30.2k
    break;
4169
3.08k
  case FT_STRINGZ:
4170
3.08k
    value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4171
3.08k
    break;
4172
1.23k
  case FT_UINT_STRING:
4173
1.23k
    value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4174
1.23k
    break;
4175
2
  case FT_STRINGZPAD:
4176
2
    value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4177
2
    break;
4178
20
  case FT_STRINGZTRUNC:
4179
20
    value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4180
20
    break;
4181
0
  default:
4182
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",
4183
34.5k
        hfinfo->abbrev);
4184
34.5k
  }
4185
4186
33.3k
  if (retval)
4187
32.6k
    *retval = value;
4188
4189
33.3k
  CHECK_FOR_NULL_TREE(tree);
4190
4191
33.2k
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4192
4193
10.1k
  new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4194
4195
10.1k
  proto_tree_set_string(new_fi, (const char*)value);
4196
4197
10.1k
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
4198
4199
10.1k
  pi = proto_tree_add_node(tree, new_fi);
4200
4201
10.1k
  switch (hfinfo->type) {
4202
4203
2.23k
  case FT_STRINGZ:
4204
2.23k
  case FT_STRINGZPAD:
4205
2.25k
  case FT_STRINGZTRUNC:
4206
3.40k
  case FT_UINT_STRING:
4207
3.40k
    break;
4208
4209
6.72k
  case FT_STRING:
4210
6.72k
    detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4211
6.72k
    break;
4212
4213
0
  default:
4214
0
    ws_assert_not_reached();
4215
10.1k
  }
4216
4217
10.1k
  return pi;
4218
10.1k
}
4219
4220
proto_item *
4221
proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4222
                               const int start, int length,
4223
                               const unsigned encoding, wmem_allocator_t *scope,
4224
                               const uint8_t **retval)
4225
31.1k
{
4226
31.1k
  return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4227
31.1k
      tvb, start, length, encoding, scope, retval, &length);
4228
31.1k
}
4229
4230
proto_item *
4231
proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4232
                                                  tvbuff_t *tvb,
4233
                                                  const int start, int length,
4234
                                                  const unsigned encoding,
4235
                                                  wmem_allocator_t *scope,
4236
                                                  char **retval,
4237
                                                  int *lenretval)
4238
3.23k
{
4239
3.23k
  proto_item *pi;
4240
3.23k
  header_field_info *hfinfo;
4241
3.23k
  field_info    *new_fi;
4242
3.23k
  const uint8_t   *value;
4243
3.23k
  uint32_t       n = 0;
4244
4245
3.23k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4246
4247
3.23k
  switch (hfinfo->type) {
4248
1.40k
  case FT_STRING:
4249
1.40k
    value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4250
1.40k
    *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH);
4251
1.40k
    ws_label_strcpy(*retval, ITEM_LABEL_LENGTH, 0, value, label_strcat_flags(hfinfo));
4252
1.40k
    break;
4253
2
  case FT_STRINGZ:
4254
2
    value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4255
2
    *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH);
4256
2
    ws_label_strcpy(*retval, ITEM_LABEL_LENGTH, 0, value, label_strcat_flags(hfinfo));
4257
2
    break;
4258
0
  case FT_UINT_STRING:
4259
0
    value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4260
0
    *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH);
4261
0
    ws_label_strcpy(*retval, ITEM_LABEL_LENGTH, 0, value, label_strcat_flags(hfinfo));
4262
0
    break;
4263
0
  case FT_STRINGZPAD:
4264
0
    value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4265
0
    *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH);
4266
0
    ws_label_strcpy(*retval, ITEM_LABEL_LENGTH, 0, value, label_strcat_flags(hfinfo));
4267
0
    break;
4268
0
  case FT_STRINGZTRUNC:
4269
0
    value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4270
0
    *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH);
4271
0
    ws_label_strcpy(*retval, ITEM_LABEL_LENGTH, 0, value, label_strcat_flags(hfinfo));
4272
0
    break;
4273
1.82k
  case FT_BYTES:
4274
1.82k
    tvb_ensure_bytes_exist(tvb, start, length);
4275
1.82k
    value = tvb_get_ptr(tvb, start, length);
4276
1.82k
    *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4277
1.82k
    *lenretval = length;
4278
1.82k
    break;
4279
0
  case FT_UINT_BYTES:
4280
0
    n = get_uint_value(tree, tvb, start, length, encoding);
4281
0
    tvb_ensure_bytes_exist(tvb, start + length, n);
4282
0
    value = tvb_get_ptr(tvb, start + length, n);
4283
0
    *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4284
0
    *lenretval = length + n;
4285
0
    break;
4286
0
  default:
4287
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",
4288
3.23k
        hfinfo->abbrev);
4289
3.23k
  }
4290
4291
3.16k
  CHECK_FOR_NULL_TREE(tree);
4292
4293
3.16k
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4294
4295
3.02k
  new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4296
4297
3.02k
  switch (hfinfo->type) {
4298
4299
1.36k
  case FT_STRING:
4300
1.36k
  case FT_STRINGZ:
4301
1.36k
  case FT_UINT_STRING:
4302
1.36k
  case FT_STRINGZPAD:
4303
1.36k
  case FT_STRINGZTRUNC:
4304
1.36k
    proto_tree_set_string(new_fi, (const char*)value);
4305
1.36k
    break;
4306
4307
1.66k
  case FT_BYTES:
4308
1.66k
    proto_tree_set_bytes(new_fi, value, length);
4309
1.66k
    break;
4310
4311
0
  case FT_UINT_BYTES:
4312
0
    proto_tree_set_bytes(new_fi, value, n);
4313
0
    break;
4314
4315
0
  default:
4316
0
    ws_assert_not_reached();
4317
3.02k
  }
4318
4319
3.02k
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
4320
4321
3.02k
  pi = proto_tree_add_node(tree, new_fi);
4322
4323
3.02k
  switch (hfinfo->type) {
4324
4325
0
  case FT_STRINGZ:
4326
0
  case FT_STRINGZPAD:
4327
0
  case FT_STRINGZTRUNC:
4328
0
  case FT_UINT_STRING:
4329
0
    break;
4330
4331
1.36k
  case FT_STRING:
4332
1.36k
    detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4333
1.36k
    break;
4334
4335
1.66k
  case FT_BYTES:
4336
1.66k
  case FT_UINT_BYTES:
4337
1.66k
    break;
4338
4339
0
  default:
4340
0
    ws_assert_not_reached();
4341
3.02k
  }
4342
4343
3.02k
  return pi;
4344
3.02k
}
4345
4346
proto_item *
4347
proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4348
                                       tvbuff_t *tvb,
4349
                                       const int start, int length,
4350
                                       const unsigned encoding,
4351
                                       wmem_allocator_t *scope,
4352
                                       char **retval)
4353
3.23k
{
4354
3.23k
  return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4355
3.23k
      tvb, start, length, encoding, scope, retval, &length);
4356
3.23k
}
4357
4358
proto_item *
4359
proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4360
  tvbuff_t *tvb,
4361
  const int start, int length, const unsigned encoding,
4362
  wmem_allocator_t *scope, char **retval)
4363
82
{
4364
82
  header_field_info *hfinfo;
4365
82
  field_info    *new_fi;
4366
82
  nstime_t    time_stamp;
4367
82
  int flags;
4368
4369
82
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4370
4371
82
  switch (hfinfo->type) {
4372
82
  case FT_ABSOLUTE_TIME:
4373
82
    get_time_value(tree, tvb, start, length, encoding, &time_stamp, false);
4374
82
    flags = ABS_TIME_TO_STR_SHOW_ZONE;
4375
82
    if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4376
0
      flags |= ABS_TIME_TO_STR_ISO8601;
4377
0
    }
4378
82
    *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4379
82
    break;
4380
0
  case FT_RELATIVE_TIME:
4381
0
    get_time_value(tree, tvb, start, length, encoding, &time_stamp, true);
4382
0
    *retval = rel_time_to_secs_str(scope, &time_stamp);
4383
0
    break;
4384
0
  default:
4385
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME",
4386
82
      hfinfo->abbrev);
4387
82
  }
4388
4389
77
  CHECK_FOR_NULL_TREE(tree);
4390
4391
77
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4392
4393
72
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4394
4395
72
  switch (hfinfo->type) {
4396
4397
72
  case FT_ABSOLUTE_TIME:
4398
72
  case FT_RELATIVE_TIME:
4399
72
    proto_tree_set_time(new_fi, &time_stamp);
4400
72
    break;
4401
0
  default:
4402
0
    ws_assert_not_reached();
4403
72
  }
4404
4405
72
  new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN;
4406
4407
72
  return proto_tree_add_node(tree, new_fi);
4408
72
}
4409
4410
/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4411
   and returns proto_item* */
4412
proto_item *
4413
ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4414
        const unsigned encoding)
4415
22.1k
{
4416
22.1k
  field_info    *new_fi;
4417
22.1k
  header_field_info *hfinfo;
4418
22.1k
  int      item_length;
4419
22.1k
  unsigned     offset;
4420
4421
22.1k
  offset = ptvc->offset;
4422
22.1k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4423
22.1k
  get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4424
22.1k
  test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4425
4426
22.1k
  ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4427
4428
22.1k
  CHECK_FOR_NULL_TREE(ptvc->tree);
4429
4430
  /* Coast clear. Try and fake it */
4431
22.1k
  TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo);
4432
4433
21.1k
  new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4434
4435
21.1k
  return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4436
21.1k
    offset, length, encoding);
4437
22.1k
}
4438
4439
/* Add an item to a proto_tree, using the text label registered to that item;
4440
   the item is extracted from the tvbuff handed to it. */
4441
proto_item *
4442
proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4443
      const int start, int length, const unsigned encoding)
4444
28.1M
{
4445
28.1M
  field_info        *new_fi;
4446
28.1M
  int     item_length;
4447
4448
28.1M
  DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4449
4450
28.1M
  get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4451
28.1M
  test_length(hfinfo, tvb, start, item_length, encoding);
4452
4453
28.1M
  CHECK_FOR_NULL_TREE(tree);
4454
4455
27.1M
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4456
4457
10.7M
  new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4458
4459
10.7M
  return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4460
27.1M
}
4461
4462
proto_item *
4463
proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4464
        const int start, int length, const unsigned encoding)
4465
28.1M
{
4466
28.1M
  register header_field_info *hfinfo;
4467
4468
28.1M
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4469
28.1M
  return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4470
28.1M
}
4471
4472
/* Add an item to a proto_tree, using the text label registered to that item;
4473
   the item is extracted from the tvbuff handed to it.
4474
4475
   Return the length of the item through the pointer. */
4476
proto_item *
4477
proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4478
           tvbuff_t *tvb, const int start,
4479
           int length, const unsigned encoding,
4480
           int *lenretval)
4481
2.29k
{
4482
2.29k
  field_info        *new_fi;
4483
2.29k
  int     item_length;
4484
2.29k
  proto_item   *item;
4485
4486
2.29k
  DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4487
4488
2.29k
  get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4489
2.29k
  test_length(hfinfo, tvb, start, item_length, encoding);
4490
4491
2.29k
  if (!tree) {
4492
    /*
4493
     * We need to get the correct item length here.
4494
     * That's normally done by proto_tree_new_item(),
4495
     * but we won't be calling it.
4496
     */
4497
0
    *lenretval = get_full_length(hfinfo, tvb, start, length,
4498
0
        item_length, encoding);
4499
0
    return NULL;
4500
0
  }
4501
4502
2.29k
  TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo, {
4503
    /*
4504
     * Even if the tree item is not referenced (and thus faked),
4505
     * the caller must still be informed of the actual length.
4506
     */
4507
2.29k
    *lenretval = get_full_length(hfinfo, tvb, start, length,
4508
2.29k
        item_length, encoding);
4509
2.29k
  });
4510
4511
2.27k
  new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4512
4513
2.27k
  item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4514
2.27k
  *lenretval = new_fi->length;
4515
2.27k
  return item;
4516
2.29k
}
4517
4518
proto_item *
4519
proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4520
             const int start, int length,
4521
             const unsigned encoding, int *lenretval)
4522
2.29k
{
4523
2.29k
  register header_field_info *hfinfo;
4524
4525
2.29k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4526
2.29k
  return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4527
2.29k
}
4528
4529
/* which FT_ types can use proto_tree_add_bytes_item() */
4530
static inline bool
4531
validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4532
29
{
4533
29
  return (type == FT_BYTES      ||
4534
0
    type == FT_UINT_BYTES ||
4535
0
    type == FT_OID        ||
4536
0
    type == FT_REL_OID    ||
4537
0
    type == FT_SYSTEM_ID  );
4538
29
}
4539
4540
/* Note: this does no validation that the byte array of an FT_OID or
4541
   FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4542
   so I think it's ok to continue not validating it?
4543
 */
4544
proto_item *
4545
proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4546
        const unsigned start, unsigned length,
4547
        const unsigned encoding,
4548
        GByteArray *retval, unsigned *endoff, int *err)
4549
29
{
4550
29
  field_info    *new_fi;
4551
29
  GByteArray    *bytes = retval;
4552
29
  GByteArray    *created_bytes = NULL;
4553
29
  bool       failed = false;
4554
29
  uint32_t     n = 0;
4555
29
  header_field_info *hfinfo;
4556
29
  bool     generate = (bytes || tree) ? true : false;
4557
4558
29
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4559
4560
29
  DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4561
4562
29
  DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),
4563
29
    "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type");
4564
4565
29
  if (length == 0) {
4566
0
    return NULL;
4567
0
  }
4568
4569
29
  if (encoding & ENC_STR_NUM) {
4570
0
    REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported");
4571
0
  }
4572
4573
29
  if (generate && (encoding & ENC_STR_HEX)) {
4574
0
    if (hfinfo->type == FT_UINT_BYTES) {
4575
      /* can't decode FT_UINT_BYTES from strings */
4576
0
      REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "
4577
0
          "FT_UINT_BYTES type, but as ENC_STR_HEX");
4578
0
    }
4579
4580
0
    unsigned hex_encoding = encoding;
4581
0
    if (!(encoding & ENC_SEP_MASK)) {
4582
      /* If none of the separator values are used,
4583
       * assume no separator (the common case). */
4584
0
      hex_encoding |= ENC_SEP_NONE;
4585
#if 0
4586
      REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called "
4587
        "with ENC_STR_HEX but no ENC_SEP_XXX value");
4588
#endif
4589
0
    }
4590
4591
0
    if (!bytes) {
4592
      /* caller doesn't care about return value, but we need it to
4593
         call tvb_get_string_bytes() and set the tree later */
4594
0
      bytes = created_bytes = g_byte_array_new();
4595
0
    }
4596
4597
    /*
4598
     * bytes might be NULL after this, but can't add expert
4599
     * error until later; if it's NULL, just note that
4600
     * it failed.
4601
     */
4602
0
    bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4603
0
    if (bytes == NULL)
4604
0
      failed = true;
4605
0
  }
4606
29
  else if (generate) {
4607
29
    tvb_ensure_bytes_exist(tvb, start, length);
4608
4609
29
    if (hfinfo->type == FT_UINT_BYTES) {
4610
0
      n = length; /* n is now the "header" length */
4611
0
      length = get_uint_value(tree, tvb, start, n, encoding);
4612
      /* length is now the value's length; only store the value in the array */
4613
0
      tvb_ensure_bytes_exist(tvb, start + n, length);
4614
0
      if (!bytes) {
4615
        /* caller doesn't care about return value, but
4616
         * we may need it to set the tree later */
4617
0
        bytes = created_bytes = g_byte_array_new();
4618
0
      }
4619
0
      g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4620
0
    }
4621
29
    else if (length > 0) {
4622
29
      if (!bytes) {
4623
        /* caller doesn't care about return value, but
4624
         * we may need it to set the tree later */
4625
29
        bytes = created_bytes = g_byte_array_new();
4626
29
      }
4627
29
      g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4628
29
    }
4629
4630
29
    if (endoff)
4631
0
        *endoff = start + n + length;
4632
29
  }
4633
4634
29
  if (err)
4635
0
    *err = failed ? EINVAL : 0;
4636
4637
29
  CHECK_FOR_NULL_TREE_AND_FREE(tree,
4638
29
    {
4639
29
        if (created_bytes)
4640
29
      g_byte_array_free(created_bytes, true);
4641
29
        created_bytes = NULL;
4642
29
        bytes = NULL;
4643
29
    } );
4644
4645
29
  TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,
4646
29
    {
4647
29
        if (created_bytes)
4648
29
      g_byte_array_free(created_bytes, true);
4649
29
        created_bytes = NULL;
4650
29
        bytes = NULL;
4651
29
    } );
4652
4653
  /* n will be zero except when it's a FT_UINT_BYTES */
4654
29
  new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4655
4656
29
  if (encoding & ENC_STRING) {
4657
0
    if (failed)
4658
0
        expert_add_info(NULL, tree, &ei_byte_array_string_decoding_failed_error);
4659
4660
0
    if (bytes)
4661
0
        proto_tree_set_bytes_gbytearray(new_fi, bytes);
4662
0
    else
4663
0
        proto_tree_set_bytes(new_fi, NULL, 0);
4664
4665
0
    if (created_bytes)
4666
0
        g_byte_array_free(created_bytes, true);
4667
0
  }
4668
29
  else {
4669
    /* n will be zero except when it's a FT_UINT_BYTES */
4670
29
    proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4671
4672
    /* XXX: If we have a non-NULL tree but NULL retval, we don't
4673
     * use the byte array created above in this case.
4674
     */
4675
29
    if (created_bytes)
4676
29
        g_byte_array_free(created_bytes, true);
4677
4678
29
    FI_SET_FLAG(new_fi,
4679
29
      (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
4680
29
  }
4681
4682
29
  return proto_tree_add_node(tree, new_fi);
4683
29
}
4684
4685
4686
proto_item *
4687
proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4688
         const unsigned start, const unsigned length,
4689
         const unsigned encoding,
4690
         nstime_t *retval, unsigned *endoff, int *err)
4691
0
{
4692
0
  field_info    *new_fi;
4693
0
  nstime_t     time_stamp;
4694
0
  int      saved_err = 0;
4695
0
  header_field_info *hfinfo;
4696
4697
0
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4698
4699
0
  DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!");
4700
4701
0
  if (length == 0) {
4702
0
    if(retval) {
4703
0
      nstime_set_zero(retval);
4704
0
    }
4705
0
    return NULL;
4706
0
  }
4707
4708
0
  nstime_set_zero(&time_stamp);
4709
4710
0
  if (encoding & ENC_STR_TIME_MASK) {
4711
0
    DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ABSOLUTE_TIME);
4712
    /* The only string format that could be a relative time is
4713
     * ENC_ISO_8601_TIME, and that is treated as an absolute time
4714
     * relative to "now" currently.
4715
     */
4716
0
    if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4717
0
      saved_err = EINVAL;
4718
0
  }
4719
0
  else {
4720
0
    DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
4721
0
    const bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true : false;
4722
4723
0
    tvb_ensure_bytes_exist(tvb, start, length);
4724
0
    get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4725
0
    if (endoff) *endoff = start + length;
4726
0
  }
4727
4728
0
  if (err) *err = saved_err;
4729
4730
0
  if (retval) {
4731
0
    retval->secs  = time_stamp.secs;
4732
0
    retval->nsecs = time_stamp.nsecs;
4733
0
  }
4734
4735
0
  CHECK_FOR_NULL_TREE(tree);
4736
4737
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo);
4738
4739
0
  new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4740
4741
0
  proto_tree_set_time(new_fi, &time_stamp);
4742
4743
0
  if (encoding & ENC_STRING) {
4744
0
    if (saved_err)
4745
0
        expert_add_info(NULL, tree, &ei_date_time_string_decoding_failed_error);
4746
0
  }
4747
0
  else {
4748
0
    FI_SET_FLAG(new_fi,
4749
0
      (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN);
4750
0
  }
4751
4752
0
  return proto_tree_add_node(tree, new_fi);
4753
0
}
4754
4755
/* Add a FT_NONE to a proto_tree */
4756
proto_item *
4757
proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4758
         const int start, int length, const char *format,
4759
         ...)
4760
5.09M
{
4761
5.09M
  proto_item    *pi;
4762
5.09M
  va_list      ap;
4763
5.09M
  header_field_info *hfinfo;
4764
4765
5.09M
  CHECK_FOR_NULL_TREE(tree);
4766
4767
5.09M
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4768
4769
973k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE);
4770
4771
973k
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4772
4773
973k
  TRY_TO_FAKE_THIS_REPR(pi);
4774
4775
973k
  va_start(ap, format);
4776
973k
  proto_tree_set_representation(pi, format, ap);
4777
973k
  va_end(ap);
4778
4779
  /* no value to set for FT_NONE */
4780
973k
  return pi;
4781
973k
}
4782
4783
/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4784
 * offset, and returns proto_item* */
4785
proto_item *
4786
ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4787
       const unsigned encoding)
4788
22.5k
{
4789
22.5k
  proto_item *item;
4790
4791
22.5k
  item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4792
22.5k
           length, encoding);
4793
4794
22.5k
  return item;
4795
22.5k
}
4796
4797
/* Advance the ptvcursor's offset within its tvbuff without
4798
 * adding anything to the proto_tree. */
4799
void
4800
ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4801
22.9k
{
4802
22.9k
  if (ckd_add(&ptvc->offset, ptvc->offset, length)) {
4803
0
    THROW(ReportedBoundsError);
4804
0
  }
4805
22.9k
}
4806
4807
4808
static void
4809
proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4810
1.92M
{
4811
1.92M
  fvalue_set_protocol(fi->value, tvb, field_data, length);
4812
1.92M
}
4813
4814
/* Add a FT_PROTOCOL to a proto_tree */
4815
proto_item *
4816
proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4817
             int start, int length, const char *format, ...)
4818
5.45M
{
4819
5.45M
  proto_item    *pi;
4820
5.45M
  tvbuff_t    *protocol_tvb;
4821
5.45M
  va_list      ap;
4822
5.45M
  header_field_info *hfinfo;
4823
5.45M
  char* protocol_rep;
4824
4825
5.45M
  CHECK_FOR_NULL_TREE(tree);
4826
4827
5.45M
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4828
4829
1.24M
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL);
4830
4831
  /*
4832
   * This can throw an exception, so do it before we allocate anything.
4833
   */
4834
1.24M
  protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4835
4836
1.24M
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4837
4838
1.24M
  va_start(ap, format);
4839
1.24M
  protocol_rep = ws_strdup_vprintf(format, ap);
4840
1.24M
  proto_tree_set_protocol_tvb(PNODE_FINFO(pi), protocol_tvb, protocol_rep, length);
4841
1.24M
  g_free(protocol_rep);
4842
1.24M
  va_end(ap);
4843
4844
1.24M
  TRY_TO_FAKE_THIS_REPR(pi);
4845
4846
1.24M
  va_start(ap, format);
4847
1.24M
  proto_tree_set_representation(pi, format, ap);
4848
1.24M
  va_end(ap);
4849
4850
1.24M
  return pi;
4851
1.24M
}
4852
4853
/* Add a FT_BYTES to a proto_tree */
4854
proto_item *
4855
proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4856
         int length, const uint8_t *start_ptr)
4857
95.8k
{
4858
95.8k
  proto_item    *pi;
4859
95.8k
  header_field_info *hfinfo;
4860
95.8k
  int     item_length;
4861
4862
95.8k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4863
95.8k
  get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA);
4864
95.8k
  test_length(hfinfo, tvb, start, item_length, ENC_NA);
4865
4866
95.8k
  CHECK_FOR_NULL_TREE(tree);
4867
4868
95.7k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4869
4870
83.4k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
4871
4872
83.4k
  if (start_ptr == NULL && tvb != NULL)
4873
81.6k
    start_ptr = tvb_get_ptr(tvb, start, length);
4874
4875
83.4k
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4876
83.4k
  proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, length);
4877
4878
83.4k
  return pi;
4879
95.7k
}
4880
4881
/* Add a FT_BYTES to a proto_tree */
4882
proto_item *
4883
proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4884
             int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4885
1.20k
{
4886
1.20k
  proto_item    *pi;
4887
1.20k
  header_field_info *hfinfo;
4888
1.20k
  int           item_length;
4889
4890
1.20k
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
4891
1.20k
  get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA);
4892
1.20k
  test_length(hfinfo, tvb, start, item_length, ENC_NA);
4893
4894
1.20k
  CHECK_FOR_NULL_TREE(tree);
4895
4896
1.20k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4897
4898
1.20k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
4899
4900
1.20k
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4901
1.20k
  proto_tree_set_bytes(PNODE_FINFO(pi), start_ptr, ptr_length);
4902
4903
1.20k
  return pi;
4904
1.20k
}
4905
4906
proto_item *
4907
proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4908
          int start, int length,
4909
          const uint8_t *start_ptr,
4910
          const char *format, ...)
4911
12.4k
{
4912
12.4k
  proto_item    *pi;
4913
12.4k
  va_list      ap;
4914
4915
12.4k
  pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4916
4917
12.4k
  TRY_TO_FAKE_THIS_REPR_NESTED(pi);
4918
4919
5.47k
  va_start(ap, format);
4920
5.47k
  proto_tree_set_representation_value(pi, format, ap);
4921
5.47k
  va_end(ap);
4922
4923
5.47k
  return pi;
4924
12.4k
}
4925
4926
proto_item *
4927
proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4928
          int start, int length, const uint8_t *start_ptr,
4929
          const char *format, ...)
4930
82.6k
{
4931
82.6k
  proto_item    *pi;
4932
82.6k
  va_list      ap;
4933
4934
82.6k
  pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4935
4936
82.6k
  TRY_TO_FAKE_THIS_REPR_NESTED(pi);
4937
4938
77.2k
  va_start(ap, format);
4939
77.2k
  proto_tree_set_representation(pi, format, ap);
4940
77.2k
  va_end(ap);
4941
4942
77.2k
  return pi;
4943
82.6k
}
4944
4945
static void
4946
proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4947
729k
{
4948
729k
  DISSECTOR_ASSERT(length >= 0);
4949
729k
  DISSECTOR_ASSERT(start_ptr != NULL || length == 0);
4950
4951
729k
  fvalue_set_bytes_data(fi->value, start_ptr, length);
4952
729k
}
4953
4954
4955
static void
4956
proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4957
644k
{
4958
644k
  tvb_ensure_bytes_exist(tvb, offset, length);
4959
644k
  proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4960
644k
}
4961
4962
static void
4963
proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4964
0
{
4965
0
  GByteArray *bytes;
4966
4967
0
  DISSECTOR_ASSERT(value != NULL);
4968
4969
0
  bytes = byte_array_dup(value);
4970
4971
0
  fvalue_set_byte_array(fi->value, bytes);
4972
0
}
4973
4974
/* Add a FT_*TIME to a proto_tree */
4975
proto_item *
4976
proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4977
        int length, const nstime_t *value_ptr)
4978
605k
{
4979
605k
  proto_item    *pi;
4980
605k
  header_field_info *hfinfo;
4981
4982
605k
  CHECK_FOR_NULL_TREE(tree);
4983
4984
605k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
4985
4986
595k
  DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo);
4987
4988
595k
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4989
595k
  proto_tree_set_time(PNODE_FINFO(pi), value_ptr);
4990
4991
595k
  return pi;
4992
605k
}
4993
4994
proto_item *
4995
proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4996
         int start, int length, nstime_t *value_ptr,
4997
         const char *format, ...)
4998
1.90k
{
4999
1.90k
  proto_item    *pi;
5000
1.90k
  va_list      ap;
5001
5002
1.90k
  pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5003
1.90k
  if (pi != tree) {
5004
1.90k
    va_start(ap, format);
5005
1.90k
    proto_tree_set_representation_value(pi, format, ap);
5006
1.90k
    va_end(ap);
5007
1.90k
  }
5008
5009
1.90k
  return pi;
5010
1.90k
}
5011
5012
proto_item *
5013
proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5014
         int start, int length, nstime_t *value_ptr,
5015
         const char *format, ...)
5016
57
{
5017
57
  proto_item    *pi;
5018
57
  va_list      ap;
5019
5020
57
  pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5021
57
  if (pi != tree) {
5022
57
    TRY_TO_FAKE_THIS_REPR(pi);
5023
5024
57
    va_start(ap, format);
5025
57
    proto_tree_set_representation(pi, format, ap);
5026
57
    va_end(ap);
5027
57
  }
5028
5029
57
  return pi;
5030
57
}
5031
5032
/* Set the FT_*TIME value */
5033
static void
5034
proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5035
599k
{
5036
599k
  DISSECTOR_ASSERT(value_ptr != NULL);
5037
5038
599k
  fvalue_set_time(fi->value, value_ptr);
5039
599k
}
5040
5041
/* Add a FT_IPXNET to a proto_tree */
5042
proto_item *
5043
proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5044
          int length, uint32_t value)
5045
12.1k
{
5046
12.1k
  proto_item    *pi;
5047
12.1k
  header_field_info *hfinfo;
5048
5049
12.1k
  CHECK_FOR_NULL_TREE(tree);
5050
5051
12.1k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5052
5053
11.9k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET);
5054
5055
11.9k
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5056
11.9k
  proto_tree_set_ipxnet(PNODE_FINFO(pi), value);
5057
5058
11.9k
  return pi;
5059
12.1k
}
5060
5061
proto_item *
5062
proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5063
           int start, int length, uint32_t value,
5064
           const char *format, ...)
5065
0
{
5066
0
  proto_item    *pi;
5067
0
  va_list      ap;
5068
5069
0
  pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5070
0
  if (pi != tree) {
5071
0
    va_start(ap, format);
5072
0
    proto_tree_set_representation_value(pi, format, ap);
5073
0
    va_end(ap);
5074
0
  }
5075
5076
0
  return pi;
5077
0
}
5078
5079
proto_item *
5080
proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5081
           int start, int length, uint32_t value,
5082
           const char *format, ...)
5083
0
{
5084
0
  proto_item    *pi;
5085
0
  va_list      ap;
5086
5087
0
  pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5088
0
  if (pi != tree) {
5089
0
    TRY_TO_FAKE_THIS_REPR(pi);
5090
5091
0
    va_start(ap, format);
5092
0
    proto_tree_set_representation(pi, format, ap);
5093
0
    va_end(ap);
5094
0
  }
5095
5096
0
  return pi;
5097
0
}
5098
5099
/* Set the FT_IPXNET value */
5100
static void
5101
proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5102
12.3k
{
5103
12.3k
  fvalue_set_uinteger(fi->value, value);
5104
12.3k
}
5105
5106
/* Add a FT_IPv4 to a proto_tree */
5107
proto_item *
5108
proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5109
        int length, ws_in4_addr value)
5110
172k
{
5111
172k
  proto_item    *pi;
5112
172k
  header_field_info *hfinfo;
5113
5114
172k
  CHECK_FOR_NULL_TREE(tree);
5115
5116
172k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5117
5118
130k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4);
5119
5120
130k
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5121
130k
  proto_tree_set_ipv4(PNODE_FINFO(pi), value);
5122
5123
130k
  return pi;
5124
172k
}
5125
5126
proto_item *
5127
proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5128
         int start, int length, ws_in4_addr value,
5129
         const char *format, ...)
5130
6.12k
{
5131
6.12k
  proto_item    *pi;
5132
6.12k
  va_list      ap;
5133
5134
6.12k
  pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5135
6.12k
  if (pi != tree) {
5136
6.12k
    va_start(ap, format);
5137
6.12k
    proto_tree_set_representation_value(pi, format, ap);
5138
6.12k
    va_end(ap);
5139
6.12k
  }
5140
5141
6.12k
  return pi;
5142
6.12k
}
5143
5144
proto_item *
5145
proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5146
         int start, int length, ws_in4_addr value,
5147
         const char *format, ...)
5148
2.19k
{
5149
2.19k
  proto_item    *pi;
5150
2.19k
  va_list      ap;
5151
5152
2.19k
  pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5153
2.19k
  if (pi != tree) {
5154
2.19k
    TRY_TO_FAKE_THIS_REPR(pi);
5155
5156
1.74k
    va_start(ap, format);
5157
1.74k
    proto_tree_set_representation(pi, format, ap);
5158
1.74k
    va_end(ap);
5159
1.74k
  }
5160
5161
1.74k
  return pi;
5162
2.19k
}
5163
5164
/* Set the FT_IPv4 value */
5165
static void
5166
proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5167
158k
{
5168
158k
  ipv4_addr_and_mask ipv4;
5169
158k
  ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5170
158k
  fvalue_set_ipv4(fi->value, &ipv4);
5171
158k
}
5172
5173
/* Add a FT_IPv6 to a proto_tree */
5174
proto_item *
5175
proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5176
        int length, const ws_in6_addr *value)
5177
24.0k
{
5178
24.0k
  proto_item    *pi;
5179
24.0k
  header_field_info *hfinfo;
5180
5181
24.0k
  CHECK_FOR_NULL_TREE(tree);
5182
5183
24.0k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5184
5185
6.30k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6);
5186
5187
6.30k
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5188
6.30k
  proto_tree_set_ipv6(PNODE_FINFO(pi), value);
5189
5190
6.30k
  return pi;
5191
24.0k
}
5192
5193
proto_item *
5194
proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5195
         int start, int length,
5196
         const ws_in6_addr *value_ptr,
5197
         const char *format, ...)
5198
2.31k
{
5199
2.31k
  proto_item    *pi;
5200
2.31k
  va_list      ap;
5201
5202
2.31k
  pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5203
2.31k
  if (pi != tree) {
5204
2.31k
    va_start(ap, format);
5205
2.31k
    proto_tree_set_representation_value(pi, format, ap);
5206
2.31k
    va_end(ap);
5207
2.31k
  }
5208
5209
2.31k
  return pi;
5210
2.31k
}
5211
5212
proto_item *
5213
proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5214
         int start, int length,
5215
         const ws_in6_addr *value_ptr,
5216
         const char *format, ...)
5217
1.34k
{
5218
1.34k
  proto_item    *pi;
5219
1.34k
  va_list      ap;
5220
5221
1.34k
  pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5222
1.34k
  if (pi != tree) {
5223
1.34k
    TRY_TO_FAKE_THIS_REPR(pi);
5224
5225
1.28k
    va_start(ap, format);
5226
1.28k
    proto_tree_set_representation(pi, format, ap);
5227
1.28k
    va_end(ap);
5228
1.28k
  }
5229
5230
1.28k
  return pi;
5231
1.34k
}
5232
5233
/* Set the FT_IPv6 value */
5234
static void
5235
proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5236
68.8k
{
5237
68.8k
  DISSECTOR_ASSERT(value != NULL);
5238
68.8k
  ipv6_addr_and_prefix ipv6;
5239
68.8k
  ipv6.addr = *value;
5240
68.8k
  ipv6.prefix = 128;
5241
68.8k
  fvalue_set_ipv6(fi->value, &ipv6);
5242
68.8k
}
5243
5244
static void
5245
proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5246
62.5k
{
5247
62.5k
  proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5248
62.5k
}
5249
5250
/* Set the FT_FCWWN value */
5251
static void
5252
proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5253
382
{
5254
382
  DISSECTOR_ASSERT(value_ptr != NULL);
5255
382
  fvalue_set_fcwwn(fi->value, value_ptr);
5256
382
}
5257
5258
static void
5259
proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5260
382
{
5261
382
  proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5262
382
}
5263
5264
/* Add a FT_GUID to a proto_tree */
5265
proto_item *
5266
proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5267
        int length, const e_guid_t *value_ptr)
5268
824
{
5269
824
  proto_item    *pi;
5270
824
  header_field_info *hfinfo;
5271
5272
824
  CHECK_FOR_NULL_TREE(tree);
5273
5274
824
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5275
5276
821
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID);
5277
5278
821
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5279
821
  proto_tree_set_guid(PNODE_FINFO(pi), value_ptr);
5280
5281
821
  return pi;
5282
824
}
5283
5284
proto_item *
5285
proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5286
         int start, int length,
5287
         const e_guid_t *value_ptr,
5288
         const char *format, ...)
5289
236
{
5290
236
  proto_item    *pi;
5291
236
  va_list      ap;
5292
5293
236
  pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5294
236
  if (pi != tree) {
5295
236
    va_start(ap, format);
5296
236
    proto_tree_set_representation_value(pi, format, ap);
5297
236
    va_end(ap);
5298
236
  }
5299
5300
236
  return pi;
5301
236
}
5302
5303
proto_item *
5304
proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5305
         int start, int length, const e_guid_t *value_ptr,
5306
         const char *format, ...)
5307
585
{
5308
585
  proto_item    *pi;
5309
585
  va_list      ap;
5310
5311
585
  pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5312
585
  if (pi != tree) {
5313
585
    TRY_TO_FAKE_THIS_REPR(pi);
5314
5315
584
    va_start(ap, format);
5316
584
    proto_tree_set_representation(pi, format, ap);
5317
584
    va_end(ap);
5318
584
  }
5319
5320
584
  return pi;
5321
585
}
5322
5323
/* Set the FT_GUID value */
5324
static void
5325
proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5326
1.61k
{
5327
1.61k
  DISSECTOR_ASSERT(value_ptr != NULL);
5328
1.61k
  fvalue_set_guid(fi->value, value_ptr);
5329
1.61k
}
5330
5331
static void
5332
proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5333
      const unsigned encoding)
5334
793
{
5335
793
  e_guid_t guid;
5336
5337
793
  tvb_get_guid(tvb, start, &guid, encoding);
5338
793
  proto_tree_set_guid(fi, &guid);
5339
793
}
5340
5341
/* Add a FT_OID to a proto_tree */
5342
proto_item *
5343
proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5344
       int length, const uint8_t* value_ptr)
5345
0
{
5346
0
  proto_item    *pi;
5347
0
  header_field_info *hfinfo;
5348
5349
0
  CHECK_FOR_NULL_TREE(tree);
5350
5351
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5352
5353
0
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID);
5354
5355
0
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5356
0
  proto_tree_set_oid(PNODE_FINFO(pi), value_ptr, length);
5357
5358
0
  return pi;
5359
0
}
5360
5361
proto_item *
5362
proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5363
        int start, int length,
5364
        const uint8_t* value_ptr,
5365
        const char *format, ...)
5366
0
{
5367
0
  proto_item    *pi;
5368
0
  va_list      ap;
5369
5370
0
  pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5371
0
  if (pi != tree) {
5372
0
    va_start(ap, format);
5373
0
    proto_tree_set_representation_value(pi, format, ap);
5374
0
    va_end(ap);
5375
0
  }
5376
5377
0
  return pi;
5378
0
}
5379
5380
proto_item *
5381
proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5382
        int start, int length, const uint8_t* value_ptr,
5383
        const char *format, ...)
5384
0
{
5385
0
  proto_item    *pi;
5386
0
  va_list      ap;
5387
5388
0
  pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5389
0
  if (pi != tree) {
5390
0
    TRY_TO_FAKE_THIS_REPR(pi);
5391
5392
0
    va_start(ap, format);
5393
0
    proto_tree_set_representation(pi, format, ap);
5394
0
    va_end(ap);
5395
0
  }
5396
5397
0
  return pi;
5398
0
}
5399
5400
/* Set the FT_OID value */
5401
static void
5402
proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5403
710
{
5404
710
  GByteArray *bytes;
5405
5406
710
  DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
5407
5408
710
  bytes = g_byte_array_new();
5409
710
  if (length > 0) {
5410
685
    g_byte_array_append(bytes, value_ptr, length);
5411
685
  }
5412
710
  fvalue_set_byte_array(fi->value, bytes);
5413
710
}
5414
5415
static void
5416
proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5417
710
{
5418
710
  proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5419
710
}
5420
5421
/* Set the FT_SYSTEM_ID value */
5422
static void
5423
proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5424
3.79k
{
5425
3.79k
  GByteArray *bytes;
5426
5427
3.79k
  DISSECTOR_ASSERT(value_ptr != NULL || length == 0);
5428
5429
3.79k
  bytes = g_byte_array_new();
5430
3.79k
  if (length > 0) {
5431
3.31k
    g_byte_array_append(bytes, value_ptr, length);
5432
3.31k
  }
5433
3.79k
  fvalue_set_byte_array(fi->value, bytes);
5434
3.79k
}
5435
5436
static void
5437
proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5438
3.79k
{
5439
3.79k
  proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5440
3.79k
}
5441
5442
/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5443
 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5444
 * is destroyed. */
5445
proto_item *
5446
proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5447
          int length, const char* value)
5448
7.56M
{
5449
7.56M
  proto_item    *pi;
5450
7.56M
  header_field_info *hfinfo;
5451
7.56M
  int     item_length;
5452
5453
7.56M
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
5454
7.56M
  get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA);
5455
  /*
5456
   * Special case - if the length is 0, skip the test, so that
5457
   * we can have an empty string right after the end of the
5458
   * packet.  (This handles URL-encoded forms where the last field
5459
   * has no value so the form ends right after the =.)
5460
   *
5461
   * XXX - length zero makes sense for FT_STRING, and more or less
5462
   * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5463
   * for FT_STRINGZ (except that a number of fields that should be
5464
   * one of the others are actually registered as FT_STRINGZ.)
5465
   */
5466
7.56M
  if (item_length != 0)
5467
1.22M
    test_length(hfinfo, tvb, start, item_length, ENC_NA);
5468
5469
7.56M
  CHECK_FOR_NULL_TREE(tree);
5470
5471
7.19M
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5472
5473
1.94M
  DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo);
5474
5475
1.94M
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5476
1.94M
  DISSECTOR_ASSERT(length >= 0);
5477
5478
1.94M
  WS_UTF_8_CHECK(value, -1);
5479
1.94M
  proto_tree_set_string(PNODE_FINFO(pi), value);
5480
5481
1.94M
  return pi;
5482
7.19M
}
5483
5484
proto_item *
5485
proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5486
           int start, int length, const char* value,
5487
           const char *format,
5488
           ...)
5489
499k
{
5490
499k
  proto_item    *pi;
5491
499k
  va_list      ap;
5492
5493
499k
  pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5494
499k
  if (pi != tree) {
5495
176k
    va_start(ap, format);
5496
176k
    proto_tree_set_representation_value(pi, format, ap);
5497
176k
    va_end(ap);
5498
176k
  }
5499
5500
499k
  return pi;
5501
499k
}
5502
5503
proto_item *
5504
proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5505
           int start, int length, const char* value,
5506
           const char *format, ...)
5507
203k
{
5508
203k
  proto_item    *pi;
5509
203k
  va_list      ap;
5510
5511
203k
  pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5512
203k
  if (pi != tree) {
5513
203k
    TRY_TO_FAKE_THIS_REPR(pi);
5514
5515
197k
    va_start(ap, format);
5516
197k
    proto_tree_set_representation(pi, format, ap);
5517
197k
    va_end(ap);
5518
197k
  }
5519
5520
198k
  return pi;
5521
203k
}
5522
5523
/* Set the FT_STRING value */
5524
static void
5525
proto_tree_set_string(field_info *fi, const char* value)
5526
2.04M
{
5527
2.04M
  if (value) {
5528
1.89M
    fvalue_set_string(fi->value, value);
5529
1.89M
  } else {
5530
    /*
5531
     * XXX - why is a null value for a string field
5532
     * considered valid?
5533
     */
5534
152k
    fvalue_set_string(fi->value, "[ Null ]");
5535
152k
  }
5536
2.04M
}
5537
5538
/* Set the FT_AX25 value */
5539
static void
5540
proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5541
478
{
5542
478
  fvalue_set_ax25(fi->value, value);
5543
478
}
5544
5545
static void
5546
proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5547
478
{
5548
478
  proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5549
478
}
5550
5551
/* Set the FT_VINES value */
5552
static void
5553
proto_tree_set_vines(field_info *fi, const uint8_t* value)
5554
227
{
5555
227
  fvalue_set_vines(fi->value, value);
5556
227
}
5557
5558
static void
5559
proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5560
227
{
5561
227
  proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN));
5562
227
}
5563
5564
/* Add a FT_ETHER to a proto_tree */
5565
proto_item *
5566
proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5567
         int length, const uint8_t* value)
5568
1.24k
{
5569
1.24k
  proto_item    *pi;
5570
1.24k
  header_field_info *hfinfo;
5571
5572
1.24k
  CHECK_FOR_NULL_TREE(tree);
5573
5574
1.24k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5575
5576
1.17k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER);
5577
5578
1.17k
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5579
1.17k
  proto_tree_set_ether(PNODE_FINFO(pi), value);
5580
5581
1.17k
  return pi;
5582
1.24k
}
5583
5584
proto_item *
5585
proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5586
          int start, int length, const uint8_t* value,
5587
          const char *format, ...)
5588
0
{
5589
0
  proto_item    *pi;
5590
0
  va_list      ap;
5591
5592
0
  pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5593
0
  if (pi != tree) {
5594
0
    va_start(ap, format);
5595
0
    proto_tree_set_representation_value(pi, format, ap);
5596
0
    va_end(ap);
5597
0
  }
5598
5599
0
  return pi;
5600
0
}
5601
5602
proto_item *
5603
proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5604
          int start, int length, const uint8_t* value,
5605
          const char *format, ...)
5606
16
{
5607
16
  proto_item    *pi;
5608
16
  va_list      ap;
5609
5610
16
  pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5611
16
  if (pi != tree) {
5612
16
    TRY_TO_FAKE_THIS_REPR(pi);
5613
5614
16
    va_start(ap, format);
5615
16
    proto_tree_set_representation(pi, format, ap);
5616
16
    va_end(ap);
5617
16
  }
5618
5619
16
  return pi;
5620
16
}
5621
5622
/* Set the FT_ETHER value */
5623
static void
5624
proto_tree_set_ether(field_info *fi, const uint8_t* value)
5625
106k
{
5626
106k
  fvalue_set_ether(fi->value, value);
5627
106k
}
5628
5629
static void
5630
proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5631
105k
{
5632
105k
  proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN));
5633
105k
}
5634
5635
/* Add a FT_BOOLEAN to a proto_tree */
5636
proto_item *
5637
proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5638
           int length, uint64_t value)
5639
13.5M
{
5640
13.5M
  proto_item    *pi;
5641
13.5M
  header_field_info *hfinfo;
5642
5643
13.5M
  CHECK_FOR_NULL_TREE(tree);
5644
5645
13.5M
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5646
5647
5.28M
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN);
5648
5649
5.28M
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5650
5.28M
  proto_tree_set_boolean(PNODE_FINFO(pi), value);
5651
5652
5.28M
  return pi;
5653
13.5M
}
5654
5655
proto_item *
5656
proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5657
            tvbuff_t *tvb, int start, int length,
5658
            uint64_t value, const char *format, ...)
5659
4.64k
{
5660
4.64k
  proto_item    *pi;
5661
4.64k
  va_list      ap;
5662
5663
4.64k
  pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5664
4.64k
  if (pi != tree) {
5665
4.64k
    va_start(ap, format);
5666
4.64k
    proto_tree_set_representation_value(pi, format, ap);
5667
4.64k
    va_end(ap);
5668
4.64k
  }
5669
5670
4.64k
  return pi;
5671
4.64k
}
5672
5673
proto_item *
5674
proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5675
            int start, int length, uint64_t value,
5676
            const char *format, ...)
5677
3.74M
{
5678
3.74M
  proto_item    *pi;
5679
3.74M
  va_list      ap;
5680
5681
3.74M
  pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5682
3.74M
  if (pi != tree) {
5683
3.74M
    TRY_TO_FAKE_THIS_REPR(pi);
5684
5685
3.73M
    va_start(ap, format);
5686
3.73M
    proto_tree_set_representation(pi, format, ap);
5687
3.73M
    va_end(ap);
5688
3.73M
  }
5689
5690
3.73M
  return pi;
5691
3.74M
}
5692
5693
/* Set the FT_BOOLEAN value */
5694
static void
5695
proto_tree_set_boolean(field_info *fi, uint64_t value)
5696
6.14M
{
5697
6.14M
  proto_tree_set_uint64(fi, value);
5698
6.14M
}
5699
5700
/* Generate, into "buf", a string showing the bits of a bitfield.
5701
   Return a pointer to the character after that string. */
5702
static char *
5703
other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5704
149k
{
5705
149k
  int i = 0;
5706
149k
  uint64_t bit;
5707
149k
  char *p;
5708
5709
149k
  p = buf;
5710
5711
  /* This is a devel error. It is safer to stop here. */
5712
149k
  DISSECTOR_ASSERT(width >= 1);
5713
5714
149k
  bit = UINT64_C(1) << (width - 1);
5715
2.23M
  for (;;) {
5716
2.23M
    if (mask & bit) {
5717
      /* This bit is part of the field.  Show its value. */
5718
1.25M
      if (val & bit)
5719
358k
        *p++ = '1';
5720
898k
      else
5721
898k
        *p++ = '0';
5722
1.25M
    } else {
5723
      /* This bit is not part of the field. */
5724
980k
      *p++ = '.';
5725
980k
    }
5726
2.23M
    bit >>= 1;
5727
2.23M
    i++;
5728
2.23M
    if (i >= width)
5729
149k
      break;
5730
2.08M
    if (i % 4 == 0)
5731
410k
      *p++ = ' ';
5732
2.08M
  }
5733
149k
  *p = '\0';
5734
149k
  return p;
5735
149k
}
5736
5737
static char *
5738
decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5739
148k
{
5740
148k
  char *p;
5741
5742
148k
  p = other_decode_bitfield_value(buf, val, mask, width);
5743
148k
  p = g_stpcpy(p, " = ");
5744
5745
148k
  return p;
5746
148k
}
5747
5748
static char *
5749
other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5750
0
{
5751
0
  int i = 0;
5752
0
  uint64_t bit;
5753
0
  char *p;
5754
5755
0
  p = buf;
5756
5757
  /* This is a devel error. It is safer to stop here. */
5758
0
  DISSECTOR_ASSERT(width >= 1);
5759
5760
0
  bit = UINT64_C(1) << (width - 1);
5761
0
  for (;;) {
5762
0
    if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5763
0
      (mask & bit)) {
5764
      /* This bit is part of the field.  Show its value. */
5765
0
      if (val & bit)
5766
0
        *p++ = '1';
5767
0
      else
5768
0
        *p++ = '0';
5769
0
    } else {
5770
      /* This bit is not part of the field. */
5771
0
      *p++ = '.';
5772
0
    }
5773
0
    bit >>= 1;
5774
0
    i++;
5775
0
    if (i >= width)
5776
0
      break;
5777
0
    if (i % 4 == 0)
5778
0
      *p++ = ' ';
5779
0
  }
5780
5781
0
  *p = '\0';
5782
0
  return p;
5783
0
}
5784
5785
static char *
5786
decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5787
0
{
5788
0
  char *p;
5789
5790
0
  p = other_decode_bitfield_varint_value(buf, val, mask, width);
5791
0
  p = g_stpcpy(p, " = ");
5792
5793
0
  return p;
5794
0
}
5795
5796
/* Add a FT_FLOAT to a proto_tree */
5797
proto_item *
5798
proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5799
         int length, float value)
5800
436k
{
5801
436k
  proto_item    *pi;
5802
436k
  header_field_info *hfinfo;
5803
5804
436k
  CHECK_FOR_NULL_TREE(tree);
5805
5806
436k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5807
5808
161k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT);
5809
5810
161k
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5811
161k
  proto_tree_set_float(PNODE_FINFO(pi), value);
5812
5813
161k
  return pi;
5814
436k
}
5815
5816
proto_item *
5817
proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5818
          int start, int length, float value,
5819
          const char *format, ...)
5820
104k
{
5821
104k
  proto_item    *pi;
5822
104k
  va_list      ap;
5823
5824
104k
  pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5825
104k
  if (pi != tree) {
5826
104k
    va_start(ap, format);
5827
104k
    proto_tree_set_representation_value(pi, format, ap);
5828
104k
    va_end(ap);
5829
104k
  }
5830
5831
104k
  return pi;
5832
104k
}
5833
5834
proto_item *
5835
proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5836
          int start, int length, float value,
5837
          const char *format, ...)
5838
273k
{
5839
273k
  proto_item    *pi;
5840
273k
  va_list      ap;
5841
5842
273k
  pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5843
273k
  if (pi != tree) {
5844
273k
    TRY_TO_FAKE_THIS_REPR(pi);
5845
5846
701
    va_start(ap, format);
5847
701
    proto_tree_set_representation(pi, format, ap);
5848
701
    va_end(ap);
5849
701
  }
5850
5851
703
  return pi;
5852
273k
}
5853
5854
/* Set the FT_FLOAT value */
5855
static void
5856
proto_tree_set_float(field_info *fi, float value)
5857
163k
{
5858
163k
  fvalue_set_floating(fi->value, value);
5859
163k
}
5860
5861
/* Add a FT_DOUBLE to a proto_tree */
5862
proto_item *
5863
proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5864
          int length, double value)
5865
544k
{
5866
544k
  proto_item    *pi;
5867
544k
  header_field_info *hfinfo;
5868
5869
544k
  CHECK_FOR_NULL_TREE(tree);
5870
5871
163k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5872
5873
158k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE);
5874
5875
158k
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5876
158k
  proto_tree_set_double(PNODE_FINFO(pi), value);
5877
5878
158k
  return pi;
5879
163k
}
5880
5881
proto_item *
5882
proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5883
           int start, int length, double value,
5884
           const char *format, ...)
5885
349
{
5886
349
  proto_item    *pi;
5887
349
  va_list      ap;
5888
5889
349
  pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5890
349
  if (pi != tree) {
5891
349
    va_start(ap, format);
5892
349
    proto_tree_set_representation_value(pi, format, ap);
5893
349
    va_end(ap);
5894
349
  }
5895
5896
349
  return pi;
5897
349
}
5898
5899
proto_item *
5900
proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5901
           int start, int length, double value,
5902
           const char *format, ...)
5903
1
{
5904
1
  proto_item    *pi;
5905
1
  va_list      ap;
5906
5907
1
  pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5908
1
  if (pi != tree) {
5909
1
    TRY_TO_FAKE_THIS_REPR(pi);
5910
5911
1
    va_start(ap, format);
5912
1
    proto_tree_set_representation(pi, format, ap);
5913
1
    va_end(ap);
5914
1
  }
5915
5916
1
  return pi;
5917
1
}
5918
5919
/* Set the FT_DOUBLE value */
5920
static void
5921
proto_tree_set_double(field_info *fi, double value)
5922
160k
{
5923
160k
  fvalue_set_floating(fi->value, value);
5924
160k
}
5925
5926
/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5927
proto_item *
5928
proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5929
        int length, uint32_t value)
5930
20.5M
{
5931
20.5M
  proto_item    *pi = NULL;
5932
20.5M
  header_field_info *hfinfo;
5933
5934
20.5M
  CHECK_FOR_NULL_TREE(tree);
5935
5936
19.5M
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
5937
5938
9.97M
  switch (hfinfo->type) {
5939
16
    case FT_CHAR:
5940
1.87M
    case FT_UINT8:
5941
2.60M
    case FT_UINT16:
5942
2.63M
    case FT_UINT24:
5943
9.92M
    case FT_UINT32:
5944
9.97M
    case FT_FRAMENUM:
5945
9.97M
      pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5946
9.97M
      proto_tree_set_uint(PNODE_FINFO(pi), value);
5947
9.97M
      break;
5948
5949
0
    default:
5950
0
      REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, or FT_FRAMENUM",
5951
9.97M
          hfinfo->abbrev);
5952
9.97M
  }
5953
5954
9.97M
  return pi;
5955
9.97M
}
5956
5957
proto_item *
5958
proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5959
         int start, int length, uint32_t value,
5960
         const char *format, ...)
5961
10.5M
{
5962
10.5M
  proto_item    *pi;
5963
10.5M
  va_list      ap;
5964
5965
10.5M
  pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5966
10.5M
  if (pi != tree) {
5967
10.5M
    va_start(ap, format);
5968
10.5M
    proto_tree_set_representation_value(pi, format, ap);
5969
10.5M
    va_end(ap);
5970
10.5M
  }
5971
5972
10.5M
  return pi;
5973
10.5M
}
5974
5975
proto_item *
5976
proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5977
         int start, int length, uint32_t value,
5978
         const char *format, ...)
5979
416k
{
5980
416k
  proto_item    *pi;
5981
416k
  va_list      ap;
5982
5983
416k
  pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5984
416k
  if (pi != tree) {
5985
416k
    TRY_TO_FAKE_THIS_REPR(pi);
5986
5987
312k
    va_start(ap, format);
5988
312k
    proto_tree_set_representation(pi, format, ap);
5989
312k
    va_end(ap);
5990
312k
  }
5991
5992
313k
  return pi;
5993
416k
}
5994
5995
/* Set the FT_UINT{8,16,24,32} value */
5996
static void
5997
proto_tree_set_uint(field_info *fi, uint32_t value)
5998
15.4M
{
5999
15.4M
  const header_field_info *hfinfo;
6000
15.4M
  uint32_t       integer;
6001
6002
15.4M
  hfinfo = fi->hfinfo;
6003
15.4M
  integer = value;
6004
6005
15.4M
  if (hfinfo->bitmask) {
6006
    /* Mask out irrelevant portions */
6007
2.28M
    integer &= (uint32_t)(hfinfo->bitmask);
6008
6009
    /* Shift bits */
6010
2.28M
    integer >>= hfinfo_bitshift(hfinfo);
6011
6012
2.28M
    FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
6013
2.28M
    FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
6014
2.28M
  }
6015
6016
15.4M
  fvalue_set_uinteger(fi->value, integer);
6017
15.4M
}
6018
6019
/* Add FT_UINT{40,48,56,64} to a proto_tree */
6020
proto_item *
6021
proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6022
          int length, uint64_t value)
6023
166k
{
6024
166k
  proto_item    *pi = NULL;
6025
166k
  header_field_info *hfinfo;
6026
6027
166k
  CHECK_FOR_NULL_TREE(tree);
6028
6029
166k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
6030
6031
161k
  switch (hfinfo->type) {
6032
111k
    case FT_UINT40:
6033
115k
    case FT_UINT48:
6034
116k
    case FT_UINT56:
6035
161k
    case FT_UINT64:
6036
161k
    case FT_FRAMENUM:
6037
161k
      pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6038
161k
      proto_tree_set_uint64(PNODE_FINFO(pi), value);
6039
161k
      break;
6040
6041
0
    default:
6042
0
      REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, or FT_FRAMENUM",
6043
161k
          hfinfo->abbrev);
6044
161k
  }
6045
6046
161k
  return pi;
6047
161k
}
6048
6049
proto_item *
6050
proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6051
           int start, int length, uint64_t value,
6052
           const char *format, ...)
6053
6.71k
{
6054
6.71k
  proto_item    *pi;
6055
6.71k
  va_list      ap;
6056
6057
6.71k
  pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6058
6.71k
  if (pi != tree) {
6059
6.71k
    va_start(ap, format);
6060
6.71k
    proto_tree_set_representation_value(pi, format, ap);
6061
6.71k
    va_end(ap);
6062
6.71k
  }
6063
6064
6.71k
  return pi;
6065
6.71k
}
6066
6067
proto_item *
6068
proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6069
           int start, int length, uint64_t value,
6070
           const char *format, ...)
6071
58
{
6072
58
  proto_item    *pi;
6073
58
  va_list      ap;
6074
6075
58
  pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6076
58
  if (pi != tree) {
6077
58
    TRY_TO_FAKE_THIS_REPR(pi);
6078
6079
54
    va_start(ap, format);
6080
54
    proto_tree_set_representation(pi, format, ap);
6081
54
    va_end(ap);
6082
54
  }
6083
6084
54
  return pi;
6085
58
}
6086
6087
/* Set the FT_UINT{40,48,56,64} value */
6088
static void
6089
proto_tree_set_uint64(field_info *fi, uint64_t value)
6090
6.40M
{
6091
6.40M
  const header_field_info *hfinfo;
6092
6.40M
  uint64_t       integer;
6093
6094
6.40M
  hfinfo = fi->hfinfo;
6095
6.40M
  integer = value;
6096
6097
6.40M
  if (hfinfo->bitmask) {
6098
    /* Mask out irrelevant portions */
6099
5.48M
    integer &= hfinfo->bitmask;
6100
6101
    /* Shift bits */
6102
5.48M
    integer >>= hfinfo_bitshift(hfinfo);
6103
6104
5.48M
    FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
6105
5.48M
    FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
6106
5.48M
  }
6107
6108
6.40M
  fvalue_set_uinteger64(fi->value, integer);
6109
6.40M
}
6110
6111
/* Add FT_INT{8,16,24,32} to a proto_tree */
6112
proto_item *
6113
proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6114
       int length, int32_t value)
6115
360k
{
6116
360k
  proto_item    *pi = NULL;
6117
360k
  header_field_info *hfinfo;
6118
6119
360k
  CHECK_FOR_NULL_TREE(tree);
6120
6121
350k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
6122
6123
303k
  switch (hfinfo->type) {
6124
23.3k
    case FT_INT8:
6125
126k
    case FT_INT16:
6126
126k
    case FT_INT24:
6127
303k
    case FT_INT32:
6128
303k
      pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6129
303k
      proto_tree_set_int(PNODE_FINFO(pi), value);
6130
303k
      break;
6131
6132
0
    default:
6133
0
      REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
6134
303k
          hfinfo->abbrev);
6135
303k
  }
6136
6137
303k
  return pi;
6138
303k
}
6139
6140
proto_item *
6141
proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6142
        int start, int length, int32_t value,
6143
        const char *format, ...)
6144
8.40k
{
6145
8.40k
  proto_item  *pi;
6146
8.40k
  va_list      ap;
6147
6148
8.40k
  pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6149
8.40k
  if (pi != tree) {
6150
8.40k
    va_start(ap, format);
6151
8.40k
    proto_tree_set_representation_value(pi, format, ap);
6152
8.40k
    va_end(ap);
6153
8.40k
  }
6154
6155
8.40k
  return pi;
6156
8.40k
}
6157
6158
proto_item *
6159
proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6160
        int start, int length, int32_t value,
6161
        const char *format, ...)
6162
12.9k
{
6163
12.9k
  proto_item *pi;
6164
12.9k
  va_list     ap;
6165
6166
12.9k
  pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6167
12.9k
  if (pi != tree) {
6168
12.9k
    TRY_TO_FAKE_THIS_REPR(pi);
6169
6170
12.6k
    va_start(ap, format);
6171
12.6k
    proto_tree_set_representation(pi, format, ap);
6172
12.6k
    va_end(ap);
6173
12.6k
  }
6174
6175
12.6k
  return pi;
6176
12.9k
}
6177
6178
/* Set the FT_INT{8,16,24,32} value */
6179
static void
6180
proto_tree_set_int(field_info *fi, int32_t value)
6181
968k
{
6182
968k
  const header_field_info *hfinfo;
6183
968k
  uint32_t       integer;
6184
968k
  int      no_of_bits;
6185
6186
968k
  hfinfo = fi->hfinfo;
6187
968k
  integer = (uint32_t) value;
6188
6189
968k
  if (hfinfo->bitmask) {
6190
    /* Mask out irrelevant portions */
6191
1.23k
    integer &= (uint32_t)(hfinfo->bitmask);
6192
6193
    /* Shift bits */
6194
1.23k
    integer >>= hfinfo_bitshift(hfinfo);
6195
6196
1.23k
    no_of_bits = ws_count_ones(hfinfo->bitmask);
6197
1.23k
    integer = ws_sign_ext32(integer, no_of_bits);
6198
6199
1.23k
    FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
6200
1.23k
    FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
6201
1.23k
  }
6202
6203
968k
  fvalue_set_sinteger(fi->value, integer);
6204
968k
}
6205
6206
/* Add FT_INT{40,48,56,64} to a proto_tree */
6207
proto_item *
6208
proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6209
         int length, int64_t value)
6210
32.6k
{
6211
32.6k
  proto_item    *pi = NULL;
6212
32.6k
  header_field_info *hfinfo;
6213
6214
32.6k
  CHECK_FOR_NULL_TREE(tree);
6215
6216
32.6k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
6217
6218
32.5k
  switch (hfinfo->type) {
6219
0
    case FT_INT40:
6220
0
    case FT_INT48:
6221
0
    case FT_INT56:
6222
32.5k
    case FT_INT64:
6223
32.5k
      pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6224
32.5k
      proto_tree_set_int64(PNODE_FINFO(pi), value);
6225
32.5k
      break;
6226
6227
0
    default:
6228
0
      REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
6229
32.5k
          hfinfo->abbrev);
6230
32.5k
  }
6231
6232
32.5k
  return pi;
6233
32.5k
}
6234
6235
proto_item *
6236
proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6237
          int start, int length, int64_t value,
6238
          const char *format, ...)
6239
1.49k
{
6240
1.49k
  proto_item    *pi;
6241
1.49k
  va_list      ap;
6242
6243
1.49k
  pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6244
1.49k
  if (pi != tree) {
6245
1.49k
    va_start(ap, format);
6246
1.49k
    proto_tree_set_representation_value(pi, format, ap);
6247
1.49k
    va_end(ap);
6248
1.49k
  }
6249
6250
1.49k
  return pi;
6251
1.49k
}
6252
6253
/* Set the FT_INT{40,48,56,64} value */
6254
static void
6255
proto_tree_set_int64(field_info *fi, int64_t value)
6256
37.8k
{
6257
37.8k
  const header_field_info *hfinfo;
6258
37.8k
  uint64_t       integer;
6259
37.8k
  int      no_of_bits;
6260
6261
37.8k
  hfinfo = fi->hfinfo;
6262
37.8k
  integer = value;
6263
6264
37.8k
  if (hfinfo->bitmask) {
6265
    /* Mask out irrelevant portions */
6266
0
    integer &= hfinfo->bitmask;
6267
6268
    /* Shift bits */
6269
0
    integer >>= hfinfo_bitshift(hfinfo);
6270
6271
0
    no_of_bits = ws_count_ones(hfinfo->bitmask);
6272
0
    integer = ws_sign_ext64(integer, no_of_bits);
6273
6274
0
    FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)));
6275
0
    FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)));
6276
0
  }
6277
6278
37.8k
  fvalue_set_sinteger64(fi->value, integer);
6279
37.8k
}
6280
6281
proto_item *
6282
proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6283
         int start, int length, int64_t value,
6284
         const char *format, ...)
6285
3.65k
{
6286
3.65k
  proto_item    *pi;
6287
3.65k
  va_list      ap;
6288
6289
3.65k
  pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6290
3.65k
  if (pi != tree) {
6291
3.65k
    TRY_TO_FAKE_THIS_REPR(pi);
6292
6293
3.63k
    va_start(ap, format);
6294
3.63k
    proto_tree_set_representation(pi, format, ap);
6295
3.63k
    va_end(ap);
6296
3.63k
  }
6297
6298
3.63k
  return pi;
6299
3.65k
}
6300
6301
/* Add a FT_EUI64 to a proto_tree */
6302
proto_item *
6303
proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6304
         int length, const uint64_t value)
6305
1.59k
{
6306
1.59k
  proto_item    *pi;
6307
1.59k
  header_field_info *hfinfo;
6308
6309
1.59k
  CHECK_FOR_NULL_TREE(tree);
6310
6311
1.59k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
6312
6313
1.58k
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64);
6314
6315
1.58k
  pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6316
1.58k
  proto_tree_set_eui64(PNODE_FINFO(pi), value);
6317
6318
1.58k
  return pi;
6319
1.59k
}
6320
6321
proto_item *
6322
proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6323
          int start, int length, const uint64_t value,
6324
          const char *format, ...)
6325
0
{
6326
0
  proto_item    *pi;
6327
0
  va_list      ap;
6328
6329
0
  pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6330
0
  if (pi != tree) {
6331
0
    va_start(ap, format);
6332
0
    proto_tree_set_representation_value(pi, format, ap);
6333
0
    va_end(ap);
6334
0
  }
6335
6336
0
  return pi;
6337
0
}
6338
6339
proto_item *
6340
proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6341
          int start, int length, const uint64_t value,
6342
          const char *format, ...)
6343
0
{
6344
0
  proto_item    *pi;
6345
0
  va_list      ap;
6346
6347
0
  pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6348
0
  if (pi != tree) {
6349
0
    TRY_TO_FAKE_THIS_REPR(pi);
6350
6351
0
    va_start(ap, format);
6352
0
    proto_tree_set_representation(pi, format, ap);
6353
0
    va_end(ap);
6354
0
  }
6355
6356
0
  return pi;
6357
0
}
6358
6359
/* Set the FT_EUI64 value */
6360
static void
6361
proto_tree_set_eui64(field_info *fi, const uint64_t value)
6362
6.73k
{
6363
6.73k
  uint8_t v[FT_EUI64_LEN];
6364
6.73k
  phtonu64(v, value);
6365
6.73k
  fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN);
6366
6.73k
}
6367
6368
static void
6369
proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6370
5.14k
{
6371
5.14k
  if (encoding)
6372
5.11k
  {
6373
5.11k
    proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6374
5.11k
  } else {
6375
31
    proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6376
31
  }
6377
5.14k
}
6378
6379
proto_item *
6380
proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6381
          const mac_hf_list_t *list_generic,
6382
          int idx, tvbuff_t *tvb,
6383
          proto_tree *tree, int offset)
6384
45.3k
{
6385
45.3k
  uint8_t     addr[6];
6386
45.3k
  const char *addr_name = NULL;
6387
45.3k
  const char *oui_name  = NULL;
6388
45.3k
  proto_item *addr_item = NULL;
6389
45.3k
  proto_tree *addr_tree = NULL;
6390
45.3k
  proto_item *ret_val   = NULL;
6391
6392
45.3k
  if (tree == NULL || list_specific == NULL) {
6393
1.46k
    return NULL;
6394
1.46k
  }
6395
6396
  /* Resolve what we can of the address */
6397
43.9k
  tvb_memcpy(tvb, addr, offset, sizeof addr);
6398
43.9k
  if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6399
43.8k
    addr_name = get_ether_name(addr);
6400
43.8k
  }
6401
43.9k
  if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6402
43.8k
    oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6403
43.8k
  }
6404
6405
  /* Add the item for the specific address type */
6406
43.9k
  ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN);
6407
43.9k
  if (idx >= 0) {
6408
40.3k
    addr_tree = proto_item_add_subtree(ret_val, idx);
6409
40.3k
  }
6410
3.55k
  else {
6411
3.55k
    addr_tree = tree;
6412
3.55k
  }
6413
6414
43.9k
  if (list_specific->hf_addr_resolved != NULL) {
6415
43.8k
    addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6416
43.8k
              tvb, offset, 6, addr_name);
6417
43.8k
    proto_item_set_generated(addr_item);
6418
43.8k
    proto_item_set_hidden(addr_item);
6419
43.8k
  }
6420
6421
43.9k
  if (list_specific->hf_oui != NULL) {
6422
43.8k
    addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN);
6423
43.8k
    proto_item_set_generated(addr_item);
6424
43.8k
    proto_item_set_hidden(addr_item);
6425
6426
43.8k
    if (oui_name != NULL && list_specific->hf_oui_resolved != NULL) {
6427
12.3k
      addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6428
12.3k
      proto_item_set_generated(addr_item);
6429
12.3k
      proto_item_set_hidden(addr_item);
6430
12.3k
    }
6431
43.8k
  }
6432
6433
43.9k
  if (list_specific->hf_lg != NULL) {
6434
40.3k
    proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN);
6435
40.3k
  }
6436
43.9k
  if (list_specific->hf_ig != NULL) {
6437
40.3k
    proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN);
6438
40.3k
  }
6439
6440
  /* Were we given a list for generic address fields? If not, stop here */
6441
43.9k
  if (list_generic == NULL) {
6442
11.8k
    return ret_val;
6443
11.8k
  }
6444
6445
32.0k
  addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN);
6446
32.0k
  proto_item_set_hidden(addr_item);
6447
6448
32.0k
  if (list_generic->hf_addr_resolved != NULL) {
6449
32.0k
    addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6450
32.0k
              tvb, offset, 6, addr_name);
6451
32.0k
    proto_item_set_generated(addr_item);
6452
32.0k
    proto_item_set_hidden(addr_item);
6453
32.0k
  }
6454
6455
32.0k
  if (list_generic->hf_oui != NULL) {
6456
32.0k
    addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN);
6457
32.0k
    proto_item_set_generated(addr_item);
6458
32.0k
    proto_item_set_hidden(addr_item);
6459
6460
32.0k
    if (oui_name != NULL && list_generic->hf_oui_resolved != NULL) {
6461
7.29k
      addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6462
7.29k
      proto_item_set_generated(addr_item);
6463
7.29k
      proto_item_set_hidden(addr_item);
6464
7.29k
    }
6465
32.0k
  }
6466
6467
32.0k
  if (list_generic->hf_lg != NULL) {
6468
32.0k
    addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN);
6469
32.0k
    proto_item_set_hidden(addr_item);
6470
32.0k
  }
6471
32.0k
  if (list_generic->hf_ig != NULL) {
6472
32.0k
    addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN);
6473
32.0k
    proto_item_set_hidden(addr_item);
6474
32.0k
  }
6475
32.0k
  return ret_val;
6476
43.9k
}
6477
6478
static proto_item *
6479
proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6480
54.1M
{
6481
54.1M
  proto_node *pnode, *tnode, *sibling;
6482
54.1M
  field_info *tfi;
6483
54.1M
  unsigned depth = 1;
6484
6485
54.1M
  ws_assert(tree);
6486
6487
  /*
6488
   * Restrict our depth. proto_tree_traverse_pre_order and
6489
   * proto_tree_traverse_post_order (and possibly others) are recursive
6490
   * so we need to be mindful of our stack size.
6491
   */
6492
54.1M
  if (tree->first_child == NULL) {
6493
221M
    for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
6494
209M
      depth++;
6495
209M
      if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)) {
6496
0
        THROW_MESSAGE(DissectorError, wmem_strdup_printf(PNODE_POOL(tree),
6497
0
                 "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)",
6498
0
                 prefs.gui_max_tree_depth,
6499
0
                 hfinfo->name, hfinfo->abbrev, G_STRFUNC, __LINE__));
6500
0
      }
6501
209M
    }
6502
12.0M
  }
6503
6504
  /*
6505
   * Make sure "tree" is ready to have subtrees under it, by
6506
   * checking whether it's been given an ett_ value.
6507
   *
6508
   * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6509
   * node of the protocol tree.  That node is not displayed,
6510
   * so it doesn't need an ett_ value to remember whether it
6511
   * was expanded.
6512
   */
6513
54.1M
  tnode = tree;
6514
54.1M
  tfi = PNODE_FINFO(tnode);
6515
54.1M
  if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6516
0
    REPORT_DISSECTOR_BUG("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",
6517
0
             hfinfo->name, hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__);
6518
    /* XXX - is it safe to continue here? */
6519
0
  }
6520
6521
54.1M
  pnode = wmem_new(PNODE_POOL(tree), proto_node);
6522
54.1M
  PROTO_NODE_INIT(pnode);
6523
54.1M
  pnode->parent = tnode;
6524
54.1M
  PNODE_HFINFO(pnode) = hfinfo;
6525
54.1M
  PNODE_FINFO(pnode) = NULL; // Faked
6526
54.1M
  pnode->tree_data = PTREE_DATA(tree);
6527
6528
54.1M
  if (tnode->last_child != NULL) {
6529
42.0M
    sibling = tnode->last_child;
6530
42.0M
    DISSECTOR_ASSERT(sibling->next == NULL);
6531
42.0M
    sibling->next = pnode;
6532
42.0M
  } else
6533
12.0M
    tnode->first_child = pnode;
6534
54.1M
  tnode->last_child = pnode;
6535
6536
  /* We should not be adding a fake node for an interesting field */
6537
54.1M
  ws_assert(hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT);
6538
6539
  /* XXX - Should the proto_item have a header_field_info member, at least
6540
   * for faked items, to know what hfi was faked? (Some dissectors look at
6541
   * the tree items directly.)
6542
   */
6543
54.1M
  return (proto_item *)pnode;
6544
54.1M
}
6545
6546
/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6547
static proto_item *
6548
proto_tree_add_node(proto_tree *tree, field_info *fi)
6549
35.4M
{
6550
35.4M
  proto_node *pnode, *tnode, *sibling;
6551
35.4M
  field_info *tfi;
6552
35.4M
  unsigned depth = 1;
6553
6554
35.4M
  ws_assert(tree);
6555
6556
  /*
6557
   * Restrict our depth. proto_tree_traverse_pre_order and
6558
   * proto_tree_traverse_post_order (and possibly others) are recursive
6559
   * so we need to be mindful of our stack size.
6560
   */
6561
35.4M
  if (tree->first_child == NULL) {
6562
127M
    for (tnode = tree; tnode != NULL; tnode = tnode->parent) {
6563
118M
      depth++;
6564
118M
      if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)) {
6565
1
        fvalue_free(fi->value);
6566
1
        fi->value = NULL;
6567
1
        THROW_MESSAGE(DissectorError, wmem_strdup_printf(PNODE_POOL(tree),
6568
1
                 "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)",
6569
1
                 prefs.gui_max_tree_depth,
6570
1
                 fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__));
6571
1
      }
6572
118M
    }
6573
9.34M
  }
6574
6575
  /*
6576
   * Make sure "tree" is ready to have subtrees under it, by
6577
   * checking whether it's been given an ett_ value.
6578
   *
6579
   * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6580
   * node of the protocol tree.  That node is not displayed,
6581
   * so it doesn't need an ett_ value to remember whether it
6582
   * was expanded.
6583
   */
6584
35.4M
  tnode = tree;
6585
35.4M
  tfi = PNODE_FINFO(tnode);
6586
35.4M
  if (tfi != NULL && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6587
    /* Since we are not adding fi to a node, its fvalue won't get
6588
     * freed by proto_tree_free_node(), so free it now.
6589
     */
6590
0
    fvalue_free(fi->value);
6591
0
    fi->value = NULL;
6592
0
    REPORT_DISSECTOR_BUG("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",
6593
0
             fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__);
6594
    /* XXX - is it safe to continue here? */
6595
0
  }
6596
6597
35.4M
  pnode = wmem_new(PNODE_POOL(tree), proto_node);
6598
35.4M
  PROTO_NODE_INIT(pnode);
6599
35.4M
  pnode->parent = tnode;
6600
35.4M
  PNODE_HFINFO(pnode) = fi->hfinfo;
6601
35.4M
  PNODE_FINFO(pnode) = fi;
6602
35.4M
  pnode->tree_data = PTREE_DATA(tree);
6603
6604
35.4M
  if (tnode->last_child != NULL) {
6605
26.1M
    sibling = tnode->last_child;
6606
26.1M
    DISSECTOR_ASSERT(sibling->next == NULL);
6607
26.1M
    sibling->next = pnode;
6608
26.1M
  } else
6609
9.34M
    tnode->first_child = pnode;
6610
35.4M
  tnode->last_child = pnode;
6611
6612
35.4M
  tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6613
6614
35.4M
  return (proto_item *)pnode;
6615
35.4M
}
6616
6617
6618
/* Generic way to allocate field_info and add to proto_tree.
6619
 * Sets *pfi to address of newly-allocated field_info struct */
6620
static proto_item *
6621
proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6622
      int *length)
6623
23.9M
{
6624
23.9M
  proto_item *pi;
6625
23.9M
  field_info *fi;
6626
23.9M
  int   item_length;
6627
6628
23.9M
  get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA);
6629
23.9M
  fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6630
23.9M
  pi = proto_tree_add_node(tree, fi);
6631
6632
23.9M
  return pi;
6633
23.9M
}
6634
6635
6636
static void
6637
get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6638
       int *item_length, const unsigned encoding)
6639
59.7M
{
6640
59.7M
  int length_remaining;
6641
6642
  /*
6643
   * We only allow a null tvbuff if the item has a zero length,
6644
   * i.e. if there's no data backing it.
6645
   */
6646
59.7M
  DISSECTOR_ASSERT(tvb != NULL || *length == 0);
6647
6648
  /*
6649
   * XXX - in some protocols, there are 32-bit unsigned length
6650
   * fields, so lengths in protocol tree and tvbuff routines
6651
   * should really be unsigned.  We should have, for those
6652
   * field types for which "to the end of the tvbuff" makes sense,
6653
   * additional routines that take no length argument and
6654
   * add fields that run to the end of the tvbuff.
6655
   */
6656
59.7M
  if (*length == -1) {
6657
    /*
6658
     * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6659
     * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6660
     * of -1 means "set the length to what remains in the
6661
     * tvbuff".
6662
     *
6663
     * The assumption is either that
6664
     *
6665
     *  1) the length of the item can only be determined
6666
     *     by dissection (typically true of items with
6667
     *     subitems, which are probably FT_NONE or
6668
     *     FT_PROTOCOL)
6669
     *
6670
     * or
6671
     *
6672
     *  2) if the tvbuff is "short" (either due to a short
6673
     *     snapshot length or due to lack of reassembly of
6674
     *     fragments/segments/whatever), we want to display
6675
     *     what's available in the field (probably FT_BYTES
6676
     *     or FT_STRING) and then throw an exception later
6677
     *
6678
     * or
6679
     *
6680
     *  3) the field is defined to be "what's left in the
6681
     *     packet"
6682
     *
6683
     * so we set the length to what remains in the tvbuff so
6684
     * that, if we throw an exception while dissecting, it
6685
     * has what is probably the right value.
6686
     *
6687
     * For FT_STRINGZ, it means "the string is null-terminated,
6688
     * not null-padded; set the length to the actual length
6689
     * of the string", and if the tvbuff if short, we just
6690
     * throw an exception.
6691
     *
6692
     * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6693
     * it means "find the end of the string",
6694
     * and if the tvbuff if short, we just throw an exception.
6695
     *
6696
     * It's not valid for any other type of field.  For those
6697
     * fields, we treat -1 the same way we treat other
6698
     * negative values - we assume the length is a Really
6699
     * Big Positive Number, and throw a ReportedBoundsError
6700
     * exception, under the assumption that the Really Big
6701
     * Length would run past the end of the packet.
6702
     */
6703
956k
    if ((FT_IS_INT(hfinfo->type)) || (FT_IS_UINT(hfinfo->type))) {
6704
23
      if (encoding & (ENC_VARINT_PROTOBUF|ENC_VARINT_ZIGZAG|ENC_VARINT_SDNV)) {
6705
        /*
6706
         * Leave the length as -1, so our caller knows
6707
         * it was -1.
6708
         */
6709
14
        *item_length = *length;
6710
14
        return;
6711
14
      } else if (encoding & ENC_VARINT_QUIC) {
6712
0
        switch (tvb_get_uint8(tvb, start) >> 6)
6713
0
        {
6714
0
        case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6715
0
          *item_length = 1;
6716
0
          break;
6717
0
        case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6718
0
          *item_length = 2;
6719
0
          break;
6720
0
        case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6721
0
          *item_length = 4;
6722
0
          break;
6723
0
        case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6724
0
          *item_length = 8;
6725
0
          break;
6726
0
        }
6727
0
      }
6728
23
    }
6729
6730
956k
    switch (hfinfo->type) {
6731
6732
335k
    case FT_PROTOCOL:
6733
574k
    case FT_NONE:
6734
955k
    case FT_BYTES:
6735
956k
    case FT_STRING:
6736
956k
    case FT_STRINGZPAD:
6737
956k
    case FT_STRINGZTRUNC:
6738
      /*
6739
       * We allow FT_PROTOCOLs to be zero-length -
6740
       * for example, an ONC RPC NULL procedure has
6741
       * neither arguments nor reply, so the
6742
       * payload for that protocol is empty.
6743
       *
6744
       * We also allow the others to be zero-length -
6745
       * because that's the way the code has been for a
6746
       * long, long time.
6747
       *
6748
       * However, we want to ensure that the start
6749
       * offset is not *past* the byte past the end
6750
       * of the tvbuff: we throw an exception in that
6751
       * case.
6752
       */
6753
956k
      *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6754
956k
      DISSECTOR_ASSERT(*length >= 0);
6755
956k
      break;
6756
6757
295
    case FT_STRINGZ:
6758
      /*
6759
       * Leave the length as -1, so our caller knows
6760
       * it was -1.
6761
       */
6762
295
      break;
6763
6764
11
    default:
6765
11
      THROW(ReportedBoundsError);
6766
11
      DISSECTOR_ASSERT_NOT_REACHED();
6767
956k
    }
6768
954k
    *item_length = *length;
6769
58.7M
  } else {
6770
58.7M
    *item_length = *length;
6771
58.7M
    if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6772
      /*
6773
       * These types are for interior nodes of the
6774
       * tree, and don't have data associated with
6775
       * them; if the length is negative (XXX - see
6776
       * above) or goes past the end of the tvbuff,
6777
       * cut it short at the end of the tvbuff.
6778
       * That way, if this field is selected in
6779
       * Wireshark, we don't highlight stuff past
6780
       * the end of the data.
6781
       */
6782
      /* XXX - what to do, if we don't have a tvb? */
6783
11.8M
      if (tvb) {
6784
9.71M
        length_remaining = tvb_captured_length_remaining(tvb, start);
6785
9.71M
        if (*item_length < 0 ||
6786
9.70M
          (*item_length > 0 &&
6787
5.51M
            (length_remaining < *item_length)))
6788
927k
          *item_length = length_remaining;
6789
9.71M
      }
6790
11.8M
    }
6791
58.7M
    if (*item_length < 0) {
6792
352
      THROW(ReportedBoundsError);
6793
352
    }
6794
58.7M
  }
6795
59.7M
}
6796
6797
static void
6798
get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6799
  unsigned* item_length, const unsigned encoding _U_)
6800
506
{
6801
506
  unsigned length_remaining;
6802
6803
  /*
6804
   * We only allow a null tvbuff if the item has a zero length,
6805
   * i.e. if there's no data backing it.
6806
   */
6807
506
  DISSECTOR_ASSERT(tvb != NULL || *length == 0);
6808
6809
6810
506
  *item_length = *length;
6811
506
  if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6812
    /*
6813
      * These types are for interior nodes of the
6814
      * tree, and don't have data associated with
6815
      * them; if the length is negative (XXX - see
6816
      * above) or goes past the end of the tvbuff,
6817
      * cut it short at the end of the tvbuff.
6818
      * That way, if this field is selected in
6819
      * Wireshark, we don't highlight stuff past
6820
      * the end of the data.
6821
      */
6822
      /* XXX - what to do, if we don't have a tvb? */
6823
0
    if (tvb) {
6824
0
      length_remaining = tvb_captured_length_remaining(tvb, start);
6825
0
      if (*item_length > 0 && (length_remaining < *item_length)) {
6826
0
        *item_length = length_remaining;
6827
0
      }
6828
0
    }
6829
0
  }
6830
506
}
6831
6832
static int
6833
get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6834
    int length, unsigned item_length, const int encoding)
6835
22.5k
{
6836
22.5k
  uint32_t n;
6837
6838
  /*
6839
   * We need to get the correct item length here.
6840
   * That's normally done by proto_tree_new_item(),
6841
   * but we won't be calling it.
6842
   */
6843
22.5k
  switch (hfinfo->type) {
6844
6845
77
  case FT_NONE:
6846
77
  case FT_PROTOCOL:
6847
651
  case FT_BYTES:
6848
    /*
6849
     * The length is the specified length.
6850
     */
6851
651
    break;
6852
6853
0
  case FT_UINT_BYTES:
6854
0
    n = get_uint_value(NULL, tvb, start, length, encoding);
6855
0
    item_length += n;
6856
0
    if ((int)item_length < length) {
6857
0
      THROW(ReportedBoundsError);
6858
0
    }
6859
0
    break;
6860
6861
  /* XXX - make these just FT_UINT? */
6862
15.2k
  case FT_UINT8:
6863
18.3k
  case FT_UINT16:
6864
18.4k
  case FT_UINT24:
6865
19.2k
  case FT_UINT32:
6866
19.2k
  case FT_UINT40:
6867
19.2k
  case FT_UINT48:
6868
19.2k
  case FT_UINT56:
6869
19.2k
  case FT_UINT64:
6870
  /* XXX - make these just FT_INT? */
6871
19.2k
  case FT_INT8:
6872
19.2k
  case FT_INT16:
6873
19.2k
  case FT_INT24:
6874
19.2k
  case FT_INT32:
6875
19.2k
  case FT_INT40:
6876
19.2k
  case FT_INT48:
6877
19.2k
  case FT_INT56:
6878
19.2k
  case FT_INT64:
6879
19.2k
    if (encoding & ENC_VARINT_MASK) {
6880
1
      if (length < -1) {
6881
0
        report_type_length_mismatch(NULL, "a FT_[U]INT", length, true);
6882
0
      }
6883
1
      if (length == -1) {
6884
1
        uint64_t dummy;
6885
        /* This can throw an exception */
6886
        /* XXX - do this without fetching the varint? */
6887
1
        length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN, &dummy, encoding);
6888
1
        if (length == 0) {
6889
0
          THROW(ReportedBoundsError);
6890
0
        }
6891
1
      }
6892
1
      item_length = length;
6893
1
      break;
6894
1
    }
6895
6896
    /*
6897
     * The length is the specified length.
6898
     */
6899
19.2k
    break;
6900
6901
19.2k
  case FT_BOOLEAN:
6902
533
  case FT_CHAR:
6903
553
  case FT_IPv4:
6904
553
  case FT_IPXNET:
6905
559
  case FT_IPv6:
6906
559
  case FT_FCWWN:
6907
559
  case FT_AX25:
6908
559
  case FT_VINES:
6909
2.63k
  case FT_ETHER:
6910
2.63k
  case FT_EUI64:
6911
2.63k
  case FT_GUID:
6912
2.63k
  case FT_OID:
6913
2.63k
  case FT_REL_OID:
6914
2.63k
  case FT_SYSTEM_ID:
6915
2.63k
  case FT_FLOAT:
6916
2.63k
  case FT_DOUBLE:
6917
2.64k
  case FT_STRING:
6918
    /*
6919
     * The length is the specified length.
6920
     */
6921
2.64k
    break;
6922
6923
1
  case FT_STRINGZ:
6924
1
    if (length < -1) {
6925
0
      report_type_length_mismatch(NULL, "a string", length, true);
6926
0
    }
6927
1
    if (length == -1) {
6928
      /* This can throw an exception */
6929
0
      item_length = tvb_strsize_enc(tvb, start, encoding);
6930
0
    }
6931
1
    break;
6932
6933
39
  case FT_UINT_STRING:
6934
39
    n = get_uint_value(NULL, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK);
6935
39
    item_length += n;
6936
39
    if ((int)item_length < length) {
6937
0
      THROW(ReportedBoundsError);
6938
0
    }
6939
39
    break;
6940
6941
0
  case FT_STRINGZPAD:
6942
0
  case FT_STRINGZTRUNC:
6943
0
  case FT_ABSOLUTE_TIME:
6944
0
  case FT_RELATIVE_TIME:
6945
0
  case FT_IEEE_11073_SFLOAT:
6946
0
  case FT_IEEE_11073_FLOAT:
6947
    /*
6948
     * The length is the specified length.
6949
     */
6950
0
    break;
6951
6952
0
  default:
6953
0
    REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in gset_full_length()",
6954
0
             hfinfo->abbrev,
6955
0
             hfinfo->type,
6956
0
             ftype_name(hfinfo->type));
6957
0
    break;
6958
22.5k
  }
6959
22.5k
  return item_length;
6960
22.5k
}
6961
6962
// This was arbitrarily chosen, but if you're adding 50K items to the tree
6963
// without advancing the offset you should probably take a long, hard look
6964
// at what you're doing.
6965
// We *could* make this a configurable option, but I (Gerald) would like to
6966
// avoid adding yet another nerd knob.
6967
# define PROTO_TREE_MAX_IDLE 50000
6968
static field_info *
6969
new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6970
         const int start, const int item_length)
6971
35.4M
{
6972
35.4M
  field_info *fi;
6973
6974
35.4M
  FIELD_INFO_NEW(PNODE_POOL(tree), fi);
6975
6976
35.4M
  fi->hfinfo     = hfinfo;
6977
35.4M
  fi->start      = start;
6978
35.4M
  fi->start     += (tvb)?tvb_raw_offset(tvb):0;
6979
  /* add the data source tvbuff */
6980
35.4M
  fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL;
6981
6982
  // If our start offset hasn't advanced after adding many items it probably
6983
  // means we're in a large or infinite loop.
6984
35.4M
  if (fi->start > 0) {
6985
27.9M
    if (fi->ds_tvb == PTREE_DATA(tree)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)->max_start) {
6986
20.5M
      PTREE_DATA(tree)->start_idle_count++;
6987
20.5M
      DISSECTOR_ASSERT_HINT(PTREE_DATA(tree)->start_idle_count < PROTO_TREE_MAX_IDLE, fi->hfinfo->abbrev);
6988
20.5M
    } else {
6989
7.37M
      PTREE_DATA(tree)->idle_count_ds_tvb = fi->ds_tvb;
6990
7.37M
      PTREE_DATA(tree)->max_start = fi->start;
6991
7.37M
      PTREE_DATA(tree)->start_idle_count = 0;
6992
7.37M
    }
6993
27.9M
  }
6994
35.4M
  fi->length     = item_length;
6995
35.4M
  fi->tree_type  = -1;
6996
35.4M
  fi->flags      = 0;
6997
35.4M
  if (!PTREE_DATA(tree)->visible) {
6998
    /* If the tree is not visible, set the item hidden, unless we
6999
     * need the representation or length and can't fake them.
7000
     */
7001
0
    if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)->fake_protocols)) {
7002
0
      FI_SET_FLAG(fi, FI_HIDDEN);
7003
0
    }
7004
0
  }
7005
35.4M
  fi->value = fvalue_new(fi->hfinfo->type);
7006
35.4M
  fi->rep        = NULL;
7007
7008
35.4M
  fi->appendix_start  = 0;
7009
35.4M
  fi->appendix_length = 0;
7010
7011
35.4M
  fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7012
35.4M
  fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7013
7014
35.4M
  return fi;
7015
35.4M
}
7016
7017
static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7018
10.2M
{
7019
10.2M
  if (hfinfo->display & BASE_NO_DISPLAY_VALUE) {
7020
155
    return 0;
7021
155
  }
7022
7023
  /* Search for field name */
7024
10.2M
  char *ptr = strstr(representation, hfinfo->name);
7025
10.2M
  if (!ptr) {
7026
3.69M
    return 0;
7027
3.69M
  }
7028
7029
  /* Check if field name ends with the ": " delimiter */
7030
6.60M
  ptr += strlen(hfinfo->name);
7031
6.60M
  if (strncmp(ptr, ": ", 2) == 0) {
7032
4.81M
    ptr += 2;
7033
4.81M
  }
7034
7035
  /* Return offset to after field name */
7036
6.60M
  return ptr - representation;
7037
10.2M
}
7038
7039
static size_t label_find_name_pos(const item_label_t *rep)
7040
6.17k
{
7041
6.17k
  size_t name_pos = 0;
7042
7043
  /* If the value_pos is too small or too large, we can't find the expected format */
7044
6.17k
  if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7045
1.15k
    return 0;
7046
1.15k
  }
7047
7048
  /* Check if the format looks like "label: value", then set name_pos before ':'. */
7049
5.02k
  if (rep->representation[rep->value_pos-2] == ':') {
7050
1.66k
    name_pos = rep->value_pos - 2;
7051
1.66k
  }
7052
7053
5.02k
  return name_pos;
7054
6.17k
}
7055
7056
/* If the protocol tree is to be visible, set the representation of a
7057
   proto_tree entry with the name of the field for the item and with
7058
   the value formatted with the supplied printf-style format and
7059
   argument list. */
7060
static void
7061
proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7062
10.8M
{
7063
10.8M
  ws_assert(pi);
7064
7065
  /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7066
   * items string representation */
7067
10.8M
  if (PTREE_DATA(pi)->visible || !proto_item_is_hidden(pi)) {
7068
2.51M
    size_t            name_pos, ret = 0;
7069
2.51M
    char              *str;
7070
2.51M
    field_info        *fi = PITEM_FINFO(pi);
7071
2.51M
    const header_field_info *hf;
7072
7073
2.51M
    DISSECTOR_ASSERT(fi);
7074
7075
2.51M
    hf = fi->hfinfo;
7076
7077
2.51M
    ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
7078
2.51M
    if (hf->bitmask && (hf->type == FT_BOOLEAN || FT_IS_UINT(hf->type))) {
7079
56.5k
      uint64_t val;
7080
56.5k
      char *p;
7081
7082
56.5k
      if (FT_IS_UINT32(hf->type))
7083
55.9k
        val = fvalue_get_uinteger(fi->value);
7084
561
      else
7085
561
        val = fvalue_get_uinteger64(fi->value);
7086
7087
56.5k
      val <<= hfinfo_bitshift(hf);
7088
7089
56.5k
      p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7090
56.5k
      ret = (p - fi->rep->representation);
7091
56.5k
    }
7092
7093
    /* put in the hf name */
7094
2.51M
    name_pos = ret = label_concat(fi->rep->representation, ret, (const uint8_t*)hf->name);
7095
7096
2.51M
    ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ");
7097
    /* If possible, Put in the value of the string */
7098
2.51M
    str = wmem_strdup_vprintf(PNODE_POOL(pi), format, ap);
7099
2.51M
    WS_UTF_8_CHECK(str, -1);
7100
2.51M
    fi->rep->value_pos = ret;
7101
2.51M
    ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH, ret, (const uint8_t*)str, 0);
7102
2.51M
    if (ret >= ITEM_LABEL_LENGTH) {
7103
      /* Uh oh, we don't have enough room.  Tell the user
7104
       * that the field is truncated.
7105
       */
7106
79
      label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7107
79
    }
7108
2.51M
    fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7109
2.51M
  }
7110
10.8M
}
7111
7112
/* If the protocol tree is to be visible, set the representation of a
7113
   proto_tree entry with the representation formatted with the supplied
7114
   printf-style format and argument list. */
7115
static void
7116
proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7117
10.2M
{
7118
10.2M
  size_t      ret;  /*tmp return value */
7119
10.2M
  char       *str;
7120
10.2M
  field_info *fi = PITEM_FINFO(pi);
7121
7122
10.2M
  DISSECTOR_ASSERT(fi);
7123
7124
10.2M
  if (!proto_item_is_hidden(pi)) {
7125
10.2M
    ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
7126
7127
10.2M
    str = wmem_strdup_vprintf(PNODE_POOL(pi), format, ap);
7128
10.2M
    WS_UTF_8_CHECK(str, -1);
7129
10.2M
    fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7130
10.2M
    ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH, 0, (const uint8_t*)str, 0);
7131
10.2M
    if (ret >= ITEM_LABEL_LENGTH) {
7132
      /* Uh oh, we don't have enough room.  Tell the user that the field is truncated. */
7133
3.28k
      size_t name_pos = label_find_name_pos(fi->rep);
7134
3.28k
      label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7135
3.28k
    }
7136
10.2M
    fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7137
10.2M
  }
7138
10.2M
}
7139
7140
static int
7141
proto_strlcpy(char *dest, const char *src, size_t dest_size)
7142
0
{
7143
0
  if (dest_size == 0) return 0;
7144
7145
0
  size_t res = g_strlcpy(dest, src, dest_size);
7146
7147
  /* At most dest_size - 1 characters will be copied
7148
   * (unless dest_size is 0). */
7149
0
  if (res >= dest_size)
7150
0
    res = dest_size - 1;
7151
0
  return (int) res;
7152
0
}
7153
7154
static header_field_info *
7155
hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7156
0
{
7157
0
  header_field_info *dup_hfinfo;
7158
7159
0
  if (hfinfo->same_name_prev_id == -1)
7160
0
    return NULL;
7161
0
  PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo);
7162
0
  return dup_hfinfo;
7163
0
}
7164
7165
static void
7166
hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7167
0
{
7168
0
  g_free(last_field_name);
7169
0
  last_field_name = NULL;
7170
7171
0
  if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7172
    /* No hfinfo with the same name */
7173
0
    wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7174
0
    return;
7175
0
  }
7176
7177
0
  if (hfinfo->same_name_next) {
7178
0
    hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7179
0
  }
7180
7181
0
  if (hfinfo->same_name_prev_id != -1) {
7182
0
    header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7183
0
    same_name_prev->same_name_next = hfinfo->same_name_next;
7184
0
    if (!hfinfo->same_name_next) {
7185
      /* It's always the latest added hfinfo which is stored in gpa_name_map */
7186
0
      wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7187
0
    }
7188
0
  }
7189
0
}
7190
7191
int
7192
proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7193
0
{
7194
0
  const header_field_info *hfinfo = finfo->hfinfo;
7195
0
  int label_len = 0;
7196
0
  char *tmp_str;
7197
0
  const char *str;
7198
0
  const uint8_t *bytes;
7199
0
  uint32_t number;
7200
0
  uint64_t number64;
7201
0
  const char *hf_str_val;
7202
0
  char number_buf[NUMBER_LABEL_LENGTH];
7203
0
  const char *number_out;
7204
0
  address addr;
7205
0
  const ipv4_addr_and_mask *ipv4;
7206
0
  const ipv6_addr_and_prefix *ipv6;
7207
7208
0
  switch (hfinfo->type) {
7209
7210
0
    case FT_NONE:
7211
0
    case FT_PROTOCOL:
7212
0
      return proto_strlcpy(display_label_str, UTF8_CHECK_MARK, label_str_size);
7213
7214
0
    case FT_UINT_BYTES:
7215
0
    case FT_BYTES:
7216
0
      tmp_str = format_bytes_hfinfo_maxlen(NULL,
7217
0
        hfinfo,
7218
0
        fvalue_get_bytes_data(finfo->value),
7219
0
        (unsigned)fvalue_length2(finfo->value),
7220
0
        label_str_size);
7221
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7222
0
      wmem_free(NULL, tmp_str);
7223
0
      break;
7224
7225
0
    case FT_ABSOLUTE_TIME:
7226
0
    {
7227
0
      const nstime_t *value = fvalue_get_time(finfo->value);
7228
0
      int flags = ABS_TIME_TO_STR_SHOW_ZONE;
7229
0
      if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7230
0
        flags |= ABS_TIME_TO_STR_ISO8601;
7231
0
      }
7232
0
      if (hfinfo->strings) {
7233
0
        const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7234
0
        if (time_string != NULL) {
7235
0
          label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7236
0
          break;
7237
0
        }
7238
0
      }
7239
0
      tmp_str = abs_time_to_str_ex(NULL, value, hfinfo->display, flags);
7240
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7241
0
      wmem_free(NULL, tmp_str);
7242
0
      break;
7243
0
    }
7244
7245
0
    case FT_RELATIVE_TIME:
7246
0
      tmp_str = rel_time_to_secs_str(NULL, fvalue_get_time(finfo->value));
7247
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7248
0
      wmem_free(NULL, tmp_str);
7249
0
      break;
7250
7251
0
    case FT_BOOLEAN:
7252
0
      number64 = fvalue_get_uinteger64(finfo->value);
7253
0
      label_len = proto_strlcpy(display_label_str,
7254
0
          tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7255
0
      break;
7256
7257
0
    case FT_CHAR:
7258
0
      number = fvalue_get_uinteger(finfo->value);
7259
7260
0
      if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
7261
0
        char tmp[ITEM_LABEL_LENGTH];
7262
0
        custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7263
7264
0
        DISSECTOR_ASSERT(fmtfunc);
7265
0
        fmtfunc(tmp, number);
7266
7267
0
        label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7268
7269
0
      } else if (hfinfo->strings) {
7270
0
        number_out = hf_try_val_to_str(number, hfinfo);
7271
7272
0
        if (!number_out) {
7273
0
          number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7274
0
        }
7275
7276
0
        label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7277
7278
0
      } else {
7279
0
        number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7280
7281
0
        label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7282
0
      }
7283
7284
0
      break;
7285
7286
    /* XXX - make these just FT_NUMBER? */
7287
0
    case FT_INT8:
7288
0
    case FT_INT16:
7289
0
    case FT_INT24:
7290
0
    case FT_INT32:
7291
0
    case FT_UINT8:
7292
0
    case FT_UINT16:
7293
0
    case FT_UINT24:
7294
0
    case FT_UINT32:
7295
0
    case FT_FRAMENUM:
7296
0
      hf_str_val = NULL;
7297
0
      number = FT_IS_INT(hfinfo->type) ?
7298
0
        (uint32_t) fvalue_get_sinteger(finfo->value) :
7299
0
        fvalue_get_uinteger(finfo->value);
7300
7301
0
      if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
7302
0
        char tmp[ITEM_LABEL_LENGTH];
7303
0
        custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7304
7305
0
        DISSECTOR_ASSERT(fmtfunc);
7306
0
        fmtfunc(tmp, number);
7307
7308
0
        label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7309
7310
0
      } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7311
0
        if (hfinfo->display & BASE_UNIT_STRING) {
7312
0
          number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7313
0
          label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7314
0
          hf_str_val = hf_try_val_to_str(number, hfinfo);
7315
0
          if (hf_str_val)
7316
0
            label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7317
0
        } else {
7318
0
          number_out = hf_try_val_to_str(number, hfinfo);
7319
7320
0
          if (!number_out) {
7321
0
            number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7322
0
          }
7323
7324
0
          label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7325
0
        }
7326
0
      } else {
7327
0
        number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7328
7329
0
        label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7330
0
      }
7331
7332
0
      break;
7333
7334
0
    case FT_INT40:
7335
0
    case FT_INT48:
7336
0
    case FT_INT56:
7337
0
    case FT_INT64:
7338
0
    case FT_UINT40:
7339
0
    case FT_UINT48:
7340
0
    case FT_UINT56:
7341
0
    case FT_UINT64:
7342
0
      hf_str_val = NULL;
7343
0
      number64 = FT_IS_INT(hfinfo->type) ?
7344
0
        (uint64_t) fvalue_get_sinteger64(finfo->value) :
7345
0
        fvalue_get_uinteger64(finfo->value);
7346
7347
0
      if (FIELD_DISPLAY(hfinfo->display) == BASE_CUSTOM) {
7348
0
        char tmp[ITEM_LABEL_LENGTH];
7349
0
        custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7350
7351
0
        DISSECTOR_ASSERT(fmtfunc64);
7352
0
        fmtfunc64(tmp, number64);
7353
7354
0
        label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7355
0
      } else if (hfinfo->strings) {
7356
0
        if (hfinfo->display & BASE_UNIT_STRING) {
7357
0
          number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7358
0
          label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7359
0
          hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7360
0
          if (hf_str_val)
7361
0
            label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7362
0
        } else {
7363
0
          number_out = hf_try_val64_to_str(number64, hfinfo);
7364
7365
0
          if (!number_out)
7366
0
            number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7367
7368
0
          label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7369
0
        }
7370
0
      } else {
7371
0
        number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7372
7373
0
        label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7374
0
      }
7375
7376
0
      break;
7377
7378
0
    case FT_EUI64:
7379
0
      set_address (&addr, AT_EUI64, EUI64_ADDR_LEN, fvalue_get_bytes_data(finfo->value));
7380
0
      tmp_str = address_to_display(NULL, &addr);
7381
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7382
0
      wmem_free(NULL, tmp_str);
7383
0
      break;
7384
7385
0
    case FT_IPv4:
7386
0
      ipv4 = fvalue_get_ipv4(finfo->value);
7387
      //XXX: Should we ignore the mask?
7388
0
      set_address_ipv4(&addr, ipv4);
7389
0
      tmp_str = address_to_display(NULL, &addr);
7390
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7391
0
      wmem_free(NULL, tmp_str);
7392
0
      free_address(&addr);
7393
0
      break;
7394
7395
0
    case FT_IPv6:
7396
0
      ipv6 = fvalue_get_ipv6(finfo->value);
7397
0
      set_address_ipv6(&addr, ipv6);
7398
0
      tmp_str = address_to_display(NULL, &addr);
7399
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7400
0
      wmem_free(NULL, tmp_str);
7401
0
      free_address(&addr);
7402
0
      break;
7403
7404
0
    case FT_FCWWN:
7405
0
      set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN, fvalue_get_bytes_data(finfo->value));
7406
0
      tmp_str = address_to_display(NULL, &addr);
7407
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7408
0
      wmem_free(NULL, tmp_str);
7409
0
      break;
7410
7411
0
    case FT_ETHER:
7412
0
      set_address (&addr, AT_ETHER, FT_ETHER_LEN, fvalue_get_bytes_data(finfo->value));
7413
0
      tmp_str = address_to_display(NULL, &addr);
7414
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7415
0
      wmem_free(NULL, tmp_str);
7416
0
      break;
7417
7418
0
    case FT_GUID:
7419
0
      tmp_str = guid_to_str(NULL, fvalue_get_guid(finfo->value));
7420
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7421
0
      wmem_free(NULL, tmp_str);
7422
0
      break;
7423
7424
0
    case FT_REL_OID:
7425
0
      bytes = fvalue_get_bytes_data(finfo->value);
7426
0
      tmp_str = rel_oid_resolved_from_encoded(NULL, bytes, (int)fvalue_length2(finfo->value));
7427
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7428
0
      wmem_free(NULL, tmp_str);
7429
0
      break;
7430
7431
0
    case FT_OID:
7432
0
      bytes = fvalue_get_bytes_data(finfo->value);
7433
0
      tmp_str = oid_resolved_from_encoded(NULL, bytes, (int)fvalue_length2(finfo->value));
7434
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7435
0
      wmem_free(NULL, tmp_str);
7436
0
      break;
7437
7438
0
    case FT_SYSTEM_ID:
7439
0
      bytes = fvalue_get_bytes_data(finfo->value);
7440
0
      tmp_str = print_system_id(NULL, bytes, (int)fvalue_length2(finfo->value));
7441
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7442
0
      wmem_free(NULL, tmp_str);
7443
0
      break;
7444
7445
0
    case FT_FLOAT:
7446
0
    case FT_DOUBLE:
7447
0
      label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7448
0
      break;
7449
7450
0
    case FT_IEEE_11073_SFLOAT:
7451
0
    case FT_IEEE_11073_FLOAT:
7452
0
      label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7453
0
      break;
7454
7455
0
    case FT_STRING:
7456
0
    case FT_STRINGZ:
7457
0
    case FT_UINT_STRING:
7458
0
    case FT_STRINGZPAD:
7459
0
    case FT_STRINGZTRUNC:
7460
0
      str = fvalue_get_string(finfo->value);
7461
0
      label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7462
0
      if (label_len >= label_str_size) {
7463
        /* Truncation occurred. Get the real length
7464
         * copied (not including '\0') */
7465
0
        label_len = label_str_size ? label_str_size - 1 : 0;
7466
0
      }
7467
0
      break;
7468
7469
0
    default:
7470
      /* First try ftype string representation */
7471
0
      tmp_str = fvalue_to_string_repr(NULL, finfo->value, FTREPR_DISPLAY, hfinfo->display);
7472
0
      if (!tmp_str) {
7473
        /* Default to show as bytes */
7474
0
        bytes = fvalue_get_bytes_data(finfo->value);
7475
0
        tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value));
7476
0
      }
7477
0
      label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7478
0
      wmem_free(NULL, tmp_str);
7479
0
      break;
7480
0
  }
7481
0
  return label_len;
7482
0
}
7483
7484
const char *
7485
proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool display_details,
7486
     char *result, char *expr, const int size)
7487
0
{
7488
0
  int                 len, prev_len, last, i, offset_r = 0, offset_e = 0;
7489
0
  GPtrArray          *finfos;
7490
0
  field_info         *finfo         = NULL;
7491
0
  header_field_info*  hfinfo;
7492
0
  const char         *abbrev        = NULL;
7493
7494
0
  char *str;
7495
0
  col_custom_t *field_idx;
7496
0
  int field_id;
7497
0
  int ii = 0;
7498
7499
0
  ws_assert(field_ids != NULL);
7500
0
  while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7501
0
    field_id = field_idx->field_id;
7502
0
    if (field_id == 0) {
7503
0
      GPtrArray *fvals = NULL;
7504
0
      bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7505
0
      if (fvals != NULL) {
7506
7507
        // XXX - Handling occurrences is unusual when more
7508
        // than one field is involved, e.g. there's four
7509
        // results for tcp.port + tcp.port. We may really
7510
        // want to apply it to the operands, not the output.
7511
        // Note that occurrences are not quite the same as
7512
        // the layer operator (should the grammar support
7513
        // both?)
7514
        /* Calculate single index or set outer boundaries */
7515
0
        len = g_ptr_array_len(fvals);
7516
0
        if (occurrence < 0) {
7517
0
          i = occurrence + len;
7518
0
          last = i;
7519
0
        } else if (occurrence > 0) {
7520
0
          i = occurrence - 1;
7521
0
          last = i;
7522
0
        } else {
7523
0
          i = 0;
7524
0
          last = len - 1;
7525
0
        }
7526
0
        if (i < 0 || i >= len) {
7527
0
          g_ptr_array_unref(fvals);
7528
0
          continue;
7529
0
        }
7530
0
        for (; i <= last; i++) {
7531
          /* XXX - We could have a "resolved" result
7532
           * for types where the value depends only
7533
           * on the type, e.g. FT_IPv4, and not on
7534
           * hfinfo->strings. Supporting the latter
7535
           * requires knowing which hfinfo matched
7536
           * if there are multiple with the same
7537
           * abbreviation. In any case, we need to
7538
           * know the expected return type of the
7539
           * field expression.
7540
           */
7541
0
          str = fvalue_to_string_repr(NULL, fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7542
0
          if (offset_r && (offset_r < (size - 1)))
7543
0
            result[offset_r++] = ',';
7544
0
          if (offset_e && (offset_e < (size - 1)))
7545
0
            expr[offset_e++] = ',';
7546
0
          offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7547
          // col_{add,append,set}_* calls ws_label_strcpy
7548
0
          offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7549
7550
0
          g_free(str);
7551
0
        }
7552
0
        g_ptr_array_unref(fvals);
7553
0
      } else if (passed) {
7554
        // XXX - Occurrence doesn't make sense for a test
7555
        // output, it should be applied to the operands.
7556
0
        if (offset_r && (offset_r < (size - 1)))
7557
0
          result[offset_r++] = ',';
7558
0
        if (offset_e && (offset_e < (size - 1)))
7559
0
          expr[offset_e++] = ',';
7560
        /* Prevent multiple check marks */
7561
0
        if (strstr(result, UTF8_CHECK_MARK ",") == NULL) {
7562
0
          offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK, size-offset_r);
7563
0
        } else {
7564
0
          result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7565
0
        }
7566
0
        if (strstr(expr, UTF8_CHECK_MARK ",") == NULL) {
7567
0
          offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK, size-offset_e);
7568
0
        } else {
7569
0
          expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7570
0
        }
7571
0
      }
7572
0
      continue;
7573
0
    }
7574
0
    PROTO_REGISTRAR_GET_NTH((unsigned)field_id, hfinfo);
7575
7576
    /* do we need to rewind ? */
7577
0
    if (!hfinfo)
7578
0
      return "";
7579
7580
0
    if (occurrence < 0) {
7581
      /* Search other direction */
7582
0
      while (hfinfo->same_name_prev_id != -1) {
7583
0
        PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
7584
0
      }
7585
0
    }
7586
7587
0
    prev_len = 0; /* Reset handled occurrences */
7588
7589
0
    while (hfinfo) {
7590
0
      finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7591
7592
0
      if (!finfos || !(len = g_ptr_array_len(finfos))) {
7593
0
        if (occurrence < 0) {
7594
0
          hfinfo = hfinfo->same_name_next;
7595
0
        } else {
7596
0
          hfinfo = hfinfo_same_name_get_prev(hfinfo);
7597
0
        }
7598
0
        continue;
7599
0
      }
7600
7601
      /* Are there enough occurrences of the field? */
7602
0
      if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7603
0
        if (occurrence < 0) {
7604
0
          hfinfo = hfinfo->same_name_next;
7605
0
        } else {
7606
0
          hfinfo = hfinfo_same_name_get_prev(hfinfo);
7607
0
        }
7608
0
        prev_len += len;
7609
0
        continue;
7610
0
      }
7611
7612
      /* Calculate single index or set outer boundaries */
7613
0
      if (occurrence < 0) {
7614
0
        i = occurrence + len + prev_len;
7615
0
        last = i;
7616
0
      } else if (occurrence > 0) {
7617
0
        i = occurrence - 1 - prev_len;
7618
0
        last = i;
7619
0
      } else {
7620
0
        i = 0;
7621
0
        last = len - 1;
7622
0
      }
7623
7624
0
      prev_len += len; /* Count handled occurrences */
7625
7626
0
      while (i <= last) {
7627
0
        finfo = (field_info *)g_ptr_array_index(finfos, i);
7628
7629
0
        if (offset_r && (offset_r < (size - 1)))
7630
0
          result[offset_r++] = ',';
7631
7632
0
        if (display_details) {
7633
0
          char representation[ITEM_LABEL_LENGTH];
7634
0
          size_t offset = 0;
7635
7636
0
          if (finfo->rep && finfo->rep->value_len) {
7637
0
            (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7638
0
                MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH));
7639
0
          } else {
7640
0
            proto_item_fill_label(finfo, representation, &offset);
7641
0
          }
7642
0
          offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7643
0
        } else {
7644
0
          switch (hfinfo->type) {
7645
7646
0
          case FT_NONE:
7647
0
          case FT_PROTOCOL:
7648
            /* Prevent multiple check marks */
7649
0
            if (strstr(result, UTF8_CHECK_MARK ",") == NULL) {
7650
0
              offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7651
0
            } else {
7652
0
              result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7653
0
            }
7654
0
            break;
7655
7656
0
          default:
7657
0
            offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7658
0
            break;
7659
0
          }
7660
0
        }
7661
7662
0
        if (offset_e && (offset_e < (size - 1)))
7663
0
          expr[offset_e++] = ',';
7664
7665
0
        if (hfinfo->strings && hfinfo->type != FT_FRAMENUM && FIELD_DISPLAY(hfinfo->display) == BASE_NONE && (FT_IS_INT(hfinfo->type) || FT_IS_UINT(hfinfo->type))) {
7666
0
          const char *hf_str_val;
7667
          /* Integer types with BASE_NONE never get the numeric value. */
7668
0
          if (FT_IS_INT32(hfinfo->type)) {
7669
0
            hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7670
0
          } else if (FT_IS_UINT32(hfinfo->type)) {
7671
0
            hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7672
0
          } else if (FT_IS_INT64(hfinfo->type)) {
7673
0
            hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7674
0
          } else { // if (FT_IS_UINT64(hfinfo->type)) {
7675
0
            hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7676
0
          }
7677
0
          snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7678
0
          offset_e = (int)strlen(expr);
7679
0
        } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7680
          /* Prevent multiple check marks */
7681
0
          if (strstr(expr, UTF8_CHECK_MARK ",") == NULL) {
7682
0
            offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7683
0
          } else {
7684
0
            expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7685
0
          }
7686
0
        } else {
7687
0
          str = fvalue_to_string_repr(NULL, finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7688
          // col_{add,append,set}_* calls ws_label_strcpy
7689
0
          offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7690
0
          wmem_free(NULL, str);
7691
0
        }
7692
0
        i++;
7693
0
      }
7694
7695
      /* XXX: Why is only the first abbreviation returned for a multifield
7696
       * custom column? */
7697
0
      if (!abbrev) {
7698
        /* Store abbrev for return value */
7699
0
        abbrev = hfinfo->abbrev;
7700
0
      }
7701
7702
0
      if (occurrence == 0) {
7703
        /* Fetch next hfinfo with same name (abbrev) */
7704
0
        hfinfo = hfinfo_same_name_get_prev(hfinfo);
7705
0
      } else {
7706
0
        hfinfo = NULL;
7707
0
      }
7708
0
    }
7709
0
  }
7710
7711
0
  if (offset_r >= (size - 1)) {
7712
0
    mark_truncated(result, 0, size, NULL);
7713
0
  }
7714
0
  if (offset_e >= (size - 1)) {
7715
0
    mark_truncated(expr, 0, size, NULL);
7716
0
  }
7717
0
  return abbrev ? abbrev : "";
7718
0
}
7719
7720
char *
7721
proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7722
0
{
7723
0
  int                 len, prev_len, last, i;
7724
0
  GPtrArray          *finfos;
7725
0
  field_info         *finfo         = NULL;
7726
0
  header_field_info*  hfinfo;
7727
7728
0
  char *filter = NULL;
7729
0
  GPtrArray *filter_array;
7730
7731
0
  col_custom_t *col_custom;
7732
0
  int field_id;
7733
7734
0
  ws_assert(field_ids != NULL);
7735
0
  filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7736
0
  for (GSList *iter = field_ids; iter; iter = iter->next) {
7737
0
    col_custom = (col_custom_t*)iter->data;
7738
0
    field_id = col_custom->field_id;
7739
0
    if (field_id == 0) {
7740
0
      GPtrArray *fvals = NULL;
7741
0
      bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7742
0
      if (fvals != NULL) {
7743
        // XXX - Handling occurrences is unusual when more
7744
        // than one field is involved, e.g. there's four
7745
        // results for tcp.port + tcp.port. We really
7746
        // want to apply it to the operands, not the output.
7747
        /* Calculate single index or set outer boundaries */
7748
0
        len = g_ptr_array_len(fvals);
7749
0
        if (occurrence < 0) {
7750
0
          i = occurrence + len;
7751
0
          last = i;
7752
0
        } else if (occurrence > 0) {
7753
0
          i = occurrence - 1;
7754
0
          last = i;
7755
0
        } else {
7756
0
          i = 0;
7757
0
          last = len - 1;
7758
0
        }
7759
0
        if (i < 0 || i >= len) {
7760
0
          g_ptr_array_unref(fvals);
7761
0
          continue;
7762
0
        }
7763
0
        for (; i <= last; i++) {
7764
          /* XXX - Should multiple values for one
7765
           * field use set membership to reduce
7766
           * verbosity, here and below? */
7767
0
          char *str = fvalue_to_string_repr(NULL, fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7768
0
          filter = wmem_strdup_printf(NULL, "%s == %s", col_custom->dftext, str);
7769
0
          wmem_free(NULL, str);
7770
0
          if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL)) {
7771
0
            g_ptr_array_add(filter_array, filter);
7772
0
          }
7773
0
        }
7774
0
        g_ptr_array_unref(fvals);
7775
0
      } else if (passed) {
7776
0
        filter = wmem_strdup(NULL, col_custom->dftext);
7777
0
        if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL)) {
7778
0
          g_ptr_array_add(filter_array, filter);
7779
0
        }
7780
0
      } else {
7781
0
        filter = wmem_strdup_printf(NULL, "!(%s)", col_custom->dftext);
7782
0
        if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL)) {
7783
0
          g_ptr_array_add(filter_array, filter);
7784
0
        }
7785
0
      }
7786
0
      continue;
7787
0
    }
7788
7789
0
    PROTO_REGISTRAR_GET_NTH((unsigned)field_id, hfinfo);
7790
7791
    /* do we need to rewind ? */
7792
0
    if (!hfinfo)
7793
0
      return NULL;
7794
7795
0
    if (occurrence < 0) {
7796
      /* Search other direction */
7797
0
      while (hfinfo->same_name_prev_id != -1) {
7798
0
        PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, hfinfo);
7799
0
      }
7800
0
    }
7801
7802
0
    prev_len = 0; /* Reset handled occurrences */
7803
7804
0
    while (hfinfo) {
7805
0
      finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7806
7807
0
      if (!finfos || !(len = g_ptr_array_len(finfos))) {
7808
0
        if (occurrence < 0) {
7809
0
          hfinfo = hfinfo->same_name_next;
7810
0
        } else {
7811
0
          hfinfo = hfinfo_same_name_get_prev(hfinfo);
7812
0
        }
7813
0
        continue;
7814
0
      }
7815
7816
      /* Are there enough occurrences of the field? */
7817
0
      if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7818
0
        if (occurrence < 0) {
7819
0
          hfinfo = hfinfo->same_name_next;
7820
0
        } else {
7821
0
          hfinfo = hfinfo_same_name_get_prev(hfinfo);
7822
0
        }
7823
0
        prev_len += len;
7824
0
        continue;
7825
0
      }
7826
7827
      /* Calculate single index or set outer boundaries */
7828
0
      if (occurrence < 0) {
7829
0
        i = occurrence + len + prev_len;
7830
0
        last = i;
7831
0
      } else if (occurrence > 0) {
7832
0
        i = occurrence - 1 - prev_len;
7833
0
        last = i;
7834
0
      } else {
7835
0
        i = 0;
7836
0
        last = len - 1;
7837
0
      }
7838
7839
0
      prev_len += len; /* Count handled occurrences */
7840
7841
0
      while (i <= last) {
7842
0
        finfo = (field_info *)g_ptr_array_index(finfos, i);
7843
7844
0
        filter = proto_construct_match_selected_string(finfo, edt);
7845
0
        if (filter) {
7846
          /* Only add the same expression once (especially for FT_PROTOCOL).
7847
           * The ptr array doesn't have NULL entries so g_str_equal is fine.
7848
           */
7849
0
          if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL)) {
7850
0
            g_ptr_array_add(filter_array, filter);
7851
0
          }
7852
0
        }
7853
0
        i++;
7854
0
      }
7855
7856
0
      if (occurrence == 0) {
7857
        /* Fetch next hfinfo with same name (abbrev) */
7858
0
        hfinfo = hfinfo_same_name_get_prev(hfinfo);
7859
0
      } else {
7860
0
        hfinfo = NULL;
7861
0
      }
7862
0
    }
7863
0
  }
7864
7865
0
  g_ptr_array_add(filter_array, NULL);
7866
7867
  /* XXX: Should this be || or && ? */
7868
0
  char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7869
7870
0
  g_ptr_array_free(filter_array, true);
7871
7872
0
  return output;
7873
0
}
7874
7875
/* Set text of proto_item after having already been created. */
7876
void
7877
proto_item_set_text(proto_item *pi, const char *format, ...)
7878
914k
{
7879
914k
  field_info *fi = NULL;
7880
914k
  va_list     ap;
7881
7882
914k
  TRY_TO_FAKE_THIS_REPR_VOID(pi);
7883
7884
852k
  fi = PITEM_FINFO(pi);
7885
852k
  if (fi == NULL)
7886
0
    return;
7887
7888
852k
  if (fi->rep) {
7889
12.5k
    ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep);
7890
12.5k
    fi->rep = NULL;
7891
12.5k
  }
7892
7893
852k
  va_start(ap, format);
7894
852k
  proto_tree_set_representation(pi, format, ap);
7895
852k
  va_end(ap);
7896
852k
}
7897
7898
/* Append to text of proto_item after having already been created. */
7899
void
7900
proto_item_append_text(proto_item *pi, const char *format, ...)
7901
10.6M
{
7902
10.6M
  field_info *fi = NULL;
7903
10.6M
  size_t      curlen;
7904
10.6M
  char       *str;
7905
10.6M
  va_list     ap;
7906
7907
10.6M
  TRY_TO_FAKE_THIS_REPR_VOID(pi);
7908
7909
6.56M
  fi = PITEM_FINFO(pi);
7910
6.56M
  if (fi == NULL) {
7911
0
    return;
7912
0
  }
7913
7914
6.56M
  if (!proto_item_is_hidden(pi)) {
7915
    /*
7916
     * If we don't already have a representation,
7917
     * generate the default representation.
7918
     */
7919
6.56M
    if (fi->rep == NULL) {
7920
1.48M
      ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
7921
1.48M
      proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7922
      /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7923
1.48M
      if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7924
629k
          (strncmp(format, ": ", 2) == 0)) {
7925
220k
        fi->rep->value_pos += 2;
7926
220k
      }
7927
1.48M
    }
7928
6.56M
    if (fi->rep) {
7929
6.56M
      curlen = strlen(fi->rep->representation);
7930
      /* curlen doesn't include the \0 byte.
7931
       * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7932
       * the representation has already been truncated (of an up
7933
       * to 4 byte UTF-8 character) or is just at the maximum length
7934
       * unless we search for " [truncated]" (which may not be
7935
       * at the start.)
7936
       * It's safer to do nothing.
7937
       */
7938
6.56M
      if (ITEM_LABEL_LENGTH > (curlen + 4)) {
7939
6.42M
        va_start(ap, format);
7940
6.42M
        str = wmem_strdup_vprintf(PNODE_POOL(pi), format, ap);
7941
6.42M
        va_end(ap);
7942
6.42M
        WS_UTF_8_CHECK(str, -1);
7943
        /* Keep fi->rep->value_pos */
7944
6.42M
        curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH, curlen, (const uint8_t*)str, 0);
7945
6.42M
        if (curlen >= ITEM_LABEL_LENGTH) {
7946
          /* Uh oh, we don't have enough room.  Tell the user that the field is truncated. */
7947
2.88k
          size_t name_pos = label_find_name_pos(fi->rep);
7948
2.88k
          label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7949
2.88k
        }
7950
6.42M
        fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7951
6.42M
      }
7952
6.56M
    }
7953
6.56M
  }
7954
6.56M
}
7955
7956
/* Prepend to text of proto_item after having already been created. */
7957
void
7958
proto_item_prepend_text(proto_item *pi, const char *format, ...)
7959
293k
{
7960
293k
  field_info *fi = NULL;
7961
293k
  size_t      pos;
7962
293k
  char        representation[ITEM_LABEL_LENGTH];
7963
293k
  char       *str;
7964
293k
  va_list     ap;
7965
7966
293k
  TRY_TO_FAKE_THIS_REPR_VOID(pi);
7967
7968
81.8k
  fi = PITEM_FINFO(pi);
7969
81.8k
  if (fi == NULL) {
7970
0
    return;
7971
0
  }
7972
7973
81.8k
  if (!proto_item_is_hidden(pi)) {
7974
    /*
7975
     * If we don't already have a representation,
7976
     * generate the default representation.
7977
     */
7978
81.8k
    if (fi->rep == NULL) {
7979
27.7k
      ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep);
7980
27.7k
      proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7981
27.7k
    } else
7982
54.1k
      (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH);
7983
7984
81.8k
    va_start(ap, format);
7985
81.8k
    str = wmem_strdup_vprintf(PNODE_POOL(pi), format, ap);
7986
81.8k
    va_end(ap);
7987
81.8k
    WS_UTF_8_CHECK(str, -1);
7988
81.8k
    fi->rep->value_pos += strlen(str);
7989
81.8k
    pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH, 0, (const uint8_t*)str, 0);
7990
81.8k
    pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH, pos, (const uint8_t*)representation, 0);
7991
    /* XXX: As above, if the old representation is close to the label
7992
     * length, it might already be marked as truncated. */
7993
81.8k
    if (pos >= ITEM_LABEL_LENGTH && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH) {
7994
      /* Uh oh, we don't have enough room.  Tell the user that the field is truncated. */
7995
0
      size_t name_pos = label_find_name_pos(fi->rep);
7996
0
      label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7997
0
    }
7998
81.8k
    fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7999
81.8k
  }
8000
81.8k
}
8001
8002
static void
8003
finfo_set_len(field_info *fi, const int length)
8004
4.49M
{
8005
4.49M
  int length_remaining;
8006
8007
4.49M
  DISSECTOR_ASSERT_HINT(length >= 0, fi->hfinfo->abbrev);
8008
4.49M
  length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
8009
4.49M
  if (length > length_remaining)
8010
34.0k
    fi->length = length_remaining;
8011
4.46M
  else
8012
4.46M
    fi->length = length;
8013
8014
  /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8015
4.49M
  if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8016
123k
    fvalue_set_protocol_length(fi->value, fi->length);
8017
123k
  }
8018
8019
  /*
8020
   * You cannot just make the "len" field of a GByteArray
8021
   * larger, if there's no data to back that length;
8022
   * you can only make it smaller.
8023
   */
8024
4.49M
  if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8025
3.90k
    GBytes *bytes = fvalue_get_bytes(fi->value);
8026
3.90k
    size_t size;
8027
3.90k
    const void *data = g_bytes_get_data(bytes, &size);
8028
3.90k
    if ((size_t)fi->length <= size) {
8029
3.67k
      fvalue_set_bytes_data(fi->value, data, fi->length);
8030
3.67k
    }
8031
3.90k
    g_bytes_unref(bytes);
8032
3.90k
  }
8033
4.49M
}
8034
8035
void
8036
proto_item_set_len(proto_item *pi, const int length)
8037
4.63M
{
8038
4.63M
  field_info *fi;
8039
8040
4.63M
  if (pi == NULL)
8041
101k
    return;
8042
8043
4.53M
  fi = PITEM_FINFO(pi);
8044
4.53M
  if (fi == NULL)
8045
239k
    return;
8046
8047
4.29M
  finfo_set_len(fi, length);
8048
4.29M
}
8049
8050
/*
8051
 * Sets the length of the item based on its start and on the specified
8052
 * offset, which is the offset past the end of the item; as the start
8053
 * in the item is relative to the beginning of the data source tvbuff,
8054
 * we need to pass in a tvbuff - the end offset is relative to the beginning
8055
 * of that tvbuff.
8056
 */
8057
void
8058
proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8059
203k
{
8060
203k
  field_info *fi;
8061
203k
  int length;
8062
8063
203k
  if (pi == NULL)
8064
2.81k
    return;
8065
8066
201k
  fi = PITEM_FINFO(pi);
8067
201k
  if (fi == NULL)
8068
1.61k
    return;
8069
8070
199k
  end += tvb_raw_offset(tvb);
8071
199k
  DISSECTOR_ASSERT(end >= fi->start);
8072
199k
  length = end - fi->start;
8073
8074
199k
  finfo_set_len(fi, length);
8075
199k
}
8076
8077
int
8078
proto_item_get_len(const proto_item *pi)
8079
3.83k
{
8080
3.83k
  field_info *fi;
8081
8082
3.83k
  if (!pi)
8083
0
    return -1;
8084
3.83k
  fi = PITEM_FINFO(pi);
8085
3.83k
  if (fi) {
8086
3.79k
    return fi->length;
8087
3.79k
  }
8088
35
  return -1;
8089
3.83k
}
8090
8091
void
8092
0
proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8093
0
  if (!ti) {
8094
0
    return;
8095
0
  }
8096
0
  FI_SET_FLAG(PNODE_FINFO(ti), FI_BITS_OFFSET(bits_offset));
8097
0
  FI_SET_FLAG(PNODE_FINFO(ti), FI_BITS_SIZE(bits_len));
8098
0
}
8099
8100
char *
8101
proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8102
18
{
8103
18
  field_info *fi;
8104
8105
18
  if (!pi)
8106
0
    return wmem_strdup(scope, "");
8107
18
  fi = PITEM_FINFO(pi);
8108
18
  if (!fi)
8109
0
    return wmem_strdup(scope, "");
8110
18
  DISSECTOR_ASSERT(fi->hfinfo != NULL);
8111
18
  return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8112
18
}
8113
8114
proto_tree *
8115
proto_tree_create_root(packet_info *pinfo)
8116
15
{
8117
15
  proto_node *pnode;
8118
8119
  /* Initialize the proto_node */
8120
15
  pnode = g_slice_new(proto_tree);
8121
15
  PROTO_NODE_INIT(pnode);
8122
15
  pnode->parent = NULL;
8123
15
  PNODE_FINFO(pnode) = NULL;
8124
15
  pnode->tree_data = g_slice_new(tree_data_t);
8125
8126
  /* Make sure we can access pinfo everywhere */
8127
15
  pnode->tree_data->pinfo = pinfo;
8128
8129
  /* Don't initialize the tree_data_t. Wait until we know we need it */
8130
15
  pnode->tree_data->interesting_hfids = NULL;
8131
8132
  /* Set the default to false so it's easier to
8133
   * find errors; if we expect to see the protocol tree
8134
   * but for some reason the default 'visible' is not
8135
   * changed, then we'll find out very quickly. */
8136
15
  pnode->tree_data->visible = false;
8137
8138
  /* Make sure that we fake protocols (if possible) */
8139
15
  pnode->tree_data->fake_protocols = true;
8140
8141
  /* Keep track of the number of children */
8142
15
  pnode->tree_data->count = 0;
8143
8144
  /* Initialize our loop checks */
8145
15
  pnode->tree_data->idle_count_ds_tvb = NULL;
8146
15
  pnode->tree_data->max_start = 0;
8147
15
  pnode->tree_data->start_idle_count = 0;
8148
8149
15
  return (proto_tree *)pnode;
8150
15
}
8151
8152
8153
/* "prime" a proto_tree with a single hfid that a dfilter
8154
 * is interested in. */
8155
void
8156
proto_tree_prime_with_hfid(proto_tree *tree _U_, const int hfid)
8157
371
{
8158
371
  header_field_info *hfinfo;
8159
8160
371
  PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
8161
  /* this field is referenced by a filter so increase the refcount.
8162
     also increase the refcount for the parent, i.e the protocol.
8163
     Don't increase the refcount if we're already printing the
8164
     type, as that is a superset of direct reference.
8165
  */
8166
371
  if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8167
371
    hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8168
371
  }
8169
  /* only increase the refcount if there is a parent.
8170
     if this is a protocol and not a field then parent will be -1
8171
     and there is no parent to add any refcounting for.
8172
  */
8173
371
  if (hfinfo->parent != -1) {
8174
371
    header_field_info *parent_hfinfo;
8175
371
    PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
8176
8177
    /* Mark parent as indirectly referenced unless it is already directly
8178
     * referenced, i.e. the user has specified the parent in a filter.
8179
     */
8180
371
    if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8181
9
      parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8182
371
  }
8183
371
}
8184
8185
/* "prime" a proto_tree with a single hfid that a dfilter
8186
 * is interested in. */
8187
void
8188
proto_tree_prime_with_hfid_print(proto_tree *tree _U_, const int hfid)
8189
0
{
8190
0
  header_field_info *hfinfo;
8191
8192
0
  PROTO_REGISTRAR_GET_NTH(hfid, hfinfo);
8193
  /* this field is referenced by an (output) filter so increase the refcount.
8194
     also increase the refcount for the parent, i.e the protocol.
8195
  */
8196
0
  hfinfo->ref_type = HF_REF_TYPE_PRINT;
8197
  /* only increase the refcount if there is a parent.
8198
     if this is a protocol and not a field then parent will be -1
8199
     and there is no parent to add any refcounting for.
8200
  */
8201
0
  if (hfinfo->parent != -1) {
8202
0
    header_field_info *parent_hfinfo;
8203
0
    PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
8204
8205
    /* Mark parent as indirectly referenced unless it is already directly
8206
     * referenced, i.e. the user has specified the parent in a filter.
8207
     */
8208
0
    if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8209
0
      parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8210
0
  }
8211
0
}
8212
8213
proto_tree *
8214
24.7M
proto_item_add_subtree(proto_item *pi,  const int idx) {
8215
24.7M
  field_info *fi;
8216
8217
24.7M
  if (!pi)
8218
845k
    return NULL;
8219
8220
24.7M
  DISSECTOR_ASSERT(idx >= 0 && idx < num_tree_types);
8221
8222
23.9M
  fi = PITEM_FINFO(pi);
8223
23.9M
  if (!fi)
8224
14.3M
    return (proto_tree *)pi;
8225
8226
9.56M
  fi->tree_type = idx;
8227
8228
9.56M
  return (proto_tree *)pi;
8229
23.9M
}
8230
8231
proto_tree *
8232
4.73k
proto_item_get_subtree(proto_item *pi) {
8233
4.73k
  field_info *fi;
8234
8235
4.73k
  if (!pi)
8236
0
    return NULL;
8237
4.73k
  fi = PITEM_FINFO(pi);
8238
4.73k
  if ( (fi) && (fi->tree_type == -1) )
8239
0
    return NULL;
8240
4.73k
  return (proto_tree *)pi;
8241
4.73k
}
8242
8243
proto_item *
8244
5.26M
proto_item_get_parent(const proto_item *ti) {
8245
5.26M
  if (!ti)
8246
0
    return NULL;
8247
5.26M
  return ti->parent;
8248
5.26M
}
8249
8250
proto_item *
8251
74.4k
proto_item_get_parent_nth(proto_item *ti, int gen) {
8252
74.4k
  if (!ti)
8253
0
    return NULL;
8254
223k
  while (gen--) {
8255
148k
    ti = ti->parent;
8256
148k
    if (!ti)
8257
0
      return NULL;
8258
148k
  }
8259
74.4k
  return ti;
8260
74.4k
}
8261
8262
8263
proto_item *
8264
156k
proto_tree_get_parent(proto_tree *tree) {
8265
156k
  if (!tree)
8266
0
    return NULL;
8267
156k
  return (proto_item *)tree;
8268
156k
}
8269
8270
proto_tree *
8271
52.4k
proto_tree_get_parent_tree(proto_tree *tree) {
8272
52.4k
  if (!tree)
8273
0
    return NULL;
8274
8275
  /* we're the root tree, there's no parent
8276
     return ourselves so the caller has at least a tree to attach to */
8277
52.4k
  if (!tree->parent)
8278
5
    return tree;
8279
8280
52.4k
  return (proto_tree *)tree->parent;
8281
52.4k
}
8282
8283
proto_tree *
8284
7.01k
proto_tree_get_root(proto_tree *tree) {
8285
7.01k
  if (!tree)
8286
0
    return NULL;
8287
14.8k
  while (tree->parent) {
8288
7.83k
    tree = tree->parent;
8289
7.83k
  }
8290
7.01k
  return tree;
8291
7.01k
}
8292
8293
void
8294
proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8295
         proto_item *item_to_move)
8296
24.5k
{
8297
  /* This function doesn't generate any values. It only reorganizes the protocol tree
8298
   * so we can bail out immediately if it isn't visible. */
8299
24.5k
  if (!tree || !PTREE_DATA(tree)->visible)
8300
11.2k
    return;
8301
8302
24.5k
  DISSECTOR_ASSERT(item_to_move->parent == tree);
8303
13.2k
  DISSECTOR_ASSERT(fixed_item->parent == tree);
8304
8305
  /*** cut item_to_move out ***/
8306
8307
  /* is item_to_move the first? */
8308
13.2k
  if (tree->first_child == item_to_move) {
8309
    /* simply change first child to next */
8310
0
    tree->first_child = item_to_move->next;
8311
8312
0
    DISSECTOR_ASSERT(tree->last_child != item_to_move);
8313
13.2k
  } else {
8314
13.2k
    proto_item *curr_item;
8315
    /* find previous and change it's next */
8316
93.1k
    for (curr_item = tree->first_child; curr_item != NULL; curr_item = curr_item->next) {
8317
93.1k
      if (curr_item->next == item_to_move) {
8318
13.2k
        break;
8319
13.2k
      }
8320
93.1k
    }
8321
8322
13.2k
    DISSECTOR_ASSERT(curr_item);
8323
8324
13.2k
    curr_item->next = item_to_move->next;
8325
8326
    /* fix last_child if required */
8327
13.2k
    if (tree->last_child == item_to_move) {
8328
13.2k
      tree->last_child = curr_item;
8329
13.2k
    }
8330
13.2k
  }
8331
8332
  /*** insert to_move after fixed ***/
8333
13.2k
  item_to_move->next = fixed_item->next;
8334
13.2k
  fixed_item->next = item_to_move;
8335
13.2k
  if (tree->last_child == fixed_item) {
8336
12
    tree->last_child = item_to_move;
8337
12
  }
8338
13.2k
}
8339
8340
void
8341
proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8342
      const int length)
8343
11.5k
{
8344
11.5k
  field_info *fi;
8345
8346
11.5k
  if (tree == NULL)
8347
733
    return;
8348
8349
10.7k
  fi = PTREE_FINFO(tree);
8350
10.7k
  if (fi == NULL)
8351
330
    return;
8352
8353
10.4k
  start += tvb_raw_offset(tvb);
8354
10.4k
  DISSECTOR_ASSERT(start >= 0);
8355
10.4k
  DISSECTOR_ASSERT(length >= 0);
8356
8357
10.4k
  fi->appendix_start = start;
8358
10.4k
  fi->appendix_length = length;
8359
10.4k
}
8360
8361
static void
8362
check_protocol_filter_name_or_fail(const char *filter_name)
8363
46.3k
{
8364
  /* Require at least two characters. */
8365
46.3k
  if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8366
0
    REPORT_DISSECTOR_BUG("Protocol filter name \"%s\" cannot have length less than two.", filter_name);
8367
0
  }
8368
8369
46.3k
  if (proto_check_field_name(filter_name) != '\0') {
8370
0
    REPORT_DISSECTOR_BUG("Protocol filter name \"%s\" has one or more invalid characters."
8371
0
      " Allowed are letters, digits, '-', '_' and non-repeating '.'."
8372
0
      " This might be caused by an inappropriate plugin or a development error.", filter_name);
8373
0
  }
8374
8375
  /* Check that it doesn't match some very common numeric forms. */
8376
46.3k
  if (filter_name[0] == '0' &&
8377
0
        (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8378
0
        filter_name[1] == 'b' || filter_name[1] == 'B')) {
8379
0
    REPORT_DISSECTOR_BUG("Protocol filter name \"%s\" cannot start with \"%c%c\".",
8380
0
            filter_name, filter_name[0], filter_name[1]);
8381
0
  }
8382
8383
  /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8384
8385
  /* Check that it contains at least one letter. */
8386
46.3k
  bool have_letter = false;
8387
46.6k
  for (const char *s = filter_name; *s != '\0'; s++) {
8388
46.6k
    if (g_ascii_isalpha(*s)) {
8389
46.3k
      have_letter = true;
8390
46.3k
      break;
8391
46.3k
    }
8392
46.6k
  }
8393
46.3k
  if (!have_letter) {
8394
0
    REPORT_DISSECTOR_BUG("Protocol filter name \"%s\" must contain at least one letter a-z.",
8395
0
            filter_name);
8396
0
  }
8397
8398
  /* Check for reserved keywords. */
8399
46.3k
  if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8400
0
    REPORT_DISSECTOR_BUG("Protocol filter name \"%s\" is invalid because it is a reserved keyword."
8401
0
      " This might be caused by an inappropriate plugin or a development error.", filter_name);
8402
0
  }
8403
46.3k
}
8404
8405
int
8406
proto_register_protocol(const char *name, const char *short_name,
8407
      const char *filter_name)
8408
31.6k
{
8409
31.6k
  protocol_t *protocol;
8410
31.6k
  header_field_info *hfinfo;
8411
8412
31.6k
  check_protocol_filter_name_or_fail(filter_name);
8413
8414
  /*
8415
   * Add this protocol to the list of known protocols;
8416
   * the list is sorted by protocol short name.
8417
   */
8418
31.6k
  protocol = g_new(protocol_t, 1);
8419
31.6k
  protocol->name = name;
8420
31.6k
  protocol->short_name = short_name;
8421
31.6k
  protocol->filter_name = filter_name;
8422
31.6k
  protocol->fields = NULL; /* Delegate until actually needed */
8423
31.6k
  protocol->is_enabled = true; /* protocol is enabled by default */
8424
31.6k
  protocol->enabled_by_default = true; /* see previous comment */
8425
31.6k
  protocol->can_toggle = true;
8426
31.6k
  protocol->parent_proto_id = -1;
8427
31.6k
  protocol->heur_list = NULL;
8428
8429
  /* List will be sorted later by name, when all protocols completed registering */
8430
31.6k
  protocols = g_list_prepend(protocols, protocol);
8431
  /*
8432
   * Make sure there's not already a protocol with any of those
8433
   * names.  Crash if there is, as that's an error in the code
8434
   * or an inappropriate plugin.
8435
   * This situation has to be fixed to not register more than one
8436
   * protocol with the same name.
8437
   */
8438
31.6k
  if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8439
    /* ws_error will terminate the program */
8440
0
    REPORT_DISSECTOR_BUG("Duplicate protocol name \"%s\"!"
8441
0
      " This might be caused by an inappropriate plugin or a development error.", name);
8442
0
  }
8443
31.6k
  if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8444
0
    REPORT_DISSECTOR_BUG("Duplicate protocol filter_name \"%s\"!"
8445
0
      " This might be caused by an inappropriate plugin or a development error.", filter_name);
8446
0
  }
8447
31.6k
  if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8448
0
    REPORT_DISSECTOR_BUG("Duplicate protocol short_name \"%s\"!"
8449
0
      " This might be caused by an inappropriate plugin or a development error.", short_name);
8450
0
  }
8451
8452
  /* Here we allocate a new header_field_info struct */
8453
31.6k
  hfinfo = g_slice_new(header_field_info);
8454
31.6k
  hfinfo->name = name;
8455
31.6k
  hfinfo->abbrev = filter_name;
8456
31.6k
  hfinfo->type = FT_PROTOCOL;
8457
31.6k
  hfinfo->display = BASE_NONE;
8458
31.6k
  hfinfo->strings = protocol;
8459
31.6k
  hfinfo->bitmask = 0;
8460
31.6k
  hfinfo->ref_type = HF_REF_TYPE_NONE;
8461
31.6k
  hfinfo->blurb = NULL;
8462
31.6k
  hfinfo->parent = -1; /* This field differentiates protos and fields */
8463
8464
31.6k
  protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8465
31.6k
  return protocol->proto_id;
8466
31.6k
}
8467
8468
int
8469
proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8470
14.7k
{
8471
14.7k
  protocol_t *protocol;
8472
14.7k
  header_field_info *hfinfo;
8473
8474
  /*
8475
   * Helper protocols don't need the strict rules as a "regular" protocol
8476
   * Just register it in a list and make a hf_ field from it
8477
   */
8478
14.7k
  if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8479
0
    REPORT_DISSECTOR_BUG("Pino \"%s\" must be of type FT_PROTOCOL or FT_BYTES.", name);
8480
0
  }
8481
8482
14.7k
  if (parent_proto <= 0) {
8483
0
    REPORT_DISSECTOR_BUG("Must have a valid parent protocol for helper protocol \"%s\"!"
8484
0
      " This might be caused by an inappropriate plugin or a development error.", name);
8485
0
  }
8486
8487
14.7k
  check_protocol_filter_name_or_fail(filter_name);
8488
8489
  /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8490
14.7k
  protocol = g_new(protocol_t, 1);
8491
14.7k
  protocol->name = name;
8492
14.7k
  protocol->short_name = short_name;
8493
14.7k
  protocol->filter_name = filter_name;
8494
14.7k
  protocol->fields = NULL; /* Delegate until actually needed */
8495
8496
  /* Enabling and toggling is really determined by parent protocol,
8497
     but provide default values here */
8498
14.7k
  protocol->is_enabled = true;
8499
14.7k
  protocol->enabled_by_default = true;
8500
14.7k
  protocol->can_toggle = true;
8501
8502
14.7k
  protocol->parent_proto_id = parent_proto;
8503
14.7k
  protocol->heur_list = NULL;
8504
8505
  /* List will be sorted later by name, when all protocols completed registering */
8506
14.7k
  protocols = g_list_prepend(protocols, protocol);
8507
8508
  /* Here we allocate a new header_field_info struct */
8509
14.7k
  hfinfo = g_slice_new(header_field_info);
8510
14.7k
  hfinfo->name = name;
8511
14.7k
  hfinfo->abbrev = filter_name;
8512
14.7k
  hfinfo->type = field_type;
8513
14.7k
  hfinfo->display = BASE_NONE;
8514
14.7k
  if (field_type == FT_BYTES) {
8515
13.7k
    hfinfo->display |= (BASE_NO_DISPLAY_VALUE|BASE_PROTOCOL_INFO);
8516
13.7k
  }
8517
14.7k
  hfinfo->strings = protocol;
8518
14.7k
  hfinfo->bitmask = 0;
8519
14.7k
  hfinfo->ref_type = HF_REF_TYPE_NONE;
8520
14.7k
  hfinfo->blurb = NULL;
8521
14.7k
  hfinfo->parent = -1; /* This field differentiates protos and fields */
8522
8523
14.7k
  protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8524
14.7k
  return protocol->proto_id;
8525
14.7k
}
8526
8527
bool
8528
proto_deregister_protocol(const char *short_name)
8529
0
{
8530
0
  protocol_t *protocol;
8531
0
  header_field_info *hfinfo;
8532
0
  int proto_id;
8533
0
  unsigned i;
8534
8535
0
  proto_id = proto_get_id_by_short_name(short_name);
8536
0
  protocol = find_protocol_by_id(proto_id);
8537
0
  if (protocol == NULL)
8538
0
    return false;
8539
8540
0
  g_hash_table_remove(proto_names, protocol->name);
8541
0
  g_hash_table_remove(proto_short_names, (void *)short_name);
8542
0
  g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8543
8544
0
  if (protocol->fields) {
8545
0
    for (i = 0; i < protocol->fields->len; i++) {
8546
0
      hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i);
8547
0
      hfinfo_remove_from_gpa_name_map(hfinfo);
8548
0
      expert_deregister_expertinfo(hfinfo->abbrev);
8549
0
      g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8550
0
    }
8551
0
    g_ptr_array_free(protocol->fields, true);
8552
0
    protocol->fields = NULL;
8553
0
  }
8554
8555
0
  g_list_free(protocol->heur_list);
8556
8557
  /* Remove this protocol from the list of known protocols */
8558
0
  protocols = g_list_remove(protocols, protocol);
8559
8560
0
  g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8561
0
  wmem_map_remove(gpa_name_map, protocol->filter_name);
8562
8563
0
  g_free(last_field_name);
8564
0
  last_field_name = NULL;
8565
8566
0
  return true;
8567
0
}
8568
8569
void
8570
proto_register_alias(const int proto_id, const char *alias_name)
8571
165
{
8572
165
  protocol_t *protocol;
8573
8574
165
  protocol = find_protocol_by_id(proto_id);
8575
165
  if (alias_name && protocol) {
8576
165
    g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8577
165
  }
8578
165
}
8579
8580
/*
8581
 * Routines to use to iterate over the protocols.
8582
 * The argument passed to the iterator routines is an opaque cookie to
8583
 * their callers; it's the GList pointer for the current element in
8584
 * the list.
8585
 * The ID of the protocol is returned, or -1 if there is no protocol.
8586
 */
8587
int
8588
proto_get_first_protocol(void **cookie)
8589
0
{
8590
0
  protocol_t *protocol;
8591
8592
0
  if (protocols == NULL)
8593
0
    return -1;
8594
0
  *cookie = protocols;
8595
0
  protocol = (protocol_t *)protocols->data;
8596
0
  return protocol->proto_id;
8597
0
}
8598
8599
int
8600
proto_get_data_protocol(void *cookie)
8601
0
{
8602
0
  GList *list_item = (GList *)cookie;
8603
8604
0
  protocol_t *protocol = (protocol_t *)list_item->data;
8605
0
  return protocol->proto_id;
8606
0
}
8607
8608
int
8609
proto_get_next_protocol(void **cookie)
8610
0
{
8611
0
  GList      *list_item = (GList *)*cookie;
8612
0
  protocol_t *protocol;
8613
8614
0
  list_item = g_list_next(list_item);
8615
0
  if (list_item == NULL)
8616
0
    return -1;
8617
0
  *cookie = list_item;
8618
0
  protocol = (protocol_t *)list_item->data;
8619
0
  return protocol->proto_id;
8620
0
}
8621
8622
header_field_info *
8623
proto_get_first_protocol_field(const int proto_id, void **cookie)
8624
0
{
8625
0
  protocol_t *protocol = find_protocol_by_id(proto_id);
8626
8627
0
  if ((protocol == NULL) || (protocol->fields == NULL) || (protocol->fields->len == 0))
8628
0
    return NULL;
8629
8630
0
  *cookie = GUINT_TO_POINTER(0);
8631
0
  return (header_field_info *)g_ptr_array_index(protocol->fields, 0);
8632
0
}
8633
8634
header_field_info *
8635
proto_get_next_protocol_field(const int proto_id, void **cookie)
8636
0
{
8637
0
  protocol_t *protocol = find_protocol_by_id(proto_id);
8638
0
  unsigned    i        = GPOINTER_TO_UINT(*cookie);
8639
8640
0
  i++;
8641
8642
0
  if ((protocol->fields == NULL) || (i >= protocol->fields->len))
8643
0
    return NULL;
8644
8645
0
  *cookie = GUINT_TO_POINTER(i);
8646
0
  return (header_field_info *)g_ptr_array_index(protocol->fields, i);
8647
0
}
8648
8649
protocol_t *
8650
find_protocol_by_id(const int proto_id)
8651
860k
{
8652
860k
  header_field_info *hfinfo;
8653
8654
860k
  if (proto_id <= 0)
8655
5.86k
    return NULL;
8656
8657
854k
  PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo);
8658
854k
  if (hfinfo->type != FT_PROTOCOL) {
8659
125k
    DISSECTOR_ASSERT(hfinfo->display & BASE_PROTOCOL_INFO);
8660
125k
  }
8661
854k
  return (protocol_t *)hfinfo->strings;
8662
860k
}
8663
8664
int
8665
proto_get_id(const protocol_t *protocol)
8666
1.40M
{
8667
1.40M
  return protocol->proto_id;
8668
1.40M
}
8669
8670
bool
8671
proto_name_already_registered(const char *name)
8672
0
{
8673
0
  DISSECTOR_ASSERT_HINT(name, "No name present");
8674
8675
0
  if (g_hash_table_lookup(proto_names, name) != NULL)
8676
0
    return true;
8677
0
  return false;
8678
0
}
8679
8680
int
8681
proto_get_id_by_filter_name(const char *filter_name)
8682
1.28k
{
8683
1.28k
  const protocol_t *protocol = NULL;
8684
8685
1.28k
  DISSECTOR_ASSERT_HINT(filter_name, "No filter name present");
8686
8687
1.28k
  protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8688
8689
1.28k
  if (protocol == NULL)
8690
75
    return -1;
8691
1.20k
  return protocol->proto_id;
8692
1.28k
}
8693
8694
int
8695
proto_get_id_by_short_name(const char *short_name)
8696
5.53k
{
8697
5.53k
  const protocol_t *protocol = NULL;
8698
8699
5.53k
  DISSECTOR_ASSERT_HINT(short_name, "No short name present");
8700
8701
5.53k
  protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8702
8703
5.53k
  if (protocol == NULL)
8704
0
    return -1;
8705
5.53k
  return protocol->proto_id;
8706
5.53k
}
8707
8708
const char *
8709
proto_get_protocol_name(const int proto_id)
8710
13.6k
{
8711
13.6k
  protocol_t *protocol;
8712
8713
13.6k
  protocol = find_protocol_by_id(proto_id);
8714
8715
13.6k
  if (protocol == NULL)
8716
0
    return NULL;
8717
13.6k
  return protocol->name;
8718
13.6k
}
8719
8720
const char *
8721
proto_get_protocol_short_name(const protocol_t *protocol)
8722
2.29M
{
8723
2.29M
  if (protocol == NULL)
8724
15
    return "(none)";
8725
2.29M
  return protocol->short_name;
8726
2.29M
}
8727
8728
const char *
8729
proto_get_protocol_long_name(const protocol_t *protocol)
8730
9
{
8731
9
  if (protocol == NULL)
8732
0
    return "(none)";
8733
9
  return protocol->name;
8734
9
}
8735
8736
const char *
8737
proto_get_protocol_filter_name(const int proto_id)
8738
438k
{
8739
438k
  protocol_t *protocol;
8740
8741
438k
  protocol = find_protocol_by_id(proto_id);
8742
438k
  if (protocol == NULL)
8743
19
    return "(none)";
8744
438k
  return protocol->filter_name;
8745
438k
}
8746
8747
void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8748
6.52k
{
8749
6.52k
  heur_dtbl_entry_t* heuristic_dissector;
8750
8751
6.52k
  if (protocol == NULL)
8752
0
    return;
8753
8754
6.52k
  heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8755
6.52k
  if (heuristic_dissector != NULL)
8756
6.52k
  {
8757
6.52k
    protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8758
6.52k
  }
8759
6.52k
}
8760
8761
void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8762
0
{
8763
0
  if (protocol == NULL)
8764
0
    return;
8765
8766
0
  g_list_foreach(protocol->heur_list, func, user_data);
8767
0
}
8768
8769
void
8770
proto_get_frame_protocols(const wmem_list_t *layers, bool *is_ip,
8771
        bool *is_tcp, bool *is_udp,
8772
        bool *is_sctp, bool *is_tls,
8773
        bool *is_rtp,
8774
        bool *is_lte_rlc)
8775
0
{
8776
0
  wmem_list_frame_t *protos = wmem_list_head(layers);
8777
0
  int     proto_id;
8778
0
  const char *proto_name;
8779
8780
  /* Walk the list of a available protocols in the packet and
8781
     attempt to find "major" ones. */
8782
  /* It might make more sense to assemble and return a bitfield. */
8783
0
  while (protos != NULL)
8784
0
  {
8785
0
    proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
8786
0
    proto_name = proto_get_protocol_filter_name(proto_id);
8787
8788
0
    if (is_ip && ((!strcmp(proto_name, "ip")) ||
8789
0
            (!strcmp(proto_name, "ipv6")))) {
8790
0
      *is_ip = true;
8791
0
    } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8792
0
      *is_tcp = true;
8793
0
    } else if (is_udp && !strcmp(proto_name, "udp")) {
8794
0
      *is_udp = true;
8795
0
    } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8796
0
      *is_sctp = true;
8797
0
    } else if (is_tls && !strcmp(proto_name, "tls")) {
8798
0
      *is_tls = true;
8799
0
    } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8800
0
      *is_rtp = true;
8801
0
    } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8802
0
      *is_lte_rlc = true;
8803
0
    }
8804
8805
0
    protos = wmem_list_frame_next(protos);
8806
0
  }
8807
0
}
8808
8809
bool
8810
proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8811
1.07k
{
8812
1.07k
  wmem_list_frame_t *protos = wmem_list_head(layers);
8813
1.07k
  int     proto_id;
8814
1.07k
  const char *name;
8815
8816
  /* Walk the list of a available protocols in the packet and
8817
     attempt to find the specified protocol. */
8818
7.53k
  while (protos != NULL)
8819
6.54k
  {
8820
6.54k
    proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
8821
6.54k
    name = proto_get_protocol_filter_name(proto_id);
8822
8823
6.54k
    if (!strcmp(name, proto_name))
8824
85
    {
8825
85
      return true;
8826
85
    }
8827
8828
6.46k
    protos = wmem_list_frame_next(protos);
8829
6.46k
  }
8830
8831
989
  return false;
8832
1.07k
}
8833
8834
char *
8835
proto_list_layers(const packet_info *pinfo)
8836
0
{
8837
0
  wmem_strbuf_t *buf;
8838
0
  wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8839
8840
0
  buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8841
8842
  /* Walk the list of layers in the packet and
8843
     return a string of all entries. */
8844
0
  while (layers != NULL)
8845
0
  {
8846
0
    wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))));
8847
8848
0
    layers = wmem_list_frame_next(layers);
8849
0
    if (layers != NULL) {
8850
0
      wmem_strbuf_append_c(buf, ':');
8851
0
    }
8852
0
  }
8853
8854
0
  return wmem_strbuf_finalize(buf);
8855
0
}
8856
8857
uint8_t
8858
proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8859
0
{
8860
0
  int *proto_layer_num_ptr;
8861
8862
0
  proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id));
8863
0
  if (proto_layer_num_ptr == NULL) {
8864
0
    return 0;
8865
0
  }
8866
8867
0
  return (uint8_t)*proto_layer_num_ptr;
8868
0
}
8869
8870
bool
8871
proto_is_pino(const protocol_t *protocol)
8872
4.37M
{
8873
4.37M
  return (protocol->parent_proto_id != -1);
8874
4.37M
}
8875
8876
bool
8877
// NOLINTNEXTLINE(misc-no-recursion)
8878
proto_is_protocol_enabled(const protocol_t *protocol)
8879
2.02M
{
8880
2.02M
  if (protocol == NULL)
8881
0
    return false;
8882
8883
  //parent protocol determines enable/disable for helper dissectors
8884
2.02M
  if (proto_is_pino(protocol))
8885
14.8k
    return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8886
8887
2.01M
  return protocol->is_enabled;
8888
2.02M
}
8889
8890
bool
8891
// NOLINTNEXTLINE(misc-no-recursion)
8892
proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8893
0
{
8894
  //parent protocol determines enable/disable for helper dissectors
8895
0
  if (proto_is_pino(protocol))
8896
0
    return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8897
8898
0
  return protocol->enabled_by_default;
8899
0
}
8900
8901
bool
8902
// NOLINTNEXTLINE(misc-no-recursion)
8903
proto_can_toggle_protocol(const int proto_id)
8904
108
{
8905
108
  protocol_t *protocol;
8906
8907
108
  protocol = find_protocol_by_id(proto_id);
8908
  //parent protocol determines toggling for helper dissectors
8909
108
  if (proto_is_pino(protocol))
8910
0
    return proto_can_toggle_protocol(protocol->parent_proto_id);
8911
8912
108
  return protocol->can_toggle;
8913
108
}
8914
8915
void
8916
proto_disable_by_default(const int proto_id)
8917
75
{
8918
75
  protocol_t *protocol;
8919
8920
75
  protocol = find_protocol_by_id(proto_id);
8921
75
  DISSECTOR_ASSERT(protocol->can_toggle);
8922
75
  DISSECTOR_ASSERT(proto_is_pino(protocol) == false);
8923
75
  protocol->is_enabled = false;
8924
75
  protocol->enabled_by_default = false;
8925
75
}
8926
8927
void
8928
proto_set_decoding(const int proto_id, const bool enabled)
8929
108
{
8930
108
  protocol_t *protocol;
8931
8932
108
  protocol = find_protocol_by_id(proto_id);
8933
108
  DISSECTOR_ASSERT(protocol->can_toggle);
8934
108
  DISSECTOR_ASSERT(proto_is_pino(protocol) == false);
8935
108
  protocol->is_enabled = enabled;
8936
108
}
8937
8938
void
8939
proto_disable_all(void)
8940
0
{
8941
  /* This doesn't explicitly disable heuristic protocols,
8942
   * but the heuristic doesn't get called if the parent
8943
   * protocol isn't enabled.
8944
   */
8945
0
  protocol_t *protocol;
8946
0
  GList      *list_item = protocols;
8947
8948
0
  if (protocols == NULL)
8949
0
    return;
8950
8951
0
  while (list_item) {
8952
0
    protocol = (protocol_t *)list_item->data;
8953
0
    if (protocol->can_toggle) {
8954
0
      protocol->is_enabled = false;
8955
0
    }
8956
0
    list_item = g_list_next(list_item);
8957
0
  }
8958
0
}
8959
8960
static void
8961
heur_reenable_cb(void *data, void *user_data _U_)
8962
0
{
8963
0
  heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8964
8965
0
  heur->enabled = heur->enabled_by_default;
8966
0
}
8967
8968
void
8969
proto_reenable_all(void)
8970
0
{
8971
0
  protocol_t *protocol;
8972
0
  GList      *list_item = protocols;
8973
8974
0
  if (protocols == NULL)
8975
0
    return;
8976
8977
0
  while (list_item) {
8978
0
    protocol = (protocol_t *)list_item->data;
8979
0
    if (protocol->can_toggle)
8980
0
      protocol->is_enabled = protocol->enabled_by_default;
8981
0
    proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL);
8982
0
    list_item = g_list_next(list_item);
8983
0
  }
8984
0
}
8985
8986
void
8987
proto_set_cant_toggle(const int proto_id)
8988
330
{
8989
330
  protocol_t *protocol;
8990
8991
330
  protocol = find_protocol_by_id(proto_id);
8992
330
  protocol->can_toggle = false;
8993
330
}
8994
8995
static int
8996
proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8997
3.62M
{
8998
3.62M
  g_ptr_array_add(proto->fields, hfi);
8999
9000
3.62M
  return proto_register_field_init(hfi, parent);
9001
3.62M
}
9002
9003
/* for use with static arrays only, since we don't allocate our own copies
9004
of the header_field_info struct contained within the hf_register_info struct */
9005
void
9006
proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9007
94.7k
{
9008
94.7k
  hf_register_info *ptr = hf;
9009
94.7k
  protocol_t   *proto;
9010
94.7k
  int     i;
9011
9012
94.7k
  proto = find_protocol_by_id(parent);
9013
9014
  /* if (proto == NULL) - error or return? */
9015
9016
94.7k
  if (proto->fields == NULL) {
9017
    /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9018
     * GLib introduced g_ptr_array_new_from_array, which might have
9019
     * given a reason to actually use it. (#17774)
9020
     */
9021
29.5k
    proto->fields = g_ptr_array_sized_new(num_records);
9022
29.5k
  }
9023
9024
3.72M
  for (i = 0; i < num_records; i++, ptr++) {
9025
    /*
9026
     * Make sure we haven't registered this yet.
9027
     * Most fields have variables associated with them that
9028
     * are initialized to 0; some are initialized to -1 (which
9029
     * was the standard before 4.4).
9030
     *
9031
     * XXX - Since this is called almost 300000 times at startup,
9032
     * it might be nice to compare to only 0 and require
9033
     * dissectors to pass in zero for unregistered fields.
9034
     */
9035
3.62M
    if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9036
0
      REPORT_DISSECTOR_BUG(
9037
0
        "Duplicate field detected in call to proto_register_field_array: %s is already registered",
9038
0
        ptr->hfinfo.abbrev);
9039
0
      return;
9040
0
    }
9041
9042
3.62M
    *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9043
3.62M
  }
9044
94.7k
}
9045
9046
/* deregister already registered fields */
9047
void
9048
proto_deregister_field (const int parent, int hf_id)
9049
0
{
9050
0
  header_field_info *hfi;
9051
0
  protocol_t       *proto;
9052
0
  unsigned          i;
9053
9054
0
  g_free(last_field_name);
9055
0
  last_field_name = NULL;
9056
9057
0
  if (hf_id == -1 || hf_id == 0)
9058
0
    return;
9059
9060
0
  proto = find_protocol_by_id (parent);
9061
0
  if (!proto || proto->fields == NULL) {
9062
0
    return;
9063
0
  }
9064
9065
0
  for (i = 0; i < proto->fields->len; i++) {
9066
0
    hfi = (header_field_info *)g_ptr_array_index(proto->fields, i);
9067
0
    if (hfi->id == hf_id) {
9068
      /* Found the hf_id in this protocol */
9069
0
      wmem_map_remove(gpa_name_map, hfi->abbrev);
9070
0
      g_ptr_array_remove_index_fast(proto->fields, i);
9071
0
      g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9072
0
      return;
9073
0
    }
9074
0
  }
9075
0
}
9076
9077
/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9078
void
9079
proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9080
135
{
9081
135
  header_field_info *hfinfo;
9082
135
  protocol_t        *proto;
9083
9084
135
  g_free(last_field_name);
9085
135
  last_field_name = NULL;
9086
9087
135
  proto = find_protocol_by_id(parent);
9088
135
  if (proto && proto->fields && proto->fields->len > 0) {
9089
135
    unsigned i = proto->fields->len;
9090
5.80k
    do {
9091
5.80k
      i--;
9092
9093
5.80k
      hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i);
9094
5.80k
      if (g_str_has_prefix(hfinfo->abbrev, prefix)) {
9095
0
        hfinfo_remove_from_gpa_name_map(hfinfo);
9096
0
        expert_deregister_expertinfo(hfinfo->abbrev);
9097
0
        g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9098
0
        g_ptr_array_remove_index_fast(proto->fields, i);
9099
0
      }
9100
5.80k
    } while (i > 0);
9101
135
  }
9102
135
}
9103
9104
void
9105
proto_add_deregistered_data (void *data)
9106
0
{
9107
0
  g_ptr_array_add(deregistered_data, data);
9108
0
}
9109
9110
void
9111
proto_add_deregistered_slice (size_t block_size, void *mem_block)
9112
0
{
9113
0
  struct g_slice_data *slice_data = g_slice_new(struct g_slice_data);
9114
9115
0
  slice_data->block_size = block_size;
9116
0
  slice_data->mem_block = mem_block;
9117
9118
0
  g_ptr_array_add(deregistered_slice, slice_data);
9119
0
}
9120
9121
void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9122
0
{
9123
0
  if (field_strings == NULL) {
9124
0
    return;
9125
0
  }
9126
9127
0
  switch (field_type) {
9128
0
    case FT_FRAMENUM:
9129
      /* This is just an integer represented as a pointer */
9130
0
      break;
9131
0
    case FT_PROTOCOL: {
9132
0
      protocol_t *protocol = (protocol_t *)field_strings;
9133
0
      g_free((char *)protocol->short_name);
9134
0
      break;
9135
0
    }
9136
0
    case FT_BOOLEAN: {
9137
0
      true_false_string *tf = (true_false_string *)field_strings;
9138
0
      g_free((char *)tf->true_string);
9139
0
      g_free((char *)tf->false_string);
9140
0
      break;
9141
0
    }
9142
0
    case FT_UINT40:
9143
0
    case FT_INT40:
9144
0
    case FT_UINT48:
9145
0
    case FT_INT48:
9146
0
    case FT_UINT56:
9147
0
    case FT_INT56:
9148
0
    case FT_UINT64:
9149
0
    case FT_INT64: {
9150
0
      if (field_display & BASE_UNIT_STRING) {
9151
0
        unit_name_string *unit = (unit_name_string *)field_strings;
9152
0
        g_free((char *)unit->singular);
9153
0
        g_free((char *)unit->plural);
9154
0
      } else if (field_display & BASE_RANGE_STRING) {
9155
0
        range_string *rs = (range_string *)field_strings;
9156
0
        while (rs->strptr) {
9157
0
          g_free((char *)rs->strptr);
9158
0
          rs++;
9159
0
        }
9160
0
      } else if (field_display & BASE_EXT_STRING) {
9161
0
        val64_string_ext *vse = (val64_string_ext *)field_strings;
9162
0
        val64_string *vs = (val64_string *)vse->_vs_p;
9163
0
        while (vs->strptr) {
9164
0
          g_free((char *)vs->strptr);
9165
0
          vs++;
9166
0
        }
9167
0
        val64_string_ext_free(vse);
9168
0
        field_strings = NULL;
9169
0
      } else if (field_display == BASE_CUSTOM) {
9170
        /* this will be a pointer to a function, don't free that */
9171
0
        field_strings = NULL;
9172
0
      } else {
9173
0
        val64_string *vs64 = (val64_string *)field_strings;
9174
0
        while (vs64->strptr) {
9175
0
          g_free((char *)vs64->strptr);
9176
0
          vs64++;
9177
0
        }
9178
0
      }
9179
0
      break;
9180
0
    }
9181
0
    case FT_CHAR:
9182
0
    case FT_UINT8:
9183
0
    case FT_INT8:
9184
0
    case FT_UINT16:
9185
0
    case FT_INT16:
9186
0
    case FT_UINT24:
9187
0
    case FT_INT24:
9188
0
    case FT_UINT32:
9189
0
    case FT_INT32:
9190
0
    case FT_FLOAT:
9191
0
    case FT_DOUBLE: {
9192
0
      if (field_display & BASE_UNIT_STRING) {
9193
0
        unit_name_string *unit = (unit_name_string *)field_strings;
9194
0
        g_free((char *)unit->singular);
9195
0
        g_free((char *)unit->plural);
9196
0
      } else if (field_display & BASE_RANGE_STRING) {
9197
0
        range_string *rs = (range_string *)field_strings;
9198
0
        while (rs->strptr) {
9199
0
          g_free((char *)rs->strptr);
9200
0
          rs++;
9201
0
        }
9202
0
      } else if (field_display & BASE_EXT_STRING) {
9203
0
        value_string_ext *vse = (value_string_ext *)field_strings;
9204
0
        value_string *vs = (value_string *)vse->_vs_p;
9205
0
        while (vs->strptr) {
9206
0
          g_free((char *)vs->strptr);
9207
0
          vs++;
9208
0
        }
9209
0
        value_string_ext_free(vse);
9210
0
        field_strings = NULL;
9211
0
      } else if (field_display == BASE_CUSTOM) {
9212
        /* this will be a pointer to a function, don't free that */
9213
0
        field_strings = NULL;
9214
0
      } else {
9215
0
        value_string *vs = (value_string *)field_strings;
9216
0
        while (vs->strptr) {
9217
0
          g_free((char *)vs->strptr);
9218
0
          vs++;
9219
0
        }
9220
0
      }
9221
0
      break;
9222
0
    default:
9223
0
      break;
9224
0
    }
9225
0
  }
9226
9227
0
  if (field_type != FT_FRAMENUM) {
9228
0
    g_free((void *)field_strings);
9229
0
  }
9230
0
}
9231
9232
static void
9233
free_deregistered_field (void *data, void *user_data _U_)
9234
0
{
9235
0
  header_field_info *hfi = (header_field_info *) data;
9236
0
  int hf_id = hfi->id;
9237
9238
0
  g_free((char *)hfi->name);
9239
0
  g_free((char *)hfi->abbrev);
9240
0
  g_free((char *)hfi->blurb);
9241
9242
0
  proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9243
9244
0
  if (hfi->parent == -1)
9245
0
    g_slice_free(header_field_info, hfi);
9246
9247
0
  gpa_hfinfo.hfi[hf_id] = NULL; /* Invalidate this hf_id / proto_id */
9248
0
}
9249
9250
static void
9251
free_deregistered_data (void *data, void *user_data _U_)
9252
0
{
9253
0
  g_free (data);
9254
0
}
9255
9256
static void
9257
free_deregistered_slice (void *data, void *user_data _U_)
9258
0
{
9259
0
  struct g_slice_data *slice_data = (struct g_slice_data *)data;
9260
9261
0
  g_slice_free1(slice_data->block_size, slice_data->mem_block);
9262
0
  g_slice_free(struct g_slice_data, slice_data);
9263
0
}
9264
9265
/* free deregistered fields and data */
9266
void
9267
proto_free_deregistered_fields (void)
9268
0
{
9269
0
  expert_free_deregistered_expertinfos();
9270
9271
0
  g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL);
9272
0
  g_ptr_array_free(deregistered_fields, true);
9273
0
  deregistered_fields = g_ptr_array_new();
9274
9275
0
  g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL);
9276
0
  g_ptr_array_free(deregistered_data, true);
9277
0
  deregistered_data = g_ptr_array_new();
9278
9279
0
  g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL);
9280
0
  g_ptr_array_free(deregistered_slice, true);
9281
0
  deregistered_slice = g_ptr_array_new();
9282
0
}
9283
9284
static const value_string hf_display[] = {
9285
  { BASE_NONE,        "BASE_NONE"        },
9286
  { BASE_DEC,       "BASE_DEC"         },
9287
  { BASE_HEX,       "BASE_HEX"         },
9288
  { BASE_OCT,       "BASE_OCT"         },
9289
  { BASE_DEC_HEX,       "BASE_DEC_HEX"       },
9290
  { BASE_HEX_DEC,       "BASE_HEX_DEC"       },
9291
  { BASE_CUSTOM,        "BASE_CUSTOM"        },
9292
  { BASE_NONE|BASE_RANGE_STRING,    "BASE_NONE|BASE_RANGE_STRING"    },
9293
  { BASE_DEC|BASE_RANGE_STRING,     "BASE_DEC|BASE_RANGE_STRING"     },
9294
  { BASE_HEX|BASE_RANGE_STRING,     "BASE_HEX|BASE_RANGE_STRING"     },
9295
  { BASE_OCT|BASE_RANGE_STRING,     "BASE_OCT|BASE_RANGE_STRING"     },
9296
  { BASE_DEC_HEX|BASE_RANGE_STRING, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9297
  { BASE_HEX_DEC|BASE_RANGE_STRING, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9298
  { BASE_CUSTOM|BASE_RANGE_STRING,  "BASE_CUSTOM|BASE_RANGE_STRING"  },
9299
  { BASE_NONE|BASE_VAL64_STRING,    "BASE_NONE|BASE_VAL64_STRING"    },
9300
  { BASE_DEC|BASE_VAL64_STRING,     "BASE_DEC|BASE_VAL64_STRING"     },
9301
  { BASE_HEX|BASE_VAL64_STRING,     "BASE_HEX|BASE_VAL64_STRING"     },
9302
  { BASE_OCT|BASE_VAL64_STRING,     "BASE_OCT|BASE_VAL64_STRING"     },
9303
  { BASE_DEC_HEX|BASE_VAL64_STRING, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9304
  { BASE_HEX_DEC|BASE_VAL64_STRING, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9305
  { BASE_CUSTOM|BASE_VAL64_STRING,  "BASE_CUSTOM|BASE_VAL64_STRING"  },
9306
  { ABSOLUTE_TIME_LOCAL,      "ABSOLUTE_TIME_LOCAL"      },
9307
  { ABSOLUTE_TIME_UTC,      "ABSOLUTE_TIME_UTC"      },
9308
  { ABSOLUTE_TIME_DOY_UTC,    "ABSOLUTE_TIME_DOY_UTC"    },
9309
  { BASE_PT_UDP,        "BASE_PT_UDP"        },
9310
  { BASE_PT_TCP,        "BASE_PT_TCP"        },
9311
  { BASE_PT_DCCP,       "BASE_PT_DCCP"       },
9312
  { BASE_PT_SCTP,       "BASE_PT_SCTP"       },
9313
  { BASE_OUI,       "BASE_OUI"         },
9314
  { 0,          NULL } };
9315
9316
const char* proto_field_display_to_string(int field_display)
9317
0
{
9318
0
  return val_to_str_const(field_display, hf_display, "Unknown");
9319
0
}
9320
9321
static inline port_type
9322
display_to_port_type(field_display_e e)
9323
0
{
9324
0
  switch (e) {
9325
0
  case BASE_PT_UDP:
9326
0
    return PT_UDP;
9327
0
  case BASE_PT_TCP:
9328
0
    return PT_TCP;
9329
0
  case BASE_PT_DCCP:
9330
0
    return PT_DCCP;
9331
0
  case BASE_PT_SCTP:
9332
0
    return PT_SCTP;
9333
0
  default:
9334
0
    break;
9335
0
  }
9336
0
  return PT_NONE;
9337
0
}
9338
9339
/* temporary function containing assert part for easier profiling */
9340
static void
9341
tmp_fld_check_assert(header_field_info *hfinfo)
9342
3.67M
{
9343
3.67M
  char* tmp_str;
9344
9345
  /* The field must have a name (with length > 0) */
9346
3.67M
  if (!hfinfo->name || !hfinfo->name[0]) {
9347
0
    if (hfinfo->abbrev)
9348
      /* Try to identify the field */
9349
0
      REPORT_DISSECTOR_BUG("Field (abbrev='%s') does not have a name",
9350
0
        hfinfo->abbrev);
9351
0
    else
9352
      /* Hum, no luck */
9353
0
      REPORT_DISSECTOR_BUG("Field does not have a name (nor an abbreviation)");
9354
0
  }
9355
9356
  /* fields with an empty string for an abbreviation aren't filterable */
9357
3.67M
  if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9358
3.67M
    REPORT_DISSECTOR_BUG("Field '%s' does not have an abbreviation", hfinfo->name);
9359
9360
  /* TODO: This check is a significant percentage of startup time (~10%),
9361
     although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9362
     It might be nice to have a way to disable this check when, e.g.,
9363
     running TShark many times with the same configuration. */
9364
  /* Check that the filter name (abbreviation) is legal;
9365
   * it must contain only alphanumerics, '-', "_", and ".". */
9366
3.67M
  unsigned char c;
9367
3.67M
  c = module_check_valid_name(hfinfo->abbrev, false);
9368
3.67M
  if (c) {
9369
0
    if (c == '.') {
9370
0
      REPORT_DISSECTOR_BUG("Invalid leading, duplicated or trailing '.' found in filter name '%s'", hfinfo->abbrev);
9371
0
    } else if (g_ascii_isprint(c)) {
9372
0
      REPORT_DISSECTOR_BUG("Invalid character '%c' in filter name '%s'", c, hfinfo->abbrev);
9373
0
    } else {
9374
0
      REPORT_DISSECTOR_BUG("Invalid byte \\%03o in filter name '%s'", c, hfinfo->abbrev);
9375
0
    }
9376
0
  }
9377
9378
  /*  These types of fields are allowed to have value_strings,
9379
   *  true_false_strings or a protocol_t struct
9380
   */
9381
3.67M
  if (hfinfo->strings != NULL && FIELD_DISPLAY(hfinfo->display) != BASE_CUSTOM) {
9382
874k
    switch (hfinfo->type) {
9383
9384
    /*
9385
     * These types are allowed to support display value_strings,
9386
     * value64_strings, the extended versions of the previous
9387
     * two, range strings, or unit strings.
9388
     */
9389
1.51k
    case FT_CHAR:
9390
183k
    case FT_UINT8:
9391
242k
    case FT_UINT16:
9392
245k
    case FT_UINT24:
9393
595k
    case FT_UINT32:
9394
595k
    case FT_UINT40:
9395
595k
    case FT_UINT48:
9396
595k
    case FT_UINT56:
9397
599k
    case FT_UINT64:
9398
600k
    case FT_INT8:
9399
601k
    case FT_INT16:
9400
601k
    case FT_INT24:
9401
613k
    case FT_INT32:
9402
613k
    case FT_INT40:
9403
613k
    case FT_INT48:
9404
613k
    case FT_INT56:
9405
614k
    case FT_INT64:
9406
822k
    case FT_BOOLEAN:
9407
854k
    case FT_PROTOCOL:
9408
854k
      break;
9409
9410
    /*
9411
     * This is allowed to have a value of type
9412
     * enum ft_framenum_type to indicate what relationship
9413
     * the frame in question has to the frame in which
9414
     * the field is put.
9415
     */
9416
3.48k
    case FT_FRAMENUM:
9417
3.48k
      break;
9418
9419
    /*
9420
     * These types are allowed to support only unit strings.
9421
     */
9422
1.09k
    case FT_FLOAT:
9423
2.59k
    case FT_DOUBLE:
9424
2.59k
    case FT_IEEE_11073_SFLOAT:
9425
2.59k
    case FT_IEEE_11073_FLOAT:
9426
2.59k
      if (!(hfinfo->display & BASE_UNIT_STRING)) {
9427
0
        REPORT_DISSECTOR_BUG("Field '%s' (%s) has a non-unit-strings 'strings' value but is of type %s"
9428
0
          " (which is only allowed to have unit strings)",
9429
0
          hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
9430
0
      }
9431
2.59k
      break;
9432
9433
    /*
9434
     * These types are allowed to support display
9435
     * time_value_strings.
9436
     */
9437
390
    case FT_ABSOLUTE_TIME:
9438
390
      if (hfinfo->display & BASE_RANGE_STRING ||
9439
390
          hfinfo->display & BASE_EXT_STRING ||
9440
390
          hfinfo->display & BASE_VAL64_STRING ||
9441
390
          hfinfo->display & BASE_UNIT_STRING) {
9442
0
        REPORT_DISSECTOR_BUG("Field '%s' (%s) has a non-time-value-strings 'strings' value but is of type %s"
9443
0
          " (which is only allowed to have time-value strings)",
9444
0
          hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
9445
0
      }
9446
390
      break;
9447
9448
    /*
9449
     * This type is only allowed to support a string if it's
9450
     * a protocol (for pinos).
9451
     */
9452
13.7k
    case FT_BYTES:
9453
13.7k
      if (!(hfinfo->display & BASE_PROTOCOL_INFO)) {
9454
0
        REPORT_DISSECTOR_BUG("Field '%s' (%s) has a non-protocol-info 'strings' value but is of type %s"
9455
0
          " (which is only allowed to have protocol-info strings)",
9456
0
          hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
9457
0
      }
9458
13.7k
      break;
9459
9460
0
    default:
9461
0
      REPORT_DISSECTOR_BUG("Field '%s' (%s) has a 'strings' value but is of type %s"
9462
874k
        " (which is not allowed to have strings)",
9463
874k
        hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type));
9464
874k
    }
9465
874k
  }
9466
9467
  /* TODO: This check may slow down startup, and output quite a few warnings.
9468
     It would be good to be able to enable this (and possibly other checks?)
9469
     in non-release builds.   */
9470
#ifdef ENABLE_CHECK_FILTER
9471
  /* Check for duplicate value_string values.
9472
     There are lots that have the same value *and* string, so for now only
9473
     report those that have same value but different string. */
9474
  if ((hfinfo->strings != NULL) &&
9475
      !(hfinfo->display & BASE_RANGE_STRING) &&
9476
      !(hfinfo->display & BASE_UNIT_STRING) &&
9477
      !((hfinfo->display & FIELD_DISPLAY_E_MASK) == BASE_CUSTOM) &&
9478
      (
9479
        (hfinfo->type == FT_CHAR)  ||
9480
        (hfinfo->type == FT_UINT8)  ||
9481
        (hfinfo->type == FT_UINT16) ||
9482
        (hfinfo->type == FT_UINT24) ||
9483
        (hfinfo->type == FT_UINT32) ||
9484
        (hfinfo->type == FT_INT8)   ||
9485
        (hfinfo->type == FT_INT16)  ||
9486
        (hfinfo->type == FT_INT24)  ||
9487
        (hfinfo->type == FT_INT32)  )) {
9488
9489
    if (hfinfo->display & BASE_EXT_STRING) {
9490
      if (hfinfo->display & BASE_VAL64_STRING) {
9491
        const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings);
9492
        CHECK_HF_VALUE(val64_string, PRIu64, start_values);
9493
      } else {
9494
        const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings);
9495
        CHECK_HF_VALUE(value_string, "u", start_values);
9496
      }
9497
    } else {
9498
      const value_string *start_values = (const value_string*)hfinfo->strings;
9499
      CHECK_HF_VALUE(value_string, "u", start_values);
9500
    }
9501
  }
9502
9503
  if (hfinfo->type == FT_BOOLEAN) {
9504
    const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9505
    if (tfs) {
9506
      if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9507
        ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",
9508
               hfinfo->name, hfinfo->abbrev,
9509
               tfs->false_string, tfs->true_string);
9510
      }
9511
    }
9512
  }
9513
9514
  if (hfinfo->display & BASE_RANGE_STRING) {
9515
    const range_string *rs = (const range_string*)(hfinfo->strings);
9516
    if (rs) {
9517
      const range_string *this_it = rs;
9518
9519
      do {
9520
        if (this_it->value_max < this_it->value_min) {
9521
          ws_warning("value_range_string error:  %s (%s) entry for \"%s\" - max(%"PRIu64" 0x%"PRIx64") is less than min(%"PRIu64" 0x%"PRIx64")",
9522
                hfinfo->name, hfinfo->abbrev,
9523
                this_it->strptr,
9524
                this_it->value_max, this_it->value_max,
9525
                this_it->value_min, this_it->value_min);
9526
          ++this_it;
9527
          continue;
9528
        }
9529
9530
        for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9531
          /* Not OK if this one is completely hidden by an earlier one! */
9532
          if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9533
            ws_warning("value_range_string error:  %s (%s) hidden by earlier entry "
9534
                  "(prev=\"%s\":  %"PRIu64" 0x%"PRIx64" -> %"PRIu64" 0x%"PRIx64")  (this=\"%s\":  %"PRIu64" 0x%"PRIx64" -> %"PRIu64" 0x%"PRIx64")",
9535
                  hfinfo->name, hfinfo->abbrev,
9536
                  prev_it->strptr, prev_it->value_min, prev_it->value_min,
9537
                  prev_it->value_max, prev_it->value_max,
9538
                  this_it->strptr, this_it->value_min, this_it->value_min,
9539
                  this_it->value_max, this_it->value_max);
9540
          }
9541
        }
9542
        ++this_it;
9543
      } while (this_it->strptr);
9544
    }
9545
  }
9546
#endif
9547
9548
3.67M
  switch (hfinfo->type) {
9549
9550
2.23k
    case FT_CHAR:
9551
      /*  Require the char type to have BASE_HEX, BASE_OCT,
9552
       *  BASE_CUSTOM, or BASE_NONE as its base.
9553
       *
9554
       *  If the display value is BASE_NONE and there is a
9555
       *  strings conversion then the dissector writer is
9556
       *  telling us that the field's numerical value is
9557
       *  meaningless; we'll avoid showing the value to the
9558
       *  user.
9559
       */
9560
2.23k
      switch (FIELD_DISPLAY(hfinfo->display)) {
9561
2.23k
        case BASE_HEX:
9562
2.23k
        case BASE_OCT:
9563
2.23k
        case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9564
2.23k
          break;
9565
0
        case BASE_NONE:
9566
0
          if (hfinfo->strings == NULL)
9567
0
            REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"
9568
0
              " but is being displayed as BASE_NONE but"
9569
0
              " without a strings conversion",
9570
0
              hfinfo->name, hfinfo->abbrev,
9571
0
              ftype_name(hfinfo->type));
9572
0
          break;
9573
0
        default:
9574
0
          tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
9575
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is a character value (%s)"
9576
2.23k
            " but is being displayed as %s",
9577
2.23k
            hfinfo->name, hfinfo->abbrev,
9578
2.23k
            ftype_name(hfinfo->type), tmp_str);
9579
          //wmem_free(NULL, tmp_str);
9580
2.23k
      }
9581
2.23k
      if (hfinfo->display & BASE_UNIT_STRING) {
9582
0
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is a character value (%s) but has a unit string",
9583
0
          hfinfo->name, hfinfo->abbrev,
9584
0
          ftype_name(hfinfo->type));
9585
0
      }
9586
2.23k
      break;
9587
5.74k
    case FT_INT8:
9588
13.5k
    case FT_INT16:
9589
13.9k
    case FT_INT24:
9590
73.6k
    case FT_INT32:
9591
73.6k
    case FT_INT40:
9592
73.7k
    case FT_INT48:
9593
73.7k
    case FT_INT56:
9594
80.7k
    case FT_INT64:
9595
      /*  Hexadecimal and octal are, in printf() and everywhere
9596
       *  else, unsigned so don't allow dissectors to register a
9597
       *  signed field to be displayed unsigned.  (Else how would
9598
       *  we display negative values?)
9599
       */
9600
80.7k
      switch (FIELD_DISPLAY(hfinfo->display)) {
9601
0
        case BASE_HEX:
9602
0
        case BASE_OCT:
9603
0
        case BASE_DEC_HEX:
9604
0
        case BASE_HEX_DEC:
9605
0
          tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
9606
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is signed (%s) but is being displayed unsigned (%s)",
9607
80.7k
            hfinfo->name, hfinfo->abbrev,
9608
80.7k
            ftype_name(hfinfo->type), tmp_str);
9609
          //wmem_free(NULL, tmp_str);
9610
80.7k
      }
9611
      /* FALL THROUGH */
9612
614k
    case FT_UINT8:
9613
916k
    case FT_UINT16:
9614
936k
    case FT_UINT24:
9615
1.88M
    case FT_UINT32:
9616
1.88M
    case FT_UINT40:
9617
1.88M
    case FT_UINT48:
9618
1.88M
    case FT_UINT56:
9619
1.94M
    case FT_UINT64:
9620
1.94M
      if (IS_BASE_PORT(hfinfo->display)) {
9621
1.42k
        tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
9622
1.42k
        if (hfinfo->type != FT_UINT16) {
9623
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT16, not %s",
9624
0
            hfinfo->name, hfinfo->abbrev,
9625
0
            tmp_str, ftype_name(hfinfo->type));
9626
0
        }
9627
1.42k
        if (hfinfo->strings != NULL) {
9628
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s (%s) but has a strings value",
9629
0
            hfinfo->name, hfinfo->abbrev,
9630
0
            ftype_name(hfinfo->type), tmp_str);
9631
0
        }
9632
1.42k
        if (hfinfo->bitmask != 0) {
9633
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s (%s) but has a bitmask",
9634
0
            hfinfo->name, hfinfo->abbrev,
9635
0
            ftype_name(hfinfo->type), tmp_str);
9636
0
        }
9637
1.42k
        wmem_free(NULL, tmp_str);
9638
1.42k
        break;
9639
1.42k
      }
9640
9641
1.94M
      if (hfinfo->display == BASE_OUI) {
9642
975
        tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
9643
975
        if (hfinfo->type != FT_UINT24) {
9644
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) has 'display' value %s but it can only be used with FT_UINT24, not %s",
9645
0
            hfinfo->name, hfinfo->abbrev,
9646
0
            tmp_str, ftype_name(hfinfo->type));
9647
0
        }
9648
975
        if (hfinfo->strings != NULL) {
9649
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s (%s) but has a strings value",
9650
0
            hfinfo->name, hfinfo->abbrev,
9651
0
            ftype_name(hfinfo->type), tmp_str);
9652
0
        }
9653
975
        if (hfinfo->bitmask != 0) {
9654
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s (%s) but has a bitmask",
9655
0
            hfinfo->name, hfinfo->abbrev,
9656
0
            ftype_name(hfinfo->type), tmp_str);
9657
0
        }
9658
975
        wmem_free(NULL, tmp_str);
9659
975
        break;
9660
975
      }
9661
9662
      /*  Require integral types (other than frame number,
9663
       *  which is always displayed in decimal) to have a
9664
       *  number base.
9665
       *
9666
       *  If the display value is BASE_NONE and there is a
9667
       *  strings conversion then the dissector writer is
9668
       *  telling us that the field's numerical value is
9669
       *  meaningless; we'll avoid showing the value to the
9670
       *  user.
9671
       */
9672
1.94M
      switch (FIELD_DISPLAY(hfinfo->display)) {
9673
1.47M
        case BASE_DEC:
9674
1.84M
        case BASE_HEX:
9675
1.84M
        case BASE_OCT:
9676
1.86M
        case BASE_DEC_HEX:
9677
1.90M
        case BASE_HEX_DEC:
9678
1.93M
        case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9679
1.93M
          break;
9680
2.59k
        case BASE_NONE:
9681
2.59k
          if (hfinfo->strings == NULL) {
9682
0
            REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"
9683
0
              " but is being displayed as BASE_NONE but"
9684
0
              " without a strings conversion",
9685
0
              hfinfo->name, hfinfo->abbrev,
9686
0
              ftype_name(hfinfo->type));
9687
0
          }
9688
2.59k
          if (hfinfo->display & BASE_SPECIAL_VALS) {
9689
0
            REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"
9690
0
              " that is being displayed as BASE_NONE but"
9691
0
              " with BASE_SPECIAL_VALS",
9692
0
              hfinfo->name, hfinfo->abbrev,
9693
0
              ftype_name(hfinfo->type));
9694
0
          }
9695
2.59k
          break;
9696
9697
0
        default:
9698
0
          tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
9699
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"
9700
1.94M
            " but is being displayed as %s",
9701
1.94M
            hfinfo->name, hfinfo->abbrev,
9702
1.94M
            ftype_name(hfinfo->type), tmp_str);
9703
          //wmem_free(NULL, tmp_str);
9704
1.94M
      }
9705
1.94M
      break;
9706
1.94M
    case FT_BYTES:
9707
246k
    case FT_UINT_BYTES:
9708
      /*  Require bytes to have a "display type" that could
9709
       *  add a character between displayed bytes.
9710
       */
9711
246k
      switch (FIELD_DISPLAY(hfinfo->display)) {
9712
243k
        case BASE_NONE:
9713
243k
        case SEP_DOT:
9714
244k
        case SEP_DASH:
9715
245k
        case SEP_COLON:
9716
246k
        case SEP_SPACE:
9717
246k
          break;
9718
0
        default:
9719
0
          tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
9720
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",
9721
246k
            hfinfo->name, hfinfo->abbrev, tmp_str);
9722
          //wmem_free(NULL, tmp_str);
9723
246k
      }
9724
246k
      if (hfinfo->bitmask != 0)
9725
246k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",
9726
246k
          hfinfo->name, hfinfo->abbrev,
9727
246k
          ftype_name(hfinfo->type));
9728
      //allowed to support string if its a protocol (for pinos)
9729
246k
      if ((hfinfo->strings != NULL) && (!(hfinfo->display & BASE_PROTOCOL_INFO)))
9730
246k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",
9731
246k
          hfinfo->name, hfinfo->abbrev,
9732
246k
          ftype_name(hfinfo->type));
9733
246k
      break;
9734
9735
34.6k
    case FT_PROTOCOL:
9736
49.4k
    case FT_FRAMENUM:
9737
49.4k
      if (hfinfo->display != BASE_NONE) {
9738
0
        tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
9739
0
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE",
9740
0
          hfinfo->name, hfinfo->abbrev,
9741
0
          ftype_name(hfinfo->type), tmp_str);
9742
        //wmem_free(NULL, tmp_str);
9743
0
      }
9744
49.4k
      if (hfinfo->bitmask != 0)
9745
49.4k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",
9746
49.4k
          hfinfo->name, hfinfo->abbrev,
9747
49.4k
          ftype_name(hfinfo->type));
9748
49.4k
      break;
9749
9750
484k
    case FT_BOOLEAN:
9751
484k
      break;
9752
9753
14.1k
    case FT_ABSOLUTE_TIME:
9754
14.1k
      if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)) {
9755
0
        tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
9756
0
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is a %s but is being displayed as %s instead of as a time",
9757
0
          hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type), tmp_str);
9758
        //wmem_free(NULL, tmp_str);
9759
0
      }
9760
14.1k
      if (hfinfo->bitmask != 0)
9761
14.1k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",
9762
14.1k
          hfinfo->name, hfinfo->abbrev,
9763
14.1k
          ftype_name(hfinfo->type));
9764
14.1k
      break;
9765
9766
177k
    case FT_STRING:
9767
190k
    case FT_STRINGZ:
9768
196k
    case FT_UINT_STRING:
9769
196k
    case FT_STRINGZPAD:
9770
199k
    case FT_STRINGZTRUNC:
9771
199k
      switch (FIELD_DISPLAY(hfinfo->display)) {
9772
199k
        case BASE_NONE:
9773
199k
        case BASE_STR_WSP:
9774
199k
          break;
9775
9776
0
        default:
9777
0
          tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
9778
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is an string value (%s)"
9779
199k
            " but is being displayed as %s",
9780
199k
            hfinfo->name, hfinfo->abbrev,
9781
199k
            ftype_name(hfinfo->type), tmp_str);
9782
          //wmem_free(NULL, tmp_str);
9783
199k
      }
9784
9785
199k
      if (hfinfo->bitmask != 0)
9786
199k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",
9787
199k
          hfinfo->name, hfinfo->abbrev,
9788
199k
          ftype_name(hfinfo->type));
9789
199k
      if (hfinfo->strings != NULL)
9790
199k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",
9791
199k
          hfinfo->name, hfinfo->abbrev,
9792
199k
          ftype_name(hfinfo->type));
9793
199k
      break;
9794
9795
21.5k
    case FT_IPv4:
9796
21.5k
      switch (hfinfo->display) {
9797
21.0k
        case BASE_NONE:
9798
21.5k
        case BASE_NETMASK:
9799
21.5k
          break;
9800
9801
0
        default:
9802
0
          tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
9803
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is an IPv4 value (%s)"
9804
0
            " but is being displayed as %s",
9805
0
            hfinfo->name, hfinfo->abbrev,
9806
0
            ftype_name(hfinfo->type), tmp_str);
9807
          //wmem_free(NULL, tmp_str);
9808
0
          break;
9809
21.5k
      }
9810
21.5k
      break;
9811
21.5k
    case FT_FLOAT:
9812
25.4k
    case FT_DOUBLE:
9813
25.4k
      switch (FIELD_DISPLAY(hfinfo->display)) {
9814
23.6k
        case BASE_NONE:
9815
25.4k
        case BASE_DEC:
9816
25.4k
        case BASE_HEX:
9817
25.4k
        case BASE_EXP:
9818
25.4k
        case BASE_CUSTOM:
9819
25.4k
          break;
9820
0
        default:
9821
0
          tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Unknown: 0x%x)");
9822
0
          REPORT_DISSECTOR_BUG("Field '%s' (%s) is a float value (%s)"
9823
25.4k
            " but is being displayed as %s",
9824
25.4k
            hfinfo->name, hfinfo->abbrev,
9825
25.4k
            ftype_name(hfinfo->type), tmp_str);
9826
          //wmem_free(NULL, tmp_str);
9827
25.4k
      }
9828
25.4k
      if (hfinfo->bitmask != 0)
9829
25.4k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",
9830
25.4k
          hfinfo->name, hfinfo->abbrev,
9831
25.4k
          ftype_name(hfinfo->type));
9832
25.4k
      if (FIELD_DISPLAY(hfinfo->display) != BASE_CUSTOM && (hfinfo->strings != NULL) && !(hfinfo->display & BASE_UNIT_STRING))
9833
25.4k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",
9834
25.4k
          hfinfo->name, hfinfo->abbrev,
9835
25.4k
          ftype_name(hfinfo->type));
9836
25.4k
      break;
9837
360
    case FT_IEEE_11073_SFLOAT:
9838
405
    case FT_IEEE_11073_FLOAT:
9839
405
      if (FIELD_DISPLAY(hfinfo->display) != BASE_NONE) {
9840
0
        tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
9841
0
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE",
9842
0
          hfinfo->name, hfinfo->abbrev,
9843
0
          ftype_name(hfinfo->type),
9844
0
          tmp_str);
9845
        //wmem_free(NULL, tmp_str);
9846
0
      }
9847
405
      if (hfinfo->bitmask != 0)
9848
405
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",
9849
405
          hfinfo->name, hfinfo->abbrev,
9850
405
          ftype_name(hfinfo->type));
9851
405
      if ((hfinfo->strings != NULL) && !(hfinfo->display & BASE_UNIT_STRING))
9852
405
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",
9853
405
          hfinfo->name, hfinfo->abbrev,
9854
405
          ftype_name(hfinfo->type));
9855
405
      break;
9856
684k
    default:
9857
684k
      if (hfinfo->display != BASE_NONE) {
9858
0
        tmp_str = val_to_str(NULL, hfinfo->display, hf_display, "(Bit count: %d)");
9859
0
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but is being displayed as %s instead of BASE_NONE",
9860
0
          hfinfo->name, hfinfo->abbrev,
9861
0
          ftype_name(hfinfo->type),
9862
0
          tmp_str);
9863
        //wmem_free(NULL, tmp_str);
9864
0
      }
9865
684k
      if (hfinfo->bitmask != 0)
9866
684k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",
9867
684k
          hfinfo->name, hfinfo->abbrev,
9868
684k
          ftype_name(hfinfo->type));
9869
684k
      if (hfinfo->strings != NULL)
9870
684k
        REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",
9871
684k
          hfinfo->name, hfinfo->abbrev,
9872
684k
          ftype_name(hfinfo->type));
9873
684k
      break;
9874
3.67M
  }
9875
3.67M
}
9876
9877
static void
9878
register_type_length_mismatch(void)
9879
15
{
9880
15
  static ei_register_info ei[] = {
9881
15
    { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED, PI_ERROR, "Trying to fetch X with length Y", EXPFILL }},
9882
15
    { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch_warn", PI_MALFORMED, PI_WARN, "Trying to fetch X with length Y", EXPFILL }},
9883
15
  };
9884
9885
15
  expert_module_t* expert_type_length_mismatch;
9886
9887
15
  proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9888
9889
15
  expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9890
15
  expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei));
9891
9892
  /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9893
     disabling them makes no sense. */
9894
15
  proto_set_cant_toggle(proto_type_length_mismatch);
9895
15
}
9896
9897
static void
9898
register_byte_array_string_decodinws_error(void)
9899
15
{
9900
15
  static ei_register_info ei[] = {
9901
15
    { &ei_byte_array_string_decoding_failed_error,
9902
15
      { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
9903
15
        "Failed to decode byte array from string", EXPFILL
9904
15
      }
9905
15
    },
9906
15
  };
9907
9908
15
  expert_module_t* expert_byte_array_string_decoding_error;
9909
9910
15
  proto_byte_array_string_decoding_error =
9911
15
    proto_register_protocol("Byte Array-String Decoding Error",
9912
15
          "Byte Array-string decoding error",
9913
15
          "_ws.byte_array_string.decoding_error");
9914
9915
15
  expert_byte_array_string_decoding_error =
9916
15
    expert_register_protocol(proto_byte_array_string_decoding_error);
9917
15
  expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei));
9918
9919
  /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9920
     disabling them makes no sense. */
9921
15
  proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9922
15
}
9923
9924
static void
9925
register_date_time_string_decodinws_error(void)
9926
15
{
9927
15
  static ei_register_info ei[] = {
9928
15
    { &ei_date_time_string_decoding_failed_error,
9929
15
      { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED, PI_ERROR,
9930
15
        "Failed to decode date and time from string", EXPFILL
9931
15
      }
9932
15
    },
9933
15
  };
9934
9935
15
  expert_module_t* expert_date_time_string_decoding_error;
9936
9937
15
  proto_date_time_string_decoding_error =
9938
15
    proto_register_protocol("Date and Time-String Decoding Error",
9939
15
          "Date and Time-string decoding error",
9940
15
          "_ws.date_time_string.decoding_error");
9941
9942
15
  expert_date_time_string_decoding_error =
9943
15
    expert_register_protocol(proto_date_time_string_decoding_error);
9944
15
  expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei));
9945
9946
  /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9947
     disabling them makes no sense. */
9948
15
  proto_set_cant_toggle(proto_date_time_string_decoding_error);
9949
15
}
9950
9951
static void
9952
register_string_errors(void)
9953
15
{
9954
15
  static ei_register_info ei[] = {
9955
15
    { &ei_string_trailing_characters,
9956
15
      { "_ws.string.trailing_stray_characters", PI_UNDECODED, PI_WARN, "Trailing stray characters", EXPFILL }
9957
15
    },
9958
15
  };
9959
9960
15
  expert_module_t* expert_string_errors;
9961
9962
15
  proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9963
9964
15
  expert_string_errors = expert_register_protocol(proto_string_errors);
9965
15
  expert_register_field_array(expert_string_errors, ei, array_length(ei));
9966
9967
  /* "String Errors" isn't really a protocol, it's an error indication;
9968
     disabling them makes no sense. */
9969
15
  proto_set_cant_toggle(proto_string_errors);
9970
15
}
9971
9972
static int
9973
proto_register_field_init(header_field_info *hfinfo, const int parent)
9974
3.67M
{
9975
9976
3.67M
  tmp_fld_check_assert(hfinfo);
9977
9978
3.67M
  hfinfo->parent         = parent;
9979
3.67M
  hfinfo->same_name_next = NULL;
9980
3.67M
  hfinfo->same_name_prev_id = -1;
9981
9982
  /* if we always add and never delete, then id == len - 1 is correct */
9983
3.67M
  if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9984
15
    if (!gpa_hfinfo.hfi) {
9985
15
      gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM;
9986
15
      gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM);
9987
      /* The entry with index 0 is not used. */
9988
15
      gpa_hfinfo.hfi[0] = NULL;
9989
15
      gpa_hfinfo.len = 1;
9990
15
    } else {
9991
0
      gpa_hfinfo.allocated_len += 1000;
9992
0
      gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9993
0
               sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9994
      /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9995
0
    }
9996
15
  }
9997
3.67M
  gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9998
3.67M
  gpa_hfinfo.len++;
9999
3.67M
  hfinfo->id = gpa_hfinfo.len - 1;
10000
10001
  /* if we have real names, enter this field in the name tree */
10002
  /* Already checked in tmp_fld_check_assert */
10003
  /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10004
3.67M
  {
10005
10006
3.67M
    header_field_info *same_name_next_hfinfo;
10007
10008
    /* We allow multiple hfinfo's to be registered under the same
10009
     * abbreviation. This was done for X.25, as, depending
10010
     * on whether it's modulo-8 or modulo-128 operation,
10011
     * some bitfield fields may be in different bits of
10012
     * a byte, and we want to be able to refer to that field
10013
     * with one name regardless of whether the packets
10014
     * are modulo-8 or modulo-128 packets. */
10015
10016
    /* wmem_map_insert - if key is already present the previous
10017
     * hfinfo with the same key/name is returned, otherwise NULL */
10018
3.67M
    same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10019
3.67M
    if (same_name_hfinfo) {
10020
      /* There's already a field with this name.
10021
       * Put the current field *before* that field
10022
       * in the list of fields with this name, Thus,
10023
       * we end up with an effectively
10024
       * doubly-linked-list of same-named hfinfo's,
10025
       * with the head of the list (stored in the
10026
       * hash) being the last seen hfinfo.
10027
       */
10028
221k
      same_name_next_hfinfo =
10029
221k
        same_name_hfinfo->same_name_next;
10030
10031
221k
      hfinfo->same_name_next = same_name_next_hfinfo;
10032
221k
      if (same_name_next_hfinfo)
10033
0
        same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10034
10035
221k
      same_name_hfinfo->same_name_next = hfinfo;
10036
221k
      hfinfo->same_name_prev_id = same_name_hfinfo->id;
10037
#ifdef ENABLE_CHECK_FILTER
10038
      while (same_name_hfinfo) {
10039
        if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10040
          ws_error("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type));
10041
        same_name_hfinfo = same_name_hfinfo->same_name_next;
10042
      }
10043
#endif
10044
221k
    }
10045
3.67M
  }
10046
10047
3.67M
  return hfinfo->id;
10048
3.67M
}
10049
10050
void
10051
proto_register_subtree_array(int * const *indices, const int num_indices)
10052
28.6k
{
10053
28.6k
  int i;
10054
28.6k
  int *const *ptr = indices;
10055
10056
  /*
10057
   * If we've already allocated the array of tree types, expand
10058
   * it; this lets plugins such as mate add tree types after
10059
   * the initial startup.  (If we haven't already allocated it,
10060
   * we don't allocate it; on the first pass, we just assign
10061
   * ett values and keep track of how many we've assigned, and
10062
   * when we're finished registering all dissectors we allocate
10063
   * the array, so that we do only one allocation rather than
10064
   * wasting CPU time and memory by growing the array for each
10065
   * dissector that registers ett values.)
10066
   */
10067
28.6k
  if (tree_is_expanded != NULL) {
10068
109
    tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10069
10070
    /* set new items to 0 */
10071
    /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10072
385
    for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10073
276
      tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10074
109
  }
10075
10076
  /*
10077
   * Assign "num_indices" subtree numbers starting at "num_tree_types",
10078
   * returning the indices through the pointers in the array whose
10079
   * first element is pointed to by "indices", and update
10080
   * "num_tree_types" appropriately.
10081
   */
10082
973k
  for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10083
945k
    if (**ptr != -1 && **ptr != 0) {
10084
0
      REPORT_DISSECTOR_BUG("register_subtree_array: subtree item type (ett_...) not -1 or 0 !"
10085
0
        " This is a development error:"
10086
0
        " Either the subtree item type has already been assigned or"
10087
0
        " was not initialized to -1 or 0.");
10088
0
    }
10089
945k
    **ptr = num_tree_types;
10090
945k
  }
10091
28.6k
}
10092
10093
static void
10094
mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10095
7.76k
{
10096
7.76k
  static const char  trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS "] ";
10097
7.76k
  const size_t       trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10098
7.76k
  char              *last_char;
10099
10100
  /* ..... field_name: dataaaaaaaaaaaaa
10101
   *                 |
10102
   *                 ^^^^^ name_pos
10103
   *
10104
   * ..... field_name […]: dataaaaaaaaaaaaa
10105
   *
10106
   * name_pos==0 means that we have only data or only a field_name
10107
   */
10108
10109
7.76k
  ws_abort_if_fail(size > trunc_len);
10110
10111
7.76k
  if (name_pos >= size - trunc_len) {
10112
    /* No room for trunc_str after the field_name, put it first. */
10113
0
    name_pos = 0;
10114
0
  }
10115
10116
7.76k
  memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10117
7.76k
  if (name_pos == 0) {
10118
    /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10119
4.50k
    memcpy(label_str, trunc_str + 1, trunc_len);
10120
4.50k
  } else {
10121
3.25k
    memcpy(label_str + name_pos, trunc_str, trunc_len);
10122
3.25k
  }
10123
  /* in general, label_str is UTF-8
10124
     we can truncate it only at the beginning of a new character
10125
     we go backwards from the byte right after our buffer and
10126
      find the next starting byte of a UTF-8 character, this is
10127
      where we cut
10128
     there's no need to use g_utf8_find_prev_char(), the search
10129
      will always succeed since we copied trunc_str into the
10130
      buffer */
10131
  /* g_utf8_prev_char does not deference the memory address
10132
   * passed in (until after decrementing it, so it is perfectly
10133
   * legal to pass in a pointer one past the last element.
10134
   */
10135
7.76k
  last_char = g_utf8_prev_char(label_str + size);
10136
7.76k
  *last_char = '\0';
10137
  /* This is unnecessary (above always terminates), but try to
10138
   * convince Coverity to avoid dozens of false positives. */
10139
7.76k
  label_str[size - 1] = '\0';
10140
10141
7.76k
  if (value_pos && *value_pos > 0) {
10142
5.27k
    if (name_pos == 0) {
10143
3.35k
      *value_pos += trunc_len;
10144
3.35k
    } else {
10145
      /* Move one back to include trunc_str in the value. */
10146
1.92k
      *value_pos -= 1;
10147
1.92k
    }
10148
5.27k
  }
10149
10150
  /* Check if value_pos is past label_str. */
10151
7.76k
  if (value_pos && *value_pos >= size) {
10152
0
    *value_pos = size - 1;
10153
0
  }
10154
7.76k
}
10155
10156
static void
10157
label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10158
7.76k
{
10159
7.76k
  mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH, value_pos);
10160
7.76k
}
10161
10162
static size_t
10163
label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10164
1.16M
{
10165
1.16M
  size_t name_pos;
10166
10167
  /* "%s: %s", hfinfo->name, text */
10168
1.16M
  name_pos = pos = label_concat(label_str, pos, (const uint8_t*)hfinfo->name);
10169
1.16M
  if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
10170
1.16M
    pos = label_concat(label_str, pos, (const uint8_t*)": ");
10171
1.16M
    if (value_pos) {
10172
853k
      *value_pos = pos;
10173
853k
    }
10174
1.16M
    pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10175
1.16M
  }
10176
10177
1.16M
  if (pos >= ITEM_LABEL_LENGTH) {
10178
    /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10179
176
    label_mark_truncated(label_str, name_pos, value_pos);
10180
176
  }
10181
10182
1.16M
  return pos;
10183
1.16M
}
10184
10185
static size_t
10186
label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10187
423k
{
10188
423k
  size_t name_pos;
10189
10190
  /* "%s: %s (%s)", hfinfo->name, text, descr */
10191
423k
  name_pos = pos = label_concat(label_str, pos, (const uint8_t*)hfinfo->name);
10192
423k
  if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE)) {
10193
423k
    pos = label_concat(label_str, pos, (const uint8_t*)": ");
10194
423k
    if (value_pos) {
10195
24.5k
      *value_pos = pos;
10196
24.5k
    }
10197
423k
    if (hfinfo->display & BASE_UNIT_STRING) {
10198
1.24k
      pos = label_concat(label_str, pos, (const uint8_t*)(descr ? descr : "(null)"));
10199
1.24k
      pos = label_concat(label_str, pos, (const uint8_t*)(text ? text : "(null)"));
10200
422k
    } else {
10201
422k
      pos = label_concat(label_str, pos, (const uint8_t*)(text ? text : "(null)"));
10202
422k
      pos = label_concat(label_str, pos, (const uint8_t*)" (");
10203
422k
      pos = label_concat(label_str, pos, (const uint8_t*)(descr ? descr : "(null)"));
10204
422k
      pos = label_concat(label_str, pos, (const uint8_t*)")");
10205
422k
    }
10206
423k
  }
10207
10208
423k
  if (pos >= ITEM_LABEL_LENGTH) {
10209
    /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10210
1.33k
    label_mark_truncated(label_str, name_pos, value_pos);
10211
1.33k
  }
10212
10213
423k
  return pos;
10214
423k
}
10215
10216
void
10217
proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10218
1.51M
{
10219
1.51M
  const header_field_info  *hfinfo;
10220
1.51M
  const char     *str;
10221
1.51M
  const uint8_t    *bytes;
10222
1.51M
  uint32_t        integer;
10223
1.51M
  const ipv4_addr_and_mask *ipv4;
10224
1.51M
  const ipv6_addr_and_prefix *ipv6;
10225
1.51M
  const e_guid_t     *guid;
10226
1.51M
  char       *name;
10227
1.51M
  address       addr;
10228
1.51M
  char       *addr_str;
10229
1.51M
  char       *tmp;
10230
10231
1.51M
  if (!label_str) {
10232
0
    ws_warning("NULL label_str passed to proto_item_fill_label.");
10233
0
    return;
10234
0
  }
10235
10236
1.51M
  label_str[0]= '\0';
10237
10238
1.51M
  if (!fi) {
10239
0
    return;
10240
0
  }
10241
10242
1.51M
  hfinfo = fi->hfinfo;
10243
10244
1.51M
  switch (hfinfo->type) {
10245
447k
    case FT_NONE:
10246
635k
    case FT_PROTOCOL:
10247
635k
      (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH);
10248
635k
      if (value_pos) {
10249
635k
        *value_pos = strlen(hfinfo->name);
10250
635k
      }
10251
635k
      break;
10252
10253
6.48k
    case FT_BOOLEAN:
10254
6.48k
      fill_label_boolean(fi, label_str, value_pos);
10255
6.48k
      break;
10256
10257
149k
    case FT_BYTES:
10258
149k
    case FT_UINT_BYTES:
10259
149k
      tmp = format_bytes_hfinfo(NULL, hfinfo,
10260
149k
          fvalue_get_bytes_data(fi->value),
10261
149k
          (unsigned)fvalue_length2(fi->value));
10262
149k
      label_fill(label_str, 0, hfinfo, tmp, value_pos);
10263
149k
      wmem_free(NULL, tmp);
10264
149k
      break;
10265
10266
0
    case FT_CHAR:
10267
0
      if (hfinfo->bitmask) {
10268
0
        fill_label_bitfield_char(fi, label_str, value_pos);
10269
0
      } else {
10270
0
        fill_label_char(fi, label_str, value_pos);
10271
0
      }
10272
0
      break;
10273
10274
    /* Four types of integers to take care of:
10275
     *  Bitfield, with val_string
10276
     *  Bitfield, w/o val_string
10277
     *  Non-bitfield, with val_string
10278
     *  Non-bitfield, w/o val_string
10279
     */
10280
178k
    case FT_UINT8:
10281
367k
    case FT_UINT16:
10282
369k
    case FT_UINT24:
10283
661k
    case FT_UINT32:
10284
661k
      if (hfinfo->bitmask) {
10285
91.7k
        fill_label_bitfield(fi, label_str, value_pos, false);
10286
570k
      } else {
10287
570k
        fill_label_number(fi, label_str, value_pos, false);
10288
570k
      }
10289
661k
      break;
10290
10291
0
    case FT_FRAMENUM:
10292
0
      fill_label_number(fi, label_str, value_pos, false);
10293
0
      break;
10294
10295
8.14k
    case FT_UINT40:
10296
8.16k
    case FT_UINT48:
10297
8.16k
    case FT_UINT56:
10298
8.53k
    case FT_UINT64:
10299
8.53k
      if (hfinfo->bitmask) {
10300
267
        fill_label_bitfield64(fi, label_str, value_pos, false);
10301
8.26k
      } else {
10302
8.26k
        fill_label_number64(fi, label_str, value_pos, false);
10303
8.26k
      }
10304
8.53k
      break;
10305
10306
220
    case FT_INT8:
10307
247
    case FT_INT16:
10308
495
    case FT_INT24:
10309
592
    case FT_INT32:
10310
592
      if (hfinfo->bitmask) {
10311
248
        fill_label_bitfield(fi, label_str, value_pos, true);
10312
344
      } else {
10313
344
        fill_label_number(fi, label_str, value_pos, true);
10314
344
      }
10315
592
      break;
10316
10317
0
    case FT_INT40:
10318
0
    case FT_INT48:
10319
0
    case FT_INT56:
10320
9
    case FT_INT64:
10321
9
      if (hfinfo->bitmask) {
10322
0
        fill_label_bitfield64(fi, label_str, value_pos, true);
10323
9
      } else {
10324
9
        fill_label_number64(fi, label_str, value_pos, true);
10325
9
      }
10326
9
      break;
10327
10328
5.24k
    case FT_FLOAT:
10329
5.78k
    case FT_DOUBLE:
10330
5.78k
      fill_label_float(fi, label_str, value_pos);
10331
5.78k
      break;
10332
10333
186
    case FT_ABSOLUTE_TIME:
10334
186
    {
10335
186
      const nstime_t *value = fvalue_get_time(fi->value);
10336
186
      int flags = ABS_TIME_TO_STR_SHOW_ZONE;
10337
186
      if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10338
0
        flags |= ABS_TIME_TO_STR_ISO8601;
10339
0
      }
10340
186
      if (hfinfo->strings) {
10341
        /*
10342
         * Table of time valus to be displayed
10343
         * specially.
10344
         */
10345
0
        const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10346
0
        if (time_string != NULL) {
10347
0
          label_fill(label_str, 0, hfinfo, time_string, value_pos);
10348
0
          break;
10349
0
        }
10350
0
      }
10351
186
      tmp = abs_time_to_str_ex(NULL, value, hfinfo->display, flags);
10352
186
      label_fill(label_str, 0, hfinfo, tmp, value_pos);
10353
186
      wmem_free(NULL, tmp);
10354
186
      break;
10355
186
    }
10356
6
    case FT_RELATIVE_TIME:
10357
6
      tmp = rel_time_to_str(NULL, fvalue_get_time(fi->value));
10358
6
      label_fill(label_str, 0, hfinfo, tmp, value_pos);
10359
6
      wmem_free(NULL, tmp);
10360
6
      break;
10361
10362
0
    case FT_IPXNET:
10363
0
      integer = fvalue_get_uinteger(fi->value);
10364
0
      tmp = get_ipxnet_name(NULL, integer);
10365
0
      addr_str = wmem_strdup_printf(NULL, "0x%08X", integer);
10366
0
      label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10367
0
      wmem_free(NULL, tmp);
10368
0
      wmem_free(NULL, addr_str);
10369
0
      break;
10370
10371
0
    case FT_VINES:
10372
0
      addr.type = AT_VINES;
10373
0
      addr.len  = VINES_ADDR_LEN;
10374
0
      addr.data = fvalue_get_bytes_data(fi->value);
10375
10376
0
      addr_str = (char*)address_to_str(NULL, &addr);
10377
0
      label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10378
0
      wmem_free(NULL, addr_str);
10379
0
      break;
10380
10381
48
    case FT_ETHER:
10382
48
      bytes = fvalue_get_bytes_data(fi->value);
10383
10384
48
      addr.type = AT_ETHER;
10385
48
      addr.len  = 6;
10386
48
      addr.data = bytes;
10387
10388
48
      addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
10389
48
      label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10390
48
      wmem_free(NULL, addr_str);
10391
48
      break;
10392
10393
290
    case FT_IPv4:
10394
290
      ipv4 = fvalue_get_ipv4(fi->value);
10395
290
      set_address_ipv4(&addr, ipv4);
10396
10397
290
      if (hfinfo->display == BASE_NETMASK) {
10398
0
        addr_str = (char*)address_to_str(NULL, &addr);
10399
290
      } else {
10400
290
        addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
10401
290
      }
10402
290
      label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10403
290
      wmem_free(NULL, addr_str);
10404
290
      free_address(&addr);
10405
290
      break;
10406
10407
3
    case FT_IPv6:
10408
3
      ipv6 = fvalue_get_ipv6(fi->value);
10409
3
      set_address_ipv6(&addr, ipv6);
10410
10411
3
      addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
10412
3
      label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10413
3
      wmem_free(NULL, addr_str);
10414
3
      free_address(&addr);
10415
3
      break;
10416
10417
0
    case FT_FCWWN:
10418
0
      bytes = fvalue_get_bytes_data(fi->value);
10419
0
      addr.type = AT_FCWWN;
10420
0
      addr.len  = FCWWN_ADDR_LEN;
10421
0
      addr.data = bytes;
10422
10423
0
      addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
10424
0
      label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10425
0
      wmem_free(NULL, addr_str);
10426
0
      break;
10427
10428
0
    case FT_GUID:
10429
0
      guid = fvalue_get_guid(fi->value);
10430
0
      tmp = guid_to_str(NULL, guid);
10431
0
      label_fill(label_str, 0, hfinfo, tmp, value_pos);
10432
0
      wmem_free(NULL, tmp);
10433
0
      break;
10434
10435
0
    case FT_OID:
10436
0
      bytes = fvalue_get_bytes_data(fi->value);
10437
0
      name = oid_resolved_from_encoded(NULL, bytes, (int)fvalue_length2(fi->value));
10438
0
      tmp = oid_encoded2string(NULL, bytes, (unsigned)fvalue_length2(fi->value));
10439
0
      if (name) {
10440
0
        label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10441
0
        wmem_free(NULL, name);
10442
0
      } else {
10443
0
        label_fill(label_str, 0, hfinfo, tmp, value_pos);
10444
0
      }
10445
0
      wmem_free(NULL, tmp);
10446
0
      break;
10447
10448
0
    case FT_REL_OID:
10449
0
      bytes = fvalue_get_bytes_data(fi->value);
10450
0
      name = rel_oid_resolved_from_encoded(NULL, bytes, (int)fvalue_length2(fi->value));
10451
0
      tmp = rel_oid_encoded2string(NULL, bytes, (unsigned)fvalue_length2(fi->value));
10452
0
      if (name) {
10453
0
        label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10454
0
        wmem_free(NULL, name);
10455
0
      } else {
10456
0
        label_fill(label_str, 0, hfinfo, tmp, value_pos);
10457
0
      }
10458
0
      wmem_free(NULL, tmp);
10459
0
      break;
10460
10461
0
    case FT_SYSTEM_ID:
10462
0
      bytes = fvalue_get_bytes_data(fi->value);
10463
0
      tmp = print_system_id(NULL, bytes, (int)fvalue_length2(fi->value));
10464
0
      label_fill(label_str, 0, hfinfo, tmp, value_pos);
10465
0
      wmem_free(NULL, tmp);
10466
0
      break;
10467
10468
310
    case FT_EUI64:
10469
310
      bytes = fvalue_get_bytes_data(fi->value);
10470
310
      addr.type = AT_EUI64;
10471
310
      addr.len  = EUI64_ADDR_LEN;
10472
310
      addr.data = bytes;
10473
10474
310
      addr_str = (char*)address_with_resolution_to_str(NULL, &addr);
10475
310
      label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10476
310
      wmem_free(NULL, addr_str);
10477
310
      break;
10478
46.3k
    case FT_STRING:
10479
46.3k
    case FT_STRINGZ:
10480
46.3k
    case FT_UINT_STRING:
10481
46.3k
    case FT_STRINGZPAD:
10482
46.3k
    case FT_STRINGZTRUNC:
10483
46.3k
    case FT_AX25:
10484
46.3k
      str = fvalue_get_string(fi->value);
10485
46.3k
      label_fill(label_str, 0, hfinfo, str, value_pos);
10486
46.3k
      break;
10487
10488
0
    case FT_IEEE_11073_SFLOAT:
10489
0
    case FT_IEEE_11073_FLOAT:
10490
0
      fill_label_ieee_11073_float(fi, label_str, value_pos);
10491
0
      break;
10492
10493
0
    default:
10494
0
      REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_fill_label()",
10495
0
               hfinfo->abbrev,
10496
0
               hfinfo->type,
10497
0
               ftype_name(hfinfo->type));
10498
0
      break;
10499
1.51M
  }
10500
1.51M
}
10501
10502
static void
10503
fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10504
6.48k
{
10505
6.48k
  char  *p;
10506
6.48k
  int      bitfield_byte_length = 0, bitwidth;
10507
6.48k
  uint64_t unshifted_value;
10508
6.48k
  uint64_t value;
10509
10510
6.48k
  const header_field_info *hfinfo   = fi->hfinfo;
10511
10512
6.48k
  value = fvalue_get_uinteger64(fi->value);
10513
6.48k
  if (hfinfo->bitmask) {
10514
    /* Figure out the bit width */
10515
195
    bitwidth = hfinfo_container_bitwidth(hfinfo);
10516
10517
    /* Un-shift bits */
10518
195
    unshifted_value = value;
10519
195
    unshifted_value <<= hfinfo_bitshift(hfinfo);
10520
10521
    /* Create the bitfield first */
10522
195
    p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10523
195
    bitfield_byte_length = (int) (p - label_str);
10524
195
  }
10525
10526
  /* Fill in the textual info */
10527
6.48k
  label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10528
6.48k
}
10529
10530
static const char *
10531
hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10532
761k
{
10533
761k
  if (hfinfo->display & BASE_RANGE_STRING)
10534
7.73k
    return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10535
10536
753k
  if (hfinfo->display & BASE_EXT_STRING) {
10537
5.71k
    if (hfinfo->display & BASE_VAL64_STRING)
10538
0
      return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10539
5.71k
    else
10540
5.71k
      return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10541
5.71k
  }
10542
10543
747k
  if (hfinfo->display & BASE_VAL64_STRING)
10544
0
    return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10545
10546
747k
  if (hfinfo->display & BASE_UNIT_STRING)
10547
1.24k
    return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10548
10549
746k
  return try_val_to_str(value, (const value_string *) hfinfo->strings);
10550
747k
}
10551
10552
static const char *
10553
hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10554
0
{
10555
0
  if (hfinfo->display & BASE_VAL64_STRING) {
10556
0
    if (hfinfo->display & BASE_EXT_STRING)
10557
0
      return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10558
0
    else
10559
0
      return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10560
0
  }
10561
10562
0
  if (hfinfo->display & BASE_RANGE_STRING)
10563
0
    return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10564
10565
0
  if (hfinfo->display & BASE_UNIT_STRING)
10566
0
    return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10567
10568
  /* If this is reached somebody registered a 64-bit field with a 32-bit
10569
   * value-string, which isn't right. */
10570
0
  REPORT_DISSECTOR_BUG("field %s is a 64-bit field with a 32-bit value_string",
10571
0
      hfinfo->abbrev);
10572
10573
  /* This is necessary to squelch MSVC errors; is there
10574
     any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10575
     never returns? */
10576
0
  return NULL;
10577
0
}
10578
10579
static const char *
10580
hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10581
0
{
10582
0
  if (hfinfo->display & BASE_UNIT_STRING)
10583
0
    return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10584
10585
0
  REPORT_DISSECTOR_BUG("field %s (FT_DOUBLE) has no base_unit_string", hfinfo->abbrev);
10586
10587
  /* This is necessary to squelch MSVC errors; is there
10588
     any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10589
     never returns? */
10590
0
  return NULL;
10591
0
}
10592
10593
static const char *
10594
hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10595
336k
{
10596
336k
  const char *str = hf_try_val_to_str(value, hfinfo);
10597
10598
336k
  return (str) ? str : unknown_str;
10599
336k
}
10600
10601
static const char *
10602
hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10603
0
{
10604
0
  const char *str = hf_try_val64_to_str(value, hfinfo);
10605
10606
0
  return (str) ? str : unknown_str;
10607
0
}
10608
10609
/* Fills data for bitfield chars with val_strings */
10610
static void
10611
fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10612
0
{
10613
0
  char       *p;
10614
0
  int         bitfield_byte_length, bitwidth;
10615
0
  uint32_t    unshifted_value;
10616
0
  uint32_t    value;
10617
10618
0
  char        buf[32];
10619
0
  const char *out;
10620
10621
0
  const header_field_info *hfinfo = fi->hfinfo;
10622
10623
  /* Figure out the bit width */
10624
0
  bitwidth = hfinfo_container_bitwidth(hfinfo);
10625
10626
  /* Un-shift bits */
10627
0
  value = fvalue_get_uinteger(fi->value);
10628
10629
0
  unshifted_value = value;
10630
0
  if (hfinfo->bitmask) {
10631
0
    unshifted_value <<= hfinfo_bitshift(hfinfo);
10632
0
  }
10633
10634
  /* Create the bitfield first */
10635
0
  p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10636
0
  bitfield_byte_length = (int) (p - label_str);
10637
10638
  /* Fill in the textual info using stored (shifted) value */
10639
0
  if (hfinfo->display == BASE_CUSTOM) {
10640
0
    char tmp[ITEM_LABEL_LENGTH];
10641
0
    const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10642
10643
0
    DISSECTOR_ASSERT(fmtfunc);
10644
0
    fmtfunc(tmp, value);
10645
0
    label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10646
0
  }
10647
0
  else if (hfinfo->strings) {
10648
0
    const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10649
10650
0
    out = hfinfo_char_vals_format(hfinfo, buf, value);
10651
0
    if (out == NULL) /* BASE_NONE so don't put integer in descr */
10652
0
      label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10653
0
    else
10654
0
      label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10655
0
  }
10656
0
  else {
10657
0
    out = hfinfo_char_value_format(hfinfo, buf, value);
10658
10659
0
    label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10660
0
  }
10661
0
}
10662
10663
/* Fills data for bitfield ints with val_strings */
10664
static void
10665
fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool is_signed)
10666
91.9k
{
10667
91.9k
  char       *p;
10668
91.9k
  int         bitfield_byte_length, bitwidth;
10669
91.9k
  uint32_t    value, unshifted_value;
10670
91.9k
  char        buf[NUMBER_LABEL_LENGTH];
10671
91.9k
  const char *out;
10672
10673
91.9k
  const header_field_info *hfinfo = fi->hfinfo;
10674
10675
  /* Figure out the bit width */
10676
91.9k
  if (fi->flags & FI_VARINT)
10677
0
    bitwidth = fi->length*8;
10678
91.9k
  else
10679
91.9k
    bitwidth = hfinfo_container_bitwidth(hfinfo);
10680
10681
  /* Un-shift bits */
10682
91.9k
  if (is_signed)
10683
248
    value = fvalue_get_sinteger(fi->value);
10684
91.7k
  else
10685
91.7k
    value = fvalue_get_uinteger(fi->value);
10686
10687
91.9k
  unshifted_value = value;
10688
91.9k
  if (hfinfo->bitmask) {
10689
91.9k
    unshifted_value <<= hfinfo_bitshift(hfinfo);
10690
91.9k
  }
10691
10692
  /* Create the bitfield first */
10693
91.9k
  if (fi->flags & FI_VARINT)
10694
0
    p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10695
91.9k
  else
10696
91.9k
    p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10697
91.9k
  bitfield_byte_length = (int) (p - label_str);
10698
10699
  /* Fill in the textual info using stored (shifted) value */
10700
91.9k
  if (hfinfo->display == BASE_CUSTOM) {
10701
50
    char tmp[ITEM_LABEL_LENGTH];
10702
50
    const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10703
10704
50
    DISSECTOR_ASSERT(fmtfunc);
10705
50
    fmtfunc(tmp, value);
10706
50
    label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10707
50
  }
10708
91.9k
  else if (hfinfo->strings) {
10709
2.96k
    const char *val_str = hf_try_val_to_str(value, hfinfo);
10710
10711
2.96k
    out = hfinfo_number_vals_format(hfinfo, buf, value);
10712
2.96k
    if (hfinfo->display & BASE_SPECIAL_VALS) {
10713
      /*
10714
       * Unique values only display value_string string
10715
       * if there is a match. Otherwise it's just a number
10716
       */
10717
0
      if (val_str) {
10718
0
        label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10719
0
      } else {
10720
0
        label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10721
0
      }
10722
2.96k
    } else {
10723
2.96k
      if (val_str == NULL)
10724
39
        val_str = "Unknown";
10725
10726
2.96k
      if (out == NULL) /* BASE_NONE so don't put integer in descr */
10727
0
        label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10728
2.96k
      else
10729
2.96k
        label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10730
2.96k
    }
10731
2.96k
  }
10732
88.9k
  else {
10733
88.9k
    out = hfinfo_number_value_format(hfinfo, buf, value);
10734
10735
88.9k
    label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10736
88.9k
  }
10737
91.9k
}
10738
10739
static void
10740
fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool is_signed)
10741
267
{
10742
267
  char       *p;
10743
267
  int         bitfield_byte_length, bitwidth;
10744
267
  uint64_t    value, unshifted_value;
10745
267
  char        buf[NUMBER_LABEL_LENGTH];
10746
267
  const char *out;
10747
10748
267
  const header_field_info *hfinfo = fi->hfinfo;
10749
10750
  /* Figure out the bit width */
10751
267
  if (fi->flags & FI_VARINT)
10752
0
    bitwidth = fi->length*8;
10753
267
  else
10754
267
    bitwidth = hfinfo_container_bitwidth(hfinfo);
10755
10756
  /* Un-shift bits */
10757
267
  if (is_signed)
10758
0
    value = fvalue_get_sinteger64(fi->value);
10759
267
  else
10760
267
    value = fvalue_get_uinteger64(fi->value);
10761
10762
267
  unshifted_value = value;
10763
267
  if (hfinfo->bitmask) {
10764
267
    unshifted_value <<= hfinfo_bitshift(hfinfo);
10765
267
  }
10766
10767
  /* Create the bitfield first */
10768
267
  if (fi->flags & FI_VARINT)
10769
0
    p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10770
267
  else
10771
267
    p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10772
267
  bitfield_byte_length = (int) (p - label_str);
10773
10774
  /* Fill in the textual info using stored (shifted) value */
10775
267
  if (hfinfo->display == BASE_CUSTOM) {
10776
0
    char tmp[ITEM_LABEL_LENGTH];
10777
0
    const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10778
10779
0
    DISSECTOR_ASSERT(fmtfunc64);
10780
0
    fmtfunc64(tmp, value);
10781
0
    label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10782
0
  }
10783
267
  else if (hfinfo->strings) {
10784
0
    const char *val_str = hf_try_val64_to_str(value, hfinfo);
10785
10786
0
    out = hfinfo_number_vals_format64(hfinfo, buf, value);
10787
0
    if (hfinfo->display & BASE_SPECIAL_VALS) {
10788
      /*
10789
       * Unique values only display value_string string
10790
       * if there is a match. Otherwise it's just a number
10791
       */
10792
0
      if (val_str) {
10793
0
        label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10794
0
      } else {
10795
0
        label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10796
0
      }
10797
0
    } else {
10798
0
      if (val_str == NULL)
10799
0
        val_str = "Unknown";
10800
10801
0
      if (out == NULL) /* BASE_NONE so don't put integer in descr */
10802
0
        label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10803
0
      else
10804
0
        label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10805
0
    }
10806
0
  }
10807
267
  else {
10808
267
    out = hfinfo_number_value_format64(hfinfo, buf, value);
10809
10810
267
    label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10811
267
  }
10812
267
}
10813
10814
static void
10815
fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10816
0
{
10817
0
  const header_field_info *hfinfo = fi->hfinfo;
10818
0
  uint32_t           value;
10819
10820
0
  char               buf[32];
10821
0
  const char        *out;
10822
10823
0
  value = fvalue_get_uinteger(fi->value);
10824
10825
  /* Fill in the textual info */
10826
0
  if (hfinfo->display == BASE_CUSTOM) {
10827
0
    char tmp[ITEM_LABEL_LENGTH];
10828
0
    const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10829
10830
0
    DISSECTOR_ASSERT(fmtfunc);
10831
0
    fmtfunc(tmp, value);
10832
0
    label_fill(label_str, 0, hfinfo, tmp, value_pos);
10833
0
  }
10834
0
  else if (hfinfo->strings) {
10835
0
    const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10836
10837
0
    out = hfinfo_char_vals_format(hfinfo, buf, value);
10838
0
    label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10839
0
  }
10840
0
  else {
10841
0
    out = hfinfo_char_value_format(hfinfo, buf, value);
10842
10843
0
    label_fill(label_str, 0, hfinfo, out, value_pos);
10844
0
  }
10845
0
}
10846
10847
static void
10848
fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool is_signed)
10849
1.27M
{
10850
1.27M
  const header_field_info *hfinfo = fi->hfinfo;
10851
1.27M
  uint32_t           value;
10852
10853
1.27M
  char               buf[NUMBER_LABEL_LENGTH];
10854
1.27M
  const char        *out;
10855
10856
1.27M
  if (is_signed)
10857
361
    value = fvalue_get_sinteger(fi->value);
10858
1.27M
  else
10859
1.27M
    value = fvalue_get_uinteger(fi->value);
10860
10861
  /* Fill in the textual info */
10862
1.27M
  if (hfinfo->display == BASE_CUSTOM) {
10863
456
    char tmp[ITEM_LABEL_LENGTH];
10864
456
    const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10865
10866
456
    DISSECTOR_ASSERT(fmtfunc);
10867
456
    fmtfunc(tmp, value);
10868
456
    label_fill(label_str, 0, hfinfo, tmp, value_pos);
10869
456
  }
10870
1.27M
  else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10871
    /*
10872
     * It makes no sense to have a value-string table for a
10873
     * frame-number field - they're just integers giving
10874
     * the ordinal frame number.
10875
     */
10876
422k
    const char *val_str = hf_try_val_to_str(value, hfinfo);
10877
10878
422k
    out = hfinfo_number_vals_format(hfinfo, buf, value);
10879
422k
    if (hfinfo->display & BASE_SPECIAL_VALS) {
10880
      /*
10881
       * Unique values only display value_string string
10882
       * if there is a match. Otherwise it's just a number
10883
       */
10884
998
      if (val_str) {
10885
0
        label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10886
998
      } else {
10887
998
        label_fill(label_str, 0, hfinfo, out, value_pos);
10888
998
      }
10889
421k
    } else {
10890
421k
      if (val_str == NULL)
10891
23.8k
        val_str = "Unknown";
10892
10893
421k
      if (out == NULL) /* BASE_NONE so don't put integer in descr */
10894
73
        label_fill(label_str, 0, hfinfo, val_str, value_pos);
10895
421k
      else
10896
421k
        label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10897
421k
    }
10898
422k
  }
10899
856k
  else if (IS_BASE_PORT(hfinfo->display)) {
10900
0
    char tmp[ITEM_LABEL_LENGTH];
10901
10902
0
    port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10903
0
      display_to_port_type((field_display_e)hfinfo->display), value);
10904
0
    label_fill(label_str, 0, hfinfo, tmp, value_pos);
10905
0
  }
10906
856k
  else {
10907
856k
    out = hfinfo_number_value_format(hfinfo, buf, value);
10908
10909
856k
    label_fill(label_str, 0, hfinfo, out, value_pos);
10910
856k
  }
10911
1.27M
}
10912
10913
static void
10914
fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool is_signed)
10915
8.43k
{
10916
8.43k
  const header_field_info *hfinfo = fi->hfinfo;
10917
8.43k
  uint64_t           value;
10918
10919
8.43k
  char               buf[NUMBER_LABEL_LENGTH];
10920
8.43k
  const char        *out;
10921
10922
8.43k
  if (is_signed)
10923
9
    value = fvalue_get_sinteger64(fi->value);
10924
8.42k
  else
10925
8.42k
    value = fvalue_get_uinteger64(fi->value);
10926
10927
  /* Fill in the textual info */
10928
8.43k
  if (hfinfo->display == BASE_CUSTOM) {
10929
0
    char tmp[ITEM_LABEL_LENGTH];
10930
0
    const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10931
10932
0
    DISSECTOR_ASSERT(fmtfunc64);
10933
0
    fmtfunc64(tmp, value);
10934
0
    label_fill(label_str, 0, hfinfo, tmp, value_pos);
10935
0
  }
10936
8.43k
  else if (hfinfo->strings) {
10937
0
    const char *val_str = hf_try_val64_to_str(value, hfinfo);
10938
10939
0
    out = hfinfo_number_vals_format64(hfinfo, buf, value);
10940
0
    if (hfinfo->display & BASE_SPECIAL_VALS) {
10941
      /*
10942
       * Unique values only display value_string string
10943
       * if there is a match. Otherwise it's just a number
10944
       */
10945
0
      if (val_str) {
10946
0
        label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10947
0
      } else {
10948
0
        label_fill(label_str, 0, hfinfo, out, value_pos);
10949
0
      }
10950
0
    } else {
10951
0
      if (val_str == NULL)
10952
0
        val_str = "Unknown";
10953
10954
0
      if (out == NULL) /* BASE_NONE so don't put integer in descr */
10955
0
        label_fill(label_str, 0, hfinfo, val_str, value_pos);
10956
0
      else
10957
0
        label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10958
0
    }
10959
0
  }
10960
8.43k
  else {
10961
8.43k
    out = hfinfo_number_value_format64(hfinfo, buf, value);
10962
10963
8.43k
    label_fill(label_str, 0, hfinfo, out, value_pos);
10964
8.43k
  }
10965
8.43k
}
10966
10967
static size_t
10968
fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10969
5.78k
{
10970
5.78k
  int display;
10971
5.78k
  int n;
10972
5.78k
  double value;
10973
10974
5.78k
  if (label_str_size < 12) {
10975
    /* Not enough room to write an entire floating point value. */
10976
0
    return 0;
10977
0
  }
10978
10979
5.78k
  display = FIELD_DISPLAY(fi->hfinfo->display);
10980
5.78k
  value = fvalue_get_floating(fi->value);
10981
10982
5.78k
  if (display == BASE_CUSTOM) {
10983
0
    const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10984
0
    DISSECTOR_ASSERT(fmtfunc);
10985
0
    fmtfunc(label_str, value);
10986
0
    return strlen(label_str);
10987
0
  }
10988
10989
5.78k
  switch (display) {
10990
5.24k
    case BASE_NONE:
10991
5.24k
      if (fi->hfinfo->type == FT_FLOAT) {
10992
5.24k
        n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG, value);
10993
5.24k
      } else {
10994
0
        n = (int)strlen(dtoa_g_fmt(label_str, value));
10995
0
      }
10996
5.24k
      break;
10997
0
    case BASE_DEC:
10998
0
      n = snprintf(label_str, label_str_size, "%f", value);
10999
0
      break;
11000
0
    case BASE_HEX:
11001
0
      n = snprintf(label_str, label_str_size, "%a", value);
11002
0
      break;
11003
549
    case BASE_EXP:
11004
549
      n = snprintf(label_str, label_str_size, "%e", value);
11005
549
      break;
11006
0
    default:
11007
0
      ws_assert_not_reached();
11008
5.78k
  }
11009
5.78k
  if (n < 0) {
11010
0
    return 0; /* error */
11011
0
  }
11012
5.78k
  if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING)) {
11013
0
    const char *hf_str_val;
11014
0
    hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11015
0
    n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11016
0
  }
11017
5.78k
  if (n > label_str_size) {
11018
0
    ws_warning("label length too small");
11019
0
    return strlen(label_str);
11020
0
  }
11021
11022
5.78k
  return n;
11023
5.78k
}
11024
11025
void
11026
fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11027
5.78k
{
11028
5.78k
  char tmp[ITEM_LABEL_LENGTH];
11029
11030
5.78k
  fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH);
11031
5.78k
  label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11032
5.78k
}
11033
11034
static size_t
11035
fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11036
0
{
11037
0
  int display;
11038
0
  size_t pos = 0;
11039
0
  double value;
11040
0
  char* tmp_str;
11041
11042
0
  if (label_str_size < 12) {
11043
    /* Not enough room to write an entire floating point value. */
11044
0
    return 0;
11045
0
  }
11046
11047
0
  display = FIELD_DISPLAY(fi->hfinfo->display);
11048
0
  tmp_str = fvalue_to_string_repr(NULL, fi->value, FTREPR_DISPLAY, display);
11049
0
  pos = label_concat(label_str, pos, (const uint8_t*)tmp_str);
11050
0
  wmem_free(NULL, tmp_str);
11051
11052
0
  if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING)) {
11053
0
    const char *hf_str_val;
11054
0
    fvalue_to_double(fi->value, &value);
11055
0
    hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11056
0
    pos = label_concat(label_str, pos, (const uint8_t*)hf_str_val);
11057
0
  }
11058
0
  if ((int)pos > label_str_size) {
11059
0
    ws_warning("label length too small");
11060
0
    return strlen(label_str);
11061
0
  }
11062
11063
0
  return pos;
11064
0
}
11065
11066
void
11067
fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11068
0
{
11069
0
  char tmp[ITEM_LABEL_LENGTH];
11070
11071
0
  fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH);
11072
0
  label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11073
0
}
11074
11075
int
11076
hfinfo_bitshift(const header_field_info *hfinfo)
11077
17.9M
{
11078
17.9M
  return ws_ctz(hfinfo->bitmask);
11079
17.9M
}
11080
11081
11082
static int
11083
hfinfo_bitoffset(const header_field_info *hfinfo)
11084
7.76M
{
11085
7.76M
  if (!hfinfo->bitmask) {
11086
0
    return 0;
11087
0
  }
11088
11089
  /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11090
   * as the first bit */
11091
7.76M
  return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11092
7.76M
}
11093
11094
static int
11095
hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11096
7.82M
{
11097
7.82M
  if (!hfinfo->bitmask) {
11098
0
    return 0;
11099
0
  }
11100
11101
  /* ilog2 = first set bit, ctz = last set bit */
11102
7.82M
  return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11103
7.82M
}
11104
11105
static int
11106
hfinfo_type_bitwidth(enum ftenum type)
11107
2.89M
{
11108
2.89M
  int bitwidth = 0;
11109
11110
2.89M
  switch (type) {
11111
0
    case FT_CHAR:
11112
1.71M
    case FT_UINT8:
11113
1.71M
    case FT_INT8:
11114
1.71M
      bitwidth = 8;
11115
1.71M
      break;
11116
623k
    case FT_UINT16:
11117
624k
    case FT_INT16:
11118
624k
      bitwidth = 16;
11119
624k
      break;
11120
29.5k
    case FT_UINT24:
11121
30.0k
    case FT_INT24:
11122
30.0k
      bitwidth = 24;
11123
30.0k
      break;
11124
391k
    case FT_UINT32:
11125
391k
    case FT_INT32:
11126
391k
      bitwidth = 32;
11127
391k
      break;
11128
120k
    case FT_UINT40:
11129
120k
    case FT_INT40:
11130
120k
      bitwidth = 40;
11131
120k
      break;
11132
3.84k
    case FT_UINT48:
11133
3.84k
    case FT_INT48:
11134
3.84k
      bitwidth = 48;
11135
3.84k
      break;
11136
720
    case FT_UINT56:
11137
720
    case FT_INT56:
11138
720
      bitwidth = 56;
11139
720
      break;
11140
4.51k
    case FT_UINT64:
11141
4.51k
    case FT_INT64:
11142
4.51k
      bitwidth = 64;
11143
4.51k
      break;
11144
0
    default:
11145
0
      DISSECTOR_ASSERT_NOT_REACHED();
11146
0
      ;
11147
2.89M
  }
11148
2.89M
  return bitwidth;
11149
2.89M
}
11150
11151
11152
static int
11153
hfinfo_container_bitwidth(const header_field_info *hfinfo)
11154
7.91M
{
11155
7.91M
  if (!hfinfo->bitmask) {
11156
0
    return 0;
11157
0
  }
11158
11159
7.91M
  if (hfinfo->type == FT_BOOLEAN) {
11160
5.36M
    return hfinfo->display; /* hacky? :) */
11161
5.36M
  }
11162
11163
2.55M
  return hfinfo_type_bitwidth(hfinfo->type);
11164
7.91M
}
11165
11166
static int
11167
hfinfo_hex_digits(const header_field_info *hfinfo)
11168
402k
{
11169
402k
  int bitwidth;
11170
11171
  /* If we have a bitmask, hfinfo->type is the width of the container, so not
11172
   * appropriate to determine the number of hex digits for the field.
11173
   * So instead, we compute it from the bitmask.
11174
   */
11175
402k
  if (hfinfo->bitmask != 0) {
11176
60.5k
    bitwidth = hfinfo_mask_bitwidth(hfinfo);
11177
341k
  } else {
11178
341k
    bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11179
341k
  }
11180
11181
  /* Divide by 4, rounding up, to get number of hex digits. */
11182
402k
  return (bitwidth + 3) / 4;
11183
402k
}
11184
11185
const char *
11186
hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11187
0
{
11188
0
  char *ptr = &buf[6];
11189
0
  static const char hex_digits[16] =
11190
0
  { '0', '1', '2', '3', '4', '5', '6', '7',
11191
0
    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11192
11193
0
  *ptr = '\0';
11194
0
  *(--ptr) = '\'';
11195
  /* Properly format value */
11196
0
  if (g_ascii_isprint(value)) {
11197
    /*
11198
     * Printable, so just show the character, and, if it needs
11199
     * to be escaped, escape it.
11200
     */
11201
0
    *(--ptr) = value;
11202
0
    if (value == '\\' || value == '\'')
11203
0
      *(--ptr) = '\\';
11204
0
  } else {
11205
    /*
11206
     * Non-printable; show it as an escape sequence.
11207
     */
11208
0
    switch (value) {
11209
11210
0
    case '\0':
11211
      /*
11212
       * Show a NUL with only one digit.
11213
       */
11214
0
      *(--ptr) = '0';
11215
0
      break;
11216
11217
0
    case '\a':
11218
0
    case '\b':
11219
0
    case '\f':
11220
0
    case '\n':
11221
0
    case '\r':
11222
0
    case '\t':
11223
0
    case '\v':
11224
0
      *(--ptr) = value - '\a' + 'a';
11225
0
      break;
11226
11227
0
    default:
11228
0
      switch (FIELD_DISPLAY(display)) {
11229
11230
0
      case BASE_OCT:
11231
0
        *(--ptr) = (value & 0x7) + '0';
11232
0
        value >>= 3;
11233
0
        *(--ptr) = (value & 0x7) + '0';
11234
0
        value >>= 3;
11235
0
        *(--ptr) = (value & 0x7) + '0';
11236
0
        break;
11237
11238
0
      case BASE_HEX:
11239
0
        *(--ptr) = hex_digits[value & 0x0F];
11240
0
        value >>= 4;
11241
0
        *(--ptr) = hex_digits[value & 0x0F];
11242
0
        *(--ptr) = 'x';
11243
0
        break;
11244
11245
0
      default:
11246
0
        REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display));
11247
0
      }
11248
0
    }
11249
0
    *(--ptr) = '\\';
11250
0
  }
11251
0
  *(--ptr) = '\'';
11252
0
  return ptr;
11253
0
}
11254
11255
static const char *
11256
hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH], uint32_t value)
11257
1.37M
{
11258
1.37M
  char *ptr = &buf[NUMBER_LABEL_LENGTH-1];
11259
1.37M
  bool isint = FT_IS_INT(hfinfo->type);
11260
11261
1.37M
  *ptr = '\0';
11262
  /* Properly format value */
11263
1.37M
  switch (FIELD_DISPLAY(display)) {
11264
979k
    case BASE_DEC:
11265
979k
      return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11266
11267
2.69k
    case BASE_DEC_HEX:
11268
2.69k
      *(--ptr) = ')';
11269
2.69k
      ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11270
2.69k
      *(--ptr) = '(';
11271
2.69k
      *(--ptr) = ' ';
11272
2.69k
      ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11273
2.69k
      return ptr;
11274
11275
1
    case BASE_OCT:
11276
1
      return oct_to_str_back(ptr, value);
11277
11278
327k
    case BASE_HEX:
11279
327k
      return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11280
11281
63.2k
    case BASE_HEX_DEC:
11282
63.2k
      *(--ptr) = ')';
11283
63.2k
      ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11284
63.2k
      *(--ptr) = '(';
11285
63.2k
      *(--ptr) = ' ';
11286
63.2k
      ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11287
63.2k
      return ptr;
11288
11289
0
    case BASE_PT_UDP:
11290
0
    case BASE_PT_TCP:
11291
0
    case BASE_PT_DCCP:
11292
0
    case BASE_PT_SCTP:
11293
0
      port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH,
11294
0
          display_to_port_type((field_display_e)display), value);
11295
0
      return buf;
11296
0
    case BASE_OUI:
11297
0
      {
11298
0
      uint8_t p_oui[3];
11299
0
      const char *manuf_name;
11300
11301
0
      p_oui[0] = value >> 16 & 0xFF;
11302
0
      p_oui[1] = value >> 8 & 0xFF;
11303
0
      p_oui[2] = value & 0xFF;
11304
11305
      /* Attempt an OUI lookup. */
11306
0
      manuf_name = uint_get_manuf_name_if_known(value);
11307
0
      if (manuf_name == NULL) {
11308
        /* Could not find an OUI. */
11309
0
        snprintf(buf, NUMBER_LABEL_LENGTH, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11310
0
      }
11311
0
      else {
11312
        /* Found an address string. */
11313
0
        snprintf(buf, NUMBER_LABEL_LENGTH, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11314
0
      }
11315
0
      return buf;
11316
0
      }
11317
11318
0
    default:
11319
0
      REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display));
11320
1.37M
  }
11321
0
  return ptr;
11322
1.37M
}
11323
11324
static const char *
11325
hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH], uint64_t value)
11326
8.70k
{
11327
8.70k
  char *ptr = &buf[NUMBER_LABEL_LENGTH-1];
11328
8.70k
  bool isint = FT_IS_INT(hfinfo->type);
11329
11330
8.70k
  *ptr = '\0';
11331
  /* Properly format value */
11332
8.70k
  switch (FIELD_DISPLAY(display)) {
11333
60
    case BASE_DEC:
11334
60
      return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11335
11336
0
    case BASE_DEC_HEX:
11337
0
      *(--ptr) = ')';
11338
0
      ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11339
0
      *(--ptr) = '(';
11340
0
      *(--ptr) = ' ';
11341
0
      ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11342
0
      return ptr;
11343
11344
0
    case BASE_OCT:
11345
0
      return oct64_to_str_back(ptr, value);
11346
11347
8.56k
    case BASE_HEX:
11348
8.56k
      return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11349
11350
73
    case BASE_HEX_DEC:
11351
73
      *(--ptr) = ')';
11352
73
      ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11353
73
      *(--ptr) = '(';
11354
73
      *(--ptr) = ' ';
11355
73
      ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11356
73
      return ptr;
11357
11358
0
    default:
11359
0
      REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display));
11360
8.70k
  }
11361
11362
0
  return ptr;
11363
8.70k
}
11364
11365
static const char *
11366
hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint32_t value)
11367
947k
{
11368
947k
  int display = hfinfo->display;
11369
11370
947k
  if (hfinfo->type == FT_FRAMENUM) {
11371
    /*
11372
     * Frame numbers are always displayed in decimal.
11373
     */
11374
0
    display = BASE_DEC;
11375
0
  }
11376
11377
947k
  return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11378
947k
}
11379
11380
static const char *
11381
hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint64_t value)
11382
8.70k
{
11383
8.70k
  int display = hfinfo->display;
11384
11385
8.70k
  if (hfinfo->type == FT_FRAMENUM) {
11386
    /*
11387
     * Frame numbers are always displayed in decimal.
11388
     */
11389
0
    display = BASE_DEC;
11390
0
  }
11391
11392
8.70k
  return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11393
8.70k
}
11394
11395
static const char *
11396
hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11397
0
{
11398
  /* Get the underlying BASE_ value */
11399
0
  int display = FIELD_DISPLAY(hfinfo->display);
11400
11401
0
  return hfinfo_char_value_format_display(display, buf, value);
11402
0
}
11403
11404
static const char *
11405
hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint32_t value)
11406
0
{
11407
  /* Get the underlying BASE_ value */
11408
0
  int display = FIELD_DISPLAY(hfinfo->display);
11409
11410
0
  if (hfinfo->type == FT_FRAMENUM) {
11411
    /*
11412
     * Frame numbers are always displayed in decimal.
11413
     */
11414
0
    display = BASE_DEC;
11415
0
  }
11416
11417
0
  if (IS_BASE_PORT(display)) {
11418
0
    display = BASE_DEC;
11419
0
  } else if (display == BASE_OUI) {
11420
0
    display = BASE_HEX;
11421
0
  }
11422
11423
0
  switch (display) {
11424
0
    case BASE_NONE:
11425
    /* case BASE_DEC: */
11426
0
    case BASE_DEC_HEX:
11427
0
    case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11428
0
    case BASE_CUSTOM:
11429
0
      display = BASE_DEC;
11430
0
      break;
11431
11432
    /* case BASE_HEX: */
11433
0
    case BASE_HEX_DEC:
11434
0
      display = BASE_HEX;
11435
0
      break;
11436
0
  }
11437
11438
0
  return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11439
0
}
11440
11441
static const char *
11442
hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint64_t value)
11443
0
{
11444
  /* Get the underlying BASE_ value */
11445
0
  int display = FIELD_DISPLAY(hfinfo->display);
11446
11447
0
  if (hfinfo->type == FT_FRAMENUM) {
11448
    /*
11449
     * Frame numbers are always displayed in decimal.
11450
     */
11451
0
    display = BASE_DEC;
11452
0
  }
11453
11454
0
  switch (display) {
11455
0
    case BASE_NONE:
11456
    /* case BASE_DEC: */
11457
0
    case BASE_DEC_HEX:
11458
0
    case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11459
0
    case BASE_CUSTOM:
11460
0
      display = BASE_DEC;
11461
0
      break;
11462
11463
    /* case BASE_HEX: */
11464
0
    case BASE_HEX_DEC:
11465
0
      display = BASE_HEX;
11466
0
      break;
11467
0
  }
11468
11469
0
  return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11470
0
}
11471
11472
static const char *
11473
hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11474
0
{
11475
  /* Get the underlying BASE_ value */
11476
0
  int display = FIELD_DISPLAY(hfinfo->display);
11477
11478
0
  return hfinfo_char_value_format_display(display, buf, value);
11479
0
}
11480
11481
static const char *
11482
hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint32_t value)
11483
425k
{
11484
  /* Get the underlying BASE_ value */
11485
425k
  int display = FIELD_DISPLAY(hfinfo->display);
11486
11487
425k
  if (display == BASE_NONE)
11488
73
    return NULL;
11489
11490
424k
  if (display == BASE_DEC_HEX)
11491
0
    display = BASE_DEC;
11492
424k
  if (display == BASE_HEX_DEC)
11493
6.54k
    display = BASE_HEX;
11494
11495
424k
  return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11496
425k
}
11497
11498
static const char *
11499
hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH], uint64_t value)
11500
0
{
11501
  /* Get the underlying BASE_ value */
11502
0
  int display = FIELD_DISPLAY(hfinfo->display);
11503
11504
0
  if (display == BASE_NONE)
11505
0
    return NULL;
11506
11507
0
  if (display == BASE_DEC_HEX)
11508
0
    display = BASE_DEC;
11509
0
  if (display == BASE_HEX_DEC)
11510
0
    display = BASE_HEX;
11511
11512
0
  return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11513
0
}
11514
11515
const char *
11516
proto_registrar_get_name(const int n)
11517
19.5k
{
11518
19.5k
  header_field_info *hfinfo;
11519
11520
19.5k
  PROTO_REGISTRAR_GET_NTH(n, hfinfo);
11521
19.5k
  return hfinfo->name;
11522
19.5k
}
11523
11524
const char *
11525
proto_registrar_get_abbrev(const int n)
11526
0
{
11527
0
  header_field_info *hfinfo;
11528
11529
0
  PROTO_REGISTRAR_GET_NTH(n, hfinfo);
11530
0
  return hfinfo->abbrev;
11531
0
}
11532
11533
enum ftenum
11534
proto_registrar_get_ftype(const int n)
11535
312
{
11536
312
  header_field_info *hfinfo;
11537
11538
312
  PROTO_REGISTRAR_GET_NTH(n, hfinfo);
11539
312
  return hfinfo->type;
11540
312
}
11541
11542
int
11543
proto_registrar_get_parent(const int n)
11544
0
{
11545
0
  header_field_info *hfinfo;
11546
11547
0
  PROTO_REGISTRAR_GET_NTH(n, hfinfo);
11548
0
  return hfinfo->parent;
11549
0
}
11550
11551
bool
11552
proto_registrar_is_protocol(const int n)
11553
0
{
11554
0
  header_field_info *hfinfo;
11555
11556
0
  PROTO_REGISTRAR_GET_NTH(n, hfinfo);
11557
0
  return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true : false);
11558
0
}
11559
11560
/* Returns length of field in packet (not necessarily the length
11561
 * in our internal representation, as in the case of IPv4).
11562
 * 0 means undeterminable at time of registration
11563
 * -1 means the field is not registered. */
11564
int
11565
proto_registrar_get_length(const int n)
11566
147
{
11567
147
  header_field_info *hfinfo;
11568
11569
147
  PROTO_REGISTRAR_GET_NTH(n, hfinfo);
11570
147
  return ftype_wire_size(hfinfo->type);
11571
147
}
11572
11573
size_t
11574
proto_registrar_get_count(struct proto_registrar_stats *stats)
11575
0
{
11576
0
  header_field_info *hfinfo;
11577
11578
  // Index zero is not used. We have to skip it.
11579
0
  size_t total_count = gpa_hfinfo.len - 1;
11580
0
  if (stats == NULL) {
11581
0
    return total_count;
11582
0
  }
11583
0
  for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11584
0
    if (gpa_hfinfo.hfi[id] == NULL) {
11585
0
      stats->deregistered_count++;
11586
0
      continue; /* This is a deregistered protocol or header field */
11587
0
    }
11588
11589
0
    PROTO_REGISTRAR_GET_NTH(id, hfinfo);
11590
11591
0
    if (proto_registrar_is_protocol(id))
11592
0
      stats->protocol_count++;
11593
11594
0
    if (hfinfo->same_name_prev_id != -1)
11595
0
      stats->same_name_count++;
11596
0
  }
11597
11598
0
  return total_count;
11599
0
}
11600
11601
/* Looks for a protocol or a field in a proto_tree. Returns true if
11602
 * it exists anywhere, or false if it exists nowhere. */
11603
bool
11604
proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11605
0
{
11606
0
  GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11607
11608
0
  if (g_ptr_array_len(ptrs) > 0) {
11609
0
    return true;
11610
0
  }
11611
0
  else {
11612
0
    return false;
11613
0
  }
11614
0
}
11615
11616
/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11617
 * This only works if the hfindex was "primed" before the dissection
11618
 * took place, as we just pass back the already-created GPtrArray*.
11619
 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11620
 * handles that. */
11621
GPtrArray *
11622
proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11623
280
{
11624
280
  if (!tree)
11625
0
    return NULL;
11626
11627
280
  if (PTREE_DATA(tree)->interesting_hfids != NULL)
11628
232
    return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)->interesting_hfids,
11629
232
             GINT_TO_POINTER(id));
11630
48
  else
11631
48
    return NULL;
11632
280
}
11633
11634
bool
11635
proto_tracking_interesting_fields(const proto_tree *tree)
11636
0
{
11637
0
  GHashTable *interesting_hfids;
11638
11639
0
  if (!tree)
11640
0
    return false;
11641
11642
0
  interesting_hfids = PTREE_DATA(tree)->interesting_hfids;
11643
11644
0
  return (interesting_hfids != NULL) && g_hash_table_size(interesting_hfids);
11645
0
}
11646
11647
/* Helper struct for proto_find_info() and  proto_all_finfos() */
11648
typedef struct {
11649
  GPtrArray *array;
11650
  int    id;
11651
} ffdata_t;
11652
11653
/* Helper function for proto_find_info() */
11654
static bool
11655
find_finfo(proto_node *node, void * data)
11656
0
{
11657
0
  field_info *fi = PNODE_FINFO(node);
11658
0
  if (fi && fi->hfinfo) {
11659
0
    if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11660
0
      g_ptr_array_add(((ffdata_t*)data)->array, fi);
11661
0
    }
11662
0
  }
11663
11664
  /* Don't stop traversing. */
11665
0
  return false;
11666
0
}
11667
11668
/* Helper function for proto_find_first_info() */
11669
static bool
11670
find_first_finfo(proto_node *node, void *data)
11671
0
{
11672
0
  field_info *fi = PNODE_FINFO(node);
11673
0
  if (fi && fi->hfinfo) {
11674
0
    if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11675
0
      g_ptr_array_add(((ffdata_t*)data)->array, fi);
11676
11677
      /* Stop traversing. */
11678
0
      return true;
11679
0
    }
11680
0
  }
11681
11682
  /* Continue traversing. */
11683
0
  return false;
11684
0
}
11685
11686
/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11687
* This works on any proto_tree, primed or unprimed, but actually searches
11688
* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11689
* The caller does need to free the returned GPtrArray with
11690
* g_ptr_array_free(<array>, true).
11691
*/
11692
GPtrArray *
11693
proto_find_finfo(proto_tree *tree, const int id)
11694
0
{
11695
0
  ffdata_t ffdata;
11696
11697
0
  ffdata.array = g_ptr_array_new();
11698
0
  ffdata.id = id;
11699
11700
0
  proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11701
11702
0
  return ffdata.array;
11703
0
}
11704
11705
/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11706
* This works on any proto_tree, primed or unprimed, but actually searches
11707
* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11708
* The caller does need to free the returned GPtrArray with
11709
* g_ptr_array_free(<array>, true).
11710
*/
11711
GPtrArray *
11712
proto_find_first_finfo(proto_tree *tree, const int id)
11713
0
{
11714
0
  ffdata_t ffdata;
11715
11716
0
  ffdata.array = g_ptr_array_new();
11717
0
  ffdata.id = id;
11718
11719
0
  proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11720
11721
0
  return ffdata.array;
11722
0
}
11723
11724
/* Helper function for proto_all_finfos() */
11725
static bool
11726
every_finfo(proto_node *node, void * data)
11727
0
{
11728
0
  field_info *fi = PNODE_FINFO(node);
11729
0
  if (fi && fi->hfinfo) {
11730
0
    g_ptr_array_add(((ffdata_t*)data)->array, fi);
11731
0
  }
11732
11733
  /* Don't stop traversing. */
11734
0
  return false;
11735
0
}
11736
11737
/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11738
 * The caller does need to free the returned GPtrArray with
11739
 * g_ptr_array_free(<array>, true).
11740
 */
11741
GPtrArray *
11742
proto_all_finfos(proto_tree *tree)
11743
0
{
11744
0
  ffdata_t ffdata;
11745
11746
  /* Pre allocate enough space to hold all fields in most cases */
11747
0
  ffdata.array = g_ptr_array_sized_new(512);
11748
0
  ffdata.id = 0;
11749
11750
0
  proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11751
11752
0
  return ffdata.array;
11753
0
}
11754
11755
11756
typedef struct {
11757
  unsigned      offset;
11758
  field_info *finfo;
11759
  tvbuff_t   *tvb;
11760
} offset_search_t;
11761
11762
static bool
11763
check_for_offset(proto_node *node, void * data)
11764
0
{
11765
0
  field_info  *fi        = PNODE_FINFO(node);
11766
0
  offset_search_t *offsearch = (offset_search_t *)data;
11767
11768
  /* !fi == the top most container node which holds nothing */
11769
0
  if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11770
0
    if (offsearch->offset >= (unsigned) fi->start &&
11771
0
        offsearch->offset < (unsigned) (fi->start + fi->length)) {
11772
11773
0
      offsearch->finfo = fi;
11774
0
      return false; /* keep traversing */
11775
0
    }
11776
0
  }
11777
0
  return false; /* keep traversing */
11778
0
}
11779
11780
/* Search a proto_tree backwards (from leaves to root) looking for the field
11781
 * whose start/length occupies 'offset' */
11782
/* XXX - I couldn't find an easy way to search backwards, so I search
11783
 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11784
 * the one I want to return to the user. This algorithm is inefficient
11785
 * and could be re-done, but I'd have to handle all the children and
11786
 * siblings of each node myself. When I have more time I'll do that.
11787
 * (yeah right) */
11788
field_info *
11789
proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11790
0
{
11791
0
  offset_search_t offsearch;
11792
11793
0
  offsearch.offset = offset;
11794
0
  offsearch.finfo  = NULL;
11795
0
  offsearch.tvb    = tvb;
11796
11797
0
  proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11798
11799
0
  return offsearch.finfo;
11800
0
}
11801
11802
typedef struct {
11803
  unsigned length;
11804
  char *buf;
11805
} decoded_data_t;
11806
11807
static bool
11808
check_for_undecoded(proto_node *node, void * data)
11809
0
{
11810
0
  field_info *fi = PNODE_FINFO(node);
11811
0
  decoded_data_t* decoded = (decoded_data_t*)data;
11812
0
  unsigned i;
11813
0
  unsigned byte;
11814
0
  unsigned bit;
11815
11816
0
  if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11817
0
    for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11818
0
      byte = i / 8;
11819
0
      bit = i % 8;
11820
0
      decoded->buf[byte] |= (1 << bit);
11821
0
    }
11822
0
  }
11823
11824
0
  return false;
11825
0
}
11826
11827
char*
11828
proto_find_undecoded_data(proto_tree *tree, unsigned length)
11829
0
{
11830
0
  decoded_data_t decoded;
11831
0
  decoded.length = length;
11832
0
  decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree), length / 8 + 1);
11833
11834
0
  proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11835
0
  return decoded.buf;
11836
0
}
11837
11838
/* Dumps the protocols in the registration database to stdout.  An independent
11839
 * program can take this output and format it into nice tables or HTML or
11840
 * whatever.
11841
 *
11842
 * There is one record per line. The fields are tab-delimited.
11843
 *
11844
 * Field 1 = protocol name
11845
 * Field 2 = protocol short name
11846
 * Field 3 = protocol filter name
11847
 * Field 4 = protocol enabled
11848
 * Field 5 = protocol enabled by default
11849
 * Field 6 = protocol can toggle
11850
 */
11851
void
11852
proto_registrar_dump_protocols(void)
11853
0
{
11854
0
  protocol_t *protocol;
11855
0
  int     i;
11856
0
  void     *cookie = NULL;
11857
11858
11859
0
  i = proto_get_first_protocol(&cookie);
11860
0
  while (i != -1) {
11861
0
    protocol = find_protocol_by_id(i);
11862
0
    printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11863
0
        protocol->name,
11864
0
        protocol->short_name,
11865
0
        protocol->filter_name,
11866
0
        (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11867
0
        (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11868
0
        (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11869
0
    i = proto_get_next_protocol(&cookie);
11870
0
  }
11871
0
}
11872
11873
/* Dumps the value_strings, extended value string headers, range_strings
11874
 * or true/false strings for fields that have them.
11875
 * There is one record per line. Fields are tab-delimited.
11876
 * There are four types of records: Value String, Extended Value String Header,
11877
 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11878
 * the type of record.
11879
 *
11880
 * Note that a record will be generated only if the value_string,... is referenced
11881
 * in a registered hfinfo entry.
11882
 *
11883
 *
11884
 * Value Strings
11885
 * -------------
11886
 * Field 1 = 'V'
11887
 * Field 2 = Field abbreviation to which this value string corresponds
11888
 * Field 3 = Integer value
11889
 * Field 4 = String
11890
 *
11891
 * Extended Value String Headers
11892
 * -----------------------------
11893
 * Field 1 = 'E'
11894
 * Field 2 = Field abbreviation to which this extended value string header corresponds
11895
 * Field 3 = Extended Value String "Name"
11896
 * Field 4 = Number of entries in the associated value_string array
11897
 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11898
 *
11899
 * Range Strings
11900
 * -------------
11901
 * Field 1 = 'R'
11902
 * Field 2 = Field abbreviation to which this range string corresponds
11903
 * Field 3 = Integer value: lower bound
11904
 * Field 4 = Integer value: upper bound
11905
 * Field 5 = String
11906
 *
11907
 * True/False Strings
11908
 * ------------------
11909
 * Field 1 = 'T'
11910
 * Field 2 = Field abbreviation to which this true/false string corresponds
11911
 * Field 3 = True String
11912
 * Field 4 = False String
11913
 */
11914
void
11915
proto_registrar_dump_values(void)
11916
0
{
11917
0
  header_field_info *hfinfo;
11918
0
  int     i, len, vi;
11919
0
  const value_string  *vals;
11920
0
  const val64_string  *vals64;
11921
0
  const range_string  *range;
11922
0
  const true_false_string *tfs;
11923
0
  const unit_name_string  *units;
11924
11925
0
  len = gpa_hfinfo.len;
11926
0
  for (i = 1; i < len ; i++) {
11927
0
    if (gpa_hfinfo.hfi[i] == NULL)
11928
0
      continue; /* This is a deregistered protocol or field */
11929
11930
0
    PROTO_REGISTRAR_GET_NTH(i, hfinfo);
11931
11932
0
    if (hfinfo->id == hf_text_only) {
11933
0
      continue;
11934
0
    }
11935
11936
    /* ignore protocols */
11937
0
    if (proto_registrar_is_protocol(i)) {
11938
0
      continue;
11939
0
    }
11940
    /* process header fields */
11941
#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11942
    /*
11943
     * If this field isn't at the head of the list of
11944
     * fields with this name, skip this field - all
11945
     * fields with the same name are really just versions
11946
     * of the same field stored in different bits, and
11947
     * should have the same type/radix/value list, and
11948
     * just differ in their bit masks.  (If a field isn't
11949
     * a bitfield, but can be, say, 1 or 2 bytes long,
11950
     * it can just be made FT_UINT16, meaning the
11951
     * *maximum* length is 2 bytes, and be used
11952
     * for all lengths.)
11953
     */
11954
    if (hfinfo->same_name_prev_id != -1)
11955
      continue;
11956
#endif
11957
0
    vals   = NULL;
11958
0
    vals64 = NULL;
11959
0
    range  = NULL;
11960
0
    tfs    = NULL;
11961
0
    units  = NULL;
11962
11963
0
    if (hfinfo->strings != NULL) {
11964
0
      if (FIELD_DISPLAY(hfinfo->display) != BASE_CUSTOM &&
11965
0
          (hfinfo->type == FT_CHAR  ||
11966
0
           hfinfo->type == FT_UINT8  ||
11967
0
           hfinfo->type == FT_UINT16 ||
11968
0
           hfinfo->type == FT_UINT24 ||
11969
0
           hfinfo->type == FT_UINT32 ||
11970
0
           hfinfo->type == FT_UINT40 ||
11971
0
           hfinfo->type == FT_UINT48 ||
11972
0
           hfinfo->type == FT_UINT56 ||
11973
0
           hfinfo->type == FT_UINT64 ||
11974
0
           hfinfo->type == FT_INT8   ||
11975
0
           hfinfo->type == FT_INT16  ||
11976
0
           hfinfo->type == FT_INT24  ||
11977
0
           hfinfo->type == FT_INT32  ||
11978
0
           hfinfo->type == FT_INT40  ||
11979
0
           hfinfo->type == FT_INT48  ||
11980
0
           hfinfo->type == FT_INT56  ||
11981
0
           hfinfo->type == FT_INT64  ||
11982
0
           hfinfo->type == FT_FLOAT  ||
11983
0
           hfinfo->type == FT_DOUBLE)) {
11984
11985
0
        if (hfinfo->display & BASE_RANGE_STRING) {
11986
0
          range = (const range_string *)hfinfo->strings;
11987
0
        } else if (hfinfo->display & BASE_EXT_STRING) {
11988
0
          if (hfinfo->display & BASE_VAL64_STRING) {
11989
0
            vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings);
11990
0
          } else {
11991
0
            vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings);
11992
0
          }
11993
0
        } else if (hfinfo->display & BASE_VAL64_STRING) {
11994
0
          vals64 = (const val64_string *)hfinfo->strings;
11995
0
        } else if (hfinfo->display & BASE_UNIT_STRING) {
11996
0
          units = (const unit_name_string *)hfinfo->strings;
11997
0
        } else {
11998
0
          vals = (const value_string *)hfinfo->strings;
11999
0
        }
12000
0
      }
12001
0
      else if (hfinfo->type == FT_BOOLEAN) {
12002
0
        tfs = (const struct true_false_string *)hfinfo->strings;
12003
0
      }
12004
0
    }
12005
12006
    /* Print value strings? */
12007
0
    if (vals) {
12008
0
      if (hfinfo->display & BASE_EXT_STRING) {
12009
0
        if (hfinfo->display & BASE_VAL64_STRING) {
12010
0
          val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12011
0
          if (!val64_string_ext_validate(vse_p)) {
12012
0
            ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev);
12013
0
            continue;
12014
0
          }
12015
0
          try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12016
0
          printf("E\t%s\t%u\t%s\t%s\n",
12017
0
                 hfinfo->abbrev,
12018
0
                 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p),
12019
0
                 VAL64_STRING_EXT_VS_NAME(vse_p),
12020
0
                 val64_string_ext_match_type_str(vse_p));
12021
0
        } else {
12022
0
          value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12023
0
          if (!value_string_ext_validate(vse_p)) {
12024
0
            ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev);
12025
0
            continue;
12026
0
          }
12027
0
          try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12028
0
          printf("E\t%s\t%u\t%s\t%s\n",
12029
0
                 hfinfo->abbrev,
12030
0
                 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p),
12031
0
                 VALUE_STRING_EXT_VS_NAME(vse_p),
12032
0
                 value_string_ext_match_type_str(vse_p));
12033
0
        }
12034
0
      }
12035
0
      vi = 0;
12036
0
      while (vals[vi].strptr) {
12037
        /* Print in the proper base */
12038
0
        if (hfinfo->type == FT_CHAR) {
12039
0
          if (g_ascii_isprint(vals[vi].value)) {
12040
0
            printf("V\t%s\t'%c'\t%s\n",
12041
0
                   hfinfo->abbrev,
12042
0
                   vals[vi].value,
12043
0
                   vals[vi].strptr);
12044
0
          } else {
12045
0
            if (hfinfo->display == BASE_HEX) {
12046
0
              printf("V\t%s\t'\\x%02x'\t%s\n",
12047
0
                     hfinfo->abbrev,
12048
0
                     vals[vi].value,
12049
0
                     vals[vi].strptr);
12050
0
            }
12051
0
            else {
12052
0
              printf("V\t%s\t'\\%03o'\t%s\n",
12053
0
                     hfinfo->abbrev,
12054
0
                     vals[vi].value,
12055
0
                     vals[vi].strptr);
12056
0
            }
12057
0
          }
12058
0
        } else {
12059
0
          if (hfinfo->display == BASE_HEX) {
12060
0
            printf("V\t%s\t0x%x\t%s\n",
12061
0
                   hfinfo->abbrev,
12062
0
                   vals[vi].value,
12063
0
                   vals[vi].strptr);
12064
0
          }
12065
0
          else {
12066
0
            printf("V\t%s\t%u\t%s\n",
12067
0
                   hfinfo->abbrev,
12068
0
                   vals[vi].value,
12069
0
                   vals[vi].strptr);
12070
0
          }
12071
0
        }
12072
0
        vi++;
12073
0
      }
12074
0
    }
12075
0
    else if (vals64) {
12076
0
      vi = 0;
12077
0
      while (vals64[vi].strptr) {
12078
0
        printf("V64\t%s\t%" PRIu64 "\t%s\n",
12079
0
               hfinfo->abbrev,
12080
0
               vals64[vi].value,
12081
0
               vals64[vi].strptr);
12082
0
        vi++;
12083
0
      }
12084
0
    }
12085
12086
    /* print range strings? */
12087
0
    else if (range) {
12088
0
      vi = 0;
12089
0
      while (range[vi].strptr) {
12090
        /* Print in the proper base */
12091
0
        if (FIELD_DISPLAY(hfinfo->display) == BASE_HEX) {
12092
0
          printf("R\t%s\t0x%"PRIx64"\t0x%"PRIx64"\t%s\n",
12093
0
                 hfinfo->abbrev,
12094
0
                 range[vi].value_min,
12095
0
                 range[vi].value_max,
12096
0
                 range[vi].strptr);
12097
0
        }
12098
0
        else {
12099
0
          printf("R\t%s\t%"PRIu64"\t%"PRIu64"\t%s\n",
12100
0
                 hfinfo->abbrev,
12101
0
                 range[vi].value_min,
12102
0
                 range[vi].value_max,
12103
0
                 range[vi].strptr);
12104
0
        }
12105
0
        vi++;
12106
0
      }
12107
0
    }
12108
12109
    /* Print true/false strings? */
12110
0
    else if (tfs) {
12111
0
      printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12112
0
             tfs->true_string, tfs->false_string);
12113
0
    }
12114
    /* Print unit strings? */
12115
0
    else if (units) {
12116
0
      printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12117
0
             units->singular, units->plural ? units->plural : "(no plural)");
12118
0
    }
12119
0
  }
12120
0
}
12121
12122
/* Prints the number of registered fields.
12123
 * Useful for determining an appropriate value for
12124
 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12125
 *
12126
 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12127
 * the number of fields, true otherwise.
12128
 */
12129
bool
12130
proto_registrar_dump_fieldcount(void)
12131
0
{
12132
0
  struct proto_registrar_stats stats = {0, 0, 0};
12133
0
  size_t total_count = proto_registrar_get_count(&stats);
12134
12135
0
  printf("There are %zu header fields registered, of which:\n"
12136
0
    "\t%zu are deregistered\n"
12137
0
    "\t%zu are protocols\n"
12138
0
    "\t%zu have the same name as another field\n\n",
12139
0
    total_count, stats.deregistered_count, stats.protocol_count,
12140
0
    stats.same_name_count);
12141
12142
0
  printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM,
12143
0
    (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM) ?
12144
0
        "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12145
0
        "\n");
12146
12147
0
  printf("The header field table consumes %u KiB of memory.\n",
12148
0
    (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12149
0
  printf("The fields themselves consume %u KiB of memory.\n",
12150
0
    (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12151
12152
0
  return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM);
12153
0
}
12154
12155
static void
12156
elastic_add_base_mapping(json_dumper *dumper)
12157
0
{
12158
0
  json_dumper_set_member_name(dumper, "index_patterns");
12159
0
  json_dumper_begin_array(dumper);
12160
  // The index names from write_json_index() in print.c
12161
0
  json_dumper_value_string(dumper, "packets-*");
12162
0
  json_dumper_end_array(dumper);
12163
12164
0
  json_dumper_set_member_name(dumper, "settings");
12165
0
  json_dumper_begin_object(dumper);
12166
0
  json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12167
0
  json_dumper_value_anyf(dumper, "%d", 1000000);
12168
0
  json_dumper_end_object(dumper);
12169
0
}
12170
12171
static char*
12172
ws_type_to_elastic(unsigned type)
12173
0
{
12174
0
  switch(type) {
12175
0
    case FT_INT8:
12176
0
      return "byte";
12177
0
    case FT_UINT8:
12178
0
    case FT_INT16:
12179
0
      return "short";
12180
0
    case FT_UINT16:
12181
0
    case FT_INT32:
12182
0
    case FT_UINT24:
12183
0
    case FT_INT24:
12184
0
      return "integer";
12185
0
    case FT_FRAMENUM:
12186
0
    case FT_UINT32:
12187
0
    case FT_UINT40:
12188
0
    case FT_UINT48:
12189
0
    case FT_UINT56:
12190
0
    case FT_INT40:
12191
0
    case FT_INT48:
12192
0
    case FT_INT56:
12193
0
    case FT_INT64:
12194
0
      return "long";
12195
0
    case FT_UINT64:
12196
0
      return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12197
0
    case FT_FLOAT:
12198
0
      return "float";
12199
0
    case FT_DOUBLE:
12200
0
    case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12201
0
      return "double";
12202
0
    case FT_IPv6:
12203
0
    case FT_IPv4:
12204
0
      return "ip";
12205
0
    case FT_ABSOLUTE_TIME:
12206
0
      return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12207
0
    case FT_BOOLEAN:
12208
0
      return "boolean";
12209
0
    default:
12210
0
      return NULL;
12211
0
  }
12212
0
}
12213
12214
static char*
12215
dot_to_underscore(char* str)
12216
0
{
12217
0
  unsigned i;
12218
0
  for (i = 0; i < strlen(str); i++) {
12219
0
    if (str[i] == '.')
12220
0
      str[i] = '_';
12221
0
  }
12222
0
  return str;
12223
0
}
12224
12225
/* Dumps a mapping file for ElasticSearch
12226
 * This is the v1 (legacy) _template API.
12227
 * At some point it may need to be updated with the composable templates
12228
 * introduced in Elasticsearch 7.8 (_index_template)
12229
 */
12230
void
12231
proto_registrar_dump_elastic(const char* filter)
12232
0
{
12233
0
  header_field_info *hfinfo;
12234
0
  header_field_info *parent_hfinfo;
12235
0
  unsigned i;
12236
0
  bool open_object = true;
12237
0
  const char* prev_proto = NULL;
12238
0
  char* str;
12239
0
  char** protos = NULL;
12240
0
  char* proto;
12241
0
  bool found;
12242
0
  unsigned j;
12243
0
  char* type;
12244
0
  char* prev_item = NULL;
12245
12246
  /* We have filtering protocols. Extract them. */
12247
0
  if (filter) {
12248
0
    protos = g_strsplit(filter, ",", -1);
12249
0
  }
12250
12251
  /*
12252
   * To help tracking down the json tree, objects have been appended with a comment:
12253
   * n.label -> where n is the indentation level and label the name of the object
12254
   */
12255
12256
0
  json_dumper dumper = {
12257
0
    .output_file = stdout,
12258
0
    .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT,
12259
0
  };
12260
0
  json_dumper_begin_object(&dumper); // 1.root
12261
0
  elastic_add_base_mapping(&dumper);
12262
12263
0
  json_dumper_set_member_name(&dumper, "mappings");
12264
0
  json_dumper_begin_object(&dumper); // 2.mappings
12265
12266
0
  json_dumper_set_member_name(&dumper, "properties");
12267
0
  json_dumper_begin_object(&dumper); // 3.properties
12268
0
  json_dumper_set_member_name(&dumper, "timestamp");
12269
0
  json_dumper_begin_object(&dumper); // 4.timestamp
12270
0
  json_dumper_set_member_name(&dumper, "type");
12271
0
  json_dumper_value_string(&dumper, "date");
12272
0
  json_dumper_end_object(&dumper); // 4.timestamp
12273
12274
0
  json_dumper_set_member_name(&dumper, "layers");
12275
0
  json_dumper_begin_object(&dumper); // 4.layers
12276
0
  json_dumper_set_member_name(&dumper, "properties");
12277
0
  json_dumper_begin_object(&dumper); // 5.properties
12278
12279
0
  for (i = 1; i < gpa_hfinfo.len; i++) {
12280
0
    if (gpa_hfinfo.hfi[i] == NULL)
12281
0
      continue; /* This is a deregistered protocol or header field */
12282
12283
0
    PROTO_REGISTRAR_GET_NTH(i, hfinfo);
12284
12285
    /*
12286
     * Skip the pseudo-field for "proto_tree_add_text()" since
12287
     * we don't want it in the list of filterable protocols.
12288
     */
12289
0
    if (hfinfo->id == hf_text_only)
12290
0
      continue;
12291
12292
0
    if (!proto_registrar_is_protocol(i)) {
12293
0
      PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
12294
12295
      /*
12296
       * Skip the field if filter protocols have been set and this one's
12297
       * parent is not listed.
12298
       */
12299
0
      if (protos) {
12300
0
        found = false;
12301
0
        j = 0;
12302
0
        proto = protos[0];
12303
0
        while(proto) {
12304
0
          if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12305
0
            found = true;
12306
0
            break;
12307
0
          }
12308
0
          j++;
12309
0
          proto = protos[j];
12310
0
        }
12311
0
        if (!found)
12312
0
          continue;
12313
0
      }
12314
12315
0
      if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12316
0
        json_dumper_end_object(&dumper); // 7.properties
12317
0
        json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12318
0
        open_object = true;
12319
0
      }
12320
12321
0
      prev_proto = parent_hfinfo->abbrev;
12322
12323
0
      if (open_object) {
12324
0
        json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12325
0
        json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12326
0
        json_dumper_set_member_name(&dumper, "properties");
12327
0
        json_dumper_begin_object(&dumper); // 7.properties
12328
0
        open_object = false;
12329
0
      }
12330
      /* Skip the fields that would map into string. This is the default in elasticsearch. */
12331
0
      type = ws_type_to_elastic(hfinfo->type);
12332
      /* when type is NULL, we have the default mapping: string */
12333
0
      if (type) {
12334
0
        str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev);
12335
0
        dot_to_underscore(str);
12336
0
        if (g_strcmp0(prev_item, str)) {
12337
0
          json_dumper_set_member_name(&dumper, str);
12338
0
          json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12339
0
          json_dumper_set_member_name(&dumper, "type");
12340
0
          json_dumper_value_string(&dumper, type);
12341
0
          json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12342
0
        }
12343
0
        g_free(prev_item);
12344
0
        prev_item = str;
12345
0
      }
12346
0
    }
12347
0
  }
12348
0
  g_free(prev_item);
12349
12350
0
  if (prev_proto) {
12351
0
    json_dumper_end_object(&dumper); // 7.properties
12352
0
    json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12353
0
  }
12354
12355
0
  json_dumper_end_object(&dumper); // 5.properties
12356
0
  json_dumper_end_object(&dumper); // 4.layers
12357
0
  json_dumper_end_object(&dumper); // 3.properties
12358
0
  json_dumper_end_object(&dumper); // 2.mappings
12359
0
  json_dumper_end_object(&dumper); // 1.root
12360
0
  bool ret = json_dumper_finish(&dumper);
12361
0
  DISSECTOR_ASSERT(ret);
12362
12363
0
  g_strfreev(protos);
12364
0
}
12365
12366
/* Dumps the contents of the registration database to stdout. An independent
12367
 * program can take this output and format it into nice tables or HTML or
12368
 * whatever.
12369
 *
12370
 * There is one record per line. Each record is either a protocol or a header
12371
 * field, differentiated by the first field. The fields are tab-delimited.
12372
 *
12373
 * Protocols
12374
 * ---------
12375
 * Field 1 = 'P'
12376
 * Field 2 = descriptive protocol name
12377
 * Field 3 = protocol abbreviation
12378
 *
12379
 * Header Fields
12380
 * -------------
12381
 * Field 1 = 'F'
12382
 * Field 2 = descriptive field name
12383
 * Field 3 = field abbreviation
12384
 * Field 4 = type ( textual representation of the ftenum type )
12385
 * Field 5 = parent protocol abbreviation
12386
 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12387
 * Field 7 = bitmask: format: hex: 0x....
12388
 * Field 8 = blurb describing field
12389
 */
12390
void
12391
proto_registrar_dump_fields(void)
12392
0
{
12393
0
  header_field_info *hfinfo, *parent_hfinfo;
12394
0
  int      i, len;
12395
0
  const char    *enum_name;
12396
0
  const char    *base_name;
12397
0
  const char    *blurb;
12398
0
  char       width[5];
12399
12400
0
  len = gpa_hfinfo.len;
12401
0
  for (i = 1; i < len ; i++) {
12402
0
    if (gpa_hfinfo.hfi[i] == NULL)
12403
0
      continue; /* This is a deregistered protocol or header field */
12404
12405
0
    PROTO_REGISTRAR_GET_NTH(i, hfinfo);
12406
12407
    /*
12408
     * Skip the pseudo-field for "proto_tree_add_text()" since
12409
     * we don't want it in the list of filterable fields.
12410
     */
12411
0
    if (hfinfo->id == hf_text_only)
12412
0
      continue;
12413
12414
    /* format for protocols */
12415
0
    if (proto_registrar_is_protocol(i)) {
12416
0
      printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12417
0
    }
12418
    /* format for header fields */
12419
0
    else {
12420
      /*
12421
       * If this field isn't at the head of the list of
12422
       * fields with this name, skip this field - all
12423
       * fields with the same name are really just versions
12424
       * of the same field stored in different bits, and
12425
       * should have the same type/radix/value list, and
12426
       * just differ in their bit masks.  (If a field isn't
12427
       * a bitfield, but can be, say, 1 or 2 bytes long,
12428
       * it can just be made FT_UINT16, meaning the
12429
       * *maximum* length is 2 bytes, and be used
12430
       * for all lengths.)
12431
       */
12432
0
      if (hfinfo->same_name_prev_id != -1)
12433
0
        continue;
12434
12435
0
      PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo);
12436
12437
0
      enum_name = ftype_name(hfinfo->type);
12438
0
      base_name = "";
12439
12440
0
      if (hfinfo->type == FT_CHAR  ||
12441
0
          hfinfo->type == FT_UINT8  ||
12442
0
          hfinfo->type == FT_UINT16 ||
12443
0
          hfinfo->type == FT_UINT24 ||
12444
0
          hfinfo->type == FT_UINT32 ||
12445
0
          hfinfo->type == FT_UINT40 ||
12446
0
          hfinfo->type == FT_UINT48 ||
12447
0
          hfinfo->type == FT_UINT56 ||
12448
0
          hfinfo->type == FT_UINT64 ||
12449
0
          hfinfo->type == FT_INT8   ||
12450
0
          hfinfo->type == FT_INT16  ||
12451
0
          hfinfo->type == FT_INT24  ||
12452
0
          hfinfo->type == FT_INT32  ||
12453
0
          hfinfo->type == FT_INT40 ||
12454
0
          hfinfo->type == FT_INT48 ||
12455
0
          hfinfo->type == FT_INT56 ||
12456
0
          hfinfo->type == FT_INT64) {
12457
12458
0
        switch (FIELD_DISPLAY(hfinfo->display)) {
12459
0
          case BASE_NONE:
12460
0
          case BASE_DEC:
12461
0
          case BASE_HEX:
12462
0
          case BASE_OCT:
12463
0
          case BASE_DEC_HEX:
12464
0
          case BASE_HEX_DEC:
12465
0
          case BASE_CUSTOM:
12466
0
          case BASE_PT_UDP:
12467
0
          case BASE_PT_TCP:
12468
0
          case BASE_PT_DCCP:
12469
0
          case BASE_PT_SCTP:
12470
0
          case BASE_OUI:
12471
0
            base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display), hf_display, "????");
12472
0
            break;
12473
0
          default:
12474
0
            base_name = "????";
12475
0
            break;
12476
0
        }
12477
0
      } else if (hfinfo->type == FT_BOOLEAN) {
12478
        /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12479
0
        snprintf(width, sizeof(width), "%d", hfinfo->display);
12480
0
        base_name = width;
12481
0
      }
12482
12483
0
      blurb = hfinfo->blurb;
12484
0
      if (blurb == NULL)
12485
0
        blurb = "";
12486
0
      else if (strlen(blurb) == 0)
12487
0
        blurb = "\"\"";
12488
12489
0
      printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64 "\t%s\n",
12490
0
        hfinfo->name, hfinfo->abbrev, enum_name,
12491
0
        parent_hfinfo->abbrev, base_name,
12492
0
        hfinfo->bitmask, blurb);
12493
0
    }
12494
0
  }
12495
0
}
12496
12497
/* Dumps all abbreviated field and protocol completions of the given string to
12498
 * stdout.  An independent program may use this for command-line tab completion
12499
 * of fields.
12500
 */
12501
bool
12502
proto_registrar_dump_field_completions(const char *prefix)
12503
0
{
12504
0
  header_field_info *hfinfo;
12505
0
  int      i, len;
12506
0
  size_t       prefix_len;
12507
0
  bool     matched = false;
12508
12509
0
  prefix_len = strlen(prefix);
12510
0
  len = gpa_hfinfo.len;
12511
0
  for (i = 1; i < len ; i++) {
12512
0
    if (gpa_hfinfo.hfi[i] == NULL)
12513
0
      continue; /* This is a deregistered protocol or header field */
12514
12515
0
    PROTO_REGISTRAR_GET_NTH(i, hfinfo);
12516
12517
    /*
12518
     * Skip the pseudo-field for "proto_tree_add_text()" since
12519
     * we don't want it in the list of filterable fields.
12520
     */
12521
0
    if (hfinfo->id == hf_text_only)
12522
0
      continue;
12523
12524
    /* format for protocols */
12525
0
    if (proto_registrar_is_protocol(i)) {
12526
0
      if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12527
0
        matched = true;
12528
0
        printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12529
0
      }
12530
0
    }
12531
    /* format for header fields */
12532
0
    else {
12533
      /*
12534
       * If this field isn't at the head of the list of
12535
       * fields with this name, skip this field - all
12536
       * fields with the same name are really just versions
12537
       * of the same field stored in different bits, and
12538
       * should have the same type/radix/value list, and
12539
       * just differ in their bit masks.  (If a field isn't
12540
       * a bitfield, but can be, say, 1 or 2 bytes long,
12541
       * it can just be made FT_UINT16, meaning the
12542
       * *maximum* length is 2 bytes, and be used
12543
       * for all lengths.)
12544
       */
12545
0
      if (hfinfo->same_name_prev_id != -1)
12546
0
        continue;
12547
12548
0
      if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12549
0
        matched = true;
12550
0
        printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12551
0
      }
12552
0
    }
12553
0
  }
12554
0
  return matched;
12555
0
}
12556
12557
/* Dumps field types and descriptive names to stdout. An independent
12558
 * program can take this output and format it into nice tables or HTML or
12559
 * whatever.
12560
 *
12561
 * There is one record per line. The fields are tab-delimited.
12562
 *
12563
 * Field 1 = field type name, e.g. FT_UINT8
12564
 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12565
 */
12566
void
12567
proto_registrar_dump_ftypes(void)
12568
0
{
12569
0
  int fte;
12570
12571
0
  for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12572
0
    printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12573
0
  }
12574
0
}
12575
12576
/* This function indicates whether it's possible to construct a
12577
 * "match selected" display filter string for the specified field,
12578
 * returns an indication of whether it's possible, and, if it's
12579
 * possible and "filter" is non-null, constructs the filter and
12580
 * sets "*filter" to point to it.
12581
 * You do not need to [g_]free() this string since it will be automatically
12582
 * freed once the next packet is dissected.
12583
 */
12584
static bool
12585
construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12586
        char **filter)
12587
0
{
12588
0
  const header_field_info *hfinfo;
12589
0
  int      start, length, length_remaining;
12590
12591
0
  if (!finfo)
12592
0
    return false;
12593
12594
0
  hfinfo     = finfo->hfinfo;
12595
0
  DISSECTOR_ASSERT(hfinfo);
12596
12597
  /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12598
   * then "the numeric value ... is not used when preparing
12599
   * filters for the field in question." If it's any other
12600
   * base, we'll generate the filter normally (which will
12601
   * be numeric, even though the human-readable string does
12602
   * work for filtering.)
12603
   *
12604
   * XXX - It might be nice to use fvalue_to_string_repr() in
12605
   * "proto_item_fill_label()" as well, although, there, you'd
12606
   * have to deal with the base *and* with resolved values for
12607
   * addresses.
12608
   *
12609
   * Perhaps in addition to taking the repr type (DISPLAY
12610
   * or DFILTER) and the display (base), fvalue_to_string_repr()
12611
   * should have the the "strings" values in the header_field_info
12612
   * structure for the field as a parameter, so it can have
12613
   * if the field is Boolean or an enumerated integer type,
12614
   * the tables used to generate human-readable values.
12615
   */
12616
0
  if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display) == BASE_NONE) {
12617
0
    const char *str = NULL;
12618
12619
0
    switch (hfinfo->type) {
12620
12621
0
    case FT_INT8:
12622
0
    case FT_INT16:
12623
0
    case FT_INT24:
12624
0
    case FT_INT32:
12625
0
      str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12626
0
      break;
12627
12628
0
    case FT_CHAR:
12629
0
    case FT_UINT8:
12630
0
    case FT_UINT16:
12631
0
    case FT_UINT24:
12632
0
    case FT_UINT32:
12633
0
      str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12634
0
      break;
12635
12636
0
    default:
12637
0
      break;
12638
0
    }
12639
12640
0
    if (str != NULL && filter != NULL) {
12641
0
      *filter = wmem_strdup_printf(NULL, "%s == \"%s\"", hfinfo->abbrev, str);
12642
0
      return true;
12643
0
    }
12644
0
  }
12645
12646
0
  switch (hfinfo->type) {
12647
12648
0
    case FT_PROTOCOL:
12649
0
      if (filter != NULL)
12650
0
        *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
12651
0
      break;
12652
12653
0
    case FT_NONE:
12654
      /*
12655
       * If the length is 0, just match the name of the
12656
       * field.
12657
       *
12658
       * (Also check for negative values, just in case,
12659
       * as we'll cast it to an unsigned value later.)
12660
       */
12661
0
      length = finfo->length;
12662
0
      if (length == 0) {
12663
0
        if (filter != NULL)
12664
0
          *filter = wmem_strdup(NULL, finfo->hfinfo->abbrev);
12665
0
        break;
12666
0
      }
12667
0
      if (length < 0)
12668
0
        return false;
12669
12670
      /*
12671
       * This doesn't have a value, so we'd match
12672
       * on the raw bytes at this address.
12673
       *
12674
       * Should we be allowed to access to the raw bytes?
12675
       * If "edt" is NULL, the answer is "no".
12676
       */
12677
0
      if (edt == NULL)
12678
0
        return false;
12679
12680
      /*
12681
       * Is this field part of the raw frame tvbuff?
12682
       * If not, we can't use "frame[N:M]" to match
12683
       * it.
12684
       *
12685
       * XXX - should this be frame-relative, or
12686
       * protocol-relative?
12687
       *
12688
       * XXX - does this fallback for non-registered
12689
       * fields even make sense?
12690
       */
12691
0
      if (finfo->ds_tvb != edt->tvb)
12692
0
        return false; /* you lose */
12693
12694
      /*
12695
       * Don't go past the end of that tvbuff.
12696
       */
12697
0
      length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12698
0
      if (length > length_remaining)
12699
0
        length = length_remaining;
12700
0
      if (length <= 0)
12701
0
        return false;
12702
12703
0
      if (filter != NULL) {
12704
0
        start = finfo->start;
12705
0
        char *str = bytes_to_dfilter_repr(NULL, tvb_get_ptr(finfo->ds_tvb, start, length), length);
12706
0
        *filter = wmem_strdup_printf(NULL, "frame[%d:%d] == %s", finfo->start, length, str);
12707
0
        wmem_free(NULL, str);
12708
0
      }
12709
0
      break;
12710
12711
    /* By default, use the fvalue's "to_string_repr" method. */
12712
0
    default:
12713
0
      if (filter != NULL) {
12714
0
        char *str = fvalue_to_string_repr(NULL, finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12715
0
        *filter = wmem_strdup_printf(NULL, "%s == %s", hfinfo->abbrev, str);
12716
0
        wmem_free(NULL, str);
12717
0
      }
12718
0
      break;
12719
0
  }
12720
12721
0
  return true;
12722
0
}
12723
12724
/*
12725
 * Returns true if we can do a "match selected" on the field, false
12726
 * otherwise.
12727
 */
12728
bool
12729
proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12730
0
{
12731
0
  return construct_match_selected_string(finfo, edt, NULL);
12732
0
}
12733
12734
/* This function attempts to construct a "match selected" display filter
12735
 * string for the specified field; if it can do so, it returns a pointer
12736
 * to the string, otherwise it returns NULL.
12737
 *
12738
 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12739
 */
12740
char *
12741
proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12742
0
{
12743
0
  char *filter = NULL;
12744
12745
0
  if (!construct_match_selected_string(finfo, edt, &filter))
12746
0
  {
12747
0
    wmem_free(NULL, filter);
12748
0
    return NULL;
12749
0
  }
12750
0
  return filter;
12751
0
}
12752
12753
/* This function is common code for all proto_tree_add_bitmask... functions.
12754
 */
12755
12756
static bool
12757
proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12758
          const int len, const int ett, int * const *fields,
12759
          const int flags, bool first,
12760
          bool use_parent_tree,
12761
          proto_tree* tree, uint64_t value)
12762
1.98M
{
12763
1.98M
  uint64_t           available_bits = UINT64_MAX;
12764
1.98M
  uint64_t           bitmask = 0;
12765
1.98M
  uint64_t           tmpval;
12766
1.98M
  header_field_info *hf;
12767
1.98M
  uint32_t           integer32;
12768
1.98M
  int                bit_offset;
12769
1.98M
  int                no_of_bits;
12770
12771
1.98M
  if (!*fields)
12772
1.98M
    REPORT_DISSECTOR_BUG("Illegal call of proto_item_add_bitmask_tree without fields");
12773
12774
1.98M
  if (len < 0 || len > 8)
12775
1.98M
    REPORT_DISSECTOR_BUG("Invalid len: %d", len);
12776
  /**
12777
   * packet-frame.c uses len=0 since the value is taken from the packet
12778
   * metadata, not the packet bytes. In that case, assume that all bits
12779
   * in the provided value are valid.
12780
   */
12781
1.98M
  if (len > 0) {
12782
1.96M
    available_bits >>= (8 - (unsigned)len)*8;
12783
1.96M
  }
12784
12785
1.98M
  if (use_parent_tree == false)
12786
1.91M
    tree = proto_item_add_subtree(item, ett);
12787
12788
12.5M
  while (*fields) {
12789
10.5M
    uint64_t present_bits;
12790
10.5M
    PROTO_REGISTRAR_GET_NTH(**fields,hf);
12791
10.5M
    DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev);
12792
12793
10.5M
    bitmask |= hf->bitmask;
12794
12795
    /* Skip fields that aren't fully present */
12796
10.5M
    present_bits = available_bits & hf->bitmask;
12797
10.5M
    if (present_bits != hf->bitmask) {
12798
4.88k
      fields++;
12799
4.88k
      continue;
12800
4.88k
    }
12801
12802
10.5M
    switch (hf->type) {
12803
0
    case FT_CHAR:
12804
850k
    case FT_UINT8:
12805
1.04M
    case FT_UINT16:
12806
1.05M
    case FT_UINT24:
12807
1.11M
    case FT_UINT32:
12808
1.11M
      proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12809
1.11M
      break;
12810
12811
0
    case FT_INT8:
12812
68
    case FT_INT16:
12813
68
    case FT_INT24:
12814
68
    case FT_INT32:
12815
68
      proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12816
68
      break;
12817
12818
114k
    case FT_UINT40:
12819
118k
    case FT_UINT48:
12820
119k
    case FT_UINT56:
12821
123k
    case FT_UINT64:
12822
123k
      proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12823
123k
      break;
12824
12825
0
    case FT_INT40:
12826
0
    case FT_INT48:
12827
0
    case FT_INT56:
12828
0
    case FT_INT64:
12829
0
      proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12830
0
      break;
12831
12832
9.31M
    case FT_BOOLEAN:
12833
9.31M
      proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12834
9.31M
      break;
12835
12836
0
    default:
12837
0
      REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()",
12838
0
               hf->abbrev,
12839
0
               hf->type,
12840
0
               ftype_name(hf->type));
12841
0
      break;
12842
10.5M
    }
12843
10.5M
    if (flags & BMT_NO_APPEND) {
12844
695k
      fields++;
12845
695k
      continue;
12846
695k
    }
12847
9.85M
    tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12848
12849
    /* XXX: README.developer and the comments have always defined
12850
     * BMT_NO_INT as "only boolean flags are added to the title /
12851
     * don't add non-boolean (integral) fields", but the
12852
     * implementation has always added BASE_CUSTOM and fields with
12853
     * value_strings, though not fields with unit_strings.
12854
     * Possibly this is because some dissectors use a FT_UINT8
12855
     * with a value_string for fields that should be a FT_BOOLEAN.
12856
     */
12857
9.85M
    switch (hf->type) {
12858
0
    case FT_CHAR:
12859
0
      if (hf->display == BASE_CUSTOM) {
12860
0
        char lbl[ITEM_LABEL_LENGTH];
12861
0
        const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12862
12863
0
        DISSECTOR_ASSERT(fmtfunc);
12864
0
        fmtfunc(lbl, (uint32_t) tmpval);
12865
0
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12866
0
            hf->name, lbl);
12867
0
        first = false;
12868
0
      }
12869
0
      else if (hf->strings) {
12870
0
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12871
0
                   hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12872
0
        first = false;
12873
0
      }
12874
0
      else if (!(flags & BMT_NO_INT)) {
12875
0
        char buf[32];
12876
0
        const char *out;
12877
12878
0
        if (!first) {
12879
0
          proto_item_append_text(item, ", ");
12880
0
        }
12881
12882
0
        out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12883
0
        proto_item_append_text(item, "%s: %s", hf->name, out);
12884
0
        first = false;
12885
0
      }
12886
12887
0
      break;
12888
12889
824k
    case FT_UINT8:
12890
973k
    case FT_UINT16:
12891
976k
    case FT_UINT24:
12892
980k
    case FT_UINT32:
12893
980k
      if (hf->display == BASE_CUSTOM) {
12894
1.29k
        char lbl[ITEM_LABEL_LENGTH];
12895
1.29k
        const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12896
12897
1.29k
        DISSECTOR_ASSERT(fmtfunc);
12898
1.29k
        fmtfunc(lbl, (uint32_t) tmpval);
12899
1.29k
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12900
1.29k
            hf->name, lbl);
12901
1.29k
        first = false;
12902
1.29k
      }
12903
979k
      else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING|BASE_SPECIAL_VALS)))) {
12904
336k
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12905
336k
                    hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12906
336k
        first = false;
12907
336k
      }
12908
643k
      else if (!(flags & BMT_NO_INT)) {
12909
2.66k
        char buf[NUMBER_LABEL_LENGTH];
12910
2.66k
        const char *out = NULL;
12911
12912
2.66k
        if (!first) {
12913
2.62k
          proto_item_append_text(item, ", ");
12914
2.62k
        }
12915
12916
2.66k
        if (hf->strings && hf->display & BASE_SPECIAL_VALS) {
12917
0
          out = hf_try_val_to_str((uint32_t) tmpval, hf);
12918
0
        }
12919
2.66k
        if (out == NULL) {
12920
2.66k
          out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12921
2.66k
        }
12922
2.66k
        proto_item_append_text(item, "%s: %s", hf->name, out);
12923
2.66k
        if (hf->strings && hf->display & BASE_UNIT_STRING) {
12924
0
          proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12925
0
        }
12926
2.66k
        first = false;
12927
2.66k
      }
12928
12929
980k
      break;
12930
12931
0
    case FT_INT8:
12932
68
    case FT_INT16:
12933
68
    case FT_INT24:
12934
68
    case FT_INT32:
12935
68
      integer32 = (uint32_t) tmpval;
12936
68
      if (hf->bitmask) {
12937
68
        no_of_bits = ws_count_ones(hf->bitmask);
12938
68
        integer32 = ws_sign_ext32(integer32, no_of_bits);
12939
68
      }
12940
68
      if (hf->display == BASE_CUSTOM) {
12941
0
        char lbl[ITEM_LABEL_LENGTH];
12942
0
        const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12943
12944
0
        DISSECTOR_ASSERT(fmtfunc);
12945
0
        fmtfunc(lbl, (int32_t) integer32);
12946
0
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12947
0
            hf->name, lbl);
12948
0
        first = false;
12949
0
      }
12950
68
      else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING|BASE_SPECIAL_VALS)))) {
12951
0
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12952
0
            hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12953
0
        first = false;
12954
0
      }
12955
68
      else if (!(flags & BMT_NO_INT)) {
12956
66
        char buf[NUMBER_LABEL_LENGTH];
12957
66
        const char *out = NULL;
12958
12959
66
        if (!first) {
12960
66
          proto_item_append_text(item, ", ");
12961
66
        }
12962
12963
66
        if (hf->strings && hf->display & BASE_SPECIAL_VALS) {
12964
0
          out = hf_try_val_to_str((int32_t) integer32, hf);
12965
0
        }
12966
66
        if (out == NULL) {
12967
66
          out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12968
66
        }
12969
66
        proto_item_append_text(item, "%s: %s", hf->name, out);
12970
66
        if (hf->strings && hf->display & BASE_UNIT_STRING) {
12971
66
          proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12972
66
        }
12973
66
        first = false;
12974
66
      }
12975
12976
68
      break;
12977
12978
73.7k
    case FT_UINT40:
12979
73.7k
    case FT_UINT48:
12980
73.7k
    case FT_UINT56:
12981
73.7k
    case FT_UINT64:
12982
73.7k
      if (hf->display == BASE_CUSTOM) {
12983
39.6k
        char lbl[ITEM_LABEL_LENGTH];
12984
39.6k
        const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12985
12986
39.6k
        DISSECTOR_ASSERT(fmtfunc);
12987
39.6k
        fmtfunc(lbl, tmpval);
12988
39.6k
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12989
39.6k
            hf->name, lbl);
12990
39.6k
        first = false;
12991
39.6k
      }
12992
34.0k
      else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING|BASE_SPECIAL_VALS)))) {
12993
0
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12994
0
            hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12995
0
        first = false;
12996
0
      }
12997
34.0k
      else if (!(flags & BMT_NO_INT)) {
12998
0
        char buf[NUMBER_LABEL_LENGTH];
12999
0
        const char *out = NULL;
13000
13001
0
        if (!first) {
13002
0
          proto_item_append_text(item, ", ");
13003
0
        }
13004
13005
0
        if (hf->strings && hf->display & BASE_SPECIAL_VALS) {
13006
0
          out = hf_try_val64_to_str(tmpval, hf);
13007
0
        }
13008
0
        if (out == NULL) {
13009
0
          out = hfinfo_number_value_format64(hf, buf, tmpval);
13010
0
        }
13011
0
        proto_item_append_text(item, "%s: %s", hf->name, out);
13012
0
        if (hf->strings && hf->display & BASE_UNIT_STRING) {
13013
0
          proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13014
0
        }
13015
0
        first = false;
13016
0
      }
13017
13018
73.7k
      break;
13019
13020
0
    case FT_INT40:
13021
0
    case FT_INT48:
13022
0
    case FT_INT56:
13023
0
    case FT_INT64:
13024
0
      if (hf->bitmask) {
13025
0
        no_of_bits = ws_count_ones(hf->bitmask);
13026
0
        tmpval = ws_sign_ext64(tmpval, no_of_bits);
13027
0
      }
13028
0
      if (hf->display == BASE_CUSTOM) {
13029
0
        char lbl[ITEM_LABEL_LENGTH];
13030
0
        const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13031
13032
0
        DISSECTOR_ASSERT(fmtfunc);
13033
0
        fmtfunc(lbl, (int64_t) tmpval);
13034
0
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13035
0
            hf->name, lbl);
13036
0
        first = false;
13037
0
      }
13038
0
      else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING|BASE_SPECIAL_VALS)))) {
13039
0
        proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13040
0
            hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13041
0
        first = false;
13042
0
      }
13043
0
      else if (!(flags & BMT_NO_INT)) {
13044
0
        char buf[NUMBER_LABEL_LENGTH];
13045
0
        const char *out = NULL;
13046
13047
0
        if (!first) {
13048
0
          proto_item_append_text(item, ", ");
13049
0
        }
13050
13051
0
        if (hf->strings && hf->display & BASE_SPECIAL_VALS) {
13052
0
          out = hf_try_val64_to_str((int64_t) tmpval, hf);
13053
0
        }
13054
0
        if (out == NULL) {
13055
0
          out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13056
0
        }
13057
0
        proto_item_append_text(item, "%s: %s", hf->name, out);
13058
0
        if (hf->strings && hf->display & BASE_UNIT_STRING) {
13059
0
          proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13060
0
        }
13061
0
        first = false;
13062
0
      }
13063
13064
0
      break;
13065
13066
8.79M
    case FT_BOOLEAN:
13067
8.79M
      if (hf->strings && !(flags & BMT_NO_TFS)) {
13068
        /* If we have true/false strings, emit full - otherwise messages
13069
           might look weird */
13070
44.9k
        const struct true_false_string *tfs =
13071
44.9k
          (const struct true_false_string *)hf->strings;
13072
13073
44.9k
        if (tmpval) {
13074
18.1k
          proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13075
18.1k
              hf->name, tfs->true_string);
13076
18.1k
          first = false;
13077
26.7k
        } else if (!(flags & BMT_NO_FALSE)) {
13078
6.10k
          proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13079
6.10k
              hf->name, tfs->false_string);
13080
6.10k
          first = false;
13081
6.10k
        }
13082
8.75M
      } else if (hf->bitmask & value) {
13083
        /* If the flag is set, show the name */
13084
2.04M
        proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13085
2.04M
        first = false;
13086
2.04M
      }
13087
8.79M
      break;
13088
0
    default:
13089
0
      REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()",
13090
0
               hf->abbrev,
13091
0
               hf->type,
13092
0
               ftype_name(hf->type));
13093
0
      break;
13094
9.85M
    }
13095
13096
9.85M
    fields++;
13097
9.85M
  }
13098
13099
  /* XXX: We don't pass the hfi into this function. Perhaps we should,
13100
   * but then again most dissectors don't set the bitmask field for
13101
   * the higher level bitmask hfi, so calculate the bitmask from the
13102
   * fields present. */
13103
1.98M
  if (item) {
13104
1.91M
    bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13105
1.91M
    no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13106
1.91M
    FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset));
13107
1.91M
    FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
13108
1.91M
  }
13109
1.98M
  return first;
13110
1.98M
}
13111
13112
/* This function will dissect a sequence of bytes that describe a
13113
 * bitmask and supply the value of that sequence through a pointer.
13114
 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13115
 * to be dissected.
13116
 * This field will form an expansion under which the individual fields of the
13117
 * bitmask is dissected and displayed.
13118
 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13119
 *
13120
 * fields is an array of pointers to int that lists all the fields of the
13121
 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13122
 * or another integer of the same type/size as hf_hdr with a mask specified.
13123
 * This array is terminated by a NULL entry.
13124
 *
13125
 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13126
 * FT_integer fields that have a value_string attached will have the
13127
 * matched string displayed on the expansion line.
13128
 */
13129
proto_item *
13130
proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13131
           const unsigned offset, const int hf_hdr,
13132
           const int ett, int * const *fields,
13133
           const unsigned encoding, uint64_t *retval)
13134
18.5k
{
13135
18.5k
  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);
13136
18.5k
}
13137
13138
/* This function will dissect a sequence of bytes that describe a
13139
 * bitmask.
13140
 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13141
 * to be dissected.
13142
 * This field will form an expansion under which the individual fields of the
13143
 * bitmask is dissected and displayed.
13144
 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13145
 *
13146
 * fields is an array of pointers to int that lists all the fields of the
13147
 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13148
 * or another integer of the same type/size as hf_hdr with a mask specified.
13149
 * This array is terminated by a NULL entry.
13150
 *
13151
 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13152
 * FT_integer fields that have a value_string attached will have the
13153
 * matched string displayed on the expansion line.
13154
 */
13155
proto_item *
13156
proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13157
           const unsigned offset, const int hf_hdr,
13158
           const int ett, int * const *fields,
13159
           const unsigned encoding)
13160
1.76M
{
13161
1.76M
  return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT|BMT_NO_TFS);
13162
1.76M
}
13163
13164
/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13165
 * what data is appended to the header.
13166
 */
13167
proto_item *
13168
proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13169
    const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13170
    uint64_t *retval)
13171
21.3k
{
13172
21.3k
  proto_item        *item = NULL;
13173
21.3k
  header_field_info *hf;
13174
21.3k
  int                len;
13175
21.3k
  uint64_t           value;
13176
13177
21.3k
  PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
13178
21.3k
  DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
13179
21.3k
  len = ftype_wire_size(hf->type);
13180
21.3k
  value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13181
13182
21.3k
  if (parent_tree) {
13183
21.3k
    item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13184
21.3k
    proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13185
21.3k
        flags, false, false, NULL, value);
13186
21.3k
  }
13187
13188
21.3k
  *retval = value;
13189
21.3k
  if (hf->bitmask) {
13190
    /* Mask out irrelevant portions */
13191
16.2k
    *retval &= hf->bitmask;
13192
    /* Shift bits */
13193
16.2k
    *retval >>= hfinfo_bitshift(hf);
13194
16.2k
  }
13195
13196
21.3k
  return item;
13197
21.3k
}
13198
13199
/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13200
 * what data is appended to the header.
13201
 */
13202
proto_item *
13203
proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13204
    const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13205
1.85M
{
13206
1.85M
  proto_item        *item = NULL;
13207
1.85M
  header_field_info *hf;
13208
1.85M
  int                len;
13209
1.85M
  uint64_t           value;
13210
13211
1.85M
  PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
13212
1.85M
  DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
13213
13214
1.85M
  if (parent_tree) {
13215
1.85M
    len = ftype_wire_size(hf->type);
13216
1.85M
    item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13217
1.85M
    value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13218
1.85M
    proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13219
1.85M
        flags, false, false, NULL, value);
13220
1.85M
  }
13221
13222
1.85M
  return item;
13223
1.85M
}
13224
13225
/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13226
   can't be retrieved directly from tvb) */
13227
proto_item *
13228
proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13229
    const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13230
788
{
13231
788
  return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13232
788
            hf_hdr, ett, fields, value, BMT_NO_INT|BMT_NO_TFS);
13233
788
}
13234
13235
/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13236
WS_DLL_PUBLIC proto_item *
13237
proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13238
    const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13239
37.7k
{
13240
37.7k
  proto_item        *item = NULL;
13241
37.7k
  header_field_info *hf;
13242
37.7k
  int                len;
13243
13244
37.7k
  PROTO_REGISTRAR_GET_NTH(hf_hdr,hf);
13245
37.7k
  DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
13246
  /* the proto_tree_add_uint/_uint64() calls below
13247
     will fail if tvb==NULL and len!=0 */
13248
37.7k
  len = tvb ? ftype_wire_size(hf->type) : 0;
13249
13250
37.7k
  if (parent_tree) {
13251
37.7k
    if (len <= 4)
13252
37.7k
      item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13253
0
    else
13254
0
      item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13255
13256
37.7k
    proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13257
37.7k
        flags, false, false, NULL, value);
13258
37.7k
  }
13259
13260
37.7k
  return item;
13261
37.7k
}
13262
13263
/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13264
void
13265
proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13266
                const int len, int * const *fields, const unsigned encoding)
13267
51.8k
{
13268
51.8k
  uint64_t value;
13269
13270
51.8k
  if (tree) {
13271
51.7k
    value = get_uint64_value(tree, tvb, offset, len, encoding);
13272
51.7k
    proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
13273
51.7k
        BMT_NO_APPEND, false, true, tree, value);
13274
51.7k
  }
13275
51.8k
}
13276
13277
WS_DLL_PUBLIC void
13278
proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13279
          const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13280
335
{
13281
335
  uint64_t value;
13282
13283
335
  value = get_uint64_value(tree, tvb, offset, len, encoding);
13284
335
  if (tree) {
13285
333
    proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
13286
333
        BMT_NO_APPEND, false, true, tree, value);
13287
333
  }
13288
335
  if (retval) {
13289
333
    *retval = value;
13290
333
  }
13291
335
}
13292
13293
WS_DLL_PUBLIC void
13294
proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13295
                const int len, int * const *fields, const uint64_t value)
13296
14.3k
{
13297
14.3k
  if (tree) {
13298
14.3k
    proto_item_add_bitmask_tree(NULL, tvb, offset, len, -1, fields,
13299
14.3k
        BMT_NO_APPEND, false, true, tree, value);
13300
14.3k
  }
13301
14.3k
}
13302
13303
13304
/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13305
 * This is intended to support bitmask fields whose lengths can vary, perhaps
13306
 * as the underlying standard evolves over time.
13307
 * With this API there is the possibility of being called to display more or
13308
 * less data than the dissector was coded to support.
13309
 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13310
 * Thus when presented with "too much" or "too little" data, MSbits will be
13311
 * ignored or MSfields sacrificed.
13312
 *
13313
 * Only fields for which all defined bits are available are displayed.
13314
 */
13315
proto_item *
13316
proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13317
           const unsigned offset,  const unsigned len, const int hf_hdr,
13318
           const int ett, int * const *fields, struct expert_field* exp,
13319
           const unsigned encoding)
13320
2
{
13321
2
  proto_item        *item = NULL;
13322
2
  header_field_info *hf;
13323
2
  unsigned   decodable_len;
13324
2
  unsigned   decodable_offset;
13325
2
  uint32_t decodable_value;
13326
2
  uint64_t value;
13327
13328
2
  PROTO_REGISTRAR_GET_NTH(hf_hdr, hf);
13329
2
  DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf);
13330
13331
2
  decodable_offset = offset;
13332
2
  decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type));
13333
13334
  /* If we are ftype_wire_size-limited,
13335
   * make sure we decode as many LSBs as possible.
13336
   */
13337
2
  if (encoding == ENC_BIG_ENDIAN) {
13338
0
    decodable_offset += (len - decodable_len);
13339
0
  }
13340
13341
2
  if (parent_tree) {
13342
2
    decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13343
2
             decodable_len, encoding);
13344
13345
    /* The root item covers all the bytes even if we can't decode them all */
13346
2
    item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13347
2
             decodable_value);
13348
2
  }
13349
13350
2
  if (decodable_len < len) {
13351
    /* Dissector likely requires updating for new protocol revision */
13352
0
    expert_add_info_format(NULL, item, exp,
13353
0
               "Only least-significant %d of %d bytes decoded",
13354
0
               decodable_len, len);
13355
0
  }
13356
13357
2
  if (item) {
13358
2
    value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13359
2
    proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13360
2
        ett, fields, BMT_NO_INT|BMT_NO_TFS, false, false, NULL, value);
13361
2
  }
13362
13363
2
  return item;
13364
2
}
13365
13366
/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13367
proto_item *
13368
proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13369
          const unsigned offset, const unsigned len,
13370
          const char *name, const char *fallback,
13371
          const int ett, int * const *fields,
13372
          const unsigned encoding, const int flags)
13373
711
{
13374
711
  proto_item *item = NULL;
13375
711
  uint64_t    value;
13376
13377
711
  if (parent_tree) {
13378
711
    item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13379
711
    value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13380
711
    if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13381
711
        flags, true, false, NULL, value) && fallback) {
13382
      /* Still at first item - append 'fallback' text if any */
13383
0
      proto_item_append_text(item, "%s", fallback);
13384
0
    }
13385
711
  }
13386
13387
711
  return item;
13388
711
}
13389
13390
proto_item *
13391
proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13392
       const unsigned bit_offset, const int no_of_bits,
13393
       const unsigned encoding)
13394
2.42M
{
13395
2.42M
  header_field_info *hfinfo;
13396
2.42M
  int      octet_length;
13397
2.42M
  int      octet_offset;
13398
13399
2.42M
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
13400
13401
2.42M
  if (no_of_bits < 0) {
13402
0
    THROW(ReportedBoundsError);
13403
0
  }
13404
2.42M
  octet_length = (no_of_bits + 7) >> 3;
13405
2.42M
  octet_offset = bit_offset >> 3;
13406
2.42M
  test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13407
13408
  /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13409
   * but only after doing a bunch more work (which we can, in the common
13410
   * case, shortcut here).
13411
   */
13412
2.42M
  CHECK_FOR_NULL_TREE(tree);
13413
908k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
13414
13415
885k
  return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL, encoding);
13416
908k
}
13417
13418
/*
13419
 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13420
 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13421
 * Offset should be given in bits from the start of the tvb.
13422
 */
13423
13424
static proto_item *
13425
_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13426
          const unsigned bit_offset, const int no_of_bits,
13427
          uint64_t *return_value, const unsigned encoding)
13428
934k
{
13429
934k
  int      offset;
13430
934k
  unsigned length;
13431
934k
  uint8_t  tot_no_bits;
13432
934k
  char    *bf_str;
13433
934k
  char     lbl_str[ITEM_LABEL_LENGTH];
13434
934k
  uint64_t value = 0;
13435
934k
  uint8_t *bytes = NULL;
13436
934k
  size_t bytes_length = 0;
13437
13438
934k
  proto_item        *pi;
13439
934k
  header_field_info *hf_field;
13440
13441
  /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13442
934k
  PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
13443
13444
934k
  if (hf_field->bitmask != 0) {
13445
0
    REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_ret_val"
13446
0
             " with field '%s' (%s) with bitmask != 0",
13447
0
             hf_field->abbrev, hf_field->name);
13448
0
  }
13449
13450
934k
  if (no_of_bits < 0) {
13451
0
    THROW(ReportedBoundsError);
13452
934k
  } else if (no_of_bits == 0) {
13453
0
    REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of 0",
13454
0
             hf_field->abbrev);
13455
0
  }
13456
13457
  /* Byte align offset */
13458
934k
  offset = bit_offset>>3;
13459
13460
  /*
13461
   * Calculate the number of octets used to hold the bits
13462
   */
13463
934k
  tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13464
934k
  length = (tot_no_bits + 7) >> 3;
13465
13466
934k
  if (no_of_bits < 65) {
13467
934k
    value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13468
934k
  } else if (hf_field->type != FT_BYTES) {
13469
33
    REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 64",
13470
33
             hf_field->abbrev, no_of_bits);
13471
33
    return NULL;
13472
33
  }
13473
13474
  /* Sign extend for signed types */
13475
934k
  switch (hf_field->type) {
13476
9
    case FT_INT8:
13477
17
    case FT_INT16:
13478
17
    case FT_INT24:
13479
17
    case FT_INT32:
13480
17
    case FT_INT40:
13481
17
    case FT_INT48:
13482
17
    case FT_INT56:
13483
17
    case FT_INT64:
13484
17
      value = ws_sign_ext64(value, no_of_bits);
13485
17
      break;
13486
13487
933k
    default:
13488
933k
      break;
13489
934k
  }
13490
13491
933k
  if (return_value) {
13492
51.5k
    *return_value = value;
13493
51.5k
  }
13494
13495
  /* Coast clear. Try and fake it */
13496
933k
  CHECK_FOR_NULL_TREE(tree);
13497
933k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
13498
13499
931k
  bf_str = decode_bits_in_field(PNODE_POOL(tree), bit_offset, no_of_bits, value, encoding);
13500
13501
931k
  switch (hf_field->type) {
13502
223k
  case FT_BOOLEAN:
13503
    /* Boolean field */
13504
223k
    return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13505
223k
      "%s = %s: %s",
13506
223k
      bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13507
0
    break;
13508
13509
0
  case FT_CHAR:
13510
0
    pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13511
0
    fill_label_char(PITEM_FINFO(pi), lbl_str, NULL);
13512
0
    break;
13513
13514
673k
  case FT_UINT8:
13515
687k
  case FT_UINT16:
13516
689k
  case FT_UINT24:
13517
707k
  case FT_UINT32:
13518
707k
    pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13519
707k
    fill_label_number(PITEM_FINFO(pi), lbl_str, NULL, false);
13520
707k
    break;
13521
13522
9
  case FT_INT8:
13523
17
  case FT_INT16:
13524
17
  case FT_INT24:
13525
17
  case FT_INT32:
13526
17
    pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13527
17
    fill_label_number(PITEM_FINFO(pi), lbl_str, NULL, true);
13528
17
    break;
13529
13530
0
  case FT_UINT40:
13531
0
  case FT_UINT48:
13532
0
  case FT_UINT56:
13533
158
  case FT_UINT64:
13534
158
    pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13535
158
    fill_label_number64(PITEM_FINFO(pi), lbl_str, NULL, false);
13536
158
    break;
13537
13538
0
  case FT_INT40:
13539
0
  case FT_INT48:
13540
0
  case FT_INT56:
13541
0
  case FT_INT64:
13542
0
    pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13543
0
    fill_label_number64(PITEM_FINFO(pi), lbl_str, NULL, true);
13544
0
    break;
13545
13546
514
  case FT_BYTES:
13547
514
    bytes = tvb_get_bits_array(PNODE_POOL(tree), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13548
514
    pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13549
514
    proto_item_fill_label(PITEM_FINFO(pi), lbl_str, NULL);
13550
514
    proto_item_set_text(pi, "%s", lbl_str);
13551
514
    return pi;
13552
13553
  /* TODO: should handle FT_UINT_BYTES ? */
13554
13555
0
  default:
13556
0
    REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_bits_ret_val()",
13557
0
             hf_field->abbrev,
13558
0
             hf_field->type,
13559
0
             ftype_name(hf_field->type));
13560
0
    return NULL;
13561
931k
  }
13562
13563
708k
  proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13564
708k
  return pi;
13565
931k
}
13566
13567
proto_item *
13568
proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13569
               const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13570
               uint64_t *return_value)
13571
278
{
13572
278
  proto_item *pi;
13573
278
  int         no_of_bits;
13574
278
  int         octet_offset;
13575
278
  unsigned    mask_initial_bit_offset;
13576
278
  unsigned    mask_greatest_bit_offset;
13577
278
  unsigned    octet_length;
13578
278
  uint8_t     i;
13579
278
  char        bf_str[256];
13580
278
  char        lbl_str[ITEM_LABEL_LENGTH];
13581
278
  uint64_t    value;
13582
278
  uint64_t    composite_bitmask;
13583
278
  uint64_t    composite_bitmap;
13584
13585
278
  header_field_info       *hf_field;
13586
13587
  /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13588
278
  PROTO_REGISTRAR_GET_NTH(hfindex, hf_field);
13589
13590
278
  if (hf_field->bitmask != 0) {
13591
0
    REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_split_bits_item_ret_val"
13592
0
             " with field '%s' (%s) with bitmask != 0",
13593
0
             hf_field->abbrev, hf_field->name);
13594
0
  }
13595
13596
278
  mask_initial_bit_offset = bit_offset % 8;
13597
13598
278
  no_of_bits = 0;
13599
278
  value      = 0;
13600
278
  i          = 0;
13601
278
  mask_greatest_bit_offset = 0;
13602
278
  composite_bitmask        = 0;
13603
278
  composite_bitmap         = 0;
13604
13605
843
  while (crumb_spec[i].crumb_bit_length != 0) {
13606
565
    uint64_t crumb_mask, crumb_value;
13607
565
    uint8_t crumb_end_bit_offset;
13608
13609
565
    crumb_value = tvb_get_bits64(tvb,
13610
565
               bit_offset + crumb_spec[i].crumb_bit_offset,
13611
565
               crumb_spec[i].crumb_bit_length,
13612
565
               ENC_BIG_ENDIAN);
13613
565
    value      += crumb_value;
13614
565
    no_of_bits += crumb_spec[i].crumb_bit_length;
13615
565
    DISSECTOR_ASSERT_HINT(no_of_bits <= 64, "a value larger than 64 bits cannot be represented");
13616
13617
    /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13618
       octet containing the initial offset.
13619
       If the mask is beyond 32 bits, then give up on bit map display.
13620
       This could be improved in future, probably showing a table
13621
       of 32 or 64 bits per row */
13622
565
    if (mask_greatest_bit_offset < 32) {
13623
559
      crumb_end_bit_offset = mask_initial_bit_offset
13624
559
        + crumb_spec[i].crumb_bit_offset
13625
559
        + crumb_spec[i].crumb_bit_length;
13626
559
      crumb_mask = (UINT64_C(1) << crumb_spec[i].crumb_bit_length) - 1;
13627
13628
559
      if (crumb_end_bit_offset > mask_greatest_bit_offset) {
13629
397
        mask_greatest_bit_offset = crumb_end_bit_offset;
13630
397
      }
13631
      /* Currently the bitmap of the crumbs are only shown if
13632
       * smaller than 32 bits. Do not bother calculating the
13633
       * mask if it is larger than that. */
13634
559
      if (crumb_end_bit_offset <= 32) {
13635
559
        composite_bitmask |= (crumb_mask  << (64 - crumb_end_bit_offset));
13636
559
        composite_bitmap  |= (crumb_value << (64 - crumb_end_bit_offset));
13637
559
      }
13638
559
    }
13639
    /* Shift left for the next segment */
13640
565
    value <<= crumb_spec[++i].crumb_bit_length;
13641
565
  }
13642
13643
  /* Sign extend for signed types */
13644
278
  switch (hf_field->type) {
13645
0
    case FT_INT8:
13646
0
    case FT_INT16:
13647
0
    case FT_INT24:
13648
0
    case FT_INT32:
13649
0
    case FT_INT40:
13650
0
    case FT_INT48:
13651
0
    case FT_INT56:
13652
0
    case FT_INT64:
13653
0
      value = ws_sign_ext64(value, no_of_bits);
13654
0
      break;
13655
272
    default:
13656
272
      break;
13657
278
  }
13658
13659
272
  if (return_value) {
13660
63
    *return_value = value;
13661
63
  }
13662
13663
  /* Coast clear. Try and fake it */
13664
272
  CHECK_FOR_NULL_TREE(tree);
13665
272
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
13666
13667
  /* initialise the format string */
13668
269
  bf_str[0] = '\0';
13669
13670
269
  octet_offset = bit_offset >> 3;
13671
13672
  /* Round up mask length to nearest octet */
13673
269
  octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13674
269
  mask_greatest_bit_offset = octet_length << 3;
13675
13676
  /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13677
     It would be a useful enhancement to eliminate this restriction. */
13678
269
  if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13679
269
    other_decode_bitfield_value(bf_str,
13680
269
              (uint32_t)(composite_bitmap  >> (64 - mask_greatest_bit_offset)),
13681
269
              (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13682
269
              mask_greatest_bit_offset);
13683
269
  } else {
13684
    /* If the bitmask is too large, try to describe its contents. */
13685
0
    snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13686
0
  }
13687
13688
269
  switch (hf_field->type) {
13689
0
  case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13690
    /* Boolean field */
13691
0
    return proto_tree_add_boolean_format(tree, hfindex,
13692
0
                 tvb, octet_offset, octet_length, value,
13693
0
                 "%s = %s: %s",
13694
0
                 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13695
0
    break;
13696
13697
0
  case FT_CHAR:
13698
0
    pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13699
0
    fill_label_char(PITEM_FINFO(pi), lbl_str, NULL);
13700
0
    break;
13701
13702
76
  case FT_UINT8:
13703
247
  case FT_UINT16:
13704
247
  case FT_UINT24:
13705
269
  case FT_UINT32:
13706
269
    pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13707
269
    fill_label_number(PITEM_FINFO(pi), lbl_str, NULL, false);
13708
269
    break;
13709
13710
0
  case FT_INT8:
13711
0
  case FT_INT16:
13712
0
  case FT_INT24:
13713
0
  case FT_INT32:
13714
0
    pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13715
0
    fill_label_number(PITEM_FINFO(pi), lbl_str, NULL, true);
13716
0
    break;
13717
13718
0
  case FT_UINT40:
13719
0
  case FT_UINT48:
13720
0
  case FT_UINT56:
13721
0
  case FT_UINT64:
13722
0
    pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13723
0
    fill_label_number64(PITEM_FINFO(pi), lbl_str, NULL, false);
13724
0
    break;
13725
13726
0
  case FT_INT40:
13727
0
  case FT_INT48:
13728
0
  case FT_INT56:
13729
0
  case FT_INT64:
13730
0
    pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13731
0
    fill_label_number64(PITEM_FINFO(pi), lbl_str, NULL, true);
13732
0
    break;
13733
13734
0
  default:
13735
0
    REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_split_bits_item_ret_val()",
13736
0
             hf_field->abbrev,
13737
0
             hf_field->type,
13738
0
             ftype_name(hf_field->type));
13739
0
    return NULL;
13740
269
  }
13741
269
  proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13742
269
  return pi;
13743
269
}
13744
13745
void
13746
proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13747
        const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13748
97
{
13749
97
  header_field_info *hfinfo;
13750
97
  int start = bit_offset >> 3;
13751
97
  int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13752
13753
  /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13754
   * so that we can use the tree's memory scope in calculating the string */
13755
97
  if (length == -1) {
13756
0
    tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13757
97
  } else {
13758
97
    tvb_ensure_bytes_exist(tvb, start, length);
13759
97
  }
13760
97
  if (!tree) return;
13761
13762
97
  PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo);
13763
97
  proto_tree_add_text_internal(tree, tvb, start, length,
13764
97
          "%s crumb %d of %s (decoded above)",
13765
97
          decode_bits_in_field(PNODE_POOL(tree), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13766
97
             tvb_get_bits32(tvb,
13767
97
                      bit_offset,
13768
97
                      crumb_spec[crumb_index].crumb_bit_length,
13769
97
                      ENC_BIG_ENDIAN),
13770
97
             ENC_BIG_ENDIAN),
13771
97
          crumb_index,
13772
97
          hfinfo->name);
13773
97
}
13774
13775
proto_item *
13776
proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13777
          const unsigned bit_offset, const int no_of_bits,
13778
          uint64_t *return_value, const unsigned encoding)
13779
934k
{
13780
934k
  proto_item *item;
13781
13782
934k
  if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13783
934k
             bit_offset, no_of_bits,
13784
934k
             return_value, encoding))) {
13785
933k
    FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset&0x7));
13786
933k
    FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
13787
933k
  }
13788
934k
  return item;
13789
934k
}
13790
13791
static proto_item *
13792
_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13793
         tvbuff_t *tvb, const unsigned bit_offset,
13794
         const int no_of_bits, void *value_ptr,
13795
         const unsigned encoding, char *value_str)
13796
68.1k
{
13797
68.1k
  int      offset;
13798
68.1k
  unsigned length;
13799
68.1k
  uint8_t  tot_no_bits;
13800
68.1k
  char    *str;
13801
68.1k
  uint64_t value = 0;
13802
68.1k
  header_field_info *hf_field;
13803
13804
  /* We do not have to return a value, try to fake it as soon as possible */
13805
68.1k
  CHECK_FOR_NULL_TREE(tree);
13806
68.1k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
13807
13808
68.1k
  if (hf_field->bitmask != 0) {
13809
0
    REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_format_value"
13810
0
             " with field '%s' (%s) with bitmask != 0",
13811
0
             hf_field->abbrev, hf_field->name);
13812
0
  }
13813
13814
68.1k
  if (no_of_bits < 0) {
13815
0
    THROW(ReportedBoundsError);
13816
68.1k
  } else if (no_of_bits == 0) {
13817
0
    REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_format_value() has a bit width of 0",
13818
0
             hf_field->abbrev);
13819
0
  }
13820
13821
  /* Byte align offset */
13822
68.1k
  offset = bit_offset>>3;
13823
13824
  /*
13825
   * Calculate the number of octets used to hold the bits
13826
   */
13827
68.1k
  tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13828
68.1k
  length      = tot_no_bits>>3;
13829
  /* If we are using part of the next octet, increase length by 1 */
13830
68.1k
  if (tot_no_bits & 0x07)
13831
26.4k
    length++;
13832
13833
68.1k
  if (no_of_bits < 65) {
13834
68.1k
    value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13835
68.1k
  } else {
13836
0
    REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_format_value() has a bit width of %u > 65",
13837
0
             hf_field->abbrev, no_of_bits);
13838
0
    return NULL;
13839
0
  }
13840
13841
68.1k
  str = decode_bits_in_field(PNODE_POOL(tree), bit_offset, no_of_bits, value, encoding);
13842
13843
68.1k
  (void) g_strlcat(str, " = ", 256+64);
13844
68.1k
  (void) g_strlcat(str, hf_field->name, 256+64);
13845
13846
  /*
13847
   * This function does not receive an actual value but a dimensionless pointer to that value.
13848
   * For this reason, the type of the header field is examined in order to determine
13849
   * what kind of value we should read from this address.
13850
   * The caller of this function must make sure that for the specific header field type the address of
13851
   * a compatible value is provided.
13852
   */
13853
68.1k
  switch (hf_field->type) {
13854
0
  case FT_BOOLEAN:
13855
0
    return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13856
0
                 "%s: %s", str, value_str);
13857
0
    break;
13858
13859
0
  case FT_CHAR:
13860
58.7k
  case FT_UINT8:
13861
58.7k
  case FT_UINT16:
13862
58.7k
  case FT_UINT24:
13863
65.2k
  case FT_UINT32:
13864
65.2k
    return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13865
65.2k
              "%s: %s", str, value_str);
13866
0
    break;
13867
13868
0
  case FT_UINT40:
13869
0
  case FT_UINT48:
13870
0
  case FT_UINT56:
13871
0
  case FT_UINT64:
13872
0
    return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13873
0
                "%s: %s", str, value_str);
13874
0
    break;
13875
13876
0
  case FT_INT8:
13877
0
  case FT_INT16:
13878
0
  case FT_INT24:
13879
0
  case FT_INT32:
13880
0
    return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13881
0
             "%s: %s", str, value_str);
13882
0
    break;
13883
13884
0
  case FT_INT40:
13885
0
  case FT_INT48:
13886
0
  case FT_INT56:
13887
2.88k
  case FT_INT64:
13888
2.88k
    return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13889
2.88k
               "%s: %s", str, value_str);
13890
0
    break;
13891
13892
0
  case FT_FLOAT:
13893
0
    return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13894
0
               "%s: %s", str, value_str);
13895
0
    break;
13896
13897
0
  default:
13898
0
    REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_bits_format_value()",
13899
0
             hf_field->abbrev,
13900
0
             hf_field->type,
13901
0
             ftype_name(hf_field->type));
13902
0
    return NULL;
13903
68.1k
  }
13904
68.1k
}
13905
13906
static proto_item *
13907
proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13908
         tvbuff_t *tvb, const unsigned bit_offset,
13909
         const int no_of_bits, void *value_ptr,
13910
         const unsigned encoding, char *value_str)
13911
68.1k
{
13912
68.1k
  proto_item *item;
13913
13914
68.1k
  if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13915
68.1k
                  tvb, bit_offset, no_of_bits,
13916
68.1k
                  value_ptr, encoding, value_str))) {
13917
68.1k
    FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset&0x7));
13918
68.1k
    FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits));
13919
68.1k
  }
13920
68.1k
  return item;
13921
68.1k
}
13922
13923
#define CREATE_VALUE_STRING(tree,dst,format,ap) \
13924
68.1k
  va_start(ap, format); \
13925
68.1k
  dst = wmem_strdup_vprintf(PNODE_POOL(tree), format, ap); \
13926
68.1k
  va_end(ap);
13927
13928
proto_item *
13929
proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13930
              tvbuff_t *tvb, const unsigned bit_offset,
13931
              const int no_of_bits, uint32_t value,
13932
              const unsigned encoding,
13933
              const char *format, ...)
13934
76.7k
{
13935
76.7k
  va_list ap;
13936
76.7k
  char   *dst;
13937
76.7k
  header_field_info *hf_field;
13938
13939
76.7k
  CHECK_FOR_NULL_TREE(tree);
13940
13941
76.7k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
13942
13943
65.2k
  switch (hf_field->type) {
13944
58.7k
    case FT_UINT8:
13945
58.7k
    case FT_UINT16:
13946
58.7k
    case FT_UINT24:
13947
65.2k
    case FT_UINT32:
13948
65.2k
      break;
13949
13950
0
    default:
13951
0
      REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
13952
0
          hf_field->abbrev);
13953
0
      return NULL;
13954
65.2k
  }
13955
13956
65.2k
  CREATE_VALUE_STRING(tree, dst, format, ap);
13957
13958
65.2k
  return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13959
65.2k
}
13960
13961
proto_item *
13962
proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13963
              tvbuff_t *tvb, const unsigned bit_offset,
13964
              const int no_of_bits, uint64_t value,
13965
              const unsigned encoding,
13966
              const char *format, ...)
13967
29
{
13968
29
  va_list ap;
13969
29
  char   *dst;
13970
29
  header_field_info *hf_field;
13971
13972
29
  CHECK_FOR_NULL_TREE(tree);
13973
13974
29
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
13975
13976
29
  switch (hf_field->type) {
13977
0
    case FT_UINT40:
13978
0
    case FT_UINT48:
13979
0
    case FT_UINT56:
13980
0
    case FT_UINT64:
13981
0
      break;
13982
13983
29
    default:
13984
29
      REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",
13985
29
          hf_field->abbrev);
13986
29
      return NULL;
13987
29
  }
13988
13989
29
  CREATE_VALUE_STRING(tree, dst, format, ap);
13990
13991
0
  return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13992
29
}
13993
13994
proto_item *
13995
proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13996
               tvbuff_t *tvb, const unsigned bit_offset,
13997
               const int no_of_bits, float value,
13998
               const unsigned encoding,
13999
               const char *format, ...)
14000
0
{
14001
0
  va_list ap;
14002
0
  char   *dst;
14003
0
  header_field_info *hf_field;
14004
14005
0
  CHECK_FOR_NULL_TREE(tree);
14006
14007
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
14008
14009
0
  DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT);
14010
14011
0
  CREATE_VALUE_STRING(tree, dst, format, ap);
14012
14013
0
  return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14014
0
}
14015
14016
proto_item *
14017
proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14018
             tvbuff_t *tvb, const unsigned bit_offset,
14019
             const int no_of_bits, int32_t value,
14020
                               const unsigned encoding,
14021
             const char *format, ...)
14022
0
{
14023
0
  va_list ap;
14024
0
  char   *dst;
14025
0
  header_field_info *hf_field;
14026
14027
0
  CHECK_FOR_NULL_TREE(tree);
14028
14029
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
14030
14031
0
  switch (hf_field->type) {
14032
0
    case FT_INT8:
14033
0
    case FT_INT16:
14034
0
    case FT_INT24:
14035
0
    case FT_INT32:
14036
0
      break;
14037
14038
0
    default:
14039
0
      REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",
14040
0
          hf_field->abbrev);
14041
0
      return NULL;
14042
0
  }
14043
14044
0
  CREATE_VALUE_STRING(tree, dst, format, ap);
14045
14046
0
  return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14047
0
}
14048
14049
proto_item *
14050
proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14051
             tvbuff_t *tvb, const unsigned bit_offset,
14052
             const int no_of_bits, int64_t value,
14053
             const unsigned encoding,
14054
             const char *format, ...)
14055
3.12k
{
14056
3.12k
  va_list ap;
14057
3.12k
  char   *dst;
14058
3.12k
  header_field_info *hf_field;
14059
14060
3.12k
  CHECK_FOR_NULL_TREE(tree);
14061
14062
2.88k
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
14063
14064
2.88k
  switch (hf_field->type) {
14065
0
    case FT_INT40:
14066
0
    case FT_INT48:
14067
0
    case FT_INT56:
14068
2.88k
    case FT_INT64:
14069
2.88k
      break;
14070
14071
0
    default:
14072
0
      REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",
14073
0
          hf_field->abbrev);
14074
0
      return NULL;
14075
2.88k
  }
14076
14077
2.88k
  CREATE_VALUE_STRING(tree, dst, format, ap);
14078
14079
2.88k
  return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14080
2.88k
}
14081
14082
proto_item *
14083
proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14084
           tvbuff_t *tvb, const unsigned bit_offset,
14085
           const int no_of_bits, uint64_t value,
14086
                 const unsigned encoding,
14087
           const char *format, ...)
14088
0
{
14089
0
  va_list ap;
14090
0
  char   *dst;
14091
0
  header_field_info *hf_field;
14092
14093
0
  CHECK_FOR_NULL_TREE(tree);
14094
14095
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field);
14096
14097
0
  DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN);
14098
14099
0
  CREATE_VALUE_STRING(tree, dst, format, ap);
14100
14101
0
  return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14102
0
}
14103
14104
proto_item *
14105
proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14106
  const unsigned bit_offset, const int no_of_chars)
14107
7
{
14108
7
  proto_item    *pi;
14109
7
  header_field_info *hfinfo;
14110
7
  int      byte_length;
14111
7
  int      byte_offset;
14112
7
  char      *string;
14113
14114
7
  CHECK_FOR_NULL_TREE(tree);
14115
14116
7
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
14117
14118
7
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
14119
14120
7
  byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14121
7
  byte_offset = bit_offset >> 3;
14122
14123
7
  string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree), tvb, bit_offset, no_of_chars);
14124
14125
7
  pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14126
7
  DISSECTOR_ASSERT(byte_length >= 0);
14127
7
  proto_tree_set_string(PNODE_FINFO(pi), string);
14128
14129
7
  return pi;
14130
7
}
14131
14132
proto_item *
14133
proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14134
  const unsigned bit_offset, const int no_of_chars)
14135
0
{
14136
0
  proto_item    *pi;
14137
0
  header_field_info *hfinfo;
14138
0
  int      byte_length;
14139
0
  int      byte_offset;
14140
0
  char      *string;
14141
14142
0
  CHECK_FOR_NULL_TREE(tree);
14143
14144
0
  TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo);
14145
14146
0
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING);
14147
14148
0
  byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14149
0
  byte_offset = bit_offset >> 3;
14150
14151
0
  string = tvb_get_ascii_7bits_string(PNODE_POOL(tree), tvb, bit_offset, no_of_chars);
14152
14153
0
  pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14154
0
  DISSECTOR_ASSERT(byte_length >= 0);
14155
0
  proto_tree_set_string(PNODE_FINFO(pi), string);
14156
14157
0
  return pi;
14158
0
}
14159
14160
const value_string proto_checksum_vals[] = {
14161
  { PROTO_CHECKSUM_E_BAD,        "Bad"  },
14162
  { PROTO_CHECKSUM_E_GOOD,       "Good" },
14163
  { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14164
  { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14165
  { PROTO_CHECKSUM_E_ILLEGAL,    "Illegal" },
14166
14167
  { 0,        NULL }
14168
};
14169
14170
#define PROTO_CHECKSUM_COMPUTED_USED (PROTO_CHECKSUM_VERIFY|PROTO_CHECKSUM_GENERATED|PROTO_CHECKSUM_NOT_PRESENT)
14171
14172
proto_item *
14173
proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14174
    const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14175
    packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14176
92.1k
{
14177
92.1k
  header_field_info *hfinfo;
14178
92.1k
  uint32_t checksum;
14179
92.1k
  uint32_t len;
14180
92.1k
  proto_item* ti = NULL;
14181
92.1k
  proto_item* ti2;
14182
92.1k
  bool incorrect_checksum = true;
14183
14184
92.1k
  PROTO_REGISTRAR_GET_NTH(hf_checksum, hfinfo);
14185
14186
92.1k
  switch (hfinfo->type) {
14187
508
  case FT_UINT8:
14188
508
    len = 1;
14189
508
    break;
14190
76.2k
  case FT_UINT16:
14191
76.2k
    len = 2;
14192
76.2k
    break;
14193
20
  case FT_UINT24:
14194
20
    len = 3;
14195
20
    break;
14196
15.3k
  case FT_UINT32:
14197
15.3k
    len = 4;
14198
15.3k
    break;
14199
0
  default:
14200
0
    REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",
14201
92.1k
        hfinfo->abbrev);
14202
92.1k
  }
14203
14204
92.1k
  if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
14205
328
    ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14206
328
    proto_item_set_generated(ti);
14207
    // Backward compatible with use of -1
14208
328
    if (hf_checksum_status > 0) {
14209
322
      ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14210
322
      proto_item_set_generated(ti2);
14211
322
    }
14212
328
    return ti;
14213
328
  }
14214
14215
91.7k
  if (flags & PROTO_CHECKSUM_GENERATED) {
14216
0
    ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14217
0
    proto_item_set_generated(ti);
14218
91.7k
  } else {
14219
91.7k
    ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14220
91.7k
    if (flags & PROTO_CHECKSUM_VERIFY) {
14221
7.26k
      if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) {
14222
4.02k
        if (computed_checksum == 0) {
14223
9
          proto_item_append_text(ti, " [correct]");
14224
          // Backward compatible with use of -1
14225
9
          if (hf_checksum_status > 0) {
14226
9
            ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14227
9
            proto_item_set_generated(ti2);
14228
9
          }
14229
9
          incorrect_checksum = false;
14230
4.01k
        } else if (flags & PROTO_CHECKSUM_IN_CKSUM) {
14231
3.83k
          computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14232
          /* XXX - This can't distinguish between "shouldbe"
14233
           * 0x0000 and 0xFFFF unless we know whether there
14234
           * were any nonzero bits (other than the checksum).
14235
           * Protocols should not use this path if they might
14236
           * have an all zero packet.
14237
           * Some implementations put the wrong zero; maybe
14238
           * we should have a special expert info for that?
14239
           */
14240
3.83k
        }
14241
4.02k
      } else {
14242
3.24k
        if (checksum == computed_checksum) {
14243
3
          proto_item_append_text(ti, " [correct]");
14244
          // Backward compatible with use of -1
14245
3
          if (hf_checksum_status > 0) {
14246
3
            ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14247
3
            proto_item_set_generated(ti2);
14248
3
          }
14249
3
          incorrect_checksum = false;
14250
3
        }
14251
3.24k
      }
14252
14253
7.26k
      if (incorrect_checksum) {
14254
        // Backward compatible with use of -1
14255
7.25k
        if (hf_checksum_status > 0) {
14256
7.20k
          ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14257
7.20k
          proto_item_set_generated(ti2);
14258
7.20k
        }
14259
7.25k
        if (flags & PROTO_CHECKSUM_ZERO) {
14260
172
          proto_item_append_text(ti, " [incorrect]");
14261
172
          if (bad_checksum_expert != NULL)
14262
172
            expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14263
7.07k
        } else {
14264
7.07k
          proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14265
7.07k
          if (bad_checksum_expert != NULL)
14266
7.02k
            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);
14267
7.07k
        }
14268
7.25k
      }
14269
84.5k
    } else {
14270
      // Backward compatible with use of -1
14271
84.5k
      if (hf_checksum_status > 0) {
14272
79.3k
        proto_item_append_text(ti, " [unverified]");
14273
79.3k
        ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14274
79.3k
        proto_item_set_generated(ti2);
14275
79.3k
      }
14276
84.5k
    }
14277
91.7k
  }
14278
14279
91.7k
  return ti;
14280
92.1k
}
14281
14282
proto_item *
14283
proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14284
    const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14285
    packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14286
24
{
14287
24
  header_field_info *hfinfo;
14288
24
  uint8_t *checksum = NULL;
14289
24
  proto_item* ti = NULL;
14290
24
  proto_item* ti2;
14291
24
  bool incorrect_checksum = true;
14292
14293
24
  PROTO_REGISTRAR_GET_NTH(hf_checksum, hfinfo);
14294
14295
24
  DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES);
14296
14297
  /* Make sure a NULL computed_checksum isn't dereferenced.
14298
   * If checksum_len is 0 it probably won't crash, but in the VERIFY
14299
   * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14300
   * cases the behavior is unexpected and still a programmer error;
14301
   * proto_tree_add_bytes retrieves it from the tvb, thus neither
14302
   * _NOT_PRESENT nor _GENERATED is correct.
14303
   */
14304
24
  DISSECTOR_ASSERT(computed_checksum || ((flags & PROTO_CHECKSUM_COMPUTED_USED) == PROTO_CHECKSUM_NO_FLAGS));
14305
14306
24
  if (flags & PROTO_CHECKSUM_NOT_PRESENT) {
14307
0
    ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14308
0
    proto_item_set_generated(ti);
14309
    // Backward compatible with use of -1
14310
0
    if (hf_checksum_status > 0) {
14311
0
      ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14312
0
      proto_item_set_generated(ti2);
14313
0
    }
14314
0
    return ti;
14315
0
  }
14316
14317
24
  if (flags & PROTO_CHECKSUM_GENERATED) {
14318
0
    ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14319
0
    proto_item_set_generated(ti);
14320
0
    return ti;
14321
0
  }
14322
14323
24
  checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14324
24
  ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14325
24
  if (flags & PROTO_CHECKSUM_VERIFY) {
14326
0
    if (flags & (PROTO_CHECKSUM_IN_CKSUM|PROTO_CHECKSUM_ZERO)) {
14327
0
      bool non_zero_flag = false;
14328
0
      for (size_t index = 0; index < checksum_len; index++) {
14329
0
        if (computed_checksum[index]) {
14330
0
          non_zero_flag = true;
14331
0
          break;
14332
0
        }
14333
0
      }
14334
0
      if (!non_zero_flag) {
14335
0
        proto_item_append_text(ti, " [correct]");
14336
        // Backward compatible with use of -1
14337
0
        if (hf_checksum_status > 0) {
14338
0
          ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14339
0
          proto_item_set_generated(ti2);
14340
0
        }
14341
0
        incorrect_checksum = false;
14342
0
      }
14343
0
    } else {
14344
0
      if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14345
0
        proto_item_append_text(ti, " [correct]");
14346
        // Backward compatible with use of -1
14347
0
        if (hf_checksum_status > 0) {
14348
0
          ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14349
0
          proto_item_set_generated(ti2);
14350
0
        }
14351
0
        incorrect_checksum = false;
14352
0
      }
14353
0
    }
14354
14355
0
    if (incorrect_checksum) {
14356
      // Backward compatible with use of -1
14357
0
      if (hf_checksum_status > 0) {
14358
0
        ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14359
0
        proto_item_set_generated(ti2);
14360
0
      }
14361
0
      if (flags & PROTO_CHECKSUM_ZERO) {
14362
0
        proto_item_append_text(ti, " [incorrect]");
14363
0
        if (bad_checksum_expert != NULL)
14364
0
          expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14365
0
      } else {
14366
0
        char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14367
0
        proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14368
0
        if (bad_checksum_expert != NULL)
14369
0
          expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14370
0
      }
14371
0
    }
14372
24
  } else {
14373
    // Backward compatible with use of -1
14374
24
    if (hf_checksum_status > 0) {
14375
0
      proto_item_append_text(ti, " [unverified]");
14376
0
      ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14377
0
      proto_item_set_generated(ti2);
14378
0
    }
14379
24
  }
14380
14381
24
  return ti;
14382
24
}
14383
14384
unsigned char
14385
proto_check_field_name(const char *field_name)
14386
90.0k
{
14387
90.0k
  return module_check_valid_name(field_name, false);
14388
90.0k
}
14389
14390
unsigned char
14391
proto_check_field_name_lower(const char *field_name)
14392
6.52k
{
14393
6.52k
  return module_check_valid_name(field_name, true);
14394
6.52k
}
14395
14396
bool
14397
tree_expanded(int tree_type)
14398
0
{
14399
0
  if (tree_type <= 0) {
14400
0
    return false;
14401
0
  }
14402
0
  ws_assert(tree_type >= 0 && tree_type < num_tree_types);
14403
0
  return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14404
0
}
14405
14406
void
14407
tree_expanded_set(int tree_type, bool value)
14408
100
{
14409
100
  ws_assert(tree_type >= 0 && tree_type < num_tree_types);
14410
14411
100
  if (value)
14412
100
    tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14413
0
  else
14414
0
    tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14415
100
}
14416
14417
/*
14418
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
14419
 *
14420
 * Local variables:
14421
 * c-basic-offset: 8
14422
 * tab-width: 8
14423
 * indent-tabs-mode: t
14424
 * End:
14425
 *
14426
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14427
 * :indentSize=8:tabSize=8:noTabs=false:
14428
 */