Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-erldp.c
Line
Count
Source
1
/* packet-erldp.c
2
 * Erlang Distribution Protocol
3
 * http://www.erlang.org/doc/apps/erts/erl_dist_protocol.html
4
 *
5
 * 2010  Tomas Kukosa
6
 *
7
 * Wireshark - Network traffic analyzer
8
 * By Gerald Combs <gerald@wireshark.org>
9
 * Copyright 1998 Gerald Combs
10
 *
11
 * SPDX-License-Identifier: GPL-2.0-or-later
12
 */
13
14
#include "config.h"
15
16
17
#include <epan/packet.h>
18
#include <epan/tfs.h>
19
#include <epan/reassemble.h>
20
#include "packet-tcp.h"
21
#include "packet-epmd.h"
22
23
0
#define ERL_PASS_THROUGH      'p'
24
25
0
#define VERSION_MAGIC 131   /* 130 in erlang 4.2 */
26
27
0
#define SMALL_INTEGER_EXT   'a'
28
0
#define INTEGER_EXT         'b'
29
0
#define FLOAT_EXT           'c'
30
#define ATOM_EXT            'd'
31
0
#define ATOM_UTF8_EXT       'v'
32
#define SMALL_ATOM_EXT      's'
33
0
#define SMALL_ATOM_UTF8_EXT 'w'
34
#define REFERENCE_EXT       'e'
35
0
#define NEW_REFERENCE_EXT   'r'
36
0
#define NEWER_REFERENCE_EXT 'Z'
37
0
#define PORT_EXT            'f'
38
0
#define NEW_PORT_EXT        'Y'
39
0
#define V4_PORT_EXT         'x'
40
0
#define NEW_FLOAT_EXT       'F'
41
0
#define PID_EXT             'g'
42
0
#define NEW_PID_EXT         'X'
43
0
#define SMALL_TUPLE_EXT     'h'
44
0
#define LARGE_TUPLE_EXT     'i'
45
0
#define NIL_EXT             'j'
46
0
#define STRING_EXT          'k'
47
0
#define LIST_EXT            'l'
48
0
#define BINARY_EXT          'm'
49
0
#define BIT_BINARY_EXT      'M'
50
0
#define SMALL_BIG_EXT       'n'
51
0
#define LARGE_BIG_EXT       'o'
52
0
#define NEW_FUN_EXT         'p'
53
0
#define EXPORT_EXT          'q'
54
0
#define FUN_EXT             'u'
55
0
#define MAP_EXT             't'
56
#define LOCAL_EXT           'y'
57
58
0
#define DIST_HEADER         'D'
59
0
#define DIST_FRAG_HEADER    'E'
60
0
#define DIST_FRAG_CONT      'F'
61
0
#define ATOM_CACHE_REF      'R'
62
#define COMPRESSED          'P'
63
64
void proto_register_erldp(void);
65
void proto_reg_handoff_erldp(void);
66
67
static const value_string etf_tag_vals[] = {
68
  { SMALL_INTEGER_EXT   , "SMALL_INTEGER_EXT" },
69
  { INTEGER_EXT         , "INTEGER_EXT" },
70
  { FLOAT_EXT           , "FLOAT_EXT" },
71
  { ATOM_EXT            , "ATOM_EXT" },
72
  { ATOM_UTF8_EXT       , "ATOM_UTF8_EXT" },
73
  { SMALL_ATOM_EXT      , "SMALL_ATOM_EXT" },
74
  { SMALL_ATOM_UTF8_EXT , "SMALL_ATOM_UTF8_EXT" },
75
  { REFERENCE_EXT       , "REFERENCE_EXT" },
76
  { NEW_REFERENCE_EXT   , "NEW_REFERENCE_EXT" },
77
  { NEWER_REFERENCE_EXT , "NEWER_REFERENCE_EXT" },
78
  { PORT_EXT            , "PORT_EXT" },
79
  { NEW_PORT_EXT        , "NEW_PORT_EXT" },
80
  { V4_PORT_EXT         , "V4_PORT_EXT" },
81
  { NEW_FLOAT_EXT       , "NEW_FLOAT_EXT" },
82
  { PID_EXT             , "PID_EXT" },
83
  { NEW_PID_EXT         , "NEW_PID_EXT" },
84
  { SMALL_TUPLE_EXT     , "SMALL_TUPLE_EXT" },
85
  { LARGE_TUPLE_EXT     , "LARGE_TUPLE_EXT" },
86
  { NIL_EXT             , "NIL_EXT" },
87
  { STRING_EXT          , "STRING_EXT" },
88
  { LIST_EXT            , "LIST_EXT" },
89
  { BINARY_EXT          , "BINARY_EXT" },
90
  { BIT_BINARY_EXT      , "BIT_BINARY_EXT" },
91
  { SMALL_BIG_EXT       , "SMALL_BIG_EXT" },
92
  { LARGE_BIG_EXT       , "LARGE_BIG_EXT" },
93
  { NEW_FUN_EXT         , "NEW_FUN_EXT" },
94
  { EXPORT_EXT          , "EXPORT_EXT" },
95
  { FUN_EXT             , "FUN_EXT" },
96
  { MAP_EXT             , "MAP_EXT" },
97
  { LOCAL_EXT           , "LOCAL_EXT" },
98
  { DIST_HEADER         , "DIST_HEADER" },
99
  { DIST_FRAG_HEADER    , "DIST_FRAG_HEADER" },
100
  { ATOM_CACHE_REF      , "ATOM_CACHE_REF" },
101
  { COMPRESSED          , "COMPRESSED" },
102
  {  0, NULL }
103
};
104
105
static const value_string etf_header_tag_vals[] = {
106
  { DIST_HEADER         , "DIST_HEADER" },
107
  { DIST_FRAG_HEADER    , "DIST_FRAG_HEADER" },
108
  { DIST_FRAG_CONT      , "DIST_FRAG_CONT" },
109
  {  0, NULL }
110
};
111
112
static const value_string erldp_ctlmsg_vals[] = {
113
  {  1, "LINK" },
114
  {  2, "SEND" },
115
  {  3, "EXIT" },
116
  {  4, "UNLINK" },
117
  {  5, "NODE_LINK" },
118
  {  6, "REG_SEND" },
119
  {  7, "GROUP_LEADER" },
120
  {  8, "EXIT2" },
121
  { 12, "SEND_TT" },
122
  { 13, "EXIT_TT" },
123
  { 16, "REG_SEND_TT" },
124
  { 18, "EXIT2_TT" },
125
  { 19, "MONITOR_P" },
126
  { 20, "DEMONITOR_P" },
127
  { 21, "MONITOR_P_EXIT" },
128
  { 22, "SEND_SENDER" },
129
  { 23, "SEND_SENDER_TT" },
130
  { 24, "PAYLOAD_EXIT" },
131
  { 25, "PAYLOAD_EXIT_TT" },
132
  { 26, "PAYLOAD_EXIT2" },
133
  { 27, "PAYLOAD_EXIT2_TT" },
134
  { 28, "PAYLOAD_MONITOR_P_EXIT" },
135
  { 29, "SPAWN_REQUEST" },
136
  { 30, "SPAWN_REQUEST_TT" },
137
  { 31, "SPAWN_REPLY" },
138
  { 32, "SPAWN_REPLY_TT" },
139
  {  0, NULL }
140
};
141
142
/* Initialize the protocol and registered fields */
143
static int proto_erldp;
144
static int hf_erldp_length_2;
145
static int hf_erldp_length_4;
146
static int hf_etf_version_magic;
147
static int hf_erldp_tag;
148
static int hf_erldp_type;
149
static int hf_erldp_version;
150
static int hf_erldp_flags_v5;
151
static int hf_erldp_flags_v6;
152
static int hf_erldp_flags_published;
153
static int hf_erldp_flags_atom_cache;
154
static int hf_erldp_flags_extended_references;
155
static int hf_erldp_flags_dist_monitor;
156
static int hf_erldp_flags_fun_tags;
157
static int hf_erldp_flags_dist_monitor_name;
158
static int hf_erldp_flags_hidden_atom_cache;
159
static int hf_erldp_flags_new_fun_tags;
160
static int hf_erldp_flags_extended_pids_ports;
161
static int hf_erldp_flags_export_ptr_tag;
162
static int hf_erldp_flags_bit_binaries;
163
static int hf_erldp_flags_new_floats;
164
static int hf_erldp_flags_unicode_io;
165
static int hf_erldp_flags_dist_hdr_atom_cache;
166
static int hf_erldp_flags_small_atom_tags;
167
static int hf_erldp_flags_ets_compressed;
168
static int hf_erldp_flags_utf8_atoms;
169
static int hf_erldp_flags_map_tag;
170
static int hf_erldp_flags_big_creation;
171
static int hf_erldp_flags_send_sender;
172
static int hf_erldp_flags_big_seqtrace_labels;
173
static int hf_erldp_flags_pending_connect;
174
static int hf_erldp_flags_exit_payload;
175
static int hf_erldp_flags_fragments;
176
static int hf_erldp_flags_handshake_23;
177
static int hf_erldp_flags_unlink_id;
178
static int hf_erldp_flags_reserved;
179
static int hf_erldp_flags_spawn;
180
static int hf_erldp_flags_name_me;
181
static int hf_erldp_flags_v4_nc;
182
static int hf_erldp_flags_alias;
183
static int hf_erldp_flags_spare;
184
static int hf_erldp_creation;
185
static int hf_erldp_challenge;
186
static int hf_erldp_digest;
187
static int hf_erldp_nlen;
188
static int hf_erldp_name;
189
static int hf_erldp_status;
190
static int hf_erldp_sequence_id;
191
static int hf_erldp_fragment_id;
192
static int hf_erldp_num_atom_cache_refs;
193
static int hf_erldp_etf_flags;
194
static int hf_erldp_internal_segment_index;
195
static int hf_erldp_atom_length;
196
static int hf_erldp_atom_length2;
197
static int hf_erldp_atom_text;
198
static int hf_erldp_string_ext_len;
199
static int hf_erldp_string_ext;
200
static int hf_erldp_atom_cache_ref;
201
static int hf_erldp_small_int_ext;
202
static int hf_erldp_int_ext;
203
static int hf_erldp_small_big_ext_len;
204
static int hf_erldp_large_big_ext_len;
205
static int hf_erldp_big_ext_int;
206
static int hf_erldp_big_ext_str;
207
static int hf_erldp_big_ext_bytes;
208
static int hf_erldp_float_ext;
209
static int hf_erldp_new_float_ext;
210
static int hf_erldp_port_ext_id;
211
static int hf_erldp_port_ext_v4_id;
212
static int hf_erldp_port_ext_creation;
213
static int hf_erldp_pid_ext_id;
214
static int hf_erldp_pid_ext_serial;
215
static int hf_erldp_pid_ext_creation;
216
static int hf_erldp_list_ext_len;
217
static int hf_erldp_map_ext_len;
218
static int hf_erldp_binary_ext_len;
219
static int hf_erldp_binary_ext_bits;
220
static int hf_erldp_binary_ext;
221
static int hf_erldp_new_ref_ext_len;
222
static int hf_erldp_new_ref_ext_creation;
223
static int hf_erldp_new_ref_ext_id;
224
static int hf_erldp_fun_ext_num_free;
225
static int hf_erldp_new_fun_ext_size;
226
static int hf_erldp_new_fun_ext_arity;
227
static int hf_erldp_new_fun_ext_uniq;
228
static int hf_erldp_new_fun_ext_index;
229
static int hf_erldp_new_fun_ext_num_free;
230
231
static int hf_etf_tag;
232
static int hf_etf_dist_header_tag;
233
static int hf_etf_dist_header_new_cache;
234
static int hf_etf_dist_header_segment_index;
235
static int hf_etf_dist_header_long_atoms;
236
static int hf_etf_arity4;
237
static int hf_etf_arity;
238
239
static int hf_etf_fragments;
240
static int hf_etf_fragment;
241
static int hf_etf_fragment_overlap;
242
static int hf_etf_fragment_overlap_conflicts;
243
static int hf_etf_fragment_multiple_tails;
244
static int hf_etf_fragment_too_long_fragment;
245
static int hf_etf_fragment_error;
246
static int hf_etf_fragment_count;
247
static int hf_etf_reassembled_in;
248
static int hf_etf_reassembled_length;
249
static int hf_etf_reassembled_data;
250
251
static reassembly_table erldp_reassembly_table;
252
253
/* Initialize the subtree pointers */
254
static int ett_erldp;
255
static int ett_erldp_flags;
256
257
static int ett_etf;
258
static int ett_etf_flags;
259
static int ett_etf_acrs;
260
static int ett_etf_acr;
261
static int ett_etf_tmp;
262
263
static int ett_etf_fragment;
264
static int ett_etf_fragments;
265
266
/* Preferences */
267
static bool erldp_desegment = true;
268
269
/* Dissectors */
270
static dissector_handle_t erldp_handle;
271
272
/* Defragmentation */
273
static const fragment_items etf_frag_items = {
274
    /* Fragment subtrees */
275
    &ett_etf_fragment,
276
    &ett_etf_fragments,
277
    /* Fragment fields */
278
    &hf_etf_fragments,
279
    &hf_etf_fragment,
280
    &hf_etf_fragment_overlap,
281
    &hf_etf_fragment_overlap_conflicts,
282
    &hf_etf_fragment_multiple_tails,
283
    &hf_etf_fragment_too_long_fragment,
284
    &hf_etf_fragment_error,
285
    &hf_etf_fragment_count,
286
    /* Reassembled in field */
287
    &hf_etf_reassembled_in,
288
    /* Reassembled length field */
289
    &hf_etf_reassembled_length,
290
    &hf_etf_reassembled_data,
291
    /* Tag */
292
    "Message fragments"
293
};
294
295
/*--- External Term Format ---*/
296
297
static int dissect_etf_type(const char *label, packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree);
298
static int dissect_etf_pdu_data(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree);
299
300
0
static int dissect_etf_dist_header(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree) {
301
0
  uint32_t num, isi;
302
0
  uint8_t flen, flg;
303
0
  int flg_offset, acrs_offset, acr_offset;
304
0
  uint32_t atom_txt_len;
305
0
  bool new_entry, long_atom;
306
0
  proto_item *ti_acrs, *ti_acr, *ti_tmp;
307
0
  proto_tree *flags_tree, *acrs_tree, *acr_tree;
308
0
  const uint8_t *str;
309
310
0
  proto_tree_add_item_ret_uint(tree, hf_erldp_num_atom_cache_refs, tvb, offset, 1, ENC_BIG_ENDIAN, &num);
311
0
  offset++;
312
313
0
  if (num == 0)
314
0
    return offset;
315
316
0
  flg_offset = offset;
317
0
  flen = num / 2 + 1;
318
0
  ti_tmp = proto_tree_add_item(tree, hf_erldp_etf_flags, tvb, offset, flen, ENC_NA );
319
0
  flags_tree = proto_item_add_subtree(ti_tmp, ett_etf_flags);
320
0
  for (unsigned i=0; i<num; i++) {
321
0
    flg = tvb_get_uint8(tvb, offset + i / 2);
322
0
    proto_tree_add_boolean_format_value(flags_tree, hf_etf_dist_header_new_cache, tvb, offset + i / 2, 1,
323
0
                            (flg & (0x08 << 4*(i%2))), "NewCacheEntryFlag[%2d]: %s",
324
0
                            i, (flg & (0x08 << 4*(i%2))) ? "SET" : "---");
325
0
    proto_tree_add_uint_format(flags_tree, hf_etf_dist_header_segment_index, tvb, offset + i / 2, 1,
326
0
                            (flg & (0x07 << 4*(i%2))), "SegmentIndex     [%2d]: %u",
327
0
                            i, (flg & (0x07 << 4*(i%2))));
328
0
  }
329
0
  flg = tvb_get_uint8(tvb, offset + num / 2);
330
0
  proto_tree_add_boolean(flags_tree, hf_etf_dist_header_long_atoms, tvb, offset + num / 2, 1, (flg & (0x01 << 4*(num%2))));
331
0
  long_atom = flg & (0x01 << 4*(num%2));
332
0
  offset += flen;
333
334
0
  acrs_offset = offset;
335
0
  acrs_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_etf_acrs, &ti_acrs, "AtomCacheRefs");
