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