336
0
  for (unsigned i=0; i<num; i++) {
337
0
    flg = tvb_get_uint8(tvb, flg_offset + i / 2);
338
0
    new_entry = flg & (0x08 << 4*(i%2));
339
0
    acr_offset = offset;
340
0
    acr_tree = proto_tree_add_subtree_format(acrs_tree, tvb, offset, 0, ett_etf_acr, &ti_acr, "AtomCacheRef[%2d]:", i);
341
0
    proto_tree_add_item_ret_uint(acr_tree, hf_erldp_internal_segment_index, tvb, offset, 1, ENC_BIG_ENDIAN, &isi);
342
0
    proto_item_append_text(ti_acr, " %3d", isi);
343
0
    offset++;
344
0
    if (!new_entry)
345
0
      continue;
346
0
    if (long_atom) {
347
0
      proto_tree_add_item_ret_uint(acr_tree, hf_erldp_atom_length2, tvb, offset, 2, ENC_BIG_ENDIAN, &atom_txt_len);
348
0
      offset += 2;
349
0
    }
350
0
    else {
351
0
      proto_tree_add_item_ret_uint(acr_tree, hf_erldp_atom_length, tvb, offset, 1, ENC_BIG_ENDIAN, &atom_txt_len);
352
0
      offset++;
353
0
    }
354
0
    proto_tree_add_item_ret_string(acr_tree, hf_erldp_atom_text, tvb, offset, atom_txt_len, ENC_NA|ENC_ASCII, pinfo->pool, &str);
355
0
    proto_item_append_text(ti_acr, " - '%s'", str);
356
0
    offset += atom_txt_len;
357
0
    proto_item_set_len(ti_acr, offset - acr_offset);
358
0
  }
359
0
  proto_item_set_len(ti_acrs, offset - acrs_offset);
360
361
0
  return offset;
362
0
}
363
364
// NOLINTNEXTLINE(misc-no-recursion)
365
0
static int dissect_etf_tuple_content(bool large, packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree, const char **value_str _U_) {
366
0
  uint32_t arity, i;
367
368
0
  if (large) {
369
0
    proto_tree_add_item_ret_uint(tree, hf_etf_arity4, tvb, offset, 4, ENC_BIG_ENDIAN, &arity);
370
0
    offset += 4;
371
0
  } else {
372
0
    proto_tree_add_item_ret_uint(tree, hf_etf_arity, tvb, offset, 1, ENC_BIG_ENDIAN, &arity);
373
0
    offset++;
374
0
  }
375
0
  for (i=0; i<arity; i++) {
376
0
    offset = dissect_etf_type(NULL, pinfo, tvb, offset, tree);
377
0
  }
378
379
0
  return offset;
380
0
}
381
382
0
static int dissect_etf_big_ext(tvbuff_t *tvb, packet_info *pinfo, int offset, uint32_t len, proto_tree *tree, const char **value_str) {
383
0
      uint8_t sign;
384
0
      int32_t i;
385
386
0
      sign = tvb_get_uint8(tvb, offset);
387
0
      offset += 1;
388
389
0
      if (len <= 8) {
390
0
        uint64_t big_val = 0;
391
392
0
        switch (len) {
393
0
        case 1: big_val = tvb_get_uint8(tvb, offset); break;
394
0
        case 2: big_val = tvb_get_letohs(tvb, offset); break;
395
0
        case 3: big_val = tvb_get_letoh24(tvb, offset); break;
396
0
        case 4: big_val = tvb_get_letohl(tvb, offset); break;
397
0
        case 5: big_val = tvb_get_letoh40(tvb, offset); break;
398
0
        case 6: big_val = tvb_get_letoh48(tvb, offset); break;
399
0
        case 7: big_val = tvb_get_letoh56(tvb, offset); break;
400
0
        case 8: big_val = tvb_get_letoh64(tvb, offset); break;
401
0
        }
402
0
        proto_tree_add_uint64_format_value(tree, hf_erldp_big_ext_int, tvb, offset, len,
403
0
                                           big_val, "%s%" PRIu64, sign ? "-"  : "", big_val);
404
0
        if (value_str)
405
0
          *value_str = wmem_strdup_printf(pinfo->pool, "%s%" PRIu64,
406
0
                                          sign ? "-"  : "", big_val);
407
0
      } if (len < 64) {
408
0
        wmem_strbuf_t *strbuf = wmem_strbuf_new_sized(pinfo->pool, len*1+3+1);
409
410
0
        wmem_strbuf_append(strbuf, "0x");
411
0
        for (i = len - 1; i >= 0; i--) {
412
0
          wmem_strbuf_append_printf(strbuf, "%02x", tvb_get_uint8(tvb, offset + i));
413
0
        }
414
0
        char *buf = wmem_strbuf_finalize(strbuf);
415
416
0
        proto_tree_add_string_format_value(tree, hf_erldp_big_ext_str, tvb, offset, len, buf, "%s", buf);
417
418
0
        if (value_str)
419
0
          *value_str = buf;
420
0
      } else
421
0
        proto_tree_add_item(tree, hf_erldp_big_ext_bytes, tvb, offset, len, ENC_NA);
422
423
0
      return offset + len;
424
0
}
425
426
// NOLINTNEXTLINE(misc-no-recursion)
427
0
static int dissect_etf_type_content(uint8_t tag, packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree, const char **value_str) {
428
0
  int32_t int_val;
429
0
  uint32_t len, i, uint_val;
430
0
  uint32_t id;
431
0
  const uint8_t *str_val;
432
433
0
  increment_dissection_depth(pinfo);
434
435
0
  switch (tag) {
436
0
    case ATOM_CACHE_REF:
437
0
      proto_tree_add_item_ret_uint(tree, hf_erldp_atom_cache_ref, tvb, offset, 1, ENC_BIG_ENDIAN, &uint_val);
438
0
      offset += 1;
439
0
      if (value_str)
440
0
        *value_str = wmem_strdup_printf(pinfo->pool, "%d", uint_val);
441
0
      break;
442
443
0
    case SMALL_INTEGER_EXT:
444
0
      proto_tree_add_item_ret_uint(tree, hf_erldp_small_int_ext, tvb, offset, 1, ENC_BIG_ENDIAN, &uint_val);
445
0
      offset += 1;
446
0
      if (value_str)
447
0
        *value_str = wmem_strdup_printf(pinfo->pool, "%u", uint_val);
448
0
      break;
449
450
0
    case INTEGER_EXT:
451
0
      proto_tree_add_item_ret_int(tree, hf_erldp_int_ext, tvb, offset, 4, ENC_BIG_ENDIAN, &int_val);
452
0
      offset += 4;
453
0
      if (value_str)
454
0
        *value_str = wmem_strdup_printf(pinfo->pool, "%d", int_val);
455
0
      break;
456
457
0
    case SMALL_BIG_EXT: {
458
0
      proto_tree_add_item_ret_uint(tree, hf_erldp_small_big_ext_len, tvb, offset, 1, ENC_BIG_ENDIAN, &len);
459
0
      offset += 1;
460
461
0
      offset = dissect_etf_big_ext(tvb, pinfo, offset, len, tree, value_str);
462
0
      break;
463
0
    }
464
465
0
    case LARGE_BIG_EXT: {
466
0
      proto_tree_add_item_ret_uint(tree, hf_erldp_large_big_ext_len, tvb, offset, 4, ENC_BIG_ENDIAN, &len);
467
0
      offset += 4;
468
469
0
      offset = dissect_etf_big_ext(tvb, pinfo, offset, len, tree, value_str);
470
0
      break;
471
0
    }
472
473
0
    case FLOAT_EXT:
474
0
      proto_tree_add_item_ret_string(tree, hf_erldp_float_ext, tvb, offset, 31, ENC_NA|ENC_UTF_8, pinfo->pool, &str_val);
475
0
      offset += 31;
476
0
      if (value_str)
477
0
        *value_str = (const char *)str_val;
478
0
      break;
479
480
0
    case NEW_FLOAT_EXT:
481
0
      proto_tree_add_item(tree, hf_erldp_new_float_ext, tvb, offset, 8, ENC_BIG_ENDIAN);
482
0
      if (value_str) {
483
0
        double   new_float_val = tvb_get_ntohieee_double(tvb, offset);
484
0
        *value_str = wmem_strdup_printf(pinfo->pool, "%f", new_float_val);
485
0
      }
486
0
      offset += 8;
487
0
      break;
488
489
0
    case ATOM_UTF8_EXT:
490
0
      proto_tree_add_item_ret_uint(tree, hf_erldp_atom_length2, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
491
0
      offset += 2;
492
0
      proto_tree_add_item_ret_string(tree, hf_erldp_atom_text, tvb, offset, len, ENC_NA|ENC_UTF_8, pinfo->pool, &str_val);
493
0
      offset += len;
494
0
      if (value_str)
495
0
        *value_str = (const char *)str_val;
496
0
      break;
497
498
0
    case SMALL_ATOM_UTF8_EXT:
499
0
      proto_tree_add_item_ret_uint(tree, hf_erldp_atom_length, tvb, offset, 1, ENC_BIG_ENDIAN, &len);
500
0
      offset++;
501
0
      proto_tree_add_item_ret_string(tree, hf_erldp_atom_text, tvb, offset, len, ENC_NA|ENC_UTF_8, pinfo->pool, &str_val);
502
0
      offset += len;
503
0
      if (value_str)
504
0
        *value_str = (const char *)str_val;
505
0
      break;
506
507
0
    case STRING_EXT:
508
0
      proto_tree_add_item_ret_uint(tree, hf_erldp_string_ext_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
509
0
      offset += 2;
510
0
      proto_tree_add_item_ret_string(tree, hf_erldp_string_ext, tvb, offset, len, ENC_NA|ENC_UTF_8, pinfo->pool, &str_val);
511
0
      offset += len;
512
0
      if (value_str)
513
0
        *value_str = (const char *)str_val;
514
0
      break;
515
516
0
    case PORT_EXT:
517
0
      offset = dissect_etf_type("Node", pinfo, tvb, offset, tree);
518
0
      proto_tree_add_item(tree, hf_erldp_port_ext_id, tvb, offset, 4, ENC_BIG_ENDIAN);
519
0
      offset += 4;
520
0
      proto_tree_add_item(tree, hf_erldp_port_ext_creation, tvb, offset, 1, ENC_BIG_ENDIAN);
521
0
      offset++;
522
0
      break;
523
524
0
    case NEW_PORT_EXT:
525
0
      offset = dissect_etf_type("Node", pinfo, tvb, offset, tree);
526
0
      proto_tree_add_item(tree, hf_erldp_port_ext_id, tvb, offset, 4, ENC_BIG_ENDIAN);
527
0
      offset += 4;
528
0
      proto_tree_add_item(tree, hf_erldp_port_ext_creation, tvb, offset, 4, ENC_BIG_ENDIAN);
529
0
      offset += 4;
530
0
      break;
531
532
0
    case V4_PORT_EXT:
533
0
      offset = dissect_etf_type("Node", pinfo, tvb, offset, tree);
534
0
      proto_tree_add_item(tree, hf_erldp_port_ext_v4_id, tvb, offset, 8, ENC_BIG_ENDIAN);
535
0
      offset += 8;
536
0
      proto_tree_add_item(tree, hf_erldp_port_ext_creation, tvb, offset, 4, ENC_BIG_ENDIAN);
537
0
      offset += 4;
538
0
      break;
539
540
0
    case PID_EXT:
541
0
      offset = dissect_etf_type("Node", pinfo, tvb, offset, tree);
542
0
      proto_tree_add_item(tree, hf_erldp_pid_ext_id, tvb, offset, 4, ENC_BIG_ENDIAN);
543
0
      offset += 4;
544
0
      proto_tree_add_item(tree, hf_erldp_pid_ext_serial, tvb, offset, 4, ENC_BIG_ENDIAN);
545
0
      offset += 4;
546
0
      proto_tree_add_item(tree, hf_erldp_pid_ext_creation, tvb, offset, 1, ENC_BIG_ENDIAN);
547
0
      offset++;
548
0
      break;
549
550
0
    case NEW_PID_EXT:
551
0
      offset = dissect_etf_type("Node", pinfo, tvb, offset, tree);
552
0
      proto_tree_add_item(tree, hf_erldp_pid_ext_id, tvb, offset, 4, ENC_BIG_ENDIAN);
553
0
      offset += 4;
554
0
      proto_tree_add_item(tree, hf_erldp_pid_ext_serial, tvb, offset, 4, ENC_BIG_ENDIAN);
555
0
      offset += 4;
556
0
      proto_tree_add_item(tree, hf_erldp_pid_ext_creation, tvb, offset, 4, ENC_BIG_ENDIAN);
557
0
      offset += 4;
558
0
      break;
559
560
0
    case SMALL_TUPLE_EXT:
561
0
      offset = dissect_etf_tuple_content(false, pinfo, tvb, offset, tree, value_str);
562
0
      break;
563
564
0
    case LARGE_TUPLE_EXT:
565
0
      offset = dissect_etf_tuple_content(true, pinfo, tvb, offset, tree, value_str);
566
0
      break;
567
568
0
    case NIL_EXT:
569
0
      break;
570
571
0
    case LIST_EXT:
572
0
      proto_tree_add_item_ret_uint(tree, hf_erldp_list_ext_len, tvb, offset, 4, ENC_BIG_ENDIAN, &len);
573
0
      offset += 4;
574
0
      for (i=0; i<len; i++) {
575
0
        offset = dissect_etf_type(NULL, pinfo, tvb, offset, tree);
576
0
      }
577
0
      offset = dissect_etf_type("Tail", pinfo, tvb, offset, tree);
578
0
      break;
579
580
0
    case MAP_EXT:
581
0
      proto_tree_add_item_ret_uint(tree, hf_erldp_map_ext_len, tvb, offset, 4, ENC_BIG_ENDIAN, &len);
582
0
      offset += 4;
583
0
      for (i=0; i<len; i++) {
584
        // key
585
0
        offset = dissect_etf_type(NULL, pinfo, tvb, offset, tree);
586
        // value
587
0
        offset = dissect_etf_type(NULL, pinfo, tvb, offset, tree);
588
0
      }
589
0
      break;
590
591
0
    case BINARY_EXT:
592
0
      proto_tree_add_item_ret_uint(tree, hf_erldp_binary_ext_len, tvb, offset, 4, ENC_BIG_ENDIAN, &len);
593
0
      offset += 4;
594
0
      proto_tree_add_item(tree, hf_erldp_binary_ext, tvb, offset, len, ENC_NA);
595
0
      offset += len;
596
0
      break;
597
598
0
    case BIT_BINARY_EXT:
599
0
      proto_tree_add_item_ret_uint(tree, hf_erldp_binary_ext_len, tvb, offset, 4, ENC_BIG_ENDIAN, &len);
600
0
      offset += 4;
601
0
      proto_tree_add_item(tree, hf_erldp_binary_ext_bits, tvb, offset, 1, ENC_BIG_ENDIAN);
602
0
      offset++;
603
0
      proto_tree_add_item(tree, hf_erldp_binary_ext, tvb, offset, len, ENC_NA);
604
0
      offset += len;
605
0
      break;
606
607
0
    case NEW_REFERENCE_EXT:
608
0
      proto_tree_add_item_ret_uint(tree, hf_erldp_new_ref_ext_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
609
0
      offset += 2;
610
0
      offset = dissect_etf_type("Node", pinfo, tvb, offset, tree);
611
0
      proto_tree_add_item(tree, hf_erldp_new_ref_ext_creation, tvb, offset, 1, ENC_BIG_ENDIAN);
612
0
      offset++;
613
0
      for (i=0; i<len; i++) {
614
0
        id = tvb_get_ntohl(tvb, offset);
615
0
        proto_tree_add_uint_format(tree, hf_erldp_new_ref_ext_id, tvb, offset, 4,
616
0
                            id, "ID[%d]: 0x%08X", i, id);
617
0
        offset += 4;
618
0
      }
619
0
      break;
620
621
0
    case NEWER_REFERENCE_EXT:
622
0
      proto_tree_add_item_ret_uint(tree, hf_erldp_new_ref_ext_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
623
0
      offset += 2;
624
0
      offset = dissect_etf_type("Node", pinfo, tvb, offset, tree);
625
0
      proto_tree_add_item(tree, hf_erldp_new_ref_ext_creation, tvb, offset, 4, ENC_BIG_ENDIAN);
626
0
      offset += 4;
627
0
      for (i=0; i<len; i++) {
628
0
        id = tvb_get_ntohl(tvb, offset);
629
0
        proto_tree_add_uint_format(tree, hf_erldp_new_ref_ext_id, tvb, offset, 4,
630
0
                            id, "ID[%d]: 0x%08X", i, id);
631
0
        offset += 4;
632
0
      }
633
0
      break;
634
635
0
    case FUN_EXT:
636
0
      proto_tree_add_item_ret_uint(tree, hf_erldp_fun_ext_num_free, tvb, offset, 4, ENC_BIG_ENDIAN, &len);
637
0
      offset += 4;
638
0
      offset = dissect_etf_type("Pid", pinfo, tvb, offset, tree);
639
0
      offset = dissect_etf_type("Module", pinfo, tvb, offset, tree);
640
0
      offset = dissect_etf_type("Index", pinfo, tvb, offset, tree);
641
0
      offset = dissect_etf_type("Unique", pinfo, tvb, offset, tree);
642
643
0
      for (i = 0; i < len; i++) {
644
0
          char buf[ITEM_LABEL_LENGTH];
645
0
          snprintf(buf, sizeof(buf), "Free Var[%u]", i + 1);
646
0
          offset = dissect_etf_type(buf, pinfo, tvb, offset, tree);
647
0
      }
648
0
      break;
649
650
0
    case NEW_FUN_EXT:
651
0
      proto_tree_add_item(tree, hf_erldp_new_fun_ext_size, tvb, offset, 4, ENC_BIG_ENDIAN);
652
0
      offset += 4;
653
0
      proto_tree_add_item(tree, hf_erldp_new_fun_ext_arity, tvb, offset, 1, ENC_BIG_ENDIAN);
654
0
      offset += 1;
655
0
      proto_tree_add_item(tree, hf_erldp_new_fun_ext_uniq, tvb, offset, 16, ENC_NA);
656
0
      offset += 16;
657
0
      proto_tree_add_item(tree, hf_erldp_new_fun_ext_index, tvb, offset, 4, ENC_BIG_ENDIAN);
658
0
      offset += 4;
659
0
      proto_tree_add_item_ret_uint(tree, hf_erldp_new_fun_ext_num_free, tvb, offset, 4, ENC_BIG_ENDIAN, &len);
660
0
      offset += 4;
661
0
      offset = dissect_etf_type("Module", pinfo, tvb, offset, tree);
662
0
      offset = dissect_etf_type("OldIndex", pinfo, tvb, offset, tree);
663
0
      offset = dissect_etf_type("OldUnique", pinfo, tvb, offset, tree);
664
0
      offset = dissect_etf_type("Pid", pinfo, tvb, offset, tree);
665
666
0
      for (i = 0; i < len; i++) {
667
0
          char buf[ITEM_LABEL_LENGTH];
668
0
          snprintf(buf, sizeof(buf), "Free Var[%u]", i + 1);
669
0
          offset = dissect_etf_type(buf, pinfo, tvb, offset, tree);
670
0
      }
671
0
      break;
672
673
0
    case EXPORT_EXT:
674
0
      offset = dissect_etf_type("Module", pinfo, tvb, offset, tree);
675
0
      offset = dissect_etf_type("Function", pinfo, tvb, offset, tree);
676
0
      offset = dissect_etf_type("Arity", pinfo, tvb, offset, tree);
677
0
      break;
678
0
  }
679
680
0
  decrement_dissection_depth(pinfo);
681
682
0
  return offset;
683
0
}
684
685
0
static int dissect_etf_pdu_data(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree) {
686
0
  uint8_t ctl_op;
687
688
0
  if ((tvb_get_uint8(tvb, offset) == SMALL_TUPLE_EXT) && (tvb_get_uint8(tvb, offset + 2) == SMALL_INTEGER_EXT)) {
689
0
    ctl_op = tvb_get_uint8(tvb, offset + 3);
690
0
    col_add_str(pinfo->cinfo, COL_INFO, val_to_str(pinfo->pool, ctl_op, VALS(erldp_ctlmsg_vals), "unknown ControlMessage operation (%d)"));
691
0
  }
692
0
  offset = dissect_etf_type("ControlMessage", pinfo, tvb, offset, tree);
693
0
  if (tvb_reported_length_remaining(tvb, offset) > 0)
694
0
    offset = dissect_etf_type("Message", pinfo, tvb, offset, tree);
695
696
0
  return offset;
697
0
}
698
699
0
static int dissect_etf_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, const char *label) {
700
0
  int offset = 0;
701
0
  uint8_t mag;
702
0
  uint32_t tag;
703
0
  proto_item *ti;
704
0
  proto_tree *etf_tree;
705
706
0
  mag = tvb_get_uint8(tvb, offset);
707
0
  if (mag != VERSION_MAGIC) {
708
0
    return 0;
709
0
  }
710
711
0
  etf_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_etf, &ti, (label) ? label : "External Term Format");
712
713
0
  proto_tree_add_item(etf_tree, hf_etf_version_magic, tvb, offset, 1, ENC_BIG_ENDIAN);
714
0
  offset++;
715
716
0
  proto_tree_add_item_ret_uint(etf_tree, hf_etf_dist_header_tag, tvb, offset, 1, ENC_BIG_ENDIAN, &tag);
717
0
  offset++;
718
719
0
  if (!label)
720
0
    proto_item_set_text(ti, "%s", val_to_str(pinfo->pool, tag, VALS(etf_header_tag_vals), "unknown tag (%d)"));
721
722
0
  switch (tag) {
723
0
    case DIST_HEADER:
724
0
      offset = dissect_etf_dist_header(pinfo, tvb, offset, etf_tree);
725
0
      proto_item_set_len(ti, offset);
726
727
0
      dissect_etf_pdu_data(pinfo, tvb, offset, tree);
728
0
      break;
729
730
0
    case DIST_FRAG_HEADER:
731
0
    case DIST_FRAG_CONT:
732
0
    {
733
0
      uint64_t sequence_id, fragment_id;
734
0
      bool save_fragmented;
735
0
      fragment_head *frag_msg = NULL;
736
0
      tvbuff_t *next_tvb = NULL;
737
0
      int len_rem;
738
739
0
      proto_tree_add_item_ret_uint64(etf_tree, hf_erldp_sequence_id, tvb, offset, 8, ENC_BIG_ENDIAN, &sequence_id);
740
0
      offset += 8;
741
742
0
      proto_tree_add_item_ret_uint64(etf_tree, hf_erldp_fragment_id, tvb, offset, 8, ENC_BIG_ENDIAN, &fragment_id);
743
0
      offset += 8;
744
745
0
      save_fragmented = pinfo->fragmented;
746
747
0
      len_rem = tvb_reported_length_remaining(tvb, offset);
748
0
      if (len_rem <= 0)
749
0
        return offset;
750
751
0
      pinfo->fragmented = true;
752
753
0
      frag_msg = fragment_add_seq_next(&erldp_reassembly_table,
754
0
                                       tvb, offset, pinfo, (uint32_t)sequence_id, NULL,
755
0
                                       len_rem, fragment_id != 1);
756
757
0
      next_tvb = process_reassembled_data(tvb, offset, pinfo,
758
0
                                          "Reassembled ErlDP", frag_msg,
759
0
                                          &etf_frag_items, NULL, tree);
760
761
0
      if (next_tvb == NULL)
762
0
      { /* make a new subset */
763
0
        next_tvb = tvb_new_subset_remaining(tvb, offset);
764
0
        call_data_dissector(next_tvb, pinfo, tree);
765
0
        col_append_fstr(pinfo->cinfo, COL_INFO, " (Fragment ID: %" PRIu64 ")", fragment_id);
766
0
      }
767
0
      else
768
0
      {
769
0
        offset = dissect_etf_dist_header(pinfo, next_tvb, 0, etf_tree);
770
0
        proto_item_set_len(ti, offset);
771
772
0
        dissect_etf_pdu_data(pinfo, next_tvb, offset, tree);
773
0
        col_append_fstr(pinfo->cinfo, COL_INFO, " (Reassembled, Fragment ID: %" PRIu64 ")", fragment_id);
774
0
      }
775
776
0
      pinfo->fragmented = save_fragmented;
777
0
      offset = tvb_reported_length_remaining(tvb, offset);
778
0
      break;
779
0
    }
780
0
  }
781
782
0
  return offset;
783
0
}
784
785
0
static int dissect_etf_versioned_type(const char *label, packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree) {
786
0
  if (tvb_get_uint8(tvb, offset) != VERSION_MAGIC) {
787
0
    proto_tree_add_item(tree, hf_erldp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
788
0
    col_set_str(pinfo->cinfo, COL_INFO, "unknown header format");
789
0
    return offset + 1;
790
0
  }
791
0
  offset += 1;
792
793
0
  return dissect_etf_type(label, pinfo, tvb, offset, tree);
794
0
}
795
796
// NOLINTNEXTLINE(misc-no-recursion)
797
0
static int dissect_etf_type(const char *label, packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *tree) {
798
0
  int begin = offset;
799
0
  uint32_t tag;
800
0
  proto_item *ti;
801
0
  proto_tree *etf_tree;
802
0
  const char *value_str = NULL;
803
804
0
  etf_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_etf, &ti, (label) ? label : "External Term Format");
805
806
0
  proto_tree_add_item_ret_uint(etf_tree, hf_etf_tag, tvb, offset, 1, ENC_BIG_ENDIAN, &tag);
807
0
  offset++;
808
809
0
  if (!label)
810
0
    proto_item_set_text(ti, "%s", val_to_str(pinfo->pool, tag, VALS(etf_tag_vals), "unknown tag (%d)"));
811
812
0
  offset = dissect_etf_type_content(tag, pinfo, tvb, offset, etf_tree, &value_str);
813
0
  if (value_str)
814
0
    proto_item_append_text(ti, ": %s", value_str);
815
816
0
  proto_item_set_len(ti, offset - begin);
817
818
0
  return offset;
819
0
}
820
821
0
static bool is_handshake(tvbuff_t *tvb, int offset) {
822
0
  uint32_t len = tvb_get_ntohs(tvb, offset);
823
0
  uint8_t tag = tvb_get_uint8(tvb, offset + 2);
824
0
  return ((len > 0) && strchr("nNras", tag) && (len == (uint32_t)tvb_captured_length_remaining(tvb, offset + 2)));
825
0
}
826
827
/*--- dissect_erldp_handshake -------------------------------------------------*/
828
0
static void dissect_erldp_handshake(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
829
0
  int offset = 0;
830
0
  uint32_t tag;
831
0
  bool is_challenge = false;
832
0
  uint32_t str_len;
833
0
  const uint8_t *str;
834
835
0
  static int * const erldp_flags_flags[] = {
836
0
    &hf_erldp_flags_spare,
837
0
    &hf_erldp_flags_alias,
838
0
    &hf_erldp_flags_v4_nc,
839
0
    &hf_erldp_flags_name_me,
840
0
    &hf_erldp_flags_spawn,
841
0
    &hf_erldp_flags_reserved,
842
0
    &hf_erldp_flags_unlink_id,
843
0
    &hf_erldp_flags_handshake_23,
844
0
    &hf_erldp_flags_fragments,
845
0
    &hf_erldp_flags_exit_payload,
846
0
    &hf_erldp_flags_pending_connect,
847
0
    &hf_erldp_flags_big_seqtrace_labels,
848
0
    &hf_erldp_flags_send_sender,
849
0
    &hf_erldp_flags_big_creation,
850
0
    &hf_erldp_flags_map_tag,
851
0
    &hf_erldp_flags_utf8_atoms,
852
0
    &hf_erldp_flags_ets_compressed,
853
0
    &hf_erldp_flags_small_atom_tags,
854
0
    &hf_erldp_flags_dist_hdr_atom_cache,
855
0
    &hf_erldp_flags_unicode_io,
856
0
    &hf_erldp_flags_new_floats,
857
0
    &hf_erldp_flags_bit_binaries,
858
0
    &hf_erldp_flags_export_ptr_tag,
859
0
    &hf_erldp_flags_extended_pids_ports,
860
0
    &hf_erldp_flags_new_fun_tags,
861
0
    &hf_erldp_flags_hidden_atom_cache,
862
0
    &hf_erldp_flags_dist_monitor_name,
863
0
    &hf_erldp_flags_fun_tags,
864
0
    &hf_erldp_flags_dist_monitor,
865
0
    &hf_erldp_flags_extended_references,
866
0
    &hf_erldp_flags_atom_cache,
867
0
    &hf_erldp_flags_published,
868
0
    NULL
869
0
  };
870
871
0
  proto_tree_add_item(tree, hf_erldp_length_2, tvb, offset, 2, ENC_BIG_ENDIAN);
872
0
  offset += 2;
873
0
  proto_tree_add_item_ret_uint(tree, hf_erldp_tag, tvb, offset, 1, ENC_ASCII, &tag);
874
0
  offset++;
875
876
0
  switch (tag) {
877
0
    case 'n' :
878
0
      proto_tree_add_item(tree, hf_erldp_version, tvb, offset, 2, ENC_BIG_ENDIAN);
879
0
      offset += 2;
880
881
0
      proto_tree_add_bitmask(tree, tvb, offset, hf_erldp_flags_v5,
882
0
         ett_erldp_flags, erldp_flags_flags, ENC_BIG_ENDIAN);
883
0
      offset += 4;
884
0
      if (tvb_bytes_exist(tvb, offset, 4)) {
885
0
        if (!tvb_ascii_isprint(tvb, offset, 4)) {
886
0
          is_challenge = true;
887
0
        }
888
0
      }
889
0
      if (is_challenge) {
890
0
        proto_tree_add_item(tree, hf_erldp_challenge, tvb, offset, 4, ENC_BIG_ENDIAN);
891
0
        offset += 4;
892
0
      }
893
0
      str_len = tvb_captured_length_remaining(tvb, offset);
894
0
      proto_tree_add_item_ret_string(tree, hf_erldp_name, tvb, offset, str_len, ENC_ASCII|ENC_NA, pinfo->pool, &str);
895
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s", (is_challenge) ? "SEND_CHALLENGE" : "SEND_NAME", str);
896
0
      break;
897
898
0
    case 'N':
899
0
      proto_tree_add_bitmask(tree, tvb, offset, hf_erldp_flags_v6,
900
0
         ett_erldp_flags, erldp_flags_flags, ENC_BIG_ENDIAN);
901
0
      offset += 8;
902
0
      if (tvb_bytes_exist(tvb, offset + 6, 4)) {
903
0
        if (!tvb_ascii_isprint(tvb, offset + 6, 4)) {
904
0
          is_challenge = true;
905
0
        }
906
0
      }
907
0
      if (is_challenge) {
908
0
        proto_tree_add_item(tree, hf_erldp_challenge, tvb, offset, 4, ENC_BIG_ENDIAN);
909
0
        offset += 4;
910
0
      }
911
0
      proto_tree_add_item(tree, hf_erldp_creation, tvb, offset, 4, ENC_BIG_ENDIAN);
912
0
      offset += 4;
913
0
      proto_tree_add_item_ret_uint(tree, hf_erldp_nlen, tvb, offset, 2, ENC_BIG_ENDIAN, &str_len);
914
0
      offset += 2;
915
0
      proto_tree_add_item_ret_string(tree, hf_erldp_name, tvb, offset, str_len, ENC_ASCII|ENC_NA, pinfo->pool, &str);
916
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s", (is_challenge) ? "SEND_CHALLENGE" : "SEND_NAME", str);
917
0
      break;
918
919
0
    case 'r' :
920
0
      proto_tree_add_item(tree, hf_erldp_challenge, tvb, offset, 4, ENC_BIG_ENDIAN);
921
0
      offset += 4;
922
0
      proto_tree_add_item(tree, hf_erldp_digest, tvb, offset, 16, ENC_NA);
923
      /*offset += 16;*/
924
0
      col_set_str(pinfo->cinfo, COL_INFO, "SEND_CHALLENGE_REPLY");
925
0
      break;
926
927
0
    case 'a' :
928
0
      proto_tree_add_item(tree, hf_erldp_digest, tvb, offset, 16, ENC_NA);
929
      /*offset += 16;*/
930
0
      col_set_str(pinfo->cinfo, COL_INFO, "SEND_CHALLENGE_ACK");
931
0
      break;
932
933
0
    case 's' :
934
0
      str_len = tvb_captured_length_remaining(tvb, offset);
935
0
      proto_tree_add_item_ret_string(tree, hf_erldp_status, tvb, offset, str_len, ENC_ASCII|ENC_NA, pinfo->pool, &str);
936
0
      col_add_fstr(pinfo->cinfo, COL_INFO, "SEND_STATUS %s", str);
937
0
      break;
938
0
  }
939
0
}
940
941
/*--- dissect_erldp_pdu -------------------------------------------------*/
942
0
static int dissect_erldp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
943
0
  int offset;
944
0
  uint32_t msg_len;
945
0
  uint8_t type;
946
0
  proto_tree *erldp_tree;
947
0
  proto_item *ti;
948
0
  tvbuff_t *next_tvb = NULL;
949
950
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "ErlDP");
951
952
0
  ti = proto_tree_add_item(tree, proto_erldp, tvb, 0, -1, ENC_NA);
953
0
  erldp_tree = proto_item_add_subtree(ti, ett_erldp);
954
955
0
  if (is_handshake(tvb, 0)) {
956
0
    dissect_erldp_handshake(tvb, pinfo, erldp_tree);
957
0
    return tvb_captured_length(tvb);
958
0
  }
959
960
0
  offset = 0;
961
962
0
  proto_tree_add_item_ret_uint(erldp_tree, hf_erldp_length_4, tvb, offset, 4, ENC_BIG_ENDIAN, &msg_len);
963
0
  offset += 4;
964
965
0
  if (msg_len == 0) {
966
0
    col_set_str(pinfo->cinfo, COL_INFO, "KEEP_ALIVE");
967
0
    return offset;
968
0
  }
969
970
0
  type = tvb_get_uint8(tvb, offset);
971
0
  switch (type) {
972
0
    case ERL_PASS_THROUGH:
973
0
      proto_tree_add_item(erldp_tree, hf_erldp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
974
0
      offset += 1;
975
976
0
      offset = dissect_etf_versioned_type("ControlMessage", pinfo, tvb, offset, erldp_tree);
977
0
      if (tvb_reported_length_remaining(tvb, offset) > 0) {
978
0
        dissect_etf_versioned_type("Message", pinfo, tvb, offset, erldp_tree);
979
0
      }
980
0
      break;
981
982
0
    case VERSION_MAGIC:
983
0
      next_tvb = tvb_new_subset_length(tvb, offset, 4 + msg_len - offset);
984
0
      dissect_etf_pdu(next_tvb, pinfo, erldp_tree, "DistributionHeader");
985
0
     break;
986
987
0
    default:
988
0
      proto_tree_add_item(erldp_tree, hf_erldp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
989
0
      offset++;
990
0
      col_set_str(pinfo->cinfo, COL_INFO, "unknown header format");
991
0
  }
992
993
0
  return tvb_captured_length(tvb);
994
0
}
995
996
/*--- get_erldp_pdu_len -------------------------------------------------*/
997
static unsigned get_erldp_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb,
998
                               int offset, void *data _U_)
999
0
{
1000
0
  if (is_handshake(tvb, offset))
1001
0
    return 2 + tvb_get_ntohs(tvb, offset);
1002
1003
0
  return 4 + tvb_get_ntohl(tvb, offset);
1004
0
}
1005
1006
/*--- dissect_erldp -------------------------------------------------*/
1007
static int
1008
0
dissect_erldp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) {
1009
0
  tcp_dissect_pdus(tvb, pinfo, tree,
1010
0
                   erldp_desegment,    /* desegment or not   */
1011
0
                    4,               /* fixed-length part of the PDU */
1012
0
                   get_erldp_pdu_len,  /* routine to get the length of the PDU */
1013
0
                   dissect_erldp_pdu, data); /* routine to dissect a PDU */
1014
0
  return tvb_captured_length(tvb);
1015
0
}
1016
1017
/*--- proto_register_erldp ----------------------------------------------*/
1018
15
void proto_register_erldp(void) {
1019
  /* module_t *erldp_module; */
1020
1021
  /* List of fields */
1022
15
  static hf_register_info hf[] = {
1023
    /*--- Handshake fields ---*/
1024
15
    { &hf_erldp_length_2, { "Length", "erldp.len",
1025
15
                        FT_UINT16, BASE_DEC, NULL, 0x0,
1026
15
                        "Message Length", HFILL}},
1027
15
    { &hf_etf_version_magic, { "VERSION_MAGIC", "erldp.version_magic",
1028
15
                        FT_UINT8, BASE_DEC, NULL, 0x0,
1029
15
                        NULL, HFILL}},
1030
15
    { &hf_erldp_tag,  { "Tag", "erldp.tag",
1031
15
                        FT_CHAR, BASE_HEX, NULL, 0x0,
1032
15
                        NULL, HFILL}},
1033
15
    { &hf_erldp_type, { "Type", "erldp.type",
1034
15
                        FT_UINT8, BASE_DEC, NULL, 0x0,
1035
15
                        NULL, HFILL}},
1036
15
    { &hf_erldp_version, { "Version", "erldp.version",
1037
15
                        FT_UINT16, BASE_DEC, VALS(epmd_version_vals), 0x0,
1038
15
                        NULL, HFILL}},
1039
15
    { &hf_erldp_flags_v5, { "Flags", "erldp.flags_v5",
1040
15
                        FT_UINT32, BASE_HEX, NULL, 0x0,
1041
15
                        NULL, HFILL}},
1042
15
    { &hf_erldp_flags_v6, { "Flags", "erldp.flags_v6",
1043
15
                        FT_UINT64, BASE_HEX, NULL, 0x0,
1044
15
                        NULL, HFILL}},
1045
15
    { &hf_erldp_flags_published, { "Published", "erldp.flags.published",
1046
15
                        FT_BOOLEAN, 64, NULL, 0x1,
1047
15
                        NULL, HFILL }},
1048
15
    { &hf_erldp_flags_atom_cache, { "Atom Cache", "erldp.flags.atom_cache",
1049
15
                        FT_BOOLEAN, 64, NULL, 0x2,
1050
15
                        NULL, HFILL }},
1051
15
    { &hf_erldp_flags_extended_references, { "Extended References", "erldp.flags.extended_references",
1052
15
                        FT_BOOLEAN, 64, NULL, 0x4,
1053
15
                        NULL, HFILL }},
1054
15
    { &hf_erldp_flags_dist_monitor, { "Dist Monitor", "erldp.flags.dist_monitor",
1055
15
                        FT_BOOLEAN, 64, NULL, 0x8,
1056
15
                        NULL, HFILL }},
1057
15
    { &hf_erldp_flags_fun_tags, { "Fun Tags", "erldp.flags.fun_tags",
1058
15
                        FT_BOOLEAN, 64, NULL, 0x10,
1059
15
                        NULL, HFILL }},
1060
15
    { &hf_erldp_flags_dist_monitor_name, { "Dist Monitor Name", "erldp.flags.dist_monitor_name",
1061
15
                        FT_BOOLEAN, 64, NULL, 0x20,
1062
15
                        NULL, HFILL }},
1063
15
    { &hf_erldp_flags_hidden_atom_cache, { "Hidden Atom Cache", "erldp.flags.hidden_atom_cache",
1064
15
                        FT_BOOLEAN, 64, NULL, 0x40,
1065
15
                        NULL, HFILL }},
1066
15
    { &hf_erldp_flags_new_fun_tags, { "New Fun Tags", "erldp.flags.new_fun_tags",
1067
15
                        FT_BOOLEAN, 64, NULL, 0x80,
1068
15
                        NULL, HFILL }},
1069
15
    { &hf_erldp_flags_extended_pids_ports, { "Extended Pids Ports", "erldp.flags.extended_pids_ports",
1070
15
                        FT_BOOLEAN, 64, NULL, 0x100,
1071
15
                        NULL, HFILL }},
1072
15
    { &hf_erldp_flags_export_ptr_tag, { "Export PTR Tag", "erldp.flags.export_ptr_tag",
1073
15
                        FT_BOOLEAN, 64, NULL, 0x200,
1074
15
                        NULL, HFILL }},
1075
15
    { &hf_erldp_flags_bit_binaries, { "Bit Binaries", "erldp.flags.bit_binaries",
1076
15
                        FT_BOOLEAN, 64, NULL, 0x400,
1077
15
                        NULL, HFILL }},
1078
15
    { &hf_erldp_flags_new_floats, { "New Floats", "erldp.flags.new_floats",
1079
15
                        FT_BOOLEAN, 64, NULL, 0x800,
1080
15
                        NULL, HFILL }},
1081
15
    { &hf_erldp_flags_unicode_io, { "Unicode IO", "erldp.flags.unicode_io",
1082
15
                        FT_BOOLEAN, 64, NULL, 0x1000,
1083
15
                        NULL, HFILL }},
1084
15
    { &hf_erldp_flags_dist_hdr_atom_cache, { "Dist HDR Atom Cache", "erldp.flags.dist_hdr_atom_cache",
1085
15
                        FT_BOOLEAN, 64, NULL, 0x2000,
1086
15
                        NULL, HFILL }},
1087
15
    { &hf_erldp_flags_small_atom_tags, { "Small Atom Tags", "erldp.flags.small_atom_tags",
1088
15
                        FT_BOOLEAN, 64, NULL, 0x4000,
1089
15
                        NULL, HFILL }},
1090
15
    { &hf_erldp_flags_ets_compressed, { "ETS Compressed", "erldp.flags.ets_compressed",
1091
15
                        FT_BOOLEAN, 64, NULL, 0x8000,
1092
15
                        NULL, HFILL }},
1093
15
    { &hf_erldp_flags_utf8_atoms, { "UTF8 Atoms", "erldp.flags.utf8_atoms",
1094
15
                        FT_BOOLEAN, 64, NULL, 0x10000,
1095
15
                        NULL, HFILL }},
1096
15
    { &hf_erldp_flags_map_tag, { "Map Tag", "erldp.flags.map_tag",
1097
15
                        FT_BOOLEAN, 64, NULL, 0x20000,
1098
15
                        NULL, HFILL }},
1099
15
    { &hf_erldp_flags_big_creation, { "Big Creation", "erldp.flags.big_creation",
1100
15
                        FT_BOOLEAN, 64, NULL, 0x40000,
1101
15
                        NULL, HFILL }},
1102
15
    { &hf_erldp_flags_send_sender, { "Send Sender", "erldp.flags.send_sender",
1103
15
                        FT_BOOLEAN, 64, NULL, 0x80000,
1104
15
                        NULL, HFILL }},
1105
15
    { &hf_erldp_flags_big_seqtrace_labels, { "Big Seqtrace Labels", "erldp.flags.big_seqtrace_labels",
1106
15
                        FT_BOOLEAN, 64, NULL, 0x100000,
1107
15
                        NULL, HFILL }},
1108
15
    { &hf_erldp_flags_pending_connect, { "Pending Connect", "erldp.flags.pending_connect",
1109
15
                        FT_BOOLEAN, 64, NULL, 0x200000,
1110
15
                        NULL, HFILL }},
1111
15
    { &hf_erldp_flags_exit_payload, { "Exit Payload", "erldp.flags.exit_payload",
1112
15
                        FT_BOOLEAN, 64, NULL, 0x400000,
1113
15
                        NULL, HFILL }},
1114
15
    { &hf_erldp_flags_fragments, { "Fragments", "erldp.flags.fragments",
1115
15
                        FT_BOOLEAN, 64, NULL, 0x800000,
1116
15
                        NULL, HFILL }},
1117
15
    { &hf_erldp_flags_handshake_23, { "Handshake 23", "erldp.flags.handshake_23",
1118
15
                        FT_BOOLEAN, 64, NULL, 0x1000000,
1119
15
                        NULL, HFILL }},
1120
15
    { &hf_erldp_flags_unlink_id, { "Unlink Id", "erldp.flags.unlink_id",
1121
15
                        FT_BOOLEAN, 64, NULL, 0x2000000,
1122
15
                        NULL, HFILL }},
1123
15
    { &hf_erldp_flags_reserved, { "Reserved", "erldp.flags.reserved",
1124
15
                        FT_UINT64, BASE_DEC, NULL, 0xfc000000,
1125
15
                        NULL, HFILL }},
1126
15
    { &hf_erldp_flags_spawn, { "Spawn", "erldp.flags.spawn",
1127
15
                        FT_BOOLEAN, 64, NULL, 1ULL << 32,
1128
15
                        NULL, HFILL }},
1129
15
    { &hf_erldp_flags_name_me, { "Name ME", "erldp.flags.name_me",
1130
15
                        FT_BOOLEAN, 64, NULL, 1ULL << 33,
1131
15
                        NULL, HFILL }},
1132
15
    { &hf_erldp_flags_v4_nc, { "V4 NC", "erldp.flags.v4_nc",
1133
15
                        FT_BOOLEAN, 64, NULL, 1ULL << 34,
1134
15
                        NULL, HFILL }},
1135
15
    { &hf_erldp_flags_alias, { "Alias", "erldp.flags.alias",
1136
15
                        FT_BOOLEAN, 64, NULL, 1ULL << 35,
1137
15
                        NULL, HFILL }},
1138
15
    { &hf_erldp_flags_spare, { "Spare", "erldp.flags.spare",
1139
15
                        FT_UINT64, BASE_DEC, NULL,  ~(0ULL) << 36,
1140
15
                        NULL, HFILL }},
1141
15
    { &hf_erldp_creation, { "Creation", "erldp.creation",
1142
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1143
15
                        NULL, HFILL}},
1144
15
    { &hf_erldp_challenge, { "Challenge", "erldp.challenge",
1145
15
                        FT_UINT32, BASE_HEX, NULL, 0x0,
1146
15
                        NULL, HFILL}},
1147
15
    { &hf_erldp_digest, { "Digest", "erldp.digest",
1148
15
                        FT_BYTES, BASE_NONE, NULL, 0x0,
1149
15
                        NULL, HFILL}},
1150
15
    { &hf_erldp_nlen, { "Name Length", "erldp.nlen",
1151
15
                        FT_UINT16, BASE_DEC, NULL, 0x0,
1152
15
                        NULL, HFILL}},
1153
15
    { &hf_erldp_name, { "Name", "erldp.name",
1154
15
                        FT_STRING, BASE_NONE, NULL, 0x0,
1155
15
                        NULL, HFILL}},
1156
15
    { &hf_erldp_status, { "Status", "erldp.status",
1157
15
                        FT_STRING, BASE_NONE, NULL, 0x0,
1158
15
                        NULL, HFILL}},
1159
15
    { &hf_erldp_sequence_id, { "Sequence Id", "erldp.sequence_id",
1160
15
                        FT_UINT64, BASE_HEX, NULL, 0x0,
1161
15
                        NULL, HFILL}},
1162
15
    { &hf_erldp_fragment_id, { "Fragment Id", "erldp.fragment_id",
1163
15
                        FT_UINT64, BASE_HEX, NULL, 0x0,
1164
15
                        NULL, HFILL}},
1165
15
    { &hf_erldp_num_atom_cache_refs, { "NumberOfAtomCacheRefs", "erldp.num_atom_cache_refs",
1166
15
                        FT_UINT8, BASE_DEC, NULL, 0x0,
1167
15
                        NULL, HFILL}},
1168
15
    { &hf_erldp_etf_flags, { "Flags", "erldp.etf_flags",
1169
15
                        FT_BYTES, BASE_NONE, NULL, 0x0,
1170
15
                        NULL, HFILL}},
1171
15
    { &hf_erldp_internal_segment_index, { "InternalSegmentIndex", "erldp.internal_segment_index",
1172
15
                        FT_UINT8, BASE_DEC, NULL, 0x0,
1173
15
                        NULL, HFILL}},
1174
15
    { &hf_erldp_atom_length, { "Length", "erldp.atom_length",
1175
15
                        FT_UINT8, BASE_DEC, NULL, 0x0,
1176
15
                        NULL, HFILL}},
1177
15
    { &hf_erldp_atom_length2, { "Length", "erldp.atom_length",
1178
15
                        FT_UINT16, BASE_DEC, NULL, 0x0,
1179
15
                        NULL, HFILL}},
1180
15
    { &hf_erldp_atom_text, { "AtomText", "erldp.atom_text",
1181
15
                        FT_STRING, BASE_NONE, NULL, 0x0,
1182
15
                        NULL, HFILL}},
1183
15
    { &hf_erldp_string_ext_len, { "Len", "erldp.string_ext_len",
1184
15
                        FT_UINT16, BASE_DEC, NULL, 0x0,
1185
15
                        NULL, HFILL}},
1186
15
    { &hf_erldp_string_ext, { "String", "erldp.string_ext",
1187
15
                        FT_STRING, BASE_SHOW_ASCII_PRINTABLE, NULL, 0x0,
1188
15
                        NULL, HFILL}},
1189
15
    { &hf_erldp_atom_cache_ref, { "AtomCacheReferenceIndex", "erldp.atom_cache_ref",
1190
15
                        FT_UINT8, BASE_DEC, NULL, 0x0,
1191
15
                        NULL, HFILL}},
1192
15
    { &hf_erldp_small_int_ext, { "Int", "erldp.small_int_ext",
1193
15
                        FT_UINT8, BASE_DEC, NULL, 0x0,
1194
15
                        NULL, HFILL}},
1195
15
    { &hf_erldp_int_ext, { "Int", "erldp.int_ext",
1196
15
                        FT_INT32, BASE_DEC, NULL, 0x0,
1197
15
                        NULL, HFILL}},
1198
15
    { &hf_erldp_small_big_ext_len, { "Len", "erldp.small_big_ext_len",
1199
15
                        FT_UINT8, BASE_DEC, NULL, 0x0,
1200
15
                        NULL, HFILL}},
1201
15
    { &hf_erldp_large_big_ext_len, { "Len", "erldp.large_big_ext_len",
1202
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1203
15
                        NULL, HFILL}},
1204
15
    { &hf_erldp_big_ext_int, { "Int", "erldp.big_ext_int",
1205
15
                        FT_UINT64, BASE_DEC, NULL, 0x0,
1206
15
                        NULL, HFILL}},
1207
15
    { &hf_erldp_big_ext_str, { "Int", "erldp.big_ext_str",
1208
15
                        FT_STRING, BASE_NONE, NULL, 0x0,
1209
15
                        NULL, HFILL}},
1210
15
    { &hf_erldp_big_ext_bytes, { "Int", "erldp.big_ext_bytes",
1211
15
                        FT_BYTES, BASE_NONE, NULL, 0x0,
1212
15
                        NULL, HFILL}},
1213
15
    { &hf_erldp_float_ext, { "Float", "erldp.float_ext",
1214
15
                        FT_STRINGZ, BASE_NONE, NULL, 0x0,
1215
15
                        NULL, HFILL}},
1216
15
    { &hf_erldp_new_float_ext, { "Float", "erldp.new_float_ext",
1217
15
                        FT_DOUBLE, BASE_NONE, NULL, 0x0,
1218
15
                        NULL, HFILL}},
1219
15
    { &hf_erldp_port_ext_id, { "ID", "erldp.port_ext.id",
1220
15
                        FT_UINT32, BASE_HEX, NULL, 0x0,
1221
15
                        NULL, HFILL}},
1222
15
    { &hf_erldp_port_ext_v4_id, { "ID", "erldp.port_ext.v4_id",
1223
15
                        FT_UINT64, BASE_HEX, NULL, 0x0,
1224
15
                        NULL, HFILL}},
1225
15
    { &hf_erldp_port_ext_creation, { "Creation", "erldp.port_ext.creation",
1226
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1227
15
                        NULL, HFILL}},
1228
15
    { &hf_erldp_pid_ext_id, { "ID", "erldp.pid_ext.id",
1229
15
                        FT_UINT32, BASE_HEX, NULL, 0x0,
1230
15
                        NULL, HFILL}},
1231
15
    { &hf_erldp_pid_ext_serial, { "Serial", "erldp.pid_ext.serial",
1232
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1233
15
                        NULL, HFILL}},
1234
15
    { &hf_erldp_pid_ext_creation, { "Creation", "erldp.pid_ext.creation",
1235
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1236
15
                        NULL, HFILL}},
1237
15
    { &hf_erldp_list_ext_len, { "Len", "erldp.list_ext.len",
1238
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1239
15
                        NULL, HFILL}},
1240
15
    { &hf_erldp_map_ext_len, { "Len", "erldp.map_ext.len",
1241
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1242
15
                        NULL, HFILL}},
1243
15
    { &hf_erldp_binary_ext_len, { "Len", "erldp.binary_ext.len",
1244
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1245
15
                        NULL, HFILL}},
1246
15
    { &hf_erldp_binary_ext_bits, { "Num bits in last byte", "erldp.binary_ext.bits",
1247
15
                        FT_UINT8, BASE_DEC, NULL, 0x0,
1248
15
                        NULL, HFILL}},
1249
15
    { &hf_erldp_binary_ext, { "Binary", "erldp.binary_ext",
1250
15
                        FT_BYTES, BASE_SHOW_ASCII_PRINTABLE, NULL, 0x0,
1251
15
                        NULL, HFILL}},
1252
15
    { &hf_erldp_new_ref_ext_len, { "Len", "erldp.new_ref_ext.len",
1253
15
                        FT_UINT16, BASE_DEC, NULL, 0x0,
1254
15
                        NULL, HFILL}},
1255
15
    { &hf_erldp_new_ref_ext_creation, { "Creation", "erldp.new_ref_ext.creation",
1256
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1257
15
                        NULL, HFILL}},
1258
15
    { &hf_erldp_new_ref_ext_id, { "ID", "erldp.new_ref_ext.id",
1259
15
                        FT_UINT32, BASE_HEX, NULL, 0x0,
1260
15
                        NULL, HFILL}},
1261
15
    { &hf_erldp_fun_ext_num_free, { "Num Free", "erldp.fun_ext.num_free",
1262
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1263
15
                        NULL, HFILL}},
1264
15
    { &hf_erldp_new_fun_ext_size, { "Size", "erldp.new_fun_ext.size",
1265
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1266
15
                        NULL, HFILL}},
1267
15
    { &hf_erldp_new_fun_ext_arity, { "Arity", "erldp.new_fun_ext.arity",
1268
15
                        FT_UINT8, BASE_DEC, NULL, 0x0,
1269
15
                        NULL, HFILL}},
1270
15
    { &hf_erldp_new_fun_ext_uniq, { "Uniq", "erldp.new_fun_ext.uniq",
1271
15
                        FT_BYTES, BASE_NONE, NULL, 0x0,
1272
15
                        NULL, HFILL}},
1273
15
    { &hf_erldp_new_fun_ext_index, { "Index", "erldp.new_fun_ext.index",
1274
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1275
15
                        NULL, HFILL}},
1276
15
    { &hf_erldp_new_fun_ext_num_free, { "Num Free", "erldp.new_fun_ext.num_free",
1277
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1278
15
                        NULL, HFILL}},
1279
1280
    /*---  ---*/
1281
15
    { &hf_erldp_length_4, { "Length", "erldp.len",
1282
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1283
15
                        "Message Length", HFILL}},
1284
1285
    /*--- ETF  ---*/
1286
15
    { &hf_etf_tag,    { "Tag", "erldp.etf_tag",
1287
15
                        FT_UINT8, BASE_DEC, VALS(etf_tag_vals), 0x0,
1288
15
                        NULL, HFILL}},
1289
15
    { &hf_etf_dist_header_tag, { "Tag", "erldp.etf_header_tag",
1290
15
                        FT_UINT8, BASE_DEC, VALS(etf_header_tag_vals), 0x0,
1291
15
                        NULL, HFILL}},
1292
1293
15
    { &hf_etf_dist_header_new_cache,    { "NewCacheEntryFlag", "erldp.dist_header.new_cache",
1294
15
                        FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x08,
1295
15
                        NULL, HFILL}},
1296
1297
15
    { &hf_etf_dist_header_segment_index,    { "SegmentIndex", "erldp.dist_header.segment_index",
1298
15
                        FT_UINT8, BASE_DEC, NULL, 0x7,
1299
15
                        NULL, HFILL}},
1300
1301
15
    { &hf_etf_dist_header_long_atoms,    { "LongAtoms", "erldp.dist_header.long_atoms",
1302
15
                        FT_BOOLEAN, 8, TFS(&tfs_yes_no), 0x12,
1303
15
                        NULL, HFILL}},
1304
1305
15
    { &hf_etf_arity4, { "Arity", "erldp.arity",
1306
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1307
15
                        NULL, HFILL}},
1308
1309
15
    { &hf_etf_arity, { "Arity", "erldp.arity",
1310
15
                        FT_UINT8, BASE_DEC, NULL, 0x0,
1311
15
                        NULL, HFILL}},
1312
1313
15
    { &hf_etf_fragments, { "Message fragments", "erldp.dist.fragments",
1314
15
                        FT_NONE, BASE_NONE, NULL, 0x0, NULL,
1315
15
                        HFILL }},
1316
1317
15
    { &hf_etf_fragment, { "Message fragment", "erldp.dist.fragment",
1318
15
                        FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1319
15
                        NULL, HFILL }},
1320
1321
15
    { &hf_etf_fragment_overlap, { "Message fragment overlap", "erldp.dist.fragment.overlap",
1322
15
                        FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1323
15
                        NULL, HFILL }},
1324
1325
15
    { &hf_etf_fragment_overlap_conflicts, { "Message fragment overlapping with conflicting data",
1326
15
                                                            "erldp.dist.fragment.overlap.conflicts",
1327
15
                        FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1328
15
                        NULL, HFILL }},
1329
1330
15
    { &hf_etf_fragment_multiple_tails, { "Message has multiple tail fragments",
1331
15
                                                         "erldp.dist.fragment.multiple_tails",
1332
15
                        FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1333
15
                        NULL, HFILL }},
1334
1335
15
    { &hf_etf_fragment_too_long_fragment, { "Message fragment too long", "erldp.dist.fragment.too_long_fragment",
1336
15
                        FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1337
15
                        NULL, HFILL }},
1338
1339
15
    { &hf_etf_fragment_error, { "Message defragmentation error", "erldp.dist.fragment.error",
1340
15
                        FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1341
15
                        NULL, HFILL }},
1342
1343
15
    { &hf_etf_fragment_count, { "Message fragment count", "erldp.dist.fragment.count",
1344
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1345
15
                        NULL, HFILL }},
1346
1347
15
    { &hf_etf_reassembled_in, { "Reassembled in", "erldp.dist.reassembled.in",
1348
15
                        FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1349
15
                        NULL, HFILL }},
1350
1351
15
    { &hf_etf_reassembled_length, { "Reassembled length", "erldp.dist.reassembled.length",
1352
15
                        FT_UINT32, BASE_DEC, NULL, 0x0,
1353
15
                        NULL, HFILL }},
1354
1355
15
    { &hf_etf_reassembled_data, { "Reassembled data", "erldp.dist.reassembled.data",
1356
15
                        FT_BYTES, BASE_NONE, NULL, 0x0,
1357
15
                        NULL, HFILL }},
1358
15
  };
1359
1360
  /* List of subtrees */
1361
15
  static int *ett[] = {
1362
15
    &ett_erldp,
1363
15
    &ett_erldp_flags,
1364
15
    &ett_etf,
1365
15
    &ett_etf_flags,
1366
15
    &ett_etf_acrs,
1367
15
    &ett_etf_acr,
1368
15
    &ett_etf_tmp,
1369
15
    &ett_etf_fragment,
1370
15
    &ett_etf_fragments,
1371
15
  };
1372
1373
  /* Register protocol and dissector */
1374
15
  proto_erldp = proto_register_protocol("Erlang Distribution Protocol", "ErlDP", "erldp");
1375
15
  reassembly_table_register(&erldp_reassembly_table,
1376
15
                          &addresses_reassembly_table_functions);
1377
1378
15
  erldp_handle = register_dissector("erldp", dissect_erldp, proto_erldp);
1379
1380
  /* Register fields and subtrees */
1381
15
  proto_register_field_array(proto_erldp, hf, array_length(hf));
1382
15
  proto_register_subtree_array(ett, array_length(ett));
1383
1384
15
}
1385
1386
/*--- proto_reg_handoff_erldp -------------------------------------------*/
1387
15
void proto_reg_handoff_erldp(void) {
1388
1389
15
  dissector_add_for_decode_as_with_preference("tcp.port", erldp_handle);
1390
15
}
1391
1392
/*
1393
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1394
 *
1395
 * Local Variables:
1396
 * c-basic-offset: 2
1397
 * tab-width: 8
1398
 * indent-tabs-mode: nil
1399
 * End:
1400
 *
1401
 * ex: set shiftwidth=2 tabstop=8 expandtab:
1402
 * :indentSize=2:tabSize=8:noTabs=true:
1403
 